Client LuaCsForBarotrauma
BarotraumaShared/SharedSource/GameSession/Data/CampaignMetadata.cs
1 #nullable enable
2 using System;
3 using System.Collections.Generic;
4 using System.Globalization;
5 using System.Xml.Linq;
6 
7 namespace Barotrauma
8 {
9  internal partial class CampaignMetadata
10  {
11  private readonly Dictionary<Identifier, object> data = new Dictionary<Identifier, object>();
12 
13  public CampaignMetadata()
14  {
15  }
16 
17  public void Load(XElement element)
18  {
19  data.Clear();
20  foreach (var subElement in element.Elements())
21  {
22  if (string.Equals(subElement.Name.ToString(), "data", StringComparison.InvariantCultureIgnoreCase))
23  {
24  Identifier identifier = subElement.GetAttributeIdentifier("key", Identifier.Empty);
25  string value = subElement.GetAttributeString("value", string.Empty);
26  string valueType = subElement.GetAttributeString("type", string.Empty);
27 
28  if (identifier.IsEmpty || string.IsNullOrWhiteSpace(value) || string.IsNullOrWhiteSpace(valueType))
29  {
30  DebugConsole.ThrowError("Unable to load value because one or more of the required attributes are empty.\n" +
31  $"key: \"{identifier}\", value: \"{value}\", type: \"{valueType}\"");
32  continue;
33  }
34 
35  Type? type = ReflectionUtils.GetType(valueType);
36 
37  if (type == null)
38  {
39  DebugConsole.ThrowError($"Type for {identifier} not found ({valueType}).");
40  continue;
41  }
42  else if (type == typeof(Identifier))
43  {
44  data.Add(identifier, value.ToIdentifier());
45  }
46  else
47  {
48  try
49  {
50  data.Add(identifier, Convert.ChangeType(value, type, NumberFormatInfo.InvariantInfo));
51  }
52  catch (Exception e)
53  {
54  DebugConsole.ThrowError($"Failed to change the type of the value \"{value}\" to {type}.", e);
55  }
56  }
57  }
58  }
59  }
60 
61  public void SetValue(Identifier identifier, object value)
62  {
63  DebugConsole.Log($"Set the value \"{identifier}\" to {value}");
64 
65  AchievementManager.OnCampaignMetadataSet(identifier, value, unlockClients: true);
66 
67  if (!data.ContainsKey(identifier))
68  {
69  data.Add(identifier, value);
70  return;
71  }
72 
73  data[identifier] = value;
74  }
75 
76  public float GetFloat(Identifier identifier, float? defaultValue = null)
77  {
78  return (float)GetTypeOrDefault(identifier, typeof(float), defaultValue ?? 0f);
79  }
80 
81  public int GetInt(Identifier identifier, int? defaultValue = null)
82  {
83  return (int)GetTypeOrDefault(identifier, typeof(int), defaultValue ?? 0);
84  }
85 
86  public bool GetBoolean(Identifier identifier, bool? defaultValue = null)
87  {
88  return (bool)GetTypeOrDefault(identifier, typeof(bool), defaultValue ?? false);
89  }
90 
91  public string GetString(Identifier identifier, string? defaultValue = null)
92  {
93  return (string)GetTypeOrDefault(identifier, typeof(string), defaultValue ?? string.Empty);
94  }
95 
96  public bool HasKey(Identifier identifier)
97  {
98  return data.ContainsKey(identifier);
99  }
100 
101  private object GetTypeOrDefault(Identifier identifier, Type type, object defaultValue)
102  {
103  object? value = GetValue(identifier);
104  if (value != null)
105  {
106  if (value.GetType() == type)
107  {
108  return value;
109  }
110  else
111  {
112  DebugConsole.ThrowError($"Attempted to get value \"{identifier}\" as a {type} but the value is {value.GetType()}.");
113  }
114  }
115  return defaultValue;
116  }
117 
118  public object? GetValue(Identifier identifier)
119  {
120  return data.ContainsKey(identifier) ? data[identifier] : null;
121  }
122 
123  public void Save(XElement modeElement)
124  {
125  XElement element = new XElement("Metadata");
126 
127  foreach (var (key, value) in data)
128  {
129  string valueStr = value.ToString() ?? throw new NullReferenceException();
130  if (value is float f)
131  {
132  valueStr = f.ToString("G", CultureInfo.InvariantCulture);
133  }
134 
135  element.Add(new XElement("Data",
136  new XAttribute("key", key),
137  new XAttribute("value", valueStr),
138  new XAttribute("type", value.GetType().FullName ?? "")));
139  }
140 #if DEBUG
141  DebugConsole.Log(element.ToString());
142 #endif
143  modeElement.Add(element);
144  }
145  }
146 }