Re-enable SMAPI Reflection checks and Updated SGame for Game loader Synching

This commit is contained in:
Chris 2019-06-01 02:48:21 -04:00 committed by ZaneYork
parent 91b1194901
commit aa2ff5bab9
10 changed files with 127 additions and 108 deletions

View File

@ -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<MainActivity>(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,8 +87,7 @@ 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);
@ -93,11 +97,8 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
{
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<object>(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
/// <param name="e">The event arguments.</param>
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);
}

View File

@ -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
{

View File

@ -8,17 +8,9 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
{
public class ModEntry : Mod
{
//private List<KeyButton> keyboard = new List<KeyButton>();
//private ModConfig modConfig;
public override void Entry(IModHelper helper)
{
VirtualToggle virtualToggle = new VirtualToggle(helper, this.Monitor);
//this.modConfig = helper.ReadConfig<ModConfig>();
//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);
}
}
}

View File

@ -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,28 +46,34 @@ 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;
}
}
private bool shouldTrigger()
{
int x1 = Mouse.GetState().X / (int)Game1.NativeZoomLevel;
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);
}
}
}

View File

@ -39,10 +39,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="required">Whether to throw an exception if the field is not found.</param>
public IReflectedField<TValue> GetField<TValue>(object obj, string name, bool required = true)
{
//return this.AssertAccessAllowed(
// this.Reflector.GetField<TValue>(obj, name, required)
//);
return this.Reflector.GetField<TValue>(obj, name, required);
return this.AssertAccessAllowed(
this.Reflector.GetField<TValue>(obj, name, required)
);
}
/// <summary>Get a static field.</summary>
@ -52,10 +51,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="required">Whether to throw an exception if the field is not found.</param>
public IReflectedField<TValue> GetField<TValue>(Type type, string name, bool required = true)
{
//return this.AssertAccessAllowed(
// this.Reflector.GetField<TValue>(type, name, required)
//);
return this.Reflector.GetField<TValue>(type, name, required);
return this.AssertAccessAllowed(
this.Reflector.GetField<TValue>(type, name, required)
);
}
/// <summary>Get an instance property.</summary>
@ -88,10 +86,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="required">Whether to throw an exception if the field is not found.</param>
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)
);
}
/// <summary>Get a static method.</summary>
@ -100,10 +97,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="required">Whether to throw an exception if the field is not found.</param>
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)
);
}

View File

@ -0,0 +1,17 @@
using System.Collections.Generic;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.Framework.RewriteFacades
{
public class ItemGrabMenuMethods : ItemGrabMenu
{
public ItemGrabMenuMethods(IList<Item> 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<Item> inventory, object context = null)
: base(inventory) { }
}
}

View File

@ -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);

View File

@ -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<int>(typeof(Game1), "tileSize", Game1.tileSize);
yield return new TypeReferenceRewriter("System.Collections.Generic.IList`1<StardewValley.Menus.IClickableMenu>", typeof(List<IClickableMenu>));
//yield return new TypeReferenceRewriter("System.Collections.Generic.IList`1<StardewValley.Menus.IClickableMenu>", typeof(List<IClickableMenu>));
yield return new FieldToPropertyRewriter(typeof(Game1), "player");
yield return new FieldToPropertyRewriter(typeof(Game1), "currentLocation");
yield return new FieldToPropertyRewriter(typeof(Character), "currentLocation");

View File

@ -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();

View File

@ -295,6 +295,7 @@
<Compile Include="Framework\Reflection\ReflectedProperty.cs" />
<Compile Include="Framework\Reflection\Reflector.cs" />
<Compile Include="Framework\RequestExitDelegate.cs" />
<Compile Include="Framework\RewriteFacades\ItemGrabMenuMethods.cs" />
<Compile Include="Framework\RewriteFacades\TextBoxMethods.cs" />
<Compile Include="Framework\RewriteFacades\MapPageMethods.cs" />
<Compile Include="Framework\RewriteFacades\IClickableMenuMethods.cs" />