Files
Lithium/Lithium/helper.cs
T
2025-11-22 14:21:26 -05:00

116 lines
4.5 KiB
C#

// Helper.cs
using System;
using System.IO;
using System.Globalization;
using System.Text.RegularExpressions;
namespace Lua
{
static class Helper
{
/// <summary>
/// Safely read lines from a file; returns empty array if missing or unreadable.
/// </summary>
public static string[] ReadLinesSafe(string path)
{
try
{
if (!File.Exists(path)) return Array.Empty<string>();
return File.ReadAllLines(path);
}
catch
{
return Array.Empty<string>();
}
}
/// <summary>
/// Parse lines of the form: key = value (case-insensitive key). Returns true when parsed.
/// For boolean values (true/false).
/// </summary>
public static bool ParseBoolFromAssignment(string line, string key, out bool result)
{
result = false;
var prefix = key + "=";
var idx = line.IndexOf('=');
if (idx < 0) return false;
var lhs = line.Substring(0, idx).Trim();
if (!string.Equals(lhs, key, StringComparison.OrdinalIgnoreCase)) return false;
var rhs = line.Substring(idx + 1).Trim();
if (rhs.Equals("true", StringComparison.OrdinalIgnoreCase)) { result = true; return true; }
if (rhs.Equals("false", StringComparison.OrdinalIgnoreCase)) { result = false; return true; }
// attempt to parse other truthy values
if (bool.TryParse(rhs, out var b)) { result = b; return true; }
return false;
}
public static bool ParseIntFromAssignment(string line, string key, out int result)
{
result = 0;
var idx = line.IndexOf('=');
if (idx < 0) return false;
var lhs = line.Substring(0, idx).Trim();
if (!string.Equals(lhs, key, StringComparison.OrdinalIgnoreCase)) return false;
var rhs = line.Substring(idx + 1).Trim();
return int.TryParse(rhs, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
}
public static bool ParseStringFromAssignment(string line, string key, out string result)
{
result = null;
var idx = line.IndexOf('=');
if (idx < 0) return false;
var lhs = line.Substring(0, idx).Trim();
if (!string.Equals(lhs, key, StringComparison.OrdinalIgnoreCase)) return false;
result = line.Substring(idx + 1).Trim();
// strip surrounding quotes if present
if ((result.StartsWith("\"") && result.EndsWith("\"")) || (result.StartsWith("'") && result.EndsWith("'")))
result = result.Substring(1, result.Length - 2);
return true;
}
public static bool ParseConsoleColorFromAssignment(string line, string key, out ConsoleColor color)
{
color = ConsoleColor.White;
if (!ParseStringFromAssignment(line, key, out var s)) return false;
return Enum.TryParse(s, true, out color);
}
/// <summary>
/// Parse a recoil definition line. Returns name and double values using InvariantCulture.
/// Matches patterns like:
/// ["Name"] = { recoilX = 1.23, recoilY = -4.56 }
/// or "['Name'] = { recoilX = 1.23, recoilY = -4.56 }"
/// </summary>
public static bool TryParseRecoilLine(string line, out string name, out double recoilX, out double recoilY)
{
name = null; recoilX = 0; recoilY = 0;
// regex to capture "Name" and two numbers
var pattern = @"\[\s*[""'](.+?)[""']\s*\]\s*=\s*\{\s*recoilX\s*=\s*([-\d\.eE]+)\s*,\s*recoilY\s*=\s*([-\d\.eE]+)\s*\}";
var m = Regex.Match(line, pattern, RegexOptions.IgnoreCase);
if (!m.Success) return false;
name = m.Groups[1].Value.Trim();
if (!double.TryParse(m.Groups[2].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out recoilX)) return false;
if (!double.TryParse(m.Groups[3].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out recoilY)) return false;
return true;
}
/// <summary>
/// Ensure index is valid for a list of given size (0..size-1). If size==0 returns 0.
/// </summary>
public static int SafeClampIndex(int idx, int size)
{
if (size <= 0) return 0;
if (idx < 0) return 0;
if (idx >= size) return size - 1;
return idx;
}
}
}