+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 โ
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;cs
public string[] tags;
public string[][] dependency;
public string[][] incompatible;
public string[][] loadAfter;
public string[][] loadBefore;
public bool builtin;
public bool activated;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;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 โ
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