Skip to content
This repository was archived by the owner on Jul 8, 2025. It is now read-only.
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Exiled.Loader.Features.Configs.CustomConverters
using System.Globalization;
using System.IO;

using Exiled.API.Features;
using Exiled.API.Features.Pools;

using UnityEngine;
Expand All @@ -21,18 +22,37 @@ namespace Exiled.Loader.Features.Configs.CustomConverters
using YamlDotNet.Serialization;

/// <summary>
/// Converts a Vector2, Vector3 or Vector4 to Yaml configs and vice versa.
/// Converts a Vector2, Vector3 or Vector4 (including nullable) to Yaml configs and vice versa.
/// </summary>
public sealed class VectorsConverter : IYamlTypeConverter
{
/// <inheritdoc cref="IYamlTypeConverter" />
public bool Accepts(Type type) => type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4);
public bool Accepts(Type type)
{
Type baseType = Nullable.GetUnderlyingType(type) ?? type;
return baseType == typeof(Vector2) || baseType == typeof(Vector3) || baseType == typeof(Vector4);
}

/// <inheritdoc cref="IYamlTypeConverter" />
public object ReadYaml(IParser parser, Type type)
{
Type baseType = Nullable.GetUnderlyingType(type) ?? type;

if (parser.TryConsume(out Scalar scalar))
{
if (string.IsNullOrEmpty(scalar.Value) || scalar.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
{
if (Nullable.GetUnderlyingType(type) != null)
return null;

Log.Error($"Cannot assign null to non-nullable type {baseType.FullName}.");
}

Log.Error($"Expected mapping, but got scalar: {scalar.Value}");
}

if (!parser.TryConsume<MappingStart>(out _))
throw new InvalidDataException($"Cannot deserialize object of type {type.FullName}.");
Log.Error($"Cannot deserialize object of type {type.FullName}.");

List<object> coordinates = ListPool<object>.Pool.Get(4);
int i = 0;
Expand All @@ -45,16 +65,17 @@ public object ReadYaml(IParser parser, Type type)
continue;
}

if (!parser.TryConsume(out Scalar scalar) || !float.TryParse(scalar.Value, NumberStyles.Float, CultureInfo.GetCultureInfo("en-US"), out float coordinate))
if (!parser.TryConsume(out Scalar coordScalar) ||
!float.TryParse(coordScalar.Value, NumberStyles.Float, CultureInfo.GetCultureInfo("en-US"), out float coordinate))
{
ListPool<object>.Pool.Return(coordinates);
throw new InvalidDataException($"Invalid float value.");
throw new InvalidDataException("Invalid float value.");
}

coordinates.Add(coordinate);
}

object vector = Activator.CreateInstance(type, coordinates.ToArray());
object vector = Activator.CreateInstance(baseType, coordinates.ToArray());

ListPool<object>.Pool.Return(coordinates);

Expand All @@ -64,6 +85,12 @@ public object ReadYaml(IParser parser, Type type)
/// <inheritdoc cref="IYamlTypeConverter" />
public void WriteYaml(IEmitter emitter, object value, Type type)
{
if (value is null)
{
emitter.Emit(new Scalar("null"));
return;
}

Dictionary<string, float> coordinates = DictionaryPool<string, float>.Pool.Get();

if (value is Vector2 vector2)
Expand Down Expand Up @@ -97,4 +124,4 @@ public void WriteYaml(IEmitter emitter, object value, Type type)
emitter.Emit(new MappingEnd());
}
}
}
}