quantum-space-buddies/QSB/Utility/Extensions.cs

218 lines
4.8 KiB
C#
Raw Normal View History

2022-01-29 04:49:07 +00:00
using Cysharp.Threading.Tasks;
using Mirror;
2022-01-15 05:18:05 +00:00
using OWML.Common;
2021-02-06 22:03:10 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
2021-02-09 10:03:13 +00:00
using System.Reflection;
2021-01-26 14:07:17 +00:00
using UnityEngine;
2021-12-26 05:02:21 +00:00
using Object = UnityEngine.Object;
2022-03-03 03:46:33 +00:00
namespace QSB.Utility;
public static class Extensions
{
2022-03-03 03:46:33 +00:00
#region UNITY
2022-03-03 03:46:33 +00:00
public static Quaternion TransformRotation(this Transform transform, Quaternion localRotation)
=> transform.rotation * localRotation;
2021-04-20 07:36:07 +00:00
2022-03-03 03:46:33 +00:00
public static GameObject InstantiateInactive(this GameObject original)
{
if (!original.activeSelf)
2020-12-02 21:23:01 +00:00
{
2022-03-03 03:46:33 +00:00
return Object.Instantiate(original);
}
2022-03-03 03:46:33 +00:00
original.SetActive(false);
var copy = Object.Instantiate(original);
original.SetActive(true);
return copy;
}
2022-01-15 05:18:05 +00:00
2022-03-03 03:46:33 +00:00
#endregion
2022-01-24 19:53:51 +00:00
2022-03-03 03:46:33 +00:00
#region MIRROR
2022-03-03 03:46:33 +00:00
public static uint GetPlayerId(this NetworkConnectionToClient conn)
{
if (!conn.identity)
{
// wtf
DebugLog.ToConsole($"Error - GetPlayerId on {conn} has no identity\n{Environment.StackTrace}", MessageType.Error);
return uint.MaxValue;
}
2022-02-04 00:43:26 +00:00
2022-03-03 03:46:33 +00:00
return conn.identity.netId;
}
2022-02-04 00:43:26 +00:00
2022-03-03 03:46:33 +00:00
public static NetworkConnectionToClient GetNetworkConnection(this uint playerId)
{
var conn = NetworkServer.connections.Values.FirstOrDefault(x => playerId == x.GetPlayerId());
if (conn == default)
{
DebugLog.ToConsole($"Error - GetNetworkConnection on {playerId} found no connection\n{Environment.StackTrace}", MessageType.Error);
}
2022-03-03 03:46:33 +00:00
return conn;
}
public static void SpawnWithServerAuthority(this GameObject go) =>
NetworkServer.Spawn(go, NetworkServer.localConnection);
2021-08-19 15:37:29 +00:00
2022-03-03 03:46:33 +00:00
#endregion
2022-03-03 03:46:33 +00:00
#region C#
2022-03-03 03:46:33 +00:00
public static void SafeInvoke(this MulticastDelegate multicast, params object[] args)
{
foreach (var del in multicast.GetInvocationList())
2021-02-06 22:03:10 +00:00
{
2022-03-03 03:46:33 +00:00
try
{
del.DynamicInvoke(args);
}
catch (TargetInvocationException ex)
2021-02-06 22:03:10 +00:00
{
2022-03-03 03:46:33 +00:00
DebugLog.ToConsole($"Error invoking delegate! {ex.InnerException}", MessageType.Error);
2021-02-06 22:03:10 +00:00
}
}
2022-03-03 03:46:33 +00:00
}
2021-03-25 23:07:53 +00:00
2022-03-03 03:46:33 +00:00
public static float Map(this float value, float inputFrom, float inputTo, float outputFrom, float outputTo, bool clamp)
{
var mappedValue = (value - inputFrom) / (inputTo - inputFrom) * (outputTo - outputFrom) + outputFrom;
2021-12-27 21:04:57 +00:00
2022-03-03 03:46:33 +00:00
return clamp
? Mathf.Clamp(mappedValue, outputTo, outputFrom)
: mappedValue;
}
2022-03-03 03:46:33 +00:00
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
2021-07-07 08:02:23 +00:00
{
2022-03-03 03:46:33 +00:00
action(item);
2021-07-07 08:02:23 +00:00
}
2022-03-03 03:46:33 +00:00
}
2021-07-07 08:02:23 +00:00
2022-03-03 03:46:33 +00:00
public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var comparer = Comparer<TKey>.Default;
var yk = default(TKey);
var y = default(TSource);
var hasValue = false;
foreach (var x in source)
{
2022-03-03 03:46:33 +00:00
var xk = keySelector(x);
if (!hasValue)
{
2022-03-03 03:46:33 +00:00
hasValue = true;
yk = xk;
y = x;
}
2022-03-03 03:46:33 +00:00
else if (comparer.Compare(xk, yk) < 0)
{
2022-03-03 03:46:33 +00:00
yk = xk;
y = x;
}
2022-03-03 03:46:33 +00:00
}
2022-03-03 03:46:33 +00:00
if (!hasValue)
{
throw new InvalidOperationException("Sequence contains no elements");
}
2022-03-03 03:46:33 +00:00
return y;
}
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var comparer = Comparer<TKey>.Default;
var yk = default(TKey);
var y = default(TSource);
var hasValue = false;
foreach (var x in source)
{
2022-03-03 03:46:33 +00:00
var xk = keySelector(x);
if (!hasValue)
{
2022-03-03 03:46:33 +00:00
hasValue = true;
yk = xk;
y = x;
}
2022-03-03 03:46:33 +00:00
else if (comparer.Compare(xk, yk) > 0)
{
2022-03-03 03:46:33 +00:00
yk = xk;
y = x;
}
2022-03-03 03:46:33 +00:00
}
2022-03-03 03:46:33 +00:00
if (!hasValue)
{
throw new InvalidOperationException("Sequence contains no elements");
}
2022-03-03 03:46:33 +00:00
return y;
}
2021-12-15 07:57:21 +00:00
2022-03-03 03:46:33 +00:00
public static bool IsInRange<T>(this IList<T> list, int index) => index >= 0 && index < list.Count;
2022-03-03 03:46:33 +00:00
public static void RaiseEvent<T>(this T instance, string eventName, params object[] args)
{
const BindingFlags flags = BindingFlags.Instance
2022-06-26 18:32:40 +00:00
| BindingFlags.Static
| BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.DeclaredOnly;
2022-03-03 03:46:33 +00:00
if (typeof(T)
2022-06-26 18:32:40 +00:00
.GetField(eventName, flags)?
.GetValue(instance) is not MulticastDelegate multiDelegate)
2022-03-03 03:46:33 +00:00
{
return;
}
2022-07-05 08:59:04 +00:00
multiDelegate.SafeInvoke(args);
2022-03-03 03:46:33 +00:00
}
2022-03-30 00:34:44 +00:00
public static IEnumerable<Type> GetDerivedTypes(this Type type) =>
2022-03-30 00:57:34 +00:00
QSBCore.Addons.Values
2022-03-30 00:34:44 +00:00
.Select(x => x.GetType().Assembly)
.Append(type.Assembly)
.SelectMany(x => x.GetTypes())
.Where(x => !x.IsInterface && !x.IsAbstract && type.IsAssignableFrom(x))
.OrderBy(x => x.FullName);
2022-03-03 03:46:33 +00:00
public static Guid ToGuid(this int value)
{
var bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
return new Guid(bytes);
}
2022-03-03 03:46:33 +00:00
public static void Try(this object self, string doingWhat, Action action)
{
try
2022-01-15 10:27:22 +00:00
{
2022-03-03 03:46:33 +00:00
action();
2022-01-15 10:27:22 +00:00
}
2022-03-03 03:46:33 +00:00
catch (Exception e)
2022-01-29 04:49:07 +00:00
{
2022-03-03 03:46:33 +00:00
DebugLog.ToConsole($"{self} - error {doingWhat} : {e}", MessageType.Error);
}
2022-03-03 03:46:33 +00:00
}
2022-03-03 03:46:33 +00:00
public static async UniTask Try(this object self, string doingWhat, Func<UniTask> func)
{
try
{
2022-03-03 03:46:33 +00:00
await func().SuppressCancellationThrow();
}
catch (Exception e)
{
DebugLog.ToConsole($"{self} - error {doingWhat} : {e}", MessageType.Error);
2022-01-29 04:49:07 +00:00
}
}
2022-03-03 03:46:33 +00:00
#endregion
}