Add conditional compilation symbols to switch code between desktop and mobile platform

This commit is contained in:
ZaneYork 2020-08-27 10:23:27 +08:00
parent 28ba6314a5
commit a2cb256360
46 changed files with 314 additions and 190 deletions

View File

@ -9,6 +9,7 @@
<LangVersion>latest</LangVersion>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
<DefineConstants Condition="$(OS) == 'Windows_NT' AND '$(BUILD_FOR_MOBILE)' == ''">$(DefineConstants);SMAPI_FOR_WINDOWS</DefineConstants>
</PropertyGroup>
<ItemGroup>
@ -17,13 +18,14 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!-- if game path is invalid, show one user-friendly error instead of a slew of reference errors -->
<Target Name="ValidateInstallPath" AfterTargets="BeforeBuild">
<Error Condition="!Exists('$(GamePath)')" Text="Failed to find the game install path automatically. You can specify where to find it; see https://smapi.io/package/custom-game-path." />
</Target>
<!-- copy files into game directory and enable debugging -->
<Target Name="CopySmapiFiles" AfterTargets="AfterBuild">
<Target Name="CopySmapiFiles" AfterTargets="AfterBuild" Condition="!$(DefineConstants.Contains('SMAPI_FOR_MOBILE'))">
<CallTarget Targets="CopySMAPI;CopyDefaultMods" />
</Target>
<Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'SMAPI'">

View File

@ -0,0 +1,10 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--set properties -->
<PropertyGroup>
<BUILD_FOR_MOBILE>Google</BUILD_FOR_MOBILE>
<DefineConstants Condition="'$(BUILD_FOR_MOBILE)' == ''">$(DefineConstants);HARMONY_1</DefineConstants>
<DefineConstants Condition="'$(BUILD_FOR_MOBILE)' == 'Google'">$(DefineConstants);SMAPI_FOR_MOBILE;ANDROID_TARGET_GOOGLE;HARMONY_1</DefineConstants>
<DefineConstants Condition="'$(BUILD_FOR_MOBILE)' == 'Amazon'">$(DefineConstants);SMAPI_FOR_MOBILE;ANDROID_TARGET_AMAZON;HARMONY_1</DefineConstants>
<DefineConstants Condition="'$(BUILD_FOR_MOBILE)' == 'Samsung'">$(DefineConstants);SMAPI_FOR_MOBILE;ANDROID_TARGET_SAMSUNG;HARMONY_1</DefineConstants>
</PropertyGroup>
</Project>

View File

@ -1,3 +1,4 @@
#if !SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@ -271,3 +272,4 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
}
}
}
#endif

View File

@ -1,4 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\define-constant.targets" />
<PropertyGroup>
<RootNamespace>StardewModdingAPI.Toolkit</RootNamespace>
<Description>A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods.</Description>
@ -12,13 +13,16 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' == ''">
<PackageReference Include="HtmlAgilityPack" Version="1.11.24" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.0.0" />
<PackageReference Include="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT' AND '$(TargetFramework)' == 'netstandard2.0'" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SMAPI.Toolkit.CoreInterfaces\SMAPI.Toolkit.CoreInterfaces.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Framework\Clients\Wiki\WikiClient.cs" />
</ItemGroup>
<Import Project="..\..\build\common.targets" />
</Project>

View File

@ -24,6 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5
..\build\find-game-folder.targets = ..\build\find-game-folder.targets
..\build\prepare-install-package.targets = ..\build\prepare-install-package.targets
..\build\prepare-nuget-package.targets = ..\build\prepare-nuget-package.targets
..\build\define-constant.targets = ..\build\define-constant.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EB35A917-67B9-4EFA-8DFC-4FB49B3949BB}"

View File

