Skip to content

Commit

Permalink
[RELEASE] SiraUtil 2.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Auros committed Nov 7, 2020
1 parent 88de482 commit 2b1c544
Show file tree
Hide file tree
Showing 16 changed files with 136 additions and 104 deletions.
3 changes: 3 additions & 0 deletions SiraUtil/Accessors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ namespace SiraUtil
{
public static class Accessors
{
/// <summary>
/// Gets a container from a MonoInstaller
/// </summary>
public static PropertyAccessor<MonoInstallerBase, DiContainer>.Getter GetDiContainer = PropertyAccessor<MonoInstallerBase, DiContainer>.GetGetter("Container");

internal static FieldAccessor<SaberTrail, Color>.Accessor TrailColor = FieldAccessor<SaberTrail, Color>.GetAccessor("_color");
Expand Down
9 changes: 5 additions & 4 deletions SiraUtil/Config.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using SemVer;
using System;
using Polyglot;
using UnityEngine;
using SiraUtil.Converters;
using Version = SemVer.Version;
using System.Collections.Generic;
using IPA.Config.Stores.Converters;
using IPA.Config.Stores.Attributes;
Expand All @@ -19,8 +20,8 @@ public class Config
[NonNullable]
public virtual SongControlOptions SongControl { get; set; } = new SongControlOptions();

[NonNullable]
public virtual LocalizationOptions Localization { get; set; } = new LocalizationOptions();
[Obsolete("SiraUtil no longer handles the loading of localization sheets. You can now optionally request an ILocalizer with an ID of SIRA.Localizer in a container to get the localizer component from SiraLocalizer (separate mod).")]
public virtual LocalizationOptions Localization { get; set; } = null;

public class SongControlOptions
{
Expand Down Expand Up @@ -49,7 +50,7 @@ public class FPFCToggleOptions

public class LocalizationOptions
{
public virtual bool Enabled { get; set; } = true;
public virtual bool Enabled { get; set; } = false;

[NonNullable, UseConverter(typeof(DictionaryConverter<LocalizationSource>))]
public virtual Dictionary<string, LocalizationSource> Sources { get; set; } = new Dictionary<string, LocalizationSource>();
Expand Down
36 changes: 36 additions & 0 deletions SiraUtil/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,44 @@ public static U Upgrade<T, U>(this T monoBehaviour) where U : T where T : MonoBe
return upgradedMonoBehaviour;
}

/// <summary>
/// Gets the localized key of a string from Polyglot, if not found then returns specified alternative.
/// </summary>
/// <param name="key">The key of the string in Polyglot.</param>
/// <param name="or">The string to be used if the key could not be found.</param>
/// <returns></returns>
public static string LocalizationGetOr(this string key, string or)
{
var localized = Localization.Get(key);
return string.IsNullOrWhiteSpace(localized) || key == localized ? or : localized;
}

/// <summary>
/// Creates a new component on a new GameObject
/// </summary>
/// <param name="name">The name of the GameObject.</param>
/// <returns></returns>
public static ScopeConcreteIdArgConditionCopyNonLazyBinder FromNewComponentOnNewGameObject(this FromBinder binder, string name = "GameObject")
{
return binder.FromNewComponentOn(new GameObject(name));
}

/// <summary>
/// Creates a new component on a new GameObject
/// </summary>
/// <param name="name">The name of the GameObject.</param>
/// <returns></returns>
public static ConditionCopyNonLazyBinder FromNewComponentOnNewGameObject(this FactoryFromBinderBase binder, string name = "GameObject")
{
return binder.FromNewComponentOn(new GameObject(name));
}

/// <summary>
/// Binds a <see cref="ViewController"/> into the Container. This creates the view controller, repairs its dependencies, and adds it to the container.
/// </summary>
/// <typeparam name="T">The type of the ViewController.</typeparam>
/// <param name="Container">The Container to install this ViewController into.</param>
/// <param name="active">Whether or not to enable it after its binded.</param>
public static void BindViewController<T>(this DiContainer Container, bool active = false) where T : ViewController
{
T vc = new GameObject(typeof(T).Name, typeof(VRGraphicRaycaster), typeof(CurvedCanvasSettings), typeof(CanvasGroup), typeof(T)).GetComponent<T>();
Expand All @@ -82,6 +104,11 @@ public static void BindViewController<T>(this DiContainer Container, bool active
Container.BindInstance(vc).AsSingle();
}

/// <summary>
/// Binds a <see cref="FlowCoordinator"/> into the Container. This creates the flow coordinator, repairs its dependencies, and adds it to the container.
/// </summary>
/// <typeparam name="T">The type of the FlowCoordinator.</typeparam>
/// <param name="Container">The Container to install this FlowCoordinator into.</param>
public static void BindFlowCoordinator<T>(this DiContainer Container) where T : FlowCoordinator
{
var inputSystem = Container.Resolve<BaseInputModule>();
Expand Down Expand Up @@ -165,6 +192,15 @@ public static void ChangeColor(this Saber saber, Color color)
}
}

/// <summary>
/// Change the color of a saber.
/// </summary>
/// <param name="color">The color to change the saber to.</param>
/// <param name="smc">The model controller of the saber.</param>
/// <param name="tintColor">The tint color of the new color.</param>
/// <param name="setSaberGlowColors">The glow color groups of the saber.</param>
/// <param name="setSaberFakeGlowColors">The fake glow color groups of the saber.</param>
/// <param name="light">The light of the saber.</param>
public static void ChangeColor(this Saber _, Color color, SaberModelController smc, Color tintColor, SetSaberGlowColor[] setSaberGlowColors, SetSaberFakeGlowColor[] setSaberFakeGlowColors, TubeBloomPrePassLight light)
{
Accessors.TrailColor(ref Accessors.SaberTrail(ref smc)) = (color * tintColor).linear;
Expand Down
5 changes: 1 addition & 4 deletions SiraUtil/Installers/SiraInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ public override void InstallBindings()
Container.Bind<FPFCToggle>().FromNewComponentOnNewGameObject(nameof(FPFCToggle)).AsSingle().NonLazy();
}
Container.Bind(typeof(IInitializable), typeof(IDisposable), typeof(WebClient)).To<WebClient>().AsSingle();
if (_config.Localization.Enabled)
{
Container.BindInterfacesAndSelfTo<Localizer>().AsSingle();
}
Container.BindInterfacesAndSelfTo<Localizer>().AsSingle();
Container.Bind<Submission.Data>().AsSingle();

// Make Zenject know this is a list
Expand Down
18 changes: 7 additions & 11 deletions SiraUtil/Sabers/SaberBindPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using SiraUtil.Interfaces;
using System.Reflection.Emit;
using System.Collections.Generic;
using System;

namespace SiraUtil.Sabers
{
Expand Down Expand Up @@ -76,24 +77,19 @@ private static SaberProvider GetProvider(DiContainer container)
[HarmonyPatch(typeof(GameplayCoreInstaller), "InstallBindings")]
public class GameplayCoreClashCheckerSwap
{
private static readonly MethodInfo _rootMethod = typeof(DiContainer).GetMethod("Bind", Array.Empty<Type>());
private static readonly MethodInfo _clashAttacher = SymbolExtensions.GetMethodInfo(() => ClashAttacher(null));
private static readonly MethodInfo _originalMethod = _rootMethod.MakeGenericMethod(new Type[] { typeof(SaberClashChecker) });

public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
int runIns = 0;
for (int i = codes.Count - 1; i > 15; i--)
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Pop && codes[i - 1].opcode == OpCodes.Callvirt &&
codes[i - 2].opcode == OpCodes.Callvirt && codes[i - 3].opcode == OpCodes.Call &&
codes[i - 4].opcode == OpCodes.Ldarg_0)
if (codes[i].Calls(_originalMethod))
{
runIns++;
if (runIns == 2)
{
codes.Insert(i - 1, new CodeInstruction(OpCodes.Callvirt, _clashAttacher));
break;
}
codes.Insert(i + 1, new CodeInstruction(OpCodes.Callvirt, _clashAttacher));
break;
}
}
return codes.AsEnumerable();
Expand Down
3 changes: 1 addition & 2 deletions SiraUtil/Sabers/SiraSaberEffectInstaller.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using Zenject;
using SiraUtil.Services;

namespace SiraUtil.Sabers
{
public class SiraSaberEffectInstaller : Installer
{
public override void InstallBindings()
{
//Container.BindInterfacesAndSelfTo<SiraSaberEffectManager>().AsSingle();
// Dummy Class
}
}
}
11 changes: 10 additions & 1 deletion SiraUtil/Services/SaberProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public bool IsSafe(bool callback = true)
}

/// <summary>
/// Get an instance of the current saber model. This CAN be null! Only use this when you know the model is present. You can subscribe to <see cref="ControllerReady"/> and then call <see cref="IsSafe(bool)"/> to ensure that you get the model. SiraSaber's handle this automatically.
/// Get an instance of the current saber model. This CAN be null! Only use this when you know the model is present. Should use <see cref="GetModel(Action{SaberModelController})"/> or <see cref="GetModel{T}(Action{T})"/> to hook into the callback so you know when the saber model is ready.
/// </summary>
/// <returns>The current saber model.</returns>
public SaberModelController GetModel()
Expand All @@ -81,11 +81,20 @@ public SaberModelController GetModel()
return smc;
}

/// <summary>
/// Get the current saber model.
/// </summary>
/// <param name="callback">The callback sent when the model is ready.</param>
public void GetModel(Action<SaberModelController> callback)
{
GetModel<SaberModelController>(callback);
}

/// <summary>
/// Get the current saber model.
/// </summary>
/// <typeparam name="T">The type of the <seealso cref="SaberModelController"/>of the model.</typeparam>
/// <param name="callback">The callback sent when the model is ready.</param>
public void GetModel<T>(Action<T> callback) where T : SaberModelController
{
if (_gameCoreInstalling)
Expand Down
26 changes: 19 additions & 7 deletions SiraUtil/Services/Submission.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,33 @@ public sealed class Submission : IDisposable
{
private readonly Data _data;
private readonly List<Ticket> _tickets = new List<Ticket>();
private readonly GameplayCoreSceneSetupData _gameplayCoreSceneSetupData;

internal Submission(Data data, GameplayCoreSceneSetupData gameplayCoreSceneSetupData)
internal Submission(Data data)
{
_data = data;
_gameplayCoreSceneSetupData = gameplayCoreSceneSetupData;
}

public void Dispose()
{
var disabled = _tickets.Count > 0;
if (disabled)
{
//_gameplayCoreSceneSetupData.SetField("practiceSettings", new SiraPracticeSettings(_gameplayCoreSceneSetupData.practiceSettings));
}
_data.Set(disabled, _tickets.ToArray());
}

/// <summary>
/// Get all the currently active tickets.
/// </summary>
/// <returns>All the currently active tickets.</returns>
public Ticket[] Tickets()
{
return _tickets.Select(x => x.Copy()).ToArray();
}

/// <summary>
/// Disables score submission for the currently played level.
/// </summary>
/// <param name="source">The name of the entity that is disabling score submission.</param>
/// <param name="subsource">A secondary source that is disabling score submission. Use this to be more specific about why submission is being disabled (ex. specific modifier)</param>
/// <returns>A ticket which can be used to disable the disabling of score submission.</returns>
public Ticket DisableScoreSubmission(string source, string subsource = null)
{
var ticket = _tickets.FirstOrDefault(x => x.Source == source);
Expand All @@ -54,11 +58,19 @@ public Ticket DisableScoreSubmission(string source, string subsource = null)
return ticket;
}

/// <summary>
/// Reenables score submission for a ticket.
/// </summary>
/// <param name="ticket"></param>
public void Remove(Ticket ticket)
{
_tickets.Remove(ticket);
}

/// <summary>
/// Reenables score submission from a source.
/// </summary>
/// <param name="source"></param>
public void Remove(string source)
{
Remove(_tickets.FirstOrDefault(x => x.Source == source && x.Assembly == Assembly.GetCallingAssembly()));
Expand Down
2 changes: 1 addition & 1 deletion SiraUtil/Tools/MultiSongControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ public void Tick()
}
}
}
}
}
2 changes: 1 addition & 1 deletion SiraUtil/Tools/SiraLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ public void Null(object obj)
Logger?.Info(obj != null ? $"{obj.GetType().Name} is not null." : $"Object is null");
}
}
}
}
20 changes: 0 additions & 20 deletions SiraUtil/Tools/SongControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,5 @@ public void Dispose()
_pauseController.didPauseEvent -= OnPause;
_pauseController.didResumeEvent -= OnResume;
}

