Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions EXILED/Exiled.API/Features/PrefabHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Exiled.API.Features
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using Exiled.API.Enums;
Expand All @@ -24,12 +25,17 @@ public static class PrefabHelper
/// <summary>
/// A <see cref="Dictionary{TKey,TValue}"/> containing all <see cref="PrefabType"/> and their corresponding <see cref="GameObject"/>.
/// </summary>
internal static readonly Dictionary<PrefabType, GameObject> Prefabs = new(Enum.GetValues(typeof(PrefabType)).Length);
internal static readonly Dictionary<PrefabType, (GameObject, Component)> Prefabs = new(Enum.GetValues(typeof(PrefabType)).Length);

/// <summary>
/// Gets a <see cref="IReadOnlyDictionary{TKey,TValue}"/> of <see cref="PrefabType"/> and their corresponding <see cref="GameObject"/>.
/// </summary>
public static IReadOnlyDictionary<PrefabType, GameObject> PrefabToGameObject => Prefabs;
public static IReadOnlyDictionary<PrefabType, (GameObject, Component)> PrefabToGameObjectAndComponent => Prefabs;

/// <summary>
/// Gets a <see cref="IReadOnlyDictionary{TKey,TValue}"/> of <see cref="PrefabType"/> and their corresponding <see cref="GameObject"/>.
/// </summary>
public static IReadOnlyDictionary<PrefabType, GameObject> PrefabToGameObject => Prefabs.ToDictionary(x => x.Key, x => x.Value.Item1);

/// <summary>
/// Gets the <see cref="PrefabAttribute"/> from a <see cref="PrefabType"/>.
Expand All @@ -49,8 +55,8 @@ public static PrefabAttribute GetPrefabAttribute(this PrefabType prefabType)
/// <returns>Returns the <see cref="GameObject"/>.</returns>
public static GameObject GetPrefab(PrefabType prefabType)
{
if (Prefabs.TryGetValue(prefabType, out GameObject prefab))
return prefab;
if (Prefabs.TryGetValue(prefabType, out (GameObject, Component) prefab))
return prefab.Item1;

return null;
}
Expand All @@ -76,8 +82,8 @@ public static bool TryGetPrefab(PrefabType prefabType, out GameObject gameObject
public static T GetPrefab<T>(PrefabType prefabType)
where T : Component
{
if (Prefabs.TryGetValue(prefabType, out GameObject prefab) && prefab.TryGetComponent(out T component))
return component;
if (Prefabs.TryGetValue(prefabType, out (GameObject, Component) prefab))
return (T)prefab.Item2;

return null;
}
Expand Down
23 changes: 12 additions & 11 deletions EXILED/Exiled.Events/Handlers/Internal/ClientStarted.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,42 +29,43 @@ public static void OnClientStarted()
{
PrefabHelper.Prefabs.Clear();

Dictionary<uint, GameObject> prefabs = new();
Dictionary<uint, (GameObject, Component)> prefabs = new();

foreach (KeyValuePair<uint, GameObject> prefab in NetworkClient.prefabs)
{
if (!prefabs.ContainsKey(prefab.Key))
prefabs.Add(prefab.Key, prefab.Value);
if(!prefabs.ContainsKey(prefab.Key) && prefab.Value.TryGetComponent(out Component component))
prefabs.Add(prefab.Key, (prefab.Value, component));
}

foreach (NetworkIdentity ragdollPrefab in RagdollManager.AllRagdollPrefabs)
{
if (!prefabs.ContainsKey(ragdollPrefab.assetId))
prefabs.Add(ragdollPrefab.assetId, ragdollPrefab.gameObject);
if(!prefabs.ContainsKey(ragdollPrefab.assetId) && ragdollPrefab.gameObject.TryGetComponent(out Component component))
prefabs.Add(ragdollPrefab.assetId, (ragdollPrefab.gameObject, component));
}

for (int i = 0; i < EnumUtils<PrefabType>.Values.Length; i++)
{
PrefabType prefabType = EnumUtils<PrefabType>.Values[i];
PrefabAttribute attribute = prefabType.GetPrefabAttribute();
if (prefabs.TryGetValue(attribute.AssetId, out GameObject gameObject))
if (prefabs.TryGetValue(attribute.AssetId, out (GameObject, Component) tuple))
{
PrefabHelper.Prefabs.Add(prefabType, gameObject);
GameObject gameObject = tuple.Item1;
PrefabHelper.Prefabs.Add(prefabType, prefabs.FirstOrDefault(prefab => prefab.Key == attribute.AssetId || prefab.Value.Item1.name.Contains(attribute.Name)).Value);
prefabs.Remove(attribute.AssetId);
continue;
}

KeyValuePair<uint, GameObject>? value = prefabs.FirstOrDefault(x => x.Value.name == attribute.Name);
KeyValuePair<uint, (GameObject, Component)>? value = prefabs.FirstOrDefault(x => x.Value.Item1.name == attribute.Name);
if (value.HasValue)
{
PrefabHelper.Prefabs.Add(prefabType, gameObject);
PrefabHelper.Prefabs.Add(prefabType, prefabs.FirstOrDefault(prefab => prefab.Key == attribute.AssetId || prefab.Value.Item1.name.Contains(attribute.Name)).Value);
prefabs.Remove(value.Value.Key);
continue;
}
}

foreach (KeyValuePair<uint, GameObject> missing in prefabs)
Log.Warn($"Missing prefab in {nameof(PrefabType)}: {missing.Value.name} ({missing.Key})");
foreach (KeyValuePair<uint, (GameObject, Component)> missing in prefabs)
Log.Warn($"Missing prefab in {nameof(PrefabType)}: {missing.Value.Item1.name} ({missing.Key})");
}
}
}