@ -41,14 +41,14 @@ namespace StardewModdingAPI
/// <summary>The absolute path to the folder containing SMAPI's internal files.</summary>
#if SMAPI_FOR_MOBILE
public static readonly string InternalFilesPath = Program.DllSearchPath;
public static readonly string InternalFilesPath = EarlyConstants.ExecutionPath;
#else
public static readonly string InternalFilesPath = Path.Combine(EarlyConstants.ExecutionPath, "smapi-internal");
#endif
/// <summary>The target game platform.</summary>
#if SMAPI_FOR_MOBILE
public static GamePlatform TargetPlatform => GamePlatform.Android;
internal static GamePlatform Platform { get; } = (GamePlatform)Enum.Parse(typeof(GamePlatform), LowLevelEnvironmentUtility.DetectPlatform());
#else
internal static GamePlatform Platform { get; } = (GamePlatform)Enum.Parse(typeof(GamePlatform), LowLevelEnvironmentUtility.DetectPlatform());
#endif
@ -67,7 +67,11 @@ namespace StardewModdingAPI
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
#if SMAPI_FOR_MOBILE
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.6.2.1", true);
#else
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.6.2");
#endif
/// <summary>The minimum supported version of Stardew Valley.</summary>
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.4.5");

View File

@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Threading;
namespace StardewModdingAPI.Framework.Logging
{
@ -11,11 +10,8 @@ namespace StardewModdingAPI.Framework.Logging
** Fields
*********/
/// <summary>The underlying stream writer.</summary>
private StreamWriter Stream;
private readonly StreamWriter Stream;
private readonly int MaxLogSize;
private int logSize;
/*********
** Accessors
@ -29,7 +25,7 @@ namespace StardewModdingAPI.Framework.Logging
*********/
/// <summary>Construct an instance.</summary>
/// <param name="path">The log file to write.</param>
public LogFileManager(string path, int maxLogSize = int.MaxValue)
public LogFileManager(string path)
{
this.Path = path;
@ -41,7 +37,6 @@ namespace StardewModdingAPI.Framework.Logging
// open log file stream
this.Stream = new StreamWriter(path, append: false) { AutoFlush = true };
this.MaxLogSize = maxLogSize;
}
/// <summary>Write a message to the log.</summary>
@ -51,22 +46,6 @@ namespace StardewModdingAPI.Framework.Logging
// always use Windows-style line endings for convenience
// (Linux/Mac editors are fine with them, Windows editors often require them)
this.Stream.Write(message + "\r\n");
Interlocked.Add(ref this.logSize, message.Length + 2);
if(this.logSize > this.MaxLogSize / 2)
{
lock (this)
{
this.Stream.Dispose();
string oldPath = this.Path + ".old";
if (File.Exists(oldPath))
{
File.Delete(oldPath);
}
File.Move(this.Path, this.Path + ".old");
this.Stream = new StreamWriter(this.Path, append: false) { AutoFlush = true };
this.logSize = 0;
}
}
}
/// <summary>Release all resources.</summary>

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Linq;
@ -76,3 +77,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Linq;
@ -16,3 +17,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Linq;
@ -81,3 +82,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
@ -25,3 +26,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -14,3 +15,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
@ -102,3 +103,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -14,3 +15,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Reflection;
using System.Reflection.Emit;
#if HARMONY_2
@ -55,3 +56,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
@ -59,3 +60,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using StardewValley;
@ -104,3 +105,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -15,3 +16,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Linq;
@ -18,3 +19,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Collections.Generic;
using StardewValley;
@ -11,3 +12,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Linq;
@ -30,3 +31,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -25,3 +26,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@ -84,3 +85,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Linq;
@ -15,3 +16,4 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
}
}
#endif

View File

@ -1,14 +1,4 @@
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 Mono.Cecil;
using Mono.Cecil.Cil;
using StardewModdingAPI.Framework.ModLoading.Finders;

View File

@ -137,10 +137,12 @@ namespace StardewModdingAPI.Framework
// write to console
if (this.WriteToConsole && (this.ShowTraceInConsole || level != ConsoleLogLevel.Trace))
this.ConsoleWriter.WriteLine(this.IgnoreChar + consoleMessage, level);
#if SMAPI_FOR_MOBILE
else if (this.ShowTraceInConsole || level != ConsoleLogLevel.Trace)
{
SGameConsole.Instance.WriteLine(consoleMessage, level);
}
#endif
// write to log file
this.LogFile.WriteLine(fullMessage);

View File

@ -1,3 +1,4 @@
#if !SMAPI_FOR_MOBILE
using System;
using Galaxy.Api;
using StardewValley.Network;
@ -49,3 +50,4 @@ namespace StardewModdingAPI.Framework.Networking
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if !SMAPI_FOR_MOBILE
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
@ -72,3 +73,4 @@ namespace StardewModdingAPI.Framework.Networking
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if !SMAPI_FOR_MOBILE
using System;
using StardewValley.Network;
@ -48,3 +49,4 @@ namespace StardewModdingAPI.Framework.Networking
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if !SMAPI_FOR_MOBILE
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
@ -66,3 +67,4 @@ namespace StardewModdingAPI.Framework.Networking
}
}
}
#endif

View File

@ -2,7 +2,9 @@ using System;
#if HARMONY_2
using HarmonyLib;
#else
#if SMAPI_FOR_MOBILE
using MonoMod.RuntimeDetour;
#endif
using Harmony;
#endif
@ -35,6 +37,7 @@ namespace StardewModdingAPI.Framework.Patching
#if HARMONY_2
Harmony harmony = new Harmony("SMAPI");
#else
#if SMAPI_FOR_MOBILE
if (!HarmonyDetourBridge.Initialized && Constants.HarmonyEnabled)
{
try {
@ -42,10 +45,12 @@ namespace StardewModdingAPI.Framework.Patching
}
catch { Constants.HarmonyEnabled = false; }
}
#endif
HarmonyInstance harmony = HarmonyInstance.Create("SMAPI");
#endif
foreach (IHarmonyPatch patch in patches)
{
#if SMAPI_FOR_MOBILE
try
{
if(Constants.HarmonyEnabled)
@ -57,6 +62,17 @@ namespace StardewModdingAPI.Framework.Patching
this.Monitor.Log($"Couldn't apply runtime patch '{patch.Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error);
this.Monitor.Log(ex.GetLogSummary(), LogLevel.Trace);
}
#else
try
{
patch.Apply(harmony);
}
catch (Exception ex)
{
this.Monitor.Log($"Couldn't apply runtime patch '{patch.Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error);
this.Monitor.Log(ex.GetLogSummary(), LogLevel.Trace);
}
#endif
}
}
}

View File

