Skip to content

+EA 23.343 Nightly - Plugin.BaseCore โ€‹

September 5, 2026

3 files modified. 1 new file created.

Important Changes โ€‹

None.

BaseModManager โ€‹

public void Parse<T>(ModItemList<T> list) where T : UnityEngine.Object

cs
public DirectoryInfo dirWorkshop;

public int priorityIndex; 
[NonSerialized]
public List<BaseModPackage> packages = new List<BaseModPackage>();

BaseModPackage โ€‹

using System;

cs
using System; 
using System.Collections.Generic; 
using System.IO;
using System.Xml;
using System.Xml.Linq; 
using UnityEngine;
using UnityEngine.UI;

public class BaseModPackage
{
	public const int defaultLoadPriority = 100; 
	public const int minLoadPriority = -999; 
	public const int maxLoadPriority = 999; 
	public static XmlReader xmlReader;

	public static XmlReaderSettings readerSetting;

public class BaseModPackage

cs
public string[] tags;

public string[][] dependency; 
public string[][] incompatible; 
public string[][] loadAfter; 
public string[][] loadBefore; 
public bool builtin;

public bool activated;

public class BaseModPackage

cs
public bool downloadStarted;

public int loadPriority; 
public int loadPriority = 100; 
public int orderIndex = -1; 
public BaseModPackage blockedBy; 
public string langDepError; 
public BaseModPackage duplicateOf; 
public string parseError; 

public object item;

public class BaseModPackage

cs
public Text progressText;

private static readonly Dictionary<string, string> builtinPackages = new Dictionary<string, string> 
{ 
	{ "_Elona", "elin_core1" }, 
	{ "_Lang_Chinese", "elin_language_chinese" }, 
	{ "_ModdingKit", "elin.plugins.modding" }, 
	{ "Mod_Slot", "elin_minigame_slot" } 
}; 
public bool CanActivate 
{ 
	get 
	{ 
		if (!hasPublishedPackage && installed) 
		{ 
			DirectoryInfo directoryInfo = dirInfo; 
			if (directoryInfo != null && directoryInfo.Exists) 
			{ 
				return willActivate; 
			} 
		} 
		return false; 
	} 
} 
public static string NormalizeId(string s) 
{ 
	if (s.IsEmpty()) 
	{ 
		return null; 
	} 
	string text = s.Trim().ToLowerInvariant(); 
	if (!text.IsEmpty()) 
	{ 
		return text; 
	} 
	return null; 
} 
public static bool IsBuiltinDir(string dirName) 
{ 
	if (!dirName.IsEmpty()) 
	{ 
		return builtinPackages.ContainsKey(dirName); 
	} 
	return false; 
} 
public static bool IsBuiltinPackage(DirectoryInfo dir, string packageId) 
{ 
	if (dir != null && builtinPackages.TryGetValue(dir.Name, out var value)) 
	{ 
		return NormalizeId(packageId) == value; 
	} 
	return false; 
} 
public bool IsValidVersion()
{
	return !Version.Get(version).IsBelow(BaseCore.Instance.versionMod); 
	if (!builtin && !version.IsEmpty() && version.Split('.').Length >= 3) 
	{ 
		return !Version.Get(version).IsBelow(BaseCore.Instance.versionMod); 
	} 
	return true; 
}

public bool Init()

public void UpdateMeta(bool updateOnly = false)

cs
	{
		return;
	}
	XmlReader xmlReader = XmlReader.Create(text, new XmlReaderSettings
	byte[] bytes; 
	try 
	{
		IgnoreComments = true, 
		IgnoreWhitespace = true
	}); 
	while (xmlReader.Read()) 
		bytes = File.ReadAllBytes(text); 
	} 
	catch (Exception ex) 
	{
		if (xmlReader.NodeType != XmlNodeType.Element) 
		{ 
			continue; 
		} 
		switch (xmlReader.Name) 
		parseError = ex.Message; 
		Debug.LogWarning($"#mod package.xml can't be read: {text}\n{ex}"); 
		return; 
	} 
	string error; 
	XDocument xDocument = ModXml.Load(bytes, out error); 
	if (xDocument?.Root == null) 
	{ 
		parseError = error.IsEmpty("no root element"); 
		Debug.LogWarning("#mod package.xml failed to parse: " + text + "\n" + parseError); 
		return; 
	} 
	string text2 = null; 
	string text3 = null; 
	string packageId = null; 
	string text4 = null; 
	string text5 = null; 
	string text6 = null; 
	string[] array = null; 
	int num = 100; 
	List<string[]> rows = null; 
	List<string[]> rows2 = null; 
	List<string[]> rows3 = null; 
	List<string[]> rows4 = null; 
	try
	{ 
		foreach (XElement item in xDocument.Root.Descendants()) 
		{
		case "title":
			if (xmlReader.Read()) 
			string text7 = ModXml.ValidXml(item.Name.LocalName); 
			if (text7 == null) 
			{
				title = xmlReader.Value; 
				Debug.LogWarning("#mod package.xml unknown element <" + item.Name.LocalName + ">, ignored: " + text); 
				continue; 
			}
			break; 
		case "author":
			if (xmlReader.Read()) 
			if (text7 != item.Name.LocalName) 
			{
				author = xmlReader.Value; 
				Debug.LogWarning("#mod package.xml <" + item.Name.LocalName + "> should be written as <" + text7 + ">, parsed: " + text); 
			}
			break; 
		case "id":
			if (xmlReader.Read()) 
			switch (text7) 
			{
				id = xmlReader.Value; 
			} 
			break; 
		case "description":
			if (xmlReader.Read()) 
			{ 
				description = xmlReader.Value; 
			} 
			break; 
		case "version":
			if (xmlReader.Read()) 
			{ 
				version = xmlReader.Value; 
			} 
			break; 
		case "builtin":
			if (xmlReader.Read()) 
			{ 
				bool.TryParse(xmlReader.Value, out builtin); 
			} 
			break; 
		case "tag":
		case "tags":
			if (xmlReader.Read()) 
			case "title":
				text2 = ModXml.Text(item); 
				break; 
			case "author":
				text3 = ModXml.Text(item); 
				break; 
			case "id":
				packageId = ModXml.Text(item); 
				break; 
			case "description":
				text4 = item.Value; 
				break; 
			case "version":
				text5 = ModXml.Text(item); 
				break; 
			case "tag":
			case "tags":
				array = ModXml.SplitTags(ModXml.Text(item)); 
				break; 
			case "loadPriority":
			{
				tags = xmlReader.Value.Split(','); 
			} 
			break; 
		case "loadPriority":
			if (!updateOnly && xmlReader.Read()) 
			{ 
				int.TryParse(xmlReader.Value, out loadPriority); 
				if (int.TryParse(ModXml.Text(item), out var result)) 
				{ 
					num = Mathf.Clamp(result, -999, 999); 
				} 
				break; 
			}
			break; 
		case "visibility":
			if (xmlReader.Read()) 
			{ 
				visibility = xmlReader.Value; 
			case "visibility":
				text6 = ModXml.Text(item); 
				break; 
			case "dependency":
				ModXml.ReadIdRow(item, ref rows, text); 
				break; 
			case "incompatible":
				ModXml.ReadIdRow(item, ref rows2, text); 
				break; 
			case "loadAfter":
				ModXml.ReadIdRow(item, ref rows3, text); 
				break; 
			case "loadBefore":
				ModXml.ReadIdRow(item, ref rows4, text); 
				break; 
			}
			break; 
		}
	}
	xmlReader.Close(); 
	catch (Exception ex2) 
	{ 
		parseError = ex2.Message; 
		Debug.LogWarning($"#mod package.xml failed to parse: {text}\n{ex2}"); 
		return; 
	} 
	title = text2; 
	author = text3; 
	id = packageId; 
	description = text4; 
	version = text5; 
	visibility = text6; 
	tags = array; 
	loadPriority = num; 
	dependency = rows?.ToArray(); 
	incompatible = rows2?.ToArray(); 
	loadAfter = rows3?.ToArray(); 
	loadBefore = rows4?.ToArray(); 
	builtin = IsBuiltinPackage(dirInfo, packageId); 
	parseError = null; 
}

