summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-03-22 19:52:42 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-03-22 19:52:42 -0400
commit7ca5efbbc576f3c6c43493654b2a0ac040fd4f31 (patch)
treefae7a4e06a14ff7f8d709e2f4d5b8b92b8784a37
parent5ae640dc91adff8dfb0827e2a3c3f6b54be7c612 (diff)
parent6d1494a56c5d04e7bc1ee406810a5a53dea2229a (diff)
downloadSMAPI-7ca5efbbc576f3c6c43493654b2a0ac040fd4f31.tar.gz
SMAPI-7ca5efbbc576f3c6c43493654b2a0ac040fd4f31.tar.bz2
SMAPI-7ca5efbbc576f3c6c43493654b2a0ac040fd4f31.zip
Merge branch 'develop' into stable
-rw-r--r--build/common.targets2
-rw-r--r--docs/README.md4
-rw-r--r--docs/release-notes.md31
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs28
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/manifest.json4
-rw-r--r--src/SMAPI.Mods.SaveBackup/manifest.json4
-rw-r--r--src/SMAPI.Toolkit/SMAPI.Toolkit.csproj2
-rw-r--r--src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs89
-rw-r--r--src/SMAPI.Web/Framework/LogParsing/LogParser.cs66
-rw-r--r--src/SMAPI.Web/Program.cs2
-rw-r--r--src/SMAPI.Web/SMAPI.Web.csproj12
-rw-r--r--src/SMAPI.Web/Startup.cs3
-rw-r--r--src/SMAPI.Web/Views/JsonValidator/Index.cshtml9
-rw-r--r--src/SMAPI.Web/Views/LogParser/Index.cshtml12
-rw-r--r--src/SMAPI.Web/wwwroot/Content/css/file-upload.css25
-rw-r--r--src/SMAPI.Web/wwwroot/Content/css/json-validator.css25
-rw-r--r--src/SMAPI.Web/wwwroot/Content/css/log-parser.css21
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/file-upload.js71
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/json-validator.js51
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/log-parser.js38
-rw-r--r--src/SMAPI/Constants.cs2
-rw-r--r--src/SMAPI/Events/ButtonPressedEventArgs.cs6
-rw-r--r--src/SMAPI/Events/ButtonReleasedEventArgs.cs6
-rw-r--r--src/SMAPI/Framework/ContentManagers/ModContentManager.cs7
-rw-r--r--src/SMAPI/Framework/Input/GamePadStateBuilder.cs283
-rw-r--r--src/SMAPI/Framework/Input/IInputStateBuilder.cs29
-rw-r--r--src/SMAPI/Framework/Input/KeyboardStateBuilder.cs78
-rw-r--r--src/SMAPI/Framework/Input/MouseStateBuilder.cs107
-rw-r--r--src/SMAPI/Framework/Input/SInputState.cs347
-rw-r--r--src/SMAPI/Framework/ModHelpers/InputHelper.cs4
-rw-r--r--src/SMAPI/Framework/Monitor.cs13
-rw-r--r--src/SMAPI/Framework/Rendering/SDisplayDevice.cs89
-rw-r--r--src/SMAPI/Framework/Rendering/SXnaDisplayDevice.cs121
-rw-r--r--src/SMAPI/Framework/SGame.cs25
-rw-r--r--src/SMAPI/Framework/WatcherCore.cs2
-rw-r--r--src/SMAPI/IMonitor.cs5
-rw-r--r--src/SMAPI/Patches/LoadErrorPatch.cs25
-rw-r--r--src/SMAPI/SMAPI.csproj2
-rw-r--r--src/SMAPI/i18n/hu.json3
39 files changed, 1115 insertions, 538 deletions
diff --git a/build/common.targets b/build/common.targets
index c1617375..b3211aba 100644
--- a/build/common.targets
+++ b/build/common.targets
@@ -4,7 +4,7 @@
<!--set properties -->
<PropertyGroup>
- <Version>3.3.2</Version>
+ <Version>3.4.0</Version>
<Product>SMAPI</Product>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
diff --git a/docs/README.md b/docs/README.md
index 50478b52..546ee6b3 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -66,8 +66,8 @@ default | ✓ [fully translated](../src/SMAPI/i18n/default.json)
Chinese | ✓ [fully translated](../src/SMAPI/i18n/zh.json)
French | ✓ [fully translated](../src/SMAPI/i18n/fr.json)
German | ✓ [fully translated](../src/SMAPI/i18n/de.json)
-Hungarian | ❑ not translated
-Italian | ❑ not translated
+Hungarian | ✓ [fully translated](../src/SMAPI/i18n/hu.json)
+Italian | ✓ [fully translated](../src/SMAPI/i18n/it.json)
Japanese | ✓ [fully translated](../src/SMAPI/i18n/ja.json)
Korean | ❑ not translated
Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 50c6f639..5a5e24d4 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,6 +1,29 @@
&larr; [README](README.md)
# Release notes
+## 3.4
+Released 22 March 2020 for Stardew Valley 1.4.1 or later.
+
+* For players:
+ * Fixed semi-transparency issues on Linux/Mac in recent versions of Mono (e.g. pink shadows).
+ * Fixed `player_add` command error if you have broken XNB mods.
+ * Removed invalid-location check now handled by the game.
+ * Updated translations. Thanks to Annosz (added Hungarian)!
+
+* For modders:
+ * Added support for flipped and rotated map tiles (in collaboration with Platonymous).
+ * Added support for `.tmx` maps using zlib compression (thanks to Platonymous!).
+ * Added `this.Monitor.LogOnce` method.
+ * Mods are no longer prevented from suppressing key presses in the chatbox.
+
+* For the web UI:
+ * Added option to upload files using a file picker.
+ * Optimized log parser for very long multi-line log messages.
+ * Fixed log parser not detecting folder path in recent versions of SMAPI.
+
+* For SMAPI developers:
+ * Added internal API to send custom input to the game/mods. This is mainly meant to support Virtual Keyboard on Android, but might be exposed as a public API in future versions.
+
## 3.3.2
Released 22 February 2020 for Stardew Valley 1.4.1 or later.
@@ -27,6 +50,10 @@ Released 22 February 2020 for Stardew Valley 1.4.1 or later.
* Fixed warning on MacOS when you have no saves yet.
* Reduced log messages.
+* For the web UI:
+ * Updated the JSON validator and Content Patcher schema for `.tmx` support.
+ * The mod compatibility page now has a sticky table header.
+
* For modders:
* Added support for [message sending](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations#Message_sending) to mods on the current computer (in addition to remote computers).
* Added `ExtendImage` method to content API when editing files to resize textures.
@@ -37,10 +64,6 @@ Released 22 February 2020 for Stardew Valley 1.4.1 or later.
* Updated dependencies (including Mono.Cecil 0.11.1 → 0.11.2).
* Fixed dialogue propagation clearing marriage dialogue.
-* For the web UI:
- * Updated the JSON validator and Content Patcher schema for `.tmx` support.
- * The mod compatibility page now has a sticky table header.
-
* For SMAPI/tool developers:
* Improved support for four-part versions to support SMAPI on Android.
* The SMAPI log now prefixes the OS name with `Android` on Android.
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
index 08dd8eed..6a17213c 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
using StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData;
using StardewValley;
using StardewValley.Menus;
@@ -59,13 +60,13 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
yield return this.TryCreate(ItemType.Flooring, id, () => new Wallpaper(id, isFloor: true) { Category = SObject.furnitureCategory });
// equipment
- foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Boots").Keys)
+ foreach (int id in this.TryLoad<int, string>("Data\\Boots").Keys)
yield return this.TryCreate(ItemType.Boots, id, () => new Boots(id));
- foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\hats").Keys)
+ foreach (int id in this.TryLoad<int, string>("Data\\hats").Keys)
yield return this.TryCreate(ItemType.Hat, id, () => new Hat(id));
// weapons
- foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\weapons").Keys)
+ foreach (int id in this.TryLoad<int, string>("Data\\weapons").Keys)
{
yield return this.TryCreate(ItemType.Weapon, id, () => (id >= 32 && id <= 34)
? (Item)new Slingshot(id)
@@ -74,7 +75,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
}
// furniture
- foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Furniture").Keys)
+ foreach (int id in this.TryLoad<int, string>("Data\\Furniture").Keys)
{
if (id == 1466 || id == 1468)
yield return this.TryCreate(ItemType.Furniture, id, () => new TV(id, Vector2.Zero));
@@ -94,7 +95,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
// secret notes
if (id == 79)
{
- foreach (int secretNoteId in Game1.content.Load<Dictionary<int, string>>("Data\\SecretNotes").Keys)
+ foreach (int secretNoteId in this.TryLoad<int, string>("Data\\SecretNotes").Keys)
{
yield return this.TryCreate(ItemType.Object, this.CustomIDOffset + secretNoteId, () =>
{
@@ -233,6 +234,23 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
/*********
** Private methods
*********/
+ /// <summary>Try to load a data file, and return empty data if it's invalid.</summary>
+ /// <typeparam name="TKey">The asset key type.</typeparam>
+ /// <typeparam name="TValue">The asset value type.</typeparam>
+ /// <param name="assetName">The data asset name.</param>
+ private Dictionary<TKey, TValue> TryLoad<TKey, TValue>(string assetName)
+ {
+ try
+ {
+ return Game1.content.Load<Dictionary<TKey, TValue>>(assetName);
+ }
+ catch (ContentLoadException)
+ {
+ // generally due to a player incorrectly replacing a data file with an XNB mod
+ return new Dictionary<TKey, TValue>();
+ }
+ }
+
/// <summary>Create a searchable item if valid.</summary>
/// <param name="type">The item type.</param>
/// <param name="id">The unique ID (if different from the item's parent sheet index).</param>
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index 0e6805dc..dbed84eb 100644
--- a/src/SMAPI.Mods.ConsoleCommands/manifest.json
+++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
- "Version": "3.3.2",
+ "Version": "3.4.0",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
- "MinimumApiVersion": "3.3.2"
+ "MinimumApiVersion": "3.4.0"
}
diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json
index 5165d2b2..dc8bc8d4 100644
--- a/src/SMAPI.Mods.SaveBackup/manifest.json
+++ b/src/SMAPI.Mods.SaveBackup/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
- "Version": "3.3.2",
+ "Version": "3.4.0",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
- "MinimumApiVersion": "3.3.2"
+ "MinimumApiVersion": "3.4.0"
}
diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
index a7de7166..edb1d612 100644
--- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
+++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="HtmlAgilityPack" Version="1.11.20" />
+ <PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="3.3.1" />
<PackageReference Include="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" />
diff --git a/src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs b/src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs
new file mode 100644
index 00000000..42e283a9
--- /dev/null
+++ b/src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Text;
+using StardewModdingAPI.Web.Framework.LogParsing.Models;
+
+namespace StardewModdingAPI.Web.Framework.LogParsing
+{
+ /// <summary>Handles constructing log message instances with minimal memory allocation.</summary>
+ internal class LogMessageBuilder
+ {
+ /*********
+ ** Fields
+ *********/
+ /// <summary>The local time when the next log was posted.</summary>
+ public string Time { get; set; }
+
+ /// <summary>The log level for the next log message.</summary>
+ public LogLevel Level { get; set; }
+
+ /// <summary>The mod name for the next log message.</summary>
+ public string Mod { get; set; }
+
+ /// <summary>The text for the next log message.</summary>
+ private readonly StringBuilder Text = new StringBuilder();
+
+
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Whether the next log message has been started.</summary>
+ public bool Started { get; private set; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Start accumulating values for a new log message.</summary>
+ /// <param name="time">The local time when the log was posted.</param>
+ /// <param name="level">The log level.</param>
+ /// <param name="mod">The mod name.</param>
+ /// <param name="text">The initial log text.</param>
+ /// <exception cref="InvalidOperationException">A log message is already started; call <see cref="Clear"/> before starting a new message.</exception>
+ public void Start(string time, LogLevel level, string mod, string text)
+ {
+ if (this.Started)
+ throw new InvalidOperationException("Can't start new message, previous log message isn't done yet.");
+
+ this.Started = true;
+
+ this.Time = time;
+ this.Level = level;
+ this.Mod = mod;
+ this.Text.Append(text);
+ }
+
+ /// <summary>Add a new line to the next log message being built.</summary>
+ /// <param name="text">The line to add.</param>
+ /// <exception cref="InvalidOperationException">A log message hasn't been started yet.</exception>
+ public void AddLine(string text)
+ {
+ if (!this.Started)
+ throw new InvalidOperationException("Can't add text, no log message started yet.");
+
+ this.Text.Append("\n");
+ this.Text.Append(text);
+ }
+
+ /// <summary>Get a log message for the accumulated values.</summary>
+ public LogMessage Build()
+ {
+ if (!this.Started)
+ return null;
+
+ return new LogMessage
+ {
+ Time = this.Time,
+ Level = this.Level,
+ Mod = this.Mod,
+ Text = this.Text.ToString()
+ };
+ }
+
+ /// <summary>Reset to start a new log message.</summary>
+ public void Clear()
+ {
+ this.Started = false;
+ this.Text.Clear();
+ }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs
index cc91ec51..cce80816 100644
--- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs
+++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs
@@ -201,7 +201,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
}
// mod path line
- else if (message.Level == LogLevel.Debug && this.ModPathPattern.IsMatch(message.Text))
+ else if (message.Level == LogLevel.Info && this.ModPathPattern.IsMatch(message.Text))
{
Match match = this.ModPathPattern.Match(message.Text);
log.ModPath = match.Groups["path"].Value;
@@ -282,43 +282,47 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
/// <exception cref="LogParseException">The log text can't be parsed successfully.</exception>
private IEnumerable<LogMessage> GetMessages(string logText)
{
- LogMessage message = new LogMessage();
- using (StringReader reader = new StringReader(logText))
+ LogMessageBuilder builder = new LogMessageBuilder();
+ using StringReader reader = new StringReader(logText);
+ while (true)
{
- while (true)
- {
- // read data
- string line = reader.ReadLine();
- if (line == null)
- break;
- Match header = this.MessageHeaderPattern.Match(line);
-
- // validate
- if (message.Text == null && !header.Success)
- throw new LogParseException("Found a log message with no SMAPI metadata. Is this a SMAPI log file?");
+ // read line
+ string line = reader.ReadLine();
+ if (line == null)
+ break;
- // start or continue message
- if (header.Success)
- {
- if (message.Text != null)
- yield return message;
+ // match header
+ Match header = this.MessageHeaderPattern.Match(line);
+ bool isNewMessage = header.Success;
- message = new LogMessage
- {
- Time = header.Groups["time"].Value,
- Level = Enum.Parse<LogLevel>(header.Groups["level"].Value, ignoreCase: true),
- Mod = header.Groups["modName"].Value,
- Text = line.Substring(header.Length)
- };
+ // start/continue message
+ if (isNewMessage)
+ {
+ if (builder.Started)
+ {
+ yield return builder.Build();
+ builder.Clear();
}
- else
- message.Text += "\n" + line;
+
+ builder.Start(
+ time: header.Groups["time"].Value,
+ level: Enum.Parse<LogLevel>(header.Groups["level"].Value, ignoreCase: true),
+ mod: header.Groups["modName"].Value,
+ text: line.Substring(header.Length)
+ );
}
+ else
+ {
+ if (!builder.Started)
+ throw new LogParseException("Found a log message with no SMAPI metadata. Is this a SMAPI log file?");
- // end last message
- if (message.Text != null)
- yield return message;
+ builder.AddLine(line);
+ }
}
+
+ // end last message
+ if (builder.Started)
+ yield return builder.Build();
}
}
}
diff --git a/src/SMAPI.Web/Program.cs b/src/SMAPI.Web/Program.cs
index 5856fc98..5d13cdf3 100644
--- a/src/SMAPI.Web/Program.cs
+++ b/src/SMAPI.Web/Program.cs
@@ -16,6 +16,8 @@ namespace StardewModdingAPI.Web
// configure web server
WebHost
.CreateDefaultBuilder(args)
+ .CaptureStartupErrors(true)
+ .UseSetting("detailedErrors", "true")
.UseStartup<Startup>()
.Build()
.Run();
diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj
index 97bea0fb..0a978b30 100644
--- a/src/SMAPI.Web/SMAPI.Web.csproj
+++ b/src/SMAPI.Web/SMAPI.Web.csproj
@@ -12,14 +12,14 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Azure.Storage.Blobs" Version="12.3.0" />
+ <PackageReference Include="Azure.Storage.Blobs" Version="12.4.0" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.9" />
- <PackageReference Include="Hangfire.MemoryStorage" Version="1.6.3" />
- <PackageReference Include="Hangfire.Mongo" Version="0.6.6" />
- <PackageReference Include="HtmlAgilityPack" Version="1.11.20" />
+ <PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
+ <PackageReference Include="Hangfire.Mongo" Version="0.6.7" />
+ <PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
<PackageReference Include="Humanizer.Core" Version="2.7.9" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
- <PackageReference Include="Markdig" Version="0.18.1" />
+ <PackageReference Include="Markdig" Version="0.18.3" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.2.0" />
@@ -27,7 +27,7 @@
<PackageReference Include="Mongo2Go" Version="2.2.12" />
<PackageReference Include="MongoDB.Driver" Version="2.10.2" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.13" />
- <PackageReference Include="Pathoschild.FluentNexus" Version="0.8.0" />
+ <PackageReference Include="Pathoschild.FluentNexus" Version="1.0.0" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="3.3.1" />
</ItemGroup>
<ItemGroup>
diff --git a/src/SMAPI.Web/Startup.cs b/src/SMAPI.Web/Startup.cs
index 29086472..56ef9a79 100644
--- a/src/SMAPI.Web/Startup.cs
+++ b/src/SMAPI.Web/Startup.cs
@@ -192,8 +192,7 @@ namespace StardewModdingAPI.Web
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// basic config
- if (env.IsDevelopment())
- app.UseDeveloperExceptionPage();
+ app.UseDeveloperExceptionPage();
app
.UseCors(policy => policy
.AllowAnyHeader()
diff --git a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
index a00c8387..7287e00b 100644
--- a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
+++ b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
@@ -28,14 +28,16 @@
{
<meta name="robots" content="noindex" />
}
- <link rel="stylesheet" href="~/Content/css/json-validator.css?r=20191204" />
+ <link rel="stylesheet" href="~/Content/css/file-upload.css?r=202002" />
+ <link rel="stylesheet" href="~/Content/css/json-validator.css?r=202002" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/tmont/sunlight@1.22.0/src/themes/sunlight.default.min.css" />
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/gh/tmont/sunlight@1.22.0/src/sunlight.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/gh/tmont/sunlight@1.22.0/src/plugins/sunlight-plugin.linenumbers.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/gh/tmont/sunlight@1.22.0/src/lang/sunlight.javascript.min.js" crossorigin="anonymous"></script>
- <script src="~/Content/js/json-validator.js?r=20191204"></script>
+ <script src="~/Content/js/file-upload.js?r=202002"></script>
+ <script src="~/Content/js/json-validator.js?r=202002"></script>
<script>
$(function() {
smapi.jsonValidator(@Json.Serialize(this.Url.PlainAction("Index", "JsonValidator", new { schemaName = "$schemaName", id = "$id" })), @Json.Serialize(Model.PasteID));
@@ -86,6 +88,7 @@ else if (!isEditView && Model.PasteID != null)
{
<h2>Upload a JSON file</h2>
<form action="@this.Url.PlainAction("PostAsync", "JsonValidator")" method="post">
+ <input id="inputFile" type="file" />
<ol>
<li>
Choose the JSON format:<br />
@@ -97,7 +100,7 @@ else if (!isEditView && Model.PasteID != null)
</select>
</li>
<li>
- Drag the file onto this textbox (or paste the text in):<br />
+ Drag the file onto this textbox <small>(or <a href="#" id="choose-file-link">choose a file</a>)</small>:<br />
<textarea id="input" name="Content" placeholder="paste file here">@Model.Content</textarea>
</li>
<li>
diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml
index 87c7f918..2183992b 100644
--- a/src/SMAPI.Web/Views/LogParser/Index.cshtml
+++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml
@@ -22,10 +22,13 @@
{
<meta name="robots" content="noindex" />
}
- <link rel="stylesheet" href="~/Content/css/log-parser.css?r=20191127" />
+ <link rel="stylesheet" href="~/Content/css/file-upload.css?r=202002" />
+ <link rel="stylesheet" href="~/Content/css/log-parser.css?r=202002" />
+
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" crossorigin="anonymous"></script>
- <script src="~/Content/js/log-parser.js?r=20190515"></script>
+ <script src="~/Content/js/file-upload.js?r=202002"></script>
+ <script src="~/Content/js/log-parser.js?r=202002"></script>
<script>
$(function() {
smapi.logParser({
@@ -135,9 +138,10 @@ else if (Model.ParsedLog?.IsValid == true)
<h2>How do I share my log?</h2>
<form action="@this.Url.PlainAction("PostAsync", "LogParser")" method="post">
+ <input id="inputFile" type="file" />
<ol>
<li>
- Drag the file onto this textbox (or paste the text in):<br />
+ Drag the file onto this textbox <small>(or <a href="#" id="choose-file-link">choose a file</a>)</small>:<br />
<textarea id="input" name="input" placeholder="paste log here"></textarea>
</li>
<li>
@@ -300,7 +304,7 @@ else if (Model.ParsedLog?.IsValid == true)
string sectionFilter = message.Section != null && !message.IsStartOfSection ? $"&& sectionsAllow('{message.Section}')" : null; // filter the message by section if applicable
<tr class="mod @levelStr @sectionStartClass"
- @if (message.IsStartOfSection) { <text> v-on:click="toggleSection('@message.Section')" </text> }
+ @if (message.IsStartOfSection) { <text> v-on:click="toggleSection('@message.Section')" </text> }
v-show="filtersAllow('@Model.GetSlug(message.Mod)', '@levelStr') @sectionFilter">
<td v-pre>@message.Time</td>
<td v-pre>@message.Level.ToString().ToUpper()</td>
diff --git a/src/SMAPI.Web/wwwroot/Content/css/file-upload.css b/src/SMAPI.Web/wwwroot/Content/css/file-upload.css
new file mode 100644
index 00000000..ff170691
--- /dev/null
+++ b/src/SMAPI.Web/wwwroot/Content/css/file-upload.css
@@ -0,0 +1,25 @@
+#inputFile {
+ display: none;
+}
+
+#input {
+ width: 100%;
+ height: 20em;
+ max-height: 70%;
+ margin: auto;
+ box-sizing: border-box;
+ border-radius: 5px;
+ border: 1px solid #000088;
+ outline: none;
+ box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 192, .2);
+}
+
+#submit {
+ font-size: 1.5em;
+ border-radius: 5px;
+ outline: none;
+ box-shadow: inset 0 0 1px 1px rgba(0, 0, 0, .2);
+ cursor: pointer;
+ border: 1px solid #008800;
+ background-color: #cfc;
+}
diff --git a/src/SMAPI.Web/wwwroot/Content/css/json-validator.css b/src/SMAPI.Web/wwwroot/Content/css/json-validator.css
index 18195098..de0f8fed 100644
--- a/