Modloader 1.5
1.Settings page 2.Mod compatibility improvement
This commit is contained in:
parent
e511ad28a8
commit
1df4408da0
|
@ -128,6 +128,7 @@ namespace ModLoader
|
||||||
private readonly Mutex _working = new Mutex(false);
|
private readonly Mutex _working = new Mutex(false);
|
||||||
|
|
||||||
public static Activity1 Instance { get; private set; }
|
public static Activity1 Instance { get; private set; }
|
||||||
|
|
||||||
private readonly HttpClient _httpClient = new HttpClient();
|
private readonly HttpClient _httpClient = new HttpClient();
|
||||||
|
|
||||||
private static readonly Dictionary<int, Action> MessageHandler = new Dictionary<int, Action>();
|
private static readonly Dictionary<int, Action> MessageHandler = new Dictionary<int, Action>();
|
||||||
|
@ -150,10 +151,29 @@ namespace ModLoader
|
||||||
protected override void OnCreate(Bundle bundle)
|
protected override void OnCreate(Bundle bundle)
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
Type[] services = { typeof(Analytics), typeof(Crashes) };
|
|
||||||
AppCenter.Start("b8eaba94-d276-4c97-9953-0c91e7357e21", services);
|
|
||||||
base.OnCreate(bundle);
|
base.OnCreate(bundle);
|
||||||
this.RequestWindowFeature(WindowFeatures.NoTitle);
|
this.RequestWindowFeature(WindowFeatures.NoTitle);
|
||||||
|
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N)
|
||||||
|
{
|
||||||
|
StrictMode.SetVmPolicy(new StrictMode.VmPolicy.Builder().Build());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
File errorLog = this.FilesDir.ListFiles().FirstOrDefault(f => f.IsDirectory && f.Name == "error")?.ListFiles().FirstOrDefault(f => f.Name.EndsWith(".dat"));
|
||||||
|
if (errorLog != null)
|
||||||
|
{
|
||||||
|
string errorLogPath = Path.Combine(this.ExternalCacheDir.AbsolutePath, "error.dat");
|
||||||
|
StreamToFile(new FileStream(errorLog.AbsolutePath, FileMode.Open), errorLogPath);
|
||||||
|
ShowConfirmDialog(this, Resource.String.Error, Resource.String.CrashReportMessage, Resource.String.View, Resource.String.Dismiss, () => { OpenTextFile(this, errorLogPath); });
|
||||||
|
}
|
||||||
|
Type[] services = { typeof(Analytics), typeof(Crashes) };
|
||||||
|
AppCenter.Start("b8eaba94-d276-4c97-9953-0c91e7357e21", services);
|
||||||
|
IEnumerable<File> errorLogs = this.FilesDir.ListFiles().FirstOrDefault(f => f.IsDirectory && f.Name == "error")?.ListFiles().ToList().FindAll(f => f.Name.EndsWith(".dat") || f.Name.EndsWith(".throwable"));
|
||||||
|
if (errorLogs != null) foreach (var file in errorLogs) file.Delete();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.P)
|
if (Build.VERSION.SdkInt >= BuildVersionCodes.P)
|
||||||
{
|
{
|
||||||
this.Window.Attributes.LayoutInDisplayCutoutMode = LayoutInDisplayCutoutMode.ShortEdges;
|
this.Window.Attributes.LayoutInDisplayCutoutMode = LayoutInDisplayCutoutMode.ShortEdges;
|
||||||
|
@ -169,13 +189,18 @@ namespace ModLoader
|
||||||
|
|
||||||
private void OnCreatePartTwo()
|
private void OnCreatePartTwo()
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N)
|
if (GetConfig(this, "compatCheck", "true") == "false")
|
||||||
{
|
Constants.CompatCheck = false;
|
||||||
StrictMode.SetVmPolicy(new StrictMode.VmPolicy.Builder().Build());
|
if (GetConfig(this, "upgradeCheck", "true") == "false")
|
||||||
}
|
Constants.UpgradeCheck = false;
|
||||||
|
else
|
||||||
new PgyUpdateManager.Builder().SetForced(false).SetUserCanRetry(true).SetDeleteHistroyApk(true).Register();
|
new PgyUpdateManager.Builder().SetForced(false).SetUserCanRetry(true).SetDeleteHistroyApk(true).Register();
|
||||||
this.InitEnvironment();
|
this.InitEnvironment();
|
||||||
|
this.FindViewById<Button>(Resource.Id.buttonSetting).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
this.StartActivity(typeof(ActivitySetting));
|
||||||
|
};
|
||||||
|
|
||||||
this.FindViewById<Button>(Resource.Id.buttonExtract).Click += (sender, args) =>
|
this.FindViewById<Button>(Resource.Id.buttonExtract).Click += (sender, args) =>
|
||||||
{
|
{
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
|
@ -251,6 +276,8 @@ namespace ModLoader
|
||||||
FileAccess.Write, FileShare.Read);
|
FileAccess.Write, FileShare.Read);
|
||||||
monoFramework.Write(stream);
|
monoFramework.Write(stream);
|
||||||
stream.Close();
|
stream.Close();
|
||||||
|
Stream stream2 = this.Resources.OpenRawResource(Resource.Raw.SMDroidFiles);
|
||||||
|
ZipHelper.UnZip(stream2, Constants.GamePath);
|
||||||
dialog.Dismiss();
|
dialog.Dismiss();
|
||||||
MakeToast(this, this.Resources.GetText(Resource.String.GeneratedMessage),
|
MakeToast(this, this.Resources.GetText(Resource.String.GeneratedMessage),
|
||||||
ToastLength.Long);
|
ToastLength.Long);
|
||||||
|
@ -406,16 +433,7 @@ namespace ModLoader
|
||||||
}
|
}
|
||||||
internal void ConfigMod(string configPath)
|
internal void ConfigMod(string configPath)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(Intent.ActionView);
|
OpenTextFile(this, configPath);
|
||||||
intent.AddCategory(Intent.CategoryDefault);
|
|
||||||
File configFile = new File(configPath);
|
|
||||||
intent.SetDataAndType(Android.Net.Uri.FromFile(configFile), "text/plain");
|
|
||||||
intent.AddFlags(ActivityFlags.NewTask);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.StartActivity(intent);
|
|
||||||
}
|
|
||||||
catch (ActivityNotFoundException) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RemoveMod(ModInfo mod)
|
internal void RemoveMod(ModInfo mod)
|
||||||
|
@ -439,6 +457,10 @@ namespace ModLoader
|
||||||
|
|
||||||
private void PrepareModList()
|
private void PrepareModList()
|
||||||
{
|
{
|
||||||
|
if (!new File(Constants.ModPath).Exists())
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Constants.ModPath);
|
||||||
|
}
|
||||||
string modListFileName = Path.Combine(Constants.GameInternalPath, "ModList.json");
|
string modListFileName = Path.Combine(Constants.GameInternalPath, "ModList.json");
|
||||||
new JsonHelper().ReadJsonFileIfExists(modListFileName, out ModInfo[] modInfos);
|
new JsonHelper().ReadJsonFileIfExists(modListFileName, out ModInfo[] modInfos);
|
||||||
Dictionary<string, ModInfo> modInfoDictionary = modInfos.ToDictionary(info => info.UniqueID, info => info);
|
Dictionary<string, ModInfo> modInfoDictionary = modInfos.ToDictionary(info => info.UniqueID, info => info);
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.OS;
|
||||||
|
using Android.Runtime;
|
||||||
|
using Android.Views;
|
||||||
|
using Android.Widget;
|
||||||
|
using ModLoader.Common;
|
||||||
|
using static ModLoader.Common.Utils;
|
||||||
|
|
||||||
|
namespace ModLoader
|
||||||
|
{
|
||||||
|
[Activity(Label = "ActivitySetting")]
|
||||||
|
public class ActivitySetting : Activity
|
||||||
|
{
|
||||||
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
base.OnCreate(savedInstanceState);
|
||||||
|
this.SetContentView(Resource.Layout.layout_setting);
|
||||||
|
CheckBox checkBoxCompat = this.FindViewById<CheckBox>(Resource.Id.checkBoxCompat);
|
||||||
|
this.WireConfig(checkBoxCompat, "compatCheck", b => Constants.CompatCheck = b);
|
||||||
|
CheckBox checkBoxUpgrade = this.FindViewById<CheckBox>(Resource.Id.checkBoxUpgrade);
|
||||||
|
this.WireConfig(checkBoxUpgrade, "upgradeCheck", b => Constants.UpgradeCheck = b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WireConfig(CheckBox checkBox, string configSection, Action<bool> onChecked)
|
||||||
|
{
|
||||||
|
if (GetConfig(this, configSection, "true") == "false")
|
||||||
|
{
|
||||||
|
onChecked(false);
|
||||||
|
checkBox.Checked = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
onChecked(true);
|
||||||
|
checkBox.Checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkBox.Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
onChecked(checkBox.Checked);
|
||||||
|
SetConfig(this, configSection, checkBox.Checked ? "true" : "false");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,5 +21,7 @@ namespace ModLoader.Common
|
||||||
public static string ModPath { get; } = Path.Combine(GamePath, "Mods");
|
public static string ModPath { get; } = Path.Combine(GamePath, "Mods");
|
||||||
public static string ContentPath { get; } = Path.Combine(Constants.GamePath, "Game/assets/Content".Replace('/', Path.DirectorySeparatorChar));
|
public static string ContentPath { get; } = Path.Combine(Constants.GamePath, "Game/assets/Content".Replace('/', Path.DirectorySeparatorChar));
|
||||||
public static string GameInternalPath { get; } = Path.Combine(Constants.GamePath, "smapi-internal");
|
public static string GameInternalPath { get; } = Path.Combine(Constants.GamePath, "smapi-internal");
|
||||||
}
|
public static bool CompatCheck { get; set; } = true;
|
||||||
|
public static bool UpgradeCheck { get; set; } = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
using ModLoader.Common;
|
using ModLoader.Common;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using Mono.Cecil.Cil;
|
using Mono.Cecil.Cil;
|
||||||
|
using OpCodes = Mono.Cecil.Cil.OpCodes;
|
||||||
|
|
||||||
namespace DllRewrite
|
namespace DllRewrite
|
||||||
{
|
{
|
||||||
|
@ -15,6 +17,7 @@ namespace DllRewrite
|
||||||
private AssemblyDefinition MonoGame_Framework;
|
private AssemblyDefinition MonoGame_Framework;
|
||||||
private readonly AssemblyDefinition mscorlib;
|
private readonly AssemblyDefinition mscorlib;
|
||||||
private readonly AssemblyDefinition Mono_Android;
|
private readonly AssemblyDefinition Mono_Android;
|
||||||
|
private readonly AssemblyDefinition System_Xml;
|
||||||
private readonly DefaultAssemblyResolver resolver;
|
private readonly DefaultAssemblyResolver resolver;
|
||||||
private readonly AssemblyDefinition StardewValley;
|
private readonly AssemblyDefinition StardewValley;
|
||||||
private readonly Dictionary<string, TypeReference> typeDict = new Dictionary<string, TypeReference>();
|
private readonly Dictionary<string, TypeReference> typeDict = new Dictionary<string, TypeReference>();
|
||||||
|
@ -25,6 +28,8 @@ namespace DllRewrite
|
||||||
this.resolver.AddSearchDirectory(Constants.AssemblyPath);
|
this.resolver.AddSearchDirectory(Constants.AssemblyPath);
|
||||||
this.mscorlib = this.resolver.Resolve(new AssemblyNameReference("mscorlib", new Version("0.0.0.0")));
|
this.mscorlib = this.resolver.Resolve(new AssemblyNameReference("mscorlib", new Version("0.0.0.0")));
|
||||||
this.Mono_Android = this.resolver.Resolve(new AssemblyNameReference("Mono.Android", new Version("0.0.0.0")));
|
this.Mono_Android = this.resolver.Resolve(new AssemblyNameReference("Mono.Android", new Version("0.0.0.0")));
|
||||||
|
this.System_Xml =
|
||||||
|
this.resolver.Resolve(new AssemblyNameReference("System.Xml", new Version("0.0.0.0")));
|
||||||
this.MonoGame_Framework =
|
this.MonoGame_Framework =
|
||||||
this.resolver.Resolve(new AssemblyNameReference("MonoGame.Framework", new Version("0.0.0.0")));
|
this.resolver.Resolve(new AssemblyNameReference("MonoGame.Framework", new Version("0.0.0.0")));
|
||||||
this.StardewValley =
|
this.StardewValley =
|
||||||
|
@ -197,6 +202,26 @@ namespace DllRewrite
|
||||||
typeGame1.Methods.Add(propertyDefinition.SetMethod);
|
typeGame1.Methods.Add(propertyDefinition.SetMethod);
|
||||||
typeGame1.Properties.Add(propertyDefinition);
|
typeGame1.Properties.Add(propertyDefinition);
|
||||||
|
|
||||||
|
// GameLocation.hook
|
||||||
|
var typeGameLocation = this.StardewValley.MainModule.GetType("StardewValley.GameLocation");
|
||||||
|
var typeDebrisManager = this.StardewValley.MainModule.GetType("StardewValley.DebrisManager");
|
||||||
|
var getDebrisNetCollection = typeDebrisManager.Methods.First(m => m.Name == "get_debrisNetCollection");
|
||||||
|
var typeDebrisCollection = getDebrisNetCollection.ReturnType;
|
||||||
|
propertyDefinition = new PropertyDefinition("debrisCollection", PropertyAttributes.None, typeDebrisCollection);
|
||||||
|
propertyDefinition.CustomAttributes.Add(new CustomAttribute(this.GetMethodReference(".ctor", "System.Xml.Serialization.XmlIgnoreAttribute", this.System_Xml)));
|
||||||
|
propertyDefinition.GetMethod = new MethodDefinition("get_debrisCollection",
|
||||||
|
MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.SpecialName |
|
||||||
|
MethodAttributes.HideBySig, typeDebrisCollection);
|
||||||
|
propertyDefinition.GetMethod.SemanticsAttributes = MethodSemanticsAttributes.Getter;
|
||||||
|
processor = propertyDefinition.GetMethod.Body.GetILProcessor();
|
||||||
|
processor.Emit(OpCodes.Ldarg_0);
|
||||||
|
getMethod = typeGameLocation.Methods.FirstOrDefault(m => m.Name == "get_debris");
|
||||||
|
processor.Emit(OpCodes.Callvirt, getMethod);
|
||||||
|
processor.Emit(OpCodes.Callvirt, getDebrisNetCollection);
|
||||||
|
processor.Emit(OpCodes.Ret);
|
||||||
|
typeGameLocation.Methods.Add(propertyDefinition.GetMethod);
|
||||||
|
typeGameLocation.Properties.Add(propertyDefinition);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//HUDMessage..ctor
|
//HUDMessage..ctor
|
||||||
|
|
|
@ -146,5 +146,32 @@ namespace ModLoader.Common
|
||||||
Microsoft.AppCenter.Crashes.Crashes.TrackError(ex);
|
Microsoft.AppCenter.Crashes.Crashes.TrackError(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void OpenTextFile(Context context, string filename)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(Intent.ActionView);
|
||||||
|
intent.AddCategory(Intent.CategoryDefault);
|
||||||
|
Java.IO.File configFile = new Java.IO.File(filename);
|
||||||
|
intent.SetDataAndType(Android.Net.Uri.FromFile(configFile), "text/plain");
|
||||||
|
intent.AddFlags(ActivityFlags.NewTask);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context.StartActivity(intent);
|
||||||
|
}
|
||||||
|
catch (ActivityNotFoundException) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetConfig(Context context, string key, string defValue)
|
||||||
|
{
|
||||||
|
ISharedPreferences sp = context.GetSharedPreferences("main_prefs", FileCreationMode.Private);
|
||||||
|
return sp.GetString(key, defValue);
|
||||||
|
}
|
||||||
|
public static void SetConfig(Context context, string key, string value)
|
||||||
|
{
|
||||||
|
ISharedPreferences sp = context.GetSharedPreferences("main_prefs", FileCreationMode.Private);
|
||||||
|
ISharedPreferencesEditor editor = sp.Edit();
|
||||||
|
editor.PutString(key, value);
|
||||||
|
editor.Apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
<AndroidHttpClientHandlerType>
|
<AndroidHttpClientHandlerType>
|
||||||
</AndroidHttpClientHandlerType>
|
</AndroidHttpClientHandlerType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
|
@ -172,6 +173,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Activity1.cs" />
|
<Compile Include="Activity1.cs" />
|
||||||
|
<Compile Include="ActivitySetting.cs" />
|
||||||
<Compile Include="Common\Constants.cs" />
|
<Compile Include="Common\Constants.cs" />
|
||||||
<Compile Include="Common\ModInfo.cs" />
|
<Compile Include="Common\ModInfo.cs" />
|
||||||
<Compile Include="Common\ModListAdapter.cs" />
|
<Compile Include="Common\ModListAdapter.cs" />
|
||||||
|
@ -894,7 +896,11 @@
|
||||||
<Compile Include="SMAPI\Framework\RewriteFacades\FarmerMethods.cs" />
|
<Compile Include="SMAPI\Framework\RewriteFacades\FarmerMethods.cs" />
|
||||||
<Compile Include="SMAPI\Framework\RewriteFacades\Game1Methods.cs" />
|
<Compile Include="SMAPI\Framework\RewriteFacades\Game1Methods.cs" />
|
||||||
<Compile Include="SMAPI\Framework\RewriteFacades\IClickableMenuMethods.cs" />
|
<Compile Include="SMAPI\Framework\RewriteFacades\IClickableMenuMethods.cs" />
|
||||||
|
<Compile Include="SMAPI\Framework\RewriteFacades\MapPageMethods.cs" />
|
||||||
<Compile Include="SMAPI\Framework\RewriteFacades\SpriteBatchMethods.cs" />
|
<Compile Include="SMAPI\Framework\RewriteFacades\SpriteBatchMethods.cs" />
|
||||||
|
<Compile Include="SMAPI\Framework\RewriteFacades\SpriteTextMethods.cs" />
|
||||||
|
<Compile Include="SMAPI\Framework\RewriteFacades\ItemGrabMenuMethods.cs" />
|
||||||
|
<Compile Include="SMAPI\Framework\RewriteFacades\TextBoxMethods.cs" />
|
||||||
<Compile Include="SMAPI\Framework\SCore.cs" />
|
<Compile Include="SMAPI\Framework\SCore.cs" />
|
||||||
<Compile Include="SMAPI\Framework\Serialisation\ColorConverter.cs" />
|
<Compile Include="SMAPI\Framework\Serialisation\ColorConverter.cs" />
|
||||||
<Compile Include="SMAPI\Framework\Serialisation\PointConverter.cs" />
|
<Compile Include="SMAPI\Framework\Serialisation\PointConverter.cs" />
|
||||||
|
@ -1067,6 +1073,11 @@
|
||||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||||
</AndroidResource>
|
</AndroidResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\Layout\layout_setting.axml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</AndroidResource>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
|
||||||
<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|
|
@ -332,10 +332,11 @@ namespace Mono.Cecil {
|
||||||
|
|
||||||
static string GetCurrentMonoGac ()
|
static string GetCurrentMonoGac ()
|
||||||
{
|
{
|
||||||
return Path.Combine (
|
if (Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName) != "")
|
||||||
Directory.GetParent (
|
return Path.Combine(
|
||||||
Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName,
|
Directory.GetParent(Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)).FullName,
|
||||||
"gac");
|
"gac");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
|
AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
|
||||||
|
|
|
@ -18,6 +18,10 @@ using static System.Reflection.IntrospectionExtensions;
|
||||||
using static System.Reflection.TypeExtensions;
|
using static System.Reflection.TypeExtensions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CECIL0_9
|
||||||
|
using InterfaceImplementation = Mono.Cecil.TypeReference;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace MonoMod {
|
namespace MonoMod {
|
||||||
|
|
||||||
public delegate bool MethodParser(MonoModder modder, MethodBody body, Instruction instr, ref int instri);
|
public delegate bool MethodParser(MonoModder modder, MethodBody body, Instruction instr, ref int instri);
|
||||||
|
|
|
@ -317,13 +317,24 @@ namespace MonoMod.RuntimeDetour {
|
||||||
return _SharedStateASM;
|
return _SharedStateASM;
|
||||||
|
|
||||||
string name = (string) GetHarmonyType("HarmonySharedState").GetField("name", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
|
string name = (string) GetHarmonyType("HarmonySharedState").GetField("name", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
|
||||||
using (ModuleDefinition module = ModuleDefinition.CreateModule(
|
#if !CECIL0_9
|
||||||
|
using (
|
||||||
|
#endif
|
||||||
|
ModuleDefinition module = ModuleDefinition.CreateModule(
|
||||||
$"MonoMod.RuntimeDetour.{name}",
|
$"MonoMod.RuntimeDetour.{name}",
|
||||||
new ModuleParameters() {
|
new ModuleParameters() {
|
||||||
Kind = ModuleKind.Dll,
|
Kind = ModuleKind.Dll,
|
||||||
|
#if !CECIL0_9
|
||||||
ReflectionImporterProvider = MMReflectionImporter.Provider
|
ReflectionImporterProvider = MMReflectionImporter.Provider
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
)) {
|
)
|
||||||
|
#if CECIL0_9
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
TypeDefinition type = new TypeDefinition(
|
TypeDefinition type = new TypeDefinition(
|
||||||
"", name,
|
"", name,
|
||||||
Mono.Cecil.TypeAttributes.Public | Mono.Cecil.TypeAttributes.Abstract | Mono.Cecil.TypeAttributes.Sealed | Mono.Cecil.TypeAttributes.Class
|
Mono.Cecil.TypeAttributes.Public | Mono.Cecil.TypeAttributes.Abstract | Mono.Cecil.TypeAttributes.Sealed | Mono.Cecil.TypeAttributes.Class
|
||||||
|
|
|
@ -32,7 +32,9 @@ namespace MonoMod.Utils {
|
||||||
module = ModuleDefinition.CreateModule(name, new ModuleParameters() {
|
module = ModuleDefinition.CreateModule(name, new ModuleParameters() {
|
||||||
Kind = ModuleKind.Dll,
|
Kind = ModuleKind.Dll,
|
||||||
AssemblyResolver = new AssemblyCecilDefinitionResolver(_ModuleGen, new DefaultAssemblyResolver()),
|
AssemblyResolver = new AssemblyCecilDefinitionResolver(_ModuleGen, new DefaultAssemblyResolver()),
|
||||||
|
#if !CECIL0_9
|
||||||
ReflectionImporterProvider = new ReflectionCecilImporterProvider(null)
|
ReflectionImporterProvider = new ReflectionCecilImporterProvider(null)
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
#if !NETSTANDARD1_X
|
#if !NETSTANDARD1_X
|
||||||
|
@ -158,8 +160,10 @@ namespace MonoMod.Utils {
|
||||||
return _Postbuild(asm.GetType(typeDef.FullName.Replace("+", "\\+"), false, false).GetMethod(clone.Name));
|
return _Postbuild(asm.GetType(typeDef.FullName.Replace("+", "\\+"), false, false).GetMethod(clone.Name));
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
#if !CECIL0_9
|
||||||
if (moduleIsPrivate)
|
if (moduleIsPrivate)
|
||||||
module.Dispose();
|
module.Dispose();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -368,10 +368,13 @@ namespace MonoMod.Utils {
|
||||||
operand = param.Index + paramOffs;
|
operand = param.Index + paramOffs;
|
||||||
|
|
||||||
} else if (operand is MemberReference mref) {
|
} else if (operand is MemberReference mref) {
|
||||||
|
#if !CECIL0_9
|
||||||
if (mref is DynamicMethodReference dmref) {
|
if (mref is DynamicMethodReference dmref) {
|
||||||
operand = dmref.DynamicMethod;
|
operand = dmref.DynamicMethod;
|
||||||
|
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
MemberInfo member = mref.ResolveReflection();
|
MemberInfo member = mref.ResolveReflection();
|
||||||
operand = member;
|
operand = member;
|
||||||
#if !NETSTANDARD
|
#if !NETSTANDARD
|
||||||
|
|
|
@ -152,7 +152,9 @@ namespace MonoMod.Utils {
|
||||||
ModuleDefinition module = _DynModuleDefinition = ModuleDefinition.CreateModule($"DMD:DynModule<{name}>?{GetHashCode()}", new ModuleParameters() {
|
ModuleDefinition module = _DynModuleDefinition = ModuleDefinition.CreateModule($"DMD:DynModule<{name}>?{GetHashCode()}", new ModuleParameters() {
|
||||||
Kind = ModuleKind.Dll,
|
Kind = ModuleKind.Dll,
|
||||||
AssemblyResolver = new AssemblyCecilDefinitionResolver(_ModuleGen, new DefaultAssemblyResolver()),
|
AssemblyResolver = new AssemblyCecilDefinitionResolver(_ModuleGen, new DefaultAssemblyResolver()),
|
||||||
|
#if !CECIL0_9
|
||||||
ReflectionImporterProvider = new ReflectionCecilImporterProvider(null)
|
ReflectionImporterProvider = new ReflectionCecilImporterProvider(null)
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
_DynModuleIsPrivate = true;
|
_DynModuleIsPrivate = true;
|
||||||
|
|
||||||
|
@ -205,7 +207,9 @@ namespace MonoMod.Utils {
|
||||||
ReaderParameters rp = new ReaderParameters();
|
ReaderParameters rp = new ReaderParameters();
|
||||||
if (_ModuleGen != null) {
|
if (_ModuleGen != null) {
|
||||||
rp.AssemblyResolver = new AssemblyCecilDefinitionResolver(_ModuleGen, rp.AssemblyResolver ?? new DefaultAssemblyResolver());
|
rp.AssemblyResolver = new AssemblyCecilDefinitionResolver(_ModuleGen, rp.AssemblyResolver ?? new DefaultAssemblyResolver());
|
||||||
|
#if !CECIL0_9
|
||||||
rp.ReflectionImporterProvider = new ReflectionCecilImporterProvider(rp.ReflectionImporterProvider);
|
rp.ReflectionImporterProvider = new ReflectionCecilImporterProvider(rp.ReflectionImporterProvider);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
module = moduleTmp = ModuleDefinition.ReadModule(location, rp);
|
module = moduleTmp = ModuleDefinition.ReadModule(location, rp);
|
||||||
|
@ -466,6 +470,7 @@ namespace MonoMod.Utils {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !CECIL0_9
|
||||||
class ReflectionCecilImporterProvider : IReflectionImporterProvider {
|
class ReflectionCecilImporterProvider : IReflectionImporterProvider {
|
||||||
private readonly IReflectionImporterProvider Fallback;
|
private readonly IReflectionImporterProvider Fallback;
|
||||||
|
|
||||||
|
@ -511,6 +516,7 @@ namespace MonoMod.Utils {
|
||||||
return Fallback.ImportReference(method, context);
|
return Fallback.ImportReference(method, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
class DynamicMethodReference : MethodReference {
|
class DynamicMethodReference : MethodReference {
|
||||||
public DynamicMethod DynamicMethod;
|
public DynamicMethod DynamicMethod;
|
||||||
|
|
|
@ -102,8 +102,13 @@ namespace MonoMod.Utils {
|
||||||
|
|
||||||
public static void Emit(this ILProcessor il, OpCode opcode, FieldInfo field)
|
public static void Emit(this ILProcessor il, OpCode opcode, FieldInfo field)
|
||||||
=> il.Emit(opcode, il.Import(field));
|
=> il.Emit(opcode, il.Import(field));
|
||||||
public static void Emit(this ILProcessor il, OpCode opcode, MethodBase method)
|
public static void Emit(this ILProcessor il, OpCode opcode, MethodBase method) {
|
||||||
=> il.Emit(opcode, il.Import(method));
|
if (method is System.Reflection.Emit.DynamicMethod) {
|
||||||
|
il.Emit(opcode, (object) method);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
il.Emit(opcode, il.Import(method));
|
||||||
|
}
|
||||||
public static void Emit(this ILProcessor il, OpCode opcode, Type type)
|
public static void Emit(this ILProcessor il, OpCode opcode, Type type)
|
||||||
=> il.Emit(opcode, il.Import(type));
|
=> il.Emit(opcode, il.Import(type));
|
||||||
public static void Emit(this ILProcessor il, OpCode opcode, MemberInfo member) {
|
public static void Emit(this ILProcessor il, OpCode opcode, MemberInfo member) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
#if !CECIL0_9
|
||||||
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
@ -99,3 +100,4 @@ namespace MonoMod.Utils {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -41,13 +41,24 @@ namespace MonoMod.Utils.Cil {
|
||||||
Type t_ILGenerator = typeof(System.Reflection.Emit.ILGenerator);
|
Type t_ILGenerator = typeof(System.Reflection.Emit.ILGenerator);
|
||||||
Type t_ILGeneratorProxyTarget = typeof(ILGeneratorShim);
|
Type t_ILGeneratorProxyTarget = typeof(ILGeneratorShim);
|
||||||
|
|
||||||
using (ModuleDefinition module = ModuleDefinition.CreateModule(
|
#if !CECIL0_9
|
||||||
|
using (
|
||||||
|
#endif
|
||||||
|
ModuleDefinition module = ModuleDefinition.CreateModule(
|
||||||
FullName,
|
FullName,
|
||||||
new ModuleParameters() {
|
new ModuleParameters() {
|
||||||
Kind = ModuleKind.Dll,
|
Kind = ModuleKind.Dll,
|
||||||
|
#if !CECIL0_9
|
||||||
ReflectionImporterProvider = MMReflectionImporter.Provider
|
ReflectionImporterProvider = MMReflectionImporter.Provider
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
)) {
|
)
|
||||||
|
#if CECIL0_9
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
|
||||||
TypeDefinition type = new TypeDefinition(
|
TypeDefinition type = new TypeDefinition(
|
||||||
Namespace,
|
Namespace,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="16" android:versionName="1.4" android:installLocation="auto" package="com.zane.smdroid" platformBuildVersionCode="28" platformBuildVersionName="9">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="20" android:versionName="1.5" android:installLocation="auto" package="com.zane.smdroid" platformBuildVersionCode="28" platformBuildVersionName="9">
|
||||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28" />
|
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
android:background="@android:color/darker_gray"
|
android:background="@android:color/darker_gray"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/linearLayout1" >
|
android:id="@+id/linearLayout1">
|
||||||
<Button
|
<Button
|
||||||
android:text="@string/Extract"
|
android:text="@string/Extract"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -39,6 +39,12 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minWidth="96sp"
|
android:minWidth="96sp"
|
||||||
android:id="@+id/buttonWiki" />
|
android:id="@+id/buttonWiki" />
|
||||||
|
<Button
|
||||||
|
android:text="@string/Setting"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="96sp"
|
||||||
|
android:id="@+id/buttonSetting" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_marginLeft="@dimen/compat_button_padding_vertical_material"
|
android:layout_marginLeft="@dimen/compat_button_padding_vertical_material"
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@android:color/background_light"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<CheckBox
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:text="@string/CompatCheck"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="25px"
|
||||||
|
android:minHeight="25px"
|
||||||
|
android:id="@+id/checkBoxCompat" />
|
||||||
|
<CheckBox
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:text="@string/UpgradeCheck"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="25px"
|
||||||
|
android:minHeight="25px"
|
||||||
|
android:id="@+id/checkBoxUpgrade" />
|
||||||
|
</LinearLayout>
|
|
@ -219,5 +219,12 @@
|
||||||
"UniqueID": "Pathoschild.ContentPatcher"
|
"UniqueID": "Pathoschild.ContentPatcher"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},{
|
||||||
|
"UniqueID": "SgtPickles.MTN",
|
||||||
|
"Name": "MTN",
|
||||||
|
"Description": "Greatly Customizes farms, along with managing multitude amount of custom farm types.",
|
||||||
|
"DownloadUrl": "http://smd.zaneyork.cn/bin/download/Main/%E7%A7%BB%E6%A4%8DMOD/WebHome/mtn-2.0.0-alpha8.zip",
|
||||||
|
"Version": "2.0.0-alpha8",
|
||||||
|
"Dependencies": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Binary file not shown.
|
@ -255,26 +255,26 @@ namespace ModLoader
|
||||||
public partial class Id
|
public partial class Id
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b001d
|
||||||
|
public const int action0 = 2131427357;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b001a
|
// aapt resource value: 0x7f0b001a
|
||||||
public const int action0 = 2131427354;
|
public const int action_container = 2131427354;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0017
|
// aapt resource value: 0x7f0b0021
|
||||||
public const int action_container = 2131427351;
|
public const int action_divider = 2131427361;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b001e
|
// aapt resource value: 0x7f0b001b
|
||||||
public const int action_divider = 2131427358;
|
public const int action_image = 2131427355;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0018
|
// aapt resource value: 0x7f0b001c
|
||||||
public const int action_image = 2131427352;
|
public const int action_text = 2131427356;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0019
|
// aapt resource value: 0x7f0b002b
|
||||||
public const int action_text = 2131427353;
|
public const int actions = 2131427371;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0028
|
// aapt resource value: 0x7f0b002f
|
||||||
public const int actions = 2131427368;
|
public const int appIcon = 2131427375;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b002c
|
|
||||||
public const int appIcon = 2131427372;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0006
|
// aapt resource value: 0x7f0b0006
|
||||||
public const int async = 2131427334;
|
public const int async = 2131427334;
|
||||||
|
@ -282,11 +282,11 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f0b0007
|
// aapt resource value: 0x7f0b0007
|
||||||
public const int blocking = 2131427335;
|
public const int blocking = 2131427335;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0013
|
|
||||||
public const int buttonAddOrRemove = 2131427347;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0014
|
// aapt resource value: 0x7f0b0014
|
||||||
public const int buttonConfig = 2131427348;
|
public const int buttonAddOrRemove = 2131427348;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0015
|
||||||
|
public const int buttonConfig = 2131427349;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b000d
|
// aapt resource value: 0x7f0b000d
|
||||||
public const int buttonExtract = 2131427341;
|
public const int buttonExtract = 2131427341;
|
||||||
|
@ -297,20 +297,29 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f0b000f
|
// aapt resource value: 0x7f0b000f
|
||||||
public const int buttonLaunch = 2131427343;
|
public const int buttonLaunch = 2131427343;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0011
|
||||||
|
public const int buttonSetting = 2131427345;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0010
|
// aapt resource value: 0x7f0b0010
|
||||||
public const int buttonWiki = 2131427344;
|
public const int buttonWiki = 2131427344;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b001b
|
// aapt resource value: 0x7f0b001e
|
||||||
public const int cancel_action = 2131427355;
|
public const int cancel_action = 2131427358;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0023
|
// aapt resource value: 0x7f0b0018
|
||||||
public const int chronometer = 2131427363;
|
public const int checkBoxCompat = 2131427352;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0031
|
// aapt resource value: 0x7f0b0019
|
||||||
public const int description = 2131427377;
|
public const int checkBoxUpgrade = 2131427353;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b002a
|
// aapt resource value: 0x7f0b0026
|
||||||
public const int end_padder = 2131427370;
|
public const int chronometer = 2131427366;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0034
|
||||||
|
public const int description = 2131427380;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b002d
|
||||||
|
public const int end_padder = 2131427373;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0008
|
// aapt resource value: 0x7f0b0008
|
||||||
public const int forever = 2131427336;
|
public const int forever = 2131427336;
|
||||||
|
@ -318,14 +327,14 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f0b000b
|
// aapt resource value: 0x7f0b000b
|
||||||
public const int gridLayout1 = 2131427339;
|
public const int gridLayout1 = 2131427339;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0025
|
// aapt resource value: 0x7f0b0028
|
||||||
public const int icon = 2131427365;
|
public const int icon = 2131427368;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0029
|
// aapt resource value: 0x7f0b002c
|
||||||
public const int icon_group = 2131427369;
|
public const int icon_group = 2131427372;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0024
|
// aapt resource value: 0x7f0b0027
|
||||||
public const int info = 2131427364;
|
public const int info = 2131427367;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0009
|
// aapt resource value: 0x7f0b0009
|
||||||
public const int italic = 2131427337;
|
public const int italic = 2131427337;
|
||||||
|
@ -339,50 +348,50 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f0b000c
|
// aapt resource value: 0x7f0b000c
|
||||||
public const int linearLayout1 = 2131427340;
|
public const int linearLayout1 = 2131427340;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0011
|
|
||||||
public const int listView1 = 2131427345;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0012
|
// aapt resource value: 0x7f0b0012
|
||||||
public const int ll_view = 2131427346;
|
public const int listView1 = 2131427346;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b001d
|
// aapt resource value: 0x7f0b0013
|
||||||
public const int media_actions = 2131427357;
|
public const int ll_view = 2131427347;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0020
|
||||||
|
public const int media_actions = 2131427360;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b000a
|
// aapt resource value: 0x7f0b000a
|
||||||
public const int normal = 2131427338;
|
public const int normal = 2131427338;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b002b
|
// aapt resource value: 0x7f0b002e
|
||||||
public const int notificationLayout = 2131427371;
|
public const int notificationLayout = 2131427374;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0027
|
// aapt resource value: 0x7f0b002a
|
||||||
public const int notification_background = 2131427367;
|
public const int notification_background = 2131427370;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0020
|
// aapt resource value: 0x7f0b0023
|
||||||
public const int notification_main_column = 2131427360;
|
public const int notification_main_column = 2131427363;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b001f
|
// aapt resource value: 0x7f0b0022
|
||||||
public const int notification_main_column_container = 2131427359;
|
public const int notification_main_column_container = 2131427362;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0030
|
// aapt resource value: 0x7f0b0033
|
||||||
public const int progress_bar = 2131427376;
|
public const int progress_bar = 2131427379;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b002f
|
|
||||||
public const int progress_bar_frame = 2131427375;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b002d
|
|
||||||
public const int progress_text = 2131427373;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0026
|
|
||||||
public const int right_icon = 2131427366;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0021
|
|
||||||
public const int right_side = 2131427361;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0032
|
// aapt resource value: 0x7f0b0032
|
||||||
public const int spacer = 2131427378;
|
public const int progress_bar_frame = 2131427378;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b001c
|
// aapt resource value: 0x7f0b0030
|
||||||
public const int status_bar_latest_event_content = 2131427356;
|
public const int progress_text = 2131427376;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0029
|
||||||
|
public const int right_icon = 2131427369;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0024
|
||||||
|
public const int right_side = 2131427364;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0035
|
||||||
|
public const int spacer = 2131427381;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b001f
|
||||||
|
public const int status_bar_latest_event_content = 2131427359;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0002
|
// aapt resource value: 0x7f0b0002
|
||||||
public const int tag_transition_group = 2131427330;
|
public const int tag_transition_group = 2131427330;
|
||||||
|
@ -393,17 +402,17 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f0b0004
|
// aapt resource value: 0x7f0b0004
|
||||||
public const int text2 = 2131427332;
|
public const int text2 = 2131427332;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0b0017
|
||||||
|
public const int textDescription = 2131427351;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0016
|
// aapt resource value: 0x7f0b0016
|
||||||
public const int textDescription = 2131427350;
|
public const int textModName = 2131427350;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0015
|
// aapt resource value: 0x7f0b0025
|
||||||
public const int textModName = 2131427349;
|
public const int time = 2131427365;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0022
|
// aapt resource value: 0x7f0b0031
|
||||||
public const int time = 2131427362;
|
public const int time_remaining = 2131427377;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b002e
|
|
||||||
public const int time_remaining = 2131427374;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0b0005
|
// aapt resource value: 0x7f0b0005
|
||||||
public const int title = 2131427333;
|
public const int title = 2131427333;
|
||||||
|
@ -447,52 +456,55 @@ namespace ModLoader
|
||||||
public const int layout_mod_list = 2130903041;
|
public const int layout_mod_list = 2130903041;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030002
|
// aapt resource value: 0x7f030002
|
||||||
public const int notification_action = 2130903042;
|
public const int layout_setting = 2130903042;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030003
|
// aapt resource value: 0x7f030003
|
||||||
public const int notification_action_tombstone = 2130903043;
|
public const int notification_action = 2130903043;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030004
|
// aapt resource value: 0x7f030004
|
||||||
public const int notification_media_action = 2130903044;
|
public const int notification_action_tombstone = 2130903044;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030005
|
// aapt resource value: 0x7f030005
|
||||||
public const int notification_media_cancel_action = 2130903045;
|
public const int notification_media_action = 2130903045;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030006
|
// aapt resource value: 0x7f030006
|
||||||
public const int notification_template_big_media = 2130903046;
|
public const int notification_media_cancel_action = 2130903046;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030007
|
// aapt resource value: 0x7f030007
|
||||||
public const int notification_template_big_media_custom = 2130903047;
|
public const int notification_template_big_media = 2130903047;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030008
|
// aapt resource value: 0x7f030008
|
||||||
public const int notification_template_big_media_narrow = 2130903048;
|
public const int notification_template_big_media_custom = 2130903048;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030009
|
// aapt resource value: 0x7f030009
|
||||||
public const int notification_template_big_media_narrow_custom = 2130903049;
|
public const int notification_template_big_media_narrow = 2130903049;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03000a
|
// aapt resource value: 0x7f03000a
|
||||||
public const int notification_template_custom_big = 2130903050;
|
public const int notification_template_big_media_narrow_custom = 2130903050;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03000b
|
// aapt resource value: 0x7f03000b
|
||||||
public const int notification_template_icon_group = 2130903051;
|
public const int notification_template_custom_big = 2130903051;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03000c
|
// aapt resource value: 0x7f03000c
|
||||||
public const int notification_template_lines_media = 2130903052;
|
public const int notification_template_icon_group = 2130903052;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03000d
|
// aapt resource value: 0x7f03000d
|
||||||
public const int notification_template_media = 2130903053;
|
public const int notification_template_lines_media = 2130903053;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03000e
|
// aapt resource value: 0x7f03000e
|
||||||
public const int notification_template_media_custom = 2130903054;
|
public const int notification_template_media = 2130903054;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03000f
|
// aapt resource value: 0x7f03000f
|
||||||
public const int notification_template_part_chronometer = 2130903055;
|
public const int notification_template_media_custom = 2130903055;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030010
|
// aapt resource value: 0x7f030010
|
||||||
public const int notification_template_part_time = 2130903056;
|
public const int notification_template_part_chronometer = 2130903056;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030011
|
// aapt resource value: 0x7f030011
|
||||||
public const int status_bar_ongoing_event_progress_bar = 2130903057;
|
public const int notification_template_part_time = 2130903057;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f030012
|
||||||
|
public const int status_bar_ongoing_event_progress_bar = 2130903058;
|
||||||
|
|
||||||
static Layout()
|
static Layout()
|
||||||
{
|
{
|
||||||
|
@ -529,41 +541,50 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f080018
|
// aapt resource value: 0x7f080018
|
||||||
public const int ApplicationName = 2131230744;
|
public const int ApplicationName = 2131230744;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080028
|
// aapt resource value: 0x7f08002b
|
||||||
public const int Cancel = 2131230760;
|
public const int Cancel = 2131230763;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080026
|
// aapt resource value: 0x7f080026
|
||||||
public const int Config = 2131230758;
|
public const int CompatCheck = 2131230758;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f080029
|
||||||
|
public const int Config = 2131230761;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080024
|
// aapt resource value: 0x7f080024
|
||||||
public const int Confirm = 2131230756;
|
public const int Confirm = 2131230756;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f080038
|
||||||
|
public const int CrashReportMessage = 2131230776;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08001c
|
// aapt resource value: 0x7f08001c
|
||||||
public const int Disable = 2131230748;
|
public const int Disable = 2131230748;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f08003a
|
||||||
|
public const int Dismiss = 2131230778;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08001d
|
// aapt resource value: 0x7f08001d
|
||||||
public const int Enable = 2131230749;
|
public const int Enable = 2131230749;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080025
|
// aapt resource value: 0x7f080028
|
||||||
public const int Error = 2131230757;
|
public const int Error = 2131230760;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080019
|
// aapt resource value: 0x7f080019
|
||||||
public const int Extract = 2131230745;
|
public const int Extract = 2131230745;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08002b
|
// aapt resource value: 0x7f08002e
|
||||||
public const int ExtractedMessage = 2131230763;
|
public const int ExtractedMessage = 2131230766;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08002a
|
// aapt resource value: 0x7f08002d
|
||||||
public const int ExtractingMessage = 2131230762;
|
public const int ExtractingMessage = 2131230765;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08001a
|
// aapt resource value: 0x7f08001a
|
||||||
public const int Generate = 2131230746;
|
public const int Generate = 2131230746;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08002d
|
// aapt resource value: 0x7f080030
|
||||||
public const int GeneratedMessage = 2131230765;
|
public const int GeneratedMessage = 2131230768;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08002c
|
// aapt resource value: 0x7f08002f
|
||||||
public const int GeneratingMessage = 2131230764;
|
public const int GeneratingMessage = 2131230767;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080023
|
// aapt resource value: 0x7f080023
|
||||||
public const int Ignore = 2131230755;
|
public const int Ignore = 2131230755;
|
||||||
|
@ -571,38 +592,41 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f08001b
|
// aapt resource value: 0x7f08001b
|
||||||
public const int Launch = 2131230747;
|
public const int Launch = 2131230747;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08002e
|
// aapt resource value: 0x7f080031
|
||||||
public const int ModDownloadingMessage = 2131230766;
|
public const int ModDownloadingMessage = 2131230769;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08001e
|
// aapt resource value: 0x7f08001e
|
||||||
public const int ModInstall = 2131230750;
|
public const int ModInstall = 2131230750;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080030
|
// aapt resource value: 0x7f080033
|
||||||
public const int ModInstalledMessage = 2131230768;
|
public const int ModInstalledMessage = 2131230771;
|
||||||
|
|
||||||
// aapt resource value: 0x7f08001f
|
// aapt resource value: 0x7f08001f
|
||||||
public const int ModRemove = 2131230751;
|
public const int ModRemove = 2131230751;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080031
|
|
||||||
public const int ModRemovedMessage = 2131230769;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f08002f
|
|
||||||
public const int NetworkErrorMessage = 2131230767;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f080033
|
|
||||||
public const int NotExtractedMessage = 2131230771;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f080034
|
// aapt resource value: 0x7f080034
|
||||||
public const int NotGeneratedMessage = 2131230772;
|
public const int ModRemovedMessage = 2131230772;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080032
|
// aapt resource value: 0x7f080032
|
||||||
public const int NotInstalledMessage = 2131230770;
|
public const int NetworkErrorMessage = 2131230770;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080027
|
// aapt resource value: 0x7f080037
|
||||||
public const int RemoveConfirmMessage = 2131230759;
|
public const int NotExtractedMessage = 2131230775;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080029
|
// aapt resource value: 0x7f080036
|
||||||
public const int StorageIsFullMessage = 2131230761;
|
public const int NotGeneratedMessage = 2131230774;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f080035
|
||||||
|
public const int NotInstalledMessage = 2131230773;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f08002a
|
||||||
|
public const int RemoveConfirmMessage = 2131230762;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f080025
|
||||||
|
public const int Setting = 2131230757;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f08002c
|
||||||
|
public const int StorageIsFullMessage = 2131230764;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080022
|
// aapt resource value: 0x7f080022
|
||||||
public const int Update = 2131230754;
|
public const int Update = 2131230754;
|
||||||
|
@ -610,6 +634,12 @@ namespace ModLoader
|
||||||
// aapt resource value: 0x7f080021
|
// aapt resource value: 0x7f080021
|
||||||
public const int UpdateTip = 2131230753;
|
public const int UpdateTip = 2131230753;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f080027
|
||||||
|
public const int UpgradeCheck = 2131230759;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f080039
|
||||||
|
public const int View = 2131230777;
|
||||||
|
|
||||||
// aapt resource value: 0x7f080020
|
// aapt resource value: 0x7f080020
|
||||||
public const int Wiki = 2131230752;
|
public const int Wiki = 2131230752;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
<string name="Update">更新</string>
|
<string name="Update">更新</string>
|
||||||
<string name="Ignore">忽略</string>
|
<string name="Ignore">忽略</string>
|
||||||
<string name="Confirm">确认</string>
|
<string name="Confirm">确认</string>
|
||||||
|
<string name="Setting">设置</string>
|
||||||
|
<string name="CompatCheck">Mod兼容性检查</string>
|
||||||
|
<string name="UpgradeCheck">检查更新</string>
|
||||||
<string name="Error">错误</string>
|
<string name="Error">错误</string>
|
||||||
<string name="Config">配置</string>
|
<string name="Config">配置</string>
|
||||||
<string name="RemoveConfirmMessage">确认移除这个插件?</string>
|
<string name="RemoveConfirmMessage">确认移除这个插件?</string>
|
||||||
|
@ -29,4 +32,7 @@
|
||||||
<string name="NotInstalledMessage">请先安装游戏本体</string>
|
<string name="NotInstalledMessage">请先安装游戏本体</string>
|
||||||
<string name="NotExtractedMessage">请先点击解压按钮</string>
|
<string name="NotExtractedMessage">请先点击解压按钮</string>
|
||||||
<string name="NotGeneratedMessage">请先点击生成按钮</string>
|
<string name="NotGeneratedMessage">请先点击生成按钮</string>
|
||||||
|
<string name="CrashReportMessage">检测到崩溃日志</string>
|
||||||
|
<string name="View">查看</string>
|
||||||
|
<string name="Dismiss">关闭</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
<string name="Update">Upgrade</string>
|
<string name="Update">Upgrade</string>
|
||||||
<string name="Ignore">Ignore</string>
|
<string name="Ignore">Ignore</string>
|
||||||
<string name="Confirm">Confirm</string>
|
<string name="Confirm">Confirm</string>
|
||||||
|
<string name="Setting">Setting</string>
|
||||||
|
<string name="CompatCheck">Mod Compatibility Check</string>
|
||||||
|
<string name="UpgradeCheck">Upgrade Check</string>
|
||||||
<string name="Error">Error</string>
|
<string name="Error">Error</string>
|
||||||
<string name="Config">Config</string>
|
<string name="Config">Config</string>
|
||||||
<string name="RemoveConfirmMessage">Are you sure to remove this mod?</string>
|
<string name="RemoveConfirmMessage">Are you sure to remove this mod?</string>
|
||||||
|
@ -27,6 +30,9 @@
|
||||||
<string name="ModInstalledMessage">Mod Installed Successfully</string>
|
<string name="ModInstalledMessage">Mod Installed Successfully</string>
|
||||||
<string name="ModRemovedMessage">Mod Removed Successfully</string>
|
<string name="ModRemovedMessage">Mod Removed Successfully</string>
|
||||||
<string name="NotInstalledMessage">Install the Stardew Valley First</string>
|
<string name="NotInstalledMessage">Install the Stardew Valley First</string>
|
||||||
<string name="NotExtractedMessage">Press Extract First</string>
|
|
||||||
<string name="NotGeneratedMessage">Press Generate First</string>
|
<string name="NotGeneratedMessage">Press Generate First</string>
|
||||||
|
<string name="NotExtractedMessage">Press Extract First</string>
|
||||||
|
<string name="CrashReportMessage">Crash report detected</string>
|
||||||
|
<string name="View">View</string>
|
||||||
|
<string name="Dismiss">Dismiss</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace StardewModdingAPI
|
||||||
****/
|
****/
|
||||||
/// <summary>SMAPI's current semantic version.</summary>
|
/// <summary>SMAPI's current semantic version.</summary>
|
||||||
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.0.0");
|
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.0.0");
|
||||||
public static ISemanticVersion CoreVersion { get; } = new Toolkit.SemanticVersion("1.4.2");
|
public static ISemanticVersion CoreVersion { get; } = new Toolkit.SemanticVersion("1.4.3");
|
||||||
|
|
||||||
/// <summary>The minimum supported version of Stardew Valley.</summary>
|
/// <summary>The minimum supported version of Stardew Valley.</summary>
|
||||||
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.3.36");
|
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.3.36");
|
||||||
|
@ -182,7 +182,6 @@ namespace StardewModdingAPI
|
||||||
"Microsoft.Xna.Framework.Graphics",
|
"Microsoft.Xna.Framework.Graphics",
|
||||||
"Microsoft.Xna.Framework.Xact",
|
"Microsoft.Xna.Framework.Xact",
|
||||||
"0Harmony",
|
"0Harmony",
|
||||||
"Newtonsoft.Json",
|
|
||||||
"StardewModdingAPI.Toolkit",
|
"StardewModdingAPI.Toolkit",
|
||||||
"StardewModdingAPI.Toolkit.CoreInterfaces"
|
"StardewModdingAPI.Toolkit.CoreInterfaces"
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,7 +60,6 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
||||||
/// <summary>Assert that the given key has a valid format and return a normalised form consistent with the underlying cache.</summary>
|
/// <summary>Assert that the given key has a valid format and return a normalised form consistent with the underlying cache.</summary>
|
||||||
/// <param name="assetName">The asset key to check.</param>
|
/// <param name="assetName">The asset key to check.</param>
|
||||||
/// <exception cref="SContentLoadException">The asset key is empty or contains invalid characters.</exception>
|
/// <exception cref="SContentLoadException">The asset key is empty or contains invalid characters.</exception>
|
||||||
[SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local", Justification = "Parameter is only used for assertion checks by design.")]
|
|
||||||
string AssertAndNormaliseAssetName(string assetName);
|
string AssertAndNormaliseAssetName(string assetName);
|
||||||
|
|
||||||
/// <summary>Get the current content locale.</summary>
|
/// <summary>Get the current content locale.</summary>
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
||||||
{
|
{
|
||||||
// XNB file
|
// XNB file
|
||||||
case ".xnb":
|
case ".xnb":
|
||||||
return this.ModedLoad<T>(relativePath, language);
|
return base.Load<T>(relativePath, language);
|
||||||
|
|
||||||
// unpacked data
|
// unpacked data
|
||||||
case ".json":
|
case ".json":
|
||||||
|
@ -189,96 +189,5 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
||||||
texture.SetData(data);
|
texture.SetData(data);
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T ModedLoad<T>(string assetName, LanguageCode language){
|
|
||||||
if (language != LanguageCode.en)
|
|
||||||
{
|
|
||||||
string key = assetName + "." + this.LanguageCodeString(language);
|
|
||||||
Dictionary<string, bool> _localizedAsset = this.Reflector.GetField<Dictionary<string, bool>>(this, "_localizedAsset").GetValue();
|
|
||||||
if (!_localizedAsset.TryGetValue(key, out bool flag) | flag)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_localizedAsset[key] = true;
|
|
||||||
return this.ModedLoad<T>(key);
|
|
||||||
}
|
|
||||||
catch (ContentLoadException)
|
|
||||||
{
|
|
||||||
_localizedAsset[key] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.ModedLoad<T>(assetName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T ModedLoad<T>(string assetName)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(assetName))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("assetName");
|
|
||||||
}
|
|
||||||
T local = default(T);
|
|
||||||
string key = assetName.Replace('\\', '/');
|
|
||||||
Dictionary<string, object> loadedAssets = this.Reflector.GetField<Dictionary<string, object>>(this, "loadedAssets").GetValue();
|
|
||||||
if (loadedAssets.TryGetValue(key, out object obj2) && (obj2 is T))
|
|
||||||
{
|
|
||||||
return (T)obj2;
|
|
||||||
}
|
|
||||||
local = this.ReadAsset<T>(assetName, null);
|
|
||||||
loadedAssets[key] = local;
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Stream OpenStream(string assetName)
|
|
||||||
{
|
|
||||||
Stream stream;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
stream = new FileStream(Path.Combine(this.RootDirectory, assetName) + ".xnb", FileMode.Open, FileAccess.Read);
|
|
||||||
MemoryStream destination = new MemoryStream();
|
|
||||||
stream.CopyTo(destination);
|
|
||||||
destination.Seek(0L, SeekOrigin.Begin);
|
|
||||||
stream.Close();
|
|
||||||
stream = destination;
|
|
||||||
}
|
|
||||||
catch (Exception exception3)
|
|
||||||
{
|
|
||||||
throw new ContentLoadException("Opening stream error.", exception3);
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
protected new T ReadAsset<T>(string assetName, Action<IDisposable> recordDisposableObject)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(assetName))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("assetName");
|
|
||||||
}
|
|
||||||
;
|
|
||||||
string str = assetName;
|
|
||||||
object obj2 = null;
|
|
||||||
if (this.Reflector.GetField<IGraphicsDeviceService>(this, "graphicsDeviceService").GetValue() == null)
|
|
||||||
{
|
|
||||||
this.Reflector.GetField<IGraphicsDeviceService>(this, "graphicsDeviceService").SetValue(this.ServiceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService);
|
|
||||||
}
|
|
||||||
Stream input = this.OpenStream(assetName);
|
|
||||||
using (BinaryReader reader = new BinaryReader(input))
|
|
||||||
{
|
|
||||||
using (ContentReader reader2 = this.Reflector.GetMethod(this, "GetContentReaderFromXnb").Invoke<ContentReader>(assetName, input, reader, recordDisposableObject))
|
|
||||||
{
|
|
||||||
MethodInfo method = reader2.GetType().GetMethod("ReadAsset", BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic, null, new Type[] { }, new ParameterModifier[] { });
|
|
||||||
obj2 = method.MakeGenericMethod(new Type[] { typeof(T) }).Invoke(reader2, null);
|
|
||||||
if (obj2 is GraphicsResource graphics)
|
|
||||||
{
|
|
||||||
graphics.Name = str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (obj2 == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Could not load " + str + " asset!");
|
|
||||||
}
|
|
||||||
return (T)obj2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ using StardewModdingAPI.Toolkit.Utilities;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
using xTile;
|
using xTile;
|
||||||
using xTile.Format;
|
using xTile.Format;
|
||||||
|
using xTile.ObjectModel;
|
||||||
using xTile.Tiles;
|
using xTile.Tiles;
|
||||||
|
|
||||||
namespace StardewModdingAPI.Framework.ModHelpers
|
namespace StardewModdingAPI.Framework.ModHelpers
|
||||||
|
@ -247,7 +248,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
||||||
return;
|
return;
|
||||||
relativeMapPath = this.ModContentManager.AssertAndNormaliseAssetName(relativeMapPath); // Mono's Path.GetDirectoryName doesn't handle Windows dir separators
|
relativeMapPath = this.ModContentManager.AssertAndNormaliseAssetName(relativeMapPath); // Mono's Path.GetDirectoryName doesn't handle Windows dir separators
|
||||||
string relativeMapFolder = Path.GetDirectoryName(relativeMapPath) ?? ""; // folder path containing the map, relative to the mod folder
|
string relativeMapFolder = Path.GetDirectoryName(relativeMapPath) ?? ""; // folder path containing the map, relative to the mod folder
|
||||||
|
bool isOutdoors = map.Properties.TryGetValue("Outdoors", out PropertyValue outdoorsProperty) && outdoorsProperty != null;
|
||||||
// fix tilesheets
|
// fix tilesheets
|
||||||
foreach (TileSheet tilesheet in map.TileSheets)
|
foreach (TileSheet tilesheet in map.TileSheets)
|
||||||
{
|
{
|
||||||
|
@ -259,7 +260,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
||||||
|
|
||||||
// get seasonal name (if applicable)
|
// get seasonal name (if applicable)
|
||||||
string seasonalImageSource = null;
|
string seasonalImageSource = null;
|
||||||
if (Context.IsSaveLoaded && Game1.currentSeason != null)
|
if (isOutdoors && Context.IsSaveLoaded && Game1.currentSeason != null)
|
||||||
{
|
{
|
||||||
string filename = Path.GetFileName(imageSource) ?? throw new InvalidOperationException($"The '{imageSource}' tilesheet couldn't be loaded: filename is unexpectedly null.");
|
string filename = Path.GetFileName(imageSource) ?? throw new InvalidOperationException($"The '{imageSource}' tilesheet couldn't be loaded: filename is unexpectedly null.");
|
||||||
bool hasSeasonalPrefix =
|
bool hasSeasonalPrefix =
|
||||||
|
|
|
@ -318,7 +318,8 @@ namespace StardewModdingAPI.Framework.ModLoading
|
||||||
// rewrite type scopes to use target assemblies
|
// rewrite type scopes to use target assemblies
|
||||||
IEnumerable<TypeReference> typeReferences = module.GetTypeReferences().OrderBy(p => p.FullName);
|
IEnumerable<TypeReference> typeReferences = module.GetTypeReferences().OrderBy(p => p.FullName);
|
||||||
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.CustomAttributes)));
|
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.CustomAttributes)));
|
||||||
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.Properties.SelectMany(p=>p.CustomAttributes))));
|
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.Methods.SelectMany(p => p.CustomAttributes))));
|
||||||
|
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.Properties.SelectMany(p => p.CustomAttributes))));
|
||||||
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.Fields.SelectMany(p => p.CustomAttributes))));
|
typeReferences = typeReferences.Concat(module.Types.SelectMany(t => this.GetAttributeTypes(t.Fields.SelectMany(p => p.CustomAttributes))));
|
||||||
foreach (TypeReference type in typeReferences)
|
foreach (TypeReference type in typeReferences)
|
||||||
this.ChangeTypeScope(type);
|
this.ChangeTypeScope(type);
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace StardewModdingAPI.Framework.ModLoading
|
||||||
public static bool IsSameType(Type type, TypeReference reference)
|
public static bool IsSameType(Type type, TypeReference reference)
|
||||||
{
|
{
|
||||||
// same namespace & name
|
// same namespace & name
|
||||||
if (type.Namespace != reference.Namespace || type.Name != reference.Name)
|
if ((type.Namespace != reference.Namespace && reference.Namespace == "" && type.Namespace != reference.DeclaringType.Namespace)|| type.Name != reference.Name)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// same generic parameters
|
// same generic parameters
|
||||||
|
@ -96,12 +96,35 @@ namespace StardewModdingAPI.Framework.ModLoading
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
public static bool HasMatchingSignature(ConstructorInfo definition, MethodReference reference)
|
||||||
|
{
|
||||||
|
// same name
|
||||||
|
if (definition.Name != reference.Name)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// same arguments
|
||||||
|
ParameterInfo[] definitionParameters = definition.GetParameters();
|
||||||
|
ParameterDefinition[] referenceParameters = reference.Parameters.ToArray();
|
||||||
|
if (referenceParameters.Length != definitionParameters.Length)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < referenceParameters.Length; i++)
|
||||||
|
{
|
||||||
|
if (!RewriteHelper.IsSameType(definitionParameters[i].ParameterType, referenceParameters[i].ParameterType))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Get whether a type has a method whose signature matches the one expected by a method reference.</summary>
|
/// <summary>Get whether a type has a method whose signature matches the one expected by a method reference.</summary>
|
||||||
/// <param name="type">The type to check.</param>
|
/// <param name="type">The type to check.</param>
|
||||||
/// <param name="reference">The method reference.</param>
|
/// <param name="reference">The method reference.</param>
|
||||||
public static bool HasMatchingSignature(Type type, MethodReference reference)
|
public static bool HasMatchingSignature(Type type, MethodReference reference)
|
||||||
{
|
{
|
||||||
|
if (reference.Name == ".ctor")
|
||||||
|
{
|
||||||
|
return type.GetConstructors(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
|
||||||
|
.Any(method => RewriteHelper.HasMatchingSignature(method, reference));
|
||||||
|
}
|
||||||
return type
|
return type
|
||||||
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
|
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
|
||||||
.Any(method => RewriteHelper.HasMatchingSignature(method, reference));
|
.Any(method => RewriteHelper.HasMatchingSignature(method, reference));
|
||||||
|
|
|
@ -14,5 +14,11 @@ namespace StardewModdingAPI.Framework.RewriteFacades
|
||||||
{
|
{
|
||||||
return base.couldInventoryAcceptThisItem(item, true);
|
return base.couldInventoryAcceptThisItem(item, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
|
||||||
|
public new bool addItemToInventoryBool(Item item)
|
||||||
|
{
|
||||||
|
return base.addItemToInventoryBool(item, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,5 +31,10 @@ namespace StardewModdingAPI.Framework.RewriteFacades
|
||||||
{
|
{
|
||||||
warpFarmer(locationName, tileX, tileY, facingDirectionAfterWarp, false, true, false);
|
warpFarmer(locationName, tileX, tileY, facingDirectionAfterWarp, false, true, false);
|
||||||
}
|
}
|
||||||
|
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
|
||||||
|
public static new void panScreen(int x, int y)
|
||||||
|
{
|
||||||
|
panScreen(x, y, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using StardewValley;
|
||||||
|
using StardewValley.Menus;
|
||||||
|
|
||||||
|
#pragma warning disable 1591 // missing documentation
|
||||||
|
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 context = null) : base(inventory, reverseGrab, showReceivingMenu, highlightFunction, behaviorOnItemSelectFunction, message,
|
||||||
|
behaviorOnItemGrab, snapToBottom, canBeExitedWithKey, playRightClickSound, allowRightClick, showOrganizeButton, source, sourceItem,
|
||||||
|
whichSpecialButton)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using StardewValley.Menus;
|
||||||
|
|
||||||
|
namespace StardewModdingAPI.Framework.RewriteFacades
|
||||||
|
{
|
||||||
|
public class MapPageMethods : MapPage
|
||||||
|
{
|
||||||
|
public MapPageMethods(int x, int y, int width, int height)
|
||||||
|
: base(x, y, width, height, 1f, 1f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using StardewValley.BellsAndWhistles;
|
||||||
|
|
||||||
|
#pragma warning disable 1591 // missing documentation
|
||||||
|
namespace StardewModdingAPI.Framework.RewriteFacades
|
||||||
|
{
|
||||||
|
public class SpriteTextMethods : SpriteText
|
||||||
|
{
|
||||||
|
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
|
||||||
|
public new static void drawStringHorizontallyCenteredAt(SpriteBatch b, string s, int x, int y, int characterPosition = 0xf423f, int width = -1, int height = 0xf423f, float alpha = 1f, float layerDepth = 0.088f, bool junimoText = false, int color = -1, int maxWidth = 0x1869f)
|
||||||
|
{
|
||||||
|
drawString(b, s, x - (getWidthOfString(s) / 2), y, characterPosition, width, height, alpha, layerDepth, junimoText, -1, "", color);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
|
||||||
|
public new static int getWidthOfString(string s, int widthConstraint = 999999)
|
||||||
|
{
|
||||||
|
return getWidthOfString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
|
||||||
|
public new static void drawStringWithScrollBackground(SpriteBatch b, string s, int x, int y,
|
||||||
|
string placeHolderWidthText = "", float alpha = 1f, int color = -1)
|
||||||
|
{
|
||||||
|
drawStringWithScrollBackground(b, s, x, y, placeHolderWidthText, alpha, color, 0.088f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using StardewValley.Menus;
|
||||||
|
|
||||||
|
#pragma warning disable 1591 // missing documentation
|
||||||
|
namespace StardewModdingAPI.Framework.RewriteFacades
|
||||||
|
{
|
||||||
|
public class TextBoxMethods : TextBox
|
||||||
|
{
|
||||||
|
public TextBoxMethods(Texture2D textboxTexture, Texture2D caretTexture, SpriteFont font, Color textColor)
|
||||||
|
: base(textboxTexture, caretTexture, font, textColor, true, false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -259,7 +259,15 @@ namespace StardewModdingAPI.Framework
|
||||||
SGame.ConstructorHack = new SGameConstructorHack(this.Monitor, this.Reflection, this.Toolkit.JsonHelper, this.InitialiseBeforeFirstAssetLoaded);
|
SGame.ConstructorHack = new SGameConstructorHack(this.Monitor, this.Reflection, this.Toolkit.JsonHelper, this.InitialiseBeforeFirstAssetLoaded);
|
||||||
if(!this.HarmonyDetourBridgeFailed)
|
if(!this.HarmonyDetourBridgeFailed)
|
||||||
{
|
{
|
||||||
HarmonyDetourBridge.Init();
|
try
|
||||||
|
{
|
||||||
|
HarmonyDetourBridge.Init();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
this.HarmonyDetourBridgeFailed = true;
|
||||||
|
this.Monitor.Log("HarmonyDetourBridge Init Failed", LogLevel.Warn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// override game
|
// override game
|
||||||
|
@ -999,7 +1007,7 @@ namespace StardewModdingAPI.Framework
|
||||||
Assembly modAssembly;
|
Assembly modAssembly;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
modAssembly = assemblyLoader.Load(mod, assemblyPath, assumeCompatible: mod.DataRecord?.Status == ModStatus.AssumeCompatible);
|
modAssembly = assemblyLoader.Load(mod, assemblyPath, assumeCompatible:!ModLoader.Common.Constants.CompatCheck || mod.DataRecord?.Status == ModStatus.AssumeCompatible);
|
||||||
this.ModRegistry.TrackAssemblies(mod, modAssembly);
|
this.ModRegistry.TrackAssemblies(mod, modAssembly);
|
||||||
}
|
}
|
||||||
catch (IncompatibleInstructionException) // details already in trace logs
|
catch (IncompatibleInstructionException) // details already in trace logs
|
||||||
|
|
|
@ -261,7 +261,8 @@ namespace StardewModdingAPI.Framework
|
||||||
throw new InvalidOperationException($"The game didn't initialise its first content manager before SMAPI's {nameof(SGame)} constructor. This indicates an incompatible lifecycle change.");
|
throw new InvalidOperationException($"The game didn't initialise its first content manager before SMAPI's {nameof(SGame)} constructor. This indicates an incompatible lifecycle change.");
|
||||||
|
|
||||||
// init XNA
|
// init XNA
|
||||||
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
|
if(GraphicsAdapter.DefaultAdapter.IsProfileSupported(GraphicsProfile.HiDef))
|
||||||
|
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
|
||||||
|
|
||||||
// init SMAPI
|
// init SMAPI
|
||||||
this.Monitor = monitor;
|
this.Monitor = monitor;
|
||||||
|
@ -884,8 +885,8 @@ namespace StardewModdingAPI.Framework
|
||||||
|
|
||||||
if (this.Monitor.IsVerbose)
|
if (this.Monitor.IsVerbose)
|
||||||
{
|
{
|
||||||
string addedText = this.Watchers.LocationsWatcher.Added.Any() ? string.Join(", ", added.Select(p => p.Name)) : "none";
|
string addedText = added.Any() ? string.Join(", ", added.Select(p => p.Name)) : "none";
|
||||||
string removedText = this.Watchers.LocationsWatcher.Removed.Any() ? string.Join(", ", removed.Select(p => p.Name)) : "none";
|
string removedText = removed.Any() ? string.Join(", ", removed.Select(p => p.Name)) : "none";
|
||||||
this.Monitor.Log($"Context: location list changed (added {addedText}; removed {removedText}).", LogLevel.Trace);
|
this.Monitor.Log($"Context: location list changed (added {addedText}; removed {removedText}).", LogLevel.Trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,6 +1111,7 @@ namespace StardewModdingAPI.Framework
|
||||||
#endif
|
#endif
|
||||||
base.Update(gameTime);
|
base.Update(gameTime);
|
||||||
events.UpdateTicked.RaiseEmpty();
|
events.UpdateTicked.RaiseEmpty();
|
||||||
|
events.UnvalidatedUpdateTicked.RaiseEmpty();
|
||||||
this.UpdateCrashTimer.Reset();
|
this.UpdateCrashTimer.Reset();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -1605,7 +1607,8 @@ namespace StardewModdingAPI.Framework
|
||||||
{
|
{
|
||||||
if (((!npc.swimming) && !npc.HideShadow) && (!npc.IsInvisible && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc.getTileLocation())))
|
if (((!npc.swimming) && !npc.HideShadow) && (!npc.IsInvisible && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc.getTileLocation())))
|
||||||
{
|
{
|
||||||
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc.Position + new Vector2(((float)(npc.Sprite.SpriteWidth * 4)) / 2f, (float)(npc.GetBoundingBox().Height + (npc.IsMonster ? 0 : 12)))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc.yJumpOffset) / 40f)) * npc.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc.getStandingY()) / 10000f)) - 1E-06f);
|
if (npc.Sprite != null)
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc.Position + new Vector2(((float)(npc.Sprite.SpriteWidth * 4)) / 2f, (float)(npc.GetBoundingBox().Height + (npc.IsMonster ? 0 : 12)))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc.yJumpOffset) / 40f)) * npc.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc.getStandingY()) / 10000f)) - 1E-06f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1615,7 +1618,8 @@ namespace StardewModdingAPI.Framework
|
||||||
{
|
{
|
||||||
if (((!npc2.swimming) && !npc2.HideShadow) && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc2.getTileLocation()))
|
if (((!npc2.swimming) && !npc2.HideShadow) && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc2.getTileLocation()))
|
||||||
{
|
{
|
||||||
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc2.Position + new Vector2(((float)(npc2.Sprite.SpriteWidth * 4)) / 2f, (float)(npc2.GetBoundingBox().Height + (npc2.IsMonster ? 0 : ((npc2.Sprite.SpriteHeight <= 0x10) ? -4 : 12))))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc2.yJumpOffset) / 40f)) * npc2.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc2.getStandingY()) / 10000f)) - 1E-06f);
|
if (npc2.Sprite != null)
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc2.Position + new Vector2(((float)(npc2.Sprite.SpriteWidth * 4)) / 2f, (float)(npc2.GetBoundingBox().Height + (npc2.IsMonster ? 0 : ((npc2.Sprite.SpriteHeight <= 0x10) ? -4 : 12))))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc2.yJumpOffset) / 40f)) * npc2.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc2.getStandingY()) / 10000f)) - 1E-06f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1651,7 +1655,8 @@ namespace StardewModdingAPI.Framework
|
||||||
{
|
{
|
||||||
if (((!npc3.swimming) && !npc3.HideShadow) && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc3.getTileLocation()))
|
if (((!npc3.swimming) && !npc3.HideShadow) && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc3.getTileLocation()))
|
||||||
{
|
{
|
||||||
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc3.Position + new Vector2(((float)(npc3.Sprite.SpriteWidth * 4)) / 2f, (float)(npc3.GetBoundingBox().Height + (npc3.IsMonster ? 0 : 12)))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc3.yJumpOffset) / 40f)) * npc3.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc3.getStandingY()) / 10000f)) - 1E-06f);
|
if (npc3.Sprite != null)
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc3.Position + new Vector2(((float)(npc3.Sprite.SpriteWidth * 4)) / 2f, (float)(npc3.GetBoundingBox().Height + (npc3.IsMonster ? 0 : 12)))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc3.yJumpOffset) / 40f)) * npc3.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc3.getStandingY()) / 10000f)) - 1E-06f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1661,7 +1666,8 @@ namespace StardewModdingAPI.Framework
|
||||||
{
|
{
|
||||||
if (((!npc4.swimming) && !npc4.HideShadow) && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc4.getTileLocation()))
|
if (((!npc4.swimming) && !npc4.HideShadow) && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(npc4.getTileLocation()))
|
||||||
{
|
{
|
||||||
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc4.Position + new Vector2(((float)(npc4.Sprite.SpriteWidth * 4)) / 2f, (float)(npc4.GetBoundingBox().Height + (npc4.IsMonster ? 0 : 12)))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc4.yJumpOffset) / 40f)) * npc4.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc4.getStandingY()) / 10000f)) - 1E-06f);
|
if (npc4.Sprite != null)
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, npc4.Position + new Vector2(((float)(npc4.Sprite.SpriteWidth * 4)) / 2f, (float)(npc4.GetBoundingBox().Height + (npc4.IsMonster ? 0 : 12)))), new Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)((4f + (((float)npc4.yJumpOffset) / 40f)) * npc4.scale), SpriteEffects.None, Math.Max((float)0f, (float)(((float)npc4.getStandingY()) / 10000f)) - 1E-06f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using StardewModdingAPI.Framework.ModLoading.Finders;
|
||||||
using StardewModdingAPI.Framework.ModLoading.Rewriters;
|
using StardewModdingAPI.Framework.ModLoading.Rewriters;
|
||||||
using StardewModdingAPI.Framework.RewriteFacades;
|
using StardewModdingAPI.Framework.RewriteFacades;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
|
using StardewValley.BellsAndWhistles;
|
||||||
using StardewValley.Menus;
|
using StardewValley.Menus;
|
||||||
|
|
||||||
namespace StardewModdingAPI.Metadata
|
namespace StardewModdingAPI.Metadata
|
||||||
|
@ -59,12 +60,24 @@ namespace StardewModdingAPI.Metadata
|
||||||
|
|
||||||
yield return new FieldToPropertyRewriter(typeof(Game1), "isDebrisWeather");
|
yield return new FieldToPropertyRewriter(typeof(Game1), "isDebrisWeather");
|
||||||
|
|
||||||
|
yield return new FieldToPropertyRewriter(typeof(GameLocation), "debris", "debrisCollection");
|
||||||
|
|
||||||
|
yield return new FieldReplaceRewriter(typeof(Farmer), "daysUntilHouseUpgrade", "daysUntilHouseUpgrade");
|
||||||
|
|
||||||
yield return new MethodParentRewriter(typeof(IClickableMenu), typeof(IClickableMenuMethods));
|
yield return new MethodParentRewriter(typeof(IClickableMenu), typeof(IClickableMenuMethods));
|
||||||
|
|
||||||
yield return new MethodParentRewriter(typeof(Game1), typeof(Game1Methods));
|
yield return new MethodParentRewriter(typeof(Game1), typeof(Game1Methods));
|
||||||
|
|
||||||
yield return new MethodParentRewriter(typeof(Farmer), typeof(FarmerMethods));
|
yield return new MethodParentRewriter(typeof(Farmer), typeof(FarmerMethods));
|
||||||
|
|
||||||
|
yield return new MethodParentRewriter(typeof(TextBox), typeof(TextBoxMethods));
|
||||||
|
|
||||||
|
yield return new MethodParentRewriter(typeof(SpriteText), typeof(SpriteTextMethods));
|
||||||
|
|
||||||
|
yield return new MethodParentRewriter(typeof(ItemGrabMenu), typeof(ItemGrabMenuMethods));
|
||||||
|
|
||||||
|
yield return new MethodParentRewriter(typeof(MapPage), typeof(MapPageMethods));
|
||||||
|
|
||||||
/****
|
/****
|
||||||
** detect mod issues
|
** detect mod issues
|
||||||
****/
|
****/
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using StardewModdingAPI.Framework;
|
|
||||||
using StardewModdingAPI.Framework.Patching;
|
using StardewModdingAPI.Framework.Patching;
|
||||||
using StardewModdingAPI.Framework.Reflection;
|
using StardewModdingAPI.Framework.Reflection;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
|
@ -14,7 +13,7 @@ namespace StardewModdingAPI.Patches
|
||||||
internal class DialogueErrorPatch : IHarmonyPatch
|
internal class DialogueErrorPatch : IHarmonyPatch
|
||||||
{
|
{
|
||||||
/*********
|
/*********
|
||||||
** Private methods
|
** Fields
|
||||||
*********/
|
*********/
|
||||||
/// <summary>Writes messages to the console and log file on behalf of the game.</summary>
|
/// <summary>Writes messages to the console and log file on behalf of the game.</summary>
|
||||||
private static IMonitor MonitorForGame;
|
private static IMonitor MonitorForGame;
|
||||||
|
@ -47,10 +46,10 @@ namespace StardewModdingAPI.Patches
|
||||||
/// <param name="harmony">The Harmony instance.</param>
|
/// <param name="harmony">The Harmony instance.</param>
|
||||||
public void Apply(HarmonyInstance harmony)
|
public void Apply(HarmonyInstance harmony)
|
||||||
{
|
{
|
||||||
ConstructorInfo constructor = AccessTools.Constructor(typeof(Dialogue), new[] { typeof(string), typeof(NPC) });
|
harmony.Patch(
|
||||||
MethodInfo prefix = AccessTools.Method(this.GetType(), nameof(DialogueErrorPatch.Prefix));
|
original: AccessTools.Constructor(typeof(Dialogue), new[] { typeof(string), typeof(NPC) }),
|
||||||
|
prefix: new HarmonyMethod(this.GetType(), nameof(DialogueErrorPatch.Prefix))
|
||||||
harmony.Patch(constructor, new HarmonyMethod(prefix), null);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +71,7 @@ namespace StardewModdingAPI.Patches
|
||||||
IReflectedMethod parseDialogueString = DialogueErrorPatch.Reflection.GetMethod(__instance, "parseDialogueString");
|
IReflectedMethod parseDialogueString = DialogueErrorPatch.Reflection.GetMethod(__instance, "parseDialogueString");
|
||||||
IReflectedMethod checkForSpecialDialogueAttributes = DialogueErrorPatch.Reflection.GetMethod(__instance, "checkForSpecialDialogueAttributes");
|
IReflectedMethod checkForSpecialDialogueAttributes = DialogueErrorPatch.Reflection.GetMethod(__instance, "checkForSpecialDialogueAttributes");
|
||||||
IReflectedField<List<string>> dialogues = DialogueErrorPatch.Reflection.GetField<List<string>>(__instance, "dialogues");
|
IReflectedField<List<string>> dialogues = DialogueErrorPatch.Reflection.GetField<List<string>>(__instance, "dialogues");
|
||||||
|
|
||||||
// replicate base constructor
|
// replicate base constructor
|
||||||
if (dialogues.GetValue() == null)
|
if (dialogues.GetValue() == null)
|
||||||
dialogues.SetValue(new List<string>());
|
dialogues.SetValue(new List<string>());
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using StardewModdingAPI.Framework;
|
|
||||||
using StardewModdingAPI.Framework.Patching;
|
using StardewModdingAPI.Framework.Patching;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using StardewModdingAPI.Enums;
|
using StardewModdingAPI.Enums;
|
||||||
using StardewModdingAPI.Framework;
|
|
||||||
using StardewModdingAPI.Framework.Patching;
|
using StardewModdingAPI.Framework.Patching;
|
||||||
using StardewModdingAPI.Framework.Reflection;
|
using StardewModdingAPI.Framework.Reflection;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
|
|
|
@ -28,13 +28,13 @@ namespace StardewModdingAPI.Patches
|
||||||
// object.getDescription
|
// object.getDescription
|
||||||
harmony.Patch(
|
harmony.Patch(
|
||||||
original: AccessTools.Method(typeof(SObject), nameof(SObject.getDescription)),
|
original: AccessTools.Method(typeof(SObject), nameof(SObject.getDescription)),
|
||||||
prefix: new HarmonyMethod(AccessTools.Method(this.GetType(), nameof(ObjectErrorPatch.Object_GetDescription_Prefix)))
|
prefix: new HarmonyMethod(this.GetType(), nameof(ObjectErrorPatch.Object_GetDescription_Prefix))
|
||||||
);
|
);
|
||||||
|
|
||||||
// IClickableMenu.drawToolTip
|
// IClickableMenu.drawToolTip
|
||||||
harmony.Patch(
|
harmony.Patch(
|
||||||
original: AccessTools.Method(typeof(IClickableMenu), nameof(IClickableMenu.drawToolTip)),
|
original: AccessTools.Method(typeof(IClickableMenu), nameof(IClickableMenu.drawToolTip)),
|
||||||
prefix: new HarmonyMethod(AccessTools.Method(this.GetType(), nameof(ObjectErrorPatch.IClickableMenu_DrawTooltip_Prefix)))
|
prefix: new HarmonyMethod(this.GetType(), nameof(ObjectErrorPatch.IClickableMenu_DrawTooltip_Prefix))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue