├── .editorconfig ├── .gitattributes ├── .github ├── CONTRIBUTING.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ └── custom.md └── SUPPORT.md ├── .gitignore ├── LICENSE.txt ├── build ├── 0Harmony.dll ├── Mono.Cecil.dll ├── Newtonsoft.Json.dll ├── Pintail.dll ├── ReadOnlyCollectionsExtensions.dll ├── ReadOnlyCollectionsInterfaces.dll ├── SetLargeAddressAware.dll ├── TMXTile.dll ├── common.targets ├── define-constant.targets ├── deploy-local-smapi.targets ├── find-game-folder.targets ├── unix │ ├── prepare-install-package.sh │ └── set-smapi-version.sh └── windows │ ├── finalize-install-package.sh │ ├── lib │ └── in-place-regex.ps1 │ ├── prepare-install-package.ps1 │ └── set-smapi-version.ps1 ├── docs ├── README.md ├── mod-build-config.md ├── release-notes-archived.md ├── release-notes.md └── technical │ ├── mod-package.md │ ├── screenshots │ └── code-analyzer-example.png │ ├── smapi.md │ └── web.md └── src ├── Loader ├── Assets │ └── AboutAssets.txt ├── Loader.csproj ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.designer.cs │ ├── drawable │ │ ├── Splash.png │ │ ├── icon.png │ │ ├── splash_logos_crop.png │ │ └── splash_screen.xml │ ├── mipmap │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ ├── values │ │ ├── colors.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── xml │ │ └── provider_paths.xml └── packages.config ├── MobilePatch ├── Mobile │ ├── EnumerableExtension.cs │ ├── MobileMemoryExtension.cs │ ├── MobileTypeExtension.cs │ └── ReferenceEqualityComparer.cs ├── MobilePatch.csproj ├── Properties │ └── AssemblyInfo.cs └── Resources │ ├── AboutResources.txt │ ├── Resource.Designer.cs │ └── values │ └── strings.xml ├── SMAPI.Installer ├── Enums │ └── ScriptAction.cs ├── Framework │ ├── InstallerContext.cs │ └── InstallerPaths.cs ├── InteractiveInstaller.cs ├── Program.cs ├── SMAPI.Installer.csproj └── assets │ ├── README.txt │ ├── install on Linux.sh │ ├── install on Windows.bat │ ├── install on macOS.command │ ├── runtimeconfig.json │ ├── unix-launcher.sh │ └── windows-exe-config.xml ├── SMAPI.Internal.Patching ├── BasePatcher.cs ├── HarmonyPatcher.cs ├── IPatcher.cs ├── PatchHelper.cs ├── SMAPI.Internal.Patching.projitems └── SMAPI.Internal.Patching.shproj ├── SMAPI.Internal ├── ConsoleWriting │ ├── ColorSchemeConfig.cs │ ├── ColorfulConsoleWriter.cs │ ├── ConsoleLogLevel.cs │ ├── IConsoleWriter.cs │ └── MonitorColorScheme.cs ├── ExceptionHelper.cs ├── SMAPI.Internal.projitems └── SMAPI.Internal.shproj ├── SMAPI.ModBuildConfig.Analyzer.Tests ├── Framework │ ├── DiagnosticResult.cs │ ├── DiagnosticVerifier.Helper.cs │ └── DiagnosticVerifier.cs ├── Mock │ ├── Netcode │ │ ├── NetCollection.cs │ │ ├── NetFieldBase.cs │ │ ├── NetInt.cs │ │ ├── NetList.cs │ │ ├── NetObjectList.cs │ │ └── NetRef.cs │ └── StardewValley │ │ ├── Farmer.cs │ │ ├── Item.cs │ │ └── Object.cs ├── NetFieldAnalyzerTests.cs ├── ObsoleteFieldAnalyzerTests.cs └── SMAPI.ModBuildConfig.Analyzer.Tests.csproj ├── SMAPI.ModBuildConfig.Analyzer ├── AnalyzerReleases.Shipped.md ├── AnalyzerUtilities.cs ├── NetFieldAnalyzer.cs ├── ObsoleteFieldAnalyzer.cs └── SMAPI.ModBuildConfig.Analyzer.csproj ├── SMAPI.ModBuildConfig ├── DeployModTask.cs ├── Framework │ ├── ExtraAssemblyType.cs │ ├── ModFileManager.cs │ └── UserErrorException.cs ├── SMAPI.ModBuildConfig.csproj ├── assets │ ├── nuget-icon.pdn │ └── nuget-icon.png └── build │ └── smapi.targets ├── SMAPI.Mods.ConsoleCommands ├── Framework │ ├── Commands │ │ ├── ArgumentParser.cs │ │ ├── ConsoleCommand.cs │ │ ├── IConsoleCommand.cs │ │ ├── Other │ │ │ ├── ApplySaveFixCommand.cs │ │ │ ├── DebugCommand.cs │ │ │ ├── RegenerateBundles.cs │ │ │ ├── ShowDataFilesCommand.cs │ │ │ ├── ShowGameFilesCommand.cs │ │ │ └── TestInputCommand.cs │ │ ├── Player │ │ │ ├── AddCommand.cs │ │ │ ├── ListItemTypesCommand.cs │ │ │ ├── ListItemsCommand.cs │ │ │ ├── SetColorCommand.cs │ │ │ ├── SetFarmTypeCommand.cs │ │ │ ├── SetHealthCommand.cs │ │ │ ├── SetImmunityCommand.cs │ │ │ ├── SetMaxHealthCommand.cs │ │ │ ├── SetMaxStaminaCommand.cs │ │ │ ├── SetMoneyCommand.cs │ │ │ ├── SetNameCommand.cs │ │ │ ├── SetStaminaCommand.cs │ │ │ └── SetStyleCommand.cs │ │ └── World │ │ │ ├── ClearCommand.cs │ │ │ ├── DownMineLevelCommand.cs │ │ │ ├── FreezeTimeCommand.cs │ │ │ ├── HurryAllCommand.cs │ │ │ ├── SetDayCommand.cs │ │ │ ├── SetMineLevelCommand.cs │ │ │ ├── SetSeasonCommand.cs │ │ │ ├── SetTimeCommand.cs │ │ │ └── SetYearCommand.cs │ ├── ItemData │ │ ├── ItemType.cs │ │ └── SearchableItem.cs │ └── ItemRepository.cs ├── ModEntry.cs ├── SMAPI.Mods.ConsoleCommands.csproj └── manifest.json ├── SMAPI.Mods.ErrorHandler ├── ModEntry.cs ├── ModPatches │ └── PyTkPatcher.cs ├── Patches │ ├── DialoguePatcher.cs │ ├── EventPatcher.cs │ ├── GameLocationPatcher.cs │ ├── IClickableMenuPatcher.cs │ ├── NpcPatcher.cs │ ├── ObjectPatcher.cs │ ├── SaveGamePatcher.cs │ ├── SpriteBatchPatcher.cs │ └── UtilityPatcher.cs ├── SMAPI.Mods.ErrorHandler.csproj ├── i18n │ ├── de.json │ ├── default.json │ ├── es.json │ ├── fr.json │ ├── hu.json │ ├── it.json │ ├── ja.json │ ├── ko.json │ ├── pl.json │ ├── pt.json │ ├── ru.json │ ├── th.json │ ├── tr.json │ ├── uk.json │ └── zh.json └── manifest.json ├── SMAPI.Mods.SaveBackup ├── ModEntry.cs ├── SMAPI.Mods.SaveBackup.csproj └── manifest.json ├── SMAPI.Mods.VirtualKeyboard ├── KeyButton.cs ├── ModConfig.cs ├── ModEntry.cs ├── Properties │ └── AssemblyInfo.cs ├── SMAPI.Mods.VirtualKeyboard.csproj ├── VirtualToggle.cs ├── assets │ └── togglebutton.png └── manifest.json ├── SMAPI.Tests.ModApiConsumer ├── ApiConsumer.cs ├── Interfaces │ └── ISimpleApi.cs ├── README.md └── SMAPI.Tests.ModApiConsumer.csproj ├── SMAPI.Tests.ModApiProvider ├── Framework │ ├── BaseApi.cs │ └── SimpleApi.cs ├── ProviderMod.cs ├── README.md └── SMAPI.Tests.ModApiProvider.csproj ├── SMAPI.Tests ├── Core │ ├── AssetNameTests.cs │ ├── AssumptionTests.cs │ ├── InterfaceProxyTests.cs │ ├── ModResolverTests.cs │ └── TranslationTests.cs ├── SMAPI.Tests.csproj ├── Sample.cs ├── Utilities │ ├── KeybindListTests.cs │ ├── PathUtilitiesTests.cs │ ├── SDateTests.cs │ └── SemanticVersionTests.cs ├── WikiClient │ └── ChangeDescriptorTests.cs └── app.config ├── SMAPI.Toolkit.CoreInterfaces ├── IManifest.cs ├── IManifestContentPackFor.cs ├── IManifestDependency.cs ├── ISemanticVersion.cs └── SMAPI.Toolkit.CoreInterfaces.csproj ├── SMAPI.Toolkit ├── Framework │ ├── Clients │ │ ├── WebApi │ │ │ ├── ModEntryModel.cs │ │ │ ├── ModEntryVersionModel.cs │ │ │ ├── ModExtendedMetadataModel.cs │ │ │ ├── ModSearchEntryModel.cs │ │ │ ├── ModSearchModel.cs │ │ │ └── WebApiClient.cs │ │ └── Wiki │ │ │ ├── ChangeDescriptor.cs │ │ │ ├── WikiClient.cs │ │ │ ├── WikiCompatibilityInfo.cs │ │ │ ├── WikiCompatibilityStatus.cs │ │ │ ├── WikiDataOverrideEntry.cs │ │ │ ├── WikiModEntry.cs │ │ │ └── WikiModList.cs │ ├── Constants.cs │ ├── GameScanning │ │ ├── GameFolderType.cs │ │ └── GameScanner.cs │ ├── LowLevelEnvironmentUtility.cs │ ├── ManifestValidator.cs │ ├── ModData │ │ ├── MetadataModel.cs │ │ ├── ModDataField.cs │ │ ├── ModDataFieldKey.cs │ │ ├── ModDataModel.cs │ │ ├── ModDataRecord.cs │ │ ├── ModDataRecordVersionedFields.cs │ │ ├── ModDatabase.cs │ │ ├── ModStatus.cs │ │ └── ModWarning.cs │ ├── ModScanning │ │ ├── ModFolder.cs │ │ ├── ModParseError.cs │ │ ├── ModScanner.cs │ │ └── ModType.cs │ ├── SemanticVersionReader.cs │ └── UpdateData │ │ ├── ModSiteKey.cs │ │ └── UpdateKey.cs ├── ModToolkit.cs ├── Properties │ └── AssemblyInfo.cs ├── SMAPI.Toolkit.csproj ├── SemanticVersion.cs ├── SemanticVersionComparer.cs ├── Serialization │ ├── Converters │ │ ├── ManifestContentPackForConverter.cs │ │ ├── ManifestDependencyArrayConverter.cs │ │ ├── NonStandardSemanticVersionConverter.cs │ │ ├── SemanticVersionConverter.cs │ │ └── SimpleReadOnlyConverter.cs │ ├── InternalExtensions.cs │ ├── JsonHelper.cs │ ├── Models │ │ ├── Manifest.cs │ │ ├── ManifestContentPackFor.cs │ │ └── ManifestDependency.cs │ └── SParseException.cs └── Utilities │ ├── EnvironmentUtility.cs │ ├── FileUtilities.cs │ ├── PathLookups │ ├── CaseInsensitiveFileLookup.cs │ ├── IFileLookup.cs │ └── MinimalFileLookup.cs │ ├── PathUtilities.cs │ └── Platform.cs ├── SMAPI.Web.LegacyRedirects └── Startup.cs ├── SMAPI.Web ├── BackgroundService.cs ├── Controllers │ ├── IndexController.cs │ ├── JsonValidatorController.cs │ ├── LogParserController.cs │ ├── ModsApiController.cs │ └── ModsController.cs ├── Framework │ ├── AllowLargePostsAttribute.cs │ ├── Caching │ │ ├── BaseCacheRepository.cs │ │ ├── Cached.cs │ │ ├── ICacheRepository.cs │ │ ├── Mods │ │ │ ├── IModCacheRepository.cs │ │ │ └── ModCacheMemoryRepository.cs │ │ └── Wiki │ │ │ ├── IWikiCacheRepository.cs │ │ │ ├── WikiCacheMemoryRepository.cs │ │ │ └── WikiMetadata.cs │ ├── Clients │ │ ├── Chucklefish │ │ │ ├── ChucklefishClient.cs │ │ │ └── IChucklefishClient.cs │ │ ├── CurseForge │ │ │ ├── CurseForgeClient.cs │ │ │ ├── ICurseForgeClient.cs │ │ │ └── ResponseModels │ │ │ │ ├── ModFileModel.cs │ │ │ │ ├── ModLinksModel.cs │ │ │ │ ├── ModModel.cs │ │ │ │ └── ResponseModel.cs │ │ ├── GenericModDownload.cs │ │ ├── GenericModPage.cs │ │ ├── GitHub │ │ │ ├── GitAsset.cs │ │ │ ├── GitHubClient.cs │ │ │ ├── GitLicense.cs │ │ │ ├── GitRelease.cs │ │ │ ├── GitRepo.cs │ │ │ └── IGitHubClient.cs │ │ ├── IModSiteClient.cs │ │ ├── ModDrop │ │ │ ├── IModDropClient.cs │ │ │ ├── ModDropClient.cs │ │ │ └── ResponseModels │ │ │ │ ├── FileDataModel.cs │ │ │ │ ├── ModDataModel.cs │ │ │ │ ├── ModListModel.cs │ │ │ │ └── ModModel.cs │ │ ├── Nexus │ │ │ ├── DisabledNexusClient.cs │ │ │ ├── INexusClient.cs │ │ │ ├── NexusClient.cs │ │ │ ├── NexusModStatus.cs │ │ │ └── ResponseModels │ │ │ │ └── NexusMod.cs │ │ └── Pastebin │ │ │ ├── IPastebinClient.cs │ │ │ ├── PasteInfo.cs │ │ │ └── PastebinClient.cs │ ├── Compression │ │ ├── GzipHelper.cs │ │ └── IGzipHelper.cs │ ├── ConfigModels │ │ ├── ApiClientsConfig.cs │ │ ├── BackgroundServicesConfig.cs │ │ ├── ModCompatibilityListConfig.cs │ │ ├── ModOverrideConfig.cs │ │ ├── ModUpdateCheckConfig.cs │ │ ├── SiteConfig.cs │ │ └── SmapiInfoConfig.cs │ ├── Extensions.cs │ ├── IModDownload.cs │ ├── IModPage.cs │ ├── InternalControllerFeatureProvider.cs │ ├── JobDashboardAuthorizationFilter.cs │ ├── LogParsing │ │ ├── LogMessageBuilder.cs │ │ ├── LogParseException.cs │ │ ├── LogParser.cs │ │ └── Models │ │ │ ├── LogLevel.cs │ │ │ ├── LogMessage.cs │ │ │ ├── LogModInfo.cs │ │ │ ├── LogSection.cs │ │ │ ├── ModType.cs │ │ │ └── ParsedLog.cs │ ├── ModInfoModel.cs │ ├── ModSiteManager.cs │ ├── RedirectRules │ │ ├── RedirectHostsToUrlsRule.cs │ │ ├── RedirectMatchRule.cs │ │ ├── RedirectPathsToUrlsRule.cs │ │ └── RedirectToHttpsRule.cs │ ├── RemoteModStatus.cs │ ├── Storage │ │ ├── IStorageProvider.cs │ │ ├── StorageProvider.cs │ │ ├── StoredFileInfo.cs │ │ └── UploadResult.cs │ └── VersionConstraint.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── SMAPI.Web.csproj ├── Startup.cs ├── ViewModels │ ├── IndexModel.cs │ ├── IndexVersionModel.cs │ ├── JsonValidator │ │ ├── JsonValidatorErrorModel.cs │ │ ├── JsonValidatorModel.cs │ │ └── JsonValidatorRequestModel.cs │ ├── LogParserModel.cs │ ├── LogViewFormat.cs │ ├── ModCompatibilityModel.cs │ ├── ModLinkModel.cs │ ├── ModListModel.cs │ └── ModModel.cs ├── Views │ ├── Index │ │ ├── Index.cshtml │ │ └── Privacy.cshtml │ ├── JsonValidator │ │ └── Index.cshtml │ ├── LogParser │ │ └── Index.cshtml │ ├── Mods │ │ └── Index.cshtml │ ├── Shared │ │ └── _Layout.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── Content │ ├── css │ │ ├── file-upload.css │ │ ├── index.css │ │ ├── json-validator.css │ │ ├── log-parser.css │ │ ├── main.css │ │ ├── mods.css │ │ └── privacy.css │ ├── images │ │ ├── direct-download-icon.png │ │ ├── external │ │ │ ├── patreon-header-help.png │ │ │ ├── patreon-header-upcoming.png │ │ │ └── patreon-header-what-i-do.png │ │ ├── ko-fi.png │ │ ├── nexus-icon.png │ │ ├── patreon.png │ │ ├── paypal.png │ │ ├── pufferchick-cool.svg │ │ ├── pufferchick.svg │ │ └── sidebar-bg.svg │ └── js │ │ ├── file-upload.js │ │ ├── index.js │ │ ├── json-validator.js │ │ ├── log-parser.js │ │ └── mods.js │ ├── SMAPI.metadata.json │ ├── favicon.ico │ └── schemas │ ├── content-patcher.json │ ├── i18n.json │ └── manifest.json ├── SMAPI.sln ├── SMAPI.sln.DotSettings └── SMAPI ├── Constants.cs ├── ContentSource.cs ├── Context.cs ├── Enums ├── LoadStage.cs └── SkillType.cs ├── Events ├── AssetEditPriority.cs ├── AssetLoadPriority.cs ├── AssetReadyEventArgs.cs ├── AssetRequestedEventArgs.cs ├── AssetsInvalidatedEventArgs.cs ├── BuildingListChangedEventArgs.cs ├── ButtonPressedEventArgs.cs ├── ButtonReleasedEventArgs.cs ├── ButtonsChangedEventArgs.cs ├── ChestInventoryChangedEventArgs.cs ├── CursorMovedEventArgs.cs ├── DayEndingEventArgs.cs ├── DayStartedEventArgs.cs ├── DebrisListChangedEventArgs.cs ├── EventPriority.cs ├── EventPriorityAttribute.cs ├── FurnitureListChangedEventArgs.cs ├── GameLaunchedEventArgs.cs ├── IContentEvents.cs ├── IDisplayEvents.cs ├── IGameLoopEvents.cs ├── IInputEvents.cs ├── IModEvents.cs ├── IMultiplayerEvents.cs ├── IPlayerEvents.cs ├── ISpecialisedEvents.cs ├── IWorldEvents.cs ├── InventoryChangedEventArgs.cs ├── ItemStackSizeChange.cs ├── LargeTerrainFeatureListChangedEventArgs.cs ├── LevelChangedEventArgs.cs ├── LoadStageChangedEventArgs.cs ├── LocaleChangedEventArgs.cs ├── LocationListChangedEventArgs.cs ├── MenuChangedEventArgs.cs ├── ModMessageReceivedEventArgs.cs ├── MouseWheelScrolledEventArgs.cs ├── NpcListChangedEventArgs.cs ├── ObjectListChangedEventArgs.cs ├── OneSecondUpdateTickedEventArgs.cs ├── OneSecondUpdateTickingEventArgs.cs ├── PeerConnectedEventArgs.cs ├── PeerContextReceivedEventArgs.cs ├── PeerDisconnectedEventArgs.cs ├── RenderedActiveMenuEventArgs.cs ├── RenderedEventArgs.cs ├── RenderedHudEventArgs.cs ├── RenderedWorldEventArgs.cs ├── RenderingActiveMenuEventArgs.cs ├── RenderingEventArgs.cs ├── RenderingHudEventArgs.cs ├── RenderingWorldEventArgs.cs ├── ReturnedToTitleEventArgs.cs ├── SaveCreatedEventArgs.cs ├── SaveCreatingEventArgs.cs ├── SaveLoadedEventArgs.cs ├── SavedEventArgs.cs ├── SavingEventArgs.cs ├── TerrainFeatureListChangedEventArgs.cs ├── TimeChangedEventArgs.cs ├── UnvalidatedUpdateTickedEventArgs.cs ├── UnvalidatedUpdateTickingEventArgs.cs ├── UpdateTickedEventArgs.cs ├── UpdateTickingEventArgs.cs ├── WarpedEventArgs.cs └── WindowResizedEventArgs.cs ├── Framework ├── Command.cs ├── CommandManager.cs ├── CommandQueue.cs ├── Commands │ ├── HarmonySummaryCommand.cs │ ├── HelpCommand.cs │ ├── IInternalCommand.cs │ └── ReloadI18nCommand.cs ├── Content │ ├── AssetData.cs │ ├── AssetDataForDictionary.cs │ ├── AssetDataForImage.cs │ ├── AssetDataForMap.cs │ ├── AssetDataForObject.cs │ ├── AssetEditOperation.cs │ ├── AssetInfo.cs │ ├── AssetInterceptorChange.cs │ ├── AssetLoadOperation.cs │ ├── AssetName.cs │ ├── AssetOperationGroup.cs │ ├── ContentCache.cs │ ├── RawTextureData.cs │ └── TilesheetReference.cs ├── ContentCoordinator.cs ├── ContentManagers │ ├── BaseContentManager.cs │ ├── GameContentManager.cs │ ├── GameContentManagerForAssetPropagation.cs │ ├── IContentManager.cs │ └── ModContentManager.cs ├── ContentPack.cs ├── CursorPosition.cs ├── Deprecations │ ├── DeprecationLevel.cs │ ├── DeprecationManager.cs │ ├── DeprecationWarning.cs │ └── ImmutableStackTrace.cs ├── Events │ ├── EventManager.cs │ ├── IManagedEvent.cs │ ├── ManagedEvent.cs │ ├── ManagedEventHandler.cs │ ├── ModContentEvents.cs │ ├── ModDisplayEvents.cs │ ├── ModEvents.cs │ ├── ModEventsBase.cs │ ├── ModGameLoopEvents.cs │ ├── ModInputEvents.cs │ ├── ModMultiplayerEvents.cs │ ├── ModPlayerEvents.cs │ ├── ModSpecialisedEvents.cs │ └── ModWorldEvents.cs ├── Exceptions │ ├── ContentLoadErrorType.cs │ ├── SAssemblyLoadFailedException.cs │ └── SContentLoadException.cs ├── ExitState.cs ├── GameVersion.cs ├── IModMetadata.cs ├── Input │ ├── GamePadStateBuilder.cs │ ├── IInputStateBuilder.cs │ ├── KeyboardStateBuilder.cs │ ├── MouseStateBuilder.cs │ └── SInputState.cs ├── InternalExtensions.cs ├── Logging │ ├── InterceptingTextWriter.cs │ ├── LogFileManager.cs │ ├── LogManager.cs │ └── LogOnceCacheKey.cs ├── ModHelpers │ ├── BaseHelper.cs │ ├── CommandHelper.cs │ ├── ContentHelper.cs │ ├── ContentPackHelper.cs │ ├── DataHelper.cs │ ├── GameContentHelper.cs │ ├── InputHelper.cs │ ├── ModContentHelper.cs │ ├── ModHelper.cs │ ├── ModRegistryHelper.cs │ ├── MultiplayerHelper.cs │ ├── ReflectionHelper.cs │ └── TranslationHelper.cs ├── ModLinked.cs ├── ModLoading │ ├── AssemblyDefinitionResolver.cs │ ├── AssemblyLoadStatus.cs │ ├── AssemblyLoader.cs │ ├── AssemblyParseResult.cs │ ├── Finders │ │ ├── EventFinder.cs │ │ ├── FieldFinder.cs │ │ ├── LegacyAssemblyFinder.cs │ │ ├── MethodFinder.cs │ │ ├── PropertyFinder.cs │ │ ├── ReferenceToMemberWithUnexpectedTypeFinder.cs │ │ ├── ReferenceToMissingMemberFinder.cs │ │ ├── TypeAssemblyFinder.cs │ │ └── TypeFinder.cs │ ├── Framework │ │ ├── BaseInstructionHandler.cs │ │ ├── RecursiveRewriter.cs │ │ └── RewriteHelper.cs │ ├── IInstructionHandler.cs │ ├── IncompatibleInstructionException.cs │ ├── InstructionHandleResult.cs │ ├── InvalidModStateException.cs │ ├── ModDependencyStatus.cs │ ├── ModFailReason.cs │ ├── ModMetadata.cs │ ├── ModMetadataStatus.cs │ ├── ModResolver.cs │ ├── PlatformAssemblyMap.cs │ ├── RewriteFacades │ │ ├── AccessToolsFacade.cs │ │ ├── AnimalQueryMenuMethods.cs │ │ ├── CraftingPageMobileMethods.cs │ │ ├── EnumMethods.cs │ │ ├── Game1Methods.cs │ │ ├── GameMenuMethods.cs │ │ ├── HarmonyInstanceFacade.cs │ │ ├── HarmonyInstanceMethods.cs │ │ ├── HarmonyMethodFacade.cs │ │ ├── IClickableMenuMethods.cs │ │ ├── InventoryMenuMethods.cs │ │ ├── ItemGrabMenuMethods.cs │ │ ├── MapPageMethods.cs │ │ ├── MenuWithInventoryMethods.cs │ │ ├── OptionsElementMethods.cs │ │ ├── SoundBankMethods.cs │ │ ├── SpriteBatchFacade.cs │ │ ├── SpriteTextMethods.cs │ │ ├── TextBoxMethods.cs │ │ └── UtilityMethods.cs │ ├── Rewriters │ │ ├── ArchitectureAssemblyRewriter.cs │ │ ├── FieldReplaceRewriter.cs │ │ ├── HarmonyRewriter.cs │ │ ├── HeuristicFieldAccessibilityRewriter.cs │ │ ├── HeuristicFieldRewriter.cs │ │ ├── HeuristicMethodRewriter.cs │ │ ├── MethodParentRewriter.cs │ │ ├── MethodToAnotherStaticMethodRewriter.cs │ │ ├── ModuleReferenceRewriter.cs │ │ ├── PropertyToFieldRewriter.cs │ │ ├── ReferenceToMissingMemberRewriter.cs │ │ ├── TypeFieldToAnotherTypeFieldRewriter.cs │ │ ├── TypeFieldToAnotherTypePropertyRewriter.cs │ │ ├── TypePropertyToAnotherTypeMethodRewriter.cs │ │ └── TypeReferenceRewriter.cs │ ├── Symbols │ │ ├── SymbolReader.cs │ │ ├── SymbolReaderProvider.cs │ │ └── SymbolWriterProvider.cs │ └── TypeReferenceComparer.cs ├── ModRegistry.cs ├── Models │ └── SConfig.cs ├── Monitor.cs ├── Networking │ ├── MessageType.cs │ ├── ModMessageModel.cs │ ├── MultiplayerPeer.cs │ ├── MultiplayerPeerMod.cs │ ├── RemoteContextModModel.cs │ ├── RemoteContextModel.cs │ ├── SGalaxyNetClient.cs │ ├── SGalaxyNetServer.cs │ ├── SLidgrenClient.cs │ └── SLidgrenServer.cs ├── Reflection │ ├── IInterfaceProxyFactory.cs │ ├── InterfaceProxyFactory.cs │ ├── ReflectedField.cs │ ├── ReflectedMethod.cs │ ├── ReflectedProperty.cs │ └── Reflector.cs ├── Rendering │ ├── SDisplayDevice.cs │ └── SXnaDisplayDevice.cs ├── SChatBox.cs ├── SCore.cs ├── SGame.cs ├── SGameRunner.cs ├── SModHooks.cs ├── SMultiplayer.cs ├── Serialization │ ├── ColorConverter.cs │ ├── KeybindConverter.cs │ ├── PointConverter.cs │ ├── RectangleConverter.cs │ └── Vector2Converter.cs ├── Singleton.cs ├── SnapshotDiff.cs ├── SnapshotItemListDiff.cs ├── SnapshotListDiff.cs ├── StateTracking │ ├── ChestTracker.cs │ ├── Comparers │ │ ├── EquatableComparer.cs │ │ ├── GenericEqualsComparer.cs │ │ └── ObjectReferenceComparer.cs │ ├── FieldWatchers │ │ ├── BaseDisposableWatcher.cs │ │ ├── ComparableListWatcher.cs │ │ ├── ComparableWatcher.cs │ │ ├── ImmutableCollectionWatcher.cs │ │ ├── NetCollectionWatcher.cs │ │ ├── NetDictionaryWatcher.cs │ │ ├── NetListWatcher.cs │ │ ├── NetValueWatcher.cs │ │ ├── ObservableCollectionWatcher.cs │ │ └── WatcherFactory.cs │ ├── ICollectionWatcher.cs │ ├── IDictionaryWatcher.cs │ ├── IValueWatcher.cs │ ├── IWatcher.cs │ ├── LocationTracker.cs │ ├── PlayerTracker.cs │ ├── Snapshots │ │ ├── LocationSnapshot.cs │ │ ├── PlayerSnapshot.cs │ │ ├── WatcherSnapshot.cs │ │ └── WorldLocationsSnapshot.cs │ └── WorldLocationsTracker.cs ├── TemporaryHacks │ └── MiniMonoModHotfix.cs ├── Translator.cs ├── Utilities │ ├── ContextHash.cs │ ├── Countdown.cs │ ├── IntervalMemoryCache.cs │ └── TickCacheDictionary.cs └── WatcherCore.cs ├── GameFramework.cs ├── GamePlatform.cs ├── IAssetData.cs ├── IAssetDataForDictionary.cs ├── IAssetDataForImage.cs ├── IAssetDataForMap.cs ├── IAssetEditor.cs ├── IAssetInfo.cs ├── IAssetLoader.cs ├── IAssetName.cs ├── ICommandHelper.cs ├── IContentHelper.cs ├── IContentPack.cs ├── IContentPackHelper.cs ├── ICursorPosition.cs ├── IDataHelper.cs ├── IGameContentHelper.cs ├── IInputHelper.cs ├── IMod.cs ├── IModContentHelper.cs ├── IModHelper.cs ├── IModInfo.cs ├── IModLinked.cs ├── IModRegistry.cs ├── IMonitor.cs ├── IMultiplayerHelper.cs ├── IMultiplayerPeer.cs ├── IMultiplayerPeerMod.cs ├── IRawTextureData.cs ├── IReflectedField.cs ├── IReflectedMethod.cs ├── IReflectedProperty.cs ├── IReflectionHelper.cs ├── ITranslationHelper.cs ├── LogLevel.cs ├── Metadata ├── CoreAssetPropagator.cs └── InstructionMetadata.cs ├── Mobile ├── FarmMigrationPatch.cs └── IsExternalInit.cs ├── Mod.cs ├── PatchMapMode.cs ├── PatchMode.cs ├── Patches ├── Game1Patcher.cs ├── JunimoHarvesterPatch.cs ├── LocationSwitchPatch.cs ├── OnAppPausePatch.cs ├── SaveBackupPatch.cs ├── SaveGamePatch.cs ├── SpriteFontPatch.cs ├── StringPatcher.cs ├── ThreadSilenceExitPatch.cs ├── TitleMenuPatcher.cs └── UIThreadPatch.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── Resources └── Resource.designer.cs ├── SAlertDialogUtil.cs ├── SButton.cs ├── SButtonState.cs ├── SGameConsole.cs ├── SMAPI.config.json ├── SMAPI.csproj ├── SMainActivity.cs ├── SemanticVersion.cs ├── Translation.cs ├── Utilities ├── AssetPathUtilities │ └── AssetNamePartEnumerator.cs ├── DelegatingModHooks.cs ├── Keybind.cs ├── KeybindList.cs ├── PathUtilities.cs ├── PerScreen.cs └── SDate.cs ├── app.manifest ├── i18n ├── de.json ├── default.json ├── es.json ├── fr.json ├── hu.json ├── it.json ├── ja.json ├── ko.json ├── pl.json ├── pt.json ├── ru.json ├── th.json ├── tr.json ├── uk.json └── zh.json ├── icon.ico └── steam_appid.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # normalize line endings 2 | * text=auto 3 | README.txt text eol=crlf 4 | 5 | *.command text eol=lf 6 | *.sh text eol=lf 7 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Do you want to... 2 | 3 | * **Ask for help or report a bug?** 4 | Please see 'get help' on [the SMAPI website](https://smapi.io) instead, don't create a GitHub 5 | issue. 6 | 7 | * **Submit a pull request?** 8 | Pull requests are welcome! If you're submitting a new feature, it's best to discuss first to make 9 | sure it'll be accepted. Feel free to come chat [on Discord](https://smapi.io/community). 10 | 11 | Documenting your code and using the same formatting conventions is appreciated, but don't worry too 12 | much about it. We'll fix up the code after we accept the pull request if needed. 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: pathoschild 2 | ko_fi: pathoschild 3 | custom: https://www.paypal.me/pathoschild 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Troubleshooting guide for players 4 | url: https://smapi.io/troubleshoot 5 | about: See if your question is already answered first! 6 | - name: Get help or discuss 7 | url: https://smapi.io/help 8 | about: Ask for help from the community, or join the Stardew Valley Discord to ask questions, report issues, or discuss with the SMAPI developer, players, and mod authors. The SMAPI developer is @Pathoschild#0001 on Discord. 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Create a development task 3 | about: DON'T DO THIS BEFORE READING. This is for specific changes to the code or technical bug reports. See below if something isn't working, you have questions or ideas, or you want to discuss something. 4 | 5 | --- 6 | 7 | 22 | 23 | **Describe the bug** 24 | A clear and concise description of what the bug is. Provide any other details you think might be relevant here. 25 | 26 | **To Reproduce** 27 | Exact steps which reproduce the bug, if possible. For example: 28 | 1. Load save '...'. 29 | 2. Walk to '....'. 30 | 3. Click '....'. 31 | 4. Error occurs. 32 | 33 | **Log file** 34 | Upload your SMAPI log to https://smapi.io/log and post a link here. 35 | 36 | **Screenshots** 37 | If applicable, add screenshots to help explain your problem. 38 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | GitHub issues are only used for SMAPI development tasks. 2 | 3 | To get help with SMAPI problems, see 'get help' on [the SMAPI website](https://smapi.io/) instead. 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # user-specific files 2 | *.suo 3 | *.user 4 | *.userosscache 5 | *.sln.docstates 6 | 7 | # build results 8 | [Dd]ebug/ 9 | [Rr]elease/ 10 | [Bb]in/ 11 | [Oo]bj/ 12 | 13 | # Visual Studio cache/options 14 | .config/ 15 | .vs/ 16 | 17 | # ReSharper 18 | _ReSharper*/ 19 | *.[Rr]e[Ss]harper 20 | *.DotSettings.user 21 | 22 | # Rider 23 | .idea/ 24 | 25 | # NuGet packages 26 | *.nupkg 27 | **/packages/* 28 | *.nuget.props 29 | *.nuget.targets 30 | 31 | # sensitive files 32 | appsettings.Development.json 33 | 34 | # Azure generated files 35 | src/SMAPI.Web/Properties/PublishProfiles/*.pubxml 36 | src/SMAPI.Web/Properties/ServiceDependencies/* - Web Deploy/ 37 | 38 | # macOS 39 | .DS_Store 40 | 41 | # Loader Game Asserts 42 | src/Loader/Assets/Content/ 43 | src/Loader/libs/ 44 | 45 | # VSHistory 46 | **/.vshistory/ 47 | /build/StardewValleyAndroidStuff/ 48 | -------------------------------------------------------------------------------- /build/0Harmony.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/0Harmony.dll -------------------------------------------------------------------------------- /build/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/Mono.Cecil.dll -------------------------------------------------------------------------------- /build/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /build/Pintail.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/Pintail.dll -------------------------------------------------------------------------------- /build/ReadOnlyCollectionsExtensions.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/ReadOnlyCollectionsExtensions.dll -------------------------------------------------------------------------------- /build/ReadOnlyCollectionsInterfaces.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/ReadOnlyCollectionsInterfaces.dll -------------------------------------------------------------------------------- /build/SetLargeAddressAware.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/SetLargeAddressAware.dll -------------------------------------------------------------------------------- /build/TMXTile.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/build/TMXTile.dll -------------------------------------------------------------------------------- /build/define-constant.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GOOGLE 6 | 7 | 8 | 9 | 10 | False 11 | SMAPI_DEPRECATED;SMAPI_FOR_MOBILE;ANDROID_TARGET_GOOGLE 12 | 13 | 14 | -------------------------------------------------------------------------------- /build/unix/set-smapi-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # 5 | # This is the Bash equivalent of ../windows/set-smapi-version.ps1. 6 | # When making changes, both scripts should be updated. 7 | # 8 | # 9 | 10 | 11 | # get version number 12 | version="$1" 13 | if [ $# -eq 0 ]; then 14 | echo "SMAPI release version (like '4.0.0'):" 15 | read version 16 | fi 17 | 18 | # move to SMAPI root 19 | cd "`dirname "$0"`/../.." 20 | 21 | # apply changes 22 | sed "s/.+<\/Version>/$version<\/Version>/" "build/common.targets" --in-place --regexp-extended 23 | sed "s/RawApiVersion = \".+?\";/RawApiVersion = \"$version\";/" "src/SMAPI/Constants.cs" --in-place --regexp-extended 24 | for modName in "ConsoleCommands" "ErrorHandler" "SaveBackup"; do 25 | sed "s/\"(Version|MinimumApiVersion)\": \".+?\"/\"\1\": \"$version\"/g" "src/SMAPI.Mods.$modName/manifest.json" --in-place --regexp-extended 26 | done 27 | -------------------------------------------------------------------------------- /build/windows/lib/in-place-regex.ps1: -------------------------------------------------------------------------------- 1 | function In-Place-Regex { 2 | param ( 3 | [Parameter(Mandatory)][string]$Path, 4 | [Parameter(Mandatory)][string]$Search, 5 | [Parameter(Mandatory)][string]$Replace 6 | ) 7 | 8 | $content = (Get-Content "$Path" -Encoding UTF8) 9 | $content = ($content -replace "$Search", "$Replace") 10 | [System.IO.File]::WriteAllLines((Get-Item "$Path").FullName, $content) 11 | } 12 | -------------------------------------------------------------------------------- /build/windows/set-smapi-version.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # This is the PowerShell equivalent of ../unix/set-smapi-version.sh. 4 | # When making changes, both scripts should be updated. 5 | # 6 | # 7 | 8 | 9 | . "$PSScriptRoot\lib\in-place-regex.ps1" 10 | 11 | # get version number 12 | $version=$args[0] 13 | if (!$version) { 14 | $version = Read-Host "SMAPI release version (like '4.0.0')" 15 | } 16 | 17 | # move to SMAPI root 18 | cd "$PSScriptRoot/../.." 19 | 20 | # apply changes 21 | In-Place-Regex -Path "build/common.targets" -Search ".+" -Replace "$version" 22 | In-Place-Regex -Path "src/SMAPI/Constants.cs" -Search "RawApiVersion = `".+?`";" -Replace "RawApiVersion = `"$version`";" 23 | ForEach ($modName in "ConsoleCommands","ErrorHandler","SaveBackup") { 24 | In-Place-Regex -Path "src/SMAPI.Mods.$modName/manifest.json" -Search "`"(Version|MinimumApiVersion)`": `".+?`"" -Replace "`"`$1`": `"$version`"" 25 | } 26 | -------------------------------------------------------------------------------- /docs/mod-build-config.md: -------------------------------------------------------------------------------- 1 | [Documentation moved](technical/mod-package.md). 2 | -------------------------------------------------------------------------------- /docs/technical/screenshots/code-analyzer-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/docs/technical/screenshots/code-analyzer-example.png -------------------------------------------------------------------------------- /src/Loader/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); -------------------------------------------------------------------------------- /src/Loader/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Loader")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Loader")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | [assembly: ComVisible(false)] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | -------------------------------------------------------------------------------- /src/Loader/Resources/drawable/Splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/drawable/Splash.png -------------------------------------------------------------------------------- /src/Loader/Resources/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/drawable/icon.png -------------------------------------------------------------------------------- /src/Loader/Resources/drawable/splash_logos_crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/drawable/splash_logos_crop.png -------------------------------------------------------------------------------- /src/Loader/Resources/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Loader/Resources/mipmap/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/mipmap/ic_launcher.png -------------------------------------------------------------------------------- /src/Loader/Resources/mipmap/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/mipmap/ic_launcher_background.png -------------------------------------------------------------------------------- /src/Loader/Resources/mipmap/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/mipmap/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src/Loader/Resources/mipmap/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/Loader/Resources/mipmap/ic_launcher_round.png -------------------------------------------------------------------------------- /src/Loader/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2c3e50 4 | #1B3147 5 | #3498db 6 | 7 | -------------------------------------------------------------------------------- /src/Loader/Resources/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2C3E50 4 | -------------------------------------------------------------------------------- /src/Loader/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Loader 3 | Settings 4 | 5 | -------------------------------------------------------------------------------- /src/Loader/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /src/Loader/Resources/xml/provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Loader/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/MobilePatch/Mobile/MobileMemoryExtension.cs: -------------------------------------------------------------------------------- 1 | namespace System; 2 | using Internal.Runtime.CompilerServices; 3 | using System.Collections.Generic; 4 | using System.Globalization; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | 9 | public static class MobileMemoryExtension 10 | { 11 | 12 | /// Indicates whether a specified value is found in a read-only span. Values are compared using IEquatable{T}.Equals(T). 13 | /// The span to search. 14 | /// The value to search for. 15 | /// The type of the span. 16 | /// 17 | /// if found, otherwise. 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 19 | public static bool Contains(this ReadOnlySpan span, T value) where T : IEquatable 20 | { 21 | return span.IndexOf(value) >= 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/MobilePatch/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("MobilePatch")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("MobilePatch")] 14 | [assembly: AssemblyCopyright("Copyright © 2023")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /src/MobilePatch/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Hello World, Click Me! 3 | MobilePatch 4 | 5 | -------------------------------------------------------------------------------- /src/SMAPI.Installer/Enums/ScriptAction.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingApi.Installer.Enums 2 | { 3 | /// The action to perform. 4 | internal enum ScriptAction 5 | { 6 | /// Install SMAPI to the game directory. 7 | Install, 8 | 9 | /// Remove SMAPI from the game directory. 10 | Uninstall 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI.Installer/SMAPI.Installer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | StardewModdingAPI.Installer 4 | The SMAPI installer for players. 5 | net5.0 6 | Exe 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/SMAPI.Installer/assets/install on Linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd "`dirname "$0"`" 4 | internal/linux/SMAPI.Installer 5 | -------------------------------------------------------------------------------- /src/SMAPI.Installer/assets/install on macOS.command: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd "`dirname "$0"`" 4 | 5 | xattr -r -d com.apple.quarantine internal 6 | internal/macOS/SMAPI.Installer 7 | -------------------------------------------------------------------------------- /src/SMAPI.Installer/assets/runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net5.0", 4 | "includedFrameworks": [ 5 | { 6 | "name": "Microsoft.NETCore.App", 7 | "version": "5.0.0", 8 | "rollForward": "latestMinor" 9 | } 10 | ], 11 | "configProperties": { 12 | // disable tiered runtime JIT: https://github.com/dotnet/runtime/blob/main/docs/design/features/tiered-compilation.md 13 | // This is disabled by the base game, and causes issues with Harmony patches. 14 | "System.Runtime.TieredCompilation": false 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI.Installer/assets/windows-exe-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/SMAPI.Internal.Patching/IPatcher.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | 3 | namespace StardewModdingAPI.Internal.Patching 4 | { 5 | /// A set of Harmony patches to apply. 6 | internal interface IPatcher 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Apply the Harmony patches for this instance. 12 | /// The Harmony instance. 13 | /// The monitor with which to log any errors. 14 | public void Apply(Harmony harmony, IMonitor monitor); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 6c16e948-3e5c-47a7-bf4b-07a7469a87a5 7 | 8 | 9 | SMAPI.Internal.Patching 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6c16e948-3e5c-47a7-bf4b-07a7469a87a5 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/SMAPI.Internal/ConsoleWriting/ConsoleLogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Internal.ConsoleWriting 2 | { 3 | /// The log severity levels. 4 | internal enum ConsoleLogLevel 5 | { 6 | /// Tracing info intended for developers. 7 | Trace, 8 | 9 | /// Troubleshooting info that may be relevant to the player. 10 | Debug, 11 | 12 | /// Info relevant to the player. This should be used judiciously. 13 | Info, 14 | 15 | /// An issue the player should be aware of. This should be used rarely. 16 | Warn, 17 | 18 | /// A message indicating something went wrong. 19 | Error, 20 | 21 | /// Important information to highlight for the player when player action is needed (e.g. new version available). This should be used rarely to avoid alert fatigue. 22 | Alert, 23 | 24 | /// A critical issue that generally signals an immediate end to the application. 25 | Critical, 26 | 27 | /// A success message that generally signals a successful end to a task. 28 | Success 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SMAPI.Internal/ConsoleWriting/IConsoleWriter.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Internal.ConsoleWriting 2 | { 3 | /// Writes text to the console. 4 | internal interface IConsoleWriter 5 | { 6 | /// Write a message line to the log. 7 | /// The message to log. 8 | /// The log level. 9 | void WriteLine(string message, ConsoleLogLevel level); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Internal.ConsoleWriting 2 | { 3 | /// A monitor color scheme to use. 4 | internal enum MonitorColorScheme 5 | { 6 | /// Choose a color scheme automatically. 7 | AutoDetect, 8 | 9 | /// Use lighter text colors that look better on a black or dark background. 10 | DarkBackground, 11 | 12 | /// Use darker text colors that look better on a white or light background. 13 | LightBackground, 14 | 15 | /// Disable console color. 16 | None 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Internal/SMAPI.Internal.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 85208f8d-6fd1-4531-be05-7142490f59fe 7 | 8 | 9 | SMAPI.Internal 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/SMAPI.Internal/SMAPI.Internal.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 85208f8d-6fd1-4531-be05-7142490f59fe 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetCollection.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace -- matches Stardew Valley's code 2 | using System.Collections.ObjectModel; 3 | 4 | namespace Netcode 5 | { 6 | /// A simplified version of Stardew Valley's Netcode.NetCollection for unit testing. 7 | public class NetCollection : Collection { } 8 | } 9 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetFieldBase.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace -- matches Stardew Valley's code 2 | namespace Netcode 3 | { 4 | /// A simplified version of Stardew Valley's Netcode.NetFieldBase for unit testing. 5 | /// The type of the synchronized value. 6 | /// The type of the current instance. 7 | public class NetFieldBase where TSelf : NetFieldBase 8 | { 9 | /// The synchronised value. 10 | public T? Value { get; set; } 11 | 12 | /// Implicitly convert a net field to the its type. 13 | /// The field to convert. 14 | public static implicit operator T?(NetFieldBase field) 15 | { 16 | return field.Value; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetInt.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace -- matches Stardew Valley's code 2 | namespace Netcode 3 | { 4 | /// A simplified version of Stardew Valley's Netcode.NetInt for unit testing. 5 | public class NetInt : NetFieldBase { } 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace -- matches Stardew Valley's code 2 | using System.Collections.Generic; 3 | 4 | namespace Netcode 5 | { 6 | /// A simplified version of Stardew Valley's Netcode.NetObjectList for unit testing. 7 | public class NetList : List { } 8 | } 9 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace -- matches Stardew Valley's code 2 | namespace Netcode 3 | { 4 | /// A simplified version of Stardew Valley's Netcode.NetObjectList for unit testing. 5 | public class NetObjectList : NetList { } 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetRef.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace -- matches Stardew Valley's code 2 | namespace Netcode 3 | { 4 | /// A simplified version of Stardew Valley's Netcode.NetRef for unit testing. 5 | public class NetRef : NetFieldBase> where T : class { } 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code 2 | // ReSharper disable UnusedMember.Global -- used dynamically for unit tests 3 | using System.Collections.Generic; 4 | 5 | namespace StardewValley 6 | { 7 | /// A simplified version of Stardew Valley's StardewValley.Farmer class for unit testing. 8 | internal class Farmer 9 | { 10 | /// A sample field which should be replaced with a different property. 11 | public readonly IDictionary friendships = new Dictionary(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Object.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code 2 | using Netcode; 3 | 4 | namespace StardewValley 5 | { 6 | /// A simplified version of Stardew Valley's StardewValley.Object class for unit testing. 7 | public class Object : Item 8 | { 9 | /// A net int field with an equivalent non-net property. 10 | public NetInt type = new() { Value = 42 }; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net5.0 4 | latest 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer/AnalyzerReleases.Shipped.md: -------------------------------------------------------------------------------- 1 | ## Release 2.1.0 2 | ### New Rules 3 | Rule ID | Category | Severity | Notes 4 | ------------------------- | ------------------ | -------- | ------------------------------------------------------------ 5 | AvoidImplicitNetFieldCast | SMAPI.CommonErrors | Warning | See [documentation](https://smapi.io/package/code-warnings). 6 | AvoidNetField | SMAPI.CommonErrors | Warning | See [documentation](https://smapi.io/package/code-warnings). 7 | AvoidObsoleteField | SMAPI.CommonErrors | Warning | See [documentation](https://smapi.io/package/code-warnings). 8 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | StardewModdingAPI.ModBuildConfig.Analyzer 4 | 3.0.0 5 | netstandard2.0 6 | false 7 | bin 8 | latest 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.ModBuildConfig.Framework 4 | { 5 | /// An extra assembly type for the field. 6 | [Flags] 7 | internal enum ExtraAssemblyTypes 8 | { 9 | /// Don't include extra assemblies. 10 | None = 0, 11 | 12 | /// Assembly files which are part of MonoGame, SMAPI, or Stardew Valley. 13 | Game = 1, 14 | 15 | /// Assembly files whose names start with Microsoft.* or System.*. 16 | System = 2, 17 | 18 | /// Assembly files which don't match any other category. 19 | ThirdParty = 4 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig/Framework/UserErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.ModBuildConfig.Framework 4 | { 5 | /// A user error whose message can be displayed to the user. 6 | internal class UserErrorException : Exception 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Construct an instance. 12 | /// The error message. 13 | public UserErrorException(string message) 14 | : base(message) { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig/assets/nuget-icon.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.ModBuildConfig/assets/nuget-icon.pdn -------------------------------------------------------------------------------- /src/SMAPI.ModBuildConfig/assets/nuget-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.ModBuildConfig/assets/nuget-icon.png -------------------------------------------------------------------------------- /src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Other/ShowDataFilesCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other 5 | { 6 | /// A command which shows the data files. 7 | [SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Loaded using reflection")] 8 | internal class ShowDataFilesCommand : ConsoleCommand 9 | { 10 | /********* 11 | ** Public methods 12 | *********/ 13 | /// Construct an instance. 14 | public ShowDataFilesCommand() 15 | : base("show_data_files", "Opens the folder containing the save and log files.") { } 16 | 17 | /// Handle the command. 18 | /// Writes messages to the console and log file. 19 | /// The command name. 20 | /// The command arguments. 21 | public override void Handle(IMonitor monitor, string command, ArgumentParser args) 22 | { 23 | Process.Start(Constants.DataPath); 24 | monitor.Log($"OK, opening {Constants.DataPath}.", LogLevel.Info); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Other/ShowGameFilesCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other 5 | { 6 | /// A command which shows the game files. 7 | [SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Loaded using reflection")] 8 | internal class ShowGameFilesCommand : ConsoleCommand 9 | { 10 | /********* 11 | ** Public methods 12 | *********/ 13 | /// Construct an instance. 14 | public ShowGameFilesCommand() 15 | : base("show_game_files", "Opens the game folder.") { } 16 | 17 | /// Handle the command. 18 | /// Writes messages to the console and log file. 19 | /// The command name. 20 | /// The command arguments. 21 | public override void Handle(IMonitor monitor, string command, ArgumentParser args) 22 | { 23 | Process.Start(Constants.GamePath); 24 | monitor.Log($"OK, opening {Constants.GamePath}.", LogLevel.Info); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ConsoleCommands/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Console Commands", 3 | "Author": "SMAPI", 4 | "Version": "3.18.4", 5 | "Description": "Adds SMAPI console commands that let you manipulate the game.", 6 | "UniqueID": "SMAPI.ConsoleCommands", 7 | "EntryDll": "ConsoleCommands.dll", 8 | "MinimumApiVersion": "3.18.4" 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | ErrorHandler 4 | StardewModdingAPI.Mods.ErrorHandler 5 | net5.0 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Ungültiger Inhalt wurde entfernt, um einen Absturz zu verhindern (siehe SMAPI Konsole für weitere Informationen)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/default.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Invalid content was removed to prevent a crash (see the SMAPI console for info)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/es.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Se ha quitado contenido inválido para evitar un cierre forzoso (revisa la consola de SMAPI para más información)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Le contenu non valide a été supprimé afin d'éviter un plantage (voir la console de SMAPI pour plus d'informations)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Érvénytelen elemek kerültek eltávolításra, hogy a játék ne omoljon össze (további információk a SMAPI konzolon)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/it.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Contenuto non valido rimosso per prevenire un crash (Guarda la console di SMAPI per maggiori informazioni)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "クラッシュを防ぐために無効なコンテンツを取り除きました (詳細はSMAPIコンソールを参照)" 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "충돌을 방지하기 위해 잘못된 컨텐츠가 제거되었습니다 (자세한 내용은 SMAPI 콘솔 참조)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Nieprawidłowa zawartość została usunięta, aby zapobiec awarii (zobacz konsolę SMAPI po więcej informacji)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Conteúdo inválido foi removido para prevenir uma falha (veja o console do SMAPI para mais informações)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Недопустимое содержимое было удалено, чтобы предотвратить сбой (см. информацию в консоли SMAPI)" 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/th.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "ทำการลบเนื้อหาที่ไม่ถูกต้องออก เพื่อป้องกันไฟล์เกมเสียหาย (ดูรายละเอียดที่หน้าคอลโซลของ SMAPI)" 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Yanlış paketlenmiş bir içerik, oyunun çökmemesi için yüklenmedi (SMAPI konsol penceresinde detaylı bilgi mevcut)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "Недійсний вміст видалено, щоб запобігти аварійному завершенню роботи (Додаткову інформацію див. на консолі SMAPI)." 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/i18n/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | // warning messages 3 | "warn.invalid-content-removed": "非法内容已移除以防游戏闪退(查看SMAPI控制台获得更多信息)" 4 | } 5 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.ErrorHandler/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Error Handler", 3 | "Author": "SMAPI", 4 | "Version": "3.18.4", 5 | "Description": "Handles some common vanilla errors to log more useful info or avoid breaking the game.", 6 | "UniqueID": "SMAPI.ErrorHandler", 7 | "EntryDll": "ErrorHandler.dll", 8 | "MinimumApiVersion": "3.18.4" 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.SaveBackup/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Save Backup", 3 | "Author": "SMAPI", 4 | "Version": "3.18.4", 5 | "Description": "Automatically backs up all your saves once per day into its folder.", 6 | "UniqueID": "SMAPI.SaveBackup", 7 | "EntryDll": "SaveBackup.dll", 8 | "MinimumApiVersion": "3.18.4" 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.VirtualKeyboard/ModEntry.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Mods.VirtualKeyboard 2 | { 3 | class ModEntry : Mod 4 | { 5 | public static float ZoomScale; 6 | public override void Entry(IModHelper helper) 7 | { 8 | new VirtualToggle(helper, this.Monitor); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/SMAPI.Mods.VirtualKeyboard/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /src/SMAPI.Mods.VirtualKeyboard/assets/togglebutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Mods.VirtualKeyboard/assets/togglebutton.png -------------------------------------------------------------------------------- /src/SMAPI.Mods.VirtualKeyboard/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "VirtualKeyboard", 3 | "Author": "SMAPI", 4 | "Version": "4.0.1", 5 | "MinimumApiVersion": "3.18.2", 6 | "Description": "A much needed Virtual Keyboard for SMAPI Android.", 7 | "UniqueID": "VirtualKeyboard", 8 | "EntryDll": "VirtualKeyboard.dll", 9 | "UpdateKeys": [ "Nexus: null" ] 10 | } 11 | -------------------------------------------------------------------------------- /src/SMAPI.Tests.ModApiConsumer/README.md: -------------------------------------------------------------------------------- 1 | This project contains a simulated [mod-provided API] consumer used in the API proxying unit tests. 2 | 3 | [mod-provided API]: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations 4 | -------------------------------------------------------------------------------- /src/SMAPI.Tests.ModApiConsumer/SMAPI.Tests.ModApiConsumer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net5.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/SMAPI.Tests.ModApiProvider/Framework/BaseApi.cs: -------------------------------------------------------------------------------- 1 | namespace SMAPI.Tests.ModApiProvider.Framework 2 | { 3 | /// The base class for . 4 | public class BaseApi 5 | { 6 | /********* 7 | ** Test interface 8 | *********/ 9 | /// A property inherited from a base class. 10 | public string? InheritedProperty { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI.Tests.ModApiProvider/README.md: -------------------------------------------------------------------------------- 1 | This project contains simulated [mod-provided APIs] used in the API proxying unit tests. 2 | 3 | [mod-provided APIs]: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations 4 | -------------------------------------------------------------------------------- /src/SMAPI.Tests.ModApiProvider/SMAPI.Tests.ModApiProvider.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net5.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/SMAPI.Tests/Sample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SMAPI.Tests 4 | { 5 | /// Provides sample values for unit testing. 6 | internal static class Sample 7 | { 8 | /********* 9 | ** Fields 10 | *********/ 11 | /// A random number generator. 12 | private static readonly Random Random = new(); 13 | 14 | 15 | /********* 16 | ** Accessors 17 | *********/ 18 | /// Get a sample string. 19 | public static string String() 20 | { 21 | return Guid.NewGuid().ToString("N"); 22 | } 23 | 24 | /// Get a sample integer. 25 | public static int Int() 26 | { 27 | return Sample.Random.Next(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SMAPI.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit.CoreInterfaces/IManifestContentPackFor.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// Indicates which mod can read the content pack represented by the containing manifest. 4 | public interface IManifestContentPackFor 5 | { 6 | /// The unique ID of the mod which can read this content pack. 7 | string UniqueID { get; } 8 | 9 | /// The minimum required version (if any). 10 | ISemanticVersion? MinimumVersion { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit.CoreInterfaces/IManifestDependency.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// A mod dependency listed in a mod manifest. 4 | public interface IManifestDependency 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The unique mod ID to require. 10 | string UniqueID { get; } 11 | 12 | /// The minimum required version (if any). 13 | ISemanticVersion? MinimumVersion { get; } 14 | 15 | /// Whether the dependency must be installed to use the mod. 16 | bool IsRequired { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | StardewModdingAPI 4 | Provides toolkit interfaces which are available to SMAPI mods. 5 | net5.0; netstandard2.0 6 | latest 7 | true 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi 4 | { 5 | /// Metadata about a mod. 6 | public class ModEntryModel 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The mod's unique ID (if known). 12 | public string ID { get; } 13 | 14 | /// The update version recommended by the web API based on its version update and mapping rules. 15 | public ModEntryVersionModel? SuggestedUpdate { get; set; } 16 | 17 | /// Optional extended data which isn't needed for update checks. 18 | public ModExtendedMetadataModel? Metadata { get; set; } 19 | 20 | /// The errors that occurred while fetching update data. 21 | public string[] Errors { get; set; } = Array.Empty(); 22 | 23 | 24 | /********* 25 | ** Public methods 26 | *********/ 27 | /// Construct an instance. 28 | /// The mod's unique ID (if known). 29 | public ModEntryModel(string id) 30 | { 31 | this.ID = id; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/Clients/WebApi/ModEntryVersionModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using StardewModdingAPI.Toolkit.Serialization.Converters; 3 | 4 | namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi 5 | { 6 | /// Metadata about a version. 7 | public class ModEntryVersionModel 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The version number. 13 | [JsonConverter(typeof(NonStandardSemanticVersionConverter))] 14 | public ISemanticVersion Version { get; } 15 | 16 | /// The mod page URL. 17 | public string Url { get; } 18 | 19 | 20 | /********* 21 | ** Public methods 22 | *********/ 23 | /// Construct an instance. 24 | /// The version number. 25 | /// The mod page URL. 26 | public ModEntryVersionModel(ISemanticVersion version, string url) 27 | { 28 | this.Version = version; 29 | this.Url = url; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki 2 | { 3 | /// The compatibility status for a mod. 4 | public enum WikiCompatibilityStatus 5 | { 6 | /// The status is unknown. 7 | Unknown, 8 | 9 | /// The mod is compatible. 10 | Ok, 11 | 12 | /// The mod is compatible if you use an optional official download. 13 | Optional, 14 | 15 | /// The mod is compatible if you use an unofficial update. 16 | Unofficial, 17 | 18 | /// The mod isn't compatible, but the player can fix it or there's a good alternative. 19 | Workaround, 20 | 21 | /// The mod isn't compatible. 22 | Broken, 23 | 24 | /// The mod is no longer maintained by the author, and an unofficial update or continuation is unlikely. 25 | Abandoned, 26 | 27 | /// The mod is no longer needed and should be removed. 28 | Obsolete 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiDataOverrideEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki 4 | { 5 | /// The data overrides to apply to matching mods. 6 | public class WikiDataOverrideEntry 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The unique mod IDs for the mods to override. 12 | public string[] Ids { get; set; } = Array.Empty(); 13 | 14 | /// Maps local versions to a semantic version for update checks. 15 | public ChangeDescriptor? ChangeLocalVersions { get; set; } 16 | 17 | /// Maps remote versions to a semantic version for update checks. 18 | public ChangeDescriptor? ChangeRemoteVersions { get; set; } 19 | 20 | /// Update keys to add (optionally prefixed by '+'), remove (prefixed by '-'), or replace. 21 | public ChangeDescriptor? ChangeUpdateKeys { get; set; } 22 | 23 | /// Whether the entry has any changes. 24 | public bool HasChanges => 25 | this.ChangeLocalVersions?.HasChanges == true 26 | || this.ChangeRemoteVersions?.HasChanges == true 27 | || this.ChangeUpdateKeys?.HasChanges == true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModList.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki 2 | { 3 | /// Metadata from the wiki's mod compatibility list. 4 | public class WikiModList 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The stable game version. 10 | public string? StableVersion { get; } 11 | 12 | /// The beta game version (if any). 13 | public string? BetaVersion { get; } 14 | 15 | /// The mods on the wiki. 16 | public WikiModEntry[] Mods { get; } 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Construct an instance. 23 | /// The stable game version. 24 | /// The beta game version (if any). 25 | /// The mods on the wiki. 26 | public WikiModList(string? stableVersion, string? betaVersion, WikiModEntry[] mods) 27 | { 28 | this.StableVersion = stableVersion; 29 | this.BetaVersion = betaVersion; 30 | this.Mods = mods; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework 2 | { 3 | /// Contains the SMAPI installer's constants and assumptions. 4 | internal static class Constants 5 | { 6 | /// The name of the game's main DLL, used to detect game folders. 7 | public const string GameDllName = "Stardew Valley.dll"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/GameScanning/GameFolderType.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.GameScanning 2 | { 3 | /// The detected validity for a Stardew Valley game folder based on file structure heuristics. 4 | public enum GameFolderType 5 | { 6 | /// The folder seems to contain a valid Stardew Valley 1.5.5+ install. 7 | Valid, 8 | 9 | /// The folder doesn't contain Stardew Valley. 10 | NoGameFound, 11 | 12 | /// The folder contains Stardew Valley 1.5.4 or earlier. This version uses XNA Framework and 32-bit .NET Framework 4.5.2 on Windows and Mono on Linux/macOS, and isn't compatible with current versions of SMAPI. 13 | Legacy154OrEarlier, 14 | 15 | /// The folder contains Stardew Valley from the game's legacy compatibility branch, which backports newer changes to the format. 16 | LegacyCompatibilityBranch, 17 | 18 | /// The folder seems to contain Stardew Valley files, but they failed to load for unknown reasons (e.g. corrupted executable). 19 | InvalidUnknown 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/ModData/MetadataModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Toolkit.Framework.ModData 4 | { 5 | /// The SMAPI predefined metadata. 6 | internal class MetadataModel 7 | { 8 | /******** 9 | ** Accessors 10 | ********/ 11 | /// Extra metadata about mods. 12 | public IDictionary ModData { get; } = new Dictionary(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/ModData/ModDataFieldKey.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.ModData 2 | { 3 | /// The valid field keys. 4 | public enum ModDataFieldKey 5 | { 6 | /// A manifest update key. 7 | UpdateKey, 8 | 9 | /// The mod's predefined compatibility status. 10 | Status, 11 | 12 | /// A reason phrase for the , or null to use the default reason. 13 | StatusReasonPhrase, 14 | 15 | /// Technical details shown in TRACE logs for the , or null to omit it. 16 | StatusReasonDetails 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/ModData/ModStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.ModData 2 | { 3 | /// Indicates how SMAPI should treat a mod. 4 | public enum ModStatus 5 | { 6 | /// Don't override the status. 7 | None, 8 | 9 | /// The mod is obsolete and shouldn't be used, regardless of version. 10 | Obsolete, 11 | 12 | /// Assume the mod is not compatible, even if SMAPI doesn't detect any incompatible code. 13 | AssumeBroken, 14 | 15 | /// Assume the mod is compatible, even if SMAPI detects incompatible code. 16 | AssumeCompatible 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/ModScanning/ModParseError.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.ModScanning 2 | { 3 | /// Indicates why a mod could not be parsed. 4 | public enum ModParseError 5 | { 6 | /// No parse error. 7 | None, 8 | 9 | /// The folder is empty or contains only ignored files. 10 | EmptyFolder, 11 | 12 | /// The folder is an empty folder managed by Vortex. 13 | EmptyVortexFolder, 14 | 15 | /// The folder is ignored by convention. 16 | IgnoredFolder, 17 | 18 | /// The mod's manifest.json could not be parsed. 19 | ManifestInvalid, 20 | 21 | /// The folder contains non-ignored and non-XNB files, but none of them are manifest.json. 22 | ManifestMissing, 23 | 24 | /// The folder is an XNB mod, which can't be loaded through SMAPI. 25 | XnbMod 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/ModScanning/ModType.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.ModScanning 2 | { 3 | /// A general mod type. 4 | public enum ModType 5 | { 6 | /// The mod is invalid and its type could not be determined. 7 | Invalid, 8 | 9 | /// The folder is ignored by convention. 10 | Ignored, 11 | 12 | /// A mod which uses SMAPI directly. 13 | Smapi, 14 | 15 | /// A mod which contains files loaded by a SMAPI mod. 16 | ContentPack, 17 | 18 | /// A legacy mod which replaces game files directly. 19 | Xnb 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Framework/UpdateData/ModSiteKey.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Framework.UpdateData 2 | { 3 | /// A mod site which SMAPI can check for updates. 4 | public enum ModSiteKey 5 | { 6 | /// An unknown or invalid mod repository. 7 | Unknown, 8 | 9 | /// The Chucklefish mod repository. 10 | Chucklefish, 11 | 12 | /// The CurseForge mod repository. 13 | CurseForge, 14 | 15 | /// A GitHub project containing releases. 16 | GitHub, 17 | 18 | /// The ModDrop mod repository. 19 | ModDrop, 20 | 21 | /// The Nexus Mods mod repository. 22 | Nexus 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("StardewModdingAPI")] 4 | [assembly: InternalsVisibleTo("SMAPI.Installer")] 5 | [assembly: InternalsVisibleTo("SMAPI.Tests")] 6 | [assembly: InternalsVisibleTo("SMAPI.Web")] 7 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/SemanticVersionComparer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Toolkit 4 | { 5 | /// A comparer for semantic versions based on the field. 6 | public class SemanticVersionComparer : IComparer 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// A singleton instance of the comparer. 12 | public static SemanticVersionComparer Instance { get; } = new(); 13 | 14 | 15 | /********* 16 | ** Public methods 17 | *********/ 18 | /// 19 | public int Compare(ISemanticVersion? x, ISemanticVersion? y) 20 | { 21 | if (object.ReferenceEquals(x, y)) 22 | return 0; 23 | 24 | if (x is null) 25 | return -1; 26 | if (y is null) 27 | return 1; 28 | 29 | return x.CompareTo(y); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Serialization/Converters/NonStandardSemanticVersionConverter.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Serialization.Converters 2 | { 3 | /// Handles deserialization of , allowing for non-standard extensions. 4 | internal class NonStandardSemanticVersionConverter : SemanticVersionConverter 5 | { 6 | /********* 7 | ** Public methods 8 | *********/ 9 | /// Construct an instance. 10 | public NonStandardSemanticVersionConverter() 11 | { 12 | this.AllowNonStandard = true; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Serialization/InternalExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json.Linq; 3 | 4 | namespace StardewModdingAPI.Toolkit.Serialization 5 | { 6 | /// Provides extension methods for parsing JSON. 7 | public static class JsonExtensions 8 | { 9 | /// Get a JSON field value from a case-insensitive field name. This will check for an exact match first, then search without case sensitivity. 10 | /// The value type. 11 | /// The JSON object to search. 12 | /// The field name. 13 | public static T? ValueIgnoreCase(this JObject obj, string fieldName) 14 | { 15 | JToken? token = obj.GetValue(fieldName, StringComparison.OrdinalIgnoreCase); 16 | return token != null 17 | ? token.Value() 18 | : default; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Serialization/SParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Toolkit.Serialization 4 | { 5 | /// A format exception which provides a user-facing error message. 6 | internal class SParseException : FormatException 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Construct an instance. 12 | /// The error message. 13 | /// The underlying exception, if any. 14 | public SParseException(string message, Exception? ex = null) 15 | : base(message, ex) { } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Utilities/PathLookups/IFileLookup.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace StardewModdingAPI.Toolkit.Utilities.PathLookups 4 | { 5 | /// An API for file lookups within a root directory. 6 | internal interface IFileLookup 7 | { 8 | /// Get the file for a given relative file path, if it exists. 9 | /// The relative path. 10 | FileInfo GetFile(string relativePath); 11 | 12 | /// Add a relative path that was just created by a SMAPI API. 13 | /// The relative path. 14 | void Add(string relativePath); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI.Toolkit/Utilities/Platform.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Toolkit.Utilities 2 | { 3 | /// The game's platform version. 4 | public enum Platform 5 | { 6 | /// The Android version of the game. 7 | Android, 8 | 9 | /// The Linux version of the game. 10 | Linux, 11 | 12 | /// The macOS version of the game. 13 | Mac, 14 | 15 | /// The Windows version of the game. 16 | Windows 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Caching/BaseCacheRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Caching 4 | { 5 | /// The base logic for a cache repository. 6 | internal abstract class BaseCacheRepository 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Whether cached data is stale. 12 | /// The date when the data was updated. 13 | /// The age in minutes before data is considered stale. 14 | public bool IsStale(DateTimeOffset lastUpdated, int staleMinutes) 15 | { 16 | return lastUpdated < DateTimeOffset.UtcNow.AddMinutes(-staleMinutes); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Caching/Cached.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Caching 4 | { 5 | /// A cache entry. 6 | /// The cached value type. 7 | internal class Cached 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The cached data. 13 | public T Data { get; } 14 | 15 | /// When the data was last updated. 16 | public DateTimeOffset LastUpdated { get; } 17 | 18 | /// When the data was last requested through the mod API. 19 | public DateTimeOffset LastRequested { get; internal set; } 20 | 21 | 22 | /********* 23 | ** Public methods 24 | *********/ 25 | /// Construct an instance. 26 | /// The cached data. 27 | public Cached(T data) 28 | { 29 | this.Data = data; 30 | this.LastUpdated = DateTimeOffset.UtcNow; 31 | this.LastRequested = DateTimeOffset.UtcNow; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Caching/ICacheRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Caching 4 | { 5 | /// Encapsulates logic for accessing data in the cache. 6 | internal interface ICacheRepository 7 | { 8 | /// Whether cached data is stale. 9 | /// The date when the data was updated. 10 | /// The age in minutes before data is considered stale. 11 | bool IsStale(DateTimeOffset lastUpdated, int staleMinutes); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Caching/Wiki/WikiMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Caching.Wiki 2 | { 3 | /// The model for cached wiki metadata. 4 | internal class WikiMetadata 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The current stable Stardew Valley version. 10 | public string? StableVersion { get; } 11 | 12 | /// The current beta Stardew Valley version. 13 | public string? BetaVersion { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// The current stable Stardew Valley version. 21 | /// The current beta Stardew Valley version. 22 | public WikiMetadata(string? stableVersion, string? betaVersion) 23 | { 24 | this.StableVersion = stableVersion; 25 | this.BetaVersion = betaVersion; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/Chucklefish/IChucklefishClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.Chucklefish 4 | { 5 | /// An HTTP client for fetching mod metadata from the Chucklefish mod site. 6 | internal interface IChucklefishClient : IModSiteClient, IDisposable { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/CurseForge/ICurseForgeClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.CurseForge 4 | { 5 | /// An HTTP client for fetching mod metadata from the CurseForge API. 6 | internal interface ICurseForgeClient : IModSiteClient, IDisposable { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/CurseForge/ResponseModels/ModFileModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients.CurseForge.ResponseModels 2 | { 3 | /// Metadata from the CurseForge API about a mod file. 4 | public class ModFileModel 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The file name as downloaded. 10 | public string FileName { get; } 11 | 12 | /// The file display name. 13 | public string? DisplayName { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// The file name as downloaded. 21 | /// The file display name. 22 | public ModFileModel(string fileName, string? displayName) 23 | { 24 | this.FileName = fileName; 25 | this.DisplayName = displayName; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/CurseForge/ResponseModels/ModLinksModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients.CurseForge.ResponseModels 2 | { 3 | /// A list of links for a mod. 4 | /// The URL for the CurseForge mod page. 5 | /// The URL for the mod's source code, if any. 6 | public record ModLinksModel(string WebsiteUrl, string? SourceUrl); 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/CurseForge/ResponseModels/ModModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients.CurseForge.ResponseModels 2 | { 3 | /// A mod from the CurseForge API. 4 | /// The mod's unique ID on CurseForge. 5 | /// The mod name. 6 | /// The available file downloads. 7 | /// The URLs for this mod. 8 | public record ModModel(int Id, string Name, ModFileModel[] LatestFiles, ModLinksModel Links); 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/CurseForge/ResponseModels/ResponseModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.CurseForge.ResponseModels 4 | { 5 | /// A response from the CurseForge API. 6 | /// The data returned by the API. 7 | public record ResponseModel(TData Data); 8 | } 9 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/GenericModDownload.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients 2 | { 3 | /// Generic metadata about a file download on a mod page. 4 | internal class GenericModDownload : IModDownload 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The download's display name. 10 | public string Name { get; } 11 | 12 | /// The download's description. 13 | public string? Description { get; } 14 | 15 | /// The download's file version. 16 | public string? Version { get; } 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Construct an instance. 23 | /// The download's display name. 24 | /// The download's description. 25 | /// The download's file version. 26 | public GenericModDownload(string name, string? description, string? version) 27 | { 28 | this.Name = name; 29 | this.Description = description; 30 | this.Version = version; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/GitHub/GitLicense.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.GitHub 4 | { 5 | /// The license info for a GitHub project. 6 | internal class GitLicense 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The license display name. 12 | [JsonProperty("name")] 13 | public string Name { get; } 14 | 15 | /// The SPDX ID for the license. 16 | [JsonProperty("spdx_id")] 17 | public string SpdxId { get; } 18 | 19 | /// The URL for the license info. 20 | [JsonProperty("url")] 21 | public string Url { get; } 22 | 23 | 24 | /********* 25 | ** Public methods 26 | *********/ 27 | /// Construct an instance. 28 | /// The license display name. 29 | /// The SPDX ID for the license. 30 | /// The URL for the license info. 31 | public GitLicense(string name, string spdxId, string url) 32 | { 33 | this.Name = name; 34 | this.SpdxId = spdxId; 35 | this.Url = url; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace StardewModdingAPI.Web.Framework.Clients.GitHub 5 | { 6 | /// An HTTP client for fetching metadata from GitHub. 7 | internal interface IGitHubClient : IModSiteClient, IDisposable 8 | { 9 | /********* 10 | ** Methods 11 | *********/ 12 | /// Get basic metadata for a GitHub repository, if available. 13 | /// The repository key (like Pathoschild/SMAPI). 14 | /// Returns the repository info if it exists, else null. 15 | Task GetRepositoryAsync(string repo); 16 | 17 | /// Get the latest release for a GitHub repository. 18 | /// The repository key (like Pathoschild/SMAPI). 19 | /// Whether to return a prerelease version if it's latest. 20 | /// Returns the release if found, else null. 21 | Task GetLatestReleaseAsync(string repo, bool includePrerelease = false); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/IModSiteClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using StardewModdingAPI.Toolkit.Framework.UpdateData; 3 | 4 | namespace StardewModdingAPI.Web.Framework.Clients 5 | { 6 | /// A client for fetching update check info from a mod site. 7 | internal interface IModSiteClient 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The unique key for the mod site. 13 | public ModSiteKey SiteKey { get; } 14 | 15 | 16 | /********* 17 | ** Methods 18 | *********/ 19 | /// Get update check info about a mod. 20 | /// The mod ID. 21 | Task GetModData(string id); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/ModDrop/IModDropClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.ModDrop 4 | { 5 | /// An HTTP client for fetching mod metadata from the ModDrop API. 6 | internal interface IModDropClient : IDisposable, IModSiteClient { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/ModDrop/ResponseModels/ModDataModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients.ModDrop.ResponseModels 2 | { 3 | /// Metadata about a mod from the ModDrop API. 4 | public class ModDataModel 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The mod's unique ID on ModDrop. 10 | public int ID { get; set; } 11 | 12 | /// The mod name. 13 | public string Title { get; set; } 14 | 15 | /// The error code, if any. 16 | public int? ErrorCode { get; set; } 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Construct an instance. 23 | /// The mod's unique ID on ModDrop. 24 | /// The mod name. 25 | /// The error code, if any. 26 | public ModDataModel(int id, string title, int? errorCode) 27 | { 28 | this.ID = id; 29 | this.Title = title; 30 | this.ErrorCode = errorCode; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/ModDrop/ResponseModels/ModListModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.ModDrop.ResponseModels 4 | { 5 | /// A list of mods from the ModDrop API. 6 | public class ModListModel 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The mod data. 12 | public IDictionary Mods { get; } = new Dictionary(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/ModDrop/ResponseModels/ModModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients.ModDrop.ResponseModels 2 | { 3 | /// An entry in a mod list from the ModDrop API. 4 | public class ModModel 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The available file downloads. 10 | public FileDataModel[] Files { get; } 11 | 12 | /// The mod metadata. 13 | public ModDataModel Mod { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// The available file downloads. 21 | /// The mod metadata. 22 | public ModModel(FileDataModel[] files, ModDataModel mod) 23 | { 24 | this.Files = files; 25 | this.Mod = mod; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/Nexus/DisabledNexusClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using StardewModdingAPI.Toolkit.Framework.UpdateData; 3 | 4 | namespace StardewModdingAPI.Web.Framework.Clients.Nexus 5 | { 6 | /// A client for the Nexus website which does nothing, used for local development. 7 | internal class DisabledNexusClient : INexusClient 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// 13 | public ModSiteKey SiteKey => ModSiteKey.Nexus; 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Get update check info about a mod. 20 | /// The mod ID. 21 | public Task GetModData(string id) 22 | { 23 | return Task.FromResult( 24 | new GenericModPage(ModSiteKey.Nexus, id).SetError(RemoteModStatus.TemporaryError, "The Nexus client is currently disabled due to the configuration.") 25 | ); 26 | } 27 | 28 | /// 29 | public void Dispose() { } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/Nexus/INexusClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Clients.Nexus 4 | { 5 | /// An HTTP client for fetching mod metadata from Nexus Mods. 6 | internal interface INexusClient : IModSiteClient, IDisposable { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/Nexus/NexusModStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.Clients.Nexus 2 | { 3 | /// The status of a Nexus mod. 4 | internal enum NexusModStatus 5 | { 6 | /// The mod is published and valid. 7 | Ok, 8 | 9 | /// The mod is hidden by the author. 10 | Hidden, 11 | 12 | /// The mod hasn't been published yet. 13 | NotPublished, 14 | 15 | /// The mod contains adult content which is hidden for anonymous web users. 16 | AdultContentForbidden, 17 | 18 | /// The Nexus API returned an unhandled error. 19 | Other 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Clients/Pastebin/IPastebinClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace StardewModdingAPI.Web.Framework.Clients.Pastebin 5 | { 6 | /// An API client for Pastebin. 7 | internal interface IPastebinClient : IDisposable 8 | { 9 | /// Fetch a saved paste. 10 | /// The paste ID. 11 | Task GetAsync(string id); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Compression/IGzipHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Compression 4 | { 5 | /// Handles GZip compression logic. 6 | internal interface IGzipHelper 7 | { 8 | /********* 9 | ** Methods 10 | *********/ 11 | /// Compress a string. 12 | /// The text to compress. 13 | string CompressString(string text); 14 | 15 | /// Decompress a string. 16 | /// The compressed text. 17 | [return: NotNullIfNotNull("rawText")] 18 | string? DecompressString(string? rawText); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/ConfigModels/BackgroundServicesConfig.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.ConfigModels 2 | { 3 | /// The config settings for background services. 4 | internal class BackgroundServicesConfig 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// Whether to enable background update services. 10 | public bool Enabled { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/ConfigModels/ModCompatibilityListConfig.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.ConfigModels 2 | { 3 | /// The config settings for the mod compatibility list. 4 | internal class ModCompatibilityListConfig 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The number of minutes before which wiki data should be considered old. 10 | public int StaleMinutes { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/ConfigModels/ModOverrideConfig.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.ConfigModels 2 | { 3 | /// Override update-check metadata for a mod. 4 | internal class ModOverrideConfig 5 | { 6 | /// The unique ID from the mod's manifest. 7 | public string ID { get; set; } = null!; 8 | 9 | /// Whether to allow non-standard versions. 10 | public bool AllowNonStandardVersions { get; set; } 11 | 12 | /// The mod page URL to use regardless of which site has the update, or null to use the site URL. 13 | public string? SetUrl { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.ConfigModels 4 | { 5 | /// The config settings for mod update checks. 6 | internal class ModUpdateCheckConfig 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The number of minutes successful update checks should be cached before re-fetching them. 12 | public int SuccessCacheMinutes { get; set; } 13 | 14 | /// The number of minutes failed update checks should be cached before re-fetching them. 15 | public int ErrorCacheMinutes { get; set; } 16 | 17 | /// Update-check metadata to override. 18 | public ModOverrideConfig[] ModOverrides { get; set; } = Array.Empty(); 19 | 20 | /// The update-check config for SMAPI's own update checks. 21 | public SmapiInfoConfig SmapiInfo { get; set; } = null!; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/ConfigModels/SiteConfig.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.ConfigModels 2 | { 3 | /// The site config settings. 4 | public class SiteConfig // must be public to pass into views 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// A message to show below the download button (e.g. for details on downloading a beta version), in Markdown format. 10 | public string? OtherBlurb { get; set; } 11 | 12 | /// A list of supports to credit on the main page, in Markdown format. 13 | public string? SupporterList { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/ConfigModels/SmapiInfoConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.ConfigModels 4 | { 5 | /// The update-check config for SMAPI's own update checks. 6 | internal class SmapiInfoConfig 7 | { 8 | /// The mod ID used for SMAPI update checks. 9 | public string ID { get; set; } = null!; 10 | 11 | /// The default update key used for SMAPI update checks. 12 | public string DefaultUpdateKey { get; set; } = null!; 13 | 14 | /// The update keys to add for SMAPI update checks when the player has a beta version installed. 15 | public string[] AddBetaUpdateKeys { get; set; } = Array.Empty(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/IModDownload.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework 2 | { 3 | /// Generic metadata about a file download on a mod page. 4 | internal interface IModDownload 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The download's display name. 10 | string Name { get; } 11 | 12 | /// The download's description. 13 | string? Description { get; } 14 | 15 | /// The download's file version. 16 | string? Version { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/InternalControllerFeatureProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Controllers; 5 | 6 | namespace StardewModdingAPI.Web.Framework 7 | { 8 | /// Discovers controllers with support for non-public controllers. 9 | internal class InternalControllerFeatureProvider : ControllerFeatureProvider 10 | { 11 | /********* 12 | ** Public methods 13 | *********/ 14 | /// Determines if a given type is a controller. 15 | /// The candidate. 16 | /// true if the type is a controller; otherwise false. 17 | protected override bool IsController(TypeInfo type) 18 | { 19 | return 20 | type.IsClass 21 | && !type.IsAbstract 22 | && (/*type.IsPublic &&*/ !type.ContainsGenericParameters) 23 | && (!type.IsDefined(typeof(NonControllerAttribute)) 24 | && (type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) || type.IsDefined(typeof(ControllerAttribute)))); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/LogParsing/LogParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Web.Framework.LogParsing 4 | { 5 | /// An error while parsing the log file which doesn't require a stack trace to troubleshoot. 6 | internal class LogParseException : Exception 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Construct an instance. 12 | /// The user-friendly error message. 13 | public LogParseException(string message) 14 | : base(message) { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/LogParsing/Models/LogLevel.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI.Internal.ConsoleWriting; 2 | 3 | namespace StardewModdingAPI.Web.Framework.LogParsing.Models 4 | { 5 | /// The log severity levels. 6 | public enum LogLevel 7 | { 8 | /// Tracing info intended for developers. 9 | Trace = ConsoleLogLevel.Trace, 10 | 11 | /// Troubleshooting info that may be relevant to the player. 12 | Debug = ConsoleLogLevel.Debug, 13 | 14 | /// Info relevant to the player. This should be used judiciously. 15 | Info = ConsoleLogLevel.Info, 16 | 17 | /// An issue the player should be aware of. This should be used rarely. 18 | Warn = ConsoleLogLevel.Warn, 19 | 20 | /// A message indicating something went wrong. 21 | Error = ConsoleLogLevel.Error, 22 | 23 | /// Important information to highlight for the player when player action is needed (e.g. new version available). This should be used rarely to avoid alert fatigue. 24 | Alert = ConsoleLogLevel.Alert, 25 | 26 | /// A critical issue that generally signals an immediate end to the application. 27 | Critical = ConsoleLogLevel.Critical 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/LogParsing/Models/LogSection.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.LogParsing.Models 2 | { 3 | /// The different sections of a log. 4 | public enum LogSection 5 | { 6 | /// The list of mods the user has. 7 | ModsList, 8 | 9 | /// The list of content packs the user has. 10 | ContentPackList, 11 | 12 | /// The list of mod updates SMAPI has found. 13 | ModUpdateList 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/LogParsing/Models/ModType.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework.LogParsing.Models 2 | { 3 | /// The type for a instance. 4 | public enum ModType 5 | { 6 | /// A special non-mod entry (e.g. for SMAPI or the game itself). 7 | Special, 8 | 9 | /// A C# mod. 10 | CodeMod, 11 | 12 | /// A content pack loaded by a C# mod. 13 | ContentPack 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/RemoteModStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.Framework 2 | { 3 | /// The mod availability status on a remote site. 4 | internal enum RemoteModStatus 5 | { 6 | /// The mod is valid. 7 | Ok, 8 | 9 | /// The mod data was fetched, but the data is not valid (e.g. version isn't semantic). 10 | InvalidData, 11 | 12 | /// The mod does not exist. 13 | DoesNotExist, 14 | 15 | /// The mod was temporarily unavailable (e.g. the site could not be reached or an unknown error occurred). 16 | TemporaryError 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Storage/IStorageProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Storage 4 | { 5 | /// Provides access to raw data storage. 6 | internal interface IStorageProvider 7 | { 8 | /// Save a text file to storage. 9 | /// The content to upload. 10 | /// Whether to gzip the text. 11 | /// Returns metadata about the save attempt. 12 | Task SaveAsync(string content, bool compress = true); 13 | 14 | /// Fetch raw text from storage. 15 | /// The storage ID returned by . 16 | /// Whether to reset the file expiry. 17 | Task GetAsync(string id, bool renew); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Framework/Storage/UploadResult.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace StardewModdingAPI.Web.Framework.Storage 4 | { 5 | /// The result of an attempt to upload a file. 6 | internal class UploadResult 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// Whether the file upload succeeded. 12 | [MemberNotNullWhen(true, nameof(UploadResult.ID))] 13 | [MemberNotNullWhen(false, nameof(UploadResult.UploadError))] 14 | public bool Succeeded => this.ID != null && this.UploadError == null; 15 | 16 | /// The file ID, if applicable. 17 | public string? ID { get; } 18 | 19 | /// The upload error, if any. 20 | public string? UploadError { get; } 21 | 22 | 23 | /********* 24 | ** Public methods 25 | *********/ 26 | /// Construct an instance. 27 | /// The file ID, if applicable. 28 | /// The upload error, if any. 29 | public UploadResult(string? id, string? uploadError) 30 | { 31 | this.ID = id; 32 | this.UploadError = uploadError; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace StardewModdingAPI.Web 5 | { 6 | /// The main app entry point. 7 | public class Program 8 | { 9 | /********* 10 | ** Public methods 11 | *********/ 12 | /// The main app entry point. 13 | /// The command-line arguments. 14 | public static void Main(string[] args) 15 | { 16 | Host 17 | .CreateDefaultBuilder(args) 18 | .ConfigureWebHostDefaults(builder => builder 19 | .CaptureStartupErrors(true) 20 | .UseSetting("detailedErrors", "true") 21 | .UseStartup() 22 | ) 23 | .Build() 24 | .Run(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:59482/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SMAPI.Web/ViewModels/JsonValidator/JsonValidatorRequestModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.ViewModels.JsonValidator 2 | { 3 | /// The view model for a JSON validation request. 4 | public class JsonValidatorRequestModel 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The schema name with which to validate the JSON. 10 | public string? SchemaName { get; set; } 11 | 12 | /// The raw content to validate. 13 | public string? Content { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Web/ViewModels/LogViewFormat.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.ViewModels 2 | { 3 | /// How a log file should be displayed. 4 | public enum LogViewFormat 5 | { 6 | /// Render a parsed log and metadata. 7 | Default, 8 | 9 | /// Render a raw log with parsed metadata. 10 | RawView, 11 | 12 | /// Render directly as a text file. 13 | RawDownload 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI.Web/ViewModels/ModLinkModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Web.ViewModels 2 | { 3 | /// Metadata about a link. 4 | public class ModLinkModel 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The URL of the linked page. 10 | public string Url { get; } 11 | 12 | /// The suggested link text. 13 | public string Text { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// The URL of the linked page. 21 | /// The suggested link text. 22 | public ModLinkModel(string url, string text) 23 | { 24 | this.Url = url; 25 | this.Text = text; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SMAPI.Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /src/SMAPI.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 4 | This file is committed to source control with the default settings, but added to .gitignore to 5 | avoid accidentally committing login details. 6 | 7 | 8 | 9 | */ 10 | { 11 | "ApiClients": { 12 | "AzureBlobConnectionString": null, 13 | 14 | "GitHubUsername": null, 15 | "GitHubPassword": null, 16 | 17 | "NexusApiKey": null 18 | }, 19 | 20 | "BackgroundServices": { 21 | "Enabled": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/css/file-upload.css: -------------------------------------------------------------------------------- 1 | #inputFile { 2 | display: none; 3 | } 4 | 5 | #input { 6 | width: 100%; 7 | height: 20em; 8 | max-height: 70%; 9 | margin: auto; 10 | box-sizing: border-box; 11 | border-radius: 5px; 12 | border: 1px solid #000088; 13 | outline: none; 14 | box-shadow: inset 0 0 1px 1px rgba(0, 0, 192, .2); 15 | } 16 | 17 | #submit { 18 | font-size: 1.5em; 19 | border-radius: 5px; 20 | outline: none; 21 | box-shadow: inset 0 0 1px 1px rgba(0, 0, 0, .2); 22 | cursor: pointer; 23 | border: 1px solid #008800; 24 | background-color: #cfc; 25 | } 26 | -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/css/privacy.css: -------------------------------------------------------------------------------- 1 | h3 { 2 | border: 0; 3 | } 4 | -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/direct-download-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/direct-download-icon.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/external/patreon-header-help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/external/patreon-header-help.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/external/patreon-header-upcoming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/external/patreon-header-upcoming.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/external/patreon-header-what-i-do.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/external/patreon-header-what-i-do.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/ko-fi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/ko-fi.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/nexus-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/nexus-icon.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/patreon.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/images/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/Content/images/paypal.png -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/Content/js/index.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | /* enable pufferchick */ 3 | var pufferchick = $("#pufferchick"); 4 | $(".cta-dropdown").hover( 5 | function () { 6 | pufferchick.attr("src", "Content/images/pufferchick-cool.svg"); 7 | }, 8 | function () { 9 | pufferchick.attr("src", "Content/images/pufferchick.svg"); 10 | } 11 | ); 12 | 13 | /* enable download dropdowns */ 14 | $(".cta-dropdown a.download").each(function(i, button) { 15 | button = $(button); 16 | var wrapper = button.parent(".cta-dropdown"); 17 | var button = wrapper.find(".download"); 18 | var dropdownContent = wrapper.find(".dropdown-content"); 19 | 20 | $(window).on("click", function(e) { 21 | var target = $(e.target); 22 | 23 | // toggle dropdown on button click 24 | if (target.is(button) || $.contains(button.get(0), target.get(0))) { 25 | e.preventDefault(); 26 | dropdownContent.toggle(); 27 | } 28 | 29 | // else hide dropdown 30 | else 31 | dropdownContent.hide(); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI.Web/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/SMAPI.Web/wwwroot/schemas/i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://smapi.io/schemas/i18n.json", 4 | "title": "SMAPI i18n file", 5 | "description": "A translation file for a SMAPI mod or content pack.", 6 | "@documentationUrl": "https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Translation", 7 | 8 | "allowComments": true, 9 | "allowTrailingCommas": true, 10 | 11 | "type": "object", 12 | "properties": { 13 | "$schema": { 14 | "title": "Schema", 15 | "description": "A reference to this JSON schema. Not part of the actual format, but useful for validation tools.", 16 | "type": "string", 17 | "const": "https://smapi.io/schemas/i18n.json" 18 | } 19 | }, 20 | 21 | "additionalProperties": { 22 | "type": "string", 23 | "@errorMessages": { 24 | "type": "Invalid property. Translation files can only contain text property values." 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI/ContentSource.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// Specifies a source containing content that can be loaded. 4 | public enum ContentSource 5 | { 6 | /// Assets in the game's content manager (i.e. XNBs in the game's content folder). 7 | GameContent, 8 | 9 | /// XNB files in the current mod's folder. 10 | ModFolder 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/Enums/SkillType.cs: -------------------------------------------------------------------------------- 1 | using StardewValley; 2 | 3 | namespace StardewModdingAPI.Enums 4 | { 5 | /// The player skill types. 6 | public enum SkillType 7 | { 8 | /// The combat skill. 9 | Combat = Farmer.combatSkill, 10 | 11 | /// The farming skill. 12 | Farming = Farmer.farmingSkill, 13 | 14 | /// The fishing skill. 15 | Fishing = Farmer.fishingSkill, 16 | 17 | /// The foraging skill. 18 | Foraging = Farmer.foragingSkill, 19 | 20 | /// The mining skill. 21 | Mining = Farmer.miningSkill, 22 | 23 | /// The luck skill. 24 | Luck = Farmer.luckSkill 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/Events/AssetEditPriority.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Events 2 | { 3 | /// The priority for an asset edit when multiple apply for the same asset. 4 | /// You can also specify arbitrary intermediate values, like AssetLoadPriority.Low + 5. 5 | public enum AssetEditPriority 6 | { 7 | /// This edit should be applied before (i.e. 'under') edits. 8 | Early = -1000, 9 | 10 | /// The default priority. 11 | Default = 0, 12 | 13 | /// This edit should be applied after (i.e. 'on top of') edits. 14 | Late = 1000 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/AssetLoadPriority.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Events 2 | { 3 | /// The priority for an asset load when multiple apply for the same asset. 4 | /// If multiple non- loads have the same priority, the one registered first will be selected. You can also specify arbitrary intermediate values, like AssetLoadPriority.Low + 5. 5 | public enum AssetLoadPriority 6 | { 7 | /// This load is optional and can safely be skipped if there are higher-priority loads. 8 | Low = -1000, 9 | 10 | /// The load is optional and can safely be skipped if there are higher-priority loads, but it should still be preferred over any -priority loads. 11 | Medium = 0, 12 | 13 | /// The load is optional and can safely be skipped if there are higher-priority loads, but it should still be preferred over any - or -priority loads. 14 | High = 1000, 15 | 16 | /// The load is not optional. If more than one loader has priority, SMAPI will log an error and ignore all of them. 17 | Exclusive = int.MaxValue 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SMAPI/Events/CursorMovedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments when the in-game cursor is moved. 6 | public class CursorMovedEventArgs : EventArgs 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The previous cursor position. 12 | public ICursorPosition OldPosition { get; } 13 | 14 | /// The current cursor position. 15 | public ICursorPosition NewPosition { get; } 16 | 17 | 18 | /********* 19 | ** Public methods 20 | *********/ 21 | /// Construct an instance. 22 | /// The previous cursor position. 23 | /// The new cursor position. 24 | internal CursorMovedEventArgs(ICursorPosition oldPosition, ICursorPosition newPosition) 25 | { 26 | this.OldPosition = oldPosition; 27 | this.NewPosition = newPosition; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SMAPI/Events/DayEndingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class DayEndingEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/DayStartedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class DayStartedEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/EventPriority.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Events 2 | { 3 | /// The event priorities for method handlers. 4 | public enum EventPriority 5 | { 6 | /// Low priority. 7 | Low = -1000, 8 | 9 | /// The default priority. 10 | Normal = 0, 11 | 12 | /// High priority. 13 | High = 1000 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/Events/EventPriorityAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// An attribute which specifies the priority for an event handler. 6 | [AttributeUsage(AttributeTargets.Method)] 7 | public class EventPriorityAttribute : Attribute 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The event handler priority, relative to other handlers across all mods registered for this event. 13 | internal EventPriority Priority { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// The event handler priority, relative to other handlers across all mods registered for this event. Higher-priority handlers are notified before lower-priority handlers. 21 | public EventPriorityAttribute(EventPriority priority) 22 | { 23 | this.Priority = priority; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/Events/GameLaunchedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class GameLaunchedEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/IInputEvents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Events raised when the player provides input using a controller, keyboard, or mouse. 6 | public interface IInputEvents 7 | { 8 | /// Raised after the player presses or releases any buttons on the keyboard, controller, or mouse. 9 | event EventHandler ButtonsChanged; 10 | 11 | /// Raised after the player presses a button on the keyboard, controller, or mouse. 12 | event EventHandler ButtonPressed; 13 | 14 | /// Raised after the player releases a button on the keyboard, controller, or mouse. 15 | event EventHandler ButtonReleased; 16 | 17 | /// Raised after the player moves the in-game cursor. 18 | event EventHandler CursorMoved; 19 | 20 | /// Raised after the player scrolls the mouse wheel. 21 | event EventHandler MouseWheelScrolled; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/SMAPI/Events/IMultiplayerEvents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Events raised for multiplayer messages and connections. 6 | public interface IMultiplayerEvents 7 | { 8 | /// Raised after the mod context for a peer is received. This happens before the game approves the connection (), so the player doesn't yet exist in the game. This is the earliest point where messages can be sent to the peer via SMAPI. 9 | event EventHandler PeerContextReceived; 10 | 11 | /// Raised after a peer connection is approved by the game. 12 | event EventHandler PeerConnected; 13 | 14 | /// Raised after a mod message is received over the network. 15 | event EventHandler ModMessageReceived; 16 | 17 | /// Raised after the connection with a peer is severed. 18 | event EventHandler PeerDisconnected; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SMAPI/Events/IPlayerEvents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Events raised when the player data changes. 6 | public interface IPlayerEvents 7 | { 8 | /// Raised after items are added or removed to a player's inventory. NOTE: this event is currently only raised for the current player. 9 | event EventHandler InventoryChanged; 10 | 11 | /// Raised after a player skill level changes. This happens as soon as they level up, not when the game notifies the player after their character goes to bed. NOTE: this event is currently only raised for the current player. 12 | event EventHandler LevelChanged; 13 | 14 | /// Raised after a player warps to a new location. NOTE: this event is currently only raised for the current player. 15 | event EventHandler Warped; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI/Events/ItemStackSizeChange.cs: -------------------------------------------------------------------------------- 1 | using StardewValley; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// An inventory item stack size change. 6 | public class ItemStackSizeChange 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The item whose stack size changed. 12 | public Item Item { get; } 13 | 14 | /// The previous stack size. 15 | public int OldSize { get; } 16 | 17 | /// The new stack size. 18 | public int NewSize { get; } 19 | 20 | 21 | /********* 22 | ** Public methods 23 | *********/ 24 | /// Construct an instance. 25 | /// The item whose stack size changed. 26 | /// The previous stack size. 27 | /// The new stack size. 28 | public ItemStackSizeChange(Item item, int oldSize, int newSize) 29 | { 30 | this.Item = item; 31 | this.OldSize = oldSize; 32 | this.NewSize = newSize; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/SMAPI/Events/LoadStageChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Enums; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class LoadStageChangedEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The previous load stage. 13 | public LoadStage OldStage { get; } 14 | 15 | /// The new load stage. 16 | public LoadStage NewStage { get; } 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Construct an instance. 23 | /// The previous load stage. 24 | /// The new load stage. 25 | public LoadStageChangedEventArgs(LoadStage old, LoadStage current) 26 | { 27 | this.OldStage = old; 28 | this.NewStage = current; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SMAPI/Events/LocationListChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using StardewValley; 5 | 6 | namespace StardewModdingAPI.Events 7 | { 8 | /// Event arguments for a event. 9 | public class LocationListChangedEventArgs : EventArgs 10 | { 11 | /********* 12 | ** Accessors 13 | *********/ 14 | /// The added locations. 15 | public IEnumerable Added { get; } 16 | 17 | /// The removed locations. 18 | public IEnumerable Removed { get; } 19 | 20 | 21 | /********* 22 | ** Public methods 23 | *********/ 24 | /// Construct an instance. 25 | /// The added locations. 26 | /// The removed locations. 27 | internal LocationListChangedEventArgs(IEnumerable added, IEnumerable removed) 28 | { 29 | this.Added = added.ToArray(); 30 | this.Removed = removed.ToArray(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SMAPI/Events/MenuChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewValley.Menus; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class MenuChangedEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The previous menu, if any. 13 | public IClickableMenu? OldMenu { get; } 14 | 15 | /// The current menu, if any. 16 | public IClickableMenu? NewMenu { get; } 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Construct an instance. 23 | /// The previous menu, if any. 24 | /// The current menu, if any. 25 | internal MenuChangedEventArgs(IClickableMenu? oldMenu, IClickableMenu? newMenu) 26 | { 27 | this.OldMenu = oldMenu; 28 | this.NewMenu = newMenu; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SMAPI/Events/OneSecondUpdateTickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class OneSecondUpdateTickedEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The number of ticks elapsed since the game started, including the current tick. 13 | public uint Ticks => SCore.TicksElapsed; 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Get whether is a multiple of the given . This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second). 20 | /// The factor to check. 21 | public bool IsMultipleOf(uint number) 22 | { 23 | return this.Ticks % number == 0; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/Events/OneSecondUpdateTickingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class OneSecondUpdateTickingEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The number of ticks elapsed since the game started, excluding the upcoming tick. 13 | public uint Ticks => SCore.TicksElapsed; 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Get whether is a multiple of the given . This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second). 20 | /// The factor to check. 21 | public bool IsMultipleOf(uint number) 22 | { 23 | return this.Ticks % number == 0; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/Events/PeerConnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class PeerConnectedEventArgs : EventArgs 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The peer whose metadata was received. 12 | public IMultiplayerPeer Peer { get; } 13 | 14 | 15 | /********* 16 | ** Public methods 17 | *********/ 18 | /// Construct an instance. 19 | /// The peer whose metadata was received. 20 | internal PeerConnectedEventArgs(IMultiplayerPeer peer) 21 | { 22 | this.Peer = peer; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/SMAPI/Events/PeerContextReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class PeerContextReceivedEventArgs : EventArgs 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The peer whose metadata was received. 12 | public IMultiplayerPeer Peer { get; } 13 | 14 | 15 | /********* 16 | ** Public methods 17 | *********/ 18 | /// Construct an instance. 19 | /// The peer whose metadata was received. 20 | internal PeerContextReceivedEventArgs(IMultiplayerPeer peer) 21 | { 22 | this.Peer = peer; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/SMAPI/Events/PeerDisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class PeerDisconnectedEventArgs : EventArgs 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The peer who disconnected. 12 | public IMultiplayerPeer Peer { get; } 13 | 14 | 15 | /********* 16 | ** Public methods 17 | *********/ 18 | /// Construct an instance. 19 | /// The peer who disconnected. 20 | internal PeerDisconnectedEventArgs(IMultiplayerPeer peer) 21 | { 22 | this.Peer = peer; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderedActiveMenuEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderedActiveMenuEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderedEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderedHudEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderedHudEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderedWorldEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderedWorldEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderingActiveMenuEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderingActiveMenuEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderingEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderingHudEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderingHudEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/RenderingWorldEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using StardewValley; 4 | 5 | namespace StardewModdingAPI.Events 6 | { 7 | /// Event arguments for an event. 8 | public class RenderingWorldEventArgs : EventArgs 9 | { 10 | /********* 11 | ** Accessors 12 | *********/ 13 | /// The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch. 14 | public SpriteBatch SpriteBatch => Game1.spriteBatch; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Events/ReturnedToTitleEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class ReturnedToTitleEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/SaveCreatedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class SaveCreatedEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/SaveCreatingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class SaveCreatingEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/SaveLoadedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class SaveLoadedEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/SavedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class SavedEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/SavingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class SavingEventArgs : EventArgs { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Events/TimeChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Events 4 | { 5 | /// Event arguments for an event. 6 | public class TimeChangedEventArgs : EventArgs 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The previous time of day in 24-hour notation (like 1600 for 4pm). The clock time resets when the player sleeps, so 2am (before sleeping) is 2600. 12 | public int OldTime { get; } 13 | 14 | /// The current time of day in 24-hour notation (like 1600 for 4pm). The clock time resets when the player sleeps, so 2am (before sleeping) is 2600. 15 | public int NewTime { get; } 16 | 17 | 18 | /********* 19 | ** Public methods 20 | *********/ 21 | /// Construct an instance. 22 | /// The previous time of day in 24-hour notation (like 1600 for 4pm). 23 | /// The current time of day in 24-hour notation (like 1600 for 4pm). 24 | internal TimeChangedEventArgs(int oldTime, int newTime) 25 | { 26 | this.OldTime = oldTime; 27 | this.NewTime = newTime; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SMAPI/Events/UnvalidatedUpdateTickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class UnvalidatedUpdateTickedEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The number of ticks elapsed since the game started, including the current tick. 13 | public uint Ticks => SCore.TicksElapsed; 14 | 15 | /// Whether is a multiple of 60, which happens approximately once per second. 16 | public bool IsOneSecond => this.Ticks % 60 == 0; 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Get whether is a multiple of the given . This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second). 23 | /// The factor to check. 24 | public bool IsMultipleOf(uint number) 25 | { 26 | return this.Ticks % number == 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Events/UnvalidatedUpdateTickingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class UnvalidatedUpdateTickingEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The number of ticks elapsed since the game started, excluding the upcoming tick. 13 | public uint Ticks => SCore.TicksElapsed; 14 | 15 | /// Whether is a multiple of 60, which happens approximately once per second. 16 | public bool IsOneSecond => this.Ticks % 60 == 0; 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Get whether is a multiple of the given . This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second). 23 | /// The factor to check. 24 | public bool IsMultipleOf(uint number) 25 | { 26 | return this.Ticks % number == 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Events/UpdateTickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class UpdateTickedEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The number of ticks elapsed since the game started, including the current tick. 13 | public uint Ticks => SCore.TicksElapsed; 14 | 15 | /// Whether is a multiple of 60, which happens approximately once per second. 16 | public bool IsOneSecond => this.Ticks % 60 == 0; 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Get whether is a multiple of the given . This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second). 23 | /// The factor to check. 24 | public bool IsMultipleOf(uint number) 25 | { 26 | return this.Ticks % number == 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Events/UpdateTickingEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class UpdateTickingEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The number of ticks elapsed since the game started, excluding the upcoming tick. 13 | public uint Ticks => SCore.TicksElapsed; 14 | 15 | /// Whether is a multiple of 60, which happens approximately once per second. 16 | public bool IsOneSecond => this.Ticks % 60 == 0; 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Get whether is a multiple of the given . This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second). 23 | /// The factor to check. 24 | public bool IsMultipleOf(uint number) 25 | { 26 | return this.Ticks % number == 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Events/WindowResizedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework; 3 | 4 | namespace StardewModdingAPI.Events 5 | { 6 | /// Event arguments for an event. 7 | public class WindowResizedEventArgs : EventArgs 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The previous window size. 13 | public Point OldSize { get; } 14 | 15 | /// The current window size. 16 | public Point NewSize { get; } 17 | 18 | 19 | /********* 20 | ** Public methods 21 | *********/ 22 | /// Construct an instance. 23 | /// The previous window size. 24 | /// The current window size. 25 | internal WindowResizedEventArgs(Point oldSize, Point newSize) 26 | { 27 | this.OldSize = oldSize; 28 | this.NewSize = newSize; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Commands/IInternalCommand.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Commands 2 | { 3 | /// A core SMAPI console command. 4 | interface IInternalCommand 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The command name, which the user must type to trigger it. 10 | string Name { get; } 11 | 12 | /// The human-readable documentation shown when the player runs the built-in 'help' command. 13 | string Description { get; } 14 | 15 | 16 | /********* 17 | ** Methods 18 | *********/ 19 | /// Handle the console command when it's entered by the user. 20 | /// The command arguments. 21 | /// Writes messages to the console. 22 | void HandleCommand(string[] args, IMonitor monitor); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Content/AssetDataForDictionary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace StardewModdingAPI.Framework.Content 5 | { 6 | /// Encapsulates access and changes to dictionary content being read from a data file. 7 | internal class AssetDataForDictionary : AssetData>, IAssetDataForDictionary 8 | { 9 | /********* 10 | ** Public methods 11 | *********/ 12 | /// Construct an instance. 13 | /// The content's locale code, if the content is localized. 14 | /// The asset name being read. 15 | /// The content data being read. 16 | /// Normalizes an asset key to match the cache key. 17 | /// A callback to invoke when the data is replaced (if any). 18 | public AssetDataForDictionary(string? locale, IAssetName assetName, IDictionary data, Func getNormalizedPath, Action> onDataReplaced) 19 | : base(locale, assetName, data, getNormalizedPath, onDataReplaced) { } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Content/AssetEditOperation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Events; 3 | 4 | namespace StardewModdingAPI.Framework.Content 5 | { 6 | /// An edit to apply to an asset when it's requested from the content pipeline. 7 | /// The mod applying the edit. 8 | /// If there are multiple edits that apply to the same asset, the priority with which this one should be applied. 9 | /// The content pack on whose behalf the edit is being applied, if any. 10 | /// Apply the edit to an asset. 11 | internal record AssetEditOperation(IModMetadata Mod, AssetEditPriority Priority, IModMetadata? OnBehalfOf, Action ApplyEdit); 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Content/AssetLoadOperation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StardewModdingAPI.Events; 3 | 4 | namespace StardewModdingAPI.Framework.Content 5 | { 6 | /// An operation which provides the initial instance of an asset when it's requested from the content pipeline. 7 | /// The mod applying the edit. 8 | /// If there are multiple loads that apply to the same asset, the priority with which this one should be applied. 9 | /// The content pack on whose behalf the asset is being loaded, if any. 10 | /// Load the initial value for an asset. 11 | internal record AssetLoadOperation(IModMetadata Mod, IModMetadata? OnBehalfOf, AssetLoadPriority Priority, Func GetData); 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Content/AssetOperationGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Framework.Content 4 | { 5 | /// A set of operations to apply to an asset. 6 | /// The load operations to apply. 7 | /// The edit operations to apply. 8 | internal record AssetOperationGroup(List LoadOperations, List EditOperations); 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Content/RawTextureData.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | namespace StardewModdingAPI.Framework.Content 4 | { 5 | /// The raw data for an image read from the filesystem. 6 | /// The image width. 7 | /// The image height. 8 | /// The loaded image data. 9 | internal record RawTextureData(int Width, int Height, Color[] Data) : IRawTextureData; 10 | } 11 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Deprecations/DeprecationLevel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Deprecations 2 | { 3 | /// Indicates how deprecated something is. 4 | internal enum DeprecationLevel 5 | { 6 | /// It's deprecated but won't be removed soon. Mod authors have some time to update their mods. Deprecation warnings should be logged, but not written to the console. 7 | Notice, 8 | 9 | /// Mods should no longer be using it. Deprecation messages should be debug entries in the console. 10 | Info, 11 | 12 | /// The code will be removed soon. Deprecation messages should be warnings in the console. 13 | PendingRemoval 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Events/IManagedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Events 2 | { 3 | /// Metadata for an event raised by SMAPI. 4 | internal interface IManagedEvent 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// A human-readable name for the event. 10 | string EventName { get; } 11 | 12 | /// Whether any handlers are listening to the event. 13 | bool HasListeners { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Events/ModEventsBase.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Events 2 | { 3 | /// An internal base class for event API classes. 4 | internal abstract class ModEventsBase 5 | { 6 | /********* 7 | ** Fields 8 | *********/ 9 | /// The underlying event manager. 10 | protected readonly EventManager EventManager; 11 | 12 | /// The mod which uses this instance. 13 | protected readonly IModMetadata Mod; 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// The mod which uses this instance. 21 | /// The underlying event manager. 22 | internal ModEventsBase(IModMetadata mod, EventManager eventManager) 23 | { 24 | this.Mod = mod; 25 | this.EventManager = eventManager; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Exceptions/ContentLoadErrorType.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Exceptions 2 | { 3 | /// Indicates why loading an asset through the content pipeline failed. 4 | internal enum ContentLoadErrorType 5 | { 6 | /// The asset name is empty or has an invalid format. 7 | InvalidName, 8 | 9 | /// The asset doesn't exist. 10 | AssetDoesNotExist, 11 | 12 | /// The asset is not available in the current context (e.g. an attempt to load another mod's assets). 13 | AccessDenied, 14 | 15 | /// The asset exists, but the data could not be deserialized or it doesn't match the expected type. 16 | InvalidData, 17 | 18 | /// An unknown error occurred. 19 | Other 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Exceptions/SAssemblyLoadFailedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Framework.Exceptions 4 | { 5 | /// An exception thrown when an assembly can't be loaded by SMAPI, with all the relevant details in the message. 6 | internal class SAssemblyLoadFailedException : Exception 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Construct an instance. 12 | /// The error message. 13 | public SAssemblyLoadFailedException(string message) 14 | : base(message) { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Exceptions/SContentLoadException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Content; 3 | 4 | namespace StardewModdingAPI.Framework.Exceptions 5 | { 6 | /// An implementation of used by SMAPI to detect whether it was thrown by SMAPI or the underlying framework. 7 | internal class SContentLoadException : ContentLoadException 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// Why loading the asset through the content pipeline failed. 13 | public ContentLoadErrorType ErrorType { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Construct an instance. 20 | /// Why loading the asset through the content pipeline failed. 21 | /// The error message. 22 | /// The underlying exception, if any. 23 | public SContentLoadException(ContentLoadErrorType errorType, string message, Exception? ex = null) 24 | : base(message, ex) 25 | { 26 | this.ErrorType = errorType; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ExitState.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework 2 | { 3 | /// The SMAPI exit state. 4 | internal enum ExitState 5 | { 6 | /// SMAPI didn't trigger an explicit exit. 7 | None, 8 | 9 | /// The game is exiting normally. 10 | GameExit, 11 | 12 | /// The game is exiting due to an error. 13 | Crash 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Input/IInputStateBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Framework.Input 4 | { 5 | /// Manages input state. 6 | /// The handler type. 7 | /// The state type. 8 | internal interface IInputStateBuilder 9 | where TState : struct 10 | where THandler : IInputStateBuilder 11 | { 12 | /********* 13 | ** Methods 14 | *********/ 15 | /// Override the states for a set of buttons. 16 | /// The button state overrides. 17 | THandler OverrideButtons(IDictionary overrides); 18 | 19 | /// Get the currently pressed buttons. 20 | IEnumerable GetPressedButtons(); 21 | 22 | /// Get the equivalent state. 23 | TState GetState(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Logging/LogOnceCacheKey.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace StardewModdingAPI.Framework.Logging 4 | { 5 | /// The cache key for the . 6 | /// The log message. 7 | /// The log level. 8 | [SuppressMessage("ReSharper", "NotAccessedPositionalProperty.Local", Justification = "This is only used as a lookup key.")] 9 | internal readonly record struct LogOnceCacheKey(string Message, LogLevel Level); 10 | } 11 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModHelpers/BaseHelper.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.ModHelpers 2 | { 3 | /// The common base class for mod helpers. 4 | internal abstract class BaseHelper : IModLinked 5 | { 6 | /********* 7 | ** Fields 8 | *********/ 9 | /// The mod using this instance. 10 | protected readonly IModMetadata Mod; 11 | 12 | 13 | /********* 14 | ** Accessors 15 | *********/ 16 | /// 17 | public string ModID => this.Mod.Manifest.UniqueID; 18 | 19 | 20 | /********* 21 | ** Protected methods 22 | *********/ 23 | /// Construct an instance. 24 | /// The mod using this instance. 25 | protected BaseHelper(IModMetadata mod) 26 | { 27 | this.Mod = mod; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLinked.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework 2 | { 3 | /// A generic tuple which links something to a mod. 4 | /// The interceptor type. 5 | internal class ModLinked 6 | { 7 | /********* 8 | ** Accessors 9 | *********/ 10 | /// The mod metadata. 11 | public IModMetadata Mod { get; } 12 | 13 | /// The instance linked to the mod. 14 | public T Data { get; } 15 | 16 | 17 | /********* 18 | ** Public methods 19 | *********/ 20 | /// Construct an instance. 21 | /// The mod metadata. 22 | /// The instance linked to the mod. 23 | public ModLinked(IModMetadata mod, T data) 24 | { 25 | this.Mod = mod; 26 | this.Data = data; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/AssemblyLoadStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.ModLoading 2 | { 3 | /// Indicates the result of an assembly load. 4 | internal enum AssemblyLoadStatus 5 | { 6 | /// The assembly was loaded successfully. 7 | Okay = 1, 8 | 9 | /// The assembly could not be loaded. 10 | Failed = 2, 11 | 12 | /// The assembly is already loaded. 13 | AlreadyLoaded = 3 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/IncompatibleInstructionException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Framework.ModLoading 4 | { 5 | /// An exception raised when an incompatible instruction is found while loading a mod assembly. 6 | internal class IncompatibleInstructionException : Exception 7 | { 8 | /********* 9 | ** Public methods 10 | *********/ 11 | /// Construct an instance. 12 | public IncompatibleInstructionException() 13 | : base("Found incompatible CIL instructions.") { } 14 | 15 | /// Construct an instance. 16 | /// A message which describes the error. 17 | public IncompatibleInstructionException(string message) 18 | : base(message) { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/InvalidModStateException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Framework.ModLoading 4 | { 5 | /// An exception which indicates that something went seriously wrong while loading mods, and SMAPI should abort outright. 6 | internal class InvalidModStateException : Exception 7 | { 8 | /// Construct an instance. 9 | /// The error message. 10 | /// The underlying exception, if any. 11 | public InvalidModStateException(string message, Exception? ex = null) 12 | : base(message, ex) { } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/ModDependencyStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.ModLoading 2 | { 3 | /// The status of a given mod in the dependency-sorting algorithm. 4 | internal enum ModDependencyStatus 5 | { 6 | /// The mod hasn't been visited yet. 7 | Queued, 8 | 9 | /// The mod is currently being analyzed as part of a dependency chain. 10 | Checking, 11 | 12 | /// The mod has already been sorted. 13 | Sorted, 14 | 15 | /// The mod couldn't be sorted due to a metadata issue (e.g. missing dependencies). 16 | Failed 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/ModMetadataStatus.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.ModLoading 2 | { 3 | /// Indicates the status of a mod's metadata resolution. 4 | internal enum ModMetadataStatus 5 | { 6 | /// The mod has been found, but hasn't been processed yet. 7 | Found, 8 | 9 | /// The mod cannot be loaded. 10 | Failed 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/RewriteFacades/CraftingPageMobileMethods.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_FOR_MOBILE 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using StardewValley; 7 | using StardewValley.Menus; 8 | using StardewValley.Objects; 9 | 10 | namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades 11 | { 12 | public class CraftingPageMobileMethods : CraftingPageMobile 13 | { 14 | public CraftingPageMobileMethods(int x, int y, int width, int height, bool cooking = false, bool standalone_menu = false, List material_containers = null) 15 | : base(x, y, width, height, cooking, 300, material_containers) 16 | { 17 | } 18 | } 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/RewriteFacades/EnumMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades; 4 | 5 | public static class EnumMethods 6 | { 7 | public static string[] GetNames() where TEnum : struct, Enum 8 | { 9 | Type enumType = typeof(TEnum); 10 | return Enum.GetNames(enumType); 11 | } 12 | 13 | public static bool IsDefined(TEnum value) where TEnum : struct, Enum 14 | { 15 | Type enumType = typeof(TEnum); 16 | return Enum.IsDefined(enumType, value); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/RewriteFacades/GameMenuMethods.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_FOR_MOBILE 2 | using System.Reflection; 3 | using StardewValley.Menus; 4 | 5 | namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades 6 | { 7 | public class GameMenuMethods : GameMenu 8 | { 9 | public GameMenuMethods(bool playOpeningSound = true) : base() 10 | { 11 | } 12 | 13 | public GameMenuMethods(int startingTab, int extra = -1, bool playOpeningSound = true) : base(startingTab, extra) 14 | { 15 | } 16 | public void changeTab(int whichTab, bool playSound = true) 17 | { 18 | base.changeTab(whichTab); 19 | } 20 | } 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceMethods.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_FOR_MOBILE 2 | using System.Reflection; 3 | using System.Reflection.Emit; 4 | using HarmonyLib; 5 | 6 | namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades 7 | { 8 | public class HarmonyInstanceMethods 9 | { 10 | public static MethodInfo Patch( 11 | Harmony instance, 12 | MethodBase original, 13 | HarmonyMethod prefix = null, 14 | HarmonyMethod postfix = null, 15 | HarmonyMethod transpiler = null, 16 | HarmonyMethod finalizer = null) 17 | { 18 | if (Constants.HarmonyEnabled) 19 | return instance.Patch(original, prefix, postfix, transpiler, finalizer); 20 | else 21 | return null; 22 | } 23 | public static void PatchAll( 24 | Harmony instance 25 | ) 26 | { 27 | if (Constants.HarmonyEnabled) 28 | instance.PatchAll(); 29 | } 30 | public static void PatchAllToAssembly( 31 | Harmony instance, 32 | Assembly assembly) 33 | { 34 | if (Constants.HarmonyEnabled) 35 | instance.PatchAll(assembly); 36 | } 37 | } 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/RewriteFacades/MapPageMethods.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_FOR_MOBILE 2 | using StardewValley.Menus; 3 | 4 | namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades 5 | { 6 | public class MapPageMethods : MapPage 7 | { 8 | public MapPageMethods(int x, int y, int width, int height) 9 | : base(x, y, width, height, 1f, 1f) 10 | { 11 | } 12 | 13 | } 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/RewriteFacades/TextBoxMethods.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_FOR_MOBILE 2 | using System.Reflection; 3 | using StardewValley.Menus; 4 | 5 | #pragma warning disable 1591 // missing documentation 6 | namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades 7 | { 8 | public class TextBoxMethods 9 | { 10 | public static void SelectedSetter(TextBox textBox, bool value) 11 | { 12 | if(!textBox.Selected && value) 13 | { 14 | typeof(TextBox).GetMethod("ShowAndroidKeyboard", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(textBox, new object[] { }); 15 | textBox.Selected = value; 16 | } 17 | else 18 | textBox.Selected = value; 19 | } 20 | } 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/ModLoading/Rewriters/ArchitectureAssemblyRewriter.cs: -------------------------------------------------------------------------------- 1 | using Mono.Cecil; 2 | using StardewModdingAPI.Framework.ModLoading.Framework; 3 | 4 | namespace StardewModdingAPI.Framework.ModLoading.Rewriters 5 | { 6 | /// Removes the 32-bit-only from loaded assemblies. 7 | internal class ArchitectureAssemblyRewriter : BaseInstructionHandler 8 | { 9 | /********* 10 | ** Public methods 11 | *********/ 12 | /// Construct an instance. 13 | public ArchitectureAssemblyRewriter() 14 | : base(defaultPhrase: "32-bit architecture") { } 15 | 16 | 17 | /// 18 | public override bool Handle(ModuleDefinition module) 19 | { 20 | if (module.Attributes.HasFlag(ModuleAttributes.Required32Bit)) 21 | { 22 | module.Attributes &= ~ModuleAttributes.Required32Bit; 23 | this.MarkRewritten(); 24 | return true; 25 | } 26 | 27 | return false; 28 | } 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Networking/MessageType.cs: -------------------------------------------------------------------------------- 1 | using StardewValley; 2 | 3 | namespace StardewModdingAPI.Framework.Networking 4 | { 5 | /// Network message types recognized by SMAPI and Stardew Valley. 6 | internal enum MessageType : byte 7 | { 8 | /********* 9 | ** SMAPI 10 | *********/ 11 | /// A data message intended for mods to consume. 12 | ModMessage = 254, 13 | 14 | /// Metadata context about a player synced by SMAPI. 15 | ModContext = 255, 16 | 17 | /********* 18 | ** Vanilla 19 | *********/ 20 | /// Metadata about the host server sent to a farmhand. 21 | ServerIntroduction = Multiplayer.serverIntroduction, 22 | 23 | /// Metadata about a player sent to a farmhand or server. 24 | PlayerIntroduction = Multiplayer.playerIntroduction 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Networking/MultiplayerPeerMod.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace StardewModdingAPI.Framework.Networking 4 | { 5 | internal class MultiplayerPeerMod : IMultiplayerPeerMod 6 | { 7 | /********* 8 | ** Accessors 9 | *********/ 10 | /// 11 | public string Name { get; } 12 | 13 | /// 14 | public string ID { get; } 15 | 16 | /// 17 | public ISemanticVersion Version { get; } 18 | 19 | 20 | /********* 21 | ** Public methods 22 | *********/ 23 | /// Construct an instance. 24 | /// The mod metadata. 25 | [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The ID shouldn't be null, but we should handle it to avoid an error just in case.")] 26 | public MultiplayerPeerMod(RemoteContextModModel mod) 27 | { 28 | this.Name = mod.Name; 29 | this.ID = mod.ID?.Trim() ?? string.Empty; 30 | this.Version = mod.Version; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Networking/RemoteContextModModel.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Networking 2 | { 3 | /// Metadata about an installed mod exchanged with connected computers. 4 | public class RemoteContextModModel 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The unique mod ID. 10 | public string ID { get; } 11 | 12 | /// The mod's display name. 13 | public string Name { get; } 14 | 15 | /// The mod version. 16 | public ISemanticVersion Version { get; } 17 | 18 | 19 | /********* 20 | ** Accessors 21 | *********/ 22 | /// Construct an instance. 23 | /// The unique mod ID. 24 | /// The mod's display name. 25 | /// The mod version. 26 | public RemoteContextModModel(string id, string name, ISemanticVersion version) 27 | { 28 | this.ID = id; 29 | this.Name = name; 30 | this.Version = version; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Reflection/IInterfaceProxyFactory.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.Reflection 2 | { 3 | /// Generates proxy classes to access mod APIs through an arbitrary interface. 4 | internal interface IInterfaceProxyFactory 5 | { 6 | /********* 7 | ** Methods 8 | *********/ 9 | /// Create an API proxy. 10 | /// The interface through which to access the API. 11 | /// The API instance to access. 12 | /// The unique ID of the mod consuming the API. 13 | /// The unique ID of the mod providing the API. 14 | TInterface CreateProxy(object instance, string sourceModID, string targetModID) 15 | where TInterface : class; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/Singleton.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework 2 | { 3 | /// Provides singleton instances of a given type. 4 | /// The instance type. 5 | internal static class Singleton where T : new() 6 | { 7 | /// The singleton instance. 8 | public static T Instance { get; } = new(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace StardewModdingAPI.Framework.StateTracking.Comparers 6 | { 7 | /// Compares instances using . 8 | /// The value type. 9 | internal class EquatableComparer : IEqualityComparer where T : IEquatable 10 | { 11 | /********* 12 | ** Public methods 13 | *********/ 14 | /// Determines whether the specified objects are equal. 15 | /// true if the specified objects are equal; otherwise, false. 16 | /// The first object to compare. 17 | /// The second object to compare. 18 | public bool Equals(T? x, T? y) 19 | { 20 | if (x == null) 21 | return y == null; 22 | return x.Equals(y); 23 | } 24 | 25 | /// Get a hash code for the specified object. 26 | /// The value. 27 | public int GetHashCode(T obj) 28 | { 29 | return RuntimeHelpers.GetHashCode(obj); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace StardewModdingAPI.Framework.StateTracking.Comparers 5 | { 6 | /// A comparer which considers two references equal if they point to the same instance. 7 | /// The value type. 8 | internal class ObjectReferenceComparer : IEqualityComparer 9 | { 10 | /********* 11 | ** Public methods 12 | *********/ 13 | /// Determines whether the specified objects are equal. 14 | /// true if the specified objects are equal; otherwise, false. 15 | /// The first object to compare. 16 | /// The second object to compare. 17 | public bool Equals(T? x, T? y) 18 | { 19 | return object.ReferenceEquals(x, y); 20 | } 21 | 22 | /// Get a hash code for the specified object. 23 | /// The value. 24 | public int GetHashCode(T obj) 25 | { 26 | return RuntimeHelpers.GetHashCode(obj); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/FieldWatchers/BaseDisposableWatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers 4 | { 5 | /// The base implementation for a disposable watcher. 6 | internal abstract class BaseDisposableWatcher : IDisposable 7 | { 8 | /********* 9 | ** Fields 10 | *********/ 11 | /// Whether the watcher has been disposed. 12 | protected bool IsDisposed { get; private set; } 13 | 14 | 15 | /********* 16 | ** Public methods 17 | *********/ 18 | /// Stop watching the field and release all references. 19 | public virtual void Dispose() 20 | { 21 | this.IsDisposed = true; 22 | } 23 | 24 | 25 | /********* 26 | ** Protected methods 27 | *********/ 28 | /// Throw an exception if the watcher is disposed. 29 | /// The watcher is disposed. 30 | protected void AssertNotDisposed() 31 | { 32 | if (this.IsDisposed) 33 | throw new ObjectDisposedException(this.GetType().Name); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/ICollectionWatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Framework.StateTracking 4 | { 5 | /// A watcher which tracks changes to a collection. 6 | internal interface ICollectionWatcher : IWatcher 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The values added since the last reset. 12 | IEnumerable Added { get; } 13 | 14 | /// The values removed since the last reset. 15 | IEnumerable Removed { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/IDictionaryWatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI.Framework.StateTracking 4 | { 5 | /// A watcher which tracks changes to a dictionary. 6 | internal interface IDictionaryWatcher : ICollectionWatcher> { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/IValueWatcher.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI.Framework.StateTracking 2 | { 3 | /// A watcher which tracks changes to a value. 4 | internal interface IValueWatcher : IWatcher 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The field value at the last reset. 10 | T PreviousValue { get; } 11 | 12 | /// The latest value. 13 | T CurrentValue { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/Framework/StateTracking/IWatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace StardewModdingAPI.Framework.StateTracking 4 | { 5 | /// A watcher which detects changes to something. 6 | internal interface IWatcher : IDisposable 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// A name which identifies what the watcher is watching, used for troubleshooting. 12 | string Name { get; } 13 | 14 | /// Whether the value changed since the last reset. 15 | bool IsChanged { get; } 16 | 17 | 18 | /********* 19 | ** Methods 20 | *********/ 21 | /// Update the current value if needed. 22 | void Update(); 23 | 24 | /// Set the current value as the baseline. 25 | void Reset(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI/GameFramework.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_DEPRECATED 2 | using System; 3 | #endif 4 | 5 | namespace StardewModdingAPI 6 | { 7 | /// The game framework running the game. 8 | public enum GameFramework 9 | { 10 | #if SMAPI_DEPRECATED 11 | /// The XNA Framework, previously used on Windows. 12 | [Obsolete("Stardew Valley no longer uses XNA Framework on any supported platform. This value will be removed in SMAPI 4.0.0.")] 13 | Xna, 14 | #endif 15 | 16 | /// The MonoGame framework. 17 | MonoGame 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SMAPI/GamePlatform.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI.Toolkit.Utilities; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// The game's platform version. 6 | public enum GamePlatform 7 | { 8 | /// The Android version of the game. 9 | Android = Platform.Android, 10 | 11 | /// The Linux version of the game. 12 | Linux = Platform.Linux, 13 | 14 | /// The macOS version of the game. 15 | Mac = Platform.Mac, 16 | 17 | /// The Windows version of the game. 18 | Windows = Platform.Windows 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SMAPI/IAssetDataForDictionary.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// Encapsulates access and changes to dictionary content being read from a data file. 6 | public interface IAssetDataForDictionary : IAssetData> { } 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/IAssetEditor.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_DEPRECATED 2 | using System; 3 | using StardewModdingAPI.Events; 4 | 5 | namespace StardewModdingAPI 6 | { 7 | /// Edits matching content assets. 8 | [Obsolete($"Use {nameof(IMod.Helper)}.{nameof(IModHelper.Events)}.{nameof(IModEvents.Content)} instead. This interface will be removed in SMAPI 4.0.0.")] 9 | public interface IAssetEditor 10 | { 11 | /********* 12 | ** Public methods 13 | *********/ 14 | /// Get whether this instance can edit the given asset. 15 | /// Basic metadata about the asset being loaded. 16 | bool CanEdit(IAssetInfo asset); 17 | 18 | /// Edit a matched asset. 19 | /// A helper which encapsulates metadata about an asset and enables changes to it. 20 | void Edit(IAssetData asset); 21 | } 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /src/SMAPI/IAssetLoader.cs: -------------------------------------------------------------------------------- 1 | #if SMAPI_DEPRECATED 2 | using System; 3 | using StardewModdingAPI.Events; 4 | 5 | namespace StardewModdingAPI 6 | { 7 | /// Provides the initial version for matching assets loaded by the game. SMAPI will raise an error if two mods try to load the same asset; in most cases you should use instead. 8 | [Obsolete($"Use {nameof(IMod.Helper)}.{nameof(IModHelper.Events)}.{nameof(IModEvents.Content)} instead. This interface will be removed in SMAPI 4.0.0.")] 9 | public interface IAssetLoader 10 | { 11 | /********* 12 | ** Public methods 13 | *********/ 14 | /// Get whether this instance can load the initial version of the given asset. 15 | /// Basic metadata about the asset being loaded. 16 | bool CanLoad(IAssetInfo asset); 17 | 18 | /// Load a matched asset. 19 | /// Basic metadata about the asset being loaded. 20 | T Load(IAssetInfo asset); 21 | } 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /src/SMAPI/IModInfo.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// Metadata for a loaded mod. 4 | public interface IModInfo 5 | { 6 | /// The mod manifest. 7 | IManifest Manifest { get; } 8 | 9 | /// Whether the mod is a content pack. 10 | bool IsContentPack { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/IModLinked.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// An instance linked to a mod. 4 | public interface IModLinked 5 | { 6 | /********* 7 | ** Accessors 8 | *********/ 9 | /// The unique ID of the mod for which the instance was created. 10 | string ModID { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/IMultiplayerPeerMod.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// Metadata about a mod installed by a connected player. 4 | public interface IMultiplayerPeerMod 5 | { 6 | /// The mod's display name. 7 | string Name { get; } 8 | 9 | /// The unique mod ID. 10 | string ID { get; } 11 | 12 | /// The mod version. 13 | ISemanticVersion Version { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/IRawTextureData.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// The raw data for an image read from the filesystem. 6 | public interface IRawTextureData 7 | { 8 | /// The image width. 9 | int Width { get; } 10 | 11 | /// The image height. 12 | int Height { get; } 13 | 14 | /// The loaded image data. 15 | Color[] Data { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SMAPI/IReflectedField.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// A field obtained through reflection. 6 | /// The field value type. 7 | public interface IReflectedField 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The reflection metadata. 13 | FieldInfo FieldInfo { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Get the field value. 20 | TValue GetValue(); 21 | 22 | /// Set the field value. 23 | //// The value to set. 24 | void SetValue(TValue value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/IReflectedMethod.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// A method obtained through reflection. 6 | public interface IReflectedMethod 7 | { 8 | /********* 9 | ** Accessors 10 | *********/ 11 | /// The reflection metadata. 12 | MethodInfo MethodInfo { get; } 13 | 14 | 15 | /********* 16 | ** Public methods 17 | *********/ 18 | /// Invoke the method. 19 | /// The return type. 20 | /// The method arguments to pass in. 21 | TValue Invoke(params object?[] arguments); 22 | 23 | /// Invoke the method. 24 | /// The method arguments to pass in. 25 | void Invoke(params object?[] arguments); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SMAPI/IReflectedProperty.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// A property obtained through reflection. 6 | /// The property value type. 7 | public interface IReflectedProperty 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The reflection metadata. 13 | PropertyInfo PropertyInfo { get; } 14 | 15 | 16 | /********* 17 | ** Public methods 18 | *********/ 19 | /// Get the property value. 20 | TValue GetValue(); 21 | 22 | /// Set the property value. 23 | //// The value to set. 24 | void SetValue(TValue value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/LogLevel.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI.Internal.ConsoleWriting; 2 | 3 | namespace StardewModdingAPI 4 | { 5 | /// The log severity levels. 6 | public enum LogLevel 7 | { 8 | /// Tracing info intended for developers. 9 | Trace = ConsoleLogLevel.Trace, 10 | 11 | /// Troubleshooting info that may be relevant to the player. 12 | Debug = ConsoleLogLevel.Debug, 13 | 14 | /// Info relevant to the player. This should be used judiciously. 15 | Info = ConsoleLogLevel.Info, 16 | 17 | /// An issue the player should be aware of. This should be used rarely. 18 | Warn = ConsoleLogLevel.Warn, 19 | 20 | /// A message indicating something went wrong. 21 | Error = ConsoleLogLevel.Error, 22 | 23 | /// Important information to highlight for the player when player action is needed (e.g. new version available). This should be used rarely to avoid alert fatigue. 24 | Alert = ConsoleLogLevel.Alert 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SMAPI/Mobile/IsExternalInit.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace System.Runtime.CompilerServices 4 | { 5 | [EditorBrowsable(EditorBrowsableState.Never)] 6 | internal class IsExternalInit{} 7 | } 8 | -------------------------------------------------------------------------------- /src/SMAPI/PatchMapMode.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// Indicates how a map should be patched. 4 | public enum PatchMapMode 5 | { 6 | /// Replace matching tiles. Target tiles missing in the source area are kept as-is. 7 | Overlay, 8 | 9 | /// Replace all tiles on layers that exist in the source map. 10 | ReplaceByLayer, 11 | 12 | /// Replace all tiles with the source map. 13 | Replace 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SMAPI/PatchMode.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// Indicates how an image should be patched. 4 | public enum PatchMode 5 | { 6 | /// Erase the original content within the area before drawing the new content. 7 | Replace, 8 | 9 | /// Draw the new content over the original content, so the original content shows through any transparent pixels. 10 | Overlay 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SMAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("SMAPI.Tests")] 4 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Moq for unit testing 5 | [assembly: InternalsVisibleTo("ContentPatcher")] 6 | [assembly: InternalsVisibleTo("ErrorHandler")] 7 | #if SMAPI_FOR_MOBILE 8 | [assembly: InternalsVisibleTo("VirtualKeyboard")] 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /src/SMAPI/SButtonState.cs: -------------------------------------------------------------------------------- 1 | namespace StardewModdingAPI 2 | { 3 | /// The input state for a button during an update frame. 4 | public enum SButtonState 5 | { 6 | /// The button was neither pressed, held, nor released. 7 | None, 8 | 9 | /// The button was pressed in this frame. 10 | Pressed, 11 | 12 | /// The button has been held since the last frame. 13 | Held, 14 | 15 | /// The button was released in this frame. 16 | Released 17 | } 18 | 19 | /// Extension methods for . 20 | public static class InputStatusExtensions 21 | { 22 | /// Whether the button was pressed or held. 23 | /// The button state. 24 | public static bool IsDown(this SButtonState state) 25 | { 26 | return state is SButtonState.Held or SButtonState.Pressed; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SMAPI/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | true/pm 15 | permonitorv2,permonitor 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}} {{day}}", 5 | "generic.date-with-year": "{{season}} {{day}} im Jahr {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/default.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}} {{day}}", 5 | "generic.date-with-year": "{{season}} {{day}} in year {{year}}", 6 | "warn.save-broken": "Load save failed, your save file may be broken.You can swap to previous day's save, or restore save files manually with save backups.Backup provided by SMAPI was located at StardewValley/smapi-internal/save-backups", 7 | "btn.swap": "Swap", 8 | "btn.back": "Back" 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/es.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{seasonLowercase}} {{day}}", 5 | "generic.date-with-year": "{{seasonLowercase}} {{day}} del año {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{day}} {{seasonLowercase}}", 5 | "generic.date-with-year": "{{day}} {{seasonLowercase}} de l'année {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}} {{day}}", 5 | "generic.date-with-year": "{{year}}. év {{season}} {{day}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/it.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{day}} {{season}}", 5 | "generic.date-with-year": "{{day}} {{season}} dell'anno {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}} {{day}}日", 5 | "generic.date-with-year": "{{year}}年目 {{season}} {{day}}日" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}} {{day}}일", 5 | "generic.date-with-year": "{{year}}년차 {{season}} {{day}}일" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{day}} {{seasonLowercase}}", 5 | "generic.date-with-year": "{{day}} {{seasonLowercase}} w roku {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}} {{day}}", 5 | "generic.date-with-year": "{{season}} {{day}} no ano {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}}, {{day}}-е число", 5 | "generic.date-with-year": "{{season}}, {{day}}-е число, {{year}}-й год" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/th.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "วันที่ {{day}} {{season}}", 5 | "generic.date-with-year": "วันที่ {{day}} {{season}} ปีที่ {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{day}} {{season}}", 5 | "generic.date-with-year": "{{day}} {{season}} Yıl {{year}}" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}}, {{day}}-й день", 5 | "generic.date-with-year": "{{season}}, {{day}}-й день, {{year}} рік" 6 | } 7 | -------------------------------------------------------------------------------- /src/SMAPI/i18n/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | // short date format for SDate 3 | // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) 4 | "generic.date": "{{season}}{{day}}日", 5 | "generic.date-with-year": "第{{year}}年{{season}}{{day}}日" 6 | "warn.save-broken": "无法加载该存档,存档可能已损坏.你可以切换到前一日的存档,或者手动恢复到备份的存档.SMAPI提供的备份文件位于: StardewValley/smapi-internal/save-backups", 7 | "btn.swap": "切换", 8 | "btn.back": "返回" 9 | } 10 | -------------------------------------------------------------------------------- /src/SMAPI/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaneYork/SMAPI/bfb0adb849310f6928f299f0f92d2eae3242da84/src/SMAPI/icon.ico -------------------------------------------------------------------------------- /src/SMAPI/steam_appid.txt: -------------------------------------------------------------------------------- 1 | 413150 --------------------------------------------------------------------------------