332 lines
10 KiB
C#
332 lines
10 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Reflection;
|
||
|
using Rewired;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace RoR2;
|
||
|
|
||
|
public class SaveFieldAttribute : Attribute
|
||
|
{
|
||
|
[Serializable]
|
||
|
public struct HardwareMapEntry
|
||
|
{
|
||
|
public string HWGuid;
|
||
|
|
||
|
public string XMLMap;
|
||
|
}
|
||
|
|
||
|
[Serializable]
|
||
|
public struct HardwareMapWrapper
|
||
|
{
|
||
|
public HardwareMapEntry[] Entries;
|
||
|
}
|
||
|
|
||
|
public Action<UserProfile, string> setter;
|
||
|
|
||
|
public Func<UserProfile, string> getter;
|
||
|
|
||
|
public Action<UserProfile, UserProfile> copier;
|
||
|
|
||
|
public string defaultValue = string.Empty;
|
||
|
|
||
|
public string fieldName;
|
||
|
|
||
|
public string explicitSetupMethod;
|
||
|
|
||
|
private FieldInfo fieldInfo;
|
||
|
|
||
|
public void Setup(FieldInfo fieldInfo)
|
||
|
{
|
||
|
this.fieldInfo = fieldInfo;
|
||
|
Type fieldType = fieldInfo.FieldType;
|
||
|
fieldName = fieldInfo.Name;
|
||
|
if (explicitSetupMethod != null)
|
||
|
{
|
||
|
MethodInfo method = typeof(SaveFieldAttribute).GetMethod(explicitSetupMethod, BindingFlags.Instance | BindingFlags.Public);
|
||
|
if (method == null)
|
||
|
{
|
||
|
Debug.LogErrorFormat("Explicit setup {0} specified by field {1} could not be found. Use the nameof() operator to ensure the method exists.");
|
||
|
}
|
||
|
else if (method.GetParameters().Length > 1)
|
||
|
{
|
||
|
Debug.LogErrorFormat("Explicit setup method {0} for field {1} must have one parameter.", explicitSetupMethod, fieldInfo.Name);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
method.Invoke(this, new object[1] { fieldInfo });
|
||
|
}
|
||
|
}
|
||
|
else if (fieldType == typeof(string))
|
||
|
{
|
||
|
SetupString(fieldInfo);
|
||
|
}
|
||
|
else if (fieldType == typeof(int))
|
||
|
{
|
||
|
SetupInt(fieldInfo);
|
||
|
}
|
||
|
else if (fieldType == typeof(uint))
|
||
|
{
|
||
|
SetupUint(fieldInfo);
|
||
|
}
|
||
|
else if (fieldType == typeof(float))
|
||
|
{
|
||
|
SetupFloat(fieldInfo);
|
||
|
}
|
||
|
else if (fieldType == typeof(bool))
|
||
|
{
|
||
|
SetupBool(fieldInfo);
|
||
|
}
|
||
|
else if (fieldType == typeof(SurvivorDef))
|
||
|
{
|
||
|
SetupSurvivorDef(fieldInfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Debug.LogErrorFormat("No explicit setup method or supported type for save field {0}", fieldInfo.Name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void SetupString(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => (string)fieldInfo.GetValue(userProfile);
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
fieldInfo.SetValue(userProfile, valueString);
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
fieldInfo.SetValue(destProfile, fieldInfo.GetValue(srcProfile));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupFloat(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => TextSerialization.ToStringInvariant((float)fieldInfo.GetValue(userProfile));
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
if (TextSerialization.TryParseInvariant(valueString, out float result))
|
||
|
{
|
||
|
fieldInfo.SetValue(userProfile, result);
|
||
|
}
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
fieldInfo.SetValue(destProfile, fieldInfo.GetValue(srcProfile));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupInt(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => TextSerialization.ToStringInvariant((int)fieldInfo.GetValue(userProfile));
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
if (TextSerialization.TryParseInvariant(valueString, out int result))
|
||
|
{
|
||
|
fieldInfo.SetValue(userProfile, result);
|
||
|
}
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
fieldInfo.SetValue(destProfile, fieldInfo.GetValue(srcProfile));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupUint(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => TextSerialization.ToStringInvariant((uint)fieldInfo.GetValue(userProfile));
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
if (TextSerialization.TryParseInvariant(valueString, out uint result))
|
||
|
{
|
||
|
fieldInfo.SetValue(userProfile, result);
|
||
|
}
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
fieldInfo.SetValue(destProfile, fieldInfo.GetValue(srcProfile));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupBool(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => (!(bool)fieldInfo.GetValue(userProfile)) ? "0" : "1";
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
if (TextSerialization.TryParseInvariant(valueString, out int result))
|
||
|
{
|
||
|
fieldInfo.SetValue(userProfile, result > 0);
|
||
|
}
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
fieldInfo.SetValue(destProfile, fieldInfo.GetValue(srcProfile));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupTokenList(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => string.Join(" ", (List<string>)fieldInfo.GetValue(userProfile));
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
List<string> list = (List<string>)fieldInfo.GetValue(userProfile);
|
||
|
list.Clear();
|
||
|
string[] array = valueString.Split(' ');
|
||
|
foreach (string item in array)
|
||
|
{
|
||
|
list.Add(item);
|
||
|
}
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
List<string> src = (List<string>)fieldInfo.GetValue(srcProfile);
|
||
|
List<string> dest = (List<string>)fieldInfo.GetValue(destProfile);
|
||
|
Util.CopyList(src, dest);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupPickupsSet(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = delegate(UserProfile userProfile)
|
||
|
{
|
||
|
bool[] pickupsSet = (bool[])fieldInfo.GetValue(userProfile);
|
||
|
return string.Join(" ", from pickupDef in PickupCatalog.allPickups
|
||
|
where pickupsSet[pickupDef.pickupIndex.value]
|
||
|
select pickupDef.internalName);
|
||
|
};
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
bool[] array2 = (bool[])fieldInfo.GetValue(userProfile);
|
||
|
Array.Clear(array2, 0, 0);
|
||
|
string[] array3 = valueString.Split(' ');
|
||
|
for (int i = 0; i < array3.Length; i++)
|
||
|
{
|
||
|
PickupIndex pickupIndex = PickupCatalog.FindPickupIndex(array3[i]);
|
||
|
if (pickupIndex.isValid)
|
||
|
{
|
||
|
array2[pickupIndex.value] = true;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
bool[] sourceArray = (bool[])fieldInfo.GetValue(srcProfile);
|
||
|
bool[] array = (bool[])fieldInfo.GetValue(destProfile);
|
||
|
Array.Copy(sourceArray, array, array.Length);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupSurvivorDef(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = delegate(UserProfile userProfile)
|
||
|
{
|
||
|
SurvivorDef survivorDef = (SurvivorDef)fieldInfo.GetValue(userProfile);
|
||
|
return (!survivorDef) ? SurvivorCatalog.defaultSurvivor.cachedName : survivorDef.cachedName;
|
||
|
};
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
SurvivorDef value = SurvivorCatalog.FindSurvivorDef(valueString);
|
||
|
fieldInfo.SetValue(userProfile, value);
|
||
|
};
|
||
|
copier = DefaultCopier;
|
||
|
}
|
||
|
|
||
|
public void SetupKeyboardMap(FieldInfo fieldInfo)
|
||
|
{
|
||
|
SetupControllerMap(fieldInfo, ControllerType.Keyboard);
|
||
|
}
|
||
|
|
||
|
public void SetupMouseMap(FieldInfo fieldInfo)
|
||
|
{
|
||
|
SetupControllerMap(fieldInfo, ControllerType.Mouse);
|
||
|
}
|
||
|
|
||
|
public void SetupJoystickMap(FieldInfo fieldInfo)
|
||
|
{
|
||
|
SetupControllerMap(fieldInfo, ControllerType.Joystick);
|
||
|
}
|
||
|
|
||
|
private void SetupControllerMap(FieldInfo fieldInfo, ControllerType controllerType)
|
||
|
{
|
||
|
getter = (UserProfile userProfile) => ((ControllerMap)fieldInfo.GetValue(userProfile))?.ToXmlString() ?? string.Empty;
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
fieldInfo.SetValue(userProfile, ControllerMap.CreateFromXml(controllerType, valueString));
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
switch (controllerType)
|
||
|
{
|
||
|
case ControllerType.Joystick:
|
||
|
fieldInfo.SetValue(destProfile, new JoystickMap((JoystickMap)fieldInfo.GetValue(srcProfile)));
|
||
|
break;
|
||
|
case ControllerType.Keyboard:
|
||
|
fieldInfo.SetValue(destProfile, new KeyboardMap((KeyboardMap)fieldInfo.GetValue(srcProfile)));
|
||
|
break;
|
||
|
case ControllerType.Mouse:
|
||
|
fieldInfo.SetValue(destProfile, new MouseMap((MouseMap)fieldInfo.GetValue(srcProfile)));
|
||
|
break;
|
||
|
default:
|
||
|
throw new NotImplementedException();
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public void SetupJoystickHardwareMap(FieldInfo fieldInfo)
|
||
|
{
|
||
|
getter = delegate(UserProfile userProfile)
|
||
|
{
|
||
|
DefaultControllerMaps.RewiredDebugLog("SetupJoystickHardwareMap.getter");
|
||
|
Dictionary<Guid, JoystickMap> dictionary2 = (Dictionary<Guid, JoystickMap>)fieldInfo.GetValue(userProfile);
|
||
|
if (dictionary2 != null)
|
||
|
{
|
||
|
List<HardwareMapEntry> list = new List<HardwareMapEntry>();
|
||
|
foreach (KeyValuePair<Guid, JoystickMap> item2 in dictionary2)
|
||
|
{
|
||
|
HardwareMapEntry item = default(HardwareMapEntry);
|
||
|
item.HWGuid = item2.Key.ToString();
|
||
|
item.XMLMap = ((item2.Value != null) ? item2.Value.ToXmlString() : "");
|
||
|
list.Add(item);
|
||
|
}
|
||
|
HardwareMapWrapper hardwareMapWrapper2 = default(HardwareMapWrapper);
|
||
|
hardwareMapWrapper2.Entries = list.ToArray();
|
||
|
string text = JsonUtility.ToJson(hardwareMapWrapper2);
|
||
|
DefaultControllerMaps.RewiredDebugLog("\tReturning '{0}'", text);
|
||
|
return text;
|
||
|
}
|
||
|
return string.Empty;
|
||
|
};
|
||
|
setter = delegate(UserProfile userProfile, string valueString)
|
||
|
{
|
||
|
DefaultControllerMaps.RewiredDebugLog("SetupJoystickHardwareMap.setter> {0}", valueString);
|
||
|
HardwareMapWrapper hardwareMapWrapper = JsonUtility.FromJson<HardwareMapWrapper>(valueString);
|
||
|
Dictionary<Guid, JoystickMap> dictionary = new Dictionary<Guid, JoystickMap>();
|
||
|
HardwareMapEntry[] entries = hardwareMapWrapper.Entries;
|
||
|
for (int i = 0; i < entries.Length; i++)
|
||
|
{
|
||
|
HardwareMapEntry hardwareMapEntry = entries[i];
|
||
|
Guid key = Guid.Parse(hardwareMapEntry.HWGuid);
|
||
|
string xMLMap = hardwareMapEntry.XMLMap;
|
||
|
if (ControllerMap.CreateFromXml(ControllerType.Joystick, xMLMap) is JoystickMap joystickMap)
|
||
|
{
|
||
|
DefaultControllerMaps.RewiredDebugLog("Serialized Joystick Map for {0}", key.ToString());
|
||
|
LocalUser.DumpControllerMap(joystickMap);
|
||
|
dictionary.Add(key, joystickMap);
|
||
|
}
|
||
|
}
|
||
|
fieldInfo.SetValue(userProfile, dictionary);
|
||
|
};
|
||
|
copier = delegate(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
DefaultControllerMaps.RewiredDebugLog("SetupJoystickHardwareMap.copier");
|
||
|
fieldInfo.SetValue(destProfile, new Dictionary<Guid, JoystickMap>((Dictionary<Guid, JoystickMap>)fieldInfo.GetValue(srcProfile)));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
private void DefaultCopier(UserProfile srcProfile, UserProfile destProfile)
|
||
|
{
|
||
|
fieldInfo.SetValue(destProfile, fieldInfo.GetValue(srcProfile));
|
||
|
}
|
||
|
}
|