Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotkey Sync fixed #2

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 130 additions & 37 deletions ValheimPlus/Configurations/BaseConfig.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
using IniParser.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using ValheimPlus.GameClasses;
using ValheimPlus.RPC;
using YamlDotNet.Core.Tokens;
using static CharacterDrop;

namespace ValheimPlus.Configurations
{
public interface IConfig
{
void LoadIniData(KeyDataCollection data);
void LoadIniData(KeyDataCollection data, string section);
}

public abstract class BaseConfig<T> : IConfig where T : IConfig, new()
public abstract class BaseConfig<T> : IConfig where T : class, IConfig, new()
{

public string ServerSerializeSection()
Expand All @@ -24,82 +31,168 @@ public string ServerSerializeSection()
}
return r;
}

public bool IsEnabled = false;
public virtual bool NeedsServerSync { get; set;} = false;
[LoadingOption(LoadingMode.Never)]
public bool IsEnabled { get; private set; } = false;
[LoadingOption(LoadingMode.Never)]
public virtual bool NeedsServerSync { get; set; } = false;

public static IniData iniUpdated = null;

public static T LoadIni(IniData data, string section)
{
var n = new T();


Debug.Log($"Loading config section {section}");
if (data[section] == null || data[section]["enabled"] == null || !data[section].GetBool("enabled"))
{
Debug.Log(" Section not enabled");
return n;
}

n.LoadIniData(data[section]);
var keyData = data[section];
n.LoadIniData(keyData, section);

return n;
}
private static Dictionary<Type, DGetDataValue> _getValues = new Dictionary<Type, DGetDataValue>()
{
{typeof(float), GetFloatValue },
{typeof(int), GetIntValue },
{typeof(KeyCode), GetKeyCodeValue },
{typeof(bool), GetBoolValue }
};

public void LoadIniData(KeyDataCollection data)
public void LoadIniData(KeyDataCollection data, string section)
{
IsEnabled = true;

foreach (var prop in typeof(T).GetProperties())
var thisConfiguration = GetCurrentConfiguration(section);
if (thisConfiguration == null)
{
var keyName = prop.Name;
if (new[] { "NeedsServerSync", "IsEnabled" }.Contains(keyName)) continue;
// Set first char of keyName to lowercase
if (keyName != string.Empty && char.IsUpper(keyName[0]))
{
keyName = char.ToLower(keyName[0]) + keyName.Substring(1);
}
Debug.Log("Configuration not set.");
thisConfiguration = this as T;
if (thisConfiguration == null) Debug.Log("Error on setting Configuration");
}

if (!data.ContainsKey(keyName)) {
Debug.Log($" Key {keyName} not defined, using default value");
continue;
}
foreach (var property in typeof(T).GetProperties())
{

Debug.Log($" Loading key {keyName}");
var existingValue = prop.GetValue(this, null);

if (prop.PropertyType == typeof(float))
if (IgnoreLoading(property))
{
prop.SetValue(this, data.GetFloat(keyName, (float)existingValue), null);
continue;
}

if (prop.PropertyType == typeof(int))
var currentValue = property.GetValue(thisConfiguration);
if (LoadLocalOnly(property))
{
prop.SetValue(this, data.GetInt(keyName, (int)existingValue), null);
property.SetValue(this, currentValue, null);
Grantapher marked this conversation as resolved.
Show resolved Hide resolved
continue;
}

if (prop.PropertyType == typeof(bool))
var keyName = GetKeyNameFromProperty(property);

if (!data.ContainsKey(keyName))
{
prop.SetValue(this, data.GetBool(keyName), null);
Debug.Log($" Key {keyName} not defined, using default value");
continue;
}

if (prop.PropertyType == typeof(KeyCode) && !RPC.VPlusConfigSync.isConnecting)
Debug.Log($"{property.Name} [{keyName}] = {currentValue} ({property.PropertyType})");

if (_getValues.ContainsKey(property.PropertyType))
{
prop.SetValue(this, data.GetKeyCode(keyName, (KeyCode)existingValue), null);
continue;
var getValue = _getValues[property.PropertyType];
var value = getValue(data, currentValue, keyName);
Debug.Log($"{keyName} = {currentValue} => {value}");
property.SetValue(this, value, null);
}
else Debug.LogWarning($" Could not load data of type {property.PropertyType} for key {keyName}");
}
}

delegate object DGetDataValue(KeyDataCollection data, object currentValue, string keyName);

