mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
better modifier unique IDs
This commit is contained in:
1 parent
caa27642db
commit
7e4a71739c
12 files changed
+134
-219
No files matched your search
@@ -45,7 +45,7 @@ public abstract class BaseModifier
|
||||
/// <summary>
|
||||
/// Gets the unique ID of the modifier.
|
||||
/// </summary>
|
||||
public uint UniqueId { get; internal set; }
|
||||
public Guid UniqueId { get; internal set; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type ID of the modifier.
|
||||
|
||||
@@ -37,14 +37,6 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
|
||||
private readonly List<BaseModifier> _toAdd = [];
|
||||
|
||||
private uint _nextUniqueId;
|
||||
|
||||
private uint GetNextUniqueId()
|
||||
{
|
||||
_nextUniqueId++;
|
||||
return _nextUniqueId;
|
||||
}
|
||||
|
||||
internal void ClearModifiers()
|
||||
{
|
||||
_toRemove.AddRange(Modifiers);
|
||||
@@ -204,22 +196,22 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
/// <param name="predicate">The predicate to check the modifier by.</param>
|
||||
/// <returns>True if the modifier was found, false otherwise.</returns>
|
||||
[HideFromIl2Cpp]
|
||||
public bool TryGetModifierByTypeId(uint id, out BaseModifier? modifier, Func<BaseModifier, bool>? predicate = null)
|
||||
public bool TryGetModifier(uint id, out BaseModifier? modifier, Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
modifier = GetModifierByTypeId(id, predicate);
|
||||
modifier = GetModifier(id, predicate);
|
||||
return modifier != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a modifier by its unique ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The modifier unique ID.</param>
|
||||
/// <param name="modifierGuid">The modifier unique ID.</param>
|
||||
/// <param name="modifier">The modifier or null.</param>
|
||||
/// <returns>True if the modifier was found, false otherwise.</returns>
|
||||
[HideFromIl2Cpp]
|
||||
public bool TryGetModifierByUniqueId(uint id, out BaseModifier? modifier)
|
||||
public bool TryGetModifier(Guid modifierGuid, out BaseModifier? modifier)
|
||||
{
|
||||
modifier = GetModifierByUniqueId(id);
|
||||
modifier = GetModifier(modifierGuid);
|
||||
return modifier != null;
|
||||
}
|
||||
|
||||
@@ -254,7 +246,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
/// <param name="predicate">The predicate to check the modifier by.</param>
|
||||
/// <returns>The Modifier if it is found, null otherwise.</returns>
|
||||
[HideFromIl2Cpp]
|
||||
public BaseModifier? GetModifierByTypeId(uint id, Func<BaseModifier, bool>? predicate = null)
|
||||
public BaseModifier? GetModifier(uint id, Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
|
||||
$"Cannot get modifier with id {id} because it is not registered.");
|
||||
@@ -265,12 +257,12 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
/// <summary>
|
||||
/// Gets a modifier by unique ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The modifier's unique ID.</param>
|
||||
/// <param name="modifierGuid">The modifier's unique ID.</param>
|
||||
/// <returns>The modifier if it is found, or null.</returns>
|
||||
[HideFromIl2Cpp]
|
||||
public BaseModifier? GetModifierByUniqueId(uint id)
|
||||
public BaseModifier? GetModifier(Guid modifierGuid)
|
||||
{
|
||||
return Modifiers.Find(x => x.UniqueId == id);
|
||||
return Modifiers.Find(x => x.UniqueId == modifierGuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -330,7 +322,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
/// <param name="typeId">The modifier's type ID.</param>
|
||||
/// <param name="predicate">The predicate to check the modifier by.</param>
|
||||
[HideFromIl2Cpp]
|
||||
public void RemoveModifierByTypeId(uint typeId, Func<BaseModifier, bool>? predicate = null)
|
||||
public void RemoveModifier(uint typeId, Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
var type = ModifierManager.GetModifierType(typeId) ?? throw new InvalidOperationException(
|
||||
$"Cannot remove modifier with id {typeId} because it is not registered.");
|
||||
@@ -342,9 +334,9 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
/// </summary>
|
||||
/// <param name="uniqueId">The modifier's unique ID.</param>
|
||||
[HideFromIl2Cpp]
|
||||
public void RemoveModifierByUniqueId(uint uniqueId)
|
||||
public void RemoveModifier(Guid uniqueId)
|
||||
{
|
||||
var modifier = GetModifierByUniqueId(uniqueId);
|
||||
var modifier = GetModifier(uniqueId);
|
||||
if (modifier == null)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Cannot remove modifier with unique id {uniqueId} because it is not active.");
|
||||
@@ -390,7 +382,10 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
_toAdd.Add(modifier);
|
||||
modifier.Player = _player;
|
||||
modifier.ModifierComponent = this;
|
||||
modifier.UniqueId = GetNextUniqueId();
|
||||
if (modifier.UniqueId == Guid.Empty)
|
||||
{
|
||||
modifier.UniqueId = Guid.NewGuid();
|
||||
}
|
||||
return modifier;
|
||||
}
|
||||
|
||||
@@ -460,13 +455,13 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a player has an active modifier by its type ID
|
||||
/// Checks if a player has an active modifier by its type ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The Modifier type ID.</param>
|
||||
/// <param name="id">The modifier's type ID.</param>
|
||||
/// <param name="predicate">The predicate to check the modifier.</param>
|
||||
/// <returns>True if the Modifier is present, false otherwise.</returns>
|
||||
/// <returns>True if the modifier is present, false otherwise.</returns>
|
||||
[HideFromIl2Cpp]
|
||||
public bool HasModifierByTypeId(uint id, Func<BaseModifier, bool>? predicate=null)
|
||||
public bool HasModifier(uint id, Func<BaseModifier, bool>? predicate=null)
|
||||
{
|
||||
var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
|
||||
$"Cannot get modifier with id {id} because it is not registered.");
|
||||
@@ -475,12 +470,12 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a player has an active modifier by its unique ID
|
||||
/// Checks if a player has an active modifier by its unique ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The Modifier type ID.</param>
|
||||
/// <returns>True if the Modifier is present, false otherwise.</returns>
|
||||
/// <param name="id">The modifier's guid.</param>
|
||||
/// <returns>True if the modifier is present, false otherwise.</returns>
|
||||
[HideFromIl2Cpp]
|
||||
public bool HasModifierByUniqueId(uint id)
|
||||
public bool HasModifier(Guid id)
|
||||
{
|
||||
return Modifiers.Exists(x => x.UniqueId == id);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace MiraAPI.Modifiers;
|
||||
|
||||
/// <summary>
|
||||
/// Modifier data for networking.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the modifier.</param>
|
||||
/// <param name="args">Parameters for constructor.</param>
|
||||
public readonly struct ModifierData(uint id, object[] args)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type of the modifier.
|
||||
/// </summary>
|
||||
public uint Id { get; } = id;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameters for the constructor.
|
||||
/// </summary>
|
||||
public object[] Args { get; } = args;
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public static class ModifierExtensions
|
||||
_ = ModifierManager.GetModifierType(typeId) ?? throw new InvalidOperationException(
|
||||
$"Modifier with ID {typeId} is not registered.");
|
||||
|
||||
Rpc<AddModifierRpc>.Instance.Send(target, new ModifierData(typeId, args));
|
||||
Rpc<AddModifierRpc>.Instance.Send(target, new ModifierData(typeId, Guid.NewGuid(), args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -63,9 +63,9 @@ public static class ModifierExtensions
|
||||
/// <param name="target">The player to remove the modifier from.</param>
|
||||
/// <param name="uniqueId">The unique ID of the modifier.</param>
|
||||
[MethodRpc((uint)MiraRpc.RemoveModifier)]
|
||||
public static void RpcRemoveModifierByUniqueId(this PlayerControl target, uint uniqueId)
|
||||
public static void RpcRemoveModifier(this PlayerControl target, Guid uniqueId)
|
||||
{
|
||||
target.RemoveModifierByUniqueId(uniqueId);
|
||||
target.RemoveModifier(uniqueId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,19 +74,19 @@ public static class ModifierExtensions
|
||||
/// <param name="target">The player to remove the modifier from.</param>
|
||||
/// <param name="typeId">The type ID of the modifier.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
public static void RpcRemoveModifierByTypeId(
|
||||
public static void RpcRemoveModifier(
|
||||
this PlayerControl target,
|
||||
uint typeId,
|
||||
Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
var modifier = target.GetModifierByTypeId(typeId, predicate);
|
||||
var modifier = target.GetModifier(typeId, predicate);
|
||||
if (modifier is null)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Player {target.PlayerId} does not have modifier with type ID {typeId}.");
|
||||
return;
|
||||
}
|
||||
|
||||
target.RpcRemoveModifierByUniqueId(modifier.UniqueId);
|
||||
target.RpcRemoveModifier(modifier.UniqueId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,7 +103,7 @@ public static class ModifierExtensions
|
||||
var id = ModifierManager.GetModifierTypeId(type) ?? throw new InvalidOperationException(
|
||||
$"Modifier {type.Name} is not registered.");
|
||||
|
||||
player.RpcRemoveModifierByTypeId(id, predicate);
|
||||
player.RpcRemoveModifier(id, predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -168,26 +168,26 @@ public static class ModifierExtensions
|
||||
/// Checks if the player has a specific modifier by type ID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="id">The type ID of the modifier.</param>
|
||||
/// <param name="typeId">The type ID of the modifier.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
/// <returns>True if the player has the modifier, false otherwise.</returns>
|
||||
public static bool HasModifierByTypeId(
|
||||
public static bool HasModifier(
|
||||
this PlayerControl player,
|
||||
uint id,
|
||||
uint typeId,
|
||||
Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
return player.GetModifierComponent().HasModifierByTypeId(id, predicate);
|
||||
return player.GetModifierComponent().HasModifier(typeId, predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the player has a specific modifier by unique ID.
|
||||
/// Checks if the player has a specific modifier by its GUID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="id">The unique ID of the modifier.</param>
|
||||
/// <param name="uniqueId">The unique ID of the modifier.</param>
|
||||
/// <returns>True if the player has the modifier, false otherwise.</returns>
|
||||
public static bool HasModifierByUniqueId(this PlayerControl player, uint id)
|
||||
public static bool HasModifier(this PlayerControl player, Guid uniqueId)
|
||||
{
|
||||
return player.GetModifierComponent().HasModifierByUniqueId(id);
|
||||
return player.GetModifierComponent().HasModifier(uniqueId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -218,31 +218,31 @@ public static class ModifierExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific modifier from the player by type ID.
|
||||
/// Gets a specific modifier from the player by its type ID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="id">The type ID of the modifier.</param>
|
||||
/// <param name="typeId">The type ID of the modifier.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
/// <returns>The modifier if found, null otherwise.</returns>
|
||||
public static BaseModifier? GetModifierByTypeId(
|
||||
public static BaseModifier? GetModifier(
|
||||
this PlayerControl player,
|
||||
uint id,
|
||||
uint typeId,
|
||||
Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
return player.GetModifierComponent().GetModifierByTypeId(id, predicate);
|
||||
return player.GetModifierComponent().GetModifier(typeId, predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific modifier from the player by ID.
|
||||
/// Gets a specific modifier from the player by its GUID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="id">The ID of the modifier.</param>
|
||||
/// <param name="uniqueId">The GUID of the modifier.</param>
|
||||
/// <returns>The modifier if found, null otherwise.</returns>
|
||||
public static BaseModifier? GetModifierByUniqueId(
|
||||
public static BaseModifier? GetModifier(
|
||||
this PlayerControl player,
|
||||
uint id)
|
||||
Guid uniqueId)
|
||||
{
|
||||
return player.GetModifierComponent().GetModifierByUniqueId(id);
|
||||
return player.GetModifierComponent().GetModifier(uniqueId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -251,7 +251,7 @@ public static class ModifierExtensions
|
||||
/// <typeparam name="T">The type of the modifiers.</typeparam>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
/// <returns>An enumerable of modifiers.</returns>
|
||||
/// <returns>A collection of modifiers.</returns>
|
||||
public static IEnumerable<T> GetModifiers<T>(this PlayerControl player, Func<T, bool>? predicate = null)
|
||||
where T : BaseModifier
|
||||
{
|
||||
@@ -264,7 +264,7 @@ public static class ModifierExtensions
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="type">The type of the modifiers.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
/// <returns>An enumerable of modifiers.</returns>
|
||||
/// <returns>A collection of modifiers.</returns>
|
||||
public static IEnumerable<BaseModifier> GetModifiers(
|
||||
this PlayerControl player,
|
||||
Type type,
|
||||
@@ -277,15 +277,15 @@ public static class ModifierExtensions
|
||||
/// Gets all modifiers of a specific type from the player by type ID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="id">The type ID of the modifiers.</param>
|
||||
/// <param name="typeId">The type ID of the modifiers.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
/// <returns>An enumerable of modifiers.</returns>
|
||||
/// <returns>A collection of modifiers.</returns>
|
||||
public static IEnumerable<BaseModifier> GetModifiers(
|
||||
this PlayerControl player,
|
||||
uint id,
|
||||
uint typeId,
|
||||
Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
return player.GetModifierComponent().GetModifiers(id, predicate);
|
||||
return player.GetModifierComponent().GetModifiers(typeId, predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -322,29 +322,29 @@ public static class ModifierExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a specific modifier from the player by ID.
|
||||
/// Removes a specific modifier from the player by its type ID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="typeId">The ID of the modifier.</param>
|
||||
/// <param name="typeId">The type ID of the modifier.</param>
|
||||
/// <param name="predicate">Optional predicate to filter the modifiers.</param>
|
||||
public static void RemoveModifierByTypeId(
|
||||
public static void RemoveModifier(
|
||||
this PlayerControl player,
|
||||
uint typeId,
|
||||
Func<BaseModifier, bool>? predicate = null)
|
||||
{
|
||||
player.GetModifierComponent().RemoveModifierByTypeId(typeId, predicate);
|
||||
player.GetModifierComponent().RemoveModifier(typeId, predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a specific modifier from the player by ID.
|
||||
/// Removes a specific modifier from the player by its GUID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl instance.</param>
|
||||
/// <param name="uniqueId">The ID of the modifier.</param>
|
||||
public static void RemoveModifierByUniqueId(
|
||||
/// <param name="uniqueId">The GUID of the modifier.</param>
|
||||
public static void RemoveModifier(
|
||||
this PlayerControl player,
|
||||
uint uniqueId)
|
||||
Guid uniqueId)
|
||||
{
|
||||
player.GetModifierComponent().RemoveModifierByUniqueId(uniqueId);
|
||||
player.GetModifierComponent().RemoveModifier(uniqueId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,12 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.Networking;
|
||||
using MiraAPI.Networking.Modifiers;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities;
|
||||
using Reactor.Networking.Rpc;
|
||||
using Reactor.Utilities;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using Random = System.Random;
|
||||
@@ -159,70 +156,6 @@ public static class ModifierManager
|
||||
private static bool IsGameModifierValid(PlayerControl player, GameModifier modifier, uint modifierId)
|
||||
{
|
||||
return (player.Data.Role is not ICustomRole role || role.IsModifierApplicable(modifier)) &&
|
||||
modifier.IsModifierValidOn(player.Data.Role) && !player.HasModifierByTypeId(modifierId);
|
||||
}
|
||||
|
||||
internal static void SyncAllModifiers(int targetId = -1)
|
||||
{
|
||||
var data = new List<NetData>();
|
||||
|
||||
foreach (var player in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
data.Add(GetPlayerModifiers(player));
|
||||
}
|
||||
|
||||
Rpc<SyncModifiersRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, [.. data]);
|
||||
}
|
||||
|
||||
internal static void HandleSyncModifiers(NetData[] data)
|
||||
{
|
||||
foreach (var netData in data)
|
||||
{
|
||||
var ids = new uint[netData.Data.Length / 4];
|
||||
Buffer.BlockCopy(netData.Data, 0, ids, 0, netData.Data.Length);
|
||||
|
||||
var plr = GameData.Instance.GetPlayerById((byte)netData.Id).Object;
|
||||
var modifierComponent = plr.GetComponent<ModifierComponent>();
|
||||
|
||||
if (!modifierComponent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
modifierComponent.ClearModifiers();
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (!IdToTypeModifierMap.TryGetValue(id, out var type))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Cannot add modifier with id {id} because it is not registered.");
|
||||
continue;
|
||||
}
|
||||
|
||||
modifierComponent.AddModifier(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static NetData GetPlayerModifiers(PlayerControl? player)
|
||||
{
|
||||
if (player == null || !player)
|
||||
{
|
||||
return new NetData(0, []);
|
||||
}
|
||||
|
||||
List<byte> bytes = [];
|
||||
var modifierComponent = player.GetComponent<ModifierComponent>();
|
||||
if (modifierComponent == null || !modifierComponent)
|
||||
{
|
||||
return new NetData(player.PlayerId, []);
|
||||
}
|
||||
|
||||
foreach (var modifier in modifierComponent.ActiveModifiers)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(TypeToIdModifierMap[modifier.GetType()]));
|
||||
}
|
||||
|
||||
return new NetData(player.PlayerId, [.. bytes]);
|
||||
modifier.IsModifierValidOn(player.Data.Role) && !player.HasModifier(modifierId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Hazel;
|
||||
using Reactor.Networking.Attributes;
|
||||
using Reactor.Networking.Serialization;
|
||||
|
||||
namespace MiraAPI.Networking;
|
||||
|
||||
/// <summary>
|
||||
/// Converter for <see cref="Guid"/>.
|
||||
/// </summary>
|
||||
[MessageConverter]
|
||||
public class GuidConverter : MessageConverter<Guid>
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Guid"/> to the writer.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void Write(MessageWriter writer, Guid value)
|
||||
{
|
||||
writer.WriteBytesAndSize(value.ToByteArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a <see cref="Guid"/> from the reader.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <returns>A GUID object.</returns>
|
||||
public override Guid Read(MessageReader reader, Type objectType)
|
||||
{
|
||||
return new Guid(reader.ReadBytesAndSize());
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,8 @@ public class AddModifierRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<Mir
|
||||
/// <inheritdoc />
|
||||
public override void Write(MessageWriter writer, ModifierData data)
|
||||
{
|
||||
writer.WritePacked(data.Id);
|
||||
writer.WritePacked(data.TypeId);
|
||||
writer.WriteBytesAndSize(data.UniqueId.ToByteArray());
|
||||
writer.WritePacked(data.Args.Length);
|
||||
foreach (var arg in data.Args)
|
||||
{
|
||||
@@ -34,6 +35,7 @@ public class AddModifierRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<Mir
|
||||
public override ModifierData Read(MessageReader reader)
|
||||
{
|
||||
var modId = reader.ReadPackedUInt32();
|
||||
var guid = new Guid(reader.ReadBytesAndSize());
|
||||
var argCount = reader.ReadPackedUInt32();
|
||||
var objects = new object[argCount];
|
||||
|
||||
@@ -48,12 +50,27 @@ public class AddModifierRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<Mir
|
||||
}
|
||||
}
|
||||
|
||||
return new ModifierData(modId, objects);
|
||||
return new ModifierData(modId, guid, objects);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Handle(PlayerControl player, ModifierData data)
|
||||
{
|
||||
player.AddModifier(data.Id, data.Args);
|
||||
var type = ModifierManager.GetModifierType(data.TypeId) ?? throw new InvalidOperationException($"Modifier type not found for ID {data.TypeId}.");
|
||||
BaseModifier? modifier;
|
||||
if (data.Args.Length > 0)
|
||||
{
|
||||
modifier = ModifierFactory.CreateInstance(type, data.Args);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifier = Activator.CreateInstance(type) as BaseModifier;
|
||||
if (modifier == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot add modifier {type.Name} because it is not a valid modifier.");
|
||||
}
|
||||
}
|
||||
modifier.UniqueId = data.UniqueId;
|
||||
player.AddModifier(modifier);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace MiraAPI.Networking.Modifiers;
|
||||
|
||||
/// <summary>
|
||||
/// Modifier data for networking.
|
||||
/// </summary>
|
||||
/// <param name="TypeId">The ID of the modifier.</param>
|
||||
/// <param name="UniqueId">The unique ID of the modifier.</param>
|
||||
/// <param name="Args">Parameters for constructor.</param>
|
||||
public record struct ModifierData(uint TypeId, Guid UniqueId, object[] Args);
|
||||
@@ -1,52 +0,0 @@
|
||||
using Hazel;
|
||||
using MiraAPI.Modifiers;
|
||||
using Reactor.Networking.Attributes;
|
||||
using Reactor.Networking.Rpc;
|
||||
|
||||
namespace MiraAPI.Networking.Modifiers;
|
||||
|
||||
[RegisterCustomRpc((uint)MiraRpc.SyncModifiers)]
|
||||
internal sealed class SyncModifiersRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<MiraApiPlugin, NetData[]>(plugin, id)
|
||||
{
|
||||
public override RpcLocalHandling LocalHandling => RpcLocalHandling.None;
|
||||
|
||||
public override void Write(MessageWriter writer, NetData[]? data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
writer.WritePacked(0U);
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePacked((uint)data.Length);
|
||||
foreach (var netData in data)
|
||||
{
|
||||
writer.WritePacked(netData.Id);
|
||||
writer.WriteBytesAndSize(netData.Data);
|
||||
}
|
||||
}
|
||||
|
||||
public override NetData[] Read(MessageReader reader)
|
||||
{
|
||||
var length = reader.ReadPackedUInt32();
|
||||
var data = new NetData[length];
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var dataId = reader.ReadPackedUInt32();
|
||||
var bytes = reader.ReadBytesAndSize();
|
||||
data[i] = new NetData(dataId, bytes);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public override void Handle(PlayerControl playerControl, NetData[]? data)
|
||||
{
|
||||
if (AmongUsClient.Instance.HostId != playerControl.OwnerId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ModifierManager.HandleSyncModifiers(data ?? []);
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,15 @@ using InnerNet;
|
||||
using MiraAPI.Events;
|
||||
using MiraAPI.Events.Vanilla.Player;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.Roles;
|
||||
|
||||
namespace MiraAPI.Patches;
|
||||
|
||||
/// <summary>
|
||||
/// Sync all options, role settings, and modifiers to the player when they join the game.
|
||||
/// Sync all settings to the player when they join the game.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(AmongUsClient))]
|
||||
public static class AmongUsClientSyncPatch
|
||||
internal static class AmongUsClientSyncPatch
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CreatePlayer))]
|
||||
@@ -33,7 +32,6 @@ public static class AmongUsClientSyncPatch
|
||||
|
||||
ModdedOptionsManager.SyncAllOptions(clientData.Id);
|
||||
CustomRoleManager.SyncAllRoleSettings(clientData.Id);
|
||||
ModifierManager.SyncAllModifiers(clientData.Id);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
|
||||
@@ -16,7 +16,7 @@ internal static class TaskAddButtonPatches
|
||||
if (uint.TryParse(__instance.name, out var result))
|
||||
{
|
||||
__instance.Overlay.sprite = __instance.CheckImage;
|
||||
__instance.Overlay.enabled = PlayerControl.LocalPlayer.HasModifierByTypeId(result);
|
||||
__instance.Overlay.enabled = PlayerControl.LocalPlayer.HasModifier(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -337,9 +337,9 @@ internal static class TaskAdderPatches
|
||||
taskAddButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
|
||||
{
|
||||
var id = modifier.TypeId;
|
||||
if (PlayerControl.LocalPlayer.HasModifierByTypeId(id))
|
||||
if (PlayerControl.LocalPlayer.HasModifier(id))
|
||||
{
|
||||
PlayerControl.LocalPlayer.RemoveModifierByTypeId(id);
|
||||
PlayerControl.LocalPlayer.RemoveModifier(id);
|
||||
taskAddButton.Overlay.enabled = false;
|
||||
}
|
||||
else
|
||||
|
||||
Reference in new issue
Block a user