Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
XmlDatabaseSerializer.cs
浏览该文件的文档.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5using System.Xml.Linq;
6using Engine;
8using XmlUtilities;
9
10namespace TemplatesDatabase {
11 public static class XmlDatabaseSerializer {
12 public static Database LoadDatabase(XElement node) {
13 Dictionary<string, DatabaseObjectType> dictionary = [];
14 XElement xElement = XmlUtils.FindChildElement(node, "DatabaseObjectTypes", true);
15 foreach (XElement item in xElement.Elements()) {
16 string attributeValue = XmlUtils.GetAttributeValue<string>(item, "Name");
17 string attributeValue2 = XmlUtils.GetAttributeValue<string>(item, "DefaultInstanceName");
18 string attributeValue3 = XmlUtils.GetAttributeValue<string>(item, "IconName");
19 int attributeValue4 = XmlUtils.GetAttributeValue<int>(item, "Order");
20 bool attributeValue5 = XmlUtils.GetAttributeValue<bool>(item, "SupportsValue");
21 bool attributeValue6 = XmlUtils.GetAttributeValue<bool>(item, "MustInherit");
22 int attributeValue7 = XmlUtils.GetAttributeValue<int>(item, "NameLengthLimit");
23 bool attributeValue8 = XmlUtils.GetAttributeValue<bool>(item, "SaveStandalone");
24 DatabaseObjectType value = new(
25 attributeValue,
26 attributeValue2,
27 attributeValue3,
28 attributeValue4,
29 attributeValue5,
30 attributeValue6,
31 attributeValue7,
32 attributeValue8
33 );
34 dictionary.Add(attributeValue, value);
35 }
36 foreach (XElement item2 in xElement.Elements()) {
37 string attributeValue9 = XmlUtils.GetAttributeValue<string>(item2, "Name");
38 string attributeValue10 = XmlUtils.GetAttributeValue<string>(item2, "AllowedNestingParents");
39 string attributeValue11 = XmlUtils.GetAttributeValue<string>(item2, "AllowedInheritanceParents");
40 string attributeValue12 = XmlUtils.GetAttributeValue<string>(item2, "NestedValueType");
41 List<DatabaseObjectType> list = [];
42 string[] array = attributeValue10.Split([',', ' '], StringSplitOptions.RemoveEmptyEntries);
43 foreach (string text in array) {
44 if (!dictionary.TryGetValue(text, out DatabaseObjectType value2)) {
45 throw new InvalidOperationException($"Database object type \"{text}\" not found.");
46 }
47 list.Add(value2);
48 }
49 List<DatabaseObjectType> list2 = [];
50 array = attributeValue11.Split([',', ' '], StringSplitOptions.RemoveEmptyEntries);
51 foreach (string text2 in array) {
52 if (!dictionary.TryGetValue(text2, out DatabaseObjectType value3)) {
53 throw new InvalidOperationException($"Database object type \"{text2}\" not found.");
54 }
55 list2.Add(value3);
56 }
57 DatabaseObjectType value4 = null;
58 if (!string.IsNullOrEmpty(attributeValue12)
59 && !dictionary.TryGetValue(attributeValue12, out value4)) {
60 throw new InvalidOperationException($"Database object type \"{attributeValue12}\" not found.");
61 }
62 dictionary[attributeValue9].InitializeRelations(list, list2, value4);
63 }
64 foreach (XElement item3 in XmlUtils.FindChildElement(node, "Assemblies", true).Elements()) {
65 string attributeValue13 = XmlUtils.GetAttributeValue<string>(item3, "Name");
66 try {
67 Assembly.Load(new AssemblyName(attributeValue13));
68 }
69 catch (Exception ex) {
70 Log.Warning($"Error loading assembly {attributeValue13}. {ex}");
71 }
72 }
73 XElement node2 = XmlUtils.FindChildElement(node, "DatabaseObjects", true);
74 Database database = new(
76 guid: XmlUtils.GetAttributeValue<Guid>(node2, "RootGuid"),
77 databaseObjectType: dictionary["Root"],
78 name: "Root",
79 value: null
80 ),
81 dictionary.Values
82 );
83 foreach (DatabaseObject item4 in LoadDatabaseObjectsList(node2, database)) {
84 item4.NestingParent = database.Root;
85 }
86 return database;
87 }
88
89 public static List<DatabaseObject> LoadDatabaseObjectsList(XElement node, Database database) =>
90 LoadDatabaseObjectsList(node, database, false);
91
92 public static List<DatabaseObject> LoadDatabaseObjectsList(XElement node, Database database, bool generateNewGuids) {
93 Dictionary<DatabaseObject, Guid> dictionary = [];
94 Dictionary<DatabaseObject, Guid> dictionary2 = [];
95 Dictionary<Guid, Guid> dictionary3 = generateNewGuids ? [] : null;
96 List<DatabaseObject> list = InternalLoadDatabaseObjectsList(node, database, dictionary, dictionary2, dictionary3);
97 Dictionary<Guid, DatabaseObject> dictionary4 = [];
98 foreach (DatabaseObject item in list) {
99 dictionary4.Add(item.Guid, item);
100 foreach (DatabaseObject explicitNestingChild in item.GetExplicitNestingChildren(null, false)) {
101 dictionary4.Add(explicitNestingChild.Guid, explicitNestingChild);
102 }
103 }
104 foreach (KeyValuePair<DatabaseObject, Guid> item2 in dictionary) {
105 Guid key = item2.Value;
106 if (dictionary3 != null
107 && dictionary3.TryGetValue(key, out Guid value)) {
108 key = value;
109 }
110 if (!dictionary4.TryGetValue(key, out DatabaseObject value2)) {
111 throw new InvalidOperationException($"Required nesting parent {item2.Value} not found in database objects list.");
112 }
113 item2.Key.NestingParent = value2;
114 }
115 foreach (KeyValuePair<DatabaseObject, Guid> item3 in dictionary2) {
116 Guid guid = item3.Value;
117 if (dictionary3 != null
118 && dictionary3.TryGetValue(guid, out Guid value3)) {
119 guid = value3;
120 }
121 item3.Key.ExplicitInheritanceParent = dictionary4.TryGetValue(guid, out DatabaseObject value4)
122 ? value4
123 : database.FindDatabaseObject(guid, null, true);
124 }
125 return list.Where(x => x.NestingParent == null).ToList();
126 }
127
128 public static DatabaseObject LoadDatabaseObject(XElement node, Database database) {
129 Dictionary<DatabaseObject, Guid> dictionary = [];
130 DatabaseObject result = InternalLoadDatabaseObject(node, database, null, dictionary, null);
131 foreach (KeyValuePair<DatabaseObject, Guid> item in dictionary) {
132 item.Key.ExplicitInheritanceParent = database.FindDatabaseObject(item.Value, null, true);
133 }
134 return result;
135 }
136
137 public static void SaveDatabase(XElement node, Database database) {
138 XElement parentNode = XmlUtils.AddElement(node, "DatabaseObjectTypes");
139 foreach (DatabaseObjectType databaseObjectType in database.DatabaseObjectTypes) {
140 XElement node2 = XmlUtils.AddElement(parentNode, "DatabaseObjectType");
141 XmlUtils.SetAttributeValue(node2, "Name", databaseObjectType.Name);
142 XmlUtils.SetAttributeValue(node2, "DefaultInstanceName", databaseObjectType.DefaultInstanceName);
144 node2,
145 "IconName",
146 !string.IsNullOrEmpty(databaseObjectType.IconName) ? databaseObjectType.IconName : string.Empty
147 );
148 XmlUtils.SetAttributeValue(node2, "Order", databaseObjectType.Order);
149 XmlUtils.SetAttributeValue(node2, "SupportsValue", databaseObjectType.SupportsValue);
150 XmlUtils.SetAttributeValue(node2, "MustInherit", databaseObjectType.MustInherit);
151 XmlUtils.SetAttributeValue(node2, "NameLengthLimit", databaseObjectType.NameLengthLimit);
152 XmlUtils.SetAttributeValue(node2, "SaveStandalone", databaseObjectType.SaveStandalone);
154 node2,
155 "AllowedNestingParents",
156 databaseObjectType.AllowedNestingParents.Aggregate(string.Empty, (r, d) => r.Length != 0 ? $"{r},{d.Name}" : d.Name)
157 );
159 node2,
160 "AllowedInheritanceParents",
161 databaseObjectType.AllowedInheritanceParents.Aggregate(string.Empty, (r, d) => r.Length != 0 ? $"{r},{d.Name}" : d.Name)
162 );
164 node2,
165 "NestedValueType",
166 databaseObjectType.NestedValueType != null ? databaseObjectType.NestedValueType.Name : string.Empty
167 );
168 }
169 List<Type> list = [];
170 database.FindUsedValueTypes(list);
171 List<Assembly> list2 = [];
172 foreach (Type item in list) {
173 if (!list2.Contains(item.GetTypeInfo().Assembly)) {
174 list2.Add(item.GetTypeInfo().Assembly);
175 }
176 }
177 list2.Sort((a1, a2) => string.CompareOrdinal(a1.FullName, a2.FullName));
178 XElement parentNode2 = XmlUtils.AddElement(node, "Assemblies");
179 foreach (Assembly item2 in list2) {
180 XmlUtils.SetAttributeValue(XmlUtils.AddElement(parentNode2, "Assembly"), "Name", item2.GetName().Name);
181 }
182 XElement node3 = XmlUtils.AddElement(node, "DatabaseObjects");
183 XmlUtils.SetAttributeValue(node3, "RootGuid", database.Root.Guid);
184 SaveDatabaseObjectsList(node3, database.Root.GetExplicitNestingChildren(null, true));
185 }
186
187 public static void SaveDatabaseObjectsList(XElement node, IEnumerable<DatabaseObject> databaseObjects) {
188 List<DatabaseObject> list = [];
189 IEnumerable<DatabaseObject> enumerable = databaseObjects as DatabaseObject[] ?? databaseObjects.ToArray();
190 foreach (DatabaseObject databaseObject in enumerable) {
191 list.AddRange(from x in databaseObject.GetExplicitNestingChildren(null, false) where x.Type.SaveStandalone select x);
192 }
193 InternalSaveDatabaseObjectsList(node, list, true);
194 InternalSaveDatabaseObjectsList(node, enumerable, false);
195 }
196
197 public static void SaveDatabaseObject(XElement node, DatabaseObject databaseObject) {
198 InternalSaveDatabaseObject(node, databaseObject, false);
199 }
200
201 public static List<DatabaseObject> InternalLoadDatabaseObjectsList(XElement node,
202 Database database,
203 Dictionary<DatabaseObject, Guid> nestingParents,
204 Dictionary<DatabaseObject, Guid> inheritanceParents,
205 Dictionary<Guid, Guid> guidTranslation) {
206 List<DatabaseObject> list = [];
207 foreach (XElement item2 in node.Elements()) {
208 DatabaseObject item = InternalLoadDatabaseObject(item2, database, nestingParents, inheritanceParents, guidTranslation);
209 list.Add(item);
210 }
211 return list;
212 }
213
214 public static DatabaseObject InternalLoadDatabaseObject(XElement node,
215 Database database,
216 Dictionary<DatabaseObject, Guid> nestingParents,
217 Dictionary<DatabaseObject, Guid> inheritanceParents,
218 Dictionary<Guid, Guid> guidTranslation) {
219 Guid guid = XmlUtils.GetAttributeValue(node, "Guid", Guid.Empty);
220 string attributeValue = XmlUtils.GetAttributeValue(node, "Name", string.Empty);
221 string attributeValue2 = XmlUtils.GetAttributeValue(node, "Description", string.Empty);
222 Guid attributeValue3 = XmlUtils.GetAttributeValue(node, "NestingParent", Guid.Empty);
223 Guid attributeValue4 = XmlUtils.GetAttributeValue(node, "InheritanceParent", Guid.Empty);
224 string attributeValue5 = XmlUtils.GetAttributeValue(node, "Type", string.Empty);
225 if (guid == Guid.Empty) {
226 guid = Guid.NewGuid();
227 }
228 if (guidTranslation != null) {
229 Guid guid2 = Guid.NewGuid();
230 guidTranslation.Add(guid, guid2);
231 guid = guid2;
232 }
233 DatabaseObjectType databaseObjectType = database.FindDatabaseObjectType(node.Name.ToString(), true);
234 object value = null;
235 if (!string.IsNullOrEmpty(attributeValue5)) {
236 Type type = TypeCache.FindType(attributeValue5, false, true);
237 value = XmlUtils.GetAttributeValue(node, "Value", type);
238 }
239 DatabaseObject databaseObject = new(databaseObjectType, guid, attributeValue, value) { Description = attributeValue2 };
240 if (nestingParents != null
241 && attributeValue3 != Guid.Empty) {
242 nestingParents.Add(databaseObject, attributeValue3);
243 }
244 if (inheritanceParents != null
245 && attributeValue4 != Guid.Empty) {
246 inheritanceParents.Add(databaseObject, attributeValue4);
247 }
248 foreach (DatabaseObject item in InternalLoadDatabaseObjectsList(node, database, nestingParents, inheritanceParents, guidTranslation)) {
249 item.NestingParent = databaseObject;
250 }
251 return databaseObject;
252 }
253
254 public static void InternalSaveDatabaseObjectsList(XElement node, IEnumerable<DatabaseObject> databaseObjects, bool saveNestingParents) {
255 List<DatabaseObject> list = new(databaseObjects);
256 list.Sort((o1, o2) => o1.Type.Order != o2.Type.Order ? o1.Type.Order - o2.Type.Order : o1.Guid.CompareTo(o2.Guid));
257 foreach (DatabaseObject item in list) {
258 InternalSaveDatabaseObject(XmlUtils.AddElement(node, item.Type.Name), item, saveNestingParents);
259 }
260 }
261
262 public static void InternalSaveDatabaseObject(XElement node, DatabaseObject databaseObject, bool saveNestingParent) {
263 XmlUtils.SetAttributeValue(node, "Name", databaseObject.Name);
264 if (!string.IsNullOrEmpty(databaseObject.Description)) {
265 XmlUtils.SetAttributeValue(node, "Description", databaseObject.Description);
266 }
267 XmlUtils.SetAttributeValue(node, "Guid", databaseObject.Guid);
268 if (databaseObject.Value != null) {
269 XmlUtils.SetAttributeValue(node, "Value", databaseObject.Value);
270 XmlUtils.SetAttributeValue(node, "Type", TypeCache.GetShortTypeName(databaseObject.Value.GetType().FullName));
271 }
272 if (databaseObject.ExplicitInheritanceParent != null) {
273 XmlUtils.SetAttributeValue(node, "InheritanceParent", databaseObject.ExplicitInheritanceParent.Guid);
274 }
275 if (saveNestingParent && databaseObject.NestingParent != null) {
276 XmlUtils.SetAttributeValue(node, "NestingParent", databaseObject.NestingParent.Guid);
277 }
279 node,
280 from x in databaseObject.GetExplicitNestingChildren(null, true) where !x.Type.SaveStandalone select x,
281 false
282 );
283 }
284 }
285}
static void Warning(object message)
定义 Log.cs:68
static Type FindType(string typeName, bool skipSystemAssemblies, bool throwIfNotFound)
static string GetShortTypeName(string longTypeName)
DatabaseObjectType FindDatabaseObjectType(string name, bool throwIfNotFound)
IList< DatabaseObjectType > DatabaseObjectTypes
void FindUsedValueTypes(List< Type > typesList)
DatabaseObject FindDatabaseObject(Guid guid, DatabaseObjectType type, bool throwIfNotFound)
IEnumerable< DatabaseObject > GetExplicitNestingChildren(DatabaseObjectType type, bool directChildrenOnly)
ReadOnlyList< DatabaseObjectType > AllowedNestingParents
ReadOnlyList< DatabaseObjectType > AllowedInheritanceParents
void InitializeRelations(IEnumerable< DatabaseObjectType > allowedNestingParents, IEnumerable< DatabaseObjectType > allowedInheritanceParents, DatabaseObjectType nestedValueType)
static DatabaseObject InternalLoadDatabaseObject(XElement node, Database database, Dictionary< DatabaseObject, Guid > nestingParents, Dictionary< DatabaseObject, Guid > inheritanceParents, Dictionary< Guid, Guid > guidTranslation)
static void SaveDatabaseObjectsList(XElement node, IEnumerable< DatabaseObject > databaseObjects)
static List< DatabaseObject > LoadDatabaseObjectsList(XElement node, Database database, bool generateNewGuids)
static void InternalSaveDatabaseObjectsList(XElement node, IEnumerable< DatabaseObject > databaseObjects, bool saveNestingParents)
static List< DatabaseObject > LoadDatabaseObjectsList(XElement node, Database database)
static void SaveDatabase(XElement node, Database database)
static void SaveDatabaseObject(XElement node, DatabaseObject databaseObject)
static List< DatabaseObject > InternalLoadDatabaseObjectsList(XElement node, Database database, Dictionary< DatabaseObject, Guid > nestingParents, Dictionary< DatabaseObject, Guid > inheritanceParents, Dictionary< Guid, Guid > guidTranslation)
static DatabaseObject LoadDatabaseObject(XElement node, Database database)
static void InternalSaveDatabaseObject(XElement node, DatabaseObject databaseObject, bool saveNestingParent)
static void SetAttributeValue(XElement node, string attributeName, object value)
static object GetAttributeValue(XElement node, string attributeName, Type type)
static XElement AddElement(XElement parentNode, string name)
static XElement FindChildElement(XElement node, string elementName, bool throwIfNotFound)