private static object GetFloatValue(KeyDataCollection data, object currentValue, string keyName)
{
return data.GetFloat(keyName, (float)currentValue);
}
private static object GetBoolValue(KeyDataCollection data, object currentValue, string keyName)
{
return data.GetBool(keyName);
}
private static object GetIntValue(KeyDataCollection data, object currentValue, string keyName)
{
return data.GetInt(keyName, (int)currentValue);
}
private static object GetKeyCodeValue(KeyDataCollection data, object currentValue, string keyName)
{
return data.GetKeyCode(keyName, (KeyCode)currentValue);
}

private string GetKeyNameFromProperty(PropertyInfo property)
{
var keyName = property.Name;

// Set first char of keyName to lowercase
if (keyName != string.Empty && char.IsUpper(keyName[0]))
{
keyName = char.ToLower(keyName[0]) + keyName.Substring(1);
}
return keyName;
}
private bool IgnoreLoading(PropertyInfo property)
{
var loadingOption = property.GetCustomAttribute<LoadingOption>();
var loadingMode = loadingOption?.LoadingMode ?? LoadingMode.Always;

return (loadingMode == LoadingMode.Never);
}
private bool LoadLocalOnly(PropertyInfo property)
{
var loadingOption = property.GetCustomAttribute<LoadingOption>();
var loadingMode = loadingOption?.LoadingMode ?? LoadingMode.Always;

return VPlusConfigSync.SyncRemote && (property.PropertyType == typeof(KeyCode) && !ConfigurationExtra.SyncHotkeys || loadingMode == LoadingMode.LocalOnly);
}

Debug.LogWarning($" Could not load data of type {prop.PropertyType} for key {keyName}");
private static object GetCurrentConfiguration(string section)
{
if (Configuration.Current == null) return null;
Debug.Log($"Reading Config '{section}'");
var properties = Configuration.Current.GetType().GetProperties();
PropertyInfo property = properties.SingleOrDefault(p => p.Name.Equals(section, System.StringComparison.CurrentCultureIgnoreCase));
if (property == null)
{
Debug.LogWarning($"Property '{section}' not found in Configuration");
return null;
}
var thisConfiguration = property.GetValue(Configuration.Current) as T;
return thisConfiguration;
}
}

public abstract class ServerSyncConfig<T> : BaseConfig<T> where T : class, IConfig, new()
{
[LoadingOption(LoadingMode.Never)]
public override bool NeedsServerSync { get; set; } = true;
}

public abstract class ServerSyncConfig<T>: BaseConfig<T> where T : IConfig, new() {
public override bool NeedsServerSync { get; set;} = true;
public class LoadingOption : Attribute
{
public LoadingMode LoadingMode { get; }
public LoadingOption(LoadingMode loadingMode)
{
LoadingMode = loadingMode;
}
}
/// <summary>
/// Defines, when a property is loaded
/// </summary>
public enum LoadingMode
{
Always = 0,
RemoteOnly = 1,
Grantapher marked this conversation as resolved.
Show resolved Hide resolved
LocalOnly = 2,
Never = 3
}
}

