From aa2ff5bab970396a3909a3d8f91b150bd047dc8f Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 1 Jun 2019 02:48:21 -0400 Subject: [PATCH] Re-enable SMAPI Reflection checks and Updated SGame for Game loader Synching --- .../KeyButton.cs | 54 ++++++++-------- .../ModConfig.cs | 8 +-- .../ModEntry.cs | 8 --- .../VirtualToggle.cs | 30 +++++---- .../Framework/ModHelpers/ReflectionHelper.cs | 28 ++++---- .../RewriteFacades/ItemGrabMenuMethods.cs | 17 +++++ src/StardewModdingAPI/Framework/SGame.cs | 64 +++++++++++-------- .../Metadata/InstructionMetadata.cs | 3 +- src/StardewModdingAPI/SMainActivity.cs | 22 +++---- .../StardewModdingAPI.csproj | 1 + 10 files changed, 127 insertions(+), 108 deletions(-) create mode 100644 src/StardewModdingAPI/Framework/RewriteFacades/ItemGrabMenuMethods.cs diff --git a/src/StardewModdingAPI.Mods.VirtualKeyboard/KeyButton.cs b/src/StardewModdingAPI.Mods.VirtualKeyboard/KeyButton.cs index b07f1b2c..6d1ec5fd 100644 --- a/src/StardewModdingAPI.Mods.VirtualKeyboard/KeyButton.cs +++ b/src/StardewModdingAPI.Mods.VirtualKeyboard/KeyButton.cs @@ -16,10 +16,15 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard private readonly Rectangle buttonRectangle; private readonly int padding; - private readonly IReflectedMethod RaiseButtonPressed; - private readonly IReflectedMethod RaiseButtonReleased; - private readonly IReflectedMethod Legacy_KeyPressed; - private readonly IReflectedMethod Legacy_KeyReleased; + private object buttonPressed; + private object buttonReleased; + private object legacyButtonPressed; + private object legacyButtonReleased; + + private readonly MethodBase RaiseButtonPressed; + private readonly MethodBase RaiseButtonReleased; + private readonly MethodBase Legacy_KeyPressed; + private readonly MethodBase Legacy_KeyReleased; private readonly SButton button; private readonly float transparency; @@ -46,26 +51,26 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard helper.Events.Input.ButtonPressed += this.EventInputButtonPressed; //TODO - //Use C# Reflection and re-enable SMAPI IReflected checks + //re-enable SMAPI IReflected checks MainActivity activity = this.helper.Reflection.GetField(typeof(MainActivity), "instance").GetValue(); object score = activity.GetType().GetField("core", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(activity); object eventManager = score.GetType().GetField("EventManager", BindingFlags.Public | BindingFlags.Instance).GetValue(score); - object buttonPressed = eventManager.GetType().GetField("ButtonPressed", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); - object buttonReleased = eventManager.GetType().GetField("ButtonReleased", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); + this.buttonPressed = eventManager.GetType().GetField("ButtonPressed", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); + this.buttonReleased = eventManager.GetType().GetField("ButtonReleased", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); - object legacyButtonPressed = eventManager.GetType().GetField("Legacy_KeyPressed", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); - object legacyButtonReleased = eventManager.GetType().GetField("Legacy_KeyReleased", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); + this.legacyButtonPressed = eventManager.GetType().GetField("Legacy_KeyPressed", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); + this.legacyButtonReleased = eventManager.GetType().GetField("Legacy_KeyReleased", BindingFlags.Public | BindingFlags.Instance).GetValue(eventManager); - this.RaiseButtonPressed = this.helper.Reflection.GetMethod(buttonPressed, "Raise"); - this.RaiseButtonReleased = this.helper.Reflection.GetMethod(buttonReleased, "Raise"); + this.RaiseButtonPressed = this.buttonPressed.GetType().GetMethod("Raise", BindingFlags.Public | BindingFlags.Instance); + this.RaiseButtonReleased = this.buttonReleased.GetType().GetMethod("Raise", BindingFlags.Public | BindingFlags.Instance); - this.Legacy_KeyPressed = this.helper.Reflection.GetMethod(legacyButtonPressed, "Raise"); - this.Legacy_KeyReleased = this.helper.Reflection.GetMethod(legacyButtonReleased, "Raise"); + this.Legacy_KeyPressed = this.legacyButtonPressed.GetType().GetMethod("Raise", BindingFlags.Public | BindingFlags.Instance); + this.Legacy_KeyReleased = this.legacyButtonReleased.GetType().GetMethod("Raise", BindingFlags.Public | BindingFlags.Instance); } - private bool shouldTrigger(Vector2 point) + private bool shouldTrigger() { int x1 = Mouse.GetState().X / (int)Game1.NativeZoomLevel; int y1 = Mouse.GetState().Y / (int)Game1.NativeZoomLevel; @@ -82,22 +87,18 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard { return; } - Vector2 point = e.Cursor.ScreenPixels; - if (this.shouldTrigger(point)) + if (this.shouldTrigger()) { object inputState = e.GetType().GetField("InputState", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(e); - + object buttonPressedEventArgs = Activator.CreateInstance(typeof(ButtonPressedEventArgs), BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this.button, e.Cursor, inputState }, null); EventArgsKeyPressed eventArgsKey = new EventArgsKeyPressed((Keys)this.button); try { this.raisingPressed = true; - //METHODBASE.INVOKE Method - //this.RaiseButtonPressed.Invoke("What goes here???", new object[] { buttonPressedEventArgs }); - - this.RaiseButtonPressed.Invoke(new object[] { buttonPressedEventArgs }); - this.Legacy_KeyPressed.Invoke(new object[] { eventArgsKey }); + this.RaiseButtonPressed.Invoke(this.buttonPressed, new object[] { buttonPressedEventArgs }); + this.Legacy_KeyPressed.Invoke(this.legacyButtonPressed, new object[] { eventArgsKey }); } finally { @@ -112,8 +113,7 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard { return; } - Vector2 point = e.Cursor.ScreenPixels; - if (this.shouldTrigger(point)) + if (this.shouldTrigger()) { object inputState = this.helper.Reflection.GetField(e, "InputState").GetValue(); object buttonReleasedEventArgs = Activator.CreateInstance(typeof(ButtonReleasedEventArgs), BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this.button, e.Cursor, inputState }, null); @@ -121,8 +121,8 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard try { this.raisingReleased = true; - this.RaiseButtonReleased.Invoke(new object[] { buttonReleasedEventArgs }); - this.Legacy_KeyReleased.Invoke(new object[] { eventArgsKeyReleased }); + this.RaiseButtonReleased.Invoke(this.buttonReleased, new object[] { buttonReleasedEventArgs }); + this.Legacy_KeyReleased.Invoke(this.legacyButtonReleased, new object[] { eventArgsKeyReleased }); } finally { @@ -136,7 +136,7 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard /// The event arguments. private void OnRenderingHud(object sender, EventArgs e) { - if (!Game1.eventUp && !this.hidden) + if (!Game1.eventUp && !this.hidden && Game1.activeClickableMenu is GameMenu == false) { IClickableMenu.drawButtonWithText(Game1.spriteBatch, Game1.smallFont, this.button.ToString(), this.buttonRectangle.X, this.buttonRectangle.Y, this.buttonRectangle.Width, this.buttonRectangle.Height, Color.BurlyWood * this.transparency); } diff --git a/src/StardewModdingAPI.Mods.VirtualKeyboard/ModConfig.cs b/src/StardewModdingAPI.Mods.VirtualKeyboard/ModConfig.cs index 79cbd0d2..7076c6dc 100644 --- a/src/StardewModdingAPI.Mods.VirtualKeyboard/ModConfig.cs +++ b/src/StardewModdingAPI.Mods.VirtualKeyboard/ModConfig.cs @@ -10,10 +10,10 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard class ModConfig { public VirtualButton[] buttons { get; set; } = new VirtualButton[] { - new VirtualButton(SButton.Q, new Rect(192, 125, 90, 90, 6), 0.5f), - new VirtualButton(SButton.I, new Rect(288, 125, 90, 90, 6), 0.5f), - new VirtualButton(SButton.O, new Rect(384, 125, 90, 90, 6), 0.5f), - new VirtualButton(SButton.P, new Rect(480, 125, 90, 90, 6), 0.5f) + new VirtualButton(SButton.Q, new Rect(192, 150, 90, 90, 6), 0.5f), + new VirtualButton(SButton.I, new Rect(288, 150, 90, 90, 6), 0.5f), + new VirtualButton(SButton.O, new Rect(384, 150, 90, 90, 6), 0.5f), + new VirtualButton(SButton.P, new Rect(480, 150, 90, 90, 6), 0.5f) }; internal class VirtualButton { diff --git a/src/StardewModdingAPI.Mods.VirtualKeyboard/ModEntry.cs b/src/StardewModdingAPI.Mods.VirtualKeyboard/ModEntry.cs index 1aaf1db6..af506b4c 100644 --- a/src/StardewModdingAPI.Mods.VirtualKeyboard/ModEntry.cs +++ b/src/StardewModdingAPI.Mods.VirtualKeyboard/ModEntry.cs @@ -8,17 +8,9 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard { public class ModEntry : Mod { - //private List keyboard = new List(); - //private ModConfig modConfig; public override void Entry(IModHelper helper) { VirtualToggle virtualToggle = new VirtualToggle(helper, this.Monitor); - //this.modConfig = helper.ReadConfig(); - //for (int i = 0; i < this.modConfig.buttons.Length; i++) - //{ - // this.keyboard.Add(new KeyButton(helper, this.modConfig.buttons[i], this.Monitor)); - //} - //helper.WriteConfig(this.modConfig); } } } diff --git a/src/StardewModdingAPI.Mods.VirtualKeyboard/VirtualToggle.cs b/src/StardewModdingAPI.Mods.VirtualKeyboard/VirtualToggle.cs index 0e21503c..b563d1b7 100644 --- a/src/StardewModdingAPI.Mods.VirtualKeyboard/VirtualToggle.cs +++ b/src/StardewModdingAPI.Mods.VirtualKeyboard/VirtualToggle.cs @@ -11,7 +11,7 @@ using StardewValley.Mobile; namespace StardewModdingAPI.Mods.VirtualKeyboard { - class VirtualToggle + class VirtualToggle : IClickableMenu { private readonly IModHelper helper; private readonly IMonitor Monitor; @@ -46,19 +46,24 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard { if (!this.enabled && this.shouldTrigger()) { - this.enabled = true; - foreach (var keys in this.keyboard) - { - keys.hidden = false; - } + this.hiddenKeys(true, false); } else if (this.enabled && this.shouldTrigger()) { - this.enabled = false; - foreach (var keys in this.keyboard) + this.hiddenKeys(false, true); + if (Game1.activeClickableMenu is IClickableMenu menu) { - keys.hidden = true; - } + menu.exitThisMenu(); + } + } + } + + private void hiddenKeys(bool enabled, bool hidden) + { + this.enabled = enabled; + foreach (var keys in this.keyboard) + { + keys.hidden = hidden; } } @@ -68,6 +73,7 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard int y1 = Mouse.GetState().Y / (int)Game1.NativeZoomLevel; if (this.virtualToggleButton.containsPoint(x1, y1)) { + Toolbar.toolbarPressed = true; return true; } return false; @@ -89,8 +95,8 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard { scale = 0.5f; } - if(!Game1.eventUp) - this.virtualToggleButton.draw(Game1.spriteBatch, Color.White * scale, 0f); + if(!Game1.eventUp || Game1.activeClickableMenu is GameMenu == false) + this.virtualToggleButton.draw(Game1.spriteBatch, Color.White * scale, 0.000001f); } } } diff --git a/src/StardewModdingAPI/Framework/ModHelpers/ReflectionHelper.cs b/src/StardewModdingAPI/Framework/ModHelpers/ReflectionHelper.cs index e66f2cb0..0ce72a9e 100644 --- a/src/StardewModdingAPI/Framework/ModHelpers/ReflectionHelper.cs +++ b/src/StardewModdingAPI/Framework/ModHelpers/ReflectionHelper.cs @@ -39,10 +39,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// Whether to throw an exception if the field is not found. public IReflectedField GetField(object obj, string name, bool required = true) { - //return this.AssertAccessAllowed( - // this.Reflector.GetField(obj, name, required) - //); - return this.Reflector.GetField(obj, name, required); + return this.AssertAccessAllowed( + this.Reflector.GetField(obj, name, required) + ); } /// Get a static field. @@ -52,10 +51,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// Whether to throw an exception if the field is not found. public IReflectedField GetField(Type type, string name, bool required = true) { - //return this.AssertAccessAllowed( - // this.Reflector.GetField(type, name, required) - //); - return this.Reflector.GetField(type, name, required); + return this.AssertAccessAllowed( + this.Reflector.GetField(type, name, required) + ); } /// Get an instance property. @@ -88,10 +86,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// Whether to throw an exception if the field is not found. public IReflectedMethod GetMethod(object obj, string name, bool required = true) { - //return this.AssertAccessAllowed( - // this.Reflector.GetMethod(obj, name, required) - //); - return this.Reflector.GetMethod(obj, name, required); + return this.AssertAccessAllowed( + this.Reflector.GetMethod(obj, name, required) + ); } /// Get a static method. @@ -100,10 +97,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// Whether to throw an exception if the field is not found. public IReflectedMethod GetMethod(Type type, string name, bool required = true) { - //return this.AssertAccessAllowed( - // this.Reflector.GetMethod(type, name, required) - //); - return this.Reflector.GetMethod(type, name, required); + return this.AssertAccessAllowed( + this.Reflector.GetMethod(type, name, required) + ); } diff --git a/src/StardewModdingAPI/Framework/RewriteFacades/ItemGrabMenuMethods.cs b/src/StardewModdingAPI/Framework/RewriteFacades/ItemGrabMenuMethods.cs new file mode 100644 index 00000000..7129625b --- /dev/null +++ b/src/StardewModdingAPI/Framework/RewriteFacades/ItemGrabMenuMethods.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using StardewValley; +using StardewValley.Menus; + +namespace StardewModdingAPI.Framework.RewriteFacades +{ + public class ItemGrabMenuMethods : ItemGrabMenu + { + public ItemGrabMenuMethods(IList inventory, bool reverseGrab, bool showReceivingMenu, InventoryMenu.highlightThisItem highlightFunction, behaviorOnItemSelect behaviorOnItemSelectFunction, string message, behaviorOnItemSelect behaviorOnItemGrab = null, bool snapToBottom = false, bool canBeExitedWithKey = false, bool playRightClickSound = true, bool allowRightClick = true, bool showOrganizeButton = false, int source = 0, Item sourceItem = null, int whichSpecialButton = -1, object specialObject = null) + : base(inventory, reverseGrab, showReceivingMenu, highlightFunction, behaviorOnItemSelectFunction, message, behaviorOnItemGrab, snapToBottom,canBeExitedWithKey, playRightClickSound, allowRightClick, showOrganizeButton, source, null, -1, null, -1, 3, null, true, null, false, null) + { } + + public ItemGrabMenuMethods(IList inventory, object context = null) + : base(inventory) { } + + } +} diff --git a/src/StardewModdingAPI/Framework/SGame.cs b/src/StardewModdingAPI/Framework/SGame.cs index 5e43d6bb..bc581a9f 100644 --- a/src/StardewModdingAPI/Framework/SGame.cs +++ b/src/StardewModdingAPI/Framework/SGame.cs @@ -291,38 +291,46 @@ namespace StardewModdingAPI.Framework // Run async tasks synchronously to avoid issues due to mod events triggering // concurrently with game code. - //bool saveParsed = false; - //if (Game1.currentLoader != null) - //{ - // this.Monitor.Log("Game loader synchronising...", LogLevel.Trace); - // while (Game1.currentLoader?.MoveNext() == true) - // { - // // raise load stage changed - // switch (Game1.currentLoader.Current) - // { - // case 20 when (!saveParsed && SaveGame.loaded != null): - // saveParsed = true; - // this.OnLoadStageChanged(LoadStage.SaveParsed); - // break; + bool saveParsed = false; + if (Game1.currentLoader != null) + { + this.Monitor.Log("Game loader synchronising...", LogLevel.Trace); + while (Game1.currentLoader?.MoveNext() == true) + { + // raise load stage changed + switch (Game1.currentLoader.Current) + { + case 1: + break; + case 24: + return; - // case 36: - // this.OnLoadStageChanged(LoadStage.SaveLoadedBasicInfo); - // break; + case 20: + if (!saveParsed && SaveGame.loaded != null) + { + saveParsed = true; + this.OnLoadStageChanged(LoadStage.SaveParsed); + } + return; - // case 50: - // this.OnLoadStageChanged(LoadStage.SaveLoadedLocations); - // break; + case 36: + this.OnLoadStageChanged(LoadStage.SaveLoadedBasicInfo); + break; - // default: - // if (Game1.gameMode == Game1.playingGameMode) - // this.OnLoadStageChanged(LoadStage.Preloaded); - // break; - // } - // } + case 50: + this.OnLoadStageChanged(LoadStage.SaveLoadedLocations); + break; - // Game1.currentLoader = null; - // this.Monitor.Log("Game loader done.", LogLevel.Trace); - //} + default: + if (Game1.gameMode == Game1.playingGameMode) + this.OnLoadStageChanged(LoadStage.Preloaded); + break; + } + } + + Game1.currentLoader = null; + this.Monitor.Log("Game loader done.", LogLevel.Trace); + } if (Game1._newDayTask?.Status == TaskStatus.Created) { this.Monitor.Log("New day task synchronising...", LogLevel.Trace); diff --git a/src/StardewModdingAPI/Metadata/InstructionMetadata.cs b/src/StardewModdingAPI/Metadata/InstructionMetadata.cs index 9f29aae2..5f82291e 100644 --- a/src/StardewModdingAPI/Metadata/InstructionMetadata.cs +++ b/src/StardewModdingAPI/Metadata/InstructionMetadata.cs @@ -54,10 +54,11 @@ namespace StardewModdingAPI.Metadata //Field Rewriters yield return new FieldReplaceRewriter(typeof(ItemGrabMenu), "context", "specialObject"); + yield return new FieldReplaceRewriter(typeof(GameLocation), "isGreenhouse", "isFarm"); // rewrite for Stardew Valley 1.3 yield return new StaticFieldToConstantRewriter(typeof(Game1), "tileSize", Game1.tileSize); - yield return new TypeReferenceRewriter("System.Collections.Generic.IList`1", typeof(List)); + //yield return new TypeReferenceRewriter("System.Collections.Generic.IList`1", typeof(List)); yield return new FieldToPropertyRewriter(typeof(Game1), "player"); yield return new FieldToPropertyRewriter(typeof(Game1), "currentLocation"); yield return new FieldToPropertyRewriter(typeof(Character), "currentLocation"); diff --git a/src/StardewModdingAPI/SMainActivity.cs b/src/StardewModdingAPI/SMainActivity.cs index f342c070..1d2c3789 100644 --- a/src/StardewModdingAPI/SMainActivity.cs +++ b/src/StardewModdingAPI/SMainActivity.cs @@ -26,6 +26,7 @@ using StardewModdingAPI.Framework; using StardewValley; using Android.Widget; using StardewModdingAPI.Framework.ModLoading; +using System.Reflection; namespace StardewModdingAPI { @@ -174,8 +175,7 @@ namespace StardewModdingAPI protected override void OnCreate(Bundle bundle) { instance = this; - AppCenter.Start("5677d40e-f7b3-4ccb-bee4-5dca56d86ade", typeof(Analytics), typeof(Crashes)); - this.RequestWindowFeature(WindowFeatures.NoTitle); + base.RequestWindowFeature(WindowFeatures.NoTitle); if (Build.VERSION.SdkInt >= BuildVersionCodes.P) { this.Window.Attributes.LayoutInDisplayCutoutMode = LayoutInDisplayCutoutMode.ShortEdges; @@ -186,7 +186,8 @@ namespace StardewModdingAPI this._wakeLock = powerManager.NewWakeLock(WakeLockFlags.Full, "StardewWakeLock"); this._wakeLock.Acquire(); base.OnCreate(bundle); - this.CheckAppPermissions(); + //this.CheckAppPermissions(); + this.OnCreatePartTwo(); } public void OnCreatePartTwo() @@ -204,11 +205,7 @@ namespace StardewModdingAPI this.SetContentView((View)this.core.GameInstance.Services.GetService(typeof(View))); this.core.GameInstance.Run(); - //this._game1 = new Game1(); - //SetContentView((View)_game1.Services.GetService(typeof(View))); - //_game1.Run(); - - this.CheckForValidLicence(); + this.CheckUsingServerManagedPolicy(); } protected override void OnResume() @@ -735,7 +732,7 @@ namespace StardewModdingAPI public void CheckAppPermissions() { this.LogPermissions(); - if (this.HasPermissions) + if (base.HasPermissions) { //("MainActivity.CheckAppPermissions permissions already granted."); this.OnCreatePartTwo(); @@ -864,7 +861,7 @@ namespace StardewModdingAPI public void Allow(PolicyResponse response) { //("MainActivity.Allow response:" + response.ToString()); - this.CheckToDownloadExpansion(); + typeof(MainActivity).GetMethod("CheckToDownloadExpansion", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(this, null); } public void DontAllow(PolicyResponse response) @@ -876,7 +873,7 @@ namespace StardewModdingAPI this.WaitThenCheckForValidLicence(); break; case PolicyResponse.Licensed: - this.CheckToDownloadExpansion(); + typeof(MainActivity).GetMethod("CheckToDownloadExpansion", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(this, null); break; } } @@ -884,7 +881,7 @@ namespace StardewModdingAPI private async void WaitThenCheckForValidLicence() { await Task.Delay(TimeSpan.FromSeconds(30.0)); - this.CheckForValidLicence(); + this.CheckUsingServerManagedPolicy(); } public void ApplicationError(LicenseCheckerErrorCode errorCode) @@ -929,6 +926,7 @@ namespace StardewModdingAPI private void OnExpansionDowloaded() { + this.OnCreatePartTwo(); if (this.core.GameInstance != null) { this.core.GameInstance.CreateMusicWaveBank(); diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj index 8e21b3a2..018f1540 100644 --- a/src/StardewModdingAPI/StardewModdingAPI.csproj +++ b/src/StardewModdingAPI/StardewModdingAPI.csproj @@ -295,6 +295,7 @@ +