Files
barotrauma-localmods/Quick Interactions/CSharp/Client/CrabUI/Global/CUIExtensions.cs

220 lines
7.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.IO;
using System.Globalization;
using Barotrauma;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using HarmonyLib;
namespace QICrabUI
{
[CUIInternal]
public static partial class CUIExtensions
{
public static int Fit(this int i, int bottom, int top) => Math.Max(bottom, Math.Min(i, top));
public static Vector2 Rotate(this Vector2 v, float angle) => Vector2.Transform(v, Matrix.CreateRotationZ(angle));
public static string SubstringSafe(this string s, int start)
{
try
{
int safeStart = start.Fit(0, s.Length);
return s.Substring(safeStart, s.Length - safeStart);
}
catch (Exception e)
{
CUI.Log($"SubstringSafe {e}");
return "";
}
}
public static string SubstringSafe(this string s, int start, int length)
{
int end = (start + length).Fit(0, s.Length);
int safeStart = start.Fit(0, s.Length);
int safeLength = end - safeStart;
try
{
return s.Substring(safeStart, safeLength);
}
catch (Exception e)
{
CUI.Log($"SubstringSafe {e.Message}\ns:\"{s}\" start: {start}->{safeStart} end: {end} length: {length}->{safeLength} ", Color.Orange);
return "";
}
}
public static Dictionary<string, string> ParseKVPairs(string raw)
{
Dictionary<string, string> props = new();
if (raw == null || raw == "") return props;
string content = raw.Split('{', '}')[1];
List<string> expressions = new();
int start = 0;
int end = 0;
int depth = 0;
for (int i = 0; i < content.Length; i++)
{
char c = content[i];
end = i;
if (c == '[' || c == '{') depth++;
if (c == ']' || c == '}') depth--;
if (depth <= 0 && c == ',')
{
expressions.Add(content.Substring(start, end - start));
start = end + 1;
}
}
expressions.Add(content.Substring(start, end - start));
var pairs = expressions.Select(s => s.Split(':').Select(sub => sub.Trim()).ToArray());
foreach (var pair in pairs) { props[pair[0].ToLower()] = pair[1]; }
return props;
}
public static string ColorToString(Color c) => $"{c.R},{c.G},{c.B},{c.A}";
public static string Vector2ToString(Vector2 v) => $"[{v.X},{v.Y}]";
public static string NullVector2ToString(Vector2? v) => v.HasValue ? $"[{v.Value.X},{v.Value.Y}]" : "null";
public static string NullIntToString(int? i) => i.HasValue ? $"{i}" : "null";
public static string RectangleToString(Rectangle r) => $"[{r.X},{r.Y},{r.Width},{r.Height}]";
public static string GUIFontToString(GUIFont f) => f.Identifier.Value;
public static string SpriteEffectsToString(SpriteEffects e)
{
if ((int)e == 3) return "FlipBothSides";
else return e.ToString();
}
public static string IEnumerableStringToString(IEnumerable<string> e) => $"[{string.Join(',', e.ToArray())}]";
public static IEnumerable<string> ParseIEnumerableString(string raw)
{
if (raw == null || raw == "") return new List<string>();
string content = raw.Split('[', ']')[1];
return content.Split(',');
}
public static string ParseString(string s) => s; // BaroDev (wide)
//public static GUISoundType ParseGUISoundType(string s) => Enum.Parse<GUISoundType>(s);
public static GUIFont ParseGUIFont(string raw)
{
GUIFont font = GUIStyle.Fonts.GetValueOrDefault(new Identifier(raw.Trim()));
font ??= GUIStyle.Font;
return font;
}
public static SpriteEffects ParseSpriteEffects(string raw)
{
if (raw == "FlipBothSides") return SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically;
else return Enum.Parse<SpriteEffects>(raw);
}
public static int? ParseNullInt(string raw)
{
if (raw == "null") return null;
return int.Parse(raw);
}
public static Vector2? ParseNullVector2(string raw)
{
if (raw == "null") return null;
return ParseVector2(raw);
}
public static Vector2 ParseVector2(string raw)
{
if (raw == null || raw == "") return new Vector2(0, 0);
string content = raw.Split('[', ']')[1];
List<string> coords = content.Split(',').Select(s => s.Trim()).ToList();
float x = 0;
float y = 0;
float.TryParse(coords.ElementAtOrDefault(0), out x);
float.TryParse(coords.ElementAtOrDefault(1), out y);
return new Vector2(x, y);
}
public static Rectangle ParseRectangle(string raw)
{
if (raw == null || raw == "") return new Rectangle(0, 0, 1, 1);
string content = raw.Split('[', ']')[1];
List<string> coords = content.Split(',').Select(s => s.Trim()).ToList();
int x = 0;
int y = 0;
int w = 0;
int h = 0;
int.TryParse(coords.ElementAtOrDefault(0), out x);
int.TryParse(coords.ElementAtOrDefault(1), out y);
int.TryParse(coords.ElementAtOrDefault(2), out w);
int.TryParse(coords.ElementAtOrDefault(3), out h);
return new Rectangle(x, y, w, h);
}
public static Color ParseColor(string s) => XMLExtensions.ParseColor(s, false);
public static Dictionary<Type, MethodInfo> Parse;
public static Dictionary<Type, MethodInfo> CustomToString;
internal static void InitStatic()
{
CUI.OnInit += () =>
{
Stopwatch sw = Stopwatch.StartNew();
Parse = new Dictionary<Type, MethodInfo>();
CustomToString = new Dictionary<Type, MethodInfo>();
Parse[typeof(string)] = typeof(CUIExtensions).GetMethod("ParseString");
//Parse[typeof(GUISoundType)] = typeof(CUIExtensions).GetMethod("ParseGUISoundType");
Parse[typeof(Rectangle)] = typeof(CUIExtensions).GetMethod("ParseRectangle");
Parse[typeof(GUIFont)] = typeof(CUIExtensions).GetMethod("ParseGUIFont");
Parse[typeof(Vector2?)] = typeof(CUIExtensions).GetMethod("ParseNullVector2");
Parse[typeof(Vector2)] = typeof(CUIExtensions).GetMethod("ParseVector2");
Parse[typeof(SpriteEffects)] = typeof(CUIExtensions).GetMethod("ParseSpriteEffects");
Parse[typeof(Color)] = typeof(CUIExtensions).GetMethod("ParseColor");
Parse[typeof(int?)] = typeof(CUIExtensions).GetMethod("ParseNullInt");
Parse[typeof(IEnumerable<string>)] = typeof(CUIExtensions).GetMethod("ParseIEnumerableString");
CustomToString[typeof(IEnumerable<string>)] = typeof(CUIExtensions).GetMethod("IEnumerableStringToString");
CustomToString[typeof(int?)] = typeof(CUIExtensions).GetMethod("NullIntToString");
CustomToString[typeof(Color)] = typeof(CUIExtensions).GetMethod("ColorToString");
CustomToString[typeof(SpriteEffects)] = typeof(CUIExtensions).GetMethod("SpriteEffectsToString");
CustomToString[typeof(Vector2)] = typeof(CUIExtensions).GetMethod("Vector2ToString");
CustomToString[typeof(Vector2?)] = typeof(CUIExtensions).GetMethod("NullVector2ToString");
CustomToString[typeof(GUIFont)] = typeof(CUIExtensions).GetMethod("GUIFontToString");
CustomToString[typeof(Rectangle)] = typeof(CUIExtensions).GetMethod("RectangleToString");
CUIDebug.Log($"CUIExtensions.Initialize took {sw.ElapsedMilliseconds}ms");
};
CUI.OnDispose += () =>
{
Parse.Clear();
CustomToString.Clear();
};
}
}
}