public void Exit()
{

}

public void Play()
{

}

public void Pause()
{

}

public void Restart()
{

}
}
}
38 changes: 24 additions & 14 deletions SiraUtil/Utilities.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using HMUI;
using System;
using Zenject;
using System.IO;
using HarmonyLib;
using UnityEngine;
Expand All @@ -18,25 +16,21 @@ public static class Utilities
{
public const string ASSERTHIT = "(Nice Assert Hit, Ding Dong)";

/// <summary>
/// A simple Task which awaits for 100ms. Mainly used to make UI feel more "natural" and for testing purposes.
/// </summary>
public static Task PauseChamp => AwaitSleep(100);

/// <summary>
/// Returns a task which awaits for a time in milliseconds.
/// </summary>
/// <param name="ms">The time in milliseconds to await for.</param>
/// <returns></returns>
public static Task AwaitSleep(int ms)
{
return Task.Run(() => Thread.Sleep(ms));
}

[Obsolete("This will be removed very soon. Please don't let Zenject instantiate the view controller. Create the View Controller manually (for example, through BSML).")]
public static void SetupViewController(InjectContext context, object source)
{
if (source is ViewController viewController)
{
viewController.rectTransform.anchorMin = new Vector2(0f, 0f);
viewController.rectTransform.anchorMax = new Vector2(1f, 1f);
viewController.rectTransform.sizeDelta = new Vector2(0f, 0f);
viewController.rectTransform.anchoredPosition = new Vector2(0f, 0f);
}
}

internal static IEnumerator ChangeColorCoroutine(Saber saber, Color color, float time = 0.05f)
{
if (time != 0)
Expand Down Expand Up @@ -77,6 +71,12 @@ public static bool OpCodeSequence(List<CodeInstruction> codes, List<OpCode> toCh
return true;
}

/// <summary>
/// Gets the Embedded Asset at a specific path in an Assembly.
/// </summary>
/// <param name="assembly">The Assembly that contains the resource.</param>
/// <param name="resource">The path to the resource in the assembly.</param>
/// <returns></returns>
public static string GetResourceContent(Assembly assembly, string resource)
{
using (Stream stream = assembly.GetManifestResourceStream(resource))
Expand All @@ -88,6 +88,9 @@ public static string GetResourceContent(Assembly assembly, string resource)
}
}

/// <summary>
/// Gets an assembly from a path.
/// </summary>
public static void AssemblyFromPath(string inputPath, out Assembly assembly, out string path)
{
string[] parameters = inputPath.Split(':');
Expand All @@ -106,6 +109,13 @@ public static void AssemblyFromPath(string inputPath, out Assembly assembly, out
}
}

/// <summary>
/// Gets the raw resource from an Assembly.
/// </summary>
/// <param name="asm">The assembly that contains the resource.</param>
/// <param name="ResourceName">The path to the resource in the assembly.</param>
/// <param name="ResourceName">The path to the resource in the assembly.</param>
/// <returns></returns>
public static byte[] GetResource(Assembly asm, string ResourceName)
{
Stream stream = asm.GetManifestResourceStream(ResourceName);
Expand Down
Loading

0 comments on commit 2b1c544

Please sign in to comment.