@ -47,6 +47,10 @@ using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Toolkit.Utilities;
using StardewModdingAPI.Utilities;
using StardewValley;
using StardewValley.Menus;
#if SMAPI_FOR_MOBILE
using StardewValley.Mobile;
#endif
using SObject = StardewValley.Object;
namespace StardewModdingAPI.Framework
@ -88,14 +92,14 @@ namespace StardewModdingAPI.Framework
private readonly CommandManager CommandManager = new CommandManager();
/// <summary>The underlying game instance.</summary>
#if SMAPI_FOR_MOBILE
internal SGame Game;
#else
private SGame Game;
#endif
/// <summary>Manages input visible to the game.</summary>
private SInputState Input => SGame.Input;
#if SMAPI_FOR_MOBILE
public SGame GameInstance;
#endif
/// <summary>The game's core multiplayer utility.</summary>
private SMultiplayer Multiplayer => SGame.Multiplayer;
@ -208,19 +212,11 @@ namespace StardewModdingAPI.Framework
this.LogManager.LogIntro(modsPath, this.Settings.GetCustomSettings());
// validate platform
#if SMAPI_FOR_WINDOWS
if (Constants.Platform != Platform.Windows)
{
this.Monitor.Log("Oops! You're running Windows, but this version of SMAPI is for Linux or Mac. Please reinstall SMAPI to fix this.", LogLevel.Error);
this.LogManager.PressAnyKeyToExit();
}
#else
if (Constants.Platform == Platform.Windows)
{
this.Monitor.Log($"Oops! You're running {Constants.Platform}, but this version of SMAPI is for Windows. Please reinstall SMAPI to fix this.", LogLevel.Error);
this.PressAnyKeyToExit();
}
#endif
}
/// <summary>Launch SMAPI.</summary>
@ -310,9 +306,7 @@ namespace StardewModdingAPI.Framework
catch (Exception ex)
{
this.Monitor.Log($"SMAPI failed to initialize: {ex.GetLogSummary()}", LogLevel.Error);
#if !SMAPI_FOR_MOBILE
this.LogManager.PressAnyKeyToExit();
#endif
return;
}
@ -336,9 +330,7 @@ namespace StardewModdingAPI.Framework
catch (Exception ex)
{
this.LogManager.LogFatalLaunchError(ex);
#if !SMAPI_FOR_MOBILE
this.LogManager.PressAnyKeyToExit();
#endif
}
finally
{
@ -396,10 +388,10 @@ namespace StardewModdingAPI.Framework
xTile.Format.FormatManager.Instance.RegisterMapFormat(new TMXTile.TMXFormat(Game1.tileSize / Game1.pixelZoom, Game1.tileSize / Game1.pixelZoom, Game1.pixelZoom, Game1.pixelZoom));
#if SMAPI_FOR_MOBILE
this.GameInstance.IsGameSuspended = true;
this.Game.IsGameSuspended = true;
new Thread(() =>
{
while (!this.GameInstance.IsAfterInitialize)
while (!this.Game.IsAfterInitialize)
Thread.Sleep(10);
#endif
// load mod data
@ -442,7 +434,7 @@ namespace StardewModdingAPI.Framework
this.LogManager.SetConsoleTitle($"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GameVersion} with {modsLoaded} mods");
#else
SGameConsole.Instance.isVisible = false;
this.GameInstance.IsGameSuspended = false;
this.Game.IsGameSuspended = false;
}).Start();
#endif
}
@ -491,10 +483,10 @@ namespace StardewModdingAPI.Framework
private void OnGameUpdating(GameTime gameTime, Action runGameUpdate)
{
#if SMAPI_FOR_MOBILE
if (this.IsGameSuspended)
if (this.Game.IsGameSuspended)
{
if (!this.IsAfterInitialize)
this.IsAfterInitialize = true;
if (!this.Game.IsAfterInitialize)
this.Game.IsAfterInitialize = true;
return;
}
@ -1068,7 +1060,6 @@ namespace StardewModdingAPI.Framework
if (!this.UpdateCrashTimer.Decrement())
this.ExitGameImmediately("The game crashed when updating, and SMAPI was unable to recover the game.");
}
#endif
}
/// <summary>Handle the game changing locale.</summary>
@ -1288,7 +1279,7 @@ namespace StardewModdingAPI.Framework
// show update message on next launch
if (updateFound != null)
this.LogManager.WriteUpdateMarker(updateFound.ToString());
#endif
// check mod versions
if (mods.Any())
{

View File

@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AppCenter.Crashes;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewModdingAPI.Enums;
using StardewModdingAPI.Events;
using StardewModdingAPI.Framework.Content;
using StardewModdingAPI.Framework.Events;
using StardewModdingAPI.Framework.Input;
using StardewModdingAPI.Framework.Reflection;
@ -18,7 +15,6 @@ using StardewValley.BellsAndWhistles;
using StardewValley.Locations;
using StardewValley.Menus;
using StardewValley.Minigames;
using StardewValley.Mobile;
using StardewValley.Tools;
using xTile.Dimensions;
using xTile.Layers;
@ -219,6 +215,7 @@ namespace StardewModdingAPI.Framework
/// <param name="gameTime">A snapshot of the game timing state.</param>
/// <param name="target_screen">The render target, if any.</param>
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "copied from game code as-is")]
#if SMAPI_FOR_MOBILE
protected override void _draw(GameTime gameTime, RenderTarget2D target_screen, RenderTarget2D toBuffer = null)
{
Context.IsInDrawLoop = true;
@ -292,6 +289,44 @@ namespace StardewModdingAPI.Framework
Context.IsInDrawLoop = false;
}
#else
protected override void _draw(GameTime gameTime, RenderTarget2D target_screen)
{
Context.IsInDrawLoop = true;
try
{
this.DrawImpl(gameTime, target_screen);
this.DrawCrashTimer.Reset();
}
catch (Exception ex)
{
// log error
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
// exit if irrecoverable
if (!this.DrawCrashTimer.Decrement())
{
this.ExitGameImmediately("The game crashed when drawing, and SMAPI was unable to recover the game.");
return;
}
// recover sprite batch
try
{
if (Game1.spriteBatch.IsOpen(this.Reflection))
{
this.Monitor.Log("Recovering sprite batch from error...");
Game1.spriteBatch.End();
}
}
catch (Exception innerEx)
{
this.Monitor.Log($"Could not recover sprite batch state: {innerEx.GetLogSummary()}", LogLevel.Error);
}
}
Context.IsInDrawLoop = false;
}
#endif
/// <summary>Replicate the game's draw logic with some changes for SMAPI.</summary>
/// <param name="gameTime">A snapshot of the game timing state.</param>
@ -763,8 +798,8 @@ namespace StardewModdingAPI.Framework
}
Dictionary<string, string> dictionary5 = dictionary1;
ErrorAttachmentLog[] errorAttachmentLogArray = Array.Empty<ErrorAttachmentLog>();
Crashes.TrackError(ex, dictionary5, errorAttachmentLogArray);
Microsoft.AppCenter.Crashes.ErrorAttachmentLog[] errorAttachmentLogArray = Array.Empty<Microsoft.AppCenter.Crashes.ErrorAttachmentLog>();
Microsoft.AppCenter.Crashes.Crashes.TrackError(ex, dictionary5, errorAttachmentLogArray);
}
}