1 change: 0 additions & 1 deletion ValheimPlus/Configurations/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ namespace ValheimPlus.Configurations
public class Configuration
{
public static Configuration Current { get; set; }
public static Configuration Settings { get; set; }
public AdvancedBuildingModeConfiguration AdvancedBuildingMode { get; set; }
public AdvancedEditingModeConfiguration AdvancedEditingMode { get; set; }
public BedConfiguration Bed { get; set; }
Expand Down
39 changes: 29 additions & 10 deletions ValheimPlus/Configurations/ConfigurationExtra.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using System.Reflection;
using UnityEngine;
using ValheimPlus.Utility;
using ValheimPlus.Configurations.Sections;
using ValheimPlus.RPC;

namespace ValheimPlus.Configurations
{
Expand All @@ -21,7 +23,7 @@ public static string GetServerHashFor(Configuration config)
{
var keyName = prop.Name;
var method = prop.PropertyType.GetMethod("ServerSerializeSection", BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance);

if (method != null)
{
var instance = prop.GetValue(config, null);
Expand Down Expand Up @@ -50,7 +52,7 @@ public static bool LoadSettings()
// get the current versions ini data
compareIni = ValheimPlusPlugin.getCurrentWebIniFile();
}
catch (Exception e) { }
catch (Exception) { }

if (compareIni != null)
{
Expand All @@ -75,15 +77,15 @@ public static bool LoadSettings()
try
{
string defaultIni = ValheimPlusPlugin.getCurrentWebIniFile();
if(defaultIni != null)
if (defaultIni != null)
{
System.IO.File.WriteAllText(ConfigIniPath, defaultIni);
Debug.Log("Default Configuration downloaded. Loading downloaded default settings.");
Configuration.Current = LoadFromIni(ConfigIniPath);
status = true;
}
}
catch (Exception e) { }
catch (Exception) { }

return status;
}
Expand All @@ -96,12 +98,13 @@ public static bool LoadSettings()

return true;
}
static public bool SyncHotkeys { get; private set; } = false;

//loading local configuration
public static Configuration LoadFromIni(string filename)
{
FileIniDataParser parser = new FileIniDataParser();
IniData configdata = parser.ReadFile(filename);

Configuration conf = new Configuration();
foreach (var prop in typeof(Configuration).GetProperties())
{
Expand All @@ -117,13 +120,26 @@ public static Configuration LoadFromIni(string filename)

return conf;
}

/// <summary>
/// Loading remote configuration
/// </summary>
/// <param name="iniStream">remote configuration stream</param>
/// <returns>new configuration</returns>
public static Configuration LoadFromIni(Stream iniStream)
{
using (StreamReader iniReader = new StreamReader(iniStream))
{
FileIniDataParser parser = new FileIniDataParser();
IniData configdata = parser.ReadData(iniReader);
var serverSection = configdata[nameof(Configuration.Server)];
var serverSyncsConfig = serverSection.GetBool(nameof(ServerConfiguration.serverSyncsConfig));
Debug.Log($"ServerSyncsConfig = {serverSyncsConfig}");

if (!serverSyncsConfig) return Configuration.Current;

var serverSyncsHotkeys = Configuration.Current.Server.serverSyncHotkeys;
Debug.Log($"ServerSyncsHotkeys = {serverSyncsConfig}");
SyncHotkeys = serverSyncsHotkeys;

Configuration conf = new Configuration();
foreach (var prop in typeof(Configuration).GetProperties())
Expand All @@ -134,7 +150,7 @@ public static Configuration LoadFromIni(Stream iniStream)

if (method != null)
{
object result = method.Invoke(null, new object[] {configdata, keyName});
object result = method.Invoke(null, new object[] { configdata, keyName });
prop.SetValue(conf, result, null);
}
}
Expand All @@ -147,7 +163,8 @@ public static class IniDataExtensions
{
public static float GetFloat(this KeyDataCollection data, string key, float defaultVal)
{
if (float.TryParse(data[key], NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out var result)) {
if (float.TryParse(data[key], NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out var result))
{
return result;
}

Expand All @@ -163,7 +180,8 @@ public static bool GetBool(this KeyDataCollection data, string key)

public static int GetInt(this KeyDataCollection data, string key, int defaultVal)
{
if (int.TryParse(data[key], NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out var result)) {
if (int.TryParse(data[key], NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out var result))
{
return result;
}

Expand All @@ -173,7 +191,8 @@ public static int GetInt(this KeyDataCollection data, string key, int defaultVal

public static KeyCode GetKeyCode(this KeyDataCollection data, string key, KeyCode defaultVal)
{
if (Enum.TryParse<KeyCode>(data[key].Trim(), out var result)) {
if (Enum.TryParse<KeyCode>(data[key].Trim(), out var result))
{
return result;
}

Expand Down
16 changes: 15 additions & 1 deletion ValheimPlus/Configurations/Sections/ServerConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
namespace ValheimPlus.Configurations.Sections
using System.Security.Policy;
using UnityEngine;

namespace ValheimPlus.Configurations.Sections
{
public class ServerConfiguration : BaseConfig<ServerConfiguration>
{
public int maxPlayers { get; internal set; } = 10;
public bool disableServerPassword { get; internal set; } = false;
public bool enforceMod { get; internal set; } = true;
/// <summary>
/// Changes whether the server will force it's config on clients that connect. Only affects servers.
/// WE HEAVILY RECOMMEND TO NEVER DISABLE THIS!
/// </summary>
[LoadingOption(LoadingMode.RemoteOnly)]
public bool serverSyncsConfig { get; internal set; } = true;
/// <summary>
/// If false allows you to keep your own defined hotkeys instead of synchronising the ones declared for the server.
/// Sections need to be enabled in your local configuration to load hotkeys.
/// This is a client side setting and not affected by server settings.
/// </summary>
[LoadingOption(LoadingMode.LocalOnly)]
public bool serverSyncHotkeys { get; internal set; } = true;
}

Expand Down
Loading