This repository has been archived on 2025-08-02. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Cryville.EEW.Unity/Assets/Cryville.EEW.Unity/SharedSettings.cs

146 lines
8.1 KiB
C#

using Cryville.EEW.Colors;
using Cryville.EEW.Core;
using Cryville.EEW.Core.Colors;
using Cryville.EEW.FERegion;
using Cryville.EEW.Map;
using Cryville.EEW.Report;
using Cryville.EEW.TTS;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text.Json;
using UnityEngine;
using Color = System.Drawing.Color;
namespace Cryville.EEW.Unity {
sealed class SharedSettings : IRVMGeneratorContext, IMapGeneratorContext, ITTSMessageGeneratorContext {
static SharedSettings s_instance;
public static SharedSettings Instance => s_instance ??= new();
public ISeverityScheme SeverityScheme { get; private set; } = DefaultSeverityScheme.Instance;
public ISeverityColorMapping SeverityColorMapping { get; private set; } = DefaultSeverityColorMapping.Instance;
public bool UseContinuousColor { get; private set; } = true;
public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance);
public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance));
public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black);
public float HillshadeLayerOpacity { get; private set; } = 1;
public TimeSpan NowcastWarningDelayTolerance { get; private set; } = TimeSpan.FromMinutes(60);
public CultureInfo RVMCulture { get; private set; } = SharedCultures.CurrentUICulture;
readonly int _infoLocationSpecificity = 3;
readonly int _ttsLocationSpecificity = 3;
readonly LocationNamer _locationNamer = new() { Namer = new FERegionLongNamer() };
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name, out int specificity) {
specificity = _ttsLocationSpecificity;
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
}
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name) {
int specificity = _infoLocationSpecificity;
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
}
public IReadOnlyCollection<TTSCultureConfig> TTSCultures { get; private set; }
public bool DoIgnoreLanguageVariant { get; private set; }
public TimeZoneInfo OverrideTimeZone { get; private set; }
public bool DoDisplayTimeZone { get; private set; } = true;
public bool DoSwitchBackToHistory { get; private set; } = true;
public IReadOnlyCollection<EventSourceConfig> EventSources { get; private set; }
public string Id { get; private set; }
public byte[] IdBytes { get; } = new byte[32];
public string UnityUserAgent { get; private set; }
public void Init() {
Id = SystemInfo.deviceUniqueIdentifier;
using var hash = SHA256.Create();
hash.ComputeHash(EEW.SharedSettings.Encoding.GetBytes(Id)).CopyTo(IdBytes, 0);
#if UNITY_STANDALONE_WIN
UnityUserAgent = string.Format(
CultureInfo.InvariantCulture,
"{0} CysTerraUnity/{1} (Windows NT {2}; {3})",
EEW.SharedSettings.UserAgent,
Application.version,
Environment.OSVersion.Version,
RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant()
);
#else
#error No Unity User Agent
#endif
var file = new FileInfo(Path.Combine(PlatformConfig.ConfigPath, "config.json"));
if (!file.Exists) {
using var stream1 = file.OpenWrite();
using var writer = new StreamWriter(stream1, EEW.SharedSettings.Encoding);
writer.Write(JsonSerializer.Serialize(Config.Default, ConfigSerializationContext.Default.Config));
}
using var stream = file.OpenRead();
var config = JsonSerializer.Deserialize(stream, ConfigSerializationContext.Default.Config) ?? throw new InvalidOperationException("Null config.");
SeverityScheme = config.SeverityScheme switch {
"Default" => new DefaultSeverityScheme(),
"Legacy" => new LegacySeverityScheme(),
_ => throw new InvalidOperationException("Unknown severity scheme."),
};
SeverityColorMapping = config.ColorScheme switch {
"Default" => new DefaultSeverityColorMapping(config.SeverityColorMappingLuminanceMultiplier),
"SREV" => new SREVSeverityColorMapping(config.SeverityColorMappingLuminanceMultiplier),
"DichromaticYB" => new DichromaticSeverityColorMapping(0.62f, 0.20f, 90, config.SeverityColorMappingLuminanceMultiplier),
"DichromaticRC" => new DichromaticSeverityColorMapping(0.62f, 0.25f, 30, config.SeverityColorMappingLuminanceMultiplier),
"DichromaticPG" => new DichromaticSeverityColorMapping(0.62f, 0.30f, -30, config.SeverityColorMappingLuminanceMultiplier),
"Monochromatic" => new MonochromaticSeverityColorMapping(config.SeverityColorMappingLuminanceMultiplier),
_ => throw new InvalidOperationException("Unknown color scheme."),
};
UseContinuousColor = config.UseContinuousColor;
ColorScheme = config.ColorScheme switch {
"Default" => new SeverityBasedColorScheme(SeverityScheme, DefaultSeverityColorMapping.Instance),
"SREV" => new SREVColorScheme(),
"DichromaticYB" => new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.20f, 90)),
"DichromaticRC" => new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.25f, 30)),
"DichromaticPG" => new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.30f, -30)),
"Monochromatic" => new SeverityBasedColorScheme(SeverityScheme, new MonochromaticSeverityColorMapping()),
_ => throw new InvalidOperationException("Unknown color scheme."),
};
BorderColorScheme = config.ColorScheme switch {
"Default" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, DefaultSeverityColorMapping.SecondaryInstance)),
"SREV" => new WrappedColorScheme(new SREVBorderColorScheme()),
"DichromaticYB" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.20f, 90, 0.75f))),
"DichromaticRC" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.25f, 30, 0.75f))),
"DichromaticPG" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.30f, -30, 0.75f))),
"Monochromatic" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new MonochromaticSeverityColorMapping(0.75f))),
_ => throw new InvalidOperationException("Unknown color scheme."),
};
TextColorScheme = config.ColorScheme switch {
"SREV" => new DefaultTextColorScheme(Color.White, Color.FromArgb(28, 28, 28), 0.555f),
_ => new DefaultTextColorScheme(Color.White, Color.Black),
};
HillshadeLayerOpacity = config.HillshadeLayerOpacity;
_locationNamer.Namer = config.LocationNamer switch {
"FERegionShort" => new FERegionShortNamer(),
_ => new FERegionLongNamer(),
};
if (config.NowcastWarningDelayTolerance is string nowcastWarningDelayTolerance)
NowcastWarningDelayTolerance = TimeSpan.Parse(nowcastWarningDelayTolerance, CultureInfo.InvariantCulture);
OverrideTimeZone = ParseTimeZone(config.OverrideTimeZone);
DoDisplayTimeZone = config.DoDisplayTimeZone;
DoSwitchBackToHistory = config.DoSwitchBackToHistory;
RVMCulture = config.OverrideDisplayCulture is string rvmCulture
? (string.IsNullOrEmpty(rvmCulture) ? SharedCultures.CurrentUICulture : SharedCultures.Get(rvmCulture))
: CultureInfo.InvariantCulture;
TTSCultures = config.TTSCultures ?? new List<TTSCultureConfig> { new(CultureInfo.InvariantCulture) };
DoIgnoreLanguageVariant = config.DoIgnoreLanguageVariant;
EventSources = config.EventSources;
}
TimeZoneInfo ParseTimeZone(string timeZone) {
if (timeZone == null) return null;
if (timeZone == "") return TimeZoneInfo.Local;
return TimeZoneInfo.CreateCustomTimeZone("Custom", TimeSpan.Parse(timeZone, CultureInfo.InvariantCulture), null, null);
}
}
}