public void Activate()
{
	if (!hasPublishedPackage && installed && dirInfo.Exists && willActivate) 
	if (CanActivate) 
	{
		Debug.Log("Activating(" + loadPriority + ") : " + title + "/" + id); 
		int num = ((BaseModManager.Instance == null) ? (-1) : BaseModManager.Instance.packages.IndexOf(this)); 
		Debug.Log("Activating(" + (num + 1) + ") : " + title + "/" + id); 
		activated = true;
		Parse();
	}

CorePath โ€‹

public class CorePackage

cs
public static string RootSaveCloud => Application.persistentDataPath + "/Cloud Save/";

public static string PathLoadOrder => rootExe + "loadorder.txt"; 
public static string PathLoadOrderPreset => user + "Load Order/"; 
public static string Temp => RootSave + "_Temp/";

public static string PathIni => RootSave + "elin.ini";

+ModXml โ€‹

File Created
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using UnityEngine;

public static class ModXml
{
	private static readonly string[] _validXml = new string[14]
	{
		"title", "author", "id", "description", "version", "builtin", "tag", "tags", "loadPriority", "visibility",
		"dependency", "incompatible", "loadAfter", "loadBefore"
	};

	public static string ValidXml(string name)
	{
		return _validXml.FirstOrDefault((string known) => string.Equals(name, known, StringComparison.OrdinalIgnoreCase));
	}

	public static string Text(XElement e)
	{
		return e.Value.Trim();
	}

	public static string[] SplitTags(string value)
	{
		if (value.IsEmpty())
		{
			return null;
		}
		List<string> list = new List<string>();
		string[] array = value.Split(',');
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (!text.IsEmpty() && !list.Contains(text))
			{
				list.Add(text);
			}
		}
		if (list.Count != 0)
		{
			return list.ToArray();
		}
		return null;
	}

	public static void ReadIdRow(XElement e, ref List<string[]> rows, string path)
	{
		try
		{
			string text = Attribute(e, "id");
			if (text.IsEmpty())
			{
				Debug.LogWarning("#mod package.xml <" + e.Name.LocalName + "> missing id, ignored: " + path);
				return;
			}
			List<string> list = null;
			string[] array = text.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = BaseModPackage.NormalizeId(array[i]);
				if (!text2.IsEmpty())
				{
					if (list == null)
					{
						list = new List<string>();
					}
					if (!list.Contains(text2))
					{
						list.Add(text2);
					}
				}
			}
			if (list != null)
			{
				if (rows == null)
				{
					rows = new List<string[]>();
				}
				rows.Add(list.ToArray());
			}
		}
		catch (Exception arg)
		{
			Debug.LogWarning($"#mod package.xml <{e.Name.LocalName}> is ill-formatted, ignored: {path}\n{arg}");
		}
	}

	private static string Attribute(XElement e, string name)
	{
		return e.Attributes().FirstOrDefault((XAttribute a) => string.Equals(a.Name.LocalName, name, StringComparison.OrdinalIgnoreCase))?.Value;
	}

	public static XDocument Load(byte[] bytes, out string error)
	{
		error = null;
		XmlReaderSettings settings = new XmlReaderSettings

โ€ฆ File