View File

@ -63,7 +63,11 @@ namespace StardewModdingAPI.Framework.StateTracking
// init watchers
this.BuildingsWatcher = location is BuildableGameLocation buildableLocation ? WatcherFactory.ForNetCollection(buildableLocation.buildings) : WatcherFactory.ForImmutableCollection<Building>();
#if SMAPI_FOR_MOBILE
this.DebrisWatcher = WatcherFactory.ForNetCollection(location.debris.debrisNetCollection);
#else
this.DebrisWatcher = WatcherFactory.ForNetCollection(location.debris);
#endif
this.LargeTerrainFeaturesWatcher = WatcherFactory.ForNetCollection(location.largeTerrainFeatures);
this.NpcsWatcher = WatcherFactory.ForNetCollection(location.characters);
this.ObjectsWatcher = WatcherFactory.ForNetDictionary(location.netObjects);

View File

@ -427,7 +427,11 @@ namespace StardewModdingAPI.Metadata
return true;
case "tilesheets\\tools": // Game1.ResetToolSpriteSheet
#if SMAPI_FOR_MOBILE
Game1.toolSpriteSheet = content.Load<Texture2D>(key);
#else
Game1.ResetToolSpriteSheet();
#endif
return true;
case "tilesheets\\weapons": // Game1.LoadContent

View File

@ -50,6 +50,7 @@ namespace StardewModdingAPI.Metadata
if (platformChanged)
yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade));
#if SMAPI_FOR_MOBILE
// Redirect reference
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "isRaining", "IsRainingProp");
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "isSnowing", "IsSnowingProp");
@ -112,16 +113,9 @@ namespace StardewModdingAPI.Metadata
//Field Rewriters
yield return new FieldReplaceRewriter(typeof(ItemGrabMenu), "context", "specialObject");
#endif
// rewrite for Stardew Valley 1.3
yield return new StaticFieldToConstantRewriter<int>(typeof(Game1), "tileSize", Game1.tileSize);
yield return new FieldToPropertyRewriter(typeof(Game1), "player");
yield return new FieldToPropertyRewriter(typeof(Game1), "currentLocation");
yield return new FieldToPropertyRewriter(typeof(Character), "currentLocation");
yield return new FieldToPropertyRewriter(typeof(Farmer), "currentLocation");
yield return new FieldToPropertyRewriter(typeof(Game1), "gameMode");
yield return new FieldToPropertyRewriter(typeof(Game1), "currentMinigame");
yield return new FieldToPropertyRewriter(typeof(Game1), "activeClickableMenu");
yield return new FieldToPropertyRewriter(typeof(Game1), "stats");
// generic rewrites
yield return new FieldToPropertyRewriter(this.ValidateReferencesToAssemblies);
@ -132,6 +126,7 @@ namespace StardewModdingAPI.Metadata
yield return new Harmony1AssemblyRewriter();
#endif
#if SMAPI_FOR_MOBILE
// MonoMod fix
if (!Constants.HarmonyEnabled)
{
@ -145,6 +140,7 @@ namespace StardewModdingAPI.Metadata
yield return new MethodToAnotherStaticMethodRewriter(typeof(HarmonyInstance), (method) => method.Name == "PatchAll" && method.Parameters.Count == 1, typeof(HarmonyInstanceMethods), "PatchAllToAssembly");
#endif
}
#endif
/****
** detect mod issues

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Diagnostics.CodeAnalysis;
#if HARMONY_2
@ -91,3 +92,4 @@ namespace StardewModdingAPI.Patches
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
@ -86,3 +87,4 @@ namespace StardewModdingAPI.Patches
}
#endif
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
@ -117,3 +118,4 @@ namespace StardewModdingAPI.Patches
#endif
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@ -208,3 +209,4 @@ namespace StardewModdingAPI.Patches
#endif
}
}
#endif

View File

@ -2,6 +2,7 @@ using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
#if SMAPI_FOR_MOBILE
using Android.App;
@ -13,7 +14,6 @@ using StardewModdingAPI.Framework;
[assembly: InternalsVisibleTo("SMAPI.Tests")]
[assembly: InternalsVisibleTo("ConsoleCommands")] // for performance monitoring commands
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Moq for unit testing
namespace StardewModdingAPI
{
/// <summary>The main entry point for SMAPI, responsible for hooking into and launching the game.</summary>
@ -36,10 +36,13 @@ namespace StardewModdingAPI
try
{
AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve;
//Program.AssertGamePresent();
//Program.AssertGameVersion();
#if SMAPI_FOR_MOBILE
Program.AssertAndroidGameVersion();
//Program.Start(args);
#else
Program.AssertGamePresent();
Program.AssertGameVersion();
Program.Start(args);
#endif
}
catch (BadImageFormatException ex) when (ex.FileName == "StardewValley" || ex.FileName == "Stardew Valley") // don't use EarlyConstants.GameAssemblyName, since we want to check both possible names
{
@ -175,8 +178,10 @@ namespace StardewModdingAPI
if (showMessage)
Console.WriteLine("Game has ended. Press any key to exit.");
Thread.Sleep(100);
#if !SMAPI_FOR_MOBILE
Console.ReadKey();
Environment.Exit(0);
#endif
}
}
}

View File

@ -1,30 +1,5 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SMAPI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SMAPI")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("SMAPI.Tests")]
[assembly: InternalsVisibleTo("ConsoleCommands")] // for performance monitoring commands
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Moq for unit testing

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System;
using Android.App;
using Android.OS;
@ -72,3 +73,4 @@ namespace StardewModdingAPI
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
@ -107,10 +108,10 @@ namespace StardewModdingAPI
this.isVisible = false;
Game1.activeClickableMenu = null;
Game1.playSound("bigDeSelect");
SGame.instance.CommandQueue.Enqueue(command);
SMainActivity.Instance.core.CommandQueue.Enqueue(command);
return;
}
SGame.instance.CommandQueue.Enqueue(command);
SMainActivity.Instance.core.CommandQueue.Enqueue(command);
}
}
@ -272,3 +273,4 @@ namespace StardewModdingAPI
}
}
}
#endif

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!--<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">-->
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\define-constant.targets" />
<PropertyGroup Condition="'$(BUILD_FOR_MOBILE)' != ''">
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
@ -19,32 +21,99 @@
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU' AND '$(BUILD_FOR_MOBILE)' != ''">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;ANDROID_TARGET_AMAZON;HARMONY_1;SMAPI_FOR_MOBILE</DefineConstants>
<!-- <DefineConstants>TRACE;DEBUG;ANDROID_TARGET_SAMSUNG;HARMONY_1;SMAPI_FOR_MOBILE</DefineConstants>-->
<!-- <DefineConstants>TRACE;DEBUG;ANDROID_TARGET_GOOGLE;HARMONY_1;SMAPI_FOR_MOBILE</DefineConstants>-->
<DefineConstants>$(DefineConstants);TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>8.0</LangVersion>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a;x86_64</AndroidSupportedAbis>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU' AND '$(BUILD_FOR_MOBILE)' != ''">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<!-- <DefineConstants>ANDROID_TARGET_AMAZON;HARMONY_1;SMAPI_FOR_MOBILE</DefineConstants>-->
<DefineConstants>ANDROID_TARGET_SAMSUNG;HARMONY_1;SMAPI_FOR_MOBILE</DefineConstants>
<!-- <DefineConstants>ANDROID_TARGET_GOOGLE;HARMONY_1;SMAPI_FOR_MOBILE</DefineConstants>-->
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>8.0</LangVersion>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a;x86_64</AndroidSupportedAbis>
</PropertyGroup>
<PropertyGroup Condition="'$(BUILD_FOR_MOBILE)' == ''">
<AssemblyName>StardewModdingAPI</AssemblyName>
<RootNamespace>StardewModdingAPI</RootNamespace>
<Description>The modding API for Stardew Valley.</Description>
<TargetFramework>net45</TargetFramework>
<PlatformTarget>x86</PlatformTarget>
<OutputType>Exe</OutputType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LargeAddressAware Condition="'$(OS)' == 'Windows_NT'">true</LargeAddressAware>
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' == ''">
<PackageReference Include="LargeAddressAware" Version="1.0.5" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Platonymous.TMXTile" Version="1.3.8" />
</ItemGroup>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' == ''">
<Reference Include="..\..\build\0Harmony.dll" Private="True" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="False" />
<Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="False" />
<Reference Include="System.Numerics" Private="True" />
<Reference Include="System.Runtime.Caching" Private="True" />
<Reference Include="GalaxyCSharp" HintPath="$(GamePath)\GalaxyCSharp.dll" Private="False" />
<Reference Include="Lidgren.Network" HintPath="$(GamePath)\Lidgren.Network.dll" Private="False" />
<Reference Include="xTile" HintPath="$(GamePath)\xTile.dll" Private="False" />
</ItemGroup>
<Choose>
<!-- Windows -->
<When Condition="$(OS) == 'Windows_NT' AND '$(BUILD_FOR_MOBILE)' == ''">
<ItemGroup Condition="!$(DefineConstants.Contains('SMAPI_FOR_MOBILE'))">
<Reference Include="Netcode" HintPath="$(GamePath)\Netcode.dll" Private="False" />
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="False" />
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="False" />
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="False" />
<Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="False" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
</When>
<!-- Linux/Mac -->
<Otherwise>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' == ''">
<Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="False" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' == ''">
<ProjectReference Include="..\SMAPI.Toolkit.CoreInterfaces\SMAPI.Toolkit.CoreInterfaces.csproj" />
<ProjectReference Include="..\SMAPI.Toolkit\SMAPI.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="SMAPI.config.json" CopyToOutputDirectory="PreserveNewest" />
<Content Include="..\SMAPI.Web\wwwroot\SMAPI.metadata.json" Link="SMAPI.metadata.json" CopyToOutputDirectory="PreserveNewest" />
<None Update="i18n\*" CopyToOutputDirectory="PreserveNewest" />
<None Update="steam_appid.txt" CopyToOutputDirectory="PreserveNewest" />
<Compile Include="..\SMAPI.Toolkit\Framework\LowLevelEnvironmentUtility.cs" Link="Framework\Utilities\LowLevelEnvironmentUtility.cs" />
<Compile Remove="Resources\Resource.designer.cs" Condition="'$(BUILD_FOR_MOBILE)' == ''" />
</ItemGroup>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' != ''">
<PackageReference Include="Microsoft.AppCenter">
<Version>3.0.0</Version>
</PackageReference>
@ -70,11 +139,10 @@
<PackageReference Include="LargeAddressAware" Version="1.0.5" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.3" />
</ItemGroup>
<Choose>
<!-- GOOGLE -->
<When Condition="$(DefineConstants.Contains('ANDROID_TARGET_GOOGLE')))">
<ItemGroup>
<ItemGroup Condition="$(DefineConstants.Contains('ANDROID_TARGET_GOOGLE'))">
<!-- <Reference Include="MonoGame.Framework">-->
<!-- <HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\base_1.4.5.145\assemblies\MonoGame.Framework.dll</HintPath>-->
<!-- </Reference>-->
@ -85,10 +153,8 @@
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\base_1.4.5.145\assemblies\StardewValley.GameData.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<!-- SAMSUNG -->
<When Condition="$(DefineConstants.Contains('ANDROID_TARGET_SAMSUNG'))">
<ItemGroup>
<ItemGroup Condition="$(DefineConstants.Contains('ANDROID_TARGET_SAMSUNG'))">
<!-- <Reference Include="MonoGame.Framework">-->
<!-- <HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\samsung_base_1.4.5.144\assemblies\MonoGame.Framework.dll</HintPath>-->
<!-- </Reference>-->
@ -99,10 +165,8 @@
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\samsung_base_1.4.5.144\assemblies\StardewValley.GameData.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<!-- AMAZON -->
<When Condition="$(DefineConstants.Contains('ANDROID_TARGET_AMAZON'))">
<ItemGroup>
<ItemGroup Condition="$(DefineConstants.Contains('ANDROID_TARGET_AMAZON'))">
<!-- <Reference Include="MonoGame.Framework">-->
<!-- <HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\amazon_base_1.4.5.144\assemblies\MonoGame.Framework.dll</HintPath>-->
<!-- </Reference>-->
@ -113,8 +177,8 @@
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\amazon_base_1.4.5.144\assemblies\StardewValley.GameData.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<ItemGroup>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' != ''">
<Reference Include="0Harmony">
<HintPath>..\..\build\0Harmony.dll</HintPath>
</Reference>
@ -146,36 +210,20 @@
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\base_1.4.5.145\assemblies\xTile.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.3" />
</ItemGroup>
<ItemGroup>
<Content Include="SMAPI.config.json" CopyToOutputDirectory="PreserveNewest" />
<Content Include="..\SMAPI.Web\wwwroot\SMAPI.metadata.json" Link="SMAPI.metadata.json" CopyToOutputDirectory="PreserveNewest" />
<None Update="i18n\*" CopyToOutputDirectory="PreserveNewest" />
<None Update="steam_appid.txt" CopyToOutputDirectory="PreserveNewest" />
<Compile Include="..\SMAPI.Toolkit\Framework\LowLevelEnvironmentUtility.cs" Link="Framework\Utilities\LowLevelEnvironmentUtility.cs" />
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' != ''">
<None Include="i18n\*.json" />
<None Include="Resources\AboutResources.txt" />
<None Include="SMAPI.config.json" />
</ItemGroup>
<ItemGroup>
<ItemGroup Condition="'$(BUILD_FOR_MOBILE)' != ''">
<AndroidResource Include="Resources\values\strings.xml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\drawable\" />
</ItemGroup>
<ItemGroup>
<Content Include="i18n\ko.json" />
<Content Include="icon.ico" />
<Content Include="steam_appid.txt" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" Condition="'$(BUILD_FOR_MOBILE)' != ''" />
<Import Project="..\SMAPI.Internal\SMAPI.Internal.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<Import Project="..\..\build\common.targets" />
</Project>

View File

@ -1,3 +1,4 @@
#if SMAPI_FOR_MOBILE
using Android.App;
using Android.Content.PM;
using Android.OS;
@ -34,7 +35,7 @@ namespace StardewModdingAPI
public class SMainActivity : MainActivity, ILicenseCheckerCallback, IJavaObject, IDisposable, IJavaPeerable
#endif
{
private SCore core;
internal SCore core;
private LicenseChecker _licenseChecker;
#if ANDROID_TARGET_GOOGLE
private ServerManagedPolicyExtended _serverManagedPolicyExtended;
@ -161,9 +162,9 @@ namespace StardewModdingAPI
this.core = new SCore(Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, modPath), false);
this.core.RunInteractively();
typeof(MainActivity).GetField("_game1", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(this, this.core.GameInstance);
typeof(MainActivity).GetField("_game1", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(this, this.core.Game);
this.SetContentView((View) this.core.GameInstance.Services.GetService(typeof(View)));
this.SetContentView((View) this.core.Game.Services.GetService(typeof(View)));
this.CheckUsingServerManagedPolicy();
}
@ -263,3 +264,4 @@ namespace StardewModdingAPI
#endif
}
}
#endif