From 0f6853bc9d99935cf3ac76e44d63cdde48359d5a Mon Sep 17 00:00:00 2001 From: gabber235 Date: Sun, 1 Sep 2024 15:31:02 +0000 Subject: [PATCH 01/32] =?UTF-8?q?Deploying=20to=20develop=20from=20@=20gab?= =?UTF-8?q?ber235/TypeWriter@f57efb85599e6bff025ce3edecaa3b0c10c63906=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c03ae0a21..66938db408 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Thanks to the following sponsors for supporting this project. Without their support, this project would not be possible. If you are using Typewriter for your server, and are making money from it, please consider [sponsoring](https://github.com/sponsors/gabber235) the project. -PixelPioneer +PixelPioneer ### Examples From 5558a0b0b28edde59249f068db2e9b25c7ee63c6 Mon Sep 17 00:00:00 2001 From: gabber235 Date: Tue, 3 Sep 2024 15:33:22 +0000 Subject: [PATCH 02/32] =?UTF-8?q?Deploying=20to=20develop=20from=20@=20gab?= =?UTF-8?q?ber235/TypeWriter@0f6853bc9d99935cf3ac76e44d63cdde48359d5a=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66938db408..5c353de0a6 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Thanks to the following sponsors for supporting this project. Without their support, this project would not be possible. If you are using Typewriter for your server, and are making money from it, please consider [sponsoring](https://github.com/sponsors/gabber235) the project. -PixelPioneer + ### Examples From 1879f44583d55d53edc195faf770e9185cf86372 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Wed, 4 Sep 2024 11:28:35 +0200 Subject: [PATCH 03/32] Extension Update --- .github/actions/build-adapter/action.yml | 22 - .../{build-plugin => build-engine}/action.yml | 12 +- .github/actions/build-extension/action.yml | 22 + .github/workflows/build-adapter.yml | 30 - .../build-development-jars-and-publish.yml | 84 +- .github/workflows/build-documentation.yml | 2 +- .../{build-plugin.yml => build-engine.yml} | 10 +- .github/workflows/build-extension.yml | 30 + .github/workflows/build-jars-on-push.yml | 138 - .github/workflows/build-jars-on-request.yml | 90 +- .gitignore | 2 +- adapters/BasicAdapter/build.gradle.kts | 2 - adapters/BasicAdapter/settings.gradle.kts | 14 - .../me/gabber235/typewriter/BasicAdapter.kt | 19 - .../entries/action/DropItemActionEntry.kt | 74 - .../entries/action/GiveItemActionEntry.kt | 63 - .../entries/action/PlaySoundActionEntry.kt | 61 - .../audience/DirectLocationPathStream.kt | 32 - .../entries/cinematic/SoundCinematicEntry.kt | 116 - .../entries/event/PlayerJoinEventEntry.kt | 26 - .../event/PlayerNearLocationEventEntry.kt | 62 - .../entries/fact/InventoryItemCountFact.kt | 64 - .../entries/static/SimpleSpeakerEntry.kt | 45 - adapters/CitizensAdapter/build.gradle.kts | 10 - .../typewriter/citizens/CitizensAdapter.kt | 58 - .../typewriter/citizens/TypewriterTrait.kt | 13 - .../entries/artifact/NpcMovementArtifact.kt | 36 - .../entries/cinematic/CitizensNpcData.kt | 155 - .../entries/cinematic/NpcCinematicEntry.kt | 149 - .../cinematic/ReferenceNpcCinematicEntry.kt | 47 - .../cinematic/SelfNpcCinematicEntry.kt | 33 - .../citizens/entries/entity/CitizensNpc.kt | 10 - .../entries/entity/ReferenceNpcEntry.kt | 57 - .../entries/event/NpcInteractEvent.kt | 74 - adapters/CombatLogXAdapter/build.gradle.kts | 8 - .../CombatLogXAdapter/settings.gradle.kts | 14 - .../combatlogx/CombatLogXAdapter.kt | 31 - .../entries/fact/CombatFactEntry.kt | 35 - adapters/EntityAdapter/build.gradle.kts | 4 - .../me/gabber235/typewriter/EntityAdapter.kt | 21 - .../minecraft/display/text/TextDisplayData.kt | 9 - .../data/minecraft/living/CollarColorData.kt | 43 - .../living/horse/LlamaCarpetColorData.kt | 41 - adapters/FancyNpcsAdapter/build.gradle.kts | 8 - adapters/FancyNpcsAdapter/settings.gradle.kts | 14 - .../gabber235/typewriter/FancyNpcsAdapter.kt | 21 - .../entries/artifact/NpcMovementArtifact.kt | 40 - .../entries/cinematic/FancyNpcData.kt | 139 - .../entries/cinematic/NpcCinematicEntry.kt | 149 - .../cinematic/ReferenceNpcCinematicEntry.kt | 49 - .../cinematic/SelfNpcCinematicEntry.kt | 33 - .../typewriter/entries/entity/FancyNPC.kt | 10 - .../entries/entity/ReferenceNpcEntry.kt | 33 - .../entries/event/NpcInteractEvent.kt | 38 - adapters/MythicMobsAdapter/build.gradle.kts | 7 - .../MythicMobsAdapter/settings.gradle.kts | 14 - .../mythicmobs/MythicMobsAdapter.kt | 23 - adapters/RPGRegionsAdapter/build.gradle.kts | 7 - .../RPGRegionsAdapter/settings.gradle.kts | 14 - .../rpgregions/RPGRegionsAdapter.kt | 24 - .../SuperiorSkyblockAdapter/build.gradle.kts | 7 - .../settings.gradle.kts | 14 - .../SuperiorSkyblockAdapter.kt | 23 - adapters/VaultAdapter/build.gradle.kts | 3 - adapters/VaultAdapter/settings.gradle.kts | 14 - adapters/WorldGuardAdapter/build.gradle.kts | 7 - .../WorldGuardAdapter/settings.gradle.kts | 14 - .../worldguard/WorldGuardAdapter.kt | 30 - .../src/main/templates/App.kt | 3 - adapters/ZNPCsPlusAdapter/build.gradle.kts | 7 - adapters/ZNPCsPlusAdapter/settings.gradle.kts | 14 - .../gabber235/typewriter/ZNPCsPlusAdapter.kt | 21 - .../entries/artifact/NpcMovementArtifact.kt | 35 - .../entries/cinematic/NpcCinematicEntry.kt | 149 - .../cinematic/ReferenceNpcCinematicEntry.kt | 47 - .../cinematic/SelfNpcCinematicEntry.kt | 33 - .../typewriter/entries/cinematic/ZNPCData.kt | 138 - .../entries/entity/ReferenceNpcEntry.kt | 33 - .../typewriter/entries/entity/ZNPC.kt | 10 - .../entries/event/NpcInteractEvent.kt | 38 - .../src/main/templates/App.kt | 3 - adapters/_DocsAdapter/build.gradle.kts | 2 - adapters/_DocsAdapter/settings.gradle.kts | 14 - .../typewritermc/example/ExampleAdapter.kt | 17 - .../_DocsAdapter/src/main/templates/App.kt | 3 - adapters/settings.gradle.kts | 22 - app/.gitignore | 2 + app/.metadata | 34 +- app/README.md | 2 +- app/ios/RunnerTests/RunnerTests.swift | 12 + app/lib/app_router.dart | 16 +- app/lib/models/adapter.freezed.dart | 2656 -------------- app/lib/models/book.dart | 101 +- app/lib/models/book.freezed.dart | 66 +- app/lib/models/communicator.dart | 63 +- app/lib/models/communicator.freezed.dart | 21 +- app/lib/models/entry.dart | 24 +- app/lib/models/entry.g.dart | 75 +- .../{adapter.dart => entry_blueprint.dart} | 253 +- app/lib/models/entry_blueprint.freezed.dart | 3160 +++++++++++++++++ ...{adapter.g.dart => entry_blueprint.g.dart} | 313 +- app/lib/models/extension.dart | 38 + app/lib/models/extension.freezed.dart | 443 +++ app/lib/models/extension.g.dart | 61 + app/lib/models/materials.freezed.dart | 21 +- app/lib/models/page.dart | 80 +- app/lib/models/page.freezed.dart | 53 +- app/lib/models/page.g.dart | 156 +- app/lib/models/segment.freezed.dart | 17 +- app/lib/models/sound.freezed.dart | 31 +- app/lib/models/sounds.freezed.dart | 21 +- app/lib/models/writers.freezed.dart | 21 +- app/lib/pages/book_page.dart | 2 +- app/lib/pages/page_editor.dart | 5 +- app/lib/pages/page_editor.g.dart | 2 +- app/lib/pages/pages_list.dart | 41 +- app/lib/pages/pages_list.freezed.dart | 49 +- app/lib/pages/pages_list.g.dart | 2 +- app/lib/utils/popups.dart | 5 +- .../components/app/cinematic_view.dart | 42 +- .../app/cinematic_view.freezed.dart | 70 +- .../components/app/cinematic_view.g.dart | 16 +- .../widgets/components/app/entries_graph.dart | 19 +- .../components/app/entries_graph.g.dart | 10 +- .../widgets/components/app/entry_node.dart | 42 +- .../widgets/components/app/entry_node.g.dart | 6 +- .../widgets/components/app/entry_search.dart | 22 +- .../components/app/entry_search.g.dart | 4 +- .../widgets/components/app/manifest_view.dart | 11 +- .../components/app/manifest_view.g.dart | 6 +- .../widgets/components/app/page_search.dart | 17 +- .../widgets/components/app/page_search.g.dart | 2 +- .../components/app/search_bar.freezed.dart | 17 +- .../components/app/static_entries_list.dart | 4 +- .../components/app/static_entries_list.g.dart | 2 +- .../components/general/filled_button.dart | 4 +- .../components/general/outline_button.dart | 10 +- .../components/general/toasts.freezed.dart | 28 +- .../components/general/tree_view.freezed.dart | 76 +- app/lib/widgets/inspector/editors.dart | 8 +- app/lib/widgets/inspector/editors.g.dart | 2 +- .../widgets/inspector/editors/boolean.dart | 19 +- app/lib/widgets/inspector/editors/color.dart | 20 +- app/lib/widgets/inspector/editors/cron.dart | 13 +- .../widgets/inspector/editors/duration.dart | 16 +- .../inspector/editors/entry_selector.dart | 19 +- app/lib/widgets/inspector/editors/enum.dart | 18 +- app/lib/widgets/inspector/editors/field.dart | 10 +- .../inspector/editors/float_range.dart | 18 +- app/lib/widgets/inspector/editors/item.dart | 102 +- app/lib/widgets/inspector/editors/list.dart | 34 +- .../widgets/inspector/editors/location.dart | 30 +- app/lib/widgets/inspector/editors/map.dart | 60 +- .../widgets/inspector/editors/material.dart | 19 +- app/lib/widgets/inspector/editors/number.dart | 35 +- app/lib/widgets/inspector/editors/object.dart | 57 +- .../widgets/inspector/editors/optional.dart | 46 +- .../inspector/editors/page_selector.dart | 36 +- .../inspector/editors/potion_effect.dart | 18 +- app/lib/widgets/inspector/editors/skin.dart | 21 +- .../widgets/inspector/editors/sound_id.dart | 16 +- .../inspector/editors/sound_source.dart | 39 +- app/lib/widgets/inspector/editors/string.dart | 25 +- app/lib/widgets/inspector/editors/vector.dart | 17 +- app/lib/widgets/inspector/header.dart | 25 +- .../inspector/headers/colored_action.dart | 16 +- .../headers/content_mode_action.dart | 22 +- .../headers/duplicate_list_item_action.dart | 15 +- .../inspector/headers/help_action.dart | 17 +- .../inspector/headers/length_action.dart | 19 +- .../inspector/headers/placeholder_action.dart | 11 +- .../inspector/headers/regex_action.dart | 11 +- app/lib/widgets/inspector/heading.dart | 22 +- app/lib/widgets/inspector/heading.g.dart | 2 +- app/lib/widgets/inspector/inspector.dart | 22 +- app/lib/widgets/inspector/operations.dart | 2 - app/macos/Runner/AppDelegate.swift | 4 + app/macos/RunnerTests/RunnerTests.swift | 12 + app/pubspec.lock | 213 +- app/pubspec.yaml | 18 +- app/test/entry_test.dart | 4 +- app/test/page_test.dart | 46 +- documentation/docs/adapters/README.mdx | 8 +- .../02-adapters/02-getting_started.mdx | 99 - .../docs/develop/02-adapters/index.mdx | 10 - .../02-extensions/02-getting_started.mdx | 138 + .../develop/02-extensions/03-initializers.mdx | 19 + .../04-entries}/cinematic/index.mdx | 0 .../04-entries}/index.mdx | 7 +- .../04-entries}/manifest/_category_.yml | 0 .../04-entries}/manifest/audience.mdx | 2 +- .../04-entries}/static/_category_.yml | 0 .../04-entries}/static/artifact.mdx | 2 +- .../04-entries}/static/asset.mdx | 0 .../04-entries}/static/sound_id.mdx | 0 .../04-entries}/static/sound_source.mdx | 0 .../04-entries}/static/speaker.mdx | 0 .../04-entries}/trigger/_category_.yml | 0 .../04-entries}/trigger/action.mdx | 0 .../trigger/custom_triggering_action.mdx | 0 .../04-entries}/trigger/dialogue.mdx | 0 .../04-entries}/trigger/event.mdx | 0 .../05-querying.mdx} | 0 .../06-triggering.mdx} | 0 .../07-api-changes/0.5.mdx} | 8 +- .../02-extensions/07-api-changes/0.6.mdx | 10 + .../07-api-changes}/index.mdx | 2 +- .../docs/develop/02-extensions/index.mdx | 10 + documentation/docs/develop/README.mdx | 2 +- documentation/docs/docs/01-home.md | 4 +- .../02-getting-started/01-installation.mdx | 10 +- .../01-interactions/index.mdx | 2 +- .../02-cinematics/03-entities.mdx | 2 +- .../02-cinematics/index.mdx | 2 +- .../03-creating-stories/03-facts/index.mdx | 4 +- .../02-interacting.mdx | 4 +- .../index.mdx | 22 +- .../06-road-network/index.mdx | 2 +- .../docs/05-helpfull-features/05-snippets.mdx | 8 +- .../docs/docs/06-troubleshooting/adapters.mdx | 31 - .../docs/06-troubleshooting/extensions.mdx | 31 + .../docs/docs/06-troubleshooting/index.mdx | 14 +- .../definition_select.png | Bin .../entity-interact-event-fields.png | Bin .../entity_location.webm | Bin .../entity_name_change.png | Bin .../fetch_skin.webm | Bin .../glow_editor.png | Bin .../glow_effect.png | Bin documentation/docusaurus.config.js | 2 +- .../plugins/code-snippets/codeSnippets.js | 2 +- .../plugins/code-snippets/snippets.json | 56 +- engine/build.gradle.kts | 78 + engine/engine-core/build.gradle.kts | 4 + .../com/typewritermc/core/TypewriterCore.kt | 33 + .../typewritermc/core/books/pages/Colors.kt | 19 + .../typewritermc/core/books/pages/PageType.kt | 22 + .../com/typewritermc/core/entries/Entry.kt | 26 + .../core/entries}/EntryReference.kt | 17 +- .../com/typewritermc/core/entries/Library.kt | 98 + .../com/typewritermc/core/entries/Page.kt | 12 + .../com/typewritermc/core/entries/Query.kt | 246 ++ .../core/extension/Initializable.kt | 56 + .../core/extension/annotations/Default.kt | 14 + .../core/extension/annotations/Entry.kt | 10 + .../extension/annotations/EntryListener.kt | 34 + .../core/extension/annotations/Initializer.kt | 3 + .../core/extension/annotations/Messenger.kt | 19 + .../core/extension/annotations/Modifiers.kt | 160 + .../core/extension/annotations/Tags.kt | 4 + .../com/typewritermc/core}/utils/Looping.kt | 2 +- .../com/typewritermc/core/utils/Reloadable.kt | 6 + .../com/typewritermc/core}/utils/Result.kt | 2 +- .../core/utils/point/Coordinate.kt | 100 + .../typewritermc/core/utils/point}/Point.kt | 38 +- .../typewritermc/core/utils/point/Position.kt | 137 + .../core/utils/point/Rotatable.kt | 79 + .../typewritermc/core/utils/point}/Vector.kt | 23 +- .../typewritermc/core/utils/point/World.kt | 5 + engine/engine-loader/build.gradle.kts | 4 + .../com/typewritermc/loader/DataSerializer.kt | 22 + .../typewritermc/loader/DependencyChecker.kt | 5 + .../typewritermc/loader/ExtensionLoader.kt | 245 ++ .../typewritermc/loader/ListenerPriority.kt | 10 + .../engine-paper}/build.gradle.kts | 106 +- .../engine/paper}/TypewriterCommand.kt | 86 +- .../engine/paper/TypewriterPaperPlugin.kt | 142 +- .../engine/paper}/content/ContentComponent.kt | 2 +- .../engine/paper}/content/ContentContext.kt | 2 +- .../engine/paper}/content/ContentEditor.kt | 57 +- .../engine/paper}/content/ContentMode.kt | 6 +- .../content/components/BossBarComponent.kt | 10 +- .../components/CompoundContentComponent.kt | 6 +- .../content/components/ExitComponent.kt | 34 +- .../content/components/ItemsComponent.kt | 4 +- .../content/components/NodesComponent.kt | 18 +- .../components/SimulateCinematicComponent.kt | 60 +- .../modes/ImmediateFieldValueContentMode.kt | 50 + .../modes/RecordingCinematicContentMode.kt | 49 +- .../engine/paper}/content/modes/Tape.kt | 2 +- .../modes/custom/HoldingItemContentMode.kt | 17 + .../modes/custom/PositionContentMode.kt | 23 + .../engine/paper}/entry/AssetManager.kt | 53 +- .../engine/paper}/entry/AudienceManager.kt | 26 +- .../engine/paper/entry/BaseEntry.kt | 64 +- .../engine/paper/entry/EntryListeners.kt | 145 + .../engine/paper}/entry/FactWatcher.kt | 11 +- .../engine/paper/entry/PlaceholderEntry.kt | 10 + .../engine/paper}/entry/StagingManager.kt | 148 +- .../engine/paper/entry/TriggerEntry.kt | 223 +- .../entry/cinematic/CinematicSequence.kt | 30 +- .../entry/cinematic/SimpleCinematicAction.kt | 10 +- .../paper}/entry/dialogue/DialogueSequence.kt | 34 +- .../paper}/entry/dialogue/MessengerFinder.kt | 84 +- .../entry/entity/ActivityEntityDisplay.kt | 7 +- .../paper}/entry/entity/ActivityManager.kt | 8 +- .../paper}/entry/entity/AdvancedEntity.kt | 24 +- .../paper}/entry/entity/DisplayEntity.kt | 23 +- .../paper}/entry/entity/EntityActivity.kt | 32 +- .../paper/entry/entity/EntityAttribute.kt | 4 + .../paper}/entry/entity/EntityHandler.kt | 12 +- .../paper/entry/entity/EntityStorage.kt | 10 + .../engine/paper}/entry/entity/FakeEntity.kt | 8 +- .../entity/GroupActivityEntityDisplay.kt | 18 +- .../entity/IndividualActivityEntityDisplay.kt | 24 +- .../paper/entry/entity/PositionProperty.kt | 99 + .../entity/SharedActivityEntityDisplay.kt | 23 +- .../paper}/entry/entity/SimpleEntity.kt | 20 +- .../entry/entity/SinglePropertyCollector.kt | 10 +- .../paper}/entry/entity/SkinProperty.kt | 4 +- .../paper}/entry/entries/ActionEntry.kt | 14 +- .../engine/paper}/entry/entries/AssetEntry.kt | 18 +- .../paper}/entry/entries/AudienceEntry.kt | 18 +- .../paper}/entry/entries/CinematicEntry.kt | 10 +- .../paper/entry/entries/DialogueEntry.kt | 16 + .../paper}/entry/entries/EntityEntry.kt | 37 +- .../engine/paper}/entry/entries/EventEntry.kt | 21 +- .../engine/paper}/entry/entries/FactEntry.kt | 35 +- .../engine/paper}/entry/entries/GroupEntry.kt | 6 +- .../engine/paper}/entry/entries/LinesEntry.kt | 10 +- .../engine/paper}/entry/entries/QuestEntry.kt | 31 +- .../paper}/entry/entries/RoadNetworkEntry.kt | 44 +- .../paper}/entry/entries/SidebarEntry.kt | 22 +- .../engine/paper}/entry/entries/SoundEntry.kt | 8 +- .../engine/paper}/entry/quest/QuestTracker.kt | 26 +- .../entry/roadnetwork/RoadNetworkEditor.kt | 14 +- .../entry/roadnetwork/RoadNetworkManager.kt | 16 +- .../content/RoadNetworkContentMode.kt | 63 +- .../content/RoadNetworkEditorComponent.kt | 18 +- .../SelectedNegativeNodeContentMode.kt | 24 +- .../content/SelectedRoadNodeContentMode.kt | 85 +- .../paper}/entry/roadnetwork/gps/GPS.kt | 17 +- .../roadnetwork/gps/PathStreamDisplay.kt | 30 +- .../entry/roadnetwork/gps/PointToPointGPS.kt | 20 +- .../entry/roadnetwork/pathfinding/PFBlock.kt | 2 +- .../pathfinding/PFColumnarSpace.kt | 3 +- .../roadnetwork/pathfinding/PFEmptyEntity.kt | 4 +- .../pathfinding/PFInstanceSpace.kt | 2 +- .../paper}/events/AsyncCinematicEndEvent.kt | 2 +- .../paper}/events/AsyncCinematicStartEvent.kt | 2 +- .../paper}/events/AsyncCinematicTickEvent.kt | 2 +- .../paper}/events/AsyncDialogueEvents.kt | 2 +- .../events/AsyncEntityDefinitionInteract.kt | 4 +- .../paper}/events/AsyncQuestStatusUpdate.kt | 8 +- .../paper}/events/AsyncTrackedQuestUpdate.kt | 6 +- .../paper}/events/ContentEditorEvents.kt | 2 +- .../paper}/events/StagingChangeEvent.kt | 4 +- .../paper/events/TypewriterUnloadEvent.kt | 4 +- .../paper/extensions/bstats/BStatsMetrics.kt | 30 + .../paper}/extensions/modrinth/Modrinth.kt | 85 +- .../extensions/packetevents/PlayerPackets.kt | 2 +- .../placeholderapi/PlaceholderExpansion.kt | 14 +- .../typewritermc/engine/paper}/facts/Fact.kt | 4 +- .../engine/paper}/facts/FactDatabase.kt | 26 +- .../engine/paper}/facts/FactStorage.kt | 2 +- .../paper}/facts/storage/FileFactStorage.kt | 16 +- .../paper}/interaction/ActionBarBlocker.kt | 4 +- .../paper}/interaction/ChatHistoryHandler.kt | 8 +- .../engine/paper}/interaction/Interaction.kt | 29 +- .../paper}/interaction/InteractionHandler.kt | 48 +- .../paper}/interaction/PacketInterceptor.kt | 16 +- .../engine/paper/loader/DataSerializer.kt | 22 + .../paper/loader/PaperDependencyChecker.kt | 8 + .../loader/serializers/ColorSerializer.kt | 21 + .../serializers/CronExpressionSerializer.kt | 25 + .../loader/serializers/DurationSerializer.kt | 25 + .../serializers/EntryReferenceSerializer.kt | 38 + .../serializers/FloatRangeSerializer.kt | 35 + .../loader/serializers/OptionalSerializer.kt | 39 + .../serializers/PotionEffectTypeSerializer.kt | 25 + .../serializers/SkinPropertySerializer.kt | 29 + .../loader/serializers/SoundIdSerializer.kt | 48 + .../serializers/SoundSourceSerializer.kt | 59 + .../loader/serializers/VectorSerializer.kt | 29 + .../loader/serializers/WorldSerializer.kt | 29 + .../engine/paper}/snippets/Snippet.kt | 2 +- .../engine/paper}/snippets/SnippetDatabase.kt | 8 +- .../engine/paper}/ui/ClientSynchronizer.kt | 44 +- .../engine/paper}/ui/CommunicationHandler.kt | 14 +- .../engine/paper}/ui/PanelHost.kt | 6 +- .../typewritermc/engine/paper}/ui/Writers.kt | 2 +- .../engine/paper}/utils/BlockPhysics.kt | 29 +- .../engine/paper}/utils/BukkitDataParser.kt | 4 +- .../typewritermc/engine/paper}/utils/Color.kt | 2 +- .../engine/paper}/utils/ComputedMap.kt | 2 +- .../engine/paper}/utils/Config.kt | 6 +- .../engine/paper}/utils/CronExpression.kt | 2 +- .../engine/paper}/utils/DurationParser.kt | 2 +- .../engine/paper}/utils/Extensions.kt | 26 +- .../engine/paper}/utils/Interpolation.kt | 19 +- .../typewritermc/engine/paper}/utils/Item.kt | 49 +- .../engine/paper}/utils/Memoized.kt | 2 +- .../engine/paper}/utils/MiniMessages.kt | 4 +- .../engine/paper}/utils/PlayerState.kt | 6 +- .../typewritermc/engine/paper/utils/Point.kt | 38 + .../engine/paper}/utils/Reloadable.kt | 8 +- .../paper}/utils/RuntimeTypeAdapterFactory.kt | 2 +- .../engine/paper/utils/ServerCommandMap.kt | 33 + .../typewritermc/engine/paper}/utils/Sound.kt | 20 +- .../engine/paper}/utils/ThreadType.kt | 4 +- .../engine/paper}/utils/Timeout.kt | 9 +- .../src/main/kotlin/lirand/api/LirandAPI.kt | 5 - .../lirand/api/architecture/KotlinPlugin.kt | 1 - .../extensions/events/ListenerExtensions.kt | 4 - .../inventory/InventoryExtensions.kt | 40 +- .../api/extensions/math/MathExtensions.kt | 24 + .../lirand/api/extensions/math/Positions.kt | 6 - .../lirand/api/extensions/math/Ranges.kt | 0 .../api/extensions/other/JsonExtensions.kt | 0 .../extensions/server/PermissionExtensions.kt | 4 - .../api/extensions/server/PluginExtensions.kt | 9 +- .../api/extensions/server/ServerExtensions.kt | 0 .../api/extensions/world/PlayerExtensions.kt | 24 + .../kotlin/lirand/api/utilities/Reflection.kt | 15 + .../com/typewritermc}/utils/CronParserTest.kt | 5 +- .../typewritermc}/utils/DurationParserTest.kt | 3 +- {plugin => engine}/gradle.properties | 0 engine/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + engine/gradlew | 249 ++ engine/gradlew.bat | 92 + .../settings.gradle.kts | 8 +- extensions/BasicExtension/build.gradle.kts | 24 + .../action/AddPotionEffectActionEntry.kt | 42 +- .../action/ApplyVelocityActionEntry.kt | 21 +- .../basic}/entries/action/CinematicEntry.kt | 21 +- .../action/ConsoleCommandActionEntry.kt | 33 +- .../entries/action/DelayedActionEntry.kt | 25 +- .../entries/action/DropItemActionEntry.kt | 52 + .../entries/action/FireworkActionEntry.kt | 40 +- .../entries/action/GiveItemActionEntry.kt | 37 + .../entries/action/GroupTriggerActionEntry.kt | 20 +- .../entries/action/MessageActionEntry.kt | 30 +- .../entries/action/PlaySoundActionEntry.kt | 35 + .../action/PlayerCommandActionEntry.kt | 33 +- .../entries/action/RandomTriggerGateEntry.kt | 18 +- .../entries/action/RemoveItemActionEntry.kt | 47 +- .../entries/action/SetBlockActionEntry.kt | 29 +- .../entries/action/SetItemActionEntry.kt | 24 +- .../entries/action/ShowTitleActionEntry.kt | 31 +- .../entries/action/SimpleActionEntry.kt | 16 +- .../action/SpawnParticleActionEntry.kt | 33 +- .../entries/action/StopSoundActionEntry.kt | 23 +- .../entries/action/SwitchServerActionEntry.kt | 22 +- .../entries/action/TeleportActionEntry.kt | 30 +- .../entries/action/TrackQuestActionEntry.kt | 17 +- .../basic}/entries/audience/BossBarEntry.kt | 22 +- .../audience/CinematicAudienceEntry.kt | 30 +- .../audience/ClosestGroupMemberPathStream.kt | 20 +- .../entries/audience/CriteriaAudience.kt | 13 +- .../basic}/entries/audience/CronAudience.kt | 22 +- .../audience/DirectLocationPathStream.kt | 34 + .../entries/audience/GameTimeAudienceEntry.kt | 14 +- .../audience/GroupMembersPathStream.kt | 20 +- .../audience/HoldingItemAudienceEntry.kt | 23 +- .../audience/ItemInInventoryAudienceEntry.kt | 26 +- .../audience/ItemInSlotAudienceEntry.kt | 24 +- .../audience/LocationObjectivesPathStream.kt | 27 +- .../audience/LoopingCinematicAudience.kt | 22 +- .../basic}/entries/audience/SidebarEntry.kt | 15 +- .../entries/audience/SimpleLinesEntry.kt | 16 +- .../audience/TabListHeaderFooterEntry.kt | 20 +- .../entries/audience/TimerAudienceEntry.kt | 22 +- .../entries/audience/TriggerAudienceEntry.kt | 20 +- .../ActionBarDialogueCinematicEntry.kt | 31 +- .../cinematic/BlindingCinematicEntry.kt | 24 +- .../entries/cinematic/CameraCinematicEntry.kt | 98 +- .../cinematic/CinematicCommandEntry.kt | 25 +- .../DisplayDialogueCinematicAction.kt | 32 +- .../cinematic/ParticleCinematicEntry.kt | 33 +- .../cinematic/PotionEffectCinematicEntry.kt | 39 +- .../cinematic/PumpkinHatCinematicEntry.kt | 40 +- .../cinematic/ScreenShakeCinematicEntry.kt | 24 +- .../cinematic/SetFakeBlockCinematicEntry.kt | 36 +- .../entries/cinematic/SoundCinematicEntry.kt | 58 + .../cinematic/SpokenDialogueCinematicEntry.kt | 41 +- .../SubtitleDialgueCinematicEntry.kt | 36 +- .../entries/cinematic/TitleCinematicEntry.kt | 28 +- .../TriggerSequenceCinematicEntry.kt | 30 +- .../entries/dialogue/MessageDialogue.kt | 21 +- .../entries/dialogue/OptionDialogueEntry.kt | 21 +- .../entries/dialogue/RandomMessageDialogue.kt | 21 +- .../dialogue/RandomSpokenDialogueEntry.kt | 19 +- .../entries/dialogue/SpokenDialogueEntry.kt | 22 +- ...iversalMessageDialogueDialogueMessenger.kt | 20 +- .../BedrockOptionDialogueDialogueMessenger.kt | 30 +- .../JavaOptionDialogueDialogueMessenger.kt | 45 +- ...ckRandomSpokenDialogueDialogueMessenger.kt | 21 +- ...vaRandomSpokenDialogueDialogueMessenger.kt | 20 +- .../RandomMessageDialogueDialogueMessenger.kt | 16 +- .../BedrockSpokenDialogueDialogueMessenger.kt | 20 +- .../JavaSpokenDialogueDialogueMessenger.kt | 24 +- .../entries/event/BlockBreakEventEntry.kt | 51 +- .../entries/event/BlockPlaceEventEntry.kt | 29 +- .../event/ChatContainsTextEventEntry.kt | 22 +- .../entries/event/CraftItemEventEntry.kt | 18 +- .../event/DetectCommandRanEventEntry.kt | 18 +- .../entries/event/FireTriggerEventEntry.kt | 12 +- .../basic}/entries/event/FishEventEntry.kt | 21 +- .../entries/event/InteractBlockEventEntry.kt | 62 +- .../entries/event/PickupItemEventEntry.kt | 41 +- .../entries/event/PlayerDeathEventEntry.kt | 17 +- .../event/PlayerHitEntityEventEntry.kt | 17 +- .../entries/event/PlayerJoinEventEntry.kt | 31 + .../event/PlayerKillEntityEventEntry.kt | 17 +- .../event/PlayerKillPlayerEventEntry.kt | 17 +- .../event/PlayerNearLocationEventEntry.kt | 61 + .../entries/event/PlayerQuitEventEntry.kt | 14 +- .../entries/event/RunCommandEventEntry.kt | 14 +- .../basic}/entries/fact/CountdownFact.kt | 20 +- .../basic}/entries/fact/CronFactEntry.kt | 24 +- .../basic}/entries/fact/InAudienceFact.kt | 20 +- .../entries/fact/InCinematicFactEntry.kt | 26 +- .../entries/fact/InventoryItemCountFact.kt | 40 + .../basic}/entries/fact/ItemHoldingFact.kt | 20 +- .../basic}/entries/fact/ItemInSlotFact.kt | 21 +- .../basic}/entries/fact/PermanentFactEntry.kt | 14 +- .../entries/fact/PlaceholderFactEntries.kt | 28 +- .../basic}/entries/fact/QuestStatusFact.kt | 25 +- .../basic}/entries/fact/SessionFactEntry.kt | 14 +- .../basic}/entries/fact/TimedFactEntry.kt | 22 +- .../basic}/entries/group/GlobalGroupEntry.kt | 10 +- .../basic}/entries/group/PlayerGroupEntry.kt | 10 +- .../basic}/entries/group/WorldGroupEntry.kt | 10 +- .../entries/quest/CompletableObjective.kt | 26 +- .../entries/quest/LocationObjectiveEntry.kt | 22 +- .../entries/quest/ObjectiveLinesEntry.kt | 24 +- .../entries/quest/QuestCompleteEventEntry.kt | 25 +- .../entries/quest/QuestStartEventEntry.kt | 25 +- .../quest/QuestStatusUpdateEventEntry.kt | 28 +- .../entries/quest/SimpleObjectiveEntry.kt | 18 +- .../basic}/entries/quest/SimpleQuestEntry.kt | 27 +- .../entries/quest/TrackedObjectiveAudience.kt | 14 +- .../entries/quest/TrackedQuestAudience.kt | 22 +- .../basic}/entries/sound/CustomSoundEntry.kt | 8 +- .../entries/static/BaseRoadNetworkEntry.kt | 16 +- .../basic}/entries/static/SelfSpeaker.kt | 14 +- .../entries/static/SimpleSpeakerEntry.kt | 22 + extensions/CitizensExtension/build.gradle.kts | 34 + .../entries/entity/ReferenceNpcEntry.kt | 34 + .../entries/event/NpcInteractEvent.kt | 50 + .../src/main/templates/App.kt | 0 .../CombatLogXExtension/build.gradle.kts | 32 + .../event/PlayerEnterCombatEventEntry.kt | 18 +- .../event/PlayerExitCombatEventEntry.kt | 14 +- .../entries/fact/CombatFactEntry.kt | 41 + .../src/main/templates/App.kt | 0 extensions/EntityExtension/build.gradle.kts | 28 + .../entries/activity/AudienceActivityPair.kt | 32 +- .../entries/activity/GameTimeActivity.kt | 29 +- .../entries/activity/InDialogueActivity.kt | 39 +- .../entries/activity/LookCloseActivity.kt | 49 +- .../activity/NavigationActivityTask.kt | 55 +- .../entries/activity/PathActivityEntry.kt | 39 +- .../entries/activity/PatrolActivity.kt | 37 +- .../entries/activity/PlayerCloseByActivity.kt | 45 +- .../activity/RandomLookActivityEntry.kt | 23 +- .../activity/TargetLocationActivity.kt | 60 +- .../entity}/entries/activity/TimedActivity.kt | 29 +- .../entries/activity/TriggerActivityEntry.kt | 32 +- .../DirectEntityInstancePathStream.kt | 25 +- .../entries/cinematic/EntityCinematicEntry.kt | 63 +- .../entries/data/minecraft/ArmSwingData.kt | 8 +- .../entries/data/minecraft/CustomNameData.kt | 19 +- .../entries/data/minecraft/DyeColorData.kt | 48 + .../entries/data/minecraft/GenericData.kt | 4 +- .../data/minecraft/GlowingEffectData.kt | 16 +- .../entries/data/minecraft/OnFireData.kt | 16 +- .../entries/data/minecraft/PoseData.kt | 17 +- .../display/BillboardConstraintData.kt | 17 +- .../data/minecraft/display/DisplayData.kt | 8 +- .../data/minecraft/display/ScaleData.kt | 20 +- .../data/minecraft/display/TranslationData.kt | 24 +- .../data/minecraft/display/block/BlockData.kt | 21 +- .../minecraft/display/item/DIsplayTypeData.kt | 26 +- .../data/minecraft/display/item/ItemData.kt | 22 +- .../display/text/TextBackgroundColorData.kt | 24 +- .../minecraft/display/text/TextDisplayData.kt | 8 + .../display/text/TextLineWidthData.kt | 16 +- .../minecraft/display/text/TextOpacityData.kt | 23 +- .../display/text/TextSeeThroughData.kt | 16 +- .../minecraft/display/text/TextShadowData.kt | 30 +- .../data/minecraft/living/AgeableData.kt | 18 +- .../data/minecraft/living/ArrowCountData.kt | 19 +- .../data/minecraft/living/EquipmentData.kt | 18 +- .../data/minecraft/living/FrogVariantData.kt | 20 +- .../data/minecraft/living/LivingData.kt | 4 +- .../minecraft/living/PotionEffectColorData.kt | 23 +- .../data/minecraft/living/SaddledData.kt | 20 +- .../entries/data/minecraft/living/SizeData.kt | 21 +- .../data/minecraft/living/TremblingData.kt | 21 +- .../minecraft/living/cat/CatVariantData.kt | 19 +- .../living/horse/ChestedHorseChestMeta.kt | 21 +- .../minecraft/living/horse/HorseEatingData.kt | 18 +- .../living/horse/HorseVariantData.kt | 17 +- .../living/horse/LlamaVariantData.kt | 19 +- .../minecraft/living/horse/RearingData.kt | 18 +- .../living/parrot/ParrotColorData.kt | 27 +- .../minecraft/living/piglin/DancingData.kt | 20 +- .../data/minecraft/living/player/SkinData.kt | 12 +- .../living/pufferfish/PuffStateData.kt | 30 +- .../minecraft/living/rabbit/RabbitTypeData.kt | 20 +- .../minecraft/living/scheep/ShearedData.kt | 20 +- .../minecraft/living/villager/VillagerData.kt | 20 +- .../data/minecraft/living/wolf/BeggingData.kt | 22 +- .../data/minecraft/other/MarkerData.kt | 18 +- .../entries/data/minecraft/other/SmallData.kt | 18 +- .../entries/entity/WrapperFakeEntity.kt | 17 +- .../entity/custom/EntityTypeProperty.kt | 18 +- .../entries/entity/custom/HitBoxEntity.kt | 38 +- .../entity/custom/InteractionIndicator.kt | 39 +- .../entries/entity/custom/NamedEntity.kt | 48 +- .../entity}/entries/entity/custom/Npc.kt | 37 +- .../entity}/entries/entity/custom/SelfNpc.kt | 26 +- .../entries/entity/custom/StackedEntity.kt | 28 +- .../entries/entity/minecraft/AllayEntity.kt | 40 +- .../entries/entity/minecraft/CatEntity.kt | 50 +- .../entries/entity/minecraft/ChickenEntity.kt | 42 +- .../entries/entity/minecraft/CowEntity.kt | 42 +- .../entity/minecraft/EndermanEntity.kt | 38 +- .../entries/entity/minecraft/FrogEntity.kt | 38 +- .../entries/entity/minecraft/HoglinEntity.kt | 38 +- .../entries/entity/minecraft/HuskEntity.kt | 42 +- .../entity/minecraft/IronGolemEntity.kt | 38 +- .../entity/minecraft/ItemDisplayEntity.kt | 46 +- .../entity/minecraft/MagmaCubeEntity.kt | 40 +- .../entity/minecraft/PiglinBruteEntity.kt | 42 +- .../entries/entity/minecraft/PiglinEntity.kt | 42 +- .../entries/entity/minecraft/PlayerEntity.kt | 67 +- .../entity/minecraft/SkeletonEntity.kt | 38 +- .../entries/entity/minecraft/SlimeEntity.kt | 40 +- .../entity/minecraft/TextDisplayEntity.kt | 46 +- .../entity/minecraft/VillagerEntity.kt | 46 +- .../entries/entity/minecraft/WardenEntity.kt | 42 +- .../entries/entity/minecraft/WitchEntity.kt | 38 +- .../entries/entity/minecraft/ZombieEntity.kt | 42 +- .../entries/event/EntityInteractEventEntry.kt | 20 +- .../instance/AdvancedEntityInstanceEntry.kt | 25 +- .../entries/quest/InteractEntityObjective.kt | 24 +- .../InteractEntityObjectivesPathStream.kt | 21 +- .../src/main/templates/App.kt | 0 .../MythicMobsExtension/build.gradle.kts | 32 + .../entries/action/DespawnMobActionEntry.kt | 26 +- .../entries/action/ExecuteSkillActionEntry.kt | 33 +- .../entries/action/SpawnMobActionEntry.kt | 38 +- .../cinematic/MythicMobCinematicEntry.kt | 40 +- .../cinematic/MythicSkillCinematicEntry.kt | 26 +- .../entries/event/MythicMobDeathEventEntry.kt | 18 +- .../event/MythicMobInteractEventEntry.kt | 18 +- .../event/MythicMobKillPlayerEventEntry.kt | 2 +- .../mythicmobs/entries/fact/MobCountFact.kt | 18 +- .../src/main/templates/App.kt | 0 .../RPGRegionsExtension/build.gradle.kts | 32 + .../action/DiscoverRegionActionEntry.kt | 25 +- .../entries/event/DiscoverRegionEventEntry.kt | 19 +- .../entries/event/EnterRegionEventEntry.kt | 18 +- .../rpgregions/entries/fact/InRegionFact.kt | 21 +- .../rpgregions/entries}/group/RegionGroup.kt | 12 +- .../src/main/templates/App.kt | 0 .../build.gradle.kts | 32 + .../action/IslandDisbandActionEntry.kt | 16 +- .../action/IslandSetBiomeActionEntry.kt | 18 +- .../action/IslandSetBorderSizeActionEntry.kt | 18 +- .../action/IslandSetMemberLimitActionEntry.kt | 18 +- .../bank/IslandBankDepositActionEntry.kt | 18 +- .../bank/IslandBankWithdrawActionEntry.kt | 18 +- .../entries/event/IslandCreateEventEntry.kt | 14 +- .../entries/event/IslandDisbandEventEntry.kt | 14 +- .../entries/event/IslandInviteEventEntry.kt | 17 +- .../entries/event/IslandJoinEventEntry.kt | 14 +- .../entries/event/IslandUpgradeEventEntry.kt | 14 +- .../event/MissionCompleteEventEntry.kt | 16 +- .../entries/fact/IslandFactEntry.kt | 19 +- .../entries/group/IslandGroupEntry.kt | 10 +- .../src/main/templates/App.kt | 0 extensions/VaultExtension/build.gradle.kts | 26 + .../typewritermc/vault/VaultInitializer.kt | 27 +- .../action/DepositBalanceActionEntry.kt | 22 +- .../entries/action/SetPrefixActionEntry.kt | 22 +- .../action/WithdrawBalanceActionEntry.kt | 22 +- .../vault/entries/fact/BalanceFactEntry.kt | 20 +- .../vault/entries/fact/PermissionFactEntry.kt | 22 +- .../vault/entries/group/BalanceGroupEntry.kt | 16 +- .../entries/group/PermissionGroupEntry.kt | 10 +- .../VaultExtension}/src/main/templates/App.kt | 0 .../WorldGuardExtension/build.gradle.kts | 29 + .../worldguard/WorldGuardHandler.kt | 40 +- .../worldguard/WorldGuardInitializer.kt | 61 + .../entries/audience/RegionAudienceEntry.kt | 34 +- .../entries/event/EnterRegionEventEntry.kt | 22 +- .../entries/event/ExitRegionEventEntry.kt | 22 +- .../worldguard/entries/fact/InRegionFact.kt | 18 +- .../worldguard/entries/group/RegionGroup.kt | 12 +- .../src/main/templates/App.kt | 0 extensions/_DocsExtension/build.gradle.kts | 22 + .../example/ExampleInitializer.kt | 17 + .../cinematic/ExampleCinematicEntry.kt | 12 +- .../entries/manifest/ExampleAudienceEntry.kt | 12 +- .../entries/static/ExampleArtifactEntry.kt | 10 +- .../entries/static/ExampleAssetEntry.kt | 10 +- .../entries/static/ExampleSoundIdEntry.kt | 6 +- .../entries/static/ExampleSoundSourceEntry.kt | 6 +- .../entries/static/ExampleSpeakerEntry.kt | 8 +- .../entries/trigger/ExampleActionEntry.kt | 14 +- .../ExampleCustomTriggeringActionEntry.kt | 21 +- .../entries/trigger/ExampleDialogueEntry.kt | 29 +- .../entries/trigger/ExampleEventEntry.kt | 14 +- .../_DocsExtension}/src/main/templates/App.kt | 0 {adapters => extensions}/build.gradle.kts | 96 +- .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {adapters => extensions}/gradlew | 0 {adapters => extensions}/gradlew.bat | 0 extensions/settings.gradle.kts | 34 + jitpack.yml | 12 - module-plugin/api/build.gradle.kts | 4 + .../TypewriterModuleConfiguration.kt | 172 + module-plugin/build.gradle.kts | 115 + .../extension-processor/build.gradle.kts | 18 + .../com/typewritermc/SharedJsonManager.kt | 25 + .../processors/DialogueMessengerProcessor.kt | 60 + .../processors/EntryListenerProcessor.kt | 73 + .../processors/ExtensionProcessor.kt | 100 + .../processors/InitializerProcessor.kt | 45 + .../typewritermc/processors/KSPExtensions.kt | 54 + .../processors/entry/CustomEditor.kt | 61 + .../processors/entry/DataBlueprint.kt | 336 ++ .../processors/entry/DataModifier.kt | 62 + .../processors/entry/DataModifierComputer.kt | 97 + .../processors/entry/EntryProcessor.kt | 117 + .../processors/entry/editors/ColorEditor.kt | 20 + .../entry/editors/CoordinateEditor.kt | 46 + .../processors/entry/editors/CronEditor.kt | 21 + .../entry/editors/DurationEditor.kt | 35 + .../entry/editors/FloatRangeEditor.kt | 47 + .../processors/entry/editors/ItemEditor.kt | 57 + .../entry/editors/MaterialEditor.kt | 21 + .../entry/editors/OptionalEditor.kt | 46 + .../entry/editors/PositionEditor.kt | 57 + .../entry/editors/PotionEffectTypeEditor.kt | 22 + .../processors/entry/editors/RefEditor.kt | 53 + .../processors/entry/editors/SkinEditor.kt | 39 + .../processors/entry/editors/SoundIdEditor.kt | 39 + .../entry/editors/SoundSourceEditor.kt | 59 + .../processors/entry/editors/VectorEditor.kt | 42 + .../processors/entry/editors/WorldEditor.kt | 23 + .../modifiers/ColoredModifierComputer.kt | 29 + .../ContentEditorModifierComputer.kt | 25 + .../modifiers/GeneratedModifierComputer.kt | 29 + .../entry/modifiers/HelpModifierComputer.kt | 18 + .../entry/modifiers/IconModifierComputer.kt | 15 + .../MaterialPropertiesModifierComputer.kt | 28 + .../modifiers/MultiLineModifierComputer.kt | 28 + .../modifiers/NegativeModifierComputer.kt | 29 + .../modifiers/OnlyTagsModifierComputer.kt | 28 + .../entry/modifiers/PageModifierComputer.kt | 28 + .../modifiers/PlaceholderModifierComputer.kt | 29 + .../entry/modifiers/RegexModifierComputer.kt | 29 + .../modifiers/SegmentModifierComputer.kt | 46 + .../entry/modifiers/SizeModifierComputer.kt | 80 + .../modifiers/SnakeCaseModifierComputer.kt | 25 + .../modifiers/WithRotationModifierComputer.kt | 27 + ...ols.ksp.processing.SymbolProcessorProvider | 1 + .../gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 60756 bytes .../gradle/wrapper/gradle-wrapper.properties | 3 +- {plugin => module-plugin}/gradlew | 0 {plugin => module-plugin}/gradlew.bat | 0 .../settings.gradle.kts | 8 +- .../typewritermc/TypewriterModulePlugin.kt | 108 + plugin/settings.gradle.kts | 12 - .../extensions/inventory/ItemExtensions.kt | 72 - .../api/extensions/math/MathExtensions.kt | 122 - .../other/ConfigurationExtensions.kt | 39 - .../server/commands/CommandController.kt | 32 - .../server/commands/CommandExtensions.kt | 54 - .../api/extensions/world/BlockExtensions.kt | 55 - .../api/extensions/world/EntityExtensions.kt | 23 - .../extensions/world/LocationExtensions.kt | 102 - .../api/extensions/world/PlayerExtensions.kt | 85 - .../src/main/kotlin/lirand/api/nbt/NbtData.kt | 200 -- .../kotlin/lirand/api/nbt/NbtDataAccessor.kt | 88 - .../kotlin/lirand/api/nbt/NbtDataLoader.kt | 60 - .../lirand/api/nbt/NbtDataSerializer.kt | 67 - .../main/kotlin/lirand/api/nbt/NbtDataType.kt | 345 -- .../api/nbt/serialization/NbtDataDecoder.kt | 158 - .../api/nbt/serialization/NbtDataEncoder.kt | 155 - .../api/nbt/serialization/NbtSerialization.kt | 140 - .../kotlin/lirand/api/utilities/Reflection.kt | 56 - .../main/kotlin/lirand/api/utilities/Scope.kt | 32 - .../typewriter/adapters/AdapterListeners.kt | 83 - .../typewriter/adapters/AdapterLoader.kt | 388 -- .../typewriter/adapters/AdapterMessenger.kt | 22 - .../typewriter/adapters/CustomEditors.kt | 249 -- .../typewriter/adapters/EntryAttributes.kt | 36 - .../typewriter/adapters/EntryBlueprint.kt | 200 -- .../typewriter/adapters/FieldModifiers.kt | 178 - .../typewriter/adapters/TypewriterAdapter.kt | 7 - .../adapters/editors/ColorEditor.kt | 21 - .../typewriter/adapters/editors/CronEditor.kt | 21 - .../adapters/editors/DurationEditor.kt | 21 - .../adapters/editors/EntryReferenceEditor.kt | 48 - .../adapters/editors/FloatRangeEditor.kt | 31 - .../typewriter/adapters/editors/ItemEditor.kt | 59 - .../adapters/editors/LocationEditor.kt | 81 - .../adapters/editors/MaterialEditor.kt | 13 - .../adapters/editors/OptionalEditor.kt | 56 - .../editors/PotionEffectTypeEditor.kt | 21 - .../typewriter/adapters/editors/SkinEditor.kt | 34 - .../adapters/editors/SoundIdEditor.kt | 50 - .../adapters/editors/SoundSourceEditor.kt | 70 - .../adapters/editors/VectorEditor.kt | 36 - .../modifiers/ColoredModifierComputer.kt | 30 - .../ContentEditorModifierComputer.kt | 24 - .../modifiers/GeneratedModifierComputer.kt | 30 - .../modifiers/HelpModifierComputer.kt | 17 - .../typewriter/adapters/modifiers/Icon.kt | 16 - .../modifiers/MaterialModifierComputer.kt | 50 - .../modifiers/MultiLineModifierComputer.kt | 30 - .../modifiers/NegativeModifierComputer.kt | 30 - .../modifiers/OnlyTagsModifierComputer.kt | 29 - .../modifiers/PageModifierComputer.kt | 30 - .../modifiers/PlaceholderModifierComputer.kt | 31 - .../modifiers/RegexModifierComputer.kt | 29 - .../modifiers/SegmentModifierComputer.kt | 45 - .../modifiers/SizeModifierComputer.kt | 42 - .../modifiers/SnakeCaseModifierComputer.kt | 31 - .../modifiers/StaticModifierComputer.kt | 146 - .../modifiers/WithRotationModifierComputer.kt | 28 - .../components/CachedInventoryComponent.kt | 24 - .../modes/ImmediateFieldValueContentMode.kt | 44 - .../typewriter/entry/EntryDatabase.kt | 261 -- .../typewriter/entry/EntryListeners.kt | 96 - .../typewriter/entry/EntryMigration.kt | 220 -- .../typewriter/entry/PageMigrator.kt | 179 - .../entry/entity/EntityAttribute.kt | 4 - .../typewriter/entry/entity/EntityStorage.kt | 11 - .../entry/entity/LocationProperty.kt | 101 - .../typewriter/entry/entries/DialogueEntry.kt | 16 - .../events/TypewriterReloadEvent.kt | 16 - .../extensions/bstats/BStatsMetrics.kt | 31 - .../typewriter/utils/ServerCommandMap.kt | 35 - plugin/src/main/resources/plugin.yml | 11 - 842 files changed, 16713 insertions(+), 17208 deletions(-) delete mode 100644 .github/actions/build-adapter/action.yml rename .github/actions/{build-plugin => build-engine}/action.yml (76%) create mode 100644 .github/actions/build-extension/action.yml delete mode 100644 .github/workflows/build-adapter.yml rename .github/workflows/{build-plugin.yml => build-engine.yml} (62%) create mode 100644 .github/workflows/build-extension.yml delete mode 100644 .github/workflows/build-jars-on-push.yml delete mode 100644 adapters/BasicAdapter/build.gradle.kts delete mode 100644 adapters/BasicAdapter/settings.gradle.kts delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerJoinEventEntry.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerNearLocationEventEntry.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/fact/InventoryItemCountFact.kt delete mode 100644 adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/static/SimpleSpeakerEntry.kt delete mode 100644 adapters/CitizensAdapter/build.gradle.kts delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/CitizensAdapter.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/TypewriterTrait.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/artifact/NpcMovementArtifact.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/CitizensNpcData.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/NpcCinematicEntry.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/ReferenceNpcCinematicEntry.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/SelfNpcCinematicEntry.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/CitizensNpc.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/ReferenceNpcEntry.kt delete mode 100644 adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/event/NpcInteractEvent.kt delete mode 100644 adapters/CombatLogXAdapter/build.gradle.kts delete mode 100644 adapters/CombatLogXAdapter/settings.gradle.kts delete mode 100644 adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/CombatLogXAdapter.kt delete mode 100644 adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/entries/fact/CombatFactEntry.kt delete mode 100644 adapters/EntityAdapter/build.gradle.kts delete mode 100644 adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/EntityAdapter.kt delete mode 100644 adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextDisplayData.kt delete mode 100644 adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/CollarColorData.kt delete mode 100644 adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaCarpetColorData.kt delete mode 100644 adapters/FancyNpcsAdapter/build.gradle.kts delete mode 100644 adapters/FancyNpcsAdapter/settings.gradle.kts delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/FancyNpcsAdapter.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/FancyNpcData.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/FancyNPC.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt delete mode 100644 adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt delete mode 100644 adapters/MythicMobsAdapter/build.gradle.kts delete mode 100644 adapters/MythicMobsAdapter/settings.gradle.kts delete mode 100644 adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt delete mode 100644 adapters/RPGRegionsAdapter/build.gradle.kts delete mode 100644 adapters/RPGRegionsAdapter/settings.gradle.kts delete mode 100644 adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/RPGRegionsAdapter.kt delete mode 100644 adapters/SuperiorSkyblockAdapter/build.gradle.kts delete mode 100644 adapters/SuperiorSkyblockAdapter/settings.gradle.kts delete mode 100644 adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/SuperiorSkyblockAdapter.kt delete mode 100644 adapters/VaultAdapter/build.gradle.kts delete mode 100644 adapters/VaultAdapter/settings.gradle.kts delete mode 100644 adapters/WorldGuardAdapter/build.gradle.kts delete mode 100644 adapters/WorldGuardAdapter/settings.gradle.kts delete mode 100644 adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardAdapter.kt delete mode 100644 adapters/WorldGuardAdapter/src/main/templates/App.kt delete mode 100644 adapters/ZNPCsPlusAdapter/build.gradle.kts delete mode 100644 adapters/ZNPCsPlusAdapter/settings.gradle.kts delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/ZNPCsPlusAdapter.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ZNPCData.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ZNPC.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt delete mode 100644 adapters/ZNPCsPlusAdapter/src/main/templates/App.kt delete mode 100644 adapters/_DocsAdapter/build.gradle.kts delete mode 100644 adapters/_DocsAdapter/settings.gradle.kts delete mode 100644 adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/ExampleAdapter.kt delete mode 100644 adapters/_DocsAdapter/src/main/templates/App.kt delete mode 100644 adapters/settings.gradle.kts create mode 100644 app/ios/RunnerTests/RunnerTests.swift delete mode 100644 app/lib/models/adapter.freezed.dart rename app/lib/models/{adapter.dart => entry_blueprint.dart} (50%) create mode 100644 app/lib/models/entry_blueprint.freezed.dart rename app/lib/models/{adapter.g.dart => entry_blueprint.g.dart} (79%) create mode 100644 app/lib/models/extension.dart create mode 100644 app/lib/models/extension.freezed.dart create mode 100644 app/lib/models/extension.g.dart create mode 100644 app/macos/RunnerTests/RunnerTests.swift delete mode 100644 documentation/docs/develop/02-adapters/02-getting_started.mdx delete mode 100644 documentation/docs/develop/02-adapters/index.mdx create mode 100644 documentation/docs/develop/02-extensions/02-getting_started.mdx create mode 100644 documentation/docs/develop/02-extensions/03-initializers.mdx rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/cinematic/index.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/index.mdx (94%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/manifest/_category_.yml (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/manifest/audience.mdx (98%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/static/_category_.yml (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/static/artifact.mdx (96%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/static/asset.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/static/sound_id.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/static/sound_source.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/static/speaker.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/trigger/_category_.yml (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/trigger/action.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/trigger/custom_triggering_action.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/trigger/dialogue.mdx (100%) rename documentation/docs/develop/{02-adapters/03-entries => 02-extensions/04-entries}/trigger/event.mdx (100%) rename documentation/docs/develop/{02-adapters/04-querying.mdx => 02-extensions/05-querying.mdx} (100%) rename documentation/docs/develop/{02-adapters/05-triggering.mdx => 02-extensions/06-triggering.mdx} (100%) rename documentation/docs/develop/{02-adapters/06-api-changes/0.5.0.mdx => 02-extensions/07-api-changes/0.5.mdx} (95%) create mode 100644 documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx rename documentation/docs/develop/{02-adapters/06-api-changes => 02-extensions/07-api-changes}/index.mdx (97%) create mode 100644 documentation/docs/develop/02-extensions/index.mdx rename documentation/docs/docs/03-creating-stories/{04-entity-adapter => 04-entity-extension}/02-interacting.mdx (92%) rename documentation/docs/docs/03-creating-stories/{04-entity-adapter => 04-entity-extension}/index.mdx (80%) delete mode 100644 documentation/docs/docs/06-troubleshooting/adapters.mdx create mode 100644 documentation/docs/docs/06-troubleshooting/extensions.mdx rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/definition_select.png (100%) rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/entity-interact-event-fields.png (100%) rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/entity_location.webm (100%) rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/entity_name_change.png (100%) rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/fetch_skin.webm (100%) rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/glow_editor.png (100%) rename documentation/docs/docs/assets/{entity-adapter => entity-extension}/glow_effect.png (100%) create mode 100644 engine/build.gradle.kts create mode 100644 engine/engine-core/build.gradle.kts create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/TypewriterCore.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/Colors.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/PageType.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Entry.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter/entry => engine/engine-core/src/main/kotlin/com/typewritermc/core/entries}/EntryReference.kt (77%) create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Library.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Page.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Query.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/Initializable.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Default.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Entry.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/EntryListener.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Initializer.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Messenger.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Modifiers.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Tags.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-core/src/main/kotlin/com/typewritermc/core}/utils/Looping.kt (94%) create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Reloadable.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-core/src/main/kotlin/com/typewritermc/core}/utils/Result.kt (92%) create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Coordinate.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter/utils => engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point}/Point.kt (80%) create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Position.kt create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Rotatable.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter/utils => engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point}/Vector.kt (81%) create mode 100644 engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/World.kt create mode 100644 engine/engine-loader/build.gradle.kts create mode 100644 engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DataSerializer.kt create mode 100644 engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DependencyChecker.kt create mode 100644 engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ExtensionLoader.kt create mode 100644 engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ListenerPriority.kt rename {plugin => engine/engine-paper}/build.gradle.kts (66%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/TypewriterCommand.kt (85%) rename plugin/src/main/kotlin/me/gabber235/typewriter/Typewriter.kt => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterPaperPlugin.kt (54%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/ContentComponent.kt (80%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/ContentContext.kt (97%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/ContentEditor.kt (77%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/ContentMode.kt (83%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/components/BossBarComponent.kt (84%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/components/CompoundContentComponent.kt (74%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/components/ExitComponent.kt (70%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/components/ItemsComponent.kt (91%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/components/NodesComponent.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/components/SimulateCinematicComponent.kt (80%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/ImmediateFieldValueContentMode.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/modes/RecordingCinematicContentMode.kt (88%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/content/modes/Tape.kt (97%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/HoldingItemContentMode.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/PositionContentMode.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/AssetManager.kt (56%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/AudienceManager.kt (89%) rename plugin/src/main/kotlin/me/gabber235/typewriter/entry/Entry.kt => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/BaseEntry.kt (50%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/EntryListeners.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/FactWatcher.kt (91%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/PlaceholderEntry.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/StagingManager.kt (73%) rename plugin/src/main/kotlin/me/gabber235/typewriter/entry/Query.kt => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/TriggerEntry.kt (54%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/cinematic/CinematicSequence.kt (75%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/cinematic/SimpleCinematicAction.kt (78%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/dialogue/DialogueSequence.kt (77%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/dialogue/MessengerFinder.kt (69%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/ActivityEntityDisplay.kt (74%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/ActivityManager.kt (69%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/AdvancedEntity.kt (81%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/DisplayEntity.kt (70%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/EntityActivity.kt (77%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityAttribute.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/EntityHandler.kt (82%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityStorage.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/FakeEntity.kt (86%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/GroupActivityEntityDisplay.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/IndividualActivityEntityDisplay.kt (81%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/PositionProperty.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/SharedActivityEntityDisplay.kt (79%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/SimpleEntity.kt (75%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/SinglePropertyCollector.kt (68%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entity/SkinProperty.kt (82%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/ActionEntry.kt (66%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/AssetEntry.kt (74%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/AudienceEntry.kt (94%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/CinematicEntry.kt (90%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/DialogueEntry.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/EntityEntry.kt (82%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/EventEntry.kt (83%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/FactEntry.kt (71%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/GroupEntry.kt (84%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/LinesEntry.kt (83%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/QuestEntry.kt (82%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/RoadNetworkEntry.kt (84%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/SidebarEntry.kt (87%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/entries/SoundEntry.kt (60%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/quest/QuestTracker.kt (87%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/RoadNetworkEditor.kt (92%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/RoadNetworkManager.kt (87%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/content/RoadNetworkContentMode.kt (86%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/content/RoadNetworkEditorComponent.kt (67%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt (82%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt (86%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/gps/GPS.kt (80%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/gps/PathStreamDisplay.kt (86%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/gps/PointToPointGPS.kt (95%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/pathfinding/PFBlock.kt (97%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/pathfinding/PFColumnarSpace.kt (88%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/pathfinding/PFEmptyEntity.kt (94%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/entry/roadnetwork/pathfinding/PFInstanceSpace.kt (94%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncCinematicEndEvent.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncCinematicStartEvent.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncCinematicTickEvent.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncDialogueEvents.kt (95%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncEntityDefinitionInteract.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncQuestStatusUpdate.kt (70%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/AsyncTrackedQuestUpdate.kt (76%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/ContentEditorEvents.kt (94%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/events/StagingChangeEvent.kt (81%) rename plugin/src/main/kotlin/me/gabber235/typewriter/events/PublishedBookEvent.kt => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/TypewriterUnloadEvent.kt (75%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/bstats/BStatsMetrics.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/extensions/modrinth/Modrinth.kt (70%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/extensions/packetevents/PlayerPackets.kt (98%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/extensions/placeholderapi/PlaceholderExpansion.kt (82%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/facts/Fact.kt (65%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/facts/FactDatabase.kt (84%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/facts/FactStorage.kt (93%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/facts/storage/FileFactStorage.kt (91%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/interaction/ActionBarBlocker.kt (97%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/interaction/ChatHistoryHandler.kt (96%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/interaction/Interaction.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/interaction/InteractionHandler.kt (81%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/interaction/PacketInterceptor.kt (92%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/DataSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/PaperDependencyChecker.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/ColorSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/CronExpressionSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/DurationSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/EntryReferenceSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/FloatRangeSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/OptionalSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/PotionEffectTypeSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SkinPropertySerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundIdSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundSourceSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/VectorSerializer.kt create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/WorldSerializer.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/snippets/Snippet.kt (95%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/snippets/SnippetDatabase.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/ui/ClientSynchronizer.kt (88%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/ui/CommunicationHandler.kt (95%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/ui/PanelHost.kt (92%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/ui/Writers.kt (98%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/BlockPhysics.kt (98%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/BukkitDataParser.kt (95%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Color.kt (92%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/ComputedMap.kt (88%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Config.kt (89%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/CronExpression.kt (99%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/DurationParser.kt (97%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Extensions.kt (88%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Interpolation.kt (90%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Item.kt (69%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Memoized.kt (93%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/MiniMessages.kt (97%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/PlayerState.kt (96%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Point.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Reloadable.kt (76%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/RuntimeTypeAdapterFactory.kt (99%) create mode 100644 engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ServerCommandMap.kt rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Sound.kt (85%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/ThreadType.kt (94%) rename {plugin/src/main/kotlin/me/gabber235/typewriter => engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper}/utils/Timeout.kt (78%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/LirandAPI.kt (75%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt (99%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt (99%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt (51%) create mode 100644 engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/math/Positions.kt (83%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/math/Ranges.kt (100%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/other/JsonExtensions.kt (100%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt (51%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt (72%) rename {plugin => engine/engine-paper}/src/main/kotlin/lirand/api/extensions/server/ServerExtensions.kt (100%) create mode 100644 engine/engine-paper/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt create mode 100644 engine/engine-paper/src/main/kotlin/lirand/api/utilities/Reflection.kt rename {plugin/src/test/kotlin/me/gabber235/typewriter => engine/engine-paper/src/test/kotlin/com/typewritermc}/utils/CronParserTest.kt (99%) rename {plugin/src/test/kotlin/me/gabber235/typewriter => engine/engine-paper/src/test/kotlin/com/typewritermc}/utils/DurationParserTest.kt (95%) rename {plugin => engine}/gradle.properties (100%) create mode 100644 engine/gradle/wrapper/gradle-wrapper.jar create mode 100644 engine/gradle/wrapper/gradle-wrapper.properties create mode 100755 engine/gradlew create mode 100644 engine/gradlew.bat rename {adapters/EntityAdapter => engine}/settings.gradle.kts (54%) create mode 100644 extensions/BasicExtension/build.gradle.kts rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/AddPotionEffectActionEntry.kt (56%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/ApplyVelocityActionEntry.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/CinematicEntry.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/ConsoleCommandActionEntry.kt (58%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/DelayedActionEntry.kt (64%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DropItemActionEntry.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/FireworkActionEntry.kt (70%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GiveItemActionEntry.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/GroupTriggerActionEntry.kt (73%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/MessageActionEntry.kt (67%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlaySoundActionEntry.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/PlayerCommandActionEntry.kt (60%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/RandomTriggerGateEntry.kt (71%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/RemoveItemActionEntry.kt (64%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/SetBlockActionEntry.kt (60%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/SetItemActionEntry.kt (56%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/ShowTitleActionEntry.kt (70%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/SimpleActionEntry.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/SpawnParticleActionEntry.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/StopSoundActionEntry.kt (65%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/SwitchServerActionEntry.kt (67%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/TeleportActionEntry.kt (55%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/action/TrackQuestActionEntry.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/BossBarEntry.kt (75%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/CinematicAudienceEntry.kt (67%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/ClosestGroupMemberPathStream.kt (70%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/CriteriaAudience.kt (83%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/CronAudience.kt (76%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/DirectLocationPathStream.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/GameTimeAudienceEntry.kt (88%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/GroupMembersPathStream.kt (65%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/HoldingItemAudienceEntry.kt (80%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/ItemInInventoryAudienceEntry.kt (60%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/ItemInSlotAudienceEntry.kt (64%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/LocationObjectivesPathStream.kt (51%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/LoopingCinematicAudience.kt (87%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/SidebarEntry.kt (59%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/SimpleLinesEntry.kt (64%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/TabListHeaderFooterEntry.kt (85%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/TimerAudienceEntry.kt (74%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/audience/TriggerAudienceEntry.kt (69%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/ActionBarDialogueCinematicEntry.kt (78%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/BlindingCinematicEntry.kt (73%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/CameraCinematicEntry.kt (86%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/CinematicCommandEntry.kt (77%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/DisplayDialogueCinematicAction.kt (80%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/ParticleCinematicEntry.kt (64%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/PotionEffectCinematicEntry.kt (70%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/PumpkinHatCinematicEntry.kt (69%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/ScreenShakeCinematicEntry.kt (71%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/SetFakeBlockCinematicEntry.kt (60%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/SpokenDialogueCinematicEntry.kt (76%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/SubtitleDialgueCinematicEntry.kt (76%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/TitleCinematicEntry.kt (71%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/cinematic/TriggerSequenceCinematicEntry.kt (66%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/MessageDialogue.kt (61%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/OptionDialogueEntry.kt (72%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/RandomMessageDialogue.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/RandomSpokenDialogueEntry.kt (68%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/SpokenDialogueEntry.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/message/UniversalMessageDialogueDialogueMessenger.kt (65%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/option/BedrockOptionDialogueDialogueMessenger.kt (66%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/option/JavaOptionDialogueDialogueMessenger.kt (84%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/random/BedrockRandomSpokenDialogueDialogueMessenger.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/random/JavaRandomSpokenDialogueDialogueMessenger.kt (60%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/random/RandomMessageDialogueDialogueMessenger.kt (55%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/spoken/BedrockSpokenDialogueDialogueMessenger.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/dialogue/messengers/spoken/JavaSpokenDialogueDialogueMessenger.kt (85%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/BlockBreakEventEntry.kt (54%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/BlockPlaceEventEntry.kt (55%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/ChatContainsTextEventEntry.kt (61%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/CraftItemEventEntry.kt (67%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/DetectCommandRanEventEntry.kt (81%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/FireTriggerEventEntry.kt (65%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/FishEventEntry.kt (73%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/InteractBlockEventEntry.kt (66%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/PickupItemEventEntry.kt (50%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/PlayerDeathEventEntry.kt (73%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/PlayerHitEntityEventEntry.kt (73%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/event/PlayerJoinEventEntry.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/PlayerKillEntityEventEntry.kt (71%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/PlayerKillPlayerEventEntry.kt (72%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/event/PlayerNearLocationEventEntry.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/PlayerQuitEventEntry.kt (60%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/event/RunCommandEventEntry.kt (71%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/CountdownFact.kt (73%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/CronFactEntry.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/InAudienceFact.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/InCinematicFactEntry.kt (61%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/fact/InventoryItemCountFact.kt rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/ItemHoldingFact.kt (67%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/ItemInSlotFact.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/PermanentFactEntry.kt (63%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/PlaceholderFactEntries.kt (82%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/QuestStatusFact.kt (65%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/SessionFactEntry.kt (62%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/fact/TimedFactEntry.kt (59%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/group/GlobalGroupEntry.kt (68%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/group/PlayerGroupEntry.kt (68%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/group/WorldGroupEntry.kt (66%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/CompletableObjective.kt (75%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/LocationObjectiveEntry.kt (66%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/ObjectiveLinesEntry.kt (61%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/QuestCompleteEventEntry.kt (53%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/QuestStartEventEntry.kt (52%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/QuestStatusUpdateEventEntry.kt (56%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/SimpleObjectiveEntry.kt (67%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/SimpleQuestEntry.kt (64%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/TrackedObjectiveAudience.kt (79%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/quest/TrackedQuestAudience.kt (70%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/sound/CustomSoundEntry.kt (72%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/static/BaseRoadNetworkEntry.kt (66%) rename {adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic}/entries/static/SelfSpeaker.kt (69%) create mode 100644 extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/static/SimpleSpeakerEntry.kt create mode 100644 extensions/CitizensExtension/build.gradle.kts create mode 100644 extensions/CitizensExtension/src/main/kotlin/com/typewritermc/citizens/entries/entity/ReferenceNpcEntry.kt create mode 100644 extensions/CitizensExtension/src/main/kotlin/com/typewritermc/citizens/entries/event/NpcInteractEvent.kt rename {adapters/BasicAdapter => extensions/CitizensExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/CombatLogXExtension/build.gradle.kts rename {adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter => extensions/CombatLogXExtension/src/main/kotlin/com/typewritermc}/combatlogx/entries/event/PlayerEnterCombatEventEntry.kt (66%) rename {adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter => extensions/CombatLogXExtension/src/main/kotlin/com/typewritermc}/combatlogx/entries/event/PlayerExitCombatEventEntry.kt (65%) create mode 100644 extensions/CombatLogXExtension/src/main/kotlin/com/typewritermc/combatlogx/entries/fact/CombatFactEntry.kt rename {adapters/CitizensAdapter => extensions/CombatLogXExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/EntityExtension/build.gradle.kts rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/AudienceActivityPair.kt (65%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/GameTimeActivity.kt (74%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/InDialogueActivity.kt (77%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/LookCloseActivity.kt (78%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/NavigationActivityTask.kt (83%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/PathActivityEntry.kt (80%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/PatrolActivity.kt (78%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/PlayerCloseByActivity.kt (72%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/RandomLookActivityEntry.kt (76%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/TargetLocationActivity.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/TimedActivity.kt (78%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/activity/TriggerActivityEntry.kt (68%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/audience/DirectEntityInstancePathStream.kt (55%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/cinematic/EntityCinematicEntry.kt (82%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/ArmSwingData.kt (80%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/CustomNameData.kt (70%) create mode 100644 extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/DyeColorData.kt rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/GenericData.kt (81%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/GlowingEffectData.kt (70%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/OnFireData.kt (68%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/PoseData.kt (73%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/BillboardConstraintData.kt (75%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/DisplayData.kt (67%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/ScaleData.kt (65%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/TranslationData.kt (64%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/block/BlockData.kt (65%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/item/DIsplayTypeData.kt (61%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/item/ItemData.kt (64%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/text/TextBackgroundColorData.kt (63%) create mode 100644 extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextDisplayData.kt rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/text/TextLineWidthData.kt (70%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/text/TextOpacityData.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/text/TextSeeThroughData.kt (71%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/display/text/TextShadowData.kt (53%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/AgeableData.kt (72%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/ArrowCountData.kt (61%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/EquipmentData.kt (87%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/FrogVariantData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/LivingData.kt (68%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/PotionEffectColorData.kt (63%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/SaddledData.kt (68%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/SizeData.kt (63%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/TremblingData.kt (63%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/cat/CatVariantData.kt (65%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt (65%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/horse/HorseEatingData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/horse/HorseVariantData.kt (68%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/horse/LlamaVariantData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/horse/RearingData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/parrot/ParrotColorData.kt (57%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/piglin/DancingData.kt (67%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/player/SkinData.kt (61%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/pufferfish/PuffStateData.kt (55%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/rabbit/RabbitTypeData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/scheep/ShearedData.kt (65%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/villager/VillagerData.kt (83%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/living/wolf/BeggingData.kt (64%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/other/MarkerData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/data/minecraft/other/SmallData.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/WrapperFakeEntity.kt (81%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/EntityTypeProperty.kt (96%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/HitBoxEntity.kt (73%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/InteractionIndicator.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/NamedEntity.kt (76%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/Npc.kt (73%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/SelfNpc.kt (74%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/custom/StackedEntity.kt (77%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/AllayEntity.kt (60%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/CatEntity.kt (55%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/ChickenEntity.kt (61%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/CowEntity.kt (58%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/EndermanEntity.kt (58%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/FrogEntity.kt (64%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/HoglinEntity.kt (63%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/HuskEntity.kt (58%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/IronGolemEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/ItemDisplayEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/MagmaCubeEntity.kt (61%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/PiglinBruteEntity.kt (60%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/PiglinEntity.kt (64%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/PlayerEntity.kt (75%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/SkeletonEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/SlimeEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/TextDisplayEntity.kt (62%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/VillagerEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/WardenEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/WitchEntity.kt (58%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/entity/minecraft/ZombieEntity.kt (59%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/event/EntityInteractEventEntry.kt (63%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/instance/AdvancedEntityInstanceEntry.kt (76%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/quest/InteractEntityObjective.kt (66%) rename {adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter => extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity}/entries/quest/InteractEntityObjectivesPathStream.kt (68%) rename {adapters/CombatLogXAdapter => extensions/EntityExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/MythicMobsExtension/build.gradle.kts rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/action/DespawnMobActionEntry.kt (68%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/action/ExecuteSkillActionEntry.kt (63%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/action/SpawnMobActionEntry.kt (58%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt (67%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt (75%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/event/MythicMobDeathEventEntry.kt (64%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/event/MythicMobInteractEventEntry.kt (64%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt (96%) rename {adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc}/mythicmobs/entries/fact/MobCountFact.kt (72%) rename {adapters/EntityAdapter => extensions/MythicMobsExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/RPGRegionsExtension/build.gradle.kts rename {adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc}/rpgregions/entries/action/DiscoverRegionActionEntry.kt (71%) rename {adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc}/rpgregions/entries/event/DiscoverRegionEventEntry.kt (63%) rename {adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc}/rpgregions/entries/event/EnterRegionEventEntry.kt (64%) rename {adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter => extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc}/rpgregions/entries/fact/InRegionFact.kt (68%) rename {adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions => extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries}/group/RegionGroup.kt (79%) rename {adapters/FancyNpcsAdapter => extensions/RPGRegionsExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/SuperiorSkyblockExtension/build.gradle.kts rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/action/IslandDisbandActionEntry.kt (68%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt (67%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt (65%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt (68%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt (68%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt (68%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/event/IslandCreateEventEntry.kt (62%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/event/IslandDisbandEventEntry.kt (63%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/event/IslandInviteEventEntry.kt (65%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/event/IslandJoinEventEntry.kt (67%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt (67%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/event/MissionCompleteEventEntry.kt (64%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/fact/IslandFactEntry.kt (79%) rename {adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter => extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc}/superiorskyblock/entries/group/IslandGroupEntry.kt (72%) rename {adapters/MythicMobsAdapter => extensions/SuperiorSkyblockExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/VaultExtension/build.gradle.kts rename adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/VaultAdapter.kt => extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/VaultInitializer.kt (68%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/action/DepositBalanceActionEntry.kt (58%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/action/SetPrefixActionEntry.kt (61%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/action/WithdrawBalanceActionEntry.kt (60%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/fact/BalanceFactEntry.kt (61%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/fact/PermissionFactEntry.kt (59%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/group/BalanceGroupEntry.kt (70%) rename {adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter => extensions/VaultExtension/src/main/kotlin/com/typewritermc}/vault/entries/group/PermissionGroupEntry.kt (79%) rename {adapters/RPGRegionsAdapter => extensions/VaultExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/WorldGuardExtension/build.gradle.kts rename {adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter => extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc}/worldguard/WorldGuardHandler.kt (54%) create mode 100644 extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardInitializer.kt rename {adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter => extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc}/worldguard/entries/audience/RegionAudienceEntry.kt (64%) rename {adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter => extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc}/worldguard/entries/event/EnterRegionEventEntry.kt (57%) rename {adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter => extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc}/worldguard/entries/event/ExitRegionEventEntry.kt (59%) rename {adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter => extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc}/worldguard/entries/fact/InRegionFact.kt (71%) rename {adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter => extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc}/worldguard/entries/group/RegionGroup.kt (77%) rename {adapters/SuperiorSkyblockAdapter => extensions/WorldGuardExtension}/src/main/templates/App.kt (100%) create mode 100644 extensions/_DocsExtension/build.gradle.kts create mode 100644 extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt (93%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt (88%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt (74%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt (73%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt (67%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt (77%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt (65%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt (65%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt (60%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt (66%) rename {adapters/_DocsAdapter => extensions/_DocsExtension}/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt (69%) rename {adapters/VaultAdapter => extensions/_DocsExtension}/src/main/templates/App.kt (100%) rename {adapters => extensions}/build.gradle.kts (57%) rename {adapters => extensions}/gradle/wrapper/gradle-wrapper.jar (100%) rename {adapters => extensions}/gradle/wrapper/gradle-wrapper.properties (100%) rename {adapters => extensions}/gradlew (100%) rename {adapters => extensions}/gradlew.bat (100%) create mode 100644 extensions/settings.gradle.kts delete mode 100644 jitpack.yml create mode 100644 module-plugin/api/build.gradle.kts create mode 100644 module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt create mode 100644 module-plugin/build.gradle.kts create mode 100644 module-plugin/extension-processor/build.gradle.kts create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/SharedJsonManager.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/DialogueMessengerProcessor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/EntryListenerProcessor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/ExtensionProcessor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/InitializerProcessor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/KSPExtensions.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/CustomEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataBlueprint.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifier.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/EntryProcessor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ColorEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CoordinateEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CronEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/DurationEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/FloatRangeEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ItemEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/MaterialEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/OptionalEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PositionEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PotionEffectTypeEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/RefEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SkinEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundIdEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundSourceEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/VectorEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/WorldEditor.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ColoredModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ContentEditorModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/GeneratedModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/HelpModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/IconModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MaterialPropertiesModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MultiLineModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/NegativeModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/OnlyTagsModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PageModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PlaceholderModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/RegexModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SegmentModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SizeModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SnakeCaseModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/WithRotationModifierComputer.kt create mode 100644 module-plugin/extension-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider rename {plugin => module-plugin}/gradle/wrapper/gradle-wrapper.jar (79%) rename {plugin => module-plugin}/gradle/wrapper/gradle-wrapper.properties (80%) rename {plugin => module-plugin}/gradlew (100%) rename {plugin => module-plugin}/gradlew.bat (100%) rename {adapters/CitizensAdapter => module-plugin}/settings.gradle.kts (53%) create mode 100644 module-plugin/src/main/kotlin/com/typewritermc/TypewriterModulePlugin.kt delete mode 100644 plugin/settings.gradle.kts delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/inventory/ItemExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/other/ConfigurationExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandController.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/world/BlockExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/world/EntityExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/world/LocationExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/NbtData.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/NbtDataAccessor.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/NbtDataLoader.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/NbtDataSerializer.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/NbtDataType.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataDecoder.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataEncoder.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtSerialization.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/utilities/Reflection.kt delete mode 100644 plugin/src/main/kotlin/lirand/api/utilities/Scope.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterListeners.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterLoader.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterMessenger.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/CustomEditors.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryAttributes.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryBlueprint.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/FieldModifiers.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/TypewriterAdapter.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ColorEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/CronEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/DurationEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/EntryReferenceEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/FloatRangeEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ItemEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/LocationEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/MaterialEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/OptionalEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/PotionEffectTypeEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SkinEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundIdEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundSourceEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/VectorEditor.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ColoredModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ContentEditorModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/GeneratedModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/HelpModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/Icon.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MaterialModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MultiLineModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/NegativeModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/OnlyTagsModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PageModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PlaceholderModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/RegexModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SegmentModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SizeModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SnakeCaseModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/StaticModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/WithRotationModifierComputer.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CachedInventoryComponent.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/ImmediateFieldValueContentMode.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryDatabase.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryListeners.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryMigration.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/PageMigrator.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityAttribute.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityStorage.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/LocationProperty.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/DialogueEntry.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/events/TypewriterReloadEvent.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/extensions/bstats/BStatsMetrics.kt delete mode 100644 plugin/src/main/kotlin/me/gabber235/typewriter/utils/ServerCommandMap.kt delete mode 100644 plugin/src/main/resources/plugin.yml diff --git a/.github/actions/build-adapter/action.yml b/.github/actions/build-adapter/action.yml deleted file mode 100644 index 7513c89ea7..0000000000 --- a/.github/actions/build-adapter/action.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "Build Adapter" -description: "Builds the adapter and runs tests" - -inputs: - adapter: - required: true - description: "Name of the adapter to build" - -runs: - using: "composite" - steps: - - name: Test Adapter - uses: gradle/gradle-build-action@v2 - with: - arguments: :${{ inputs.adapter }}:test --scan - build-root-directory: ./adapters - - name: Build Adapter - uses: gradle/gradle-build-action@v2 - with: - arguments: :${{ inputs.adapter }}:buildRelease --scan - build-root-directory: ./adapters - diff --git a/.github/actions/build-plugin/action.yml b/.github/actions/build-engine/action.yml similarity index 76% rename from .github/actions/build-plugin/action.yml rename to .github/actions/build-engine/action.yml index 2a460b490c..b4a66bf0b3 100644 --- a/.github/actions/build-plugin/action.yml +++ b/.github/actions/build-engine/action.yml @@ -1,4 +1,4 @@ -name: Build Plugin +name: Build Paper Engine description: "Builds the plugin and runs tests" runs: @@ -24,14 +24,14 @@ runs: run: flutter build web --release shell: bash working-directory: ./app - - name: Test Plugin + - name: Test Paper Engine uses: gradle/gradle-build-action@v2 with: - arguments: test --scan - build-root-directory: ./plugin + arguments: paper-engine:test --scan + build-root-directory: ./engine - name: Build Plugin uses: gradle/gradle-build-action@v2 with: - arguments: buildRelease --scan - build-root-directory: ./plugin + arguments: paper-engine:buildRelease --scan + build-root-directory: ./engine diff --git a/.github/actions/build-extension/action.yml b/.github/actions/build-extension/action.yml new file mode 100644 index 0000000000..ce702b8962 --- /dev/null +++ b/.github/actions/build-extension/action.yml @@ -0,0 +1,22 @@ +name: "Build Extension" +description: "Builds the extension" + +inputs: + extension: + required: true + description: "Name of the extension to build" + +runs: + using: "composite" + steps: + - name: Test extension + uses: gradle/gradle-build-action@v2 + with: + arguments: :${{ inputs.extension }}:test --scan + build-root-directory: ./extensions + - name: Build Adapter + uses: gradle/gradle-build-action@v2 + with: + arguments: :${{ inputs.extension }}:buildRelease --scan + build-root-directory: ./extensions + diff --git a/.github/workflows/build-adapter.yml b/.github/workflows/build-adapter.yml deleted file mode 100644 index 2f7502217f..0000000000 --- a/.github/workflows/build-adapter.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Build Specified Adapter - -on: - workflow_call: - inputs: - adapter: - required: true - type: string - description: The name of the adapter to build - -jobs: - build-adapter: - name: Build ${{ inputs.adapter }} Adapter - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 21 - - name: Build Adapter - uses: ./.github/actions/build-adapter - with: - adapter: ${{ inputs.adapter }} - - name: Upload Adapter - uses: actions/upload-artifact@v2 - with: - name: ${{ inputs.adapter }}.jar - path: adapters/${{ inputs.adapter }}/build/libs/${{ inputs.adapter }}.jar diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 0b53429ad8..6f2f9ef0f3 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -24,44 +24,62 @@ jobs: full_version="${version}-beta-${run_number}" echo $full_version > version.txt echo "version=$full_version" >> $GITHUB_OUTPUT - - name: Build Plugin - uses: ./.github/actions/build-plugin - - name: Build Basic Adapter - uses: ./.github/actions/build-adapter + - name: Build Engine + uses: ./.github/actions/build-engine +# ---------------------------------------------------------------------------------------------------- + - name: Build Basic Extension + uses: ./.github/actions/build-extension with: - adapter: BasicAdapter - - name: Build Citizens Adapter - uses: ./.github/actions/build-adapter + extension: BasicExtension + - name: Build Citizens Extension + uses: ./.github/actions/build-extension with: - adapter: CitizensAdapter - - name: Build CombatLogX Adapter - uses: ./.github/actions/build-adapter + extension: CitizensExtension + - name: Build CombatLogX Extension + uses: ./.github/actions/build-extension with: - adapter: CombatLogXAdapter - - name: Build MythicMobs Adapter - uses: ./.github/actions/build-adapter + extension: CombatLogXExtension + - name: Build MythicMobs Extension + uses: ./.github/actions/build-extension with: - adapter: MythicMobsAdapter - - name: Build EntityAdapter - uses: ./.github/actions/build-adapter + extension: MythicMobsExtension + - name: Build EntityExtension + uses: ./.github/actions/build-extension with: - adapter: EntityAdapter - - name: Build RPGRegions Adapter - uses: ./.github/actions/build-adapter + extension: EntityExtension + - name: Build RPGRegions Extension + uses: ./.github/actions/build-extension with: - adapter: RPGRegionsAdapter - - name: Build SuperiorSkyblock Adapter - uses: ./.github/actions/build-adapter + extension: RPGRegionsExtension + - name: Build SuperiorSkyblock Extension + uses: ./.github/actions/build-extension with: - adapter: SuperiorSkyblockAdapter - - name: Build Vault Adapter - uses: ./.github/actions/build-adapter + extension: SuperiorSkyblockExtension + - name: Build Vault Extension + uses: ./.github/actions/build-extension with: - adapter: VaultAdapter - - name: Build WorldGuard Adapter - uses: ./.github/actions/build-adapter + extension: VaultExtension + - name: Build WorldGuard Extension + uses: ./.github/actions/build-extension with: - adapter: WorldGuardAdapter + extension: WorldGuardExtension +# ---------------------------------------------------------------------------------------------------- + - name: Publish Engine to Beta Maven Repository + uses: gradle/gradle-build-action@v2 + with: + arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan + build-root-directory: ./engine + - name: Publish All Extensions to Beta Maven Repository + uses: gradle/gradle-build-action@v2 + with: + arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan + build-root-directory: ./extensions + - name: Publish Module-Plugin to Beta Maven Repository + uses: gradle/gradle-build-action@v2 + with: + arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan + build-root-directory: ./module-plugin +# ---------------------------------------------------------------------------------------------------- - name: Publish Modrinth uses: Kir-Antipov/mc-publish@v3.3 id: publish @@ -71,13 +89,12 @@ jobs: modrinth-featured: false files: | plugin/build/libs/typewriter.jar - adapters/**/build/libs/*.jar + extensions/**/build/libs/*.jar name: "Typewriter v${{ steps.vars.outputs.version }} Development Build" version: "${{ steps.vars.outputs.version }}" version-type: "beta" loaders: | paper - purpur game-versions: | [1.21] dependencies: | @@ -92,11 +109,12 @@ jobs: arguments: publishPluginPublicationToHangar --scan build-root-directory: ./plugin - name: Add Tag - uses: laputansoft/github-tag-action@v4.6 + uses: mathieudutour/github-tag-action@v6.2 with: github_token: ${{ env.github-token }} default_bump: false - tag: "v${{ steps.vars.outputs.version }}" + custom_tag: "${{ steps.vars.outputs.version }}" + release_branches: develop - name: Notify Discord uses: sarisia/actions-status-discord@v1 with: diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml index eb941e60fb..a57097772e 100644 --- a/.github/workflows/build-documentation.yml +++ b/.github/workflows/build-documentation.yml @@ -11,7 +11,7 @@ on: jobs: deploy: name: Deploy to GitHub Pages - runs-on: self-hosted + runs-on: arc-runner-set steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 diff --git a/.github/workflows/build-plugin.yml b/.github/workflows/build-engine.yml similarity index 62% rename from .github/workflows/build-plugin.yml rename to .github/workflows/build-engine.yml index 45366785c9..3ac2f8223a 100644 --- a/.github/workflows/build-plugin.yml +++ b/.github/workflows/build-engine.yml @@ -1,4 +1,4 @@ -name: Build Typewriter Plugin +name: Build Typewriter Engine on: [workflow_call] @@ -12,10 +12,10 @@ jobs: with: distribution: temurin java-version: 21 - - name: Build Plugin - uses: ./.github/actions/build-plugin + - name: Build Engine + uses: ./.github/actions/build-engine - name: Upload Plugin uses: actions/upload-artifact@v2 with: - name: typewriter.jar - path: plugin/build/libs/typewriter.jar + name: Typewriter.jar + path: engine/engine-paper/build/libs/Typewriter.jar diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml new file mode 100644 index 0000000000..b3cf8f851e --- /dev/null +++ b/.github/workflows/build-extension.yml @@ -0,0 +1,30 @@ +name: Build Specified Extension + +on: + workflow_call: + inputs: + extension: + required: true + type: string + description: The name of the extension to build + +jobs: + build-adapter: + name: Build ${{ inputs.extension }} Extension + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 21 + - name: Build Adapter + uses: ./.github/actions/build-extension + with: + extension: ${{ inputs.extension }} + - name: Upload Extension + uses: actions/upload-artifact@v2 + with: + name: ${{ inputs.extension }}.jar + path: adapters/${{ inputs.extension }}/build/libs/${{ inputs.extension }}.jar diff --git a/.github/workflows/build-jars-on-push.yml b/.github/workflows/build-jars-on-push.yml deleted file mode 100644 index 5e068f6b5b..0000000000 --- a/.github/workflows/build-jars-on-push.yml +++ /dev/null @@ -1,138 +0,0 @@ -name: Build Jars on Push - -on: - push: - branches: - - feature/** - -jobs: - changes: - runs-on: self-hosted - outputs: - plugin: ${{ steps.changes.outputs.plugin }} - steps: - - uses: actions/checkout@v3 - - uses: dorny/paths-filter@v2 - id: changes - with: - filters: | - plugin: - - plugin/** - - app/** - basic_adapter: - - adapters/BasicAdapter/** - citizens_adapter: - - adapters/CitizensAdapter/** - combat_log_x_adapter: - - adapters/CombatLogXAdapter/** - entity_adapter: - - adapters/EntityAdapter/** - mythic_mobs_adapter: - - adapters/MythicMobsAdapter/** - rpg_regions_adapter: - - adapters/RPGRegionsAdapter/** - superior_skyblock_adapter: - - adapters/SuperiorSkyblockAdapter/** - vault_adapter: - - adapters/VaultAdapter/** - worldguard_adapter: - - adapters/WorldGuardAdapter/** - znpcs_adapter: - - adapters/ZNPCsPlusAdapter/** - fancynpcs_adapter: - - adapters/FancyNpcsAdapter/** - - build-plugin: - name: Build Typewriter Plugin - needs: changes - if: needs.changes.outputs.plugin == 'true' - uses: ./.github/workflows/build-plugin.yml - - build-adapter-basic: - name: Build Basic Adapter - needs: changes - if: needs.changes.outputs.basic_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: BasicAdapter - - build-adapter-citizens: - name: Build Citizens Adapter - needs: changes - if: needs.changes.outputs.citizens_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: CitizensAdapter - - - build-adapter-combat-log-x: - name: Build CombatLogX Adapter - needs: changes - if: needs.changes.outputs.combat_log_x_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: CombatLogXAdapter - - build-adapter-entity: - name: Build EntityAdapter - needs: changes - if: needs.changes.outputs.entity_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: EntityAdapter - - build-adapter-mythic-mobs: - name: Build MythicMobs Adapter - needs: changes - if: needs.changes.outputs.mythic_mobs_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: MythicMobsAdapter - - build-adapter-rpg-regions: - name: Build RPGRegions Adapter - needs: changes - if: needs.changes.outputs.rpg_regions_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: RPGRegionsAdapter - - build-adapter-superior-skyblock: - name: Build SuperiorSkyblock Adapter - needs: changes - if: needs.changes.outputs.superior_skyblock_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: SuperiorSkyblockAdapter - - build-adapter-vault: - name: Build Vault Adapter - needs: changes - if: needs.changes.outputs.vault_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: VaultAdapter - - build-adapter-worldguard: - name: Build WorldGuard Adapter - needs: changes - if: needs.changes.outputs.world_guard_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: WorldGuardAdapter - - build-adapter-znpcs: - name: Build ZNPCsPlus Adapter - needs: changes - if: needs.changes.outputs.znpcs_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: ZNPCsPlusAdapter - - build-adapter-fancynpcs: - name: Build FancyNpcs Adapter - needs: changes - if: needs.changes.outputs.fancynpcs_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: FancyNpcsAdapter diff --git a/.github/workflows/build-jars-on-request.yml b/.github/workflows/build-jars-on-request.yml index 75bdf6eaa4..9dc7dad3d8 100644 --- a/.github/workflows/build-jars-on-request.yml +++ b/.github/workflows/build-jars-on-request.yml @@ -3,73 +3,61 @@ name: Build Jars on Request on: [workflow_dispatch] jobs: - build-plugin: - name: Build Typewriter Plugin - uses: ./.github/workflows/build-plugin.yml + build-engine: + name: Build Typewriter Engine + uses: ./.github/workflows/build-engine.yml - build-adapter-basic: - name: Build Basic Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-basic: + name: Build Basic Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: BasicAdapter + extension: BasicExtension - build-adapter-citizens: - name: Build Citizens Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-citizens: + name: Build Citizens Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: CitizensAdapter + extension: CitizensExtension - build-adapter-combat-log-x: - name: Build CombatLogX Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-combat-log-x: + name: Build CombatLogX Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: CombatLogXAdapter + extension: CombatLogXExtension - build-adapter-entity: - name: Build EntityAdapter - uses: ./.github/workflows/build-adapter.yml + build-extension-entity: + name: Build EntityExtension + uses: ./.github/workflows/build-extension.yml with: - adapter: EntityAdapter + extension: EntityExtension - build-adapter-mythic-mobs: - name: Build MythicMobs Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-mythic-mobs: + name: Build MythicMobs Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: MythicMobsAdapter + extension: MythicMobsExtension - build-adapter-rpg-regions: - name: Build RPGRegions Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-rpg-regions: + name: Build RPGRegions Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: RPGRegionsAdapter + extension: RPGRegionsExtension - build-adapter-superior-skyblock: - name: Build SuperiorSkyblock Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-superior-skyblock: + name: Build SuperiorSkyblock Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: SuperiorSkyblockAdapter + extension: SuperiorSkyblockExtension - build-adapter-vault: - name: Build Vault Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-vault: + name: Build Vault Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: VaultAdapter + extension: VaultExtension - build-adapter-worldguard: - name: Build WorldGuard Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-worldguard: + name: Build WorldGuard Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: WorldGuardAdapter - - build-adapter-znpcs: - name: Build ZNPCsPlus Adapter - uses: ./.github/workflows/build-adapter.yml - with: - adapter: ZNPCsPlusAdapter - - build-adapter-fancynpcs: - name: Build FancyNpcs Adapter - uses: ./.github/workflows/build-adapter.yml - with: - adapter: FancyNpcsAdapter + extension: WorldGuardExtension diff --git a/.gitignore b/.gitignore index 1093ab3e7f..90ca0cde7e 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,7 @@ run/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar -/plugin/server +/server/ .DS_Store # Rust diff --git a/adapters/BasicAdapter/build.gradle.kts b/adapters/BasicAdapter/build.gradle.kts deleted file mode 100644 index 0cda5ef4ab..0000000000 --- a/adapters/BasicAdapter/build.gradle.kts +++ /dev/null @@ -1,2 +0,0 @@ -repositories { } -dependencies { } \ No newline at end of file diff --git a/adapters/BasicAdapter/settings.gradle.kts b/adapters/BasicAdapter/settings.gradle.kts deleted file mode 100644 index 8b09043a96..0000000000 --- a/adapters/BasicAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "BasicAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt deleted file mode 100644 index 74c454ddd6..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt +++ /dev/null @@ -1,19 +0,0 @@ -package me.gabber235.typewriter - -import App -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter - -@Adapter("Basic", "For all the most basic entries", App.VERSION) -/** - * The Basic Adapter contains all the essential entries for Typewriter. - * In most cases, it should be installed with Typewriter. - * If you haven't installed Typewriter or the adapter yet, - * please follow the [Installation Guide](../../docs/02-getting-started/01-installation.mdx) - * first. - */ -object BasicAdapter : TypewriterAdapter() { - override fun initialize() { - - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt deleted file mode 100644 index c441a948e7..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt +++ /dev/null @@ -1,74 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.optional -import org.bukkit.Location -import org.bukkit.Material -import org.bukkit.entity.Player -import java.util.* - -@Entry("drop_item", "Drop an item at location, or on player", Colors.RED, "fa-brands:dropbox") -/** - * The `Drop Item Action` is an action that drops an item in the world. - * This action provides you with the ability to drop an item with a specified Minecraft material, amount, display name, lore, and location. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. - * You can use it to create treasure chests with randomized items, drop loot from defeated enemies, or spawn custom items in the world. - * The possibilities are endless! - */ -class DropItemActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("The item to drop.") - val item: Item = Item.Empty, - @Help("The location to drop the item. (Defaults to the player's location)") - // The location to drop the item at. If this field is left blank, the item will be dropped at the location of the player triggering the action. - private val location: Optional = Optional.empty(), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - // Run on main thread - SYNC.launch { - if (location.isPresent) { - location.get().world.dropItem(location.get(), item.build(player)) - } else { - player.location.world.dropItem(player.location, item.build(player)) - } - } - } -} - -@EntryMigration(DropItemActionEntry::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "amount", "displayName", "lore"]) -fun migrate040DropItemAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "amount", "displayName", "lore") - - val material = json.getAndParse("material", context.gson).optional - val amount = json.getAndParse("amount", context.gson).optional - val displayName = json.getAndParse("displayName", context.gson).optional - val lore = json.getAndParse("lore", context.gson).optional - - val item = Item( - material = material, - amount = amount, - name = displayName, - lore = lore, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt deleted file mode 100644 index 147da37915..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt +++ /dev/null @@ -1,63 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.optional -import org.bukkit.Material -import org.bukkit.entity.Player - -@Entry("give_item", "Give an item to the player", Colors.RED, "streamline:give-gift-solid") -/** - * The `Give Item Action` is an action that gives a player an item. This action provides you with the ability to give an item with a specified Minecraft material, amount, display name, and lore. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to give players rewards for completing quests, unlockables for reaching certain milestones, or any other custom items you want to give players. The possibilities are endless! - */ -class GiveItemActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("The item to give.") - val item: Item = Item.Empty, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - SYNC.launch { - player.inventory.addItem(item.build(player)) - } - } -} - -@EntryMigration(GiveItemActionEntry::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "amount", "displayName", "lore"]) -fun migrate040GiveItemAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "amount", "displayName", "lore") - - val material = json.getAndParse("material", context.gson).optional - val amount = json.getAndParse("amount", context.gson).optional - val displayName = json.getAndParse("displayName", context.gson).optional - val lore = json.getAndParse("lore", context.gson).optional - - val item = Item( - material = material, - amount = amount, - name = displayName, - lore = lore, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt deleted file mode 100644 index 303e70152d..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt +++ /dev/null @@ -1,61 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.* -import org.bukkit.Location -import org.bukkit.entity.Player -import java.util.* -import kotlin.jvm.optionals.getOrDefault - -@Entry("play_sound", "Play sound at player, or location", Colors.RED, "fa6-solid:volume-high") -/** - * The `Play Sound Action` is an action that plays a sound for the player. This action provides you with the ability to play any sound that is available in Minecraft, at a specified location. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to provide audio feedback to players, such as when they successfully complete a challenge, or to create ambiance in your Minecraft world, such as by playing background music or sound effects. The possibilities are endless! - */ -class PlaySoundActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("The sound to play.") - val sound: Sound = Sound.EMPTY, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - player.playSound(sound) - } -} - -@EntryMigration(PlaySoundActionEntry::class, "0.4.0") -@NeedsMigrationIfNotParsable -fun migrate040PlaySoundAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "sound", "location", "volume", "pitch") - - val soundString = json.getAndParse("sound", context.gson).optional - val location = json.getAndParse>("location", context.gson).optional - val volume = json.getAndParse("volume", context.gson).optional - val pitch = json.getAndParse("pitch", context.gson).optional - - val sound = Sound( - soundId = soundString.map(::DefaultSoundId).getOrDefault(SoundId.EMPTY), - soundSource = location.map(::LocationSoundSource).getOrDefault(SelfSoundSource), - volume = volume.orElse(1.0f), - pitch = pitch.orElse(1.0f), - ) - - data["sound"] = context.gson.toJsonTree(sound) - - return data -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt deleted file mode 100644 index 09e97826e4..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt +++ /dev/null @@ -1,32 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.PathStreamDisplay -import org.bukkit.Location - -@Entry( - "direct_location_path_stream", - "A Path Stream to a Direct Location", - Colors.GREEN, - "material-symbols:conversion-path" -) -/** - * The `Direct Location Path Stream` entry is a path stream that shows the path to a specific location. - * When the player has this entry, a path stream will be displayed to the specified location. - * - * ## How could this be used? - * This could be used to show a path to a specific location in the world. - */ -class DirectLocationPathStream( - override val id: String = "", - override val name: String = "", - val road: Ref = emptyRef(), - val targetLocation: Location = Location(null, 0.0, 0.0, 0.0), -) : AudienceEntry { - override fun display(): AudienceDisplay = PathStreamDisplay(road, endLocation = { targetLocation }) -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt deleted file mode 100644 index c5b2c8652c..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt +++ /dev/null @@ -1,116 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.utils.* -import org.bukkit.entity.Player -import kotlin.jvm.optionals.getOrDefault -import net.kyori.adventure.sound.Sound as AdventureSound - -@Entry("sound_cinematic", "Play a sound during a cinematic", Colors.YELLOW, "fa6-solid:music") -/** - * The `Sound Cinematic` entry plays a sound during a cinematic. - * - * ## How could this be used? - * - * This entry could be used to play a sound during a cinematic, such as a sound effect for a cutscene. - */ -class SoundCinematicEntry( - override val id: String, - override val name: String, - override val criteria: List, - @Segments(icon = "fa6-solid:music", color = Colors.YELLOW) - val segments: List, -) : CinematicEntry { - override fun create(player: Player): CinematicAction { - return SoundCinematicAction( - player, - this, - ) - } -} - -data class SoundSegment( - override val startFrame: Int, - override val endFrame: Int, - @Help("The sound to play") - val sound: Sound, -) : Segment - -class SoundCinematicAction( - private val player: Player, - private val entry: SoundCinematicEntry, -) : SimpleCinematicAction() { - - override val segments: List = entry.segments - - override suspend fun startSegment(segment: SoundSegment) { - super.startSegment(segment) - player.playSound(segment.sound) - } - - override suspend fun stopSegment(segment: SoundSegment) { - super.stopSegment(segment) - player.stopSound(segment.sound) - } - -} - -@EntryMigration(SoundCinematicEntry::class, "0.4.0") -@NeedsMigrationIfNotParsable -fun migrate040SoundCinematic(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "segments", "channel") - - val channel = json.getAndParse("channel", context.gson).optional - - val segmentsJson = json["segments"] - if (segmentsJson?.isJsonArray == true) { - logger.severe("Tried migrating sound cinematic entry ${json["name"]}, but segments were not an array.") - return data - } - - val segmentsArray = segmentsJson?.asJsonArray ?: JsonArray() - - val segments = segmentsArray.mapNotNull { - if (!it.isJsonObject) { - logger.severe("Tried migrating sound cinematic entry ${json["name"]}, but segment was not an object.") - return@mapNotNull null - } - - val segmentJson = it.asJsonObject - val startFrame = segmentJson.getAndParse("startFrame", context.gson).optional - val endFrame = segmentJson.getAndParse("endFrame", context.gson).optional - val sound = segmentJson.getAndParse("sound", context.gson).optional - val volume = segmentJson.getAndParse("volume", context.gson).optional - val pitch = segmentJson.getAndParse("pitch", context.gson).optional - - SoundSegment( - startFrame = startFrame.getOrDefault(0), - endFrame = endFrame.getOrDefault(0), - sound = Sound( - soundId = sound.map(::DefaultSoundId).getOrDefault(SoundId.EMPTY), - soundSource = SelfSoundSource, - track = channel.getOrDefault(AdventureSound.Source.MASTER), - volume = volume.getOrDefault(1.0f), - pitch = pitch.getOrDefault(1.0f), - ) - ) - } - - data["segments"] = context.gson.toJsonTree(segments) - - - return data -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerJoinEventEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerJoinEventEntry.kt deleted file mode 100644 index 7e6f8a65fb..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerJoinEventEntry.kt +++ /dev/null @@ -1,26 +0,0 @@ -package me.gabber235.typewriter.entries.event - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry -import org.bukkit.event.player.PlayerJoinEvent - -@Entry("on_player_join", "When the player joins the server", Colors.YELLOW, "fluent:person-add-20-filled") -/** - * The `Player Join Event` event is called when a player joins the server. - * - * ## How could this be used? - * - * This could be used with [facts](/docs/creating-stories/facts) to give a new player a welcome message, or welcome back new players. You can also use it to give new players a starting item, or to give them a starting amount of money with the [Vault adapter](/adapters/VaultAdapter). - */ -class PlayerJoinEventEntry( - override val id: String = "", - override val name: String = "", - override val triggers: List> = emptyList(), -) : EventEntry - -@EntryListener(PlayerJoinEventEntry::class) -fun onJoin(event: PlayerJoinEvent, query: Query) { - query.find() triggerAllFor event.player -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerNearLocationEventEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerNearLocationEventEntry.kt deleted file mode 100644 index 165ee5006d..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/PlayerNearLocationEventEntry.kt +++ /dev/null @@ -1,62 +0,0 @@ -package me.gabber235.typewriter.entries.event - -import lirand.api.extensions.math.blockLocation -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Min -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EmptyTrigger -import me.gabber235.typewriter.entry.entries.EventEntry -import org.bukkit.Location -import org.bukkit.event.EventHandler -import org.bukkit.event.player.PlayerMoveEvent -import org.bukkit.event.player.PlayerTeleportEvent - -@Entry("on_player_near_location", "When the player is near a certain location", Colors.YELLOW, "mdi:map-marker-radius") -/** - * The `PlayerNearLocationEventEntry` class represents an event that is triggered when a player is within a certain range of a location. - * - * ## How could this be used? - * - * This could be used to create immersive gameplay experiences such as triggering a special event or dialogue when a player approaches a specific location. - * For example, when a player gets close to a hidden treasure, a hint could be revealed or a guardian could spawn. - */ -class PlayerNearLocationEventEntry( - override val id: String = "", - override val name: String = "", - override val triggers: List> = emptyList(), - @Help("The location the player should be near.") - val location: Location = Location(null, 0.0, 0.0, 0.0), - @Help("The range within which the event should trigger.") - @Min(1) - val range: Double = 1.0 -) : EventEntry - -@EntryListener(PlayerNearLocationEventEntry::class) -fun onPlayerNearLocation(event: PlayerMoveEvent, query: Query) { - // Only check if the player moved a block - if (!event.hasChangedBlock()) return - - query findWhere { entry -> - !event.from.blockLocation.isInRange( - entry.location, - entry.range - ) && event.to.blockLocation.isInRange(entry.location, entry.range) - } triggerAllFor event.player -} - -@EntryListener(PlayerNearLocationEventEntry::class) -fun onPlayerTeleportNearLocation(event: PlayerTeleportEvent, query: Query) { - query findWhere { entry -> - !event.from.blockLocation.isInRange( - entry.location, - entry.range - ) && event.to.blockLocation.isInRange(entry.location, entry.range) - } triggerAllFor event.player -} - -fun Location.isInRange(location: Location, range: Double): Boolean { - if (location.world != world) return false - return this.distanceSquared(location) <= range * range -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/fact/InventoryItemCountFact.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/fact/InventoryItemCountFact.kt deleted file mode 100644 index 6891dbf168..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/fact/InventoryItemCountFact.kt +++ /dev/null @@ -1,64 +0,0 @@ -package me.gabber235.typewriter.entries.fact - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.optional -import org.bukkit.Material -import org.bukkit.entity.Player -import java.util.* - -@Entry( - "inventory_item_count_fact", - "The amount of a specific item in the player's inventory", - Colors.PURPLE, - "fa6-solid:bag-shopping" -) -/** - * The `Inventory Item Count Fact` is a fact that returns the amount of a specific item in the player's inventory. - * - * - * - * ## How could this be used? - * - * This could be used to check if the player has a specific item in their inventory, or to check if they have a specific amount of an item. - * Like giving the player a quest to collect 10 apples, and then checking if they have 10 apples in their inventory. - */ -class InventoryItemCountFact( - override val id: String = "", - override val name: String = "", - override val comment: String = "", - override val group: Ref = emptyRef(), - @Help("The item to check for.") - val item: Item = Item.Empty, -) : ReadableFactEntry { - override fun readSinglePlayer(player: Player): FactData { - val amount = player.inventory.contents.filterNotNull().filter { item.isSameAs(player, it) }.sumOf { it.amount } - return FactData(amount) - } -} - -@EntryMigration(InventoryItemCountFact::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "itemName"]) -fun migrate040InventoryItemCount(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "itemName") - - val material = json.getAndParse>("material", context.gson).optional - val displayName = json.getAndParse>("itemName", context.gson).optional - - val item = Item( - material = material, - name = displayName, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/static/SimpleSpeakerEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/static/SimpleSpeakerEntry.kt deleted file mode 100644 index 53f2630c1e..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/static/SimpleSpeakerEntry.kt +++ /dev/null @@ -1,45 +0,0 @@ -package me.gabber235.typewriter.entries.static - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.utils.* -import kotlin.jvm.optionals.getOrDefault - -@Entry("simple_speaker", "The most basic speaker", Colors.ORANGE, "bi:person-fill") -/** - * The `Spoken Dialogue Action` is an action that displays an animated message to the player. This action provides you with the ability to display a message with a specified speaker, text, and duration. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to create storylines, provide instructions to players, or create immersive roleplay experiences. The possibilities are endless! - */ -class SimpleSpeakerEntry( - override val id: String = "", - override val name: String = "", - override val displayName: String = "", - override val sound: Sound = Sound.EMPTY, -) : SpeakerEntry, StaticEntry - -@EntryMigration(SimpleSpeakerEntry::class, "0.4.0") -@NeedsMigrationIfNotParsable -fun migrate040SimpleSpeaker(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "sound") - - val soundId = json.getAndParse("sound", context.gson).optional - - val sound = Sound( - soundId = soundId.map(::DefaultSoundId).getOrDefault(SoundId.EMPTY), - soundSource = SelfSoundSource, - volume = 1.0f, - pitch = 1.0f, - ) - - data["sound"] = context.gson.toJsonTree(sound) - - return data -} diff --git a/adapters/CitizensAdapter/build.gradle.kts b/adapters/CitizensAdapter/build.gradle.kts deleted file mode 100644 index 4d9cf263d2..0000000000 --- a/adapters/CitizensAdapter/build.gradle.kts +++ /dev/null @@ -1,10 +0,0 @@ -repositories { - maven("https://repo.citizensnpcs.co/") -} - -dependencies { - // External dependencies - compileOnly("net.citizensnpcs:citizens-main:2.0.33-SNAPSHOT") { - exclude(group = "*", module = "*") - } -} diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/CitizensAdapter.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/CitizensAdapter.kt deleted file mode 100644 index 038eaafee6..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/CitizensAdapter.kt +++ /dev/null @@ -1,58 +0,0 @@ -package me.gabber235.typewriter.citizens - -import App -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Unsupported -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import net.citizensnpcs.api.CitizensAPI -import net.citizensnpcs.api.npc.MemoryNPCDataStore -import net.citizensnpcs.api.npc.NPC -import net.citizensnpcs.api.npc.NPCDataStore -import net.citizensnpcs.api.npc.NPCRegistry -import net.citizensnpcs.api.trait.TraitInfo - -@Unsupported -@Adapter("Citizens", "For the Citizens plugin", App.VERSION) -/** - * The Citizens adapter allows you to create custom interactions with NPCs. - */ -object CitizensAdapter : TypewriterAdapter() { - private var tmpRegistry: NPCRegistry? = null - val temporaryRegistry: NPCRegistry - get() = tmpRegistry ?: CitizensAPI.createAnonymousNPCRegistry(MemoryNPCDataStore()).also { tmpRegistry = it } - - override fun initialize() { - if (!plugin.server.pluginManager.isPluginEnabled("Citizens")) { - logger.warning("Citizens plugin not found, try installing it or disabling the Citizens adapter") - return - } - - CitizensAPI.getTraitFactory().registerTrait(TraitInfo.create(TypewriterTrait::class.java)) - tmpRegistry = CitizensAPI.createAnonymousNPCRegistry(MemoryNPCDataStore(23500)) - } - - override fun shutdown() { - // If citizens is not enabled, we don't need to do anything - if (!CitizensAPI.hasImplementation()) return - CitizensAPI.getTraitFactory().deregisterTrait(TraitInfo.create(TypewriterTrait::class.java)) - tmpRegistry?.deregisterAll() - tmpRegistry = null - } -} - - -class MemoryNPCDataStore(private var lastID: Int = 0) : NPCDataStore { - override fun clearData(npc: NPC) {} - override fun createUniqueNPCId(registry: NPCRegistry): Int { - return lastID++ - } - - override fun loadInto(registry: NPCRegistry) {} - override fun saveToDisk() {} - override fun saveToDiskImmediate() {} - override fun store(npc: NPC) {} - override fun storeAll(registry: NPCRegistry) {} - override fun reloadFromSource() {} -} \ No newline at end of file diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/TypewriterTrait.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/TypewriterTrait.kt deleted file mode 100644 index 260fb2bdfd..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/TypewriterTrait.kt +++ /dev/null @@ -1,13 +0,0 @@ -package me.gabber235.typewriter.citizens - -import me.gabber235.typewriter.entry.* -import net.citizensnpcs.api.persistence.Persist -import net.citizensnpcs.api.trait.Trait -import net.citizensnpcs.api.trait.TraitName - -@TraitName("typewriter") -class TypewriterTrait : Trait("typewriter") { - - @Persist - var identifier: String = "" -} diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/artifact/NpcMovementArtifact.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/artifact/NpcMovementArtifact.kt deleted file mode 100644 index 6509024489..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/artifact/NpcMovementArtifact.kt +++ /dev/null @@ -1,36 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.artifact - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.ArtifactEntry -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import org.bukkit.Location -import org.bukkit.inventory.ItemStack - -@Deprecated("Use the EntityAdapter instead") -@Entry("npc_movement_artifact", "Movement data for an npc", Colors.PINK, "fa6-solid:person-walking") -@Tags("npc_movement_artifact") -/** - * The `Npc Movement Artifact` is an artifact that stores the movement data of an NPC. - * There is no reason to create this on its own. - * It should always be connected to another entry - */ -class CitizensNpcMovementArtifact( - override val id: String = "", - override val name: String = "", - override val artifactId: String = "", -) : ArtifactEntry - -data class NpcFrame( - val location: Location?, - val sneaking: Boolean?, - val swing: ArmSwing?, - - val mainHand: ItemStack?, - val offHand: ItemStack?, - val helmet: ItemStack?, - val chestplate: ItemStack?, - val leggings: ItemStack?, - val boots: ItemStack?, -) diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/CitizensNpcData.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/CitizensNpcData.kt deleted file mode 100644 index f0c5463917..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/CitizensNpcData.kt +++ /dev/null @@ -1,155 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.cinematic - -import me.gabber235.typewriter.citizens.CitizensAdapter.temporaryRegistry -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.utils.ThreadType -import net.citizensnpcs.api.CitizensAPI -import net.citizensnpcs.api.npc.NPC -import net.citizensnpcs.api.trait.trait.Equipment -import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot.* -import net.citizensnpcs.api.trait.trait.MobType -import net.citizensnpcs.api.trait.trait.PlayerFilter -import net.citizensnpcs.trait.HologramTrait -import net.citizensnpcs.trait.SkinTrait -import net.citizensnpcs.trait.SneakTrait -import org.bukkit.Location -import org.bukkit.entity.EntityType -import org.bukkit.entity.LivingEntity -import org.bukkit.entity.Player -import org.bukkit.inventory.EquipmentSlot -import org.bukkit.inventory.ItemStack - - -interface CitizensNpcData : NpcData { - override val threadType: ThreadType - get() = ThreadType.SYNC - - override fun spawn(player: Player, npc: NPC, location: Location) { - val filter = npc.getOrAddTrait(PlayerFilter::class.java) - filter.setAllowlist() - filter.addPlayer(player.uniqueId) - npc.spawn(location) - } - - override fun handleMovement(player: Player, npc: NPC, location: Location) { - npc.entity?.teleport(location) - } - - override fun handleSneaking(player: Player, npc: NPC, sneaking: Boolean) { - val sneakingTrait = npc.getOrAddTrait(SneakTrait::class.java) - if (sneakingTrait.isSneaking != sneaking) { - sneakingTrait.isSneaking = sneaking - } - } - - override fun handlePunching(player: Player, npc: NPC, punching: ArmSwing) { - val entity = npc.entity ?: return - if (entity !is LivingEntity) return - if (punching.swingLeft) entity.swingOffHand() - if (punching.swingRight) entity.swingMainHand() - } - - override fun handleInventory(player: Player, npc: NPC, slot: EquipmentSlot, itemStack: ItemStack) { - val equipmentTrait: Equipment = npc.getOrAddTrait(Equipment::class.java) - val citizensSlot = when (slot) { - EquipmentSlot.HAND -> HAND - EquipmentSlot.OFF_HAND -> OFF_HAND - EquipmentSlot.HEAD -> HELMET - EquipmentSlot.CHEST -> CHESTPLATE - EquipmentSlot.LEGS -> LEGGINGS - EquipmentSlot.FEET -> BOOTS - else -> CHESTPLATE - } - equipmentTrait.set(citizensSlot, itemStack) - } - - override fun teardown(player: Player, npc: NPC) { - npc.destroy() - } -} - -class PlayerNpcData : CitizensNpcData { - override fun create(player: Player, location: Location): NPC { - val npc = temporaryRegistry.createNPC(EntityType.PLAYER, player.name) - - npc.getOrAddTrait(SkinTrait::class.java).skinName = player.name - - npc.getOrAddTrait(Equipment::class.java).apply { - set(HELMET, player.inventory.helmet) - set(CHESTPLATE, player.inventory.chestplate) - set(LEGGINGS, player.inventory.leggings) - set(BOOTS, player.inventory.boots) - } - - npc.data()[NPC.Metadata.NAMEPLATE_VISIBLE] = false - - return npc - } -} - -data class ReferenceNpcData(val id: Int) : CitizensNpcData { - override fun create(player: Player, location: Location): NPC { - val original = - CitizensAPI.getNPCRegistry().getById(id) ?: throw IllegalArgumentException("NPC with id $id not found.") - - val type = original.getOrAddTrait(MobType::class.java).type - val npc = temporaryRegistry.createNPC(type, original.name) - - if (original.hasTrait(SkinTrait::class.java)) { - val originalSkin = original.getOrAddTrait(SkinTrait::class.java) - - if (originalSkin.signature == null || originalSkin.texture == null) { - npc.getOrAddTrait(SkinTrait::class.java).skinName = originalSkin.skinName ?: "" - } else { - npc.getOrAddTrait(SkinTrait::class.java) - .setSkinPersistent(originalSkin.skinName ?: "", originalSkin.signature, originalSkin.texture) - } - } - - if (original.requiresNameHologram()) { - npc.setAlwaysUseNameHologram(true) - npc.name = original.fullName - } - - if (original.hasTrait(HologramTrait::class.java)) { - val originalHologram = original.getOrAddTrait(HologramTrait::class.java) - - npc.getOrAddTrait(HologramTrait::class.java).apply { - lineHeight = originalHologram.lineHeight - originalHologram.lines.forEach { addLine(it) } - } - } - - val namePlateVisible = original.data().get(NPC.Metadata.NAMEPLATE_VISIBLE, true).toString().toBoolean() - npc.data()[NPC.Metadata.NAMEPLATE_VISIBLE] = namePlateVisible - - return npc - } - - override fun spawn(player: Player, npc: NPC, location: Location) { - val original = - CitizensAPI.getNPCRegistry().getById(id) ?: throw IllegalArgumentException("NPC with id $id not found.") - val filter = original.getOrAddTrait(PlayerFilter::class.java) - - if (filter.isAllowlist) { - filter.removePlayer(player.uniqueId) - } else { - filter.addPlayer(player.uniqueId) - } - - super.spawn(player, npc, location) - } - - override fun teardown(player: Player, npc: NPC) { - super.teardown(player, npc) - - val original = - CitizensAPI.getNPCRegistry().getById(id) ?: throw IllegalArgumentException("NPC with id $id not found.") - val filter = original.getOrAddTrait(PlayerFilter::class.java) - if (filter.isAllowlist) { - filter.addPlayer(player.uniqueId) - } else { - filter.removePlayer(player.uniqueId) - } - } -} diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/NpcCinematicEntry.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/NpcCinematicEntry.kt deleted file mode 100644 index 0e8f69e993..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/NpcCinematicEntry.kt +++ /dev/null @@ -1,149 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.cinematic - -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.citizens.entries.artifact.CitizensNpcMovementArtifact -import me.gabber235.typewriter.citizens.entries.artifact.NpcFrame -import me.gabber235.typewriter.content.modes.Tape -import me.gabber235.typewriter.content.modes.firstNotNullWhere -import me.gabber235.typewriter.content.modes.getExactFrame -import me.gabber235.typewriter.content.modes.getFrame -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.utils.ThreadType -import org.bukkit.Location -import org.bukkit.entity.Player -import org.bukkit.inventory.EquipmentSlot -import org.bukkit.inventory.EquipmentSlot.* -import org.bukkit.inventory.ItemStack -import org.koin.core.qualifier.named -import org.koin.java.KoinJavaComponent - -interface NpcCinematicEntry : PrimaryCinematicEntry { - @Help("Recorded segments of the NPC's interactions") - @Segments(Colors.PINK, "fa6-solid:person-walking") - val recordedSegments: List -} - -class NpcRecordedSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - @Help("The artifact for the recorded interactions data") - val artifact: Ref = emptyRef(), -) : Segment - -interface NpcData { - val threadType: ThreadType - get() = ThreadType.REMAIN - - /// Create a new NPC with the data. - fun create(player: Player, location: Location): N - - /// Spawn the NPC in the world. - fun spawn(player: Player, npc: N, location: Location) - - fun handleMovement(player: Player, npc: N, location: Location) - fun handleSneaking(player: Player, npc: N, sneaking: Boolean) - fun handlePunching(player: Player, npc: N, punching: ArmSwing) - fun handleInventory(player: Player, npc: N, slot: EquipmentSlot, itemStack: ItemStack) - - /// Ran when the cinematic is stopped. - fun teardown(player: Player, npc: N) -} - -class NpcCinematicAction( - private val player: Player, - private val entry: NpcCinematicEntry, - private val data: NpcData, -) : - CinematicAction { - private val assetManager: AssetManager by KoinJavaComponent.inject(AssetManager::class.java) - private val gson: Gson by KoinJavaComponent.inject(Gson::class.java, named("bukkitDataParser")) - - private var npc: N? = null - private var recordings: Map> = emptyMap() - - override suspend fun setup() { - super.setup() - - recordings = entry.recordedSegments - .associate { it.artifact.id to it.artifact.get() } - .filterValues { it != null } - .mapValues { assetManager.fetchAsset(it.value!!) } - .filterValues { it != null } - .mapValues { gson.fromJson(it.value, object : TypeToken>() {}.type) } - - - val firstLocation = - entry.recordedSegments.asSequence() - .mapNotNull { recording -> recordings[recording.artifact.id]?.firstNotNullWhere { it.location } } - .firstOrNull() ?: player.location - - withCorrectContext { - npc = data.create(player, firstLocation).apply { - data.spawn(player, this, firstLocation) - } - } - } - - override suspend fun tick(frame: Int) { - super.tick(frame) - - val segment = (entry.recordedSegments activeSegmentAt frame) ?: return - val recording = recordings[segment.artifact.id] ?: return - val segmentFrame = frame - segment.startFrame - withCorrectContext { - npc?.let { - handleMovement(player, it, recording.getFrame(segmentFrame) { location }) - handleSneaking(player, it, recording.getFrame(segmentFrame) { sneaking }) - handlePunching(player, it, recording.getExactFrame(segmentFrame) { swing }) - - handleInventory(player, it, HAND, recording.getExactFrame(segmentFrame) { mainHand }) - handleInventory(player, it, OFF_HAND, recording.getExactFrame(segmentFrame) { offHand }) - handleInventory(player, it, HEAD, recording.getExactFrame(segmentFrame) { helmet }) - handleInventory(player, it, CHEST, recording.getExactFrame(segmentFrame) { chestplate }) - handleInventory(player, it, LEGS, recording.getExactFrame(segmentFrame) { leggings }) - handleInventory(player, it, FEET, recording.getExactFrame(segmentFrame) { boots }) - } - } - } - - private fun handleMovement(player: Player, npc: N, location: Location?) { - if (location == null) return - data.handleMovement(player, npc, location) - } - - private fun handleSneaking(player: Player, npc: N, sneaking: Boolean?) { - if (sneaking == null) return - data.handleSneaking(player, npc, sneaking) - } - - private fun handlePunching(player: Player, npc: N, punching: ArmSwing?) { - if (punching == null) return - data.handlePunching(player, npc, punching) - } - - private fun handleInventory(player: Player, npc: N, slot: EquipmentSlot, itemStack: ItemStack?) { - if (itemStack == null) return - data.handleInventory(player, npc, slot, itemStack) - } - - override suspend fun teardown() { - super.teardown() - withCorrectContext { - npc?.let { data.teardown(player, it) } - } - } - - private suspend inline fun withCorrectContext(noinline block: suspend () -> Unit) { - data.threadType.switchContext(block) - } - - override fun canFinish(frame: Int): Boolean = entry.recordedSegments canFinishAt frame -} \ No newline at end of file diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/ReferenceNpcCinematicEntry.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/ReferenceNpcCinematicEntry.kt deleted file mode 100644 index cfc227c93a..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/ReferenceNpcCinematicEntry.kt +++ /dev/null @@ -1,47 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.cinematic - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.citizens.entries.entity.ReferenceNpcEntry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.CinematicAction -import org.bukkit.entity.Player - -@Deprecated("Use the EntityAdapter instead") -@Entry( - "reference_npc_cinematic", - "A reference to an existing npc specifically for cinematic", - Colors.PINK, - "fa-solid:user-tie" -) -/** - * The `Reference NPC Cinematic` entry that plays a recorded animation back on a reference NPC. - * When active, the original NPC will be hidden and a clone will be spawned in its place. - * - * ## How could this be used? - * - * This could be used to create a cinematic where the player is talking to an NPC. - * Like going in to a store and talking to the shopkeeper. - */ -class ReferenceNpcCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val recordedSegments: List = emptyList(), - @Help("Reference npc to clone") - val referenceNpc: Ref = emptyRef(), -) : NpcCinematicEntry { - override fun create(player: Player): CinematicAction { - val referenceNpc = - this.referenceNpc.get() ?: throw Exception("Reference npc not found") - - return NpcCinematicAction( - player, - this, - ReferenceNpcData(referenceNpc.npcId), - ) - } -} diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/SelfNpcCinematicEntry.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/SelfNpcCinematicEntry.kt deleted file mode 100644 index 3bb20ddd74..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/cinematic/SelfNpcCinematicEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.cinematic - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.entries.CinematicAction -import org.bukkit.entity.Player - -@Deprecated("Use the EntityAdapter instead") -@Entry("self_npc_cinematic", "The player itself as an cinematic npc", Colors.PINK, "heroicons:user-16-solid") -/** - * The `Self NPC Cinematic` entry that plays a recorded animation back on the player with an NPC with the player's skin. - * If the NPC recording does not have any armor, the player's armor when starting the cinematic will be used. - * - * ## How could this be used? - * - * This could be used to create a cinematic where the player is talking to an NPC. - * Like going in to a store and talking to the shopkeeper. - */ -class SelfNpcCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val recordedSegments: List = emptyList(), -) : NpcCinematicEntry { - override fun create(player: Player): CinematicAction { - return NpcCinematicAction( - player, - this, - PlayerNpcData(), - ) - } -} diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/CitizensNpc.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/CitizensNpc.kt deleted file mode 100644 index a3989b33ce..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/CitizensNpc.kt +++ /dev/null @@ -1,10 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.entity - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.SoundSourceEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry - -@Tags("citizens_npc") -interface CitizensNpc : SoundSourceEntry, SpeakerEntry { - val npcId: Int -} \ No newline at end of file diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/ReferenceNpcEntry.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/ReferenceNpcEntry.kt deleted file mode 100644 index eae9d4d693..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/entity/ReferenceNpcEntry.kt +++ /dev/null @@ -1,57 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.entity - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.Unsupported -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.utils.* -import net.citizensnpcs.api.CitizensAPI -import kotlin.jvm.optionals.getOrDefault -import net.kyori.adventure.sound.Sound as AdventureSound - -@Tags("reference_npc") -@Entry("reference_npc", "When the npc is not managed by TypeWriter", Colors.ORANGE, "fa-solid:user-tie") -/** - * An identifier that references an NPC in the Citizens plugin. But does not manage the NPC. - * - * ## How could this be used? - * - * This can be used to reference an NPC which is already in the world. This could be used to create a quest that requires the player to talk to an NPC. - */ -class ReferenceNpcEntry( - override val id: String = "", - override val name: String = "", - override val displayName: String = "", - override val sound: Sound, - @Help("The id of the NPC in the Citizens plugin.") - override val npcId: Int = 0, -) : CitizensNpc { - override fun getEmitter(): AdventureSound.Emitter { - val npc = CitizensAPI.getNPCRegistry().getById(npcId) ?: return AdventureSound.Emitter.self() - return npc.entity ?: AdventureSound.Emitter.self() - } -} - -@EntryMigration(ReferenceNpcEntry::class, "0.4.0") -@NeedsMigrationIfNotParsable -fun migrate040ReferenceNpc(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "sound") - - val soundId = json.getAndParse("sound", context.gson).optional - - val sound = Sound( - soundId = soundId.map(::DefaultSoundId).getOrDefault(SoundId.EMPTY), - soundSource = SelfSoundSource, - volume = 1.0f, - pitch = 1.0f, - ) - - data["sound"] = context.gson.toJsonTree(sound) - - return data -} \ No newline at end of file diff --git a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/event/NpcInteractEvent.kt b/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/event/NpcInteractEvent.kt deleted file mode 100644 index c8dbec9255..0000000000 --- a/adapters/CitizensAdapter/src/main/kotlin/me/gabber235/typewriter/citizens/entries/event/NpcInteractEvent.kt +++ /dev/null @@ -1,74 +0,0 @@ -package me.gabber235.typewriter.citizens.entries.event - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.citizens.TypewriterTrait -import me.gabber235.typewriter.citizens.entries.entity.CitizensNpc -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry -import me.gabber235.typewriter.logger -import net.citizensnpcs.api.event.NPCLeftClickEvent -import net.citizensnpcs.api.event.NPCRightClickEvent -import org.bukkit.entity.Player - -@Entry("on_npc_interact", "When a player clicks on an NPC", Colors.YELLOW, "fa6-solid:people-robbery") -/** - * The `NPC Interact Event` is fired when a player interacts with an NPC. - * - * ## How could this be used? - * - * This can be used to create a variety of interactions that can occur between an NPC and a player. For example, you could create an NPC that gives the player an item when they interact with it. - */ -class NpcInteractEventEntry( - override val id: String = "", - override val name: String = "", - override val triggers: List> = emptyList(), - @Help("The identifier of the NPC.") - // The NPC that needs to be interacted with. - val identifier: Ref, -) : EventEntry - -private fun onNpcInteract(player: Player, identifier: String, query: Query) { - val speaker: CitizensNpc? = Query findByName identifier - if (speaker == null) { - logger.warning("Could not find a speaker with name $identifier.") - return - } - query findWhere { - it.identifier.id == speaker.id - } startDialogueWithOrNextDialogue player -} - -private fun onReferenceNpcInteract(player: Player, npcId: Int, query: Query) { - val references: Sequence = Query findWhere { it.npcId == npcId } - val identifiers = references.map { it.id }.toList() - - query.findWhere { - it.identifier.id in identifiers - } startDialogueWithOrNextDialogue player -} - -@EntryListener(NpcInteractEventEntry::class) -fun onNpcRightClick(event: NPCRightClickEvent, query: Query) { - val identifier = event.npc.getTraitNullable(TypewriterTrait::class.java)?.identifier - - if (identifier == null) { - onReferenceNpcInteract(event.clicker, event.npc.id, query) - return - } - - onNpcInteract(event.clicker, identifier, query) -} - -@EntryListener(NpcInteractEventEntry::class) -fun onNpcLeftClick(event: NPCLeftClickEvent, query: Query) { - val identifier = event.npc.getTraitNullable(TypewriterTrait::class.java)?.identifier - - if (identifier == null) { - onReferenceNpcInteract(event.clicker, event.npc.id, query) - return - } - - onNpcInteract(event.clicker, identifier, query) -} \ No newline at end of file diff --git a/adapters/CombatLogXAdapter/build.gradle.kts b/adapters/CombatLogXAdapter/build.gradle.kts deleted file mode 100644 index 60142c7c4a..0000000000 --- a/adapters/CombatLogXAdapter/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -repositories { - maven("https://nexus.sirblobman.xyz/public/") -} - -dependencies { - compileOnly("com.github.sirblobman.api:core:2.9-SNAPSHOT") - compileOnly("com.github.sirblobman.combatlogx:api:11.4-SNAPSHOT") -} diff --git a/adapters/CombatLogXAdapter/settings.gradle.kts b/adapters/CombatLogXAdapter/settings.gradle.kts deleted file mode 100644 index 5c02e65063..0000000000 --- a/adapters/CombatLogXAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "CombatLogXAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/CombatLogXAdapter.kt b/adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/CombatLogXAdapter.kt deleted file mode 100644 index 7e04fb0c9b..0000000000 --- a/adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/CombatLogXAdapter.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.caleb.typewriter.combatlogx - -import App -import com.github.sirblobman.combatlogx.api.ICombatLogX -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Untested -import me.gabber235.typewriter.logger -import org.bukkit.Bukkit - -@Untested -@Adapter("CombatLogX", "For Using CombatLogX", App.VERSION) -/** - * The CombatLogX Adapter allows you to create entries that are triggered when a player enters or leaves combat. - */ -object CombatLogXAdapter : TypewriterAdapter() { - - override fun initialize() { - if (!server.pluginManager.isPluginEnabled("CombatLogX")) { - logger.warning("CombatLogX plugin not found, try installing it or disabling the CombatLogX adapter") - return - } - } - - fun getAPI(): ICombatLogX? { - val pluginManager = Bukkit.getPluginManager() - val plugin = pluginManager.getPlugin("CombatLogX") - return plugin as? ICombatLogX - } -} \ No newline at end of file diff --git a/adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/entries/fact/CombatFactEntry.kt b/adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/entries/fact/CombatFactEntry.kt deleted file mode 100644 index 2c4120abf7..0000000000 --- a/adapters/CombatLogXAdapter/src/main/kotlin/com/caleb/typewriter/combatlogx/entries/fact/CombatFactEntry.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.caleb.typewriter.combatlogx.entries.fact - -import com.caleb.typewriter.combatlogx.CombatLogXAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData -import org.bukkit.entity.Player - -@Entry("combat_fact", "If the player is in combat", Colors.PURPLE, "fa6-solid:shield-halved") -/** - * A [fact](/docs/creating-stories/facts) that tells whether a player is in combat. - * - * - * - * ## How could this be used? - * - * This could be used to disable certain actions when the player is in combat. - */ -class CombatFactEntry( - override val id: String = "", - override val name: String = "", - override val comment: String = "", - override val group: Ref = emptyRef(), -) : ReadableFactEntry { - override fun readSinglePlayer(player: Player): FactData { - val combatLogger = CombatLogXAdapter.getAPI() ?: return FactData(0) - val value = if (combatLogger.combatManager.isInCombat(player)) 1 else 0 - - return FactData(value) - } -} \ No newline at end of file diff --git a/adapters/EntityAdapter/build.gradle.kts b/adapters/EntityAdapter/build.gradle.kts deleted file mode 100644 index c0bee5b0b7..0000000000 --- a/adapters/EntityAdapter/build.gradle.kts +++ /dev/null @@ -1,4 +0,0 @@ -repositories {} -dependencies { - compileOnly("com.extollit.gaming:hydrazine-path-engine:1.8.1") -} \ No newline at end of file diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/EntityAdapter.kt b/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/EntityAdapter.kt deleted file mode 100644 index efbf800162..0000000000 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/EntityAdapter.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter - -import App -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter - -@Adapter("Entity", "For all entity related interactions", App.VERSION) -/** - * The Entity Adapter contains all the essential entries working with entities. - * It allows you to create dynamic entities such as NPC's or Holograms. - * - * In most cases, it should be installed with Typewriter. - * If you haven't installed Typewriter or the adapter yet, - * please follow the [Installation Guide](../../docs/02-getting-started/01-installation.mdx) - * first. - */ -object EntityAdapter : TypewriterAdapter() { - override fun initialize() { - - } -} diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextDisplayData.kt b/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextDisplayData.kt deleted file mode 100644 index e62c8cace9..0000000000 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextDisplayData.kt +++ /dev/null @@ -1,9 +0,0 @@ -package me.gabber235.typewriter.entries.data.minecraft.display.text - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.tofaa.entitylib.wrapper.WrapperEntity - -@Tags("text_display_data") -interface TextDisplayEntityData

: EntityData

diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/CollarColorData.kt b/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/CollarColorData.kt deleted file mode 100644 index c7a34071b7..0000000000 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/CollarColorData.kt +++ /dev/null @@ -1,43 +0,0 @@ -package me.gabber235.typewriter.entries.data.minecraft.living - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas -import me.tofaa.entitylib.extras.DyeColor -import me.tofaa.entitylib.meta.mobs.tameable.CatMeta -import me.tofaa.entitylib.meta.mobs.tameable.WolfMeta -import me.tofaa.entitylib.wrapper.WrapperEntity -import org.bukkit.entity.Player -import java.util.* -import kotlin.reflect.KClass - -@Entry("collar_color_data", "The color of the cat's or wolfs collar", Colors.RED, "fluent:paint-bucket-16-filled") -@Tags("cat_data", "wolf_data", "collar_color_data") -class CollarColorData( - override val id: String = "", - override val name: String = "", - @Help("The color of the cat's collar.") - val catCollarColor: DyeColor = DyeColor.RED, - override val priorityOverride: Optional = Optional.empty(), -) : EntityData { - override fun type(): KClass = CollarColorProperty::class - - override fun build(player: Player): CollarColorProperty = CollarColorProperty(catCollarColor) -} - -data class CollarColorProperty(val collarColor: DyeColor) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(CollarColorProperty::class) -} - -fun applyCollarColorData(entity: WrapperEntity, property: CollarColorProperty) { - entity.metas { - meta { collarColor = property.collarColor } - meta { collarColor = property.collarColor.ordinal } - error("Could not apply CatCollarColorData to ${entity.entityType} entity.") - } -} \ No newline at end of file diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaCarpetColorData.kt b/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaCarpetColorData.kt deleted file mode 100644 index f76daaa13d..0000000000 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaCarpetColorData.kt +++ /dev/null @@ -1,41 +0,0 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.horse - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas -import me.tofaa.entitylib.meta.mobs.horse.LlamaMeta -import me.tofaa.entitylib.wrapper.WrapperEntity -import org.bukkit.entity.Player -import java.util.* -import kotlin.reflect.KClass - -@Entry("llama_carpet_color_data", "The color of the llama's carpet.", Colors.RED, "mdi:llama") -@Tags("llama_data", "carpet_color_data") -class LlamaCarpetColorData( - override val id: String = "", - override val name: String = "", - @Help("The color of the llama's carpet.") - val color: Int = 0, - override val priorityOverride: Optional = Optional.empty(), -) : EntityData { - override fun type(): KClass = LlamaCarpetColorProperty::class - - override fun build(player: Player): LlamaCarpetColorProperty = LlamaCarpetColorProperty(color) -} - -data class LlamaCarpetColorProperty(val color: Int) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(LlamaCarpetColorProperty::class) -} - -fun applyLlamaCarpetColorData(entity: WrapperEntity, property: LlamaCarpetColorProperty) { - entity.metas { - meta { carpetColor = property.color } - error("Could not apply LlamaCarpetColorData to ${entity.entityType} entity.") - } -} \ No newline at end of file diff --git a/adapters/FancyNpcsAdapter/build.gradle.kts b/adapters/FancyNpcsAdapter/build.gradle.kts deleted file mode 100644 index df2364c522..0000000000 --- a/adapters/FancyNpcsAdapter/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -repositories { - // FancyNpc Repositories - maven("https://repo.fancyplugins.de/releases") -} - -dependencies { - compileOnly("de.oliver:FancyNpcs:2.0.9") -} diff --git a/adapters/FancyNpcsAdapter/settings.gradle.kts b/adapters/FancyNpcsAdapter/settings.gradle.kts deleted file mode 100644 index a9d3af79ec..0000000000 --- a/adapters/FancyNpcsAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "FancyNpcsAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/FancyNpcsAdapter.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/FancyNpcsAdapter.kt deleted file mode 100644 index 110a89a7e8..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/FancyNpcsAdapter.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter - -import App -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Untested - -@Untested -@Deprecated("Use the EntityAdapter instead") -@Adapter("FancyNpcs", "For the FancyNpcs plugin", App.VERSION) -/** - * The FancyNpcs adapter allows you to create custom interactions with NPCs. - */ -object FancyNpcsAdapter : TypewriterAdapter() { - override fun initialize() { - if (!plugin.server.pluginManager.isPluginEnabled("FancyNpcs")) { - logger.warning("FancyNpcs plugin not found, try installing it or disabling the FancyNpcs adapter") - return - } - } -} diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt deleted file mode 100644 index ed018ab243..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt +++ /dev/null @@ -1,40 +0,0 @@ -package me.gabber235.typewriter.entries.artifact - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.ArtifactEntry -import me.gabber235.typewriter.entry.entries.AssetEntry -import me.gabber235.typewriter.entry.entries.getAssetFromFieldValue -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.utils.onFail -import org.bukkit.Location -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.PlayerInventory - -@Deprecated("Use the EntityAdapter instead") -@Entry("fancy_npc_movement_artifact", "Movement data for an npc", Colors.PINK, "fa6-solid:person-walking") -@Tags("npc_movement_artifact") -/** - * The `Npc Movement Artifact` is an artifact that stores the movement data of an NPC. - * There is no reason to create this on its own. - * It should always be connected to another entry - */ -class FancyNpcMovementArtifact( - override val id: String = "", - override val name: String = "", - override val artifactId: String = "", -) : ArtifactEntry - -data class NpcFrame( - val location: Location?, - val sneaking: Boolean?, - val swing: ArmSwing?, - - val mainHand: ItemStack?, - val offHand: ItemStack?, - val helmet: ItemStack?, - val chestplate: ItemStack?, - val leggings: ItemStack?, - val boots: ItemStack?, -) \ No newline at end of file diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/FancyNpcData.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/FancyNpcData.kt deleted file mode 100644 index 491ef8187d..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/FancyNpcData.kt +++ /dev/null @@ -1,139 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import de.oliver.fancynpcs.api.FancyNpcsPlugin -import de.oliver.fancynpcs.api.Npc -import de.oliver.fancynpcs.api.utils.NpcEquipmentSlot.* -import de.oliver.fancynpcs.api.utils.SkinFetcher -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.extensions.packetevents.swingArm -import me.gabber235.typewriter.utils.ThreadType -import net.kyori.adventure.text.format.NamedTextColor -import org.bukkit.Location -import org.bukkit.entity.EntityType -import org.bukkit.entity.Player -import org.bukkit.inventory.EquipmentSlot -import org.bukkit.inventory.ItemStack -import java.util.* - - -interface FancyNpcData : NpcData { - override val threadType: ThreadType - get() = ThreadType.ASYNC - - override fun spawn(player: Player, npc: Npc, location: Location) { - npc.data.location = location - npc.spawn(player) - } - - override fun handleMovement(player: Player, npc: Npc, location: Location) { - npc.data.location = location - npc.update(player) - } - - override fun handleSneaking(player: Player, npc: Npc, sneaking: Boolean) { - val poseAttr = FancyNpcsPlugin.get().attributeManager.getAttributeByName(EntityType.PLAYER, "pose") - if (sneaking) { - npc.data.addAttribute(poseAttr, "CROUCHING") - } else { - npc.data.addAttribute(poseAttr, "STANDING") - } - npc.update(player) - } - - override fun handlePunching(player: Player, npc: Npc, punching: ArmSwing) { - // TODD: Wait for FancyNPCs API to add punching - // For now we directly send the packet - player.swingArm(npc.entityId, punching) - } - - override fun handleInventory(player: Player, npc: Npc, slot: EquipmentSlot, itemStack: ItemStack) { - val fancySlot = when (slot) { - EquipmentSlot.HAND -> MAINHAND - EquipmentSlot.OFF_HAND -> OFFHAND - EquipmentSlot.HEAD -> HEAD - EquipmentSlot.CHEST -> CHEST - EquipmentSlot.LEGS -> LEGS - EquipmentSlot.FEET -> FEET - else -> CHEST - } - npc.data.equipment[fancySlot] = itemStack - npc.update(player) - } - - override fun teardown(player: Player, npc: Npc) { - npc.remove(player) - } -} - -class PlayerNpcData : FancyNpcData { - override fun create(player: Player, location: Location): Npc { - val data = de.oliver.fancynpcs.api.NpcData(player.name, player.uniqueId, location) - data.skin = SkinFetcher(player.uniqueId.toString()) - - data.equipment[HEAD] = player.inventory.helmet - data.equipment[CHEST] = player.inventory.chestplate - data.equipment[LEGS] = player.inventory.leggings - data.equipment[FEET] = player.inventory.boots - - val npc = FancyNpcsPlugin.get().npcAdapter.apply(data) - - npc.isSaveToFile = false - npc.create() - return npc - } -} - -class ReferenceNpcData(private val npcId: String) : FancyNpcData { - override fun create(player: Player, location: Location): Npc { - val original = FancyNpcsPlugin.get().npcManager.getNpc(npcId) - ?: throw IllegalArgumentException("NPC with id '$npcId' not found.") - val ogData = original.data - - val data = de.oliver.fancynpcs.api.NpcData( - UUID.randomUUID().toString(), - ogData.name, - ogData.creator, - ogData.displayName, - ogData.skin, - location, - false, - true, - false, - false, - NamedTextColor.WHITE, - ogData.type, - ogData.equipment, - false, - {}, - emptyList(), - false, - "", - emptyList(), - 0f, - emptyMap(), - false - ) - - val npc = FancyNpcsPlugin.get().npcAdapter.apply(data) - npc.create() - return npc - } - - override fun spawn(player: Player, npc: Npc, location: Location) { - val original = FancyNpcsPlugin.get().npcManager.getNpc(npcId) - ?: throw IllegalArgumentException("NPC with id '$npcId' not found.") - - original.remove(player) - - super.spawn(player, npc, location) - } - - override fun teardown(player: Player, npc: Npc) { - super.teardown(player, npc) - - val original = FancyNpcsPlugin.get().npcManager.getNpc(npcId) - ?: throw IllegalArgumentException("NPC with id '$npcId' not found.") - - original.spawn(player) - } -} \ No newline at end of file diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt deleted file mode 100644 index a327b9b257..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt +++ /dev/null @@ -1,149 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.content.modes.Tape -import me.gabber235.typewriter.content.modes.firstNotNullWhere -import me.gabber235.typewriter.content.modes.getExactFrame -import me.gabber235.typewriter.content.modes.getFrame -import me.gabber235.typewriter.entries.artifact.FancyNpcMovementArtifact -import me.gabber235.typewriter.entries.artifact.NpcFrame -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.utils.ThreadType -import org.bukkit.Location -import org.bukkit.entity.Player -import org.bukkit.inventory.EquipmentSlot -import org.bukkit.inventory.EquipmentSlot.* -import org.bukkit.inventory.ItemStack -import org.koin.core.qualifier.named -import org.koin.java.KoinJavaComponent - -interface NpcCinematicEntry : PrimaryCinematicEntry { - @Help("Recorded segments of the NPC's interactions") - @Segments(Colors.PINK, "fa6-solid:person-walking") - val recordedSegments: List -} - -class NpcRecordedSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - @Help("The artifact for the recorded interactions data") - val artifact: Ref = emptyRef(), -) : Segment - -interface NpcData { - val threadType: ThreadType - get() = ThreadType.REMAIN - - /// Create a new NPC with the data. - fun create(player: Player, location: Location): N - - /// Spawn the NPC in the world. - fun spawn(player: Player, npc: N, location: Location) - - fun handleMovement(player: Player, npc: N, location: Location) - fun handleSneaking(player: Player, npc: N, sneaking: Boolean) - fun handlePunching(player: Player, npc: N, punching: ArmSwing) - fun handleInventory(player: Player, npc: N, slot: EquipmentSlot, itemStack: ItemStack) - - /// Ran when the cinematic is stopped. - fun teardown(player: Player, npc: N) -} - -class NpcCinematicAction( - private val player: Player, - private val entry: NpcCinematicEntry, - private val data: NpcData, -) : - CinematicAction { - private val assetManager: AssetManager by KoinJavaComponent.inject(AssetManager::class.java) - private val gson: Gson by KoinJavaComponent.inject(Gson::class.java, named("bukkitDataParser")) - - private var npc: N? = null - private var recordings: Map> = emptyMap() - - override suspend fun setup() { - super.setup() - - recordings = entry.recordedSegments - .associate { it.artifact.id to it.artifact.get() } - .filterValues { it != null } - .mapValues { assetManager.fetchAsset(it.value!!) } - .filterValues { it != null } - .mapValues { gson.fromJson(it.value, object : TypeToken>() {}.type) } - - - val firstLocation = - entry.recordedSegments.asSequence() - .mapNotNull { recording -> recordings[recording.artifact.id]?.firstNotNullWhere { it.location } } - .firstOrNull() ?: player.location - - withCorrectContext { - npc = data.create(player, firstLocation).apply { - data.spawn(player, this, firstLocation) - } - } - } - - override suspend fun tick(frame: Int) { - super.tick(frame) - - val segment = (entry.recordedSegments activeSegmentAt frame) ?: return - val recording = recordings[segment.artifact.id] ?: return - val segmentFrame = frame - segment.startFrame - withCorrectContext { - npc?.let { - handleMovement(player, it, recording.getFrame(segmentFrame) { location }) - handleSneaking(player, it, recording.getFrame(segmentFrame) { sneaking }) - handlePunching(player, it, recording.getExactFrame(segmentFrame) { swing }) - - handleInventory(player, it, HAND, recording.getExactFrame(segmentFrame) { mainHand }) - handleInventory(player, it, OFF_HAND, recording.getExactFrame(segmentFrame) { offHand }) - handleInventory(player, it, HEAD, recording.getExactFrame(segmentFrame) { helmet }) - handleInventory(player, it, CHEST, recording.getExactFrame(segmentFrame) { chestplate }) - handleInventory(player, it, LEGS, recording.getExactFrame(segmentFrame) { leggings }) - handleInventory(player, it, FEET, recording.getExactFrame(segmentFrame) { boots }) - } - } - } - - private fun handleMovement(player: Player, npc: N, location: Location?) { - if (location == null) return - data.handleMovement(player, npc, location) - } - - private fun handleSneaking(player: Player, npc: N, sneaking: Boolean?) { - if (sneaking == null) return - data.handleSneaking(player, npc, sneaking) - } - - private fun handlePunching(player: Player, npc: N, punching: ArmSwing?) { - if (punching == null) return - data.handlePunching(player, npc, punching) - } - - private fun handleInventory(player: Player, npc: N, slot: EquipmentSlot, itemStack: ItemStack?) { - if (itemStack == null) return - data.handleInventory(player, npc, slot, itemStack) - } - - override suspend fun teardown() { - super.teardown() - withCorrectContext { - npc?.let { data.teardown(player, it) } - } - } - - private suspend inline fun withCorrectContext(noinline block: suspend () -> Unit) { - data.threadType.switchContext(block) - } - - override fun canFinish(frame: Int): Boolean = entry.recordedSegments canFinishAt frame -} \ No newline at end of file diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt deleted file mode 100644 index a67b5c6f8c..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt +++ /dev/null @@ -1,49 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entries.entity.ReferenceNpcEntry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.CinematicAction -import org.bukkit.entity.Player - -@Deprecated("Use the EntityAdapter instead") -@Entry( - "fancy_reference_npc_cinematic", - "A reference to an existing npc specifically for cinematic", - Colors.PINK, - "fa-solid:user-tie" -) -/** - * The `Reference NPC Cinematic` entry that plays a recorded animation back on a reference NPC. - * When active, the original NPC will be hidden and a clone will be spawned in its place. - * - * ## How could this be used? - * - * This could be used to create a cinematic where the player is talking to an NPC. - * Like going in to a store and talking to the shopkeeper. - */ -class ReferenceNpcCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val recordedSegments: List = emptyList(), - @Help("Reference npc to clone") - val referenceNpc: Ref = emptyRef(), -) : NpcCinematicEntry { - override fun create(player: Player): CinematicAction { - if (!referenceNpc.isSet) throw Exception("Reference npc is not set for $id ($name)") - val referenceNpc = - this.referenceNpc.get() - ?: throw Exception("Reference npc '$referenceNpc' not found") - - return NpcCinematicAction( - player, - this, - ReferenceNpcData(referenceNpc.npcId), - ) - } -} diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt deleted file mode 100644 index 71fc94a99f..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.entries.CinematicAction -import org.bukkit.entity.Player - -@Deprecated("Use the EntityAdapter instead") -@Entry("fancy_self_npc_cinematic", "The player itself as an cinematic npc", Colors.PINK, "heroicons:user-16-solid") -/** - * The `Self NPC Cinematic` entry that plays a recorded animation back on the player with an NPC with the player's skin. - * If the NPC recording does not have any armor, the player's armor when starting the cinematic will be used. - * - * ## How could this be used? - * - * This could be used to create a cinematic where the player is talking to an NPC. - * Like going in to a store and talking to the shopkeeper. - */ -class SelfNpcCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val recordedSegments: List = emptyList(), -) : NpcCinematicEntry { - override fun create(player: Player): CinematicAction { - return NpcCinematicAction( - player, - this, - PlayerNpcData(), - ) - } -} \ No newline at end of file diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/FancyNPC.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/FancyNPC.kt deleted file mode 100644 index feb558a567..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/FancyNPC.kt +++ /dev/null @@ -1,10 +0,0 @@ -package me.gabber235.typewriter.entries.entity - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.SoundSourceEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry - -@Tags("fancy_npc") -interface FancyNpc : SpeakerEntry, SoundSourceEntry { - val npcId: String -} diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt deleted file mode 100644 index 3b836b24f9..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.entries.entity - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.utils.Sound -import net.kyori.adventure.sound.Sound as AdventureSound - - -@Deprecated("Use the EntityAdapter instead") -@Tags("fancy_reference_npc") -@Entry("fancy_reference_npc", "When the npc is not managed by TypeWriter", Colors.ORANGE, "fa-solid:user-tie") -/** - * An identifier that references an NPC in the FancyNpcs plugin. But does not manage the NPC. - * - * ## How could this be used? - * - * This can be used to reference an NPC which is already in the world. This could be used to create a quest that requires the player to talk to an NPC. - */ -class ReferenceNpcEntry( - override val id: String = "", - override val name: String = "", - override val displayName: String = "", - override val sound: Sound, - @Help("The id of the NPC in the FancyNpcs plugin.") - override val npcId: String = "", -) : FancyNpc { - override fun getEmitter(): AdventureSound.Emitter { - // Since the FancyNpcs npcs are all done using packets. We can't get the emitter, since there is none. - return AdventureSound.Emitter.self() - } -} diff --git a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt b/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt deleted file mode 100644 index 1755252dc8..0000000000 --- a/adapters/FancyNpcsAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt +++ /dev/null @@ -1,38 +0,0 @@ -package me.gabber235.typewriter.entries.event - -import de.oliver.fancynpcs.api.events.NpcInteractEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entries.entity.FancyNpc -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry - -@Deprecated("Use the EntityAdapter instead") -@Entry("fancy_on_npc_interact", "When a player clicks on an NPC", Colors.YELLOW, "fa6-solid:people-robbery") -/** - * The `NPC Interact Event` is fired when a player interacts with an NPC. - * - * ## How could this be used? - * - * This can be used to create a variety of interactions that can occur between an NPC and a player. For example, you could create an NPC that gives the player an item when they interact with it. - */ -class NpcInteractEventEntry( - override val id: String = "", - override val name: String = "", - override val triggers: List> = emptyList(), - @Help("The identifier of the NPC.") - // The NPC that needs to be interacted with. - val identifier: Ref = emptyRef(), -) : EventEntry - - -@EntryListener(NpcInteractEventEntry::class) -fun onNpcInteract(event: NpcInteractEvent, query: Query) { - val entries: Sequence = Query findWhere { it.id == event.npc.data.id } - val identifiers = entries.map { it.id }.toList() - - query findWhere { - it.identifier.id in identifiers - } startDialogueWithOrNextDialogue event.player -} diff --git a/adapters/MythicMobsAdapter/build.gradle.kts b/adapters/MythicMobsAdapter/build.gradle.kts deleted file mode 100644 index 62a42df63a..0000000000 --- a/adapters/MythicMobsAdapter/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -repositories { - maven("https://mvn.lumine.io/repository/maven-public/") -} - -dependencies { - compileOnly("io.lumine:Mythic-Dist:5.6.1") -} \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/settings.gradle.kts b/adapters/MythicMobsAdapter/settings.gradle.kts deleted file mode 100644 index fc727bd3c3..0000000000 --- a/adapters/MythicMobsAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "MythicMobsAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt deleted file mode 100644 index 99368e886c..0000000000 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt +++ /dev/null @@ -1,23 +0,0 @@ -package me.ahdg6.typewriter.mythicmobs - -import App -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Untested -import me.gabber235.typewriter.logger - -@Untested -@Adapter("MythicMobs", "For Using MythicMobs", App.VERSION) -/** - * The MythicMobs Adapter is an adapter for the MythicMobs plugin. It allows you handle mob-related things in TypeWriter. - */ -object MythicMobsAdapter : TypewriterAdapter() { - - override fun initialize() { - if (!server.pluginManager.isPluginEnabled("MythicMobs")) { - logger.warning("MythicMobs plugin not found, try installing it or disabling the MythicMobs adapter") - return - } - } -} \ No newline at end of file diff --git a/adapters/RPGRegionsAdapter/build.gradle.kts b/adapters/RPGRegionsAdapter/build.gradle.kts deleted file mode 100644 index 38ccd43e7b..0000000000 --- a/adapters/RPGRegionsAdapter/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -repositories { - maven("https://repo.convallyria.com/releases") -} - -dependencies { - compileOnly("net.islandearth.rpgregions:api:1.4.4") // 1.4.4 -} \ No newline at end of file diff --git a/adapters/RPGRegionsAdapter/settings.gradle.kts b/adapters/RPGRegionsAdapter/settings.gradle.kts deleted file mode 100644 index 1369697e80..0000000000 --- a/adapters/RPGRegionsAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "RPGRegionsAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/RPGRegionsAdapter.kt b/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/RPGRegionsAdapter.kt deleted file mode 100644 index b7e0d4718f..0000000000 --- a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/RPGRegionsAdapter.kt +++ /dev/null @@ -1,24 +0,0 @@ -package me.ahdg6.typewriter.rpgregions - -import App -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Untested -import me.gabber235.typewriter.logger - -@Untested -@Adapter("RPGRegions", "For Using RPGRegions", App.VERSION) -/** - * The RPGRegions Adapter is an adapter for the RPGRegions plugin. It allows you to use RPGRegions's discovery system in your dialogue. - */ -object RPGRegionsAdapter : TypewriterAdapter() { - - override fun initialize() { - if (!server.pluginManager.isPluginEnabled("RPGRegions")) { - logger.warning("RPGRegions plugin not found, try installing it or disabling the adapter") - return - } - } - -} \ No newline at end of file diff --git a/adapters/SuperiorSkyblockAdapter/build.gradle.kts b/adapters/SuperiorSkyblockAdapter/build.gradle.kts deleted file mode 100644 index da3c2dcf71..0000000000 --- a/adapters/SuperiorSkyblockAdapter/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -repositories { - maven("https://repo.bg-software.com/repository/api/") -} - -dependencies { - compileOnly("com.bgsoftware:SuperiorSkyblockAPI:1.11.1") -} \ No newline at end of file diff --git a/adapters/SuperiorSkyblockAdapter/settings.gradle.kts b/adapters/SuperiorSkyblockAdapter/settings.gradle.kts deleted file mode 100644 index 4f695cffbc..0000000000 --- a/adapters/SuperiorSkyblockAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "SuperiorSkyblockAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} \ No newline at end of file diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/SuperiorSkyblockAdapter.kt b/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/SuperiorSkyblockAdapter.kt deleted file mode 100644 index 02cbd9abca..0000000000 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/SuperiorSkyblockAdapter.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.caleb.typewriter.superiorskyblock - -import App -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Untested -import me.gabber235.typewriter.logger - -@Untested -@Adapter("SuperiorSkyblock", "For SuperiorSkyblock2, made by Caleb (Sniper)", App.VERSION) -/** - * The Superior Skyblock Adapter allows you to use the Superior Skyblock plugin with TypeWriter. - * It includes many events for you to use in your dialogue, as well as a few actions and conditions. - */ -object SuperiorSkyblockAdapter : TypewriterAdapter() { - override fun initialize() { - if (!server.pluginManager.isPluginEnabled("SuperiorSkyblock2")) { - logger.warning("SuperiorSkyblock2 plugin not found, try installing it or disabling the SuperiorSkyblock2 adapter") - } - - } -} \ No newline at end of file diff --git a/adapters/VaultAdapter/build.gradle.kts b/adapters/VaultAdapter/build.gradle.kts deleted file mode 100644 index 6c08d98299..0000000000 --- a/adapters/VaultAdapter/build.gradle.kts +++ /dev/null @@ -1,3 +0,0 @@ -dependencies { - compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") -} \ No newline at end of file diff --git a/adapters/VaultAdapter/settings.gradle.kts b/adapters/VaultAdapter/settings.gradle.kts deleted file mode 100644 index eb52b84c0b..0000000000 --- a/adapters/VaultAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "VaultAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/WorldGuardAdapter/build.gradle.kts b/adapters/WorldGuardAdapter/build.gradle.kts deleted file mode 100644 index 785c06d463..0000000000 --- a/adapters/WorldGuardAdapter/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -repositories { - maven("https://maven.enginehub.org/repo/") -} - -dependencies { - compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.6-SNAPSHOT") -} \ No newline at end of file diff --git a/adapters/WorldGuardAdapter/settings.gradle.kts b/adapters/WorldGuardAdapter/settings.gradle.kts deleted file mode 100644 index b4260b8e3d..0000000000 --- a/adapters/WorldGuardAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "WorldGuardAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardAdapter.kt b/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardAdapter.kt deleted file mode 100644 index 4bdf62d891..0000000000 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardAdapter.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.caleb.typewriter.worldguard - -import App -import com.sk89q.worldguard.WorldGuard -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.logger - -@Adapter("WorldGuard", "For Using WorldGuard", App.VERSION) -/** - * The WorldGuard Adapter allows you to create dialogue that is triggered by WorldGuard regions. - */ -object WorldGuardAdapter : TypewriterAdapter() { - - override fun initialize() { - if (!server.pluginManager.isPluginEnabled("WorldGuard")) { - logger.warning("WorldGuard plugin not found, try installing it or disabling the WorldGuard adapter") - return - } - - val worldGuard = WorldGuard.getInstance() - - val registered = worldGuard.platform.sessionManager.registerHandler(WorldGuardHandler.Factory(), null) - - if (!registered) { - logger.warning("Failed to register WorldGuardHandler. This is a bug, please report it on the Typewriter Discord.") - } - } -} \ No newline at end of file diff --git a/adapters/WorldGuardAdapter/src/main/templates/App.kt b/adapters/WorldGuardAdapter/src/main/templates/App.kt deleted file mode 100644 index c35b69218d..0000000000 --- a/adapters/WorldGuardAdapter/src/main/templates/App.kt +++ /dev/null @@ -1,3 +0,0 @@ -object App { - const val VERSION = "$version" -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/build.gradle.kts b/adapters/ZNPCsPlusAdapter/build.gradle.kts deleted file mode 100644 index 8ca6bc0017..0000000000 --- a/adapters/ZNPCsPlusAdapter/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -repositories { - maven("https://repo.pyr.lol/snapshots") -} - -dependencies { - compileOnly("lol.pyr:znpcsplus-api:2.0.0-SNAPSHOT") -} diff --git a/adapters/ZNPCsPlusAdapter/settings.gradle.kts b/adapters/ZNPCsPlusAdapter/settings.gradle.kts deleted file mode 100644 index 53960ade4c..0000000000 --- a/adapters/ZNPCsPlusAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "ZNPCsPlusAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/ZNPCsPlusAdapter.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/ZNPCsPlusAdapter.kt deleted file mode 100644 index 8ae52e4620..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/ZNPCsPlusAdapter.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter - -import App -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.adapters.Untested - -@Untested -@Deprecated("Use the EntityAdapter instead") -@Adapter("ZNPCsPlus", "For the ZNPCsPlus plugin", App.VERSION) -/** - * The ZNPCsPlus adapter allows you to create custom interactions with NPCs. - */ -object ZNPCsPlusAdapter : TypewriterAdapter() { - override fun initialize() { - if (!plugin.server.pluginManager.isPluginEnabled("ZNPCsPlus")) { - logger.warning("ZNPCsPlus plugin not found, try installing it or disabling the ZNPCsPlus adapter") - return - } - } -} diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt deleted file mode 100644 index 4ddc809fd8..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/artifact/NpcMovementArtifact.kt +++ /dev/null @@ -1,35 +0,0 @@ -package me.gabber235.typewriter.entries.artifact - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.ArtifactEntry -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import org.bukkit.Location -import org.bukkit.inventory.ItemStack - -@Deprecated("Use the EntityAdapter instead") -@Entry("znpc_movement_artifact", "Movement data for an npc", Colors.PINK, "fa6-solid:person-walking") -@Tags("npc_movement_artifact") -/** - * The `Npc Movement Artifact` is an artifact that stores the movement data of an NPC. - * There is no reason to create this on its own. - * It should always be connected to another entry - */ -class ZNpcMovementArtifact( - override val id: String = "", - override val name: String = "", - override val artifactId: String = "", -) : ArtifactEntry - -data class NpcFrame( - val location: Location?, - val sneaking: Boolean?, - val swing: ArmSwing?, - val mainHand: ItemStack?, - val offHand: ItemStack?, - val helmet: ItemStack?, - val chestplate: ItemStack?, - val leggings: ItemStack?, - val boots: ItemStack?, -) \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt deleted file mode 100644 index ac3c23075f..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/NpcCinematicEntry.kt +++ /dev/null @@ -1,149 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.content.modes.Tape -import me.gabber235.typewriter.content.modes.firstNotNullWhere -import me.gabber235.typewriter.content.modes.getExactFrame -import me.gabber235.typewriter.content.modes.getFrame -import me.gabber235.typewriter.entries.artifact.NpcFrame -import me.gabber235.typewriter.entries.artifact.ZNpcMovementArtifact -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.utils.ThreadType -import org.bukkit.Location -import org.bukkit.entity.Player -import org.bukkit.inventory.EquipmentSlot -import org.bukkit.inventory.EquipmentSlot.* -import org.bukkit.inventory.ItemStack -import org.koin.core.qualifier.named -import org.koin.java.KoinJavaComponent - -interface NpcCinematicEntry : CinematicEntry { - @Help("Recorded segments of the NPC's interactions") - @Segments(Colors.PINK, "fa6-solid:person-walking") - val recordedSegments: List -} - -class NpcRecordedSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - @Help("The artifact for the recorded interactions data") - val artifact: Ref = emptyRef(), -) : Segment - -interface NpcData { - val threadType: ThreadType - get() = ThreadType.REMAIN - - /// Create a new NPC with the data. - fun create(player: Player, location: Location): N - - /// Spawn the NPC in the world. - fun spawn(player: Player, npc: N, location: Location) - - fun handleMovement(player: Player, npc: N, location: Location) - fun handleSneaking(player: Player, npc: N, sneaking: Boolean) - fun handlePunching(player: Player, npc: N, punching: ArmSwing) - fun handleInventory(player: Player, npc: N, slot: EquipmentSlot, itemStack: ItemStack) - - /// Ran when the cinematic is stopped. - fun teardown(player: Player, npc: N) -} - -class NpcCinematicAction( - private val player: Player, - private val entry: NpcCinematicEntry, - private val data: NpcData, -) : - CinematicAction { - private val assetManager: AssetManager by KoinJavaComponent.inject(AssetManager::class.java) - private val gson: Gson by KoinJavaComponent.inject(Gson::class.java, named("bukkitDataParser")) - - private var npc: N? = null - private var recordings: Map> = emptyMap() - - override suspend fun setup() { - super.setup() - - recordings = entry.recordedSegments - .associate { it.artifact.id to it.artifact.get() } - .filterValues { it != null } - .mapValues { assetManager.fetchAsset(it.value!!) } - .filterValues { it != null } - .mapValues { gson.fromJson(it.value, object : TypeToken>() {}.type) } - - - val firstLocation = - entry.recordedSegments.asSequence() - .mapNotNull { recording -> recordings[recording.artifact.id]?.firstNotNullWhere { it.location } } - .firstOrNull() ?: player.location - - withCorrectContext { - npc = data.create(player, firstLocation).apply { - data.spawn(player, this, firstLocation) - } - } - } - - override suspend fun tick(frame: Int) { - super.tick(frame) - - val segment = (entry.recordedSegments activeSegmentAt frame) ?: return - val recording = recordings[segment.artifact.id] ?: return - val segmentFrame = frame - segment.startFrame - withCorrectContext { - npc?.let { - handleMovement(player, it, recording.getFrame(segmentFrame) { location }) - handleSneaking(player, it, recording.getFrame(segmentFrame) { sneaking }) - handlePunching(player, it, recording.getExactFrame(segmentFrame) { swing }) - - handleInventory(player, it, HAND, recording.getExactFrame(segmentFrame) { mainHand }) - handleInventory(player, it, OFF_HAND, recording.getExactFrame(segmentFrame) { offHand }) - handleInventory(player, it, HEAD, recording.getExactFrame(segmentFrame) { helmet }) - handleInventory(player, it, CHEST, recording.getExactFrame(segmentFrame) { chestplate }) - handleInventory(player, it, LEGS, recording.getExactFrame(segmentFrame) { leggings }) - handleInventory(player, it, FEET, recording.getExactFrame(segmentFrame) { boots }) - } - } - } - - private fun handleMovement(player: Player, npc: N, location: Location?) { - if (location == null) return - data.handleMovement(player, npc, location) - } - - private fun handleSneaking(player: Player, npc: N, sneaking: Boolean?) { - if (sneaking == null) return - data.handleSneaking(player, npc, sneaking) - } - - private fun handlePunching(player: Player, npc: N, punching: ArmSwing?) { - if (punching == null) return - data.handlePunching(player, npc, punching) - } - - private fun handleInventory(player: Player, npc: N, slot: EquipmentSlot, itemStack: ItemStack?) { - if (itemStack == null) return - data.handleInventory(player, npc, slot, itemStack) - } - - override suspend fun teardown() { - super.teardown() - withCorrectContext { - npc?.let { data.teardown(player, it) } - } - } - - private suspend inline fun withCorrectContext(noinline block: suspend () -> Unit) { - data.threadType.switchContext(block) - } - - override fun canFinish(frame: Int): Boolean = entry.recordedSegments canFinishAt frame -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt deleted file mode 100644 index fb57c8d98e..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ReferenceNpcCinematicEntry.kt +++ /dev/null @@ -1,47 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entries.entity.ReferenceNpcEntry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.CinematicAction -import org.bukkit.entity.Player - -@Deprecated("Use the EntityAdapter instead") -@Entry( - "znpc_reference_npc_cinematic", - "A reference to an existing npc specifically for cinematic", - Colors.PINK, - "fa-solid:user-tie" -) -/** - * The `Reference NPC Cinematic` entry that plays a recorded animation back on a reference NPC. - * When active, the original NPC will be hidden and a clone will be spawned in its place. - * - * ## How could this be used? - * - * This could be used to create a cinematic where the player is talking to an NPC. - * Like going in to a store and talking to the shopkeeper. - */ -class ReferenceNpcCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val recordedSegments: List = emptyList(), - @Help("Reference npc to clone") - val referenceNpc: Ref = emptyRef(), -) : NpcCinematicEntry { - override fun create(player: Player): CinematicAction { - if (!referenceNpc.isSet) throw Exception("Reference npc is not set for $id ($name)") - val referenceNpc = referenceNpc.get() ?: throw Exception("Reference npc '$referenceNpc' not found") - - return NpcCinematicAction( - player, - this, - ReferenceNpcData(referenceNpc.npcId), - ) - } -} diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt deleted file mode 100644 index 345ac2d1f7..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SelfNpcCinematicEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.entries.CinematicAction -import org.bukkit.entity.Player - -@Deprecated("Use the EntityAdapter instead") -@Entry("znpc_self_npc_cinematic", "The player itself as an cinematic npc", Colors.PINK, "heroicons:user-16-solid") -/** - * The `Self NPC Cinematic` entry that plays a recorded animation back on the player with an NPC with the player's skin. - * If the NPC recording does not have any armor, the player's armor when starting the cinematic will be used. - * - * ## How could this be used? - * - * This could be used to create a cinematic where the player is talking to an NPC. - * Like going in to a store and talking to the shopkeeper. - */ -class SelfNpcCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val recordedSegments: List = emptyList(), -) : NpcCinematicEntry { - override fun create(player: Player): CinematicAction { - return NpcCinematicAction( - player, - this, - PlayerNpcData(), - ) - } -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ZNPCData.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ZNPCData.kt deleted file mode 100644 index a948739f33..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ZNPCData.kt +++ /dev/null @@ -1,138 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import lol.pyr.znpcsplus.api.NpcApiProvider -import lol.pyr.znpcsplus.api.entity.EntityProperty -import lol.pyr.znpcsplus.api.npc.NpcEntry -import lol.pyr.znpcsplus.api.skin.SkinDescriptor -import lol.pyr.znpcsplus.util.NpcLocation -import lol.pyr.znpcsplus.util.NpcPose -import me.gabber235.typewriter.extensions.packetevents.ArmSwing -import me.gabber235.typewriter.logger -import org.bukkit.Location -import org.bukkit.entity.Player -import org.bukkit.inventory.EquipmentSlot -import org.bukkit.inventory.ItemStack -import java.util.* - -interface ZNPCData : NpcData { - override fun spawn(player: Player, npc: NpcEntry, location: Location) { - if (player.world != location.world) { - logger.severe( - """| - |Player and NPC are not in the same world! Cannot spawn NPC. - |(Player: ${player.world}, NPC: ${location.world}) - |Make sure that the player is teleported before the NPC is spawned. - """.trimMargin() - ) - } - npc.npc.location = NpcLocation(location) - npc.isProcessed = false - npc.isSave = false - npc.npc.show(player) - } - - override fun handleMovement(player: Player, npc: NpcEntry, location: Location) { - npc.npc.location = NpcLocation(location) - } - - override fun handleSneaking(player: Player, npc: NpcEntry, sneaking: Boolean) { - val property = NpcApiProvider.get().propertyRegistry.getByName("pose", NpcPose::class.java) - - if (sneaking) { - npc.npc.setProperty(property, NpcPose.CROUCHING) - } else { - npc.npc.setProperty(property, NpcPose.STANDING) - } - } - - override fun handlePunching(player: Player, npc: NpcEntry, punching: ArmSwing) { - npc.npc.swingHand(punching.swingLeft) - } - - override fun handleInventory(player: Player, npc: NpcEntry, slot: EquipmentSlot, itemStack: ItemStack) { - val zNpcSlot = when (slot) { - EquipmentSlot.HAND -> "hand" - EquipmentSlot.OFF_HAND -> "offhand" - EquipmentSlot.HEAD -> "helmet" - EquipmentSlot.CHEST -> "chestplate" - EquipmentSlot.LEGS -> "leggings" - EquipmentSlot.FEET -> "boots" - else -> "chestplate" - } - - val property = NpcApiProvider.get().propertyRegistry.getByName(zNpcSlot, ItemStack::class.java) - npc.npc.setItemProperty(property, itemStack) - } - - override fun teardown(player: Player, npc: NpcEntry) { - npc.npc.hide(player) - NpcApiProvider.get().npcRegistry.delete(npc.id) - } -} - -class PlayerNpcData : ZNPCData { - override fun create(player: Player, location: Location): NpcEntry { - val api = NpcApiProvider.get() - val type = api.npcTypeRegistry.getByName("player") - val entry = api.npcRegistry.create( - UUID.randomUUID().toString(), - location.world, - type, - NpcLocation(location) - ) - - val npc = entry.npc - - val skin = api.skinDescriptorFactory.createStaticDescriptor(player.name) - npc.setProperty(api.propertyRegistry.getByName("skin", SkinDescriptor::class.java), skin) - - player.inventory.helmet?.let { handleInventory(player, entry, EquipmentSlot.HEAD, it) } - player.inventory.chestplate?.let { handleInventory(player, entry, EquipmentSlot.CHEST, it) } - player.inventory.leggings?.let { handleInventory(player, entry, EquipmentSlot.LEGS, it) } - player.inventory.boots?.let { handleInventory(player, entry, EquipmentSlot.FEET, it) } - - return entry - } -} - -class ReferenceNpcData(private val npcId: String) : ZNPCData { - override fun create(player: Player, location: Location): NpcEntry { - val api = NpcApiProvider.get() - val npcRegistry = api.npcRegistry - - val original = npcRegistry.getById(npcId) ?: throw IllegalArgumentException("NPC with id $npcId not found.") - val type = original.npc.type - - val entry = api.npcRegistry.create( - UUID.randomUUID().toString(), - location.world, - type, - NpcLocation(location) - ) - - for (property in original.npc.appliedProperties) { - val value = original.npc.getProperty(property) - entry.npc.setProperty(property as EntityProperty, value) - } - - return entry - } - - override fun spawn(player: Player, npc: NpcEntry, location: Location) { - val original = NpcApiProvider.get().npcRegistry.getById(npcId) - ?: throw IllegalArgumentException("NPC with id $npcId not found.") - - original.npc.hide(player) - - super.spawn(player, npc, location) - } - - override fun teardown(player: Player, npc: NpcEntry) { - super.teardown(player, npc) - - val original = NpcApiProvider.get().npcRegistry.getById(npcId) - ?: throw IllegalArgumentException("NPC with id $npcId not found.") - - original.npc.show(player) - } -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt deleted file mode 100644 index 603587350e..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ReferenceNpcEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.entries.entity - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.utils.Sound -import net.kyori.adventure.sound.Sound as AdventureSound - - -@Deprecated("Use the EntityAdapter instead") -@Tags("znpc_reference_npc") -@Entry("znpc_reference_npc", "When the npc is not managed by TypeWriter", Colors.ORANGE, "fa-solid:user-tie") -/** - * An identifier that references an NPC in the ZNPCsPlus plugin. But does not manage the NPC. - * - * ## How could this be used? - * - * This can be used to reference an NPC which is already in the world. This could be used to create a quest that requires the player to talk to an NPC. - */ -class ReferenceNpcEntry( - override val id: String = "", - override val name: String = "", - override val displayName: String = "", - override val sound: Sound, - @Help("The id of the NPC in the ZNPCsPlus plugin.") - override val npcId: String = "", -) : ZNPC { - override fun getEmitter(): AdventureSound.Emitter { - // Since the zNPCsPlus npcs are all done using packets. We can't get the emitter, since there is none. - return AdventureSound.Emitter.self() - } -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ZNPC.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ZNPC.kt deleted file mode 100644 index 77d78d645e..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/ZNPC.kt +++ /dev/null @@ -1,10 +0,0 @@ -package me.gabber235.typewriter.entries.entity - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.SoundSourceEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry - -@Tags("z_npc") -interface ZNPC : SpeakerEntry, SoundSourceEntry { - val npcId: String -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt b/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt deleted file mode 100644 index 61653f4dd1..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/NpcInteractEvent.kt +++ /dev/null @@ -1,38 +0,0 @@ -package me.gabber235.typewriter.entries.event - -import lol.pyr.znpcsplus.api.event.NpcInteractEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entries.entity.ZNPC -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry - -@Deprecated("Use the EntityAdapter instead") -@Entry("znpc_on_npc_interact", "When a player clicks on an NPC", Colors.YELLOW, "fa6-solid:people-robbery") -/** - * The `NPC Interact Event` is fired when a player interacts with an NPC. - * - * ## How could this be used? - * - * This can be used to create a variety of interactions that can occur between an NPC and a player. For example, you could create an NPC that gives the player an item when they interact with it. - */ -class NpcInteractEventEntry( - override val id: String = "", - override val name: String = "", - override val triggers: List> = emptyList(), - @Help("The identifier of the NPC.") - // The NPC that needs to be interacted with. - val identifier: Ref = emptyRef() -) : EventEntry - - -@EntryListener(NpcInteractEventEntry::class) -fun onNpcInteract(event: NpcInteractEvent, query: Query) { - val entries: Sequence = Query findWhere { it.id == event.entry.id } - val identifiers = entries.map { it.id }.toList() - - query findWhere { - it.identifier.id in identifiers - } startDialogueWithOrNextDialogue event.player -} \ No newline at end of file diff --git a/adapters/ZNPCsPlusAdapter/src/main/templates/App.kt b/adapters/ZNPCsPlusAdapter/src/main/templates/App.kt deleted file mode 100644 index c35b69218d..0000000000 --- a/adapters/ZNPCsPlusAdapter/src/main/templates/App.kt +++ /dev/null @@ -1,3 +0,0 @@ -object App { - const val VERSION = "$version" -} \ No newline at end of file diff --git a/adapters/_DocsAdapter/build.gradle.kts b/adapters/_DocsAdapter/build.gradle.kts deleted file mode 100644 index dbca3f4b5a..0000000000 --- a/adapters/_DocsAdapter/build.gradle.kts +++ /dev/null @@ -1,2 +0,0 @@ -repositories {} -dependencies {} diff --git a/adapters/_DocsAdapter/settings.gradle.kts b/adapters/_DocsAdapter/settings.gradle.kts deleted file mode 100644 index 2c434271a4..0000000000 --- a/adapters/_DocsAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "DocsAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/ExampleAdapter.kt b/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/ExampleAdapter.kt deleted file mode 100644 index 2300d3e65f..0000000000 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/ExampleAdapter.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.typewritermc.example - -// -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter - -@Adapter("Example", "An example adapter for documentation purposes", "0.0.1") -object ExampleAdapter : TypewriterAdapter() { - override fun initialize() { - // Do something when the adapter is initialized - } - - override fun shutdown() { - // Do something when the adapter is shutdown - } -} -// \ No newline at end of file diff --git a/adapters/_DocsAdapter/src/main/templates/App.kt b/adapters/_DocsAdapter/src/main/templates/App.kt deleted file mode 100644 index c35b69218d..0000000000 --- a/adapters/_DocsAdapter/src/main/templates/App.kt +++ /dev/null @@ -1,3 +0,0 @@ -object App { - const val VERSION = "$version" -} \ No newline at end of file diff --git a/adapters/settings.gradle.kts b/adapters/settings.gradle.kts deleted file mode 100644 index 5c01f1ed9a..0000000000 --- a/adapters/settings.gradle.kts +++ /dev/null @@ -1,22 +0,0 @@ -includeBuild("../plugin") - -val ignoringAdapters: List = emptyList() - -val directories = file("./").listFiles()?.filter { - it.name.endsWith("Adapter") && it.isDirectory && it.name !in ignoringAdapters -} ?: emptyList() - -for (directory in directories) { - include(directory.name) -} - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/app/.gitignore b/app/.gitignore index 24476c5d1e..6c319542b3 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/app/.metadata b/app/.metadata index 083a42e9bd..9be1e30be1 100644 --- a/app/.metadata +++ b/app/.metadata @@ -1,11 +1,11 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled. +# This file should be version controlled and should not be manually edited. version: - revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - channel: stable + revision: "7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30" + channel: "beta" project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 - platform: android - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 - platform: ios - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 - platform: linux - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 - platform: macos - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 - platform: web - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 - platform: windows - create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf - base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 + base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30 # User provided section diff --git a/app/README.md b/app/README.md index 849a534ad2..f01ea2ab5e 100644 --- a/app/README.md +++ b/app/README.md @@ -1,3 +1,3 @@ # Typewriter -This is the web application for Typewriter. It helps you to create and manage your Typewriter projects \ No newline at end of file +This is the web application for Typewriter. It helps you to create and manage your Typewriter projects diff --git a/app/ios/RunnerTests/RunnerTests.swift b/app/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000000..86a7c3b1b6 --- /dev/null +++ b/app/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/app/lib/app_router.dart b/app/lib/app_router.dart index 7bfc1c94a7..79348959e6 100644 --- a/app/lib/app_router.dart +++ b/app/lib/app_router.dart @@ -95,29 +95,29 @@ extension AppRouterX on AppRouter { /// containing the entry and then navigate to the entry. /// Returns true if the page was changed. Future navigateToEntry(PassingRef ref, String entryId) async { - final entryPage = ref.read(globalEntryWithPageProvider(entryId))?.key; + final entryPageId = ref.read(entryPageIdProvider(entryId)); - if (entryPage == null) { + if (entryPageId == null) { return; } - await navigateToPage(ref, entryPage); + await navigateToPage(ref, entryPageId); } - /// Navigate to the given [pageName]. + /// Navigate to the given [pageId]. /// Returns true if the page was changed. - Future navigateToPage(PassingRef ref, String pageName) async { + Future navigateToPage(PassingRef ref, String pageId) async { final currentPage = ref.read(currentPageProvider); - if (currentPage?.pageName == pageName) { + if (currentPage?.id == pageId) { return; } // Sometimes the app router does not complete the future and it gets stuck. unawaited( ref.read(appRouter).push( - PageEditorRoute(id: pageName), + PageEditorRoute(id: pageId), onFailure: (e) => - debugPrint("Failed to navigate to page $pageName: $e"), + debugPrint("Failed to navigate to page $pageId: $e"), ), ); } diff --git a/app/lib/models/adapter.freezed.dart b/app/lib/models/adapter.freezed.dart deleted file mode 100644 index 73e68626d0..0000000000 --- a/app/lib/models/adapter.freezed.dart +++ /dev/null @@ -1,2656 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'adapter.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -Adapter _$AdapterFromJson(Map json) { - return _Adapter.fromJson(json); -} - -/// @nodoc -mixin _$Adapter { - String get name => throw _privateConstructorUsedError; - String get description => throw _privateConstructorUsedError; - String get version => throw _privateConstructorUsedError; - List get entries => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $AdapterCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $AdapterCopyWith<$Res> { - factory $AdapterCopyWith(Adapter value, $Res Function(Adapter) then) = - _$AdapterCopyWithImpl<$Res, Adapter>; - @useResult - $Res call( - {String name, - String description, - String version, - List entries}); -} - -/// @nodoc -class _$AdapterCopyWithImpl<$Res, $Val extends Adapter> - implements $AdapterCopyWith<$Res> { - _$AdapterCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? description = null, - Object? version = null, - Object? entries = null, - }) { - return _then(_value.copyWith( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - description: null == description - ? _value.description - : description // ignore: cast_nullable_to_non_nullable - as String, - version: null == version - ? _value.version - : version // ignore: cast_nullable_to_non_nullable - as String, - entries: null == entries - ? _value.entries - : entries // ignore: cast_nullable_to_non_nullable - as List, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$AdapterImplCopyWith<$Res> implements $AdapterCopyWith<$Res> { - factory _$$AdapterImplCopyWith( - _$AdapterImpl value, $Res Function(_$AdapterImpl) then) = - __$$AdapterImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String name, - String description, - String version, - List entries}); -} - -/// @nodoc -class __$$AdapterImplCopyWithImpl<$Res> - extends _$AdapterCopyWithImpl<$Res, _$AdapterImpl> - implements _$$AdapterImplCopyWith<$Res> { - __$$AdapterImplCopyWithImpl( - _$AdapterImpl _value, $Res Function(_$AdapterImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? description = null, - Object? version = null, - Object? entries = null, - }) { - return _then(_$AdapterImpl( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - description: null == description - ? _value.description - : description // ignore: cast_nullable_to_non_nullable - as String, - version: null == version - ? _value.version - : version // ignore: cast_nullable_to_non_nullable - as String, - entries: null == entries - ? _value._entries - : entries // ignore: cast_nullable_to_non_nullable - as List, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$AdapterImpl with DiagnosticableTreeMixin implements _Adapter { - const _$AdapterImpl( - {required this.name, - required this.description, - required this.version, - required final List entries}) - : _entries = entries; - - factory _$AdapterImpl.fromJson(Map json) => - _$$AdapterImplFromJson(json); - - @override - final String name; - @override - final String description; - @override - final String version; - final List _entries; - @override - List get entries { - if (_entries is EqualUnmodifiableListView) return _entries; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_entries); - } - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Adapter(name: $name, description: $description, version: $version, entries: $entries)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'Adapter')) - ..add(DiagnosticsProperty('name', name)) - ..add(DiagnosticsProperty('description', description)) - ..add(DiagnosticsProperty('version', version)) - ..add(DiagnosticsProperty('entries', entries)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$AdapterImpl && - (identical(other.name, name) || other.name == name) && - (identical(other.description, description) || - other.description == description) && - (identical(other.version, version) || other.version == version) && - const DeepCollectionEquality().equals(other._entries, _entries)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, name, description, version, - const DeepCollectionEquality().hash(_entries)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$AdapterImplCopyWith<_$AdapterImpl> get copyWith => - __$$AdapterImplCopyWithImpl<_$AdapterImpl>(this, _$identity); - - @override - Map toJson() { - return _$$AdapterImplToJson( - this, - ); - } -} - -abstract class _Adapter implements Adapter { - const factory _Adapter( - {required final String name, - required final String description, - required final String version, - required final List entries}) = _$AdapterImpl; - - factory _Adapter.fromJson(Map json) = _$AdapterImpl.fromJson; - - @override - String get name; - @override - String get description; - @override - String get version; - @override - List get entries; - @override - @JsonKey(ignore: true) - _$$AdapterImplCopyWith<_$AdapterImpl> get copyWith => - throw _privateConstructorUsedError; -} - -EntryBlueprint _$EntryBlueprintFromJson(Map json) { - return _EntryBlueprint.fromJson(json); -} - -/// @nodoc -mixin _$EntryBlueprint { - String get name => throw _privateConstructorUsedError; - String get description => throw _privateConstructorUsedError; - String get adapter => throw _privateConstructorUsedError; - ObjectField get fields => throw _privateConstructorUsedError; - List get tags => throw _privateConstructorUsedError; - @ColorConverter() - Color get color => throw _privateConstructorUsedError; - String get icon => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $EntryBlueprintCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $EntryBlueprintCopyWith<$Res> { - factory $EntryBlueprintCopyWith( - EntryBlueprint value, $Res Function(EntryBlueprint) then) = - _$EntryBlueprintCopyWithImpl<$Res, EntryBlueprint>; - @useResult - $Res call( - {String name, - String description, - String adapter, - ObjectField fields, - List tags, - @ColorConverter() Color color, - String icon}); -} - -/// @nodoc -class _$EntryBlueprintCopyWithImpl<$Res, $Val extends EntryBlueprint> - implements $EntryBlueprintCopyWith<$Res> { - _$EntryBlueprintCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? description = null, - Object? adapter = null, - Object? fields = freezed, - Object? tags = null, - Object? color = null, - Object? icon = null, - }) { - return _then(_value.copyWith( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - description: null == description - ? _value.description - : description // ignore: cast_nullable_to_non_nullable - as String, - adapter: null == adapter - ? _value.adapter - : adapter // ignore: cast_nullable_to_non_nullable - as String, - fields: freezed == fields - ? _value.fields - : fields // ignore: cast_nullable_to_non_nullable - as ObjectField, - tags: null == tags - ? _value.tags - : tags // ignore: cast_nullable_to_non_nullable - as List, - color: null == color - ? _value.color - : color // ignore: cast_nullable_to_non_nullable - as Color, - icon: null == icon - ? _value.icon - : icon // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$EntryBlueprintImplCopyWith<$Res> - implements $EntryBlueprintCopyWith<$Res> { - factory _$$EntryBlueprintImplCopyWith(_$EntryBlueprintImpl value, - $Res Function(_$EntryBlueprintImpl) then) = - __$$EntryBlueprintImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String name, - String description, - String adapter, - ObjectField fields, - List tags, - @ColorConverter() Color color, - String icon}); -} - -/// @nodoc -class __$$EntryBlueprintImplCopyWithImpl<$Res> - extends _$EntryBlueprintCopyWithImpl<$Res, _$EntryBlueprintImpl> - implements _$$EntryBlueprintImplCopyWith<$Res> { - __$$EntryBlueprintImplCopyWithImpl( - _$EntryBlueprintImpl _value, $Res Function(_$EntryBlueprintImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? description = null, - Object? adapter = null, - Object? fields = freezed, - Object? tags = null, - Object? color = null, - Object? icon = null, - }) { - return _then(_$EntryBlueprintImpl( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - description: null == description - ? _value.description - : description // ignore: cast_nullable_to_non_nullable - as String, - adapter: null == adapter - ? _value.adapter - : adapter // ignore: cast_nullable_to_non_nullable - as String, - fields: freezed == fields - ? _value.fields - : fields // ignore: cast_nullable_to_non_nullable - as ObjectField, - tags: null == tags - ? _value._tags - : tags // ignore: cast_nullable_to_non_nullable - as List, - color: null == color - ? _value.color - : color // ignore: cast_nullable_to_non_nullable - as Color, - icon: null == icon - ? _value.icon - : icon // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$EntryBlueprintImpl - with DiagnosticableTreeMixin - implements _EntryBlueprint { - const _$EntryBlueprintImpl( - {required this.name, - required this.description, - required this.adapter, - required this.fields, - final List tags = const [], - @ColorConverter() this.color = Colors.grey, - this.icon = TWIcons.help}) - : _tags = tags; - - factory _$EntryBlueprintImpl.fromJson(Map json) => - _$$EntryBlueprintImplFromJson(json); - - @override - final String name; - @override - final String description; - @override - final String adapter; - @override - final ObjectField fields; - final List _tags; - @override - @JsonKey() - List get tags { - if (_tags is EqualUnmodifiableListView) return _tags; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_tags); - } - - @override - @JsonKey() - @ColorConverter() - final Color color; - @override - @JsonKey() - final String icon; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'EntryBlueprint(name: $name, description: $description, adapter: $adapter, fields: $fields, tags: $tags, color: $color, icon: $icon)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'EntryBlueprint')) - ..add(DiagnosticsProperty('name', name)) - ..add(DiagnosticsProperty('description', description)) - ..add(DiagnosticsProperty('adapter', adapter)) - ..add(DiagnosticsProperty('fields', fields)) - ..add(DiagnosticsProperty('tags', tags)) - ..add(DiagnosticsProperty('color', color)) - ..add(DiagnosticsProperty('icon', icon)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$EntryBlueprintImpl && - (identical(other.name, name) || other.name == name) && - (identical(other.description, description) || - other.description == description) && - (identical(other.adapter, adapter) || other.adapter == adapter) && - const DeepCollectionEquality().equals(other.fields, fields) && - const DeepCollectionEquality().equals(other._tags, _tags) && - (identical(other.color, color) || other.color == color) && - (identical(other.icon, icon) || other.icon == icon)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - name, - description, - adapter, - const DeepCollectionEquality().hash(fields), - const DeepCollectionEquality().hash(_tags), - color, - icon); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$EntryBlueprintImplCopyWith<_$EntryBlueprintImpl> get copyWith => - __$$EntryBlueprintImplCopyWithImpl<_$EntryBlueprintImpl>( - this, _$identity); - - @override - Map toJson() { - return _$$EntryBlueprintImplToJson( - this, - ); - } -} - -abstract class _EntryBlueprint implements EntryBlueprint { - const factory _EntryBlueprint( - {required final String name, - required final String description, - required final String adapter, - required final ObjectField fields, - final List tags, - @ColorConverter() final Color color, - final String icon}) = _$EntryBlueprintImpl; - - factory _EntryBlueprint.fromJson(Map json) = - _$EntryBlueprintImpl.fromJson; - - @override - String get name; - @override - String get description; - @override - String get adapter; - @override - ObjectField get fields; - @override - List get tags; - @override - @ColorConverter() - Color get color; - @override - String get icon; - @override - @JsonKey(ignore: true) - _$$EntryBlueprintImplCopyWith<_$EntryBlueprintImpl> get copyWith => - throw _privateConstructorUsedError; -} - -FieldInfo _$FieldInfoFromJson(Map json) { - switch (json['kind']) { - case 'default': - return _FieldType.fromJson(json); - case 'primitive': - return PrimitiveField.fromJson(json); - case 'enum': - return EnumField.fromJson(json); - case 'list': - return ListField.fromJson(json); - case 'map': - return MapField.fromJson(json); - case 'object': - return ObjectField.fromJson(json); - case 'custom': - return CustomField.fromJson(json); - - default: - throw CheckedFromJsonException( - json, 'kind', 'FieldInfo', 'Invalid union type "${json['kind']}"!'); - } -} - -/// @nodoc -mixin _$FieldInfo { - List get modifiers => throw _privateConstructorUsedError; - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $FieldInfoCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $FieldInfoCopyWith<$Res> { - factory $FieldInfoCopyWith(FieldInfo value, $Res Function(FieldInfo) then) = - _$FieldInfoCopyWithImpl<$Res, FieldInfo>; - @useResult - $Res call({List modifiers}); -} - -/// @nodoc -class _$FieldInfoCopyWithImpl<$Res, $Val extends FieldInfo> - implements $FieldInfoCopyWith<$Res> { - _$FieldInfoCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? modifiers = null, - }) { - return _then(_value.copyWith( - modifiers: null == modifiers - ? _value.modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$FieldTypeImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$FieldTypeImplCopyWith( - _$FieldTypeImpl value, $Res Function(_$FieldTypeImpl) then) = - __$$FieldTypeImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({List modifiers}); -} - -/// @nodoc -class __$$FieldTypeImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$FieldTypeImpl> - implements _$$FieldTypeImplCopyWith<$Res> { - __$$FieldTypeImplCopyWithImpl( - _$FieldTypeImpl _value, $Res Function(_$FieldTypeImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? modifiers = null, - }) { - return _then(_$FieldTypeImpl( - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$FieldTypeImpl with DiagnosticableTreeMixin implements _FieldType { - const _$FieldTypeImpl( - {final List modifiers = const [], final String? $type}) - : _modifiers = modifiers, - $type = $type ?? 'default'; - - factory _$FieldTypeImpl.fromJson(Map json) => - _$$FieldTypeImplFromJson(json); - - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo(modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo')) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$FieldTypeImpl && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => - Object.hash(runtimeType, const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$FieldTypeImplCopyWith<_$FieldTypeImpl> get copyWith => - __$$FieldTypeImplCopyWithImpl<_$FieldTypeImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return $default(modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return $default?.call(modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if ($default != null) { - return $default(modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return $default(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return $default?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if ($default != null) { - return $default(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$FieldTypeImplToJson( - this, - ); - } -} - -abstract class _FieldType implements FieldInfo { - const factory _FieldType({final List modifiers}) = _$FieldTypeImpl; - - factory _FieldType.fromJson(Map json) = - _$FieldTypeImpl.fromJson; - - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$FieldTypeImplCopyWith<_$FieldTypeImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$PrimitiveFieldImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$PrimitiveFieldImplCopyWith(_$PrimitiveFieldImpl value, - $Res Function(_$PrimitiveFieldImpl) then) = - __$$PrimitiveFieldImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({PrimitiveFieldType type, List modifiers}); -} - -/// @nodoc -class __$$PrimitiveFieldImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$PrimitiveFieldImpl> - implements _$$PrimitiveFieldImplCopyWith<$Res> { - __$$PrimitiveFieldImplCopyWithImpl( - _$PrimitiveFieldImpl _value, $Res Function(_$PrimitiveFieldImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? type = null, - Object? modifiers = null, - }) { - return _then(_$PrimitiveFieldImpl( - type: null == type - ? _value.type - : type // ignore: cast_nullable_to_non_nullable - as PrimitiveFieldType, - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$PrimitiveFieldImpl - with DiagnosticableTreeMixin - implements PrimitiveField { - const _$PrimitiveFieldImpl( - {required this.type, - final List modifiers = const [], - final String? $type}) - : _modifiers = modifiers, - $type = $type ?? 'primitive'; - - factory _$PrimitiveFieldImpl.fromJson(Map json) => - _$$PrimitiveFieldImplFromJson(json); - - @override - final PrimitiveFieldType type; - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo.primitive(type: $type, modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo.primitive')) - ..add(DiagnosticsProperty('type', type)) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$PrimitiveFieldImpl && - (identical(other.type, type) || other.type == type) && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, type, const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$PrimitiveFieldImplCopyWith<_$PrimitiveFieldImpl> get copyWith => - __$$PrimitiveFieldImplCopyWithImpl<_$PrimitiveFieldImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return primitive(type, modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return primitive?.call(type, modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if (primitive != null) { - return primitive(type, modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return primitive(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return primitive?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if (primitive != null) { - return primitive(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$PrimitiveFieldImplToJson( - this, - ); - } -} - -abstract class PrimitiveField implements FieldInfo { - const factory PrimitiveField( - {required final PrimitiveFieldType type, - final List modifiers}) = _$PrimitiveFieldImpl; - - factory PrimitiveField.fromJson(Map json) = - _$PrimitiveFieldImpl.fromJson; - - PrimitiveFieldType get type; - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$PrimitiveFieldImplCopyWith<_$PrimitiveFieldImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$EnumFieldImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$EnumFieldImplCopyWith( - _$EnumFieldImpl value, $Res Function(_$EnumFieldImpl) then) = - __$$EnumFieldImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({List values, List modifiers}); -} - -/// @nodoc -class __$$EnumFieldImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$EnumFieldImpl> - implements _$$EnumFieldImplCopyWith<$Res> { - __$$EnumFieldImplCopyWithImpl( - _$EnumFieldImpl _value, $Res Function(_$EnumFieldImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? values = null, - Object? modifiers = null, - }) { - return _then(_$EnumFieldImpl( - values: null == values - ? _value._values - : values // ignore: cast_nullable_to_non_nullable - as List, - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$EnumFieldImpl with DiagnosticableTreeMixin implements EnumField { - const _$EnumFieldImpl( - {required final List values, - final List modifiers = const [], - final String? $type}) - : _values = values, - _modifiers = modifiers, - $type = $type ?? 'enum'; - - factory _$EnumFieldImpl.fromJson(Map json) => - _$$EnumFieldImplFromJson(json); - - final List _values; - @override - List get values { - if (_values is EqualUnmodifiableListView) return _values; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_values); - } - - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo.enumField(values: $values, modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo.enumField')) - ..add(DiagnosticsProperty('values', values)) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$EnumFieldImpl && - const DeepCollectionEquality().equals(other._values, _values) && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - const DeepCollectionEquality().hash(_values), - const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$EnumFieldImplCopyWith<_$EnumFieldImpl> get copyWith => - __$$EnumFieldImplCopyWithImpl<_$EnumFieldImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return enumField(values, modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return enumField?.call(values, modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if (enumField != null) { - return enumField(values, modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return enumField(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return enumField?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if (enumField != null) { - return enumField(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$EnumFieldImplToJson( - this, - ); - } -} - -abstract class EnumField implements FieldInfo { - const factory EnumField( - {required final List values, - final List modifiers}) = _$EnumFieldImpl; - - factory EnumField.fromJson(Map json) = - _$EnumFieldImpl.fromJson; - - List get values; - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$EnumFieldImplCopyWith<_$EnumFieldImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$ListFieldImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$ListFieldImplCopyWith( - _$ListFieldImpl value, $Res Function(_$ListFieldImpl) then) = - __$$ListFieldImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({FieldInfo type, List modifiers}); - - $FieldInfoCopyWith<$Res> get type; -} - -/// @nodoc -class __$$ListFieldImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$ListFieldImpl> - implements _$$ListFieldImplCopyWith<$Res> { - __$$ListFieldImplCopyWithImpl( - _$ListFieldImpl _value, $Res Function(_$ListFieldImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? type = null, - Object? modifiers = null, - }) { - return _then(_$ListFieldImpl( - type: null == type - ? _value.type - : type // ignore: cast_nullable_to_non_nullable - as FieldInfo, - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } - - @override - @pragma('vm:prefer-inline') - $FieldInfoCopyWith<$Res> get type { - return $FieldInfoCopyWith<$Res>(_value.type, (value) { - return _then(_value.copyWith(type: value)); - }); - } -} - -/// @nodoc -@JsonSerializable() -class _$ListFieldImpl with DiagnosticableTreeMixin implements ListField { - const _$ListFieldImpl( - {required this.type, - final List modifiers = const [], - final String? $type}) - : _modifiers = modifiers, - $type = $type ?? 'list'; - - factory _$ListFieldImpl.fromJson(Map json) => - _$$ListFieldImplFromJson(json); - - @override - final FieldInfo type; - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo.list(type: $type, modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo.list')) - ..add(DiagnosticsProperty('type', type)) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ListFieldImpl && - (identical(other.type, type) || other.type == type) && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, type, const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$ListFieldImplCopyWith<_$ListFieldImpl> get copyWith => - __$$ListFieldImplCopyWithImpl<_$ListFieldImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return list(type, modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return list?.call(type, modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if (list != null) { - return list(type, modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return list(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return list?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if (list != null) { - return list(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$ListFieldImplToJson( - this, - ); - } -} - -abstract class ListField implements FieldInfo { - const factory ListField( - {required final FieldInfo type, - final List modifiers}) = _$ListFieldImpl; - - factory ListField.fromJson(Map json) = - _$ListFieldImpl.fromJson; - - FieldInfo get type; - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$ListFieldImplCopyWith<_$ListFieldImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$MapFieldImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$MapFieldImplCopyWith( - _$MapFieldImpl value, $Res Function(_$MapFieldImpl) then) = - __$$MapFieldImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({FieldInfo key, FieldInfo value, List modifiers}); - - $FieldInfoCopyWith<$Res> get key; - $FieldInfoCopyWith<$Res> get value; -} - -/// @nodoc -class __$$MapFieldImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$MapFieldImpl> - implements _$$MapFieldImplCopyWith<$Res> { - __$$MapFieldImplCopyWithImpl( - _$MapFieldImpl _value, $Res Function(_$MapFieldImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? key = null, - Object? value = null, - Object? modifiers = null, - }) { - return _then(_$MapFieldImpl( - key: null == key - ? _value.key - : key // ignore: cast_nullable_to_non_nullable - as FieldInfo, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as FieldInfo, - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } - - @override - @pragma('vm:prefer-inline') - $FieldInfoCopyWith<$Res> get key { - return $FieldInfoCopyWith<$Res>(_value.key, (value) { - return _then(_value.copyWith(key: value)); - }); - } - - @override - @pragma('vm:prefer-inline') - $FieldInfoCopyWith<$Res> get value { - return $FieldInfoCopyWith<$Res>(_value.value, (value) { - return _then(_value.copyWith(value: value)); - }); - } -} - -/// @nodoc -@JsonSerializable() -class _$MapFieldImpl with DiagnosticableTreeMixin implements MapField { - const _$MapFieldImpl( - {required this.key, - required this.value, - final List modifiers = const [], - final String? $type}) - : _modifiers = modifiers, - $type = $type ?? 'map'; - - factory _$MapFieldImpl.fromJson(Map json) => - _$$MapFieldImplFromJson(json); - - @override - final FieldInfo key; - @override - final FieldInfo value; - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo.map(key: $key, value: $value, modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo.map')) - ..add(DiagnosticsProperty('key', key)) - ..add(DiagnosticsProperty('value', value)) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$MapFieldImpl && - (identical(other.key, key) || other.key == key) && - (identical(other.value, value) || other.value == value) && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, key, value, const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$MapFieldImplCopyWith<_$MapFieldImpl> get copyWith => - __$$MapFieldImplCopyWithImpl<_$MapFieldImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return map(key, value, modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return map?.call(key, value, modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if (map != null) { - return map(key, value, modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return map(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return map?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if (map != null) { - return map(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$MapFieldImplToJson( - this, - ); - } -} - -abstract class MapField implements FieldInfo { - const factory MapField( - {required final FieldInfo key, - required final FieldInfo value, - final List modifiers}) = _$MapFieldImpl; - - factory MapField.fromJson(Map json) = - _$MapFieldImpl.fromJson; - - FieldInfo get key; - FieldInfo get value; - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$MapFieldImplCopyWith<_$MapFieldImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$ObjectFieldImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$ObjectFieldImplCopyWith( - _$ObjectFieldImpl value, $Res Function(_$ObjectFieldImpl) then) = - __$$ObjectFieldImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({Map fields, List modifiers}); -} - -/// @nodoc -class __$$ObjectFieldImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$ObjectFieldImpl> - implements _$$ObjectFieldImplCopyWith<$Res> { - __$$ObjectFieldImplCopyWithImpl( - _$ObjectFieldImpl _value, $Res Function(_$ObjectFieldImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? fields = null, - Object? modifiers = null, - }) { - return _then(_$ObjectFieldImpl( - fields: null == fields - ? _value._fields - : fields // ignore: cast_nullable_to_non_nullable - as Map, - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$ObjectFieldImpl with DiagnosticableTreeMixin implements ObjectField { - const _$ObjectFieldImpl( - {required final Map fields, - final List modifiers = const [], - final String? $type}) - : _fields = fields, - _modifiers = modifiers, - $type = $type ?? 'object'; - - factory _$ObjectFieldImpl.fromJson(Map json) => - _$$ObjectFieldImplFromJson(json); - - final Map _fields; - @override - Map get fields { - if (_fields is EqualUnmodifiableMapView) return _fields; - // ignore: implicit_dynamic_type - return EqualUnmodifiableMapView(_fields); - } - - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo.object(fields: $fields, modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo.object')) - ..add(DiagnosticsProperty('fields', fields)) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ObjectFieldImpl && - const DeepCollectionEquality().equals(other._fields, _fields) && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - const DeepCollectionEquality().hash(_fields), - const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$ObjectFieldImplCopyWith<_$ObjectFieldImpl> get copyWith => - __$$ObjectFieldImplCopyWithImpl<_$ObjectFieldImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return object(fields, modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return object?.call(fields, modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if (object != null) { - return object(fields, modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return object(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return object?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if (object != null) { - return object(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$ObjectFieldImplToJson( - this, - ); - } -} - -abstract class ObjectField implements FieldInfo { - const factory ObjectField( - {required final Map fields, - final List modifiers}) = _$ObjectFieldImpl; - - factory ObjectField.fromJson(Map json) = - _$ObjectFieldImpl.fromJson; - - Map get fields; - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$ObjectFieldImplCopyWith<_$ObjectFieldImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$CustomFieldImplCopyWith<$Res> - implements $FieldInfoCopyWith<$Res> { - factory _$$CustomFieldImplCopyWith( - _$CustomFieldImpl value, $Res Function(_$CustomFieldImpl) then) = - __$$CustomFieldImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers}); - - $FieldInfoCopyWith<$Res>? get fieldInfo; -} - -/// @nodoc -class __$$CustomFieldImplCopyWithImpl<$Res> - extends _$FieldInfoCopyWithImpl<$Res, _$CustomFieldImpl> - implements _$$CustomFieldImplCopyWith<$Res> { - __$$CustomFieldImplCopyWithImpl( - _$CustomFieldImpl _value, $Res Function(_$CustomFieldImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? editor = null, - Object? defaultValue = freezed, - Object? fieldInfo = freezed, - Object? modifiers = null, - }) { - return _then(_$CustomFieldImpl( - editor: null == editor - ? _value.editor - : editor // ignore: cast_nullable_to_non_nullable - as String, - defaultValue: freezed == defaultValue - ? _value.defaultValue - : defaultValue // ignore: cast_nullable_to_non_nullable - as dynamic, - fieldInfo: freezed == fieldInfo - ? _value.fieldInfo - : fieldInfo // ignore: cast_nullable_to_non_nullable - as FieldInfo?, - modifiers: null == modifiers - ? _value._modifiers - : modifiers // ignore: cast_nullable_to_non_nullable - as List, - )); - } - - @override - @pragma('vm:prefer-inline') - $FieldInfoCopyWith<$Res>? get fieldInfo { - if (_value.fieldInfo == null) { - return null; - } - - return $FieldInfoCopyWith<$Res>(_value.fieldInfo!, (value) { - return _then(_value.copyWith(fieldInfo: value)); - }); - } -} - -/// @nodoc -@JsonSerializable() -class _$CustomFieldImpl with DiagnosticableTreeMixin implements CustomField { - const _$CustomFieldImpl( - {required this.editor, - @JsonKey(name: "default") this.defaultValue, - this.fieldInfo, - final List modifiers = const [], - final String? $type}) - : _modifiers = modifiers, - $type = $type ?? 'custom'; - - factory _$CustomFieldImpl.fromJson(Map json) => - _$$CustomFieldImplFromJson(json); - - @override - final String editor; - @override - @JsonKey(name: "default") - final dynamic defaultValue; - @override - final FieldInfo? fieldInfo; - final List _modifiers; - @override - @JsonKey() - List get modifiers { - if (_modifiers is EqualUnmodifiableListView) return _modifiers; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_modifiers); - } - - @JsonKey(name: 'kind') - final String $type; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'FieldInfo.custom(editor: $editor, defaultValue: $defaultValue, fieldInfo: $fieldInfo, modifiers: $modifiers)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'FieldInfo.custom')) - ..add(DiagnosticsProperty('editor', editor)) - ..add(DiagnosticsProperty('defaultValue', defaultValue)) - ..add(DiagnosticsProperty('fieldInfo', fieldInfo)) - ..add(DiagnosticsProperty('modifiers', modifiers)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$CustomFieldImpl && - (identical(other.editor, editor) || other.editor == editor) && - const DeepCollectionEquality() - .equals(other.defaultValue, defaultValue) && - (identical(other.fieldInfo, fieldInfo) || - other.fieldInfo == fieldInfo) && - const DeepCollectionEquality() - .equals(other._modifiers, _modifiers)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, - editor, - const DeepCollectionEquality().hash(defaultValue), - fieldInfo, - const DeepCollectionEquality().hash(_modifiers)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$CustomFieldImplCopyWith<_$CustomFieldImpl> get copyWith => - __$$CustomFieldImplCopyWithImpl<_$CustomFieldImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(List modifiers) $default, { - required TResult Function(PrimitiveFieldType type, List modifiers) - primitive, - required TResult Function(List values, List modifiers) - enumField, - required TResult Function(FieldInfo type, List modifiers) list, - required TResult Function( - FieldInfo key, FieldInfo value, List modifiers) - map, - required TResult Function( - Map fields, List modifiers) - object, - required TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers) - custom, - }) { - return custom(editor, defaultValue, fieldInfo, modifiers); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(List modifiers)? $default, { - TResult? Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult? Function(List values, List modifiers)? enumField, - TResult? Function(FieldInfo type, List modifiers)? list, - TResult? Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult? Function(Map fields, List modifiers)? - object, - TResult? Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - }) { - return custom?.call(editor, defaultValue, fieldInfo, modifiers); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(List modifiers)? $default, { - TResult Function(PrimitiveFieldType type, List modifiers)? - primitive, - TResult Function(List values, List modifiers)? enumField, - TResult Function(FieldInfo type, List modifiers)? list, - TResult Function(FieldInfo key, FieldInfo value, List modifiers)? - map, - TResult Function(Map fields, List modifiers)? - object, - TResult Function( - String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, - List modifiers)? - custom, - required TResult orElse(), - }) { - if (custom != null) { - return custom(editor, defaultValue, fieldInfo, modifiers); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_FieldType value) $default, { - required TResult Function(PrimitiveField value) primitive, - required TResult Function(EnumField value) enumField, - required TResult Function(ListField value) list, - required TResult Function(MapField value) map, - required TResult Function(ObjectField value) object, - required TResult Function(CustomField value) custom, - }) { - return custom(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_FieldType value)? $default, { - TResult? Function(PrimitiveField value)? primitive, - TResult? Function(EnumField value)? enumField, - TResult? Function(ListField value)? list, - TResult? Function(MapField value)? map, - TResult? Function(ObjectField value)? object, - TResult? Function(CustomField value)? custom, - }) { - return custom?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_FieldType value)? $default, { - TResult Function(PrimitiveField value)? primitive, - TResult Function(EnumField value)? enumField, - TResult Function(ListField value)? list, - TResult Function(MapField value)? map, - TResult Function(ObjectField value)? object, - TResult Function(CustomField value)? custom, - required TResult orElse(), - }) { - if (custom != null) { - return custom(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$CustomFieldImplToJson( - this, - ); - } -} - -abstract class CustomField implements FieldInfo { - const factory CustomField( - {required final String editor, - @JsonKey(name: "default") final dynamic defaultValue, - final FieldInfo? fieldInfo, - final List modifiers}) = _$CustomFieldImpl; - - factory CustomField.fromJson(Map json) = - _$CustomFieldImpl.fromJson; - - String get editor; - @JsonKey(name: "default") - dynamic get defaultValue; - FieldInfo? get fieldInfo; - @override - List get modifiers; - @override - @JsonKey(ignore: true) - _$$CustomFieldImplCopyWith<_$CustomFieldImpl> get copyWith => - throw _privateConstructorUsedError; -} - -Modifier _$ModifierFromJson(Map json) { - return _Modifier.fromJson(json); -} - -/// @nodoc -mixin _$Modifier { - String get name => throw _privateConstructorUsedError; - dynamic get data => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $ModifierCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ModifierCopyWith<$Res> { - factory $ModifierCopyWith(Modifier value, $Res Function(Modifier) then) = - _$ModifierCopyWithImpl<$Res, Modifier>; - @useResult - $Res call({String name, dynamic data}); -} - -/// @nodoc -class _$ModifierCopyWithImpl<$Res, $Val extends Modifier> - implements $ModifierCopyWith<$Res> { - _$ModifierCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? data = freezed, - }) { - return _then(_value.copyWith( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - data: freezed == data - ? _value.data - : data // ignore: cast_nullable_to_non_nullable - as dynamic, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$ModifierImplCopyWith<$Res> - implements $ModifierCopyWith<$Res> { - factory _$$ModifierImplCopyWith( - _$ModifierImpl value, $Res Function(_$ModifierImpl) then) = - __$$ModifierImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({String name, dynamic data}); -} - -/// @nodoc -class __$$ModifierImplCopyWithImpl<$Res> - extends _$ModifierCopyWithImpl<$Res, _$ModifierImpl> - implements _$$ModifierImplCopyWith<$Res> { - __$$ModifierImplCopyWithImpl( - _$ModifierImpl _value, $Res Function(_$ModifierImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? name = null, - Object? data = freezed, - }) { - return _then(_$ModifierImpl( - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - data: freezed == data - ? _value.data - : data // ignore: cast_nullable_to_non_nullable - as dynamic, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$ModifierImpl with DiagnosticableTreeMixin implements _Modifier { - const _$ModifierImpl({required this.name, this.data}); - - factory _$ModifierImpl.fromJson(Map json) => - _$$ModifierImplFromJson(json); - - @override - final String name; - @override - final dynamic data; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Modifier(name: $name, data: $data)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'Modifier')) - ..add(DiagnosticsProperty('name', name)) - ..add(DiagnosticsProperty('data', data)); - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ModifierImpl && - (identical(other.name, name) || other.name == name) && - const DeepCollectionEquality().equals(other.data, data)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => - Object.hash(runtimeType, name, const DeepCollectionEquality().hash(data)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$ModifierImplCopyWith<_$ModifierImpl> get copyWith => - __$$ModifierImplCopyWithImpl<_$ModifierImpl>(this, _$identity); - - @override - Map toJson() { - return _$$ModifierImplToJson( - this, - ); - } -} - -abstract class _Modifier implements Modifier { - const factory _Modifier({required final String name, final dynamic data}) = - _$ModifierImpl; - - factory _Modifier.fromJson(Map json) = - _$ModifierImpl.fromJson; - - @override - String get name; - @override - dynamic get data; - @override - @JsonKey(ignore: true) - _$$ModifierImplCopyWith<_$ModifierImpl> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/app/lib/models/book.dart b/app/lib/models/book.dart index 449c7757c4..9d20f717d4 100644 --- a/app/lib/models/book.dart +++ b/app/lib/models/book.dart @@ -2,16 +2,18 @@ import "package:collection/collection.dart"; import "package:collection_ext/all.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/communicator.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; +import "package:typewriter/models/extension.dart"; import "package:typewriter/models/page.dart"; +import "package:typewriter/utils/extensions.dart"; part "book.freezed.dart"; final bookProvider = StateNotifierProvider( (ref) => - BookNotifier(const Book(name: "", adapters: [], pages: []), ref: ref), + BookNotifier(const Book(name: "", extensions: [], pages: []), ref: ref), name: "bookProvider", ); @@ -19,7 +21,7 @@ final bookProvider = StateNotifierProvider( class Book with _$Book { const factory Book({ required String name, - required List adapters, + required List extensions, required List pages, }) = _Book; } @@ -35,49 +37,59 @@ class BookNotifier extends StateNotifier { bool updateShouldNotify(Book old, Book current) => old != current; /// Creates a new page. - Future createPage( + Future createPage( String name, [ PageType type = PageType.static, String chapter = "", int priority = 0, ]) async { - final page = - Page(pageName: name, type: type, chapter: chapter, priority: priority); + final page = Page( + id: getRandomString(), + pageName: name, + type: type, + chapter: chapter, + priority: priority, + ); await ref.read(communicatorProvider).createPage(page); state = state.copyWith( pages: [...state.pages, page], ); + return page; } /// Inserts a page. If the page already exists, it will be replaced. void insertPage(Page page) { state = state.copyWith( - pages: state.pages - .map((p) => p.pageName == page.pageName ? page : p) - .toList(), + pages: state.pages.map((p) => p.id == page.id ? page : p).toList(), ); } /// Rename a page. /// If the page does not exist, it will be added. - Future renamePage(String old, String newName) async { - final page = state.pages.firstWhereOrNull((p) => p.pageName == old); + Future renamePage(String pageId, String newName) async { + final page = state.pages.firstWhereOrNull((p) => p.id == pageId); if (page == null) return; - await ref.read(communicatorProvider).renamePage(old, newName); - syncRenamePage(old, newName); + await ref.read(communicatorProvider).renamePage(pageId, newName); + syncRenamePage(pageId, newName); } /// Deletes a page. - Future deletePage(String name) async { - await ref.read(communicatorProvider).deletePage(name); - syncDeletePage(name); + Future deletePage(String pageId) async { + await ref.read(communicatorProvider).deletePage(pageId); + syncDeletePage(pageId); } ///Moves an entry from one page to another. - Future moveEntry(String entryId, String fromPage, String toPage) async { - if (fromPage == toPage) return; - await ref.read(communicatorProvider).moveEntry(entryId, fromPage, toPage); - syncMoveEntry(entryId, fromPage, toPage); + Future moveEntry( + String entryId, + String fromPageId, + String toPageId, + ) async { + if (fromPageId == toPageId) return; + await ref + .read(communicatorProvider) + .moveEntry(entryId, fromPageId, toPageId); + syncMoveEntry(entryId, fromPageId, toPageId); } /// Reloads the book from the server. @@ -86,41 +98,33 @@ class BookNotifier extends StateNotifier { } /// Only for internal use. - void syncRenamePage(String old, String newName) { - final page = state.pages.firstWhereOrNull((p) => p.pageName == old); + void syncRenamePage(String pageId, String newName) { + final page = state.pages.firstWhereOrNull((p) => p.id == pageId); if (page == null) return; - state = state.copyWith( - pages: [ - ...state.pages - .where((p) => p.pageName != old) - .map((p) => _fixPage(p, old, newName)), - _fixPage(page, old, newName).copyWith(pageName: newName), - ], - ); + insertPage(page.copyWith(pageName: newName)); } /// Only for internal use. - void syncDeletePage(String name) { + void syncDeletePage(String pageId) { state = state.copyWith( pages: state.pages - .where((p) => p.pageName != name) - .map((p) => _fixPage(p, name, null)) + .where((p) => p.id != pageId) + .map((p) => _removePageReferences(p, pageId)) .toList(), ); } /// Only for internal use. - void syncMoveEntry(String entryId, String fromPage, String toPage) { - final from = state.pages.firstWhereOrNull((p) => p.pageName == fromPage); - final to = state.pages.firstWhereOrNull((p) => p.pageName == toPage); + void syncMoveEntry(String entryId, String fromPageId, String toPageId) { + final from = state.pages.firstWhereOrNull((p) => p.id == fromPageId); + final to = state.pages.firstWhereOrNull((p) => p.id == toPageId); if (from == null || to == null) return; final entry = from.entries.firstWhereOrNull((e) => e.id == entryId); if (entry == null) return; state = state.copyWith( pages: [ - ...state.pages - .where((p) => p.pageName != fromPage && p.pageName != toPage), + ...state.pages.where((p) => p.id != fromPageId && p.id != toPageId), from.copyWith( entries: from.entries.where((e) => e.id != entryId).toList(), ), @@ -129,11 +133,11 @@ class BookNotifier extends StateNotifier { ); } - /// Fix page references. This is called for all other pages when a page is renamed or deleted. - Page _fixPage(Page page, String targetId, String? newId) { + /// Remove page references from entries. + Page _removePageReferences(Page page, String targetPageId) { final newEntries = page.entries .map( - (entry) => _removedReferencesFromEntry(page, entry, targetId, newId), + (entry) => _removedReferencesFromEntry(page, entry, targetPageId), ) .toList(); return page.copyWith(entries: newEntries); @@ -143,12 +147,11 @@ class BookNotifier extends StateNotifier { Entry _removedReferencesFromEntry( Page page, Entry entry, - String targetId, - String? newId, + String targetPageId, ) { - final referenceEntryPaths = state.adapters - .flatMap((adapter) => adapter.entries) - .firstWhereOrNull((blueprint) => blueprint.name == entry.type) + final referenceEntryPaths = state.extensions + .flatMap((extension) => extension.entries) + .firstWhereOrNull((blueprint) => blueprint.id == entry.blueprintId) ?.fieldsWithModifier("page") .keys .toList() ?? @@ -158,7 +161,7 @@ class BookNotifier extends StateNotifier { .expand((path) => entry.getAll(path)) .whereType() .toList(); - if (!referenceEntryIds.contains(targetId)) { + if (!referenceEntryIds.contains(targetPageId)) { return entry; } @@ -166,11 +169,11 @@ class BookNotifier extends StateNotifier { entry, (previousEntry, path) => previousEntry.copyMapped( path, - (value) => value == targetId ? newId : value, + (value) => value == targetPageId ? null : value, ), ); - ref.read(communicatorProvider).updateEntireEntry(page.pageName, newEntry); + ref.read(communicatorProvider).updateEntireEntry(page.id, newEntry); return newEntry; } diff --git a/app/lib/models/book.freezed.dart b/app/lib/models/book.freezed.dart index 9b7384a1b7..63ddf18f26 100644 --- a/app/lib/models/book.freezed.dart +++ b/app/lib/models/book.freezed.dart @@ -17,10 +17,12 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$Book { String get name => throw _privateConstructorUsedError; - List get adapters => throw _privateConstructorUsedError; + List get extensions => throw _privateConstructorUsedError; List get pages => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of Book + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $BookCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -29,7 +31,7 @@ abstract class $BookCopyWith<$Res> { factory $BookCopyWith(Book value, $Res Function(Book) then) = _$BookCopyWithImpl<$Res, Book>; @useResult - $Res call({String name, List adapters, List pages}); + $Res call({String name, List extensions, List pages}); } /// @nodoc @@ -42,11 +44,13 @@ class _$BookCopyWithImpl<$Res, $Val extends Book> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Book + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ Object? name = null, - Object? adapters = null, + Object? extensions = null, Object? pages = null, }) { return _then(_value.copyWith( @@ -54,10 +58,10 @@ class _$BookCopyWithImpl<$Res, $Val extends Book> ? _value.name : name // ignore: cast_nullable_to_non_nullable as String, - adapters: null == adapters - ? _value.adapters - : adapters // ignore: cast_nullable_to_non_nullable - as List, + extensions: null == extensions + ? _value.extensions + : extensions // ignore: cast_nullable_to_non_nullable + as List, pages: null == pages ? _value.pages : pages // ignore: cast_nullable_to_non_nullable @@ -73,7 +77,7 @@ abstract class _$$BookImplCopyWith<$Res> implements $BookCopyWith<$Res> { __$$BookImplCopyWithImpl<$Res>; @override @useResult - $Res call({String name, List adapters, List pages}); + $Res call({String name, List extensions, List pages}); } /// @nodoc @@ -83,11 +87,13 @@ class __$$BookImplCopyWithImpl<$Res> __$$BookImplCopyWithImpl(_$BookImpl _value, $Res Function(_$BookImpl) _then) : super(_value, _then); + /// Create a copy of Book + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ Object? name = null, - Object? adapters = null, + Object? extensions = null, Object? pages = null, }) { return _then(_$BookImpl( @@ -95,10 +101,10 @@ class __$$BookImplCopyWithImpl<$Res> ? _value.name : name // ignore: cast_nullable_to_non_nullable as String, - adapters: null == adapters - ? _value._adapters - : adapters // ignore: cast_nullable_to_non_nullable - as List, + extensions: null == extensions + ? _value._extensions + : extensions // ignore: cast_nullable_to_non_nullable + as List, pages: null == pages ? _value._pages : pages // ignore: cast_nullable_to_non_nullable @@ -112,19 +118,19 @@ class __$$BookImplCopyWithImpl<$Res> class _$BookImpl implements _Book { const _$BookImpl( {required this.name, - required final List adapters, + required final List extensions, required final List pages}) - : _adapters = adapters, + : _extensions = extensions, _pages = pages; @override final String name; - final List _adapters; + final List _extensions; @override - List get adapters { - if (_adapters is EqualUnmodifiableListView) return _adapters; + List get extensions { + if (_extensions is EqualUnmodifiableListView) return _extensions; // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_adapters); + return EqualUnmodifiableListView(_extensions); } final List _pages; @@ -137,7 +143,7 @@ class _$BookImpl implements _Book { @override String toString() { - return 'Book(name: $name, adapters: $adapters, pages: $pages)'; + return 'Book(name: $name, extensions: $extensions, pages: $pages)'; } @override @@ -146,7 +152,8 @@ class _$BookImpl implements _Book { (other.runtimeType == runtimeType && other is _$BookImpl && (identical(other.name, name) || other.name == name) && - const DeepCollectionEquality().equals(other._adapters, _adapters) && + const DeepCollectionEquality() + .equals(other._extensions, _extensions) && const DeepCollectionEquality().equals(other._pages, _pages)); } @@ -154,10 +161,12 @@ class _$BookImpl implements _Book { int get hashCode => Object.hash( runtimeType, name, - const DeepCollectionEquality().hash(_adapters), + const DeepCollectionEquality().hash(_extensions), const DeepCollectionEquality().hash(_pages)); - @JsonKey(ignore: true) + /// Create a copy of Book + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$BookImplCopyWith<_$BookImpl> get copyWith => @@ -167,17 +176,20 @@ class _$BookImpl implements _Book { abstract class _Book implements Book { const factory _Book( {required final String name, - required final List adapters, + required final List extensions, required final List pages}) = _$BookImpl; @override String get name; @override - List get adapters; + List get extensions; @override List get pages; + + /// Create a copy of Book + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$BookImplCopyWith<_$BookImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/communicator.dart b/app/lib/models/communicator.dart index d5b6f04e90..c48337b5ad 100644 --- a/app/lib/models/communicator.dart +++ b/app/lib/models/communicator.dart @@ -2,15 +2,15 @@ import "dart:async"; import "dart:convert"; import "package:flutter/material.dart" hide Page; -import "package:flutter_animate/flutter_animate.dart" hide Adapter; +import "package:flutter_animate/flutter_animate.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; import "package:socket_io_client/socket_io_client.dart"; import "package:typewriter/app_router.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/book.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/extension.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/models/staging.dart"; import "package:typewriter/models/writers.dart"; @@ -112,7 +112,7 @@ class SocketNotifier extends StateNotifier { return; } - var url = "http://$hostname:$port"; + var url = "//$hostname:$port"; if (token != null) url += "?token=$token"; debugPrint("Initializing socket"); @@ -241,18 +241,19 @@ class Communicator { } final String rawPages = await socket.emitWithAckAsync("fetch", "pages"); - final String rawAdapters = - await socket.emitWithAckAsync("fetch", "adapters"); + final String rawExtensions = + await socket.emitWithAckAsync("fetch", "extensions"); final jsonPages = jsonDecode(rawPages) as List; - final jsonAdapters = jsonDecode(rawAdapters) as List; + final jsonExtensions = jsonDecode(rawExtensions) as List; // ignore: unnecessary_lambdas final pages = jsonPages.map((p) => Page.fromJson(p)).toList(); // ignore: unnecessary_lambdas - final adapters = jsonAdapters.map((a) => Adapter.fromJson(a)).toList(); + final extensions = + jsonExtensions.map((a) => Extension.fromJson(a)).toList(); - final book = Book(name: "Typewriter", adapters: adapters, pages: pages); + final book = Book(name: "Typewriter", extensions: extensions, pages: pages); ref.read(bookProvider.notifier).book = book; } @@ -267,28 +268,32 @@ class Communicator { ); } - Future renamePage(String old, String newName) async { + Future renamePage(String pageId, String newName) async { final socket = ref.read(socketProvider); if (socket == null || !socket.connected) { return; } final data = { - "old": old, + "pageId": pageId, "new": newName, }; await socket.emitWithAckAsync("renamePage", jsonEncode(data)); } - Future changePageValue(String page, String path, dynamic value) async { + Future changePageValue( + String pageId, + String path, + dynamic value, + ) async { final socket = ref.read(socketProvider); if (socket == null || !socket.connected) { return; } final data = { - "pageId": page, + "pageId": pageId, "path": path, "value": value, }; @@ -298,18 +303,22 @@ class Communicator { ); } - Future deletePage(String name) async { + Future deletePage(String pageId) async { final socket = ref.read(socketProvider); if (socket == null || !socket.connected) { return; } handleAck( - await socket.emitWithAckAsync("deletePage", name), + await socket.emitWithAckAsync("deletePage", pageId), ); } - Future moveEntry(String entryId, String fromPage, String toPage) async { + Future moveEntry( + String entryId, + String fromPageId, + String toPageId, + ) async { final socket = ref.read(socketProvider); if (socket == null || !socket.connected) { return; @@ -317,8 +326,8 @@ class Communicator { final data = { "entryId": entryId, - "fromPage": fromPage, - "toPage": toPage, + "fromPageId": fromPageId, + "toPageId": toPageId, }; handleAck( @@ -326,14 +335,14 @@ class Communicator { ); } - Future createEntry(String page, Entry entry) async { + Future createEntry(String pageId, Entry entry) async { final socket = ref.read(socketProvider); if (socket == null || !socket.connected) { return; } final data = { - "pageId": page, + "pageId": pageId, "entry": entry.toJson(), }; @@ -474,22 +483,24 @@ class Communicator { void handleRenamePage(dynamic data) { final json = jsonDecode(data as String) as Map; - final old = json["old"] as String; + final pageId = json["pageId"] as String; final newName = json["new"] as String; - ref.read(bookProvider.notifier).syncRenamePage(old, newName); + ref.read(bookProvider.notifier).syncRenamePage(pageId, newName); } void handleDeletePage(dynamic data) { - final name = data as String; - ref.read(bookProvider.notifier).syncDeletePage(name); + final pageId = data as String; + ref.read(bookProvider.notifier).syncDeletePage(pageId); } void handleMoveEntry(dynamic data) { final json = jsonDecode(data as String) as Map; final entryId = json["entryId"] as String; - final fromPage = json["fromPage"] as String; - final toPage = json["toPage"] as String; - ref.read(bookProvider.notifier).syncMoveEntry(entryId, fromPage, toPage); + final fromPageId = json["fromPageId"] as String; + final toPageId = json["toPageId"] as String; + ref + .read(bookProvider.notifier) + .syncMoveEntry(entryId, fromPageId, toPageId); } void handleCreateEntry(dynamic data) { diff --git a/app/lib/models/communicator.freezed.dart b/app/lib/models/communicator.freezed.dart index 8e1e8f00f1..c9a6691e28 100644 --- a/app/lib/models/communicator.freezed.dart +++ b/app/lib/models/communicator.freezed.dart @@ -23,8 +23,12 @@ mixin _$Response { bool get success => throw _privateConstructorUsedError; String get message => throw _privateConstructorUsedError; + /// Serializes this Response to a JSON map. Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + + /// Create a copy of Response + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $ResponseCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -47,6 +51,8 @@ class _$ResponseCopyWithImpl<$Res, $Val extends Response> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Response + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -85,6 +91,8 @@ class __$$ResponseImplCopyWithImpl<$Res> _$ResponseImpl _value, $Res Function(_$ResponseImpl) _then) : super(_value, _then); + /// Create a copy of Response + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -131,11 +139,13 @@ class _$ResponseImpl implements _Response { (identical(other.message, message) || other.message == message)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, success, message); - @JsonKey(ignore: true) + /// Create a copy of Response + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$ResponseImplCopyWith<_$ResponseImpl> get copyWith => @@ -161,8 +171,11 @@ abstract class _Response implements Response { bool get success; @override String get message; + + /// Create a copy of Response + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$ResponseImplCopyWith<_$ResponseImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/entry.dart b/app/lib/models/entry.dart index 8338922757..f1b9029a26 100644 --- a/app/lib/models/entry.dart +++ b/app/lib/models/entry.dart @@ -2,7 +2,7 @@ import "dart:convert"; import "package:collection/collection.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -19,7 +19,7 @@ EntryDefinition? entryDefinition( return null; } final entry = ref.watch(entryProvider(pageId, entryId)); - final blueprint = ref.watch(entryBlueprintProvider(entry?.type ?? "")); + final blueprint = ref.watch(entryBlueprintProvider(entry?.blueprintId ?? "")); if (entry == null || blueprint == null) { return null; } @@ -33,9 +33,9 @@ String? entryName(EntryNameRef ref, String entryId) { } @riverpod -String? entryType(EntryTypeRef ref, String entryId) { +String? entryBlueprintId(EntryBlueprintIdRef ref, String entryId) { final entry = ref.watch(globalEntryProvider(entryId)); - return entry?.type; + return entry?.blueprintId; } @riverpod @@ -68,10 +68,10 @@ class Entry { required String id, required EntryBlueprint blueprint, }) : data = { - ...blueprint.fields.defaultValue, + ...blueprint.dataBlueprint.defaultValue(), "id": id, "name": "new_${blueprint.name}", - "type": blueprint.name, + "type": blueprint.id, }; factory Entry.fromJson(Map json) => Entry(json); @@ -85,7 +85,15 @@ class Entry { String get formattedName => name.formatted; - String get type => data["type"] as String; + /// Returns the blueprint id of the entry. + /// TODO: Remove the old `type` field. + String get blueprintId { + final blueprintId = data["blueprintId"]; + if (blueprintId is String) return blueprintId; + final type = data["type"]; + if (type is String) return type; + throw Exception("Could not find blueprint id or type in entry data"); + } /// Returns the values in [map] that match [path]. /// @@ -269,7 +277,7 @@ class Entry { } } if (item is List) { - item.replaceRange(0, item.length, item.map(mapper).whereNotNull()); + item.replaceRange(0, item.length, item.map(mapper).nonNulls); } } diff --git a/app/lib/models/entry.g.dart b/app/lib/models/entry.g.dart index 7ebc701702..aaa652bed1 100644 --- a/app/lib/models/entry.g.dart +++ b/app/lib/models/entry.g.dart @@ -6,7 +6,7 @@ part of 'entry.dart'; // RiverpodGenerator // ************************************************************************** -String _$entryDefinitionHash() => r'2c725143bba770203fbcda73a8e2e479698e3cee'; +String _$entryDefinitionHash() => r'5604a6f065efbc96ada8aa30cb33b9ec653b361d'; /// Copied from Dart SDK class _SystemHash { @@ -283,29 +283,29 @@ class _EntryNameProviderElement extends AutoDisposeProviderElement String get entryId => (origin as EntryNameProvider).entryId; } -String _$entryTypeHash() => r'467b4a9545b746b07f721913e6c480ee100eedb1'; +String _$entryBlueprintIdHash() => r'5cac165b3797bad6ce6518cd948251f1107d7a2d'; -/// See also [entryType]. -@ProviderFor(entryType) -const entryTypeProvider = EntryTypeFamily(); +/// See also [entryBlueprintId]. +@ProviderFor(entryBlueprintId) +const entryBlueprintIdProvider = EntryBlueprintIdFamily(); -/// See also [entryType]. -class EntryTypeFamily extends Family { - /// See also [entryType]. - const EntryTypeFamily(); +/// See also [entryBlueprintId]. +class EntryBlueprintIdFamily extends Family { + /// See also [entryBlueprintId]. + const EntryBlueprintIdFamily(); - /// See also [entryType]. - EntryTypeProvider call( + /// See also [entryBlueprintId]. + EntryBlueprintIdProvider call( String entryId, ) { - return EntryTypeProvider( + return EntryBlueprintIdProvider( entryId, ); } @override - EntryTypeProvider getProviderOverride( - covariant EntryTypeProvider provider, + EntryBlueprintIdProvider getProviderOverride( + covariant EntryBlueprintIdProvider provider, ) { return call( provider.entryId, @@ -324,31 +324,32 @@ class EntryTypeFamily extends Family { _allTransitiveDependencies; @override - String? get name => r'entryTypeProvider'; + String? get name => r'entryBlueprintIdProvider'; } -/// See also [entryType]. -class EntryTypeProvider extends AutoDisposeProvider { - /// See also [entryType]. - EntryTypeProvider( +/// See also [entryBlueprintId]. +class EntryBlueprintIdProvider extends AutoDisposeProvider { + /// See also [entryBlueprintId]. + EntryBlueprintIdProvider( String entryId, ) : this._internal( - (ref) => entryType( - ref as EntryTypeRef, + (ref) => entryBlueprintId( + ref as EntryBlueprintIdRef, entryId, ), - from: entryTypeProvider, - name: r'entryTypeProvider', + from: entryBlueprintIdProvider, + name: r'entryBlueprintIdProvider', debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') ? null - : _$entryTypeHash, - dependencies: EntryTypeFamily._dependencies, - allTransitiveDependencies: EntryTypeFamily._allTransitiveDependencies, + : _$entryBlueprintIdHash, + dependencies: EntryBlueprintIdFamily._dependencies, + allTransitiveDependencies: + EntryBlueprintIdFamily._allTransitiveDependencies, entryId: entryId, ); - EntryTypeProvider._internal( + EntryBlueprintIdProvider._internal( super._createNotifier, { required super.name, required super.dependencies, @@ -362,12 +363,12 @@ class EntryTypeProvider extends AutoDisposeProvider { @override Override overrideWith( - String? Function(EntryTypeRef provider) create, + String? Function(EntryBlueprintIdRef provider) create, ) { return ProviderOverride( origin: this, - override: EntryTypeProvider._internal( - (ref) => create(ref as EntryTypeRef), + override: EntryBlueprintIdProvider._internal( + (ref) => create(ref as EntryBlueprintIdRef), from: from, name: null, dependencies: null, @@ -380,12 +381,12 @@ class EntryTypeProvider extends AutoDisposeProvider { @override AutoDisposeProviderElement createElement() { - return _EntryTypeProviderElement(this); + return _EntryBlueprintIdProviderElement(this); } @override bool operator ==(Object other) { - return other is EntryTypeProvider && other.entryId == entryId; + return other is EntryBlueprintIdProvider && other.entryId == entryId; } @override @@ -397,17 +398,17 @@ class EntryTypeProvider extends AutoDisposeProvider { } } -mixin EntryTypeRef on AutoDisposeProviderRef { +mixin EntryBlueprintIdRef on AutoDisposeProviderRef { /// The parameter `entryId` of this provider. String get entryId; } -class _EntryTypeProviderElement extends AutoDisposeProviderElement - with EntryTypeRef { - _EntryTypeProviderElement(super.provider); +class _EntryBlueprintIdProviderElement + extends AutoDisposeProviderElement with EntryBlueprintIdRef { + _EntryBlueprintIdProviderElement(super.provider); @override - String get entryId => (origin as EntryTypeProvider).entryId; + String get entryId => (origin as EntryBlueprintIdProvider).entryId; } String _$isEntryDeprecatedHash() => r'f7417cbbc63faac9f66342e4170f30e7466c646a'; diff --git a/app/lib/models/adapter.dart b/app/lib/models/entry_blueprint.dart similarity index 50% rename from app/lib/models/adapter.dart rename to app/lib/models/entry_blueprint.dart index 0ca1ea779e..67fd9afb51 100644 --- a/app/lib/models/adapter.dart +++ b/app/lib/models/entry_blueprint.dart @@ -3,57 +3,52 @@ import "package:flutter/foundation.dart"; import "package:flutter/material.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/main.dart"; -import "package:typewriter/models/book.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/extension.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/utils/color_converter.dart"; import "package:typewriter/utils/icons.dart"; -import "package:typewriter/widgets/inspector/editors/object.dart"; import "package:url_launcher/url_launcher_string.dart"; -part "adapter.freezed.dart"; -part "adapter.g.dart"; +import "../main.dart"; -/// A generated provider to fetch and cache a list of [Adapter]s. -@riverpod -List adapters(AdaptersRef ref) => ref.watch(bookProvider).adapters; +part "entry_blueprint.freezed.dart"; +part "entry_blueprint.g.dart"; /// A generated provider to fetch and cache a list of all the [EntryBlueprint]s. @riverpod List entryBlueprints(EntryBlueprintsRef ref) => - ref.watch(adaptersProvider).expand((e) => e.entries).toList(); + ref.watch(extensionsProvider).expand((e) => e.entries).toList(); -/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. +/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. @riverpod -EntryBlueprint? entryBlueprint(EntryBlueprintRef ref, String blueprintName) => - ref - .watch(entryBlueprintsProvider) - .firstWhereOrNull((e) => e.name == blueprintName); +EntryBlueprint? entryBlueprint(EntryBlueprintRef ref, String blueprintId) => ref + .watch(entryBlueprintsProvider) + .firstWhereOrNull((e) => e.id == blueprintId); @riverpod List entryBlueprintTags( EntryBlueprintTagsRef ref, - String blueprintName, + String blueprintId, ) => - ref.watch(entryBlueprintProvider(blueprintName))?.tags ?? []; + ref.watch(entryBlueprintProvider(blueprintId))?.tags ?? []; @riverpod List entryTags( EntryTagsRef ref, String entryId, ) { - final blueprint = ref.watch(entryTypeProvider(entryId)); - if (blueprint == null) return []; - return ref.watch(entryBlueprintTagsProvider(blueprint)); + final blueprintId = ref.watch(entryBlueprintIdProvider(entryId)); + if (blueprintId == null) return []; + return ref.watch(entryBlueprintTagsProvider(blueprintId)); } @riverpod PageType entryBlueprintPageType( EntryBlueprintPageTypeRef ref, - String blueprintName, + String blueprintId, ) { - final blueprint = ref.watch(entryBlueprintProvider(blueprintName)); + final blueprint = ref.watch(entryBlueprintProvider(blueprintId)); if (blueprint == null) return PageType.static; return PageType.fromBlueprint(blueprint); } @@ -62,11 +57,11 @@ PageType entryBlueprintPageType( @riverpod Map fieldModifiers( FieldModifiersRef ref, - String blueprintName, + String blueprintId, String modifierName, ) { return ref - .watch(entryBlueprintProvider(blueprintName)) + .watch(entryBlueprintProvider(blueprintId)) ?.fieldsWithModifier(modifierName) ?? {}; } @@ -75,40 +70,27 @@ Map fieldModifiers( @riverpod List modifierPaths( ModifierPathsRef ref, - String blueprintName, + String blueprintId, String modifierName, [ String? data, ]) { return ref - .watch(fieldModifiersProvider(blueprintName, modifierName)) + .watch(fieldModifiersProvider(blueprintId, modifierName)) .entries .where((e) => data == null || e.value.data == data) .map((e) => e.key) .toList(); } -/// A data model that represents an adapter. -@freezed -class Adapter with _$Adapter { - const factory Adapter({ - required String name, - required String description, - required String version, - required List entries, - }) = _Adapter; - - factory Adapter.fromJson(Map json) => - _$AdapterFromJson(json); -} - /// A data model that represents an entry blueprint. @freezed class EntryBlueprint with _$EntryBlueprint { const factory EntryBlueprint({ + required String id, required String name, required String description, - required String adapter, - required ObjectField fields, + required String extension, + required ObjectBlueprint dataBlueprint, @Default([]) List tags, @ColorConverter() @Default(Colors.grey) Color color, @Default(TWIcons.help) String icon, @@ -118,57 +100,63 @@ class EntryBlueprint with _$EntryBlueprint { _$EntryBlueprintFromJson(json); } -/// A data model for the fields of an adapter entry. +/// A data blueprint for the fields of an entry blueprint. @Freezed(unionKey: "kind") -class FieldInfo with _$FieldInfo { +class DataBlueprint with _$DataBlueprint { /// A default constructor that should never be used. - const factory FieldInfo({ + const factory DataBlueprint({ + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = _FieldType; + }) = _DataBlueprintType; /// Primitive field type, such as a string or a number. - const factory FieldInfo.primitive({ - required PrimitiveFieldType type, + const factory DataBlueprint.primitive({ + required PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = PrimitiveField; + }) = PrimitiveBlueprint; /// Enum field type, such as a list of options. @FreezedUnionValue("enum") - const factory FieldInfo.enumField({ + const factory DataBlueprint.enumBlueprint({ required List values, + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = EnumField; + }) = EnumBlueprint; /// List field type, such as a list of strings. - const factory FieldInfo.list({ - required FieldInfo type, + const factory DataBlueprint.list({ + required DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = ListField; - - /// Map field type, such as a map of strings to strings. - /// Only strings and enums are supported as keys. - const factory FieldInfo.map({ - required FieldInfo key, - required FieldInfo value, + }) = ListBlueprint; + + /// Map blueprint, such as a map of strings to strings. + /// Only strings and enums, and entry references are supported as keys. + const factory DataBlueprint.map({ + required DataBlueprint key, + required DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = MapField; + }) = MapBlueprint; - /// Object field type, such as a nested object. - const factory FieldInfo.object({ - required Map fields, + /// Object blueprint, such as a nested object. + const factory DataBlueprint.object({ + required Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = ObjectField; + }) = ObjectBlueprint; - /// Custom field type, where a custom editor is used. - const factory FieldInfo.custom({ + /// Custom blueprint, where a custom editor is used. + const factory DataBlueprint.custom({ required String editor, - @JsonKey(name: "default") dynamic defaultValue, - FieldInfo? fieldInfo, + required DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, @Default([]) List modifiers, - }) = CustomField; + }) = CustomBlueprint; - factory FieldInfo.fromJson(Map json) => - _$FieldInfoFromJson(json); + factory DataBlueprint.fromJson(Map json) => + _$DataBlueprintFromJson(json); } @freezed @@ -188,21 +176,21 @@ const wikiBaseUrl = kDebugMode extension EntryBlueprintExt on EntryBlueprint { Map fieldsWithModifier(String name) => - _fieldsWithModifier(name, "", fields); + _fieldsWithModifier(name, "", dataBlueprint); /// Parse through the fields of this entry and return a list of all the fields that have the given modifier with [name]. Map _fieldsWithModifier( String name, String path, - FieldInfo info, + DataBlueprint blueprint, ) { final fields = { - if (info.hasModifier(name)) path: info.getModifier(name)!, + if (blueprint.hasModifier(name)) path: blueprint.getModifier(name)!, }; final separator = path.isEmpty ? "" : "."; - if (info is ObjectField) { - for (final field in info.fields.entries) { + if (blueprint is ObjectBlueprint) { + for (final field in blueprint.fields.entries) { fields.addAll( _fieldsWithModifier( name, @@ -211,24 +199,28 @@ extension EntryBlueprintExt on EntryBlueprint { ), ); } - } else if (info is ListField) { - fields.addAll(_fieldsWithModifier(name, "$path$separator*", info.type)); - } else if (info is MapField) { - fields.addAll(_fieldsWithModifier(name, "$path$separator*", info.value)); + } else if (blueprint is ListBlueprint) { + fields.addAll( + _fieldsWithModifier(name, "$path$separator*", blueprint.type), + ); + } else if (blueprint is MapBlueprint) { + fields.addAll( + _fieldsWithModifier(name, "$path$separator*", blueprint.value), + ); } return fields; } - FieldInfo? getField(String path) { + DataBlueprint? getField(String path) { final parts = path.split("."); - FieldInfo? info = fields; + DataBlueprint? info = dataBlueprint; for (final part in parts) { - if (info is ObjectField) { + if (info is ObjectBlueprint) { info = info.fields[part]; - } else if (info is ListField) { + } else if (info is ListBlueprint) { info = info.type; - } else if (info is MapField) { + } else if (info is MapBlueprint) { info = info.value; } } @@ -243,15 +235,16 @@ extension EntryBlueprintExt on EntryBlueprint { "fact", "speaker", ]; + // TODO: Change once the module marketplace is implemented String get wikiUrl { final category = tags.firstWhereOrNull((tag) => _wikiCategories.contains(tag)); if (category == null) { - return "$wikiBaseUrl/adapters/${adapter}Adapter"; + return "$wikiBaseUrl/extensions/${extension}Extension"; } - return "$wikiBaseUrl/adapters/${adapter}Adapter/entries/$category/$name"; + return "$wikiBaseUrl/extensions/${extension}Extension/entries/$category/$name"; } Future openWiki() async { @@ -271,21 +264,47 @@ final _customEditorCustomLayout = [ ]; /// Since freezed does not support methods on data models, we have to create a separate extension class. -extension FieldTypeExtension on FieldInfo { - /// Get the default value for this field type. - dynamic get defaultValue => when( +extension DataBlueprintExtension on DataBlueprint { + /// Get the default value for this data blueprint. + dynamic defaultValue() => map( (_) => null, - primitive: (type, _) => _defaultPrimitiveValue(type), - enumField: (values, _) => values.first, - list: (type, _) => [], - map: (key, value, _) => {}, - object: (fields, _) => - fields.map((key, value) => MapEntry(key, value.defaultValue)), - custom: (_, defaultValue, __, ___) => defaultValue, + primitive: (data) { + if (data.type.validate(data.internalDefaultValue)) { + return data.defaultValue; + } + return _defaultPrimitiveValue(data.type); + }, + enumBlueprint: (data) { + if (data.values.contains(data.internalDefaultValue)) { + return data.internalDefaultValue; + } + return data.values.first; + }, + list: (data) { + if (data.type.internalDefaultValue is List) { + return data.type.internalDefaultValue; + } + return []; + }, + map: (data) { + if (data.internalDefaultValue is Map) { + return data.internalDefaultValue; + } + return {}; + }, + object: (data) { + if (data.internalDefaultValue is Map) { + return data.internalDefaultValue; + } + + return data.fields + .map((key, value) => MapEntry(key, value.defaultValue())); + }, + custom: (data) => data.internalDefaultValue, ); - dynamic _defaultPrimitiveValue(PrimitiveFieldType type) { - if (type == PrimitiveFieldType.string) { + dynamic _defaultPrimitiveValue(PrimitiveType type) { + if (type == PrimitiveType.string) { if (hasModifier("generated")) { return uuid.v4(); } @@ -296,23 +315,23 @@ extension FieldTypeExtension on FieldInfo { /// If the [ObjectEditor] needs to show a default layout or if a field declares a custom layout. bool get hasCustomLayout { - if (this is CustomField) { - final editor = (this as CustomField).editor; + if (this is CustomBlueprint) { + final editor = (this as CustomBlueprint).editor; if (_customEditorCustomLayout.contains(editor)) { return true; } } - if (this is ObjectField) { + if (this is ObjectBlueprint) { return true; } - if (this is ListField) { + if (this is ListBlueprint) { return true; } - if (this is MapField) { + if (this is MapBlueprint) { return true; } - if (this is PrimitiveField && - (this as PrimitiveField).type == PrimitiveFieldType.boolean) { + if (this is PrimitiveBlueprint && + (this as PrimitiveBlueprint).type == PrimitiveType.boolean) { return true; } return false; @@ -333,16 +352,32 @@ extension FieldTypeExtension on FieldInfo { } /// A data model that represents a primitive field type. -enum PrimitiveFieldType { +enum PrimitiveType { boolean(false), double(0.0), integer(0), string(""), ; - /// A constructor that is used to create an instance of the [PrimitiveFieldType] class. - const PrimitiveFieldType(this.defaultValue); + /// A constructor that is used to create an instance of the [PrimitiveType] class. + const PrimitiveType(this.defaultValue); /// The default value for this field type. final dynamic defaultValue; } + +extension PrimitiveTypeExtension on PrimitiveType { + // It has to be outside of the enum since double clashes with the double type. + bool validate(dynamic value) { + switch (this) { + case PrimitiveType.boolean: + return value is bool; + case PrimitiveType.double: + return value is double; + case PrimitiveType.integer: + return value is int; + case PrimitiveType.string: + return value is String; + } + } +} diff --git a/app/lib/models/entry_blueprint.freezed.dart b/app/lib/models/entry_blueprint.freezed.dart new file mode 100644 index 0000000000..ae8348cdcb --- /dev/null +++ b/app/lib/models/entry_blueprint.freezed.dart @@ -0,0 +1,3160 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'entry_blueprint.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +EntryBlueprint _$EntryBlueprintFromJson(Map json) { + return _EntryBlueprint.fromJson(json); +} + +/// @nodoc +mixin _$EntryBlueprint { + String get id => throw _privateConstructorUsedError; + String get name => throw _privateConstructorUsedError; + String get description => throw _privateConstructorUsedError; + String get extension => throw _privateConstructorUsedError; + ObjectBlueprint get dataBlueprint => throw _privateConstructorUsedError; + List get tags => throw _privateConstructorUsedError; + @ColorConverter() + Color get color => throw _privateConstructorUsedError; + String get icon => throw _privateConstructorUsedError; + + /// Serializes this EntryBlueprint to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of EntryBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $EntryBlueprintCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $EntryBlueprintCopyWith<$Res> { + factory $EntryBlueprintCopyWith( + EntryBlueprint value, $Res Function(EntryBlueprint) then) = + _$EntryBlueprintCopyWithImpl<$Res, EntryBlueprint>; + @useResult + $Res call( + {String id, + String name, + String description, + String extension, + ObjectBlueprint dataBlueprint, + List tags, + @ColorConverter() Color color, + String icon}); +} + +/// @nodoc +class _$EntryBlueprintCopyWithImpl<$Res, $Val extends EntryBlueprint> + implements $EntryBlueprintCopyWith<$Res> { + _$EntryBlueprintCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of EntryBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? name = null, + Object? description = null, + Object? extension = null, + Object? dataBlueprint = freezed, + Object? tags = null, + Object? color = null, + Object? icon = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + extension: null == extension + ? _value.extension + : extension // ignore: cast_nullable_to_non_nullable + as String, + dataBlueprint: freezed == dataBlueprint + ? _value.dataBlueprint + : dataBlueprint // ignore: cast_nullable_to_non_nullable + as ObjectBlueprint, + tags: null == tags + ? _value.tags + : tags // ignore: cast_nullable_to_non_nullable + as List, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as Color, + icon: null == icon + ? _value.icon + : icon // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$EntryBlueprintImplCopyWith<$Res> + implements $EntryBlueprintCopyWith<$Res> { + factory _$$EntryBlueprintImplCopyWith(_$EntryBlueprintImpl value, + $Res Function(_$EntryBlueprintImpl) then) = + __$$EntryBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String id, + String name, + String description, + String extension, + ObjectBlueprint dataBlueprint, + List tags, + @ColorConverter() Color color, + String icon}); +} + +/// @nodoc +class __$$EntryBlueprintImplCopyWithImpl<$Res> + extends _$EntryBlueprintCopyWithImpl<$Res, _$EntryBlueprintImpl> + implements _$$EntryBlueprintImplCopyWith<$Res> { + __$$EntryBlueprintImplCopyWithImpl( + _$EntryBlueprintImpl _value, $Res Function(_$EntryBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of EntryBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? name = null, + Object? description = null, + Object? extension = null, + Object? dataBlueprint = freezed, + Object? tags = null, + Object? color = null, + Object? icon = null, + }) { + return _then(_$EntryBlueprintImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + extension: null == extension + ? _value.extension + : extension // ignore: cast_nullable_to_non_nullable + as String, + dataBlueprint: freezed == dataBlueprint + ? _value.dataBlueprint + : dataBlueprint // ignore: cast_nullable_to_non_nullable + as ObjectBlueprint, + tags: null == tags + ? _value._tags + : tags // ignore: cast_nullable_to_non_nullable + as List, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as Color, + icon: null == icon + ? _value.icon + : icon // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$EntryBlueprintImpl + with DiagnosticableTreeMixin + implements _EntryBlueprint { + const _$EntryBlueprintImpl( + {required this.id, + required this.name, + required this.description, + required this.extension, + required this.dataBlueprint, + final List tags = const [], + @ColorConverter() this.color = Colors.grey, + this.icon = TWIcons.help}) + : _tags = tags; + + factory _$EntryBlueprintImpl.fromJson(Map json) => + _$$EntryBlueprintImplFromJson(json); + + @override + final String id; + @override + final String name; + @override + final String description; + @override + final String extension; + @override + final ObjectBlueprint dataBlueprint; + final List _tags; + @override + @JsonKey() + List get tags { + if (_tags is EqualUnmodifiableListView) return _tags; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_tags); + } + + @override + @JsonKey() + @ColorConverter() + final Color color; + @override + @JsonKey() + final String icon; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'EntryBlueprint(id: $id, name: $name, description: $description, extension: $extension, dataBlueprint: $dataBlueprint, tags: $tags, color: $color, icon: $icon)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'EntryBlueprint')) + ..add(DiagnosticsProperty('id', id)) + ..add(DiagnosticsProperty('name', name)) + ..add(DiagnosticsProperty('description', description)) + ..add(DiagnosticsProperty('extension', extension)) + ..add(DiagnosticsProperty('dataBlueprint', dataBlueprint)) + ..add(DiagnosticsProperty('tags', tags)) + ..add(DiagnosticsProperty('color', color)) + ..add(DiagnosticsProperty('icon', icon)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$EntryBlueprintImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.name, name) || other.name == name) && + (identical(other.description, description) || + other.description == description) && + (identical(other.extension, extension) || + other.extension == extension) && + const DeepCollectionEquality() + .equals(other.dataBlueprint, dataBlueprint) && + const DeepCollectionEquality().equals(other._tags, _tags) && + (identical(other.color, color) || other.color == color) && + (identical(other.icon, icon) || other.icon == icon)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + id, + name, + description, + extension, + const DeepCollectionEquality().hash(dataBlueprint), + const DeepCollectionEquality().hash(_tags), + color, + icon); + + /// Create a copy of EntryBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$EntryBlueprintImplCopyWith<_$EntryBlueprintImpl> get copyWith => + __$$EntryBlueprintImplCopyWithImpl<_$EntryBlueprintImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$EntryBlueprintImplToJson( + this, + ); + } +} + +abstract class _EntryBlueprint implements EntryBlueprint { + const factory _EntryBlueprint( + {required final String id, + required final String name, + required final String description, + required final String extension, + required final ObjectBlueprint dataBlueprint, + final List tags, + @ColorConverter() final Color color, + final String icon}) = _$EntryBlueprintImpl; + + factory _EntryBlueprint.fromJson(Map json) = + _$EntryBlueprintImpl.fromJson; + + @override + String get id; + @override + String get name; + @override + String get description; + @override + String get extension; + @override + ObjectBlueprint get dataBlueprint; + @override + List get tags; + @override + @ColorConverter() + Color get color; + @override + String get icon; + + /// Create a copy of EntryBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$EntryBlueprintImplCopyWith<_$EntryBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +DataBlueprint _$DataBlueprintFromJson(Map json) { + switch (json['kind']) { + case 'default': + return _DataBlueprintType.fromJson(json); + case 'primitive': + return PrimitiveBlueprint.fromJson(json); + case 'enum': + return EnumBlueprint.fromJson(json); + case 'list': + return ListBlueprint.fromJson(json); + case 'map': + return MapBlueprint.fromJson(json); + case 'object': + return ObjectBlueprint.fromJson(json); + case 'custom': + return CustomBlueprint.fromJson(json); + + default: + throw CheckedFromJsonException(json, 'kind', 'DataBlueprint', + 'Invalid union type "${json['kind']}"!'); + } +} + +/// @nodoc +mixin _$DataBlueprint { + @JsonKey(name: "default") + dynamic get internalDefaultValue => throw _privateConstructorUsedError; + List get modifiers => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + + /// Serializes this DataBlueprint to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DataBlueprintCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DataBlueprintCopyWith<$Res> { + factory $DataBlueprintCopyWith( + DataBlueprint value, $Res Function(DataBlueprint) then) = + _$DataBlueprintCopyWithImpl<$Res, DataBlueprint>; + @useResult + $Res call( + {@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); +} + +/// @nodoc +class _$DataBlueprintCopyWithImpl<$Res, $Val extends DataBlueprint> + implements $DataBlueprintCopyWith<$Res> { + _$DataBlueprintCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_value.copyWith( + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value.modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$DataBlueprintTypeImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$DataBlueprintTypeImplCopyWith(_$DataBlueprintTypeImpl value, + $Res Function(_$DataBlueprintTypeImpl) then) = + __$$DataBlueprintTypeImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); +} + +/// @nodoc +class __$$DataBlueprintTypeImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$DataBlueprintTypeImpl> + implements _$$DataBlueprintTypeImplCopyWith<$Res> { + __$$DataBlueprintTypeImplCopyWithImpl(_$DataBlueprintTypeImpl _value, + $Res Function(_$DataBlueprintTypeImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$DataBlueprintTypeImpl( + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$DataBlueprintTypeImpl + with DiagnosticableTreeMixin + implements _DataBlueprintType { + const _$DataBlueprintTypeImpl( + {@JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _modifiers = modifiers, + $type = $type ?? 'default'; + + factory _$DataBlueprintTypeImpl.fromJson(Map json) => + _$$DataBlueprintTypeImplFromJson(json); + + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint(internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint')) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DataBlueprintTypeImpl && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DataBlueprintTypeImplCopyWith<_$DataBlueprintTypeImpl> get copyWith => + __$$DataBlueprintTypeImplCopyWithImpl<_$DataBlueprintTypeImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return $default(internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return $default?.call(internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if ($default != null) { + return $default(internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return $default(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return $default?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if ($default != null) { + return $default(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$DataBlueprintTypeImplToJson( + this, + ); + } +} + +abstract class _DataBlueprintType implements DataBlueprint { + const factory _DataBlueprintType( + {@JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$DataBlueprintTypeImpl; + + factory _DataBlueprintType.fromJson(Map json) = + _$DataBlueprintTypeImpl.fromJson; + + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DataBlueprintTypeImplCopyWith<_$DataBlueprintTypeImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$PrimitiveBlueprintImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$PrimitiveBlueprintImplCopyWith(_$PrimitiveBlueprintImpl value, + $Res Function(_$PrimitiveBlueprintImpl) then) = + __$$PrimitiveBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); +} + +/// @nodoc +class __$$PrimitiveBlueprintImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$PrimitiveBlueprintImpl> + implements _$$PrimitiveBlueprintImplCopyWith<$Res> { + __$$PrimitiveBlueprintImplCopyWithImpl(_$PrimitiveBlueprintImpl _value, + $Res Function(_$PrimitiveBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? type = null, + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$PrimitiveBlueprintImpl( + type: null == type + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as PrimitiveType, + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$PrimitiveBlueprintImpl + with DiagnosticableTreeMixin + implements PrimitiveBlueprint { + const _$PrimitiveBlueprintImpl( + {required this.type, + @JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _modifiers = modifiers, + $type = $type ?? 'primitive'; + + factory _$PrimitiveBlueprintImpl.fromJson(Map json) => + _$$PrimitiveBlueprintImplFromJson(json); + + @override + final PrimitiveType type; + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint.primitive(type: $type, internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint.primitive')) + ..add(DiagnosticsProperty('type', type)) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$PrimitiveBlueprintImpl && + (identical(other.type, type) || other.type == type) && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + type, + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$PrimitiveBlueprintImplCopyWith<_$PrimitiveBlueprintImpl> get copyWith => + __$$PrimitiveBlueprintImplCopyWithImpl<_$PrimitiveBlueprintImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return primitive(type, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return primitive?.call(type, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if (primitive != null) { + return primitive(type, internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return primitive(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return primitive?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if (primitive != null) { + return primitive(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$PrimitiveBlueprintImplToJson( + this, + ); + } +} + +abstract class PrimitiveBlueprint implements DataBlueprint { + const factory PrimitiveBlueprint( + {required final PrimitiveType type, + @JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$PrimitiveBlueprintImpl; + + factory PrimitiveBlueprint.fromJson(Map json) = + _$PrimitiveBlueprintImpl.fromJson; + + PrimitiveType get type; + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$PrimitiveBlueprintImplCopyWith<_$PrimitiveBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$EnumBlueprintImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$EnumBlueprintImplCopyWith( + _$EnumBlueprintImpl value, $Res Function(_$EnumBlueprintImpl) then) = + __$$EnumBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); +} + +/// @nodoc +class __$$EnumBlueprintImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$EnumBlueprintImpl> + implements _$$EnumBlueprintImplCopyWith<$Res> { + __$$EnumBlueprintImplCopyWithImpl( + _$EnumBlueprintImpl _value, $Res Function(_$EnumBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? values = null, + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$EnumBlueprintImpl( + values: null == values + ? _value._values + : values // ignore: cast_nullable_to_non_nullable + as List, + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$EnumBlueprintImpl + with DiagnosticableTreeMixin + implements EnumBlueprint { + const _$EnumBlueprintImpl( + {required final List values, + @JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _values = values, + _modifiers = modifiers, + $type = $type ?? 'enum'; + + factory _$EnumBlueprintImpl.fromJson(Map json) => + _$$EnumBlueprintImplFromJson(json); + + final List _values; + @override + List get values { + if (_values is EqualUnmodifiableListView) return _values; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_values); + } + + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint.enumBlueprint(values: $values, internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint.enumBlueprint')) + ..add(DiagnosticsProperty('values', values)) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$EnumBlueprintImpl && + const DeepCollectionEquality().equals(other._values, _values) && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_values), + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$EnumBlueprintImplCopyWith<_$EnumBlueprintImpl> get copyWith => + __$$EnumBlueprintImplCopyWithImpl<_$EnumBlueprintImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return enumBlueprint(values, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return enumBlueprint?.call(values, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if (enumBlueprint != null) { + return enumBlueprint(values, internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return enumBlueprint(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return enumBlueprint?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if (enumBlueprint != null) { + return enumBlueprint(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$EnumBlueprintImplToJson( + this, + ); + } +} + +abstract class EnumBlueprint implements DataBlueprint { + const factory EnumBlueprint( + {required final List values, + @JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$EnumBlueprintImpl; + + factory EnumBlueprint.fromJson(Map json) = + _$EnumBlueprintImpl.fromJson; + + List get values; + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$EnumBlueprintImplCopyWith<_$EnumBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$ListBlueprintImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$ListBlueprintImplCopyWith( + _$ListBlueprintImpl value, $Res Function(_$ListBlueprintImpl) then) = + __$$ListBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); + + $DataBlueprintCopyWith<$Res> get type; +} + +/// @nodoc +class __$$ListBlueprintImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$ListBlueprintImpl> + implements _$$ListBlueprintImplCopyWith<$Res> { + __$$ListBlueprintImplCopyWithImpl( + _$ListBlueprintImpl _value, $Res Function(_$ListBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? type = null, + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$ListBlueprintImpl( + type: null == type + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as DataBlueprint, + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DataBlueprintCopyWith<$Res> get type { + return $DataBlueprintCopyWith<$Res>(_value.type, (value) { + return _then(_value.copyWith(type: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _$ListBlueprintImpl + with DiagnosticableTreeMixin + implements ListBlueprint { + const _$ListBlueprintImpl( + {required this.type, + @JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _modifiers = modifiers, + $type = $type ?? 'list'; + + factory _$ListBlueprintImpl.fromJson(Map json) => + _$$ListBlueprintImplFromJson(json); + + @override + final DataBlueprint type; + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint.list(type: $type, internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint.list')) + ..add(DiagnosticsProperty('type', type)) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ListBlueprintImpl && + (identical(other.type, type) || other.type == type) && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + type, + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ListBlueprintImplCopyWith<_$ListBlueprintImpl> get copyWith => + __$$ListBlueprintImplCopyWithImpl<_$ListBlueprintImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return list(type, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return list?.call(type, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if (list != null) { + return list(type, internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return list(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return list?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if (list != null) { + return list(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$ListBlueprintImplToJson( + this, + ); + } +} + +abstract class ListBlueprint implements DataBlueprint { + const factory ListBlueprint( + {required final DataBlueprint type, + @JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$ListBlueprintImpl; + + factory ListBlueprint.fromJson(Map json) = + _$ListBlueprintImpl.fromJson; + + DataBlueprint get type; + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ListBlueprintImplCopyWith<_$ListBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$MapBlueprintImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$MapBlueprintImplCopyWith( + _$MapBlueprintImpl value, $Res Function(_$MapBlueprintImpl) then) = + __$$MapBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); + + $DataBlueprintCopyWith<$Res> get key; + $DataBlueprintCopyWith<$Res> get value; +} + +/// @nodoc +class __$$MapBlueprintImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$MapBlueprintImpl> + implements _$$MapBlueprintImplCopyWith<$Res> { + __$$MapBlueprintImplCopyWithImpl( + _$MapBlueprintImpl _value, $Res Function(_$MapBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? key = null, + Object? value = null, + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$MapBlueprintImpl( + key: null == key + ? _value.key + : key // ignore: cast_nullable_to_non_nullable + as DataBlueprint, + value: null == value + ? _value.value + : value // ignore: cast_nullable_to_non_nullable + as DataBlueprint, + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DataBlueprintCopyWith<$Res> get key { + return $DataBlueprintCopyWith<$Res>(_value.key, (value) { + return _then(_value.copyWith(key: value)); + }); + } + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DataBlueprintCopyWith<$Res> get value { + return $DataBlueprintCopyWith<$Res>(_value.value, (value) { + return _then(_value.copyWith(value: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _$MapBlueprintImpl with DiagnosticableTreeMixin implements MapBlueprint { + const _$MapBlueprintImpl( + {required this.key, + required this.value, + @JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _modifiers = modifiers, + $type = $type ?? 'map'; + + factory _$MapBlueprintImpl.fromJson(Map json) => + _$$MapBlueprintImplFromJson(json); + + @override + final DataBlueprint key; + @override + final DataBlueprint value; + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint.map(key: $key, value: $value, internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint.map')) + ..add(DiagnosticsProperty('key', key)) + ..add(DiagnosticsProperty('value', value)) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$MapBlueprintImpl && + (identical(other.key, key) || other.key == key) && + (identical(other.value, value) || other.value == value) && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + key, + value, + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$MapBlueprintImplCopyWith<_$MapBlueprintImpl> get copyWith => + __$$MapBlueprintImplCopyWithImpl<_$MapBlueprintImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return map(key, value, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return map?.call(key, value, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if (map != null) { + return map(key, value, internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return map(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return map?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if (map != null) { + return map(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$MapBlueprintImplToJson( + this, + ); + } +} + +abstract class MapBlueprint implements DataBlueprint { + const factory MapBlueprint( + {required final DataBlueprint key, + required final DataBlueprint value, + @JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$MapBlueprintImpl; + + factory MapBlueprint.fromJson(Map json) = + _$MapBlueprintImpl.fromJson; + + DataBlueprint get key; + DataBlueprint get value; + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$MapBlueprintImplCopyWith<_$MapBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$ObjectBlueprintImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$ObjectBlueprintImplCopyWith(_$ObjectBlueprintImpl value, + $Res Function(_$ObjectBlueprintImpl) then) = + __$$ObjectBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); +} + +/// @nodoc +class __$$ObjectBlueprintImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$ObjectBlueprintImpl> + implements _$$ObjectBlueprintImplCopyWith<$Res> { + __$$ObjectBlueprintImplCopyWithImpl( + _$ObjectBlueprintImpl _value, $Res Function(_$ObjectBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? fields = null, + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$ObjectBlueprintImpl( + fields: null == fields + ? _value._fields + : fields // ignore: cast_nullable_to_non_nullable + as Map, + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ObjectBlueprintImpl + with DiagnosticableTreeMixin + implements ObjectBlueprint { + const _$ObjectBlueprintImpl( + {required final Map fields, + @JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _fields = fields, + _modifiers = modifiers, + $type = $type ?? 'object'; + + factory _$ObjectBlueprintImpl.fromJson(Map json) => + _$$ObjectBlueprintImplFromJson(json); + + final Map _fields; + @override + Map get fields { + if (_fields is EqualUnmodifiableMapView) return _fields; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(_fields); + } + + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint.object(fields: $fields, internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint.object')) + ..add(DiagnosticsProperty('fields', fields)) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ObjectBlueprintImpl && + const DeepCollectionEquality().equals(other._fields, _fields) && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_fields), + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ObjectBlueprintImplCopyWith<_$ObjectBlueprintImpl> get copyWith => + __$$ObjectBlueprintImplCopyWithImpl<_$ObjectBlueprintImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return object(fields, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return object?.call(fields, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if (object != null) { + return object(fields, internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return object(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return object?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if (object != null) { + return object(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$ObjectBlueprintImplToJson( + this, + ); + } +} + +abstract class ObjectBlueprint implements DataBlueprint { + const factory ObjectBlueprint( + {required final Map fields, + @JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$ObjectBlueprintImpl; + + factory ObjectBlueprint.fromJson(Map json) = + _$ObjectBlueprintImpl.fromJson; + + Map get fields; + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ObjectBlueprintImplCopyWith<_$ObjectBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$CustomBlueprintImplCopyWith<$Res> + implements $DataBlueprintCopyWith<$Res> { + factory _$$CustomBlueprintImplCopyWith(_$CustomBlueprintImpl value, + $Res Function(_$CustomBlueprintImpl) then) = + __$$CustomBlueprintImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers}); + + $DataBlueprintCopyWith<$Res> get shape; +} + +/// @nodoc +class __$$CustomBlueprintImplCopyWithImpl<$Res> + extends _$DataBlueprintCopyWithImpl<$Res, _$CustomBlueprintImpl> + implements _$$CustomBlueprintImplCopyWith<$Res> { + __$$CustomBlueprintImplCopyWithImpl( + _$CustomBlueprintImpl _value, $Res Function(_$CustomBlueprintImpl) _then) + : super(_value, _then); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? editor = null, + Object? shape = null, + Object? internalDefaultValue = freezed, + Object? modifiers = null, + }) { + return _then(_$CustomBlueprintImpl( + editor: null == editor + ? _value.editor + : editor // ignore: cast_nullable_to_non_nullable + as String, + shape: null == shape + ? _value.shape + : shape // ignore: cast_nullable_to_non_nullable + as DataBlueprint, + internalDefaultValue: freezed == internalDefaultValue + ? _value.internalDefaultValue + : internalDefaultValue // ignore: cast_nullable_to_non_nullable + as dynamic, + modifiers: null == modifiers + ? _value._modifiers + : modifiers // ignore: cast_nullable_to_non_nullable + as List, + )); + } + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DataBlueprintCopyWith<$Res> get shape { + return $DataBlueprintCopyWith<$Res>(_value.shape, (value) { + return _then(_value.copyWith(shape: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _$CustomBlueprintImpl + with DiagnosticableTreeMixin + implements CustomBlueprint { + const _$CustomBlueprintImpl( + {required this.editor, + required this.shape, + @JsonKey(name: "default") this.internalDefaultValue, + final List modifiers = const [], + final String? $type}) + : _modifiers = modifiers, + $type = $type ?? 'custom'; + + factory _$CustomBlueprintImpl.fromJson(Map json) => + _$$CustomBlueprintImplFromJson(json); + + @override + final String editor; + @override + final DataBlueprint shape; + @override + @JsonKey(name: "default") + final dynamic internalDefaultValue; + final List _modifiers; + @override + @JsonKey() + List get modifiers { + if (_modifiers is EqualUnmodifiableListView) return _modifiers; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modifiers); + } + + @JsonKey(name: 'kind') + final String $type; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'DataBlueprint.custom(editor: $editor, shape: $shape, internalDefaultValue: $internalDefaultValue, modifiers: $modifiers)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'DataBlueprint.custom')) + ..add(DiagnosticsProperty('editor', editor)) + ..add(DiagnosticsProperty('shape', shape)) + ..add(DiagnosticsProperty('internalDefaultValue', internalDefaultValue)) + ..add(DiagnosticsProperty('modifiers', modifiers)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$CustomBlueprintImpl && + (identical(other.editor, editor) || other.editor == editor) && + (identical(other.shape, shape) || other.shape == shape) && + const DeepCollectionEquality() + .equals(other.internalDefaultValue, internalDefaultValue) && + const DeepCollectionEquality() + .equals(other._modifiers, _modifiers)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + editor, + shape, + const DeepCollectionEquality().hash(internalDefaultValue), + const DeepCollectionEquality().hash(_modifiers)); + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$CustomBlueprintImplCopyWith<_$CustomBlueprintImpl> get copyWith => + __$$CustomBlueprintImplCopyWithImpl<_$CustomBlueprintImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + $default, { + required TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + primitive, + required TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + enumBlueprint, + required TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + list, + required TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + map, + required TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + object, + required TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers) + custom, + }) { + return custom(editor, shape, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult? Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult? Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult? Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult? Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult? Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult? Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + }) { + return custom?.call(editor, shape, internalDefaultValue, modifiers); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function(@JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + $default, { + TResult Function( + PrimitiveType type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + primitive, + TResult Function( + List values, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + enumBlueprint, + TResult Function( + DataBlueprint type, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + list, + TResult Function( + DataBlueprint key, + DataBlueprint value, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + map, + TResult Function( + Map fields, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + object, + TResult Function( + String editor, + DataBlueprint shape, + @JsonKey(name: "default") dynamic internalDefaultValue, + List modifiers)? + custom, + required TResult orElse(), + }) { + if (custom != null) { + return custom(editor, shape, internalDefaultValue, modifiers); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_DataBlueprintType value) $default, { + required TResult Function(PrimitiveBlueprint value) primitive, + required TResult Function(EnumBlueprint value) enumBlueprint, + required TResult Function(ListBlueprint value) list, + required TResult Function(MapBlueprint value) map, + required TResult Function(ObjectBlueprint value) object, + required TResult Function(CustomBlueprint value) custom, + }) { + return custom(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_DataBlueprintType value)? $default, { + TResult? Function(PrimitiveBlueprint value)? primitive, + TResult? Function(EnumBlueprint value)? enumBlueprint, + TResult? Function(ListBlueprint value)? list, + TResult? Function(MapBlueprint value)? map, + TResult? Function(ObjectBlueprint value)? object, + TResult? Function(CustomBlueprint value)? custom, + }) { + return custom?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_DataBlueprintType value)? $default, { + TResult Function(PrimitiveBlueprint value)? primitive, + TResult Function(EnumBlueprint value)? enumBlueprint, + TResult Function(ListBlueprint value)? list, + TResult Function(MapBlueprint value)? map, + TResult Function(ObjectBlueprint value)? object, + TResult Function(CustomBlueprint value)? custom, + required TResult orElse(), + }) { + if (custom != null) { + return custom(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$CustomBlueprintImplToJson( + this, + ); + } +} + +abstract class CustomBlueprint implements DataBlueprint { + const factory CustomBlueprint( + {required final String editor, + required final DataBlueprint shape, + @JsonKey(name: "default") final dynamic internalDefaultValue, + final List modifiers}) = _$CustomBlueprintImpl; + + factory CustomBlueprint.fromJson(Map json) = + _$CustomBlueprintImpl.fromJson; + + String get editor; + DataBlueprint get shape; + @override + @JsonKey(name: "default") + dynamic get internalDefaultValue; + @override + List get modifiers; + + /// Create a copy of DataBlueprint + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$CustomBlueprintImplCopyWith<_$CustomBlueprintImpl> get copyWith => + throw _privateConstructorUsedError; +} + +Modifier _$ModifierFromJson(Map json) { + return _Modifier.fromJson(json); +} + +/// @nodoc +mixin _$Modifier { + String get name => throw _privateConstructorUsedError; + dynamic get data => throw _privateConstructorUsedError; + + /// Serializes this Modifier to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of Modifier + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ModifierCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ModifierCopyWith<$Res> { + factory $ModifierCopyWith(Modifier value, $Res Function(Modifier) then) = + _$ModifierCopyWithImpl<$Res, Modifier>; + @useResult + $Res call({String name, dynamic data}); +} + +/// @nodoc +class _$ModifierCopyWithImpl<$Res, $Val extends Modifier> + implements $ModifierCopyWith<$Res> { + _$ModifierCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of Modifier + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? data = freezed, + }) { + return _then(_value.copyWith( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + data: freezed == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as dynamic, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ModifierImplCopyWith<$Res> + implements $ModifierCopyWith<$Res> { + factory _$$ModifierImplCopyWith( + _$ModifierImpl value, $Res Function(_$ModifierImpl) then) = + __$$ModifierImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({String name, dynamic data}); +} + +/// @nodoc +class __$$ModifierImplCopyWithImpl<$Res> + extends _$ModifierCopyWithImpl<$Res, _$ModifierImpl> + implements _$$ModifierImplCopyWith<$Res> { + __$$ModifierImplCopyWithImpl( + _$ModifierImpl _value, $Res Function(_$ModifierImpl) _then) + : super(_value, _then); + + /// Create a copy of Modifier + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? data = freezed, + }) { + return _then(_$ModifierImpl( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + data: freezed == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as dynamic, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ModifierImpl with DiagnosticableTreeMixin implements _Modifier { + const _$ModifierImpl({required this.name, this.data}); + + factory _$ModifierImpl.fromJson(Map json) => + _$$ModifierImplFromJson(json); + + @override + final String name; + @override + final dynamic data; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'Modifier(name: $name, data: $data)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'Modifier')) + ..add(DiagnosticsProperty('name', name)) + ..add(DiagnosticsProperty('data', data)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ModifierImpl && + (identical(other.name, name) || other.name == name) && + const DeepCollectionEquality().equals(other.data, data)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => + Object.hash(runtimeType, name, const DeepCollectionEquality().hash(data)); + + /// Create a copy of Modifier + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ModifierImplCopyWith<_$ModifierImpl> get copyWith => + __$$ModifierImplCopyWithImpl<_$ModifierImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ModifierImplToJson( + this, + ); + } +} + +abstract class _Modifier implements Modifier { + const factory _Modifier({required final String name, final dynamic data}) = + _$ModifierImpl; + + factory _Modifier.fromJson(Map json) = + _$ModifierImpl.fromJson; + + @override + String get name; + @override + dynamic get data; + + /// Create a copy of Modifier + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ModifierImplCopyWith<_$ModifierImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/app/lib/models/adapter.g.dart b/app/lib/models/entry_blueprint.g.dart similarity index 79% rename from app/lib/models/adapter.g.dart rename to app/lib/models/entry_blueprint.g.dart index 55060bf6aa..18266c9aa7 100644 --- a/app/lib/models/adapter.g.dart +++ b/app/lib/models/entry_blueprint.g.dart @@ -1,35 +1,19 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'adapter.dart'; +part of 'entry_blueprint.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -_$AdapterImpl _$$AdapterImplFromJson(Map json) => - _$AdapterImpl( - name: json['name'] as String, - description: json['description'] as String, - version: json['version'] as String, - entries: (json['entries'] as List) - .map((e) => EntryBlueprint.fromJson(e as Map)) - .toList(), - ); - -Map _$$AdapterImplToJson(_$AdapterImpl instance) => - { - 'name': instance.name, - 'description': instance.description, - 'version': instance.version, - 'entries': instance.entries, - }; - _$EntryBlueprintImpl _$$EntryBlueprintImplFromJson(Map json) => _$EntryBlueprintImpl( + id: json['id'] as String, name: json['name'] as String, description: json['description'] as String, - adapter: json['adapter'] as String, - fields: ObjectField.fromJson(json['fields'] as Map), + extension: json['extension'] as String, + dataBlueprint: ObjectBlueprint.fromJson( + json['dataBlueprint'] as Map), tags: (json['tags'] as List?)?.map((e) => e as String).toList() ?? const [], @@ -42,17 +26,20 @@ _$EntryBlueprintImpl _$$EntryBlueprintImplFromJson(Map json) => Map _$$EntryBlueprintImplToJson( _$EntryBlueprintImpl instance) => { + 'id': instance.id, 'name': instance.name, 'description': instance.description, - 'adapter': instance.adapter, - 'fields': instance.fields, + 'extension': instance.extension, + 'dataBlueprint': instance.dataBlueprint, 'tags': instance.tags, 'color': const ColorConverter().toJson(instance.color), 'icon': instance.icon, }; -_$FieldTypeImpl _$$FieldTypeImplFromJson(Map json) => - _$FieldTypeImpl( +_$DataBlueprintTypeImpl _$$DataBlueprintTypeImplFromJson( + Map json) => + _$DataBlueprintTypeImpl( + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -60,15 +47,19 @@ _$FieldTypeImpl _$$FieldTypeImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$FieldTypeImplToJson(_$FieldTypeImpl instance) => +Map _$$DataBlueprintTypeImplToJson( + _$DataBlueprintTypeImpl instance) => { + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; -_$PrimitiveFieldImpl _$$PrimitiveFieldImplFromJson(Map json) => - _$PrimitiveFieldImpl( - type: $enumDecode(_$PrimitiveFieldTypeEnumMap, json['type']), +_$PrimitiveBlueprintImpl _$$PrimitiveBlueprintImplFromJson( + Map json) => + _$PrimitiveBlueprintImpl( + type: $enumDecode(_$PrimitiveTypeEnumMap, json['type']), + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -76,25 +67,27 @@ _$PrimitiveFieldImpl _$$PrimitiveFieldImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$PrimitiveFieldImplToJson( - _$PrimitiveFieldImpl instance) => +Map _$$PrimitiveBlueprintImplToJson( + _$PrimitiveBlueprintImpl instance) => { - 'type': _$PrimitiveFieldTypeEnumMap[instance.type]!, + 'type': _$PrimitiveTypeEnumMap[instance.type]!, + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; -const _$PrimitiveFieldTypeEnumMap = { - PrimitiveFieldType.boolean: 'boolean', - PrimitiveFieldType.double: 'double', - PrimitiveFieldType.integer: 'integer', - PrimitiveFieldType.string: 'string', +const _$PrimitiveTypeEnumMap = { + PrimitiveType.boolean: 'boolean', + PrimitiveType.double: 'double', + PrimitiveType.integer: 'integer', + PrimitiveType.string: 'string', }; -_$EnumFieldImpl _$$EnumFieldImplFromJson(Map json) => - _$EnumFieldImpl( +_$EnumBlueprintImpl _$$EnumBlueprintImplFromJson(Map json) => + _$EnumBlueprintImpl( values: (json['values'] as List).map((e) => e as String).toList(), + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -102,16 +95,18 @@ _$EnumFieldImpl _$$EnumFieldImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$EnumFieldImplToJson(_$EnumFieldImpl instance) => +Map _$$EnumBlueprintImplToJson(_$EnumBlueprintImpl instance) => { 'values': instance.values, + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; -_$ListFieldImpl _$$ListFieldImplFromJson(Map json) => - _$ListFieldImpl( - type: FieldInfo.fromJson(json['type'] as Map), +_$ListBlueprintImpl _$$ListBlueprintImplFromJson(Map json) => + _$ListBlueprintImpl( + type: DataBlueprint.fromJson(json['type'] as Map), + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -119,17 +114,19 @@ _$ListFieldImpl _$$ListFieldImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$ListFieldImplToJson(_$ListFieldImpl instance) => +Map _$$ListBlueprintImplToJson(_$ListBlueprintImpl instance) => { 'type': instance.type, + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; -_$MapFieldImpl _$$MapFieldImplFromJson(Map json) => - _$MapFieldImpl( - key: FieldInfo.fromJson(json['key'] as Map), - value: FieldInfo.fromJson(json['value'] as Map), +_$MapBlueprintImpl _$$MapBlueprintImplFromJson(Map json) => + _$MapBlueprintImpl( + key: DataBlueprint.fromJson(json['key'] as Map), + value: DataBlueprint.fromJson(json['value'] as Map), + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -137,19 +134,23 @@ _$MapFieldImpl _$$MapFieldImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$MapFieldImplToJson(_$MapFieldImpl instance) => +Map _$$MapBlueprintImplToJson(_$MapBlueprintImpl instance) => { 'key': instance.key, 'value': instance.value, + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; -_$ObjectFieldImpl _$$ObjectFieldImplFromJson(Map json) => - _$ObjectFieldImpl( +_$ObjectBlueprintImpl _$$ObjectBlueprintImplFromJson( + Map json) => + _$ObjectBlueprintImpl( fields: (json['fields'] as Map).map( - (k, e) => MapEntry(k, FieldInfo.fromJson(e as Map)), + (k, e) => + MapEntry(k, DataBlueprint.fromJson(e as Map)), ), + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -157,20 +158,21 @@ _$ObjectFieldImpl _$$ObjectFieldImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$ObjectFieldImplToJson(_$ObjectFieldImpl instance) => +Map _$$ObjectBlueprintImplToJson( + _$ObjectBlueprintImpl instance) => { 'fields': instance.fields, + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; -_$CustomFieldImpl _$$CustomFieldImplFromJson(Map json) => - _$CustomFieldImpl( +_$CustomBlueprintImpl _$$CustomBlueprintImplFromJson( + Map json) => + _$CustomBlueprintImpl( editor: json['editor'] as String, - defaultValue: json['default'], - fieldInfo: json['fieldInfo'] == null - ? null - : FieldInfo.fromJson(json['fieldInfo'] as Map), + shape: DataBlueprint.fromJson(json['shape'] as Map), + internalDefaultValue: json['default'], modifiers: (json['modifiers'] as List?) ?.map((e) => Modifier.fromJson(e as Map)) .toList() ?? @@ -178,11 +180,12 @@ _$CustomFieldImpl _$$CustomFieldImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$CustomFieldImplToJson(_$CustomFieldImpl instance) => +Map _$$CustomBlueprintImplToJson( + _$CustomBlueprintImpl instance) => { 'editor': instance.editor, - 'default': instance.defaultValue, - 'fieldInfo': instance.fieldInfo, + 'shape': instance.shape, + 'default': instance.internalDefaultValue, 'modifiers': instance.modifiers, 'kind': instance.$type, }; @@ -203,23 +206,7 @@ Map _$$ModifierImplToJson(_$ModifierImpl instance) => // RiverpodGenerator // ************************************************************************** -String _$adaptersHash() => r'b55e4dd5d1802c4e21359d057a765443bb896bd3'; - -/// A generated provider to fetch and cache a list of [Adapter]s. -/// -/// Copied from [adapters]. -@ProviderFor(adapters) -final adaptersProvider = AutoDisposeProvider>.internal( - adapters, - name: r'adaptersProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$adaptersHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef AdaptersRef = AutoDisposeProviderRef>; -String _$entryBlueprintsHash() => r'0e9019f7b17aa6dbeaed59a83c58fa1f1c0a52f6'; +String _$entryBlueprintsHash() => r'f0fa147f0decf8c831c0f3aa4d33530002a2b51b'; /// A generated provider to fetch and cache a list of all the [EntryBlueprint]s. /// @@ -237,7 +224,7 @@ final entryBlueprintsProvider = ); typedef EntryBlueprintsRef = AutoDisposeProviderRef>; -String _$entryBlueprintHash() => r'331a2ea9f825002876e28ac1a1805ed8e63e0934'; +String _$entryBlueprintHash() => r'6823811ab4f61b543b7b06c4069f224179cec055'; /// Copied from Dart SDK class _SystemHash { @@ -260,29 +247,29 @@ class _SystemHash { } } -/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. +/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. /// /// Copied from [entryBlueprint]. @ProviderFor(entryBlueprint) const entryBlueprintProvider = EntryBlueprintFamily(); -/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. +/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. /// /// Copied from [entryBlueprint]. class EntryBlueprintFamily extends Family { - /// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. + /// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. /// /// Copied from [entryBlueprint]. const EntryBlueprintFamily(); - /// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. + /// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. /// /// Copied from [entryBlueprint]. EntryBlueprintProvider call( - String blueprintName, + String blueprintId, ) { return EntryBlueprintProvider( - blueprintName, + blueprintId, ); } @@ -291,7 +278,7 @@ class EntryBlueprintFamily extends Family { covariant EntryBlueprintProvider provider, ) { return call( - provider.blueprintName, + provider.blueprintId, ); } @@ -310,19 +297,19 @@ class EntryBlueprintFamily extends Family { String? get name => r'entryBlueprintProvider'; } -/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. +/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. /// /// Copied from [entryBlueprint]. class EntryBlueprintProvider extends AutoDisposeProvider { - /// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintName]. + /// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId]. /// /// Copied from [entryBlueprint]. EntryBlueprintProvider( - String blueprintName, + String blueprintId, ) : this._internal( (ref) => entryBlueprint( ref as EntryBlueprintRef, - blueprintName, + blueprintId, ), from: entryBlueprintProvider, name: r'entryBlueprintProvider', @@ -333,7 +320,7 @@ class EntryBlueprintProvider extends AutoDisposeProvider { dependencies: EntryBlueprintFamily._dependencies, allTransitiveDependencies: EntryBlueprintFamily._allTransitiveDependencies, - blueprintName: blueprintName, + blueprintId: blueprintId, ); EntryBlueprintProvider._internal( @@ -343,10 +330,10 @@ class EntryBlueprintProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.blueprintName, + required this.blueprintId, }) : super.internal(); - final String blueprintName; + final String blueprintId; @override Override overrideWith( @@ -361,7 +348,7 @@ class EntryBlueprintProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - blueprintName: blueprintName, + blueprintId: blueprintId, ), ); } @@ -373,22 +360,21 @@ class EntryBlueprintProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { - return other is EntryBlueprintProvider && - other.blueprintName == blueprintName; + return other is EntryBlueprintProvider && other.blueprintId == blueprintId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, blueprintName.hashCode); + hash = _SystemHash.combine(hash, blueprintId.hashCode); return _SystemHash.finish(hash); } } mixin EntryBlueprintRef on AutoDisposeProviderRef { - /// The parameter `blueprintName` of this provider. - String get blueprintName; + /// The parameter `blueprintId` of this provider. + String get blueprintId; } class _EntryBlueprintProviderElement @@ -396,11 +382,11 @@ class _EntryBlueprintProviderElement _EntryBlueprintProviderElement(super.provider); @override - String get blueprintName => (origin as EntryBlueprintProvider).blueprintName; + String get blueprintId => (origin as EntryBlueprintProvider).blueprintId; } String _$entryBlueprintTagsHash() => - r'999df9eb33de7198efa9eb463cca6dd400d6456a'; + r'dc8074c390aabc3d6ff2b7778ee679d343c8ddac'; /// See also [entryBlueprintTags]. @ProviderFor(entryBlueprintTags) @@ -413,10 +399,10 @@ class EntryBlueprintTagsFamily extends Family> { /// See also [entryBlueprintTags]. EntryBlueprintTagsProvider call( - String blueprintName, + String blueprintId, ) { return EntryBlueprintTagsProvider( - blueprintName, + blueprintId, ); } @@ -425,7 +411,7 @@ class EntryBlueprintTagsFamily extends Family> { covariant EntryBlueprintTagsProvider provider, ) { return call( - provider.blueprintName, + provider.blueprintId, ); } @@ -448,11 +434,11 @@ class EntryBlueprintTagsFamily extends Family> { class EntryBlueprintTagsProvider extends AutoDisposeProvider> { /// See also [entryBlueprintTags]. EntryBlueprintTagsProvider( - String blueprintName, + String blueprintId, ) : this._internal( (ref) => entryBlueprintTags( ref as EntryBlueprintTagsRef, - blueprintName, + blueprintId, ), from: entryBlueprintTagsProvider, name: r'entryBlueprintTagsProvider', @@ -463,7 +449,7 @@ class EntryBlueprintTagsProvider extends AutoDisposeProvider> { dependencies: EntryBlueprintTagsFamily._dependencies, allTransitiveDependencies: EntryBlueprintTagsFamily._allTransitiveDependencies, - blueprintName: blueprintName, + blueprintId: blueprintId, ); EntryBlueprintTagsProvider._internal( @@ -473,10 +459,10 @@ class EntryBlueprintTagsProvider extends AutoDisposeProvider> { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.blueprintName, + required this.blueprintId, }) : super.internal(); - final String blueprintName; + final String blueprintId; @override Override overrideWith( @@ -491,7 +477,7 @@ class EntryBlueprintTagsProvider extends AutoDisposeProvider> { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - blueprintName: blueprintName, + blueprintId: blueprintId, ), ); } @@ -504,21 +490,21 @@ class EntryBlueprintTagsProvider extends AutoDisposeProvider> { @override bool operator ==(Object other) { return other is EntryBlueprintTagsProvider && - other.blueprintName == blueprintName; + other.blueprintId == blueprintId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, blueprintName.hashCode); + hash = _SystemHash.combine(hash, blueprintId.hashCode); return _SystemHash.finish(hash); } } mixin EntryBlueprintTagsRef on AutoDisposeProviderRef> { - /// The parameter `blueprintName` of this provider. - String get blueprintName; + /// The parameter `blueprintId` of this provider. + String get blueprintId; } class _EntryBlueprintTagsProviderElement @@ -527,11 +513,10 @@ class _EntryBlueprintTagsProviderElement _EntryBlueprintTagsProviderElement(super.provider); @override - String get blueprintName => - (origin as EntryBlueprintTagsProvider).blueprintName; + String get blueprintId => (origin as EntryBlueprintTagsProvider).blueprintId; } -String _$entryTagsHash() => r'b71bc52479db49fa3f55d80106a998243f377f3d'; +String _$entryTagsHash() => r'26e764a45dae73ed8e21ac9affbe0c3c524e59ef'; /// See also [entryTags]. @ProviderFor(entryTags) @@ -659,7 +644,7 @@ class _EntryTagsProviderElement extends AutoDisposeProviderElement> } String _$entryBlueprintPageTypeHash() => - r'ab9695f4ad5cf34bf53658d8f765b51d8f463868'; + r'7ea4a3693045d74a338e7a2fe7de83c915b23137'; /// See also [entryBlueprintPageType]. @ProviderFor(entryBlueprintPageType) @@ -672,10 +657,10 @@ class EntryBlueprintPageTypeFamily extends Family { /// See also [entryBlueprintPageType]. EntryBlueprintPageTypeProvider call( - String blueprintName, + String blueprintId, ) { return EntryBlueprintPageTypeProvider( - blueprintName, + blueprintId, ); } @@ -684,7 +669,7 @@ class EntryBlueprintPageTypeFamily extends Family { covariant EntryBlueprintPageTypeProvider provider, ) { return call( - provider.blueprintName, + provider.blueprintId, ); } @@ -707,11 +692,11 @@ class EntryBlueprintPageTypeFamily extends Family { class EntryBlueprintPageTypeProvider extends AutoDisposeProvider { /// See also [entryBlueprintPageType]. EntryBlueprintPageTypeProvider( - String blueprintName, + String blueprintId, ) : this._internal( (ref) => entryBlueprintPageType( ref as EntryBlueprintPageTypeRef, - blueprintName, + blueprintId, ), from: entryBlueprintPageTypeProvider, name: r'entryBlueprintPageTypeProvider', @@ -722,7 +707,7 @@ class EntryBlueprintPageTypeProvider extends AutoDisposeProvider { dependencies: EntryBlueprintPageTypeFamily._dependencies, allTransitiveDependencies: EntryBlueprintPageTypeFamily._allTransitiveDependencies, - blueprintName: blueprintName, + blueprintId: blueprintId, ); EntryBlueprintPageTypeProvider._internal( @@ -732,10 +717,10 @@ class EntryBlueprintPageTypeProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.blueprintName, + required this.blueprintId, }) : super.internal(); - final String blueprintName; + final String blueprintId; @override Override overrideWith( @@ -750,7 +735,7 @@ class EntryBlueprintPageTypeProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - blueprintName: blueprintName, + blueprintId: blueprintId, ), ); } @@ -763,21 +748,21 @@ class EntryBlueprintPageTypeProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { return other is EntryBlueprintPageTypeProvider && - other.blueprintName == blueprintName; + other.blueprintId == blueprintId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, blueprintName.hashCode); + hash = _SystemHash.combine(hash, blueprintId.hashCode); return _SystemHash.finish(hash); } } mixin EntryBlueprintPageTypeRef on AutoDisposeProviderRef { - /// The parameter `blueprintName` of this provider. - String get blueprintName; + /// The parameter `blueprintId` of this provider. + String get blueprintId; } class _EntryBlueprintPageTypeProviderElement @@ -786,11 +771,11 @@ class _EntryBlueprintPageTypeProviderElement _EntryBlueprintPageTypeProviderElement(super.provider); @override - String get blueprintName => - (origin as EntryBlueprintPageTypeProvider).blueprintName; + String get blueprintId => + (origin as EntryBlueprintPageTypeProvider).blueprintId; } -String _$fieldModifiersHash() => r'2e926b371b7db972ec7c3ed7db468baaa6839aba'; +String _$fieldModifiersHash() => r'356ae9f89ffe0ab87b1d27055284326ee202e770'; /// Gets all the modifiers with a given name. /// @@ -811,11 +796,11 @@ class FieldModifiersFamily extends Family> { /// /// Copied from [fieldModifiers]. FieldModifiersProvider call( - String blueprintName, + String blueprintId, String modifierName, ) { return FieldModifiersProvider( - blueprintName, + blueprintId, modifierName, ); } @@ -825,7 +810,7 @@ class FieldModifiersFamily extends Family> { covariant FieldModifiersProvider provider, ) { return call( - provider.blueprintName, + provider.blueprintId, provider.modifierName, ); } @@ -854,12 +839,12 @@ class FieldModifiersProvider /// /// Copied from [fieldModifiers]. FieldModifiersProvider( - String blueprintName, + String blueprintId, String modifierName, ) : this._internal( (ref) => fieldModifiers( ref as FieldModifiersRef, - blueprintName, + blueprintId, modifierName, ), from: fieldModifiersProvider, @@ -871,7 +856,7 @@ class FieldModifiersProvider dependencies: FieldModifiersFamily._dependencies, allTransitiveDependencies: FieldModifiersFamily._allTransitiveDependencies, - blueprintName: blueprintName, + blueprintId: blueprintId, modifierName: modifierName, ); @@ -882,11 +867,11 @@ class FieldModifiersProvider required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.blueprintName, + required this.blueprintId, required this.modifierName, }) : super.internal(); - final String blueprintName; + final String blueprintId; final String modifierName; @override @@ -902,7 +887,7 @@ class FieldModifiersProvider dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - blueprintName: blueprintName, + blueprintId: blueprintId, modifierName: modifierName, ), ); @@ -916,14 +901,14 @@ class FieldModifiersProvider @override bool operator ==(Object other) { return other is FieldModifiersProvider && - other.blueprintName == blueprintName && + other.blueprintId == blueprintId && other.modifierName == modifierName; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, blueprintName.hashCode); + hash = _SystemHash.combine(hash, blueprintId.hashCode); hash = _SystemHash.combine(hash, modifierName.hashCode); return _SystemHash.finish(hash); @@ -931,8 +916,8 @@ class FieldModifiersProvider } mixin FieldModifiersRef on AutoDisposeProviderRef> { - /// The parameter `blueprintName` of this provider. - String get blueprintName; + /// The parameter `blueprintId` of this provider. + String get blueprintId; /// The parameter `modifierName` of this provider. String get modifierName; @@ -944,12 +929,12 @@ class _FieldModifiersProviderElement _FieldModifiersProviderElement(super.provider); @override - String get blueprintName => (origin as FieldModifiersProvider).blueprintName; + String get blueprintId => (origin as FieldModifiersProvider).blueprintId; @override String get modifierName => (origin as FieldModifiersProvider).modifierName; } -String _$modifierPathsHash() => r'284078b7f30b5e344e771c4a093ded5131de6632'; +String _$modifierPathsHash() => r'a493a5169c9cf43cf8611369477bcbe968f50fd4'; /// Gets all the paths from fields with a given modifier. /// @@ -970,12 +955,12 @@ class ModifierPathsFamily extends Family> { /// /// Copied from [modifierPaths]. ModifierPathsProvider call( - String blueprintName, + String blueprintId, String modifierName, [ String? data, ]) { return ModifierPathsProvider( - blueprintName, + blueprintId, modifierName, data, ); @@ -986,7 +971,7 @@ class ModifierPathsFamily extends Family> { covariant ModifierPathsProvider provider, ) { return call( - provider.blueprintName, + provider.blueprintId, provider.modifierName, provider.data, ); @@ -1015,13 +1000,13 @@ class ModifierPathsProvider extends AutoDisposeProvider> { /// /// Copied from [modifierPaths]. ModifierPathsProvider( - String blueprintName, + String blueprintId, String modifierName, [ String? data, ]) : this._internal( (ref) => modifierPaths( ref as ModifierPathsRef, - blueprintName, + blueprintId, modifierName, data, ), @@ -1034,7 +1019,7 @@ class ModifierPathsProvider extends AutoDisposeProvider> { dependencies: ModifierPathsFamily._dependencies, allTransitiveDependencies: ModifierPathsFamily._allTransitiveDependencies, - blueprintName: blueprintName, + blueprintId: blueprintId, modifierName: modifierName, data: data, ); @@ -1046,12 +1031,12 @@ class ModifierPathsProvider extends AutoDisposeProvider> { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.blueprintName, + required this.blueprintId, required this.modifierName, required this.data, }) : super.internal(); - final String blueprintName; + final String blueprintId; final String modifierName; final String? data; @@ -1068,7 +1053,7 @@ class ModifierPathsProvider extends AutoDisposeProvider> { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - blueprintName: blueprintName, + blueprintId: blueprintId, modifierName: modifierName, data: data, ), @@ -1083,7 +1068,7 @@ class ModifierPathsProvider extends AutoDisposeProvider> { @override bool operator ==(Object other) { return other is ModifierPathsProvider && - other.blueprintName == blueprintName && + other.blueprintId == blueprintId && other.modifierName == modifierName && other.data == data; } @@ -1091,7 +1076,7 @@ class ModifierPathsProvider extends AutoDisposeProvider> { @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, blueprintName.hashCode); + hash = _SystemHash.combine(hash, blueprintId.hashCode); hash = _SystemHash.combine(hash, modifierName.hashCode); hash = _SystemHash.combine(hash, data.hashCode); @@ -1100,8 +1085,8 @@ class ModifierPathsProvider extends AutoDisposeProvider> { } mixin ModifierPathsRef on AutoDisposeProviderRef> { - /// The parameter `blueprintName` of this provider. - String get blueprintName; + /// The parameter `blueprintId` of this provider. + String get blueprintId; /// The parameter `modifierName` of this provider. String get modifierName; @@ -1115,7 +1100,7 @@ class _ModifierPathsProviderElement _ModifierPathsProviderElement(super.provider); @override - String get blueprintName => (origin as ModifierPathsProvider).blueprintName; + String get blueprintId => (origin as ModifierPathsProvider).blueprintId; @override String get modifierName => (origin as ModifierPathsProvider).modifierName; @override diff --git a/app/lib/models/extension.dart b/app/lib/models/extension.dart new file mode 100644 index 0000000000..9499631822 --- /dev/null +++ b/app/lib/models/extension.dart @@ -0,0 +1,38 @@ +import "package:flutter/foundation.dart"; +import "package:freezed_annotation/freezed_annotation.dart"; +import "package:riverpod_annotation/riverpod_annotation.dart"; +import "package:typewriter/models/book.dart"; +import "package:typewriter/models/entry_blueprint.dart"; + +part "extension.freezed.dart"; +part "extension.g.dart"; + +/// A generated provider to fetch and cache a list of [Extension]s. +@riverpod +List extensions(ExtensionsRef ref) => + ref.watch(bookProvider).extensions; + +/// A data model that represents an extension. +@freezed +class Extension with _$Extension { + const factory Extension({ + required ExtensionInfo extension, + required List entries, + }) = _Extension; + + factory Extension.fromJson(Map json) => + _$ExtensionFromJson(json); +} + +@freezed +class ExtensionInfo with _$ExtensionInfo { + const factory ExtensionInfo({ + required String name, + required String shortDescription, + required String description, + required String version, + }) = _ExtensionInfo; + + factory ExtensionInfo.fromJson(Map json) => + _$ExtensionInfoFromJson(json); +} diff --git a/app/lib/models/extension.freezed.dart b/app/lib/models/extension.freezed.dart new file mode 100644 index 0000000000..215ac5fe44 --- /dev/null +++ b/app/lib/models/extension.freezed.dart @@ -0,0 +1,443 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'extension.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +Extension _$ExtensionFromJson(Map json) { + return _Extension.fromJson(json); +} + +/// @nodoc +mixin _$Extension { + ExtensionInfo get extension => throw _privateConstructorUsedError; + List get entries => throw _privateConstructorUsedError; + + /// Serializes this Extension to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of Extension + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ExtensionCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ExtensionCopyWith<$Res> { + factory $ExtensionCopyWith(Extension value, $Res Function(Extension) then) = + _$ExtensionCopyWithImpl<$Res, Extension>; + @useResult + $Res call({ExtensionInfo extension, List entries}); + + $ExtensionInfoCopyWith<$Res> get extension; +} + +/// @nodoc +class _$ExtensionCopyWithImpl<$Res, $Val extends Extension> + implements $ExtensionCopyWith<$Res> { + _$ExtensionCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of Extension + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? extension = null, + Object? entries = null, + }) { + return _then(_value.copyWith( + extension: null == extension + ? _value.extension + : extension // ignore: cast_nullable_to_non_nullable + as ExtensionInfo, + entries: null == entries + ? _value.entries + : entries // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } + + /// Create a copy of Extension + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ExtensionInfoCopyWith<$Res> get extension { + return $ExtensionInfoCopyWith<$Res>(_value.extension, (value) { + return _then(_value.copyWith(extension: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ExtensionImplCopyWith<$Res> + implements $ExtensionCopyWith<$Res> { + factory _$$ExtensionImplCopyWith( + _$ExtensionImpl value, $Res Function(_$ExtensionImpl) then) = + __$$ExtensionImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ExtensionInfo extension, List entries}); + + @override + $ExtensionInfoCopyWith<$Res> get extension; +} + +/// @nodoc +class __$$ExtensionImplCopyWithImpl<$Res> + extends _$ExtensionCopyWithImpl<$Res, _$ExtensionImpl> + implements _$$ExtensionImplCopyWith<$Res> { + __$$ExtensionImplCopyWithImpl( + _$ExtensionImpl _value, $Res Function(_$ExtensionImpl) _then) + : super(_value, _then); + + /// Create a copy of Extension + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? extension = null, + Object? entries = null, + }) { + return _then(_$ExtensionImpl( + extension: null == extension + ? _value.extension + : extension // ignore: cast_nullable_to_non_nullable + as ExtensionInfo, + entries: null == entries + ? _value._entries + : entries // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ExtensionImpl with DiagnosticableTreeMixin implements _Extension { + const _$ExtensionImpl( + {required this.extension, required final List entries}) + : _entries = entries; + + factory _$ExtensionImpl.fromJson(Map json) => + _$$ExtensionImplFromJson(json); + + @override + final ExtensionInfo extension; + final List _entries; + @override + List get entries { + if (_entries is EqualUnmodifiableListView) return _entries; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_entries); + } + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'Extension(extension: $extension, entries: $entries)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'Extension')) + ..add(DiagnosticsProperty('extension', extension)) + ..add(DiagnosticsProperty('entries', entries)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ExtensionImpl && + (identical(other.extension, extension) || + other.extension == extension) && + const DeepCollectionEquality().equals(other._entries, _entries)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, extension, const DeepCollectionEquality().hash(_entries)); + + /// Create a copy of Extension + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ExtensionImplCopyWith<_$ExtensionImpl> get copyWith => + __$$ExtensionImplCopyWithImpl<_$ExtensionImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ExtensionImplToJson( + this, + ); + } +} + +abstract class _Extension implements Extension { + const factory _Extension( + {required final ExtensionInfo extension, + required final List entries}) = _$ExtensionImpl; + + factory _Extension.fromJson(Map json) = + _$ExtensionImpl.fromJson; + + @override + ExtensionInfo get extension; + @override + List get entries; + + /// Create a copy of Extension + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ExtensionImplCopyWith<_$ExtensionImpl> get copyWith => + throw _privateConstructorUsedError; +} + +ExtensionInfo _$ExtensionInfoFromJson(Map json) { + return _ExtensionInfo.fromJson(json); +} + +/// @nodoc +mixin _$ExtensionInfo { + String get name => throw _privateConstructorUsedError; + String get shortDescription => throw _privateConstructorUsedError; + String get description => throw _privateConstructorUsedError; + String get version => throw _privateConstructorUsedError; + + /// Serializes this ExtensionInfo to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ExtensionInfo + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ExtensionInfoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ExtensionInfoCopyWith<$Res> { + factory $ExtensionInfoCopyWith( + ExtensionInfo value, $Res Function(ExtensionInfo) then) = + _$ExtensionInfoCopyWithImpl<$Res, ExtensionInfo>; + @useResult + $Res call( + {String name, + String shortDescription, + String description, + String version}); +} + +/// @nodoc +class _$ExtensionInfoCopyWithImpl<$Res, $Val extends ExtensionInfo> + implements $ExtensionInfoCopyWith<$Res> { + _$ExtensionInfoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ExtensionInfo + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? shortDescription = null, + Object? description = null, + Object? version = null, + }) { + return _then(_value.copyWith( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + shortDescription: null == shortDescription + ? _value.shortDescription + : shortDescription // ignore: cast_nullable_to_non_nullable + as String, + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + version: null == version + ? _value.version + : version // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ExtensionInfoImplCopyWith<$Res> + implements $ExtensionInfoCopyWith<$Res> { + factory _$$ExtensionInfoImplCopyWith( + _$ExtensionInfoImpl value, $Res Function(_$ExtensionInfoImpl) then) = + __$$ExtensionInfoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String name, + String shortDescription, + String description, + String version}); +} + +/// @nodoc +class __$$ExtensionInfoImplCopyWithImpl<$Res> + extends _$ExtensionInfoCopyWithImpl<$Res, _$ExtensionInfoImpl> + implements _$$ExtensionInfoImplCopyWith<$Res> { + __$$ExtensionInfoImplCopyWithImpl( + _$ExtensionInfoImpl _value, $Res Function(_$ExtensionInfoImpl) _then) + : super(_value, _then); + + /// Create a copy of ExtensionInfo + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? shortDescription = null, + Object? description = null, + Object? version = null, + }) { + return _then(_$ExtensionInfoImpl( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + shortDescription: null == shortDescription + ? _value.shortDescription + : shortDescription // ignore: cast_nullable_to_non_nullable + as String, + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + version: null == version + ? _value.version + : version // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ExtensionInfoImpl + with DiagnosticableTreeMixin + implements _ExtensionInfo { + const _$ExtensionInfoImpl( + {required this.name, + required this.shortDescription, + required this.description, + required this.version}); + + factory _$ExtensionInfoImpl.fromJson(Map json) => + _$$ExtensionInfoImplFromJson(json); + + @override + final String name; + @override + final String shortDescription; + @override + final String description; + @override + final String version; + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'ExtensionInfo(name: $name, shortDescription: $shortDescription, description: $description, version: $version)'; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('type', 'ExtensionInfo')) + ..add(DiagnosticsProperty('name', name)) + ..add(DiagnosticsProperty('shortDescription', shortDescription)) + ..add(DiagnosticsProperty('description', description)) + ..add(DiagnosticsProperty('version', version)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ExtensionInfoImpl && + (identical(other.name, name) || other.name == name) && + (identical(other.shortDescription, shortDescription) || + other.shortDescription == shortDescription) && + (identical(other.description, description) || + other.description == description) && + (identical(other.version, version) || other.version == version)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => + Object.hash(runtimeType, name, shortDescription, description, version); + + /// Create a copy of ExtensionInfo + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ExtensionInfoImplCopyWith<_$ExtensionInfoImpl> get copyWith => + __$$ExtensionInfoImplCopyWithImpl<_$ExtensionInfoImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ExtensionInfoImplToJson( + this, + ); + } +} + +abstract class _ExtensionInfo implements ExtensionInfo { + const factory _ExtensionInfo( + {required final String name, + required final String shortDescription, + required final String description, + required final String version}) = _$ExtensionInfoImpl; + + factory _ExtensionInfo.fromJson(Map json) = + _$ExtensionInfoImpl.fromJson; + + @override + String get name; + @override + String get shortDescription; + @override + String get description; + @override + String get version; + + /// Create a copy of ExtensionInfo + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ExtensionInfoImplCopyWith<_$ExtensionInfoImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/app/lib/models/extension.g.dart b/app/lib/models/extension.g.dart new file mode 100644 index 0000000000..4fa051b264 --- /dev/null +++ b/app/lib/models/extension.g.dart @@ -0,0 +1,61 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'extension.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$ExtensionImpl _$$ExtensionImplFromJson(Map json) => + _$ExtensionImpl( + extension: + ExtensionInfo.fromJson(json['extension'] as Map), + entries: (json['entries'] as List) + .map((e) => EntryBlueprint.fromJson(e as Map)) + .toList(), + ); + +Map _$$ExtensionImplToJson(_$ExtensionImpl instance) => + { + 'extension': instance.extension, + 'entries': instance.entries, + }; + +_$ExtensionInfoImpl _$$ExtensionInfoImplFromJson(Map json) => + _$ExtensionInfoImpl( + name: json['name'] as String, + shortDescription: json['shortDescription'] as String, + description: json['description'] as String, + version: json['version'] as String, + ); + +Map _$$ExtensionInfoImplToJson(_$ExtensionInfoImpl instance) => + { + 'name': instance.name, + 'shortDescription': instance.shortDescription, + 'description': instance.description, + 'version': instance.version, + }; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$extensionsHash() => r'c5ab97411f68e5201eaf3154a8c578929e519906'; + +/// A generated provider to fetch and cache a list of [Extension]s. +/// +/// Copied from [extensions]. +@ProviderFor(extensions) +final extensionsProvider = AutoDisposeProvider>.internal( + extensions, + name: r'extensionsProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$extensionsHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef ExtensionsRef = AutoDisposeProviderRef>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/app/lib/models/materials.freezed.dart b/app/lib/models/materials.freezed.dart index 0d273d7c46..efc72d83df 100644 --- a/app/lib/models/materials.freezed.dart +++ b/app/lib/models/materials.freezed.dart @@ -24,8 +24,12 @@ mixin _$MinecraftMaterial { List get properties => throw _privateConstructorUsedError; String get icon => throw _privateConstructorUsedError; + /// Serializes this MinecraftMaterial to a JSON map. Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + + /// Create a copy of MinecraftMaterial + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $MinecraftMaterialCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -49,6 +53,8 @@ class _$MinecraftMaterialCopyWithImpl<$Res, $Val extends MinecraftMaterial> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of MinecraftMaterial + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -92,6 +98,8 @@ class __$$MinecraftMaterialImplCopyWithImpl<$Res> $Res Function(_$MinecraftMaterialImpl) _then) : super(_value, _then); + /// Create a copy of MinecraftMaterial + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -157,12 +165,14 @@ class _$MinecraftMaterialImpl implements _MinecraftMaterial { (identical(other.icon, icon) || other.icon == icon)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, name, const DeepCollectionEquality().hash(_properties), icon); - @JsonKey(ignore: true) + /// Create a copy of MinecraftMaterial + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$MinecraftMaterialImplCopyWith<_$MinecraftMaterialImpl> get copyWith => @@ -192,8 +202,11 @@ abstract class _MinecraftMaterial implements MinecraftMaterial { List get properties; @override String get icon; + + /// Create a copy of MinecraftMaterial + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$MinecraftMaterialImplCopyWith<_$MinecraftMaterialImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/page.dart b/app/lib/models/page.dart index 5d4f3a6974..20e42c597e 100644 --- a/app/lib/models/page.dart +++ b/app/lib/models/page.dart @@ -2,10 +2,10 @@ import "package:collection/collection.dart"; import "package:flutter/material.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/book.dart"; import "package:typewriter/models/communicator.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -23,30 +23,28 @@ List pages(PagesRef ref) { } @riverpod -Page? page(PageRef ref, String pageName) { - return ref - .watch(pagesProvider) - .firstWhereOrNull((page) => page.pageName == pageName); +Page? page(PageRef ref, String pageId) { + return ref.watch(pagesProvider).firstWhereOrNull((page) => page.id == pageId); } @riverpod -bool pageExists(PageExistsRef ref, String pageName) { - return ref.watch(pageProvider(pageName)) != null; +bool pageExists(PageExistsRef ref, String pageId) { + return ref.watch(pageProvider(pageId)) != null; } @riverpod -PageType pageType(PageTypeRef ref, String pageName) { - return ref.watch(pageProvider(pageName))?.type ?? PageType.sequence; +PageType pageType(PageTypeRef ref, String pageId) { + return ref.watch(pageProvider(pageId))?.type ?? PageType.sequence; } @riverpod -String pageChapter(PageChapterRef ref, String pageName) { - return ref.watch(pageProvider(pageName))?.chapter ?? ""; +String pageChapter(PageChapterRef ref, String pageId) { + return ref.watch(pageProvider(pageId))?.chapter ?? ""; } @riverpod -int pagePriority(PagePriorityRef ref, String pageName) { - return ref.watch(pageProvider(pageName))?.priority ?? 0; +int pagePriority(PagePriorityRef ref, String pageId) { + return ref.watch(pageProvider(pageId))?.priority ?? 0; } @riverpod @@ -56,7 +54,7 @@ String? entryPageId(EntryPageIdRef ref, String entryId) { .firstWhereOrNull( (page) => page.entries.any((entry) => entry.id == entryId), ) - ?.pageName; + ?.id; } @riverpod @@ -76,11 +74,14 @@ Entry? entry(EntryRef ref, String pageId, String entryId) { @riverpod Entry? globalEntry(GlobalEntryRef ref, String entryId) { - final pageId = ref.watch(entryPageIdProvider(entryId)); - if (pageId == null) { - return null; + final pages = ref.watch(pagesProvider); + for (final page in pages) { + final entry = page.entries.firstWhereOrNull((entry) => entry.id == entryId); + if (entry != null) { + return entry; + } } - return ref.watch(entryProvider(pageId, entryId)); + return null; } @riverpod @@ -136,6 +137,7 @@ enum PageType { @freezed class Page with _$Page { const factory Page({ + required String id, @JsonKey(name: "name") required String pageName, required PageType type, @Default([]) List entries, @@ -149,7 +151,7 @@ class Page with _$Page { extension PageExtension on Page { void updatePage(PassingRef ref, Page Function(Page) update) { // If multiple updates are done at the same time, `this` might be outdated. So we need to get the latest version. - final currentPage = ref.read(pageProvider(pageName)); + final currentPage = ref.read(pageProvider(id)); if (currentPage == null) { return; } @@ -164,7 +166,7 @@ extension PageExtension on Page { ); await ref .read(communicatorProvider) - .changePageValue(pageName, "chapter", newChapter); + .changePageValue(id, "chapter", newChapter); } Future changePriority(PassingRef ref, int newPriority) async { @@ -174,7 +176,7 @@ extension PageExtension on Page { ); await ref .read(communicatorProvider) - .changePageValue(pageName, "priority", newPriority); + .changePageValue(id, "priority", newPriority); } Future createEntry(PassingRef ref, Entry entry) async { @@ -182,7 +184,7 @@ extension PageExtension on Page { ref, (page) => _insertEntry(page, entry), ); - await ref.read(communicatorProvider).createEntry(pageName, entry); + await ref.read(communicatorProvider).createEntry(id, entry); } Future updateEntireEntry(PassingRef ref, Entry entry) async { @@ -190,7 +192,7 @@ extension PageExtension on Page { ref, (page) => _insertEntry(page, entry), ); - await ref.read(communicatorProvider).updateEntireEntry(pageName, entry); + await ref.read(communicatorProvider).updateEntireEntry(id, entry); } Future updateEntryValue( @@ -203,14 +205,12 @@ extension PageExtension on Page { ref, (page) => _insertEntry(page, entry.copyWith(path, value)), ); - await ref - .read(communicatorProvider) - .updateEntry(pageName, entry.id, path, value); + await ref.read(communicatorProvider).updateEntry(id, entry.id, path, value); } void reorderEntry(PassingRef ref, String entryId, int newIndex) { syncReorderEntry(ref, entryId, newIndex); - ref.read(communicatorProvider).reorderEntry(pageName, entryId, newIndex); + ref.read(communicatorProvider).reorderEntry(id, entryId, newIndex); } void syncReorderEntry(PassingRef ref, String entryId, int newIndex) { @@ -258,7 +258,7 @@ extension PageExtension on Page { } void deleteEntry(PassingRef ref, Entry entry) { - ref.read(communicatorProvider).deleteEntry(pageName, entry.id); + ref.read(communicatorProvider).deleteEntry(id, entry.id); updatePage( ref, (page) => page.copyWith( @@ -270,11 +270,7 @@ extension PageExtension on Page { ), ); // Also delete all references to this entry from other pages. - ref - .read(bookProvider) - .pages - .where((page) => page.pageName != pageName) - .forEach((page) { + ref.read(bookProvider).pages.where((page) => page.id != id).forEach((page) { page.removeReferencesTo(ref, entry.id); }); @@ -303,7 +299,7 @@ extension PageExtension on Page { String targetId, ) { final referenceEntryPaths = - ref.read(modifierPathsProvider(entry.type, "entry")); + ref.read(modifierPathsProvider(entry.blueprintId, "entry")); final referenceEntryIds = referenceEntryPaths .expand((path) => entry.getAll(path)) @@ -322,7 +318,7 @@ extension PageExtension on Page { ), ); - ref.read(communicatorProvider).updateEntireEntry(pageName, newEntry); + ref.read(communicatorProvider).updateEntireEntry(id, newEntry); return newEntry; } @@ -393,10 +389,11 @@ extension PageX on Page { String entryId, String path, ) async { - final entry = ref.read(entryProvider(pageName, entryId)); + final entry = ref.read(entryProvider(id, entryId)); if (entry == null) return; - final modifiers = ref.read(fieldModifiersProvider(entry.type, "entry")); + final modifiers = + ref.read(fieldModifiersProvider(entry.blueprintId, "entry")); final wildPath = path.wild(); final pathModifier = modifiers[wildPath]; @@ -428,9 +425,10 @@ extension PageX on Page { } void linkWith(PassingRef ref, String entryId, String path) { - final entry = ref.read(entryProvider(pageName, entryId)); + final entry = ref.read(entryProvider(id, entryId)); if (entry == null) return; - final modifiers = ref.read(fieldModifiersProvider(entry.type, "entry")); + final modifiers = + ref.read(fieldModifiersProvider(entry.blueprintId, "entry")); final wildPath = path.wild(); final pathModifier = modifiers[wildPath]; @@ -445,7 +443,7 @@ extension PageX on Page { // If the path has a only_tags modifier, we can only link to entries any of those tags and the tag of the entry. final onlyTagsModifier = - ref.read(fieldModifiersProvider(entry.type, "only_tags")); + ref.read(fieldModifiersProvider(entry.blueprintId, "only_tags")); final onlyTags = onlyTagsModifier[wildPath]; final List tags; @@ -489,7 +487,7 @@ extension PageX on Page { content: "Are you sure you want to delete this entry?", confirmText: "Delete", onConfirm: () { - final entry = ref.read(entryProvider(pageName, entryId)); + final entry = ref.read(entryProvider(id, entryId)); if (entry == null) return; deleteEntry(ref, entry); }, diff --git a/app/lib/models/page.freezed.dart b/app/lib/models/page.freezed.dart index b1c2db1802..941288e3e3 100644 --- a/app/lib/models/page.freezed.dart +++ b/app/lib/models/page.freezed.dart @@ -20,6 +20,7 @@ Page _$PageFromJson(Map json) { /// @nodoc mixin _$Page { + String get id => throw _privateConstructorUsedError; @JsonKey(name: "name") String get pageName => throw _privateConstructorUsedError; PageType get type => throw _privateConstructorUsedError; @@ -27,8 +28,12 @@ mixin _$Page { String get chapter => throw _privateConstructorUsedError; int get priority => throw _privateConstructorUsedError; + /// Serializes this Page to a JSON map. Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + + /// Create a copy of Page + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $PageCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -38,7 +43,8 @@ abstract class $PageCopyWith<$Res> { _$PageCopyWithImpl<$Res, Page>; @useResult $Res call( - {@JsonKey(name: "name") String pageName, + {String id, + @JsonKey(name: "name") String pageName, PageType type, List entries, String chapter, @@ -55,9 +61,12 @@ class _$PageCopyWithImpl<$Res, $Val extends Page> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Page + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ + Object? id = null, Object? pageName = null, Object? type = null, Object? entries = null, @@ -65,6 +74,10 @@ class _$PageCopyWithImpl<$Res, $Val extends Page> Object? priority = null, }) { return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, pageName: null == pageName ? _value.pageName : pageName // ignore: cast_nullable_to_non_nullable @@ -97,7 +110,8 @@ abstract class _$$PageImplCopyWith<$Res> implements $PageCopyWith<$Res> { @override @useResult $Res call( - {@JsonKey(name: "name") String pageName, + {String id, + @JsonKey(name: "name") String pageName, PageType type, List entries, String chapter, @@ -111,9 +125,12 @@ class __$$PageImplCopyWithImpl<$Res> __$$PageImplCopyWithImpl(_$PageImpl _value, $Res Function(_$PageImpl) _then) : super(_value, _then); + /// Create a copy of Page + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ + Object? id = null, Object? pageName = null, Object? type = null, Object? entries = null, @@ -121,6 +138,10 @@ class __$$PageImplCopyWithImpl<$Res> Object? priority = null, }) { return _then(_$PageImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, pageName: null == pageName ? _value.pageName : pageName // ignore: cast_nullable_to_non_nullable @@ -149,7 +170,8 @@ class __$$PageImplCopyWithImpl<$Res> @JsonSerializable() class _$PageImpl implements _Page { const _$PageImpl( - {@JsonKey(name: "name") required this.pageName, + {required this.id, + @JsonKey(name: "name") required this.pageName, required this.type, final List entries = const [], this.chapter = "", @@ -159,6 +181,8 @@ class _$PageImpl implements _Page { factory _$PageImpl.fromJson(Map json) => _$$PageImplFromJson(json); + @override + final String id; @override @JsonKey(name: "name") final String pageName; @@ -182,7 +206,7 @@ class _$PageImpl implements _Page { @override String toString() { - return 'Page(pageName: $pageName, type: $type, entries: $entries, chapter: $chapter, priority: $priority)'; + return 'Page(id: $id, pageName: $pageName, type: $type, entries: $entries, chapter: $chapter, priority: $priority)'; } @override @@ -190,6 +214,7 @@ class _$PageImpl implements _Page { return identical(this, other) || (other.runtimeType == runtimeType && other is _$PageImpl && + (identical(other.id, id) || other.id == id) && (identical(other.pageName, pageName) || other.pageName == pageName) && (identical(other.type, type) || other.type == type) && @@ -199,12 +224,14 @@ class _$PageImpl implements _Page { other.priority == priority)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash(runtimeType, pageName, type, + int get hashCode => Object.hash(runtimeType, id, pageName, type, const DeepCollectionEquality().hash(_entries), chapter, priority); - @JsonKey(ignore: true) + /// Create a copy of Page + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$PageImplCopyWith<_$PageImpl> get copyWith => @@ -220,7 +247,8 @@ class _$PageImpl implements _Page { abstract class _Page implements Page { const factory _Page( - {@JsonKey(name: "name") required final String pageName, + {required final String id, + @JsonKey(name: "name") required final String pageName, required final PageType type, final List entries, final String chapter, @@ -228,6 +256,8 @@ abstract class _Page implements Page { factory _Page.fromJson(Map json) = _$PageImpl.fromJson; + @override + String get id; @override @JsonKey(name: "name") String get pageName; @@ -239,8 +269,11 @@ abstract class _Page implements Page { String get chapter; @override int get priority; + + /// Create a copy of Page + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$PageImplCopyWith<_$PageImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/page.g.dart b/app/lib/models/page.g.dart index 0b79311845..fd826f35d0 100644 --- a/app/lib/models/page.g.dart +++ b/app/lib/models/page.g.dart @@ -7,6 +7,7 @@ part of 'page.dart'; // ************************************************************************** _$PageImpl _$$PageImplFromJson(Map json) => _$PageImpl( + id: json['id'] as String, pageName: json['name'] as String, type: $enumDecode(_$PageTypeEnumMap, json['type']), entries: (json['entries'] as List?) @@ -19,6 +20,7 @@ _$PageImpl _$$PageImplFromJson(Map json) => _$PageImpl( Map _$$PageImplToJson(_$PageImpl instance) => { + 'id': instance.id, 'name': instance.pageName, 'type': _$PageTypeEnumMap[instance.type]!, 'entries': instance.entries, @@ -51,7 +53,7 @@ final pagesProvider = AutoDisposeProvider>.internal( ); typedef PagesRef = AutoDisposeProviderRef>; -String _$pageHash() => r'0c5240a645e0582f10cb6e594f6fd35bb2d48c1a'; +String _$pageHash() => r'884d7b74470acd1d1cd7aefeb91f51364a14ba89'; /// Copied from Dart SDK class _SystemHash { @@ -85,10 +87,10 @@ class PageFamily extends Family { /// See also [page]. PageProvider call( - String pageName, + String pageId, ) { return PageProvider( - pageName, + pageId, ); } @@ -97,7 +99,7 @@ class PageFamily extends Family { covariant PageProvider provider, ) { return call( - provider.pageName, + provider.pageId, ); } @@ -120,11 +122,11 @@ class PageFamily extends Family { class PageProvider extends AutoDisposeProvider { /// See also [page]. PageProvider( - String pageName, + String pageId, ) : this._internal( (ref) => page( ref as PageRef, - pageName, + pageId, ), from: pageProvider, name: r'pageProvider', @@ -132,7 +134,7 @@ class PageProvider extends AutoDisposeProvider { const bool.fromEnvironment('dart.vm.product') ? null : _$pageHash, dependencies: PageFamily._dependencies, allTransitiveDependencies: PageFamily._allTransitiveDependencies, - pageName: pageName, + pageId: pageId, ); PageProvider._internal( @@ -142,10 +144,10 @@ class PageProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.pageName, + required this.pageId, }) : super.internal(); - final String pageName; + final String pageId; @override Override overrideWith( @@ -160,7 +162,7 @@ class PageProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - pageName: pageName, + pageId: pageId, ), ); } @@ -172,21 +174,21 @@ class PageProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { - return other is PageProvider && other.pageName == pageName; + return other is PageProvider && other.pageId == pageId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, pageName.hashCode); + hash = _SystemHash.combine(hash, pageId.hashCode); return _SystemHash.finish(hash); } } mixin PageRef on AutoDisposeProviderRef { - /// The parameter `pageName` of this provider. - String get pageName; + /// The parameter `pageId` of this provider. + String get pageId; } class _PageProviderElement extends AutoDisposeProviderElement @@ -194,10 +196,10 @@ class _PageProviderElement extends AutoDisposeProviderElement _PageProviderElement(super.provider); @override - String get pageName => (origin as PageProvider).pageName; + String get pageId => (origin as PageProvider).pageId; } -String _$pageExistsHash() => r'1c42a5607890607b3818f12bb68d98196ccab59d'; +String _$pageExistsHash() => r'68e3ea46a1e212bb9bc01ac653a749e9668d47f3'; /// See also [pageExists]. @ProviderFor(pageExists) @@ -210,10 +212,10 @@ class PageExistsFamily extends Family { /// See also [pageExists]. PageExistsProvider call( - String pageName, + String pageId, ) { return PageExistsProvider( - pageName, + pageId, ); } @@ -222,7 +224,7 @@ class PageExistsFamily extends Family { covariant PageExistsProvider provider, ) { return call( - provider.pageName, + provider.pageId, ); } @@ -245,11 +247,11 @@ class PageExistsFamily extends Family { class PageExistsProvider extends AutoDisposeProvider { /// See also [pageExists]. PageExistsProvider( - String pageName, + String pageId, ) : this._internal( (ref) => pageExists( ref as PageExistsRef, - pageName, + pageId, ), from: pageExistsProvider, name: r'pageExistsProvider', @@ -260,7 +262,7 @@ class PageExistsProvider extends AutoDisposeProvider { dependencies: PageExistsFamily._dependencies, allTransitiveDependencies: PageExistsFamily._allTransitiveDependencies, - pageName: pageName, + pageId: pageId, ); PageExistsProvider._internal( @@ -270,10 +272,10 @@ class PageExistsProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.pageName, + required this.pageId, }) : super.internal(); - final String pageName; + final String pageId; @override Override overrideWith( @@ -288,7 +290,7 @@ class PageExistsProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - pageName: pageName, + pageId: pageId, ), ); } @@ -300,21 +302,21 @@ class PageExistsProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { - return other is PageExistsProvider && other.pageName == pageName; + return other is PageExistsProvider && other.pageId == pageId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, pageName.hashCode); + hash = _SystemHash.combine(hash, pageId.hashCode); return _SystemHash.finish(hash); } } mixin PageExistsRef on AutoDisposeProviderRef { - /// The parameter `pageName` of this provider. - String get pageName; + /// The parameter `pageId` of this provider. + String get pageId; } class _PageExistsProviderElement extends AutoDisposeProviderElement @@ -322,10 +324,10 @@ class _PageExistsProviderElement extends AutoDisposeProviderElement _PageExistsProviderElement(super.provider); @override - String get pageName => (origin as PageExistsProvider).pageName; + String get pageId => (origin as PageExistsProvider).pageId; } -String _$pageTypeHash() => r'6912833664c34d2689d328d901719f479be512ac'; +String _$pageTypeHash() => r'e22516e95c00d6723256e425e31624dc3beccddb'; /// See also [pageType]. @ProviderFor(pageType) @@ -338,10 +340,10 @@ class PageTypeFamily extends Family { /// See also [pageType]. PageTypeProvider call( - String pageName, + String pageId, ) { return PageTypeProvider( - pageName, + pageId, ); } @@ -350,7 +352,7 @@ class PageTypeFamily extends Family { covariant PageTypeProvider provider, ) { return call( - provider.pageName, + provider.pageId, ); } @@ -373,11 +375,11 @@ class PageTypeFamily extends Family { class PageTypeProvider extends AutoDisposeProvider { /// See also [pageType]. PageTypeProvider( - String pageName, + String pageId, ) : this._internal( (ref) => pageType( ref as PageTypeRef, - pageName, + pageId, ), from: pageTypeProvider, name: r'pageTypeProvider', @@ -387,7 +389,7 @@ class PageTypeProvider extends AutoDisposeProvider { : _$pageTypeHash, dependencies: PageTypeFamily._dependencies, allTransitiveDependencies: PageTypeFamily._allTransitiveDependencies, - pageName: pageName, + pageId: pageId, ); PageTypeProvider._internal( @@ -397,10 +399,10 @@ class PageTypeProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.pageName, + required this.pageId, }) : super.internal(); - final String pageName; + final String pageId; @override Override overrideWith( @@ -415,7 +417,7 @@ class PageTypeProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - pageName: pageName, + pageId: pageId, ), ); } @@ -427,21 +429,21 @@ class PageTypeProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { - return other is PageTypeProvider && other.pageName == pageName; + return other is PageTypeProvider && other.pageId == pageId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, pageName.hashCode); + hash = _SystemHash.combine(hash, pageId.hashCode); return _SystemHash.finish(hash); } } mixin PageTypeRef on AutoDisposeProviderRef { - /// The parameter `pageName` of this provider. - String get pageName; + /// The parameter `pageId` of this provider. + String get pageId; } class _PageTypeProviderElement extends AutoDisposeProviderElement @@ -449,10 +451,10 @@ class _PageTypeProviderElement extends AutoDisposeProviderElement _PageTypeProviderElement(super.provider); @override - String get pageName => (origin as PageTypeProvider).pageName; + String get pageId => (origin as PageTypeProvider).pageId; } -String _$pageChapterHash() => r'9cdd570d02d94300415088471aa61037d66464eb'; +String _$pageChapterHash() => r'c8725780b13e27c6bfb7ade62625aabb4d7ca392'; /// See also [pageChapter]. @ProviderFor(pageChapter) @@ -465,10 +467,10 @@ class PageChapterFamily extends Family { /// See also [pageChapter]. PageChapterProvider call( - String pageName, + String pageId, ) { return PageChapterProvider( - pageName, + pageId, ); } @@ -477,7 +479,7 @@ class PageChapterFamily extends Family { covariant PageChapterProvider provider, ) { return call( - provider.pageName, + provider.pageId, ); } @@ -500,11 +502,11 @@ class PageChapterFamily extends Family { class PageChapterProvider extends AutoDisposeProvider { /// See also [pageChapter]. PageChapterProvider( - String pageName, + String pageId, ) : this._internal( (ref) => pageChapter( ref as PageChapterRef, - pageName, + pageId, ), from: pageChapterProvider, name: r'pageChapterProvider', @@ -515,7 +517,7 @@ class PageChapterProvider extends AutoDisposeProvider { dependencies: PageChapterFamily._dependencies, allTransitiveDependencies: PageChapterFamily._allTransitiveDependencies, - pageName: pageName, + pageId: pageId, ); PageChapterProvider._internal( @@ -525,10 +527,10 @@ class PageChapterProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.pageName, + required this.pageId, }) : super.internal(); - final String pageName; + final String pageId; @override Override overrideWith( @@ -543,7 +545,7 @@ class PageChapterProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - pageName: pageName, + pageId: pageId, ), ); } @@ -555,21 +557,21 @@ class PageChapterProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { - return other is PageChapterProvider && other.pageName == pageName; + return other is PageChapterProvider && other.pageId == pageId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, pageName.hashCode); + hash = _SystemHash.combine(hash, pageId.hashCode); return _SystemHash.finish(hash); } } mixin PageChapterRef on AutoDisposeProviderRef { - /// The parameter `pageName` of this provider. - String get pageName; + /// The parameter `pageId` of this provider. + String get pageId; } class _PageChapterProviderElement extends AutoDisposeProviderElement @@ -577,10 +579,10 @@ class _PageChapterProviderElement extends AutoDisposeProviderElement _PageChapterProviderElement(super.provider); @override - String get pageName => (origin as PageChapterProvider).pageName; + String get pageId => (origin as PageChapterProvider).pageId; } -String _$pagePriorityHash() => r'6d67e3c592c0e5656c4c26213da90d64691825b5'; +String _$pagePriorityHash() => r'340f23a4c9b80bbd159ea066d79044424a8e4692'; /// See also [pagePriority]. @ProviderFor(pagePriority) @@ -593,10 +595,10 @@ class PagePriorityFamily extends Family { /// See also [pagePriority]. PagePriorityProvider call( - String pageName, + String pageId, ) { return PagePriorityProvider( - pageName, + pageId, ); } @@ -605,7 +607,7 @@ class PagePriorityFamily extends Family { covariant PagePriorityProvider provider, ) { return call( - provider.pageName, + provider.pageId, ); } @@ -628,11 +630,11 @@ class PagePriorityFamily extends Family { class PagePriorityProvider extends AutoDisposeProvider { /// See also [pagePriority]. PagePriorityProvider( - String pageName, + String pageId, ) : this._internal( (ref) => pagePriority( ref as PagePriorityRef, - pageName, + pageId, ), from: pagePriorityProvider, name: r'pagePriorityProvider', @@ -643,7 +645,7 @@ class PagePriorityProvider extends AutoDisposeProvider { dependencies: PagePriorityFamily._dependencies, allTransitiveDependencies: PagePriorityFamily._allTransitiveDependencies, - pageName: pageName, + pageId: pageId, ); PagePriorityProvider._internal( @@ -653,10 +655,10 @@ class PagePriorityProvider extends AutoDisposeProvider { required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.pageName, + required this.pageId, }) : super.internal(); - final String pageName; + final String pageId; @override Override overrideWith( @@ -671,7 +673,7 @@ class PagePriorityProvider extends AutoDisposeProvider { dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - pageName: pageName, + pageId: pageId, ), ); } @@ -683,21 +685,21 @@ class PagePriorityProvider extends AutoDisposeProvider { @override bool operator ==(Object other) { - return other is PagePriorityProvider && other.pageName == pageName; + return other is PagePriorityProvider && other.pageId == pageId; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, pageName.hashCode); + hash = _SystemHash.combine(hash, pageId.hashCode); return _SystemHash.finish(hash); } } mixin PagePriorityRef on AutoDisposeProviderRef { - /// The parameter `pageName` of this provider. - String get pageName; + /// The parameter `pageId` of this provider. + String get pageId; } class _PagePriorityProviderElement extends AutoDisposeProviderElement @@ -705,10 +707,10 @@ class _PagePriorityProviderElement extends AutoDisposeProviderElement _PagePriorityProviderElement(super.provider); @override - String get pageName => (origin as PagePriorityProvider).pageName; + String get pageId => (origin as PagePriorityProvider).pageId; } -String _$entryPageIdHash() => r'ceb41cef3f8d8b1f0a28e5de7aead8969f03d6ac'; +String _$entryPageIdHash() => r'a317d09f9de338ebefec45be649af4dc1c60a22d'; /// See also [entryPageId]. @ProviderFor(entryPageId) @@ -1107,7 +1109,7 @@ class _EntryProviderElement extends AutoDisposeProviderElement String get entryId => (origin as EntryProvider).entryId; } -String _$globalEntryHash() => r'df6937f53ba0fe88ed629630eb2b366d2ed3a540'; +String _$globalEntryHash() => r'f304c143cc53b98eeccb7696c4c1152464820b93'; /// See also [globalEntry]. @ProviderFor(globalEntry) diff --git a/app/lib/models/segment.freezed.dart b/app/lib/models/segment.freezed.dart index 4009e50249..d98ef02412 100644 --- a/app/lib/models/segment.freezed.dart +++ b/app/lib/models/segment.freezed.dart @@ -26,7 +26,9 @@ mixin _$Segment { int? get maxFrames => throw _privateConstructorUsedError; Map get data => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of Segment + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $SegmentCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -57,6 +59,8 @@ class _$SegmentCopyWithImpl<$Res, $Val extends Segment> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Segment + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -138,6 +142,8 @@ class __$$SegmentImplCopyWithImpl<$Res> _$SegmentImpl _value, $Res Function(_$SegmentImpl) _then) : super(_value, _then); + /// Create a copy of Segment + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -276,7 +282,9 @@ class _$SegmentImpl implements _Segment { maxFrames, const DeepCollectionEquality().hash(_data)); - @JsonKey(ignore: true) + /// Create a copy of Segment + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$SegmentImplCopyWith<_$SegmentImpl> get copyWith => @@ -313,8 +321,11 @@ abstract class _Segment implements Segment { int? get maxFrames; @override Map get data; + + /// Create a copy of Segment + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$SegmentImplCopyWith<_$SegmentImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/sound.freezed.dart b/app/lib/models/sound.freezed.dart index 9130650bdf..a2bd94fa5f 100644 --- a/app/lib/models/sound.freezed.dart +++ b/app/lib/models/sound.freezed.dart @@ -67,6 +67,8 @@ mixin _$SoundId { required TResult orElse(), }) => throw _privateConstructorUsedError; + + /// Serializes this SoundId to a JSON map. Map toJson() => throw _privateConstructorUsedError; } @@ -85,6 +87,9 @@ class _$SoundIdCopyWithImpl<$Res, $Val extends SoundId> final $Val _value; // ignore: unused_field final $Res Function($Val) _then; + + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. } /// @nodoc @@ -104,6 +109,8 @@ class __$$DefaultSoundIdImplCopyWithImpl<$Res> _$DefaultSoundIdImpl _value, $Res Function(_$DefaultSoundIdImpl) _then) : super(_value, _then); + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -148,11 +155,13 @@ class _$DefaultSoundIdImpl implements DefaultSoundId { (identical(other.id, id) || other.id == id)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, id); - @JsonKey(ignore: true) + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$DefaultSoundIdImplCopyWith<_$DefaultSoundIdImpl> get copyWith => @@ -239,7 +248,10 @@ abstract class DefaultSoundId implements SoundId { @JsonKey(name: "value") String get id; - @JsonKey(ignore: true) + + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$DefaultSoundIdImplCopyWith<_$DefaultSoundIdImpl> get copyWith => throw _privateConstructorUsedError; } @@ -261,6 +273,8 @@ class __$$EntrySoundIdImplCopyWithImpl<$Res> _$EntrySoundIdImpl _value, $Res Function(_$EntrySoundIdImpl) _then) : super(_value, _then); + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -305,11 +319,13 @@ class _$EntrySoundIdImpl implements EntrySoundId { (identical(other.entryId, entryId) || other.entryId == entryId)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, entryId); - @JsonKey(ignore: true) + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$EntrySoundIdImplCopyWith<_$EntrySoundIdImpl> get copyWith => @@ -395,7 +411,10 @@ abstract class EntrySoundId implements SoundId { @JsonKey(name: "value") String get entryId; - @JsonKey(ignore: true) + + /// Create a copy of SoundId + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$EntrySoundIdImplCopyWith<_$EntrySoundIdImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/sounds.freezed.dart b/app/lib/models/sounds.freezed.dart index fe5e245156..8528513c3b 100644 --- a/app/lib/models/sounds.freezed.dart +++ b/app/lib/models/sounds.freezed.dart @@ -24,8 +24,12 @@ mixin _$SoundData { int get weight => throw _privateConstructorUsedError; double get volume => throw _privateConstructorUsedError; + /// Serializes this SoundData to a JSON map. Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + + /// Create a copy of SoundData + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $SoundDataCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -48,6 +52,8 @@ class _$SoundDataCopyWithImpl<$Res, $Val extends SoundData> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of SoundData + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -91,6 +97,8 @@ class __$$SoundDataImplCopyWithImpl<$Res> _$SoundDataImpl _value, $Res Function(_$SoundDataImpl) _then) : super(_value, _then); + /// Create a copy of SoundData + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -148,11 +156,13 @@ class _$SoundDataImpl implements _SoundData { (identical(other.volume, volume) || other.volume == volume)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, name, weight, volume); - @JsonKey(ignore: true) + /// Create a copy of SoundData + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$SoundDataImplCopyWith<_$SoundDataImpl> get copyWith => @@ -181,8 +191,11 @@ abstract class _SoundData implements SoundData { int get weight; @override double get volume; + + /// Create a copy of SoundData + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$SoundDataImplCopyWith<_$SoundDataImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/models/writers.freezed.dart b/app/lib/models/writers.freezed.dart index fcbd2817d9..a7f2896772 100644 --- a/app/lib/models/writers.freezed.dart +++ b/app/lib/models/writers.freezed.dart @@ -26,8 +26,12 @@ mixin _$Writer { String? get entryId => throw _privateConstructorUsedError; String? get field => throw _privateConstructorUsedError; + /// Serializes this Writer to a JSON map. Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + + /// Create a copy of Writer + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $WriterCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -54,6 +58,8 @@ class _$WriterCopyWithImpl<$Res, $Val extends Writer> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Writer + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -111,6 +117,8 @@ class __$$WriterImplCopyWithImpl<$Res> _$WriterImpl _value, $Res Function(_$WriterImpl) _then) : super(_value, _then); + /// Create a copy of Writer + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -182,12 +190,14 @@ class _$WriterImpl implements _Writer { (identical(other.field, field) || other.field == field)); } - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) @override int get hashCode => Object.hash(runtimeType, id, iconUrl, pageId, entryId, field); - @JsonKey(ignore: true) + /// Create a copy of Writer + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$WriterImplCopyWith<_$WriterImpl> get copyWith => @@ -221,8 +231,11 @@ abstract class _Writer implements Writer { String? get entryId; @override String? get field; + + /// Create a copy of Writer + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$WriterImplCopyWith<_$WriterImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/pages/book_page.dart b/app/lib/pages/book_page.dart index 92dad81a09..6c4d955686 100644 --- a/app/lib/pages/book_page.dart +++ b/app/lib/pages/book_page.dart @@ -5,9 +5,9 @@ import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:typewriter/app_router.dart"; import "package:typewriter/hooks/delayed_execution.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/book.dart"; import "package:typewriter/models/communicator.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/pages/connect_page.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/widgets/components/app/search_bar.dart"; diff --git a/app/lib/pages/page_editor.dart b/app/lib/pages/page_editor.dart index d811bc06a9..ea3ac1ee5d 100644 --- a/app/lib/pages/page_editor.dart +++ b/app/lib/pages/page_editor.dart @@ -5,7 +5,6 @@ import "package:flutter/services.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; import "package:typewriter/app_router.dart"; -import "package:typewriter/models/book.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/extensions.dart"; @@ -38,9 +37,9 @@ String currentPageLabel(CurrentPageLabelRef ref) { @riverpod Page? currentPage(CurrentPageRef ref) { final id = ref.watch(currentPageIdProvider); - final book = ref.watch(bookProvider); + final pages = ref.watch(pagesProvider); - return book.pages.firstWhereOrNull((element) => element.pageName == id); + return pages.firstWhereOrNull((element) => element.id == id); } @riverpod diff --git a/app/lib/pages/page_editor.g.dart b/app/lib/pages/page_editor.g.dart index 032a9aa49b..a6e3708427 100644 --- a/app/lib/pages/page_editor.g.dart +++ b/app/lib/pages/page_editor.g.dart @@ -36,7 +36,7 @@ final currentPageLabelProvider = AutoDisposeProvider.internal( ); typedef CurrentPageLabelRef = AutoDisposeProviderRef; -String _$currentPageHash() => r'e4061bc62721be6ea098919cee27392d81d8de10'; +String _$currentPageHash() => r'99dc4a27dceb05b9ee1022d03e314f029969ed16'; /// See also [currentPage]. @ProviderFor(currentPage) diff --git a/app/lib/pages/pages_list.dart b/app/lib/pages/pages_list.dart index 20ccdb61f0..6f0c475c88 100644 --- a/app/lib/pages/pages_list.dart +++ b/app/lib/pages/pages_list.dart @@ -11,9 +11,9 @@ import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; import "package:typewriter/app_router.dart"; import "package:typewriter/hooks/delayed_execution.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/book.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/pages/page_editor.dart"; @@ -38,6 +38,7 @@ part "pages_list.g.dart"; @freezed class _PageData with _$PageData { const factory _PageData({ + required String id, required String name, required PageType type, required String chapter, @@ -51,6 +52,7 @@ List<_PageData> _pagesData(_PagesDataRef ref) { .pages .map( (page) => _PageData( + id: page.id, name: page.pageName, type: page.type, chapter: page.chapter, @@ -374,7 +376,8 @@ class _PageTile extends HookConsumerWidget { }); final _PageData pageData; - String get pageId => pageData.name; + String get pageId => pageData.id; + String get name => pageData.name; String get chapter => pageData.chapter; bool _needsShift(int amount) { @@ -394,7 +397,10 @@ class _PageTile extends HookConsumerWidget { icon: TWIcons.pencil, onTap: () => showDialog( context: context, - builder: (_) => RenamePageDialogue(old: pageId), + builder: (_) => RenamePageDialogue( + pageId: pageId, + oldName: name, + ), ), ), ContextMenuTile.button( @@ -444,7 +450,7 @@ class _PageTile extends HookConsumerWidget { child: DragTarget( onWillAcceptWithDetails: (details) { final entryId = details.data.entryId; - final entryType = ref.read(entryTypeProvider(entryId)); + final entryType = ref.read(entryBlueprintIdProvider(entryId)); if (entryType == null) return false; final entryPageType = ref.read(entryBlueprintPageTypeProvider(entryType)); @@ -682,19 +688,20 @@ class AddPageDialogue extends HookConsumerWidget { final PageType? fixedType; final bool autoNavigate; - Future _addPage( + Future _addPage( WidgetRef ref, String name, PageType type, String chapter, int priority, ) async { - await ref + final page = await ref .read(bookProvider.notifier) .createPage(name, type, chapter, priority); - if (!autoNavigate) return; + if (!autoNavigate) return page.id; unawaited(ref.read(appRouter).push(PageEditorRoute(id: name))); + return page.id; } /// Validates the proposed name for a page. @@ -822,14 +829,14 @@ class AddPageDialogue extends HookConsumerWidget { ? null : () async { final navigator = Navigator.of(context); - await _addPage( + final pageId = await _addPage( ref, nameController.text, type.value, chapterController.text, int.tryParse(priorityController.text) ?? 0, ); - navigator.pop(nameController.text); + navigator.pop(pageId); }, label: const Text("Add"), icon: const Iconify(TWIcons.plus), @@ -841,14 +848,16 @@ class AddPageDialogue extends HookConsumerWidget { class RenamePageDialogue extends HookConsumerWidget { const RenamePageDialogue({ - required this.old, + required this.pageId, + required this.oldName, super.key, }); - final String old; + final String pageId; + final String oldName; Future _renamePage(WidgetRef ref, String newName) async { - await ref.read(bookProvider.notifier).renamePage(old, newName); + await ref.read(bookProvider.notifier).renamePage(pageId, newName); unawaited(ref.read(appRouter).push(PageEditorRoute(id: newName))); } @@ -862,7 +871,7 @@ class RenamePageDialogue extends HookConsumerWidget { return "Name cannot be empty"; } - if (text == old) { + if (text == oldName) { return "Name cannot be the same"; } @@ -876,13 +885,13 @@ class RenamePageDialogue extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final pagesNames = ref.watch(_pageNamesProvider); - final controller = useTextEditingController(text: old); + final controller = useTextEditingController(text: oldName); final isNameValid = useState(false); return AlertDialog( - title: Text("Rename ${old.formatted}"), + title: Text("Rename ${oldName.formatted}"), content: ValidatedTextField( - value: old, + value: oldName, controller: controller, name: "Page Name", icon: TWIcons.book, diff --git a/app/lib/pages/pages_list.freezed.dart b/app/lib/pages/pages_list.freezed.dart index c45e814d02..12a87e1259 100644 --- a/app/lib/pages/pages_list.freezed.dart +++ b/app/lib/pages/pages_list.freezed.dart @@ -16,11 +16,14 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$PageData { + String get id => throw _privateConstructorUsedError; String get name => throw _privateConstructorUsedError; PageType get type => throw _privateConstructorUsedError; String get chapter => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of _PageData + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$PageDataCopyWith<_PageData> get copyWith => throw _privateConstructorUsedError; } @@ -30,7 +33,7 @@ abstract class _$PageDataCopyWith<$Res> { factory _$PageDataCopyWith(_PageData value, $Res Function(_PageData) then) = __$PageDataCopyWithImpl<$Res, _PageData>; @useResult - $Res call({String name, PageType type, String chapter}); + $Res call({String id, String name, PageType type, String chapter}); } /// @nodoc @@ -43,14 +46,21 @@ class __$PageDataCopyWithImpl<$Res, $Val extends _PageData> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of _PageData + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ + Object? id = null, Object? name = null, Object? type = null, Object? chapter = null, }) { return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, name: null == name ? _value.name : name // ignore: cast_nullable_to_non_nullable @@ -75,7 +85,7 @@ abstract class _$$$__PageDataImplCopyWith<$Res> __$$$__PageDataImplCopyWithImpl<$Res>; @override @useResult - $Res call({String name, PageType type, String chapter}); + $Res call({String id, String name, PageType type, String chapter}); } /// @nodoc @@ -86,14 +96,21 @@ class __$$$__PageDataImplCopyWithImpl<$Res> _$$__PageDataImpl _value, $Res Function(_$$__PageDataImpl) _then) : super(_value, _then); + /// Create a copy of _PageData + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ + Object? id = null, Object? name = null, Object? type = null, Object? chapter = null, }) { return _then(_$$__PageDataImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, name: null == name ? _value.name : name // ignore: cast_nullable_to_non_nullable @@ -114,8 +131,13 @@ class __$$$__PageDataImplCopyWithImpl<$Res> class _$$__PageDataImpl implements _$__PageData { const _$$__PageDataImpl( - {required this.name, required this.type, required this.chapter}); + {required this.id, + required this.name, + required this.type, + required this.chapter}); + @override + final String id; @override final String name; @override @@ -125,7 +147,7 @@ class _$$__PageDataImpl implements _$__PageData { @override String toString() { - return '_PageData(name: $name, type: $type, chapter: $chapter)'; + return '_PageData(id: $id, name: $name, type: $type, chapter: $chapter)'; } @override @@ -133,15 +155,18 @@ class _$$__PageDataImpl implements _$__PageData { return identical(this, other) || (other.runtimeType == runtimeType && other is _$$__PageDataImpl && + (identical(other.id, id) || other.id == id) && (identical(other.name, name) || other.name == name) && (identical(other.type, type) || other.type == type) && (identical(other.chapter, chapter) || other.chapter == chapter)); } @override - int get hashCode => Object.hash(runtimeType, name, type, chapter); + int get hashCode => Object.hash(runtimeType, id, name, type, chapter); - @JsonKey(ignore: true) + /// Create a copy of _PageData + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$$__PageDataImplCopyWith<_$$__PageDataImpl> get copyWith => @@ -150,18 +175,24 @@ class _$$__PageDataImpl implements _$__PageData { abstract class _$__PageData implements _PageData { const factory _$__PageData( - {required final String name, + {required final String id, + required final String name, required final PageType type, required final String chapter}) = _$$__PageDataImpl; + @override + String get id; @override String get name; @override PageType get type; @override String get chapter; + + /// Create a copy of _PageData + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$$__PageDataImplCopyWith<_$$__PageDataImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/pages/pages_list.g.dart b/app/lib/pages/pages_list.g.dart index 79b4e1c63b..86cc19d9a1 100644 --- a/app/lib/pages/pages_list.g.dart +++ b/app/lib/pages/pages_list.g.dart @@ -6,7 +6,7 @@ part of 'pages_list.dart'; // RiverpodGenerator // ************************************************************************** -String _$pagesDataHash() => r'27d0b4987ac30e8743d3a522dacdd52889cafdc8'; +String _$pagesDataHash() => r'dde2241455047364635cf0985d51de217c282fc0'; /// See also [_pagesData]. @ProviderFor(_pagesData) diff --git a/app/lib/utils/popups.dart b/app/lib/utils/popups.dart index 7280e371ce..5c532cac3d 100644 --- a/app/lib/utils/popups.dart +++ b/app/lib/utils/popups.dart @@ -73,7 +73,10 @@ class ConfirmationDialogue extends HookWidget { content: Text(content), actions: [ TextButton.icon( - icon: Iconify(cancelIcon), + icon: Iconify( + cancelIcon, + color: Theme.of(context).textTheme.bodySmall?.color, + ), label: Text(cancelText), onPressed: () { Navigator.of(context).pop(false); diff --git a/app/lib/widgets/components/app/cinematic_view.dart b/app/lib/widgets/components/app/cinematic_view.dart index f3bace823c..0a957b764e 100644 --- a/app/lib/widgets/components/app/cinematic_view.dart +++ b/app/lib/widgets/components/app/cinematic_view.dart @@ -10,8 +10,8 @@ import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; import "package:typewriter/hooks/global_key.dart"; import "package:typewriter/hooks/text_size.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/models/segment.dart"; import "package:typewriter/models/writers.dart"; @@ -108,10 +108,10 @@ String? _addSegment( final segments = ref.read(_segmentsProvider(entryId, segmentPath)); final page = ref.read(currentPageProvider); if (page == null) return null; - final entry = ref.read(entryProvider(page.pageName, entryId)); + final entry = ref.read(entryProvider(page.id, entryId)); if (entry == null) return null; - final blueprint = ref.read(entryBlueprintProvider(entry.type)); + final blueprint = ref.read(entryBlueprintProvider(entry.blueprintId)); if (blueprint == null) return null; final segmentField = blueprint.getField(segmentPath); if (segmentField == null) return null; @@ -139,7 +139,7 @@ String? _addSegment( final (:startFrame, :endFrame) = timings; - final segment = segmentField.defaultValue; + final segment = segmentField.defaultValue(); if (segment == null) return null; final newSegment = { @@ -163,7 +163,7 @@ List _allSegments(_AllSegmentsRef ref, String entryId) { final paths = ref.watch(_segmentPathsProvider(entryId)); return paths.keys .map((path) => ref.watch(_segmentsProvider(entryId, path))) - .whereNotNull() + .nonNulls .expand((x) => x) .toList(); } @@ -186,7 +186,7 @@ void _deleteSegment(PassingRef ref, String entryId, String segmentPath) { ); return; } - final entry = ref.read(entryProvider(page.pageName, entryId)); + final entry = ref.read(entryProvider(page.id, entryId)); if (entry == null) { Toasts.showError( ref, @@ -196,7 +196,7 @@ void _deleteSegment(PassingRef ref, String entryId, String segmentPath) { return; } - final blueprint = ref.read(entryBlueprintProvider(entry.type)); + final blueprint = ref.read(entryBlueprintProvider(entry.blueprintId)); if (blueprint == null) { Toasts.showError( ref, @@ -386,7 +386,7 @@ String _longestEntryName(_LongestEntryNameRef ref) { final entryIds = ref.watch(_cinematicEntryIdsProvider); final names = entryIds .map((entryId) => ref.watch(entryNameProvider(entryId))) - .whereNotNull() + .nonNulls .toList() + ["Track Duration"]; return names.isEmpty @@ -395,7 +395,7 @@ String _longestEntryName(_LongestEntryNameRef ref) { } @riverpod -ObjectField? _segmentFields(_SegmentFieldsRef ref) { +ObjectBlueprint? _segmentFields(_SegmentFieldsRef ref) { final blueprint = ref.watch( inspectingEntryDefinitionProvider .select((definition) => definition?.blueprint), @@ -403,17 +403,17 @@ ObjectField? _segmentFields(_SegmentFieldsRef ref) { if (blueprint == null) return null; final segmentId = ref.watch(inspectingSegmentIdProvider); if (segmentId == null) return null; - final fieldInfo = blueprint.getField(segmentId); - if (fieldInfo is! ObjectField) return null; - return fieldInfo; + final dataBlueprint = blueprint.getField(segmentId); + if (dataBlueprint is! ObjectBlueprint) return null; + return dataBlueprint; } // @riverpod Map _segmentPaths(_SegmentPathsRef ref, String entryId) { - final type = ref.watch(entryTypeProvider(entryId)); - if (type == null) return {}; - final blueprint = ref.watch(entryBlueprintProvider(type)); + final blueprintId = ref.watch(entryBlueprintIdProvider(entryId)); + if (blueprintId == null) return {}; + final blueprint = ref.watch(entryBlueprintProvider(blueprintId)); if (blueprint == null) return {}; return blueprint.fieldsWithModifier("segment"); @@ -428,7 +428,7 @@ List _segments(_SegmentsRef ref, String entryId, String path) { final entry = ref.watch(globalEntryProvider(entryId)); if (entry == null) return []; - final blueprint = ref.watch(entryBlueprintProvider(entry.type)); + final blueprint = ref.watch(entryBlueprintProvider(entry.blueprintId)); if (blueprint == null) return []; final segmentModifierData = modifier.data; @@ -534,7 +534,7 @@ int _totalSequenceFrames(_TotalSequenceFramesRef ref) { final entryIds = ref.watch(_cinematicEntryIdsProvider); final frames = entryIds .map((entryId) => ref.watch(_endingFrameProvider(entryId))) - .whereNotNull() + .nonNulls .toList(); return frames.map((frame) => frame).maxOrNull ?? 0; } @@ -1102,12 +1102,12 @@ class _InspectorContents extends HookConsumerWidget { final segmentId = ref.watch(inspectingSegmentIdProvider); if (segmentId == null) return const SizedBox.shrink(); - final object = ref.watch(_segmentFieldsProvider); - if (object == null) return const SizedBox.shrink(); + final objectBlueprint = ref.watch(_segmentFieldsProvider); + if (objectBlueprint == null) return const SizedBox.shrink(); return ObjectEditor( path: segmentId, - object: object, + objectBlueprint: objectBlueprint, defaultExpanded: true, ignoreFields: const [ "startFrame", @@ -1266,7 +1266,7 @@ class _MoveNotifier extends StateNotifier<_MoveState?> { void _updateEntry(String entryId, String path, dynamic value) { final page = ref.read(currentPageProvider); if (page == null) return; - final entry = ref.read(entryProvider(page.pageName, entryId)); + final entry = ref.read(entryProvider(page.id, entryId)); if (entry == null) return; page.updateEntryValue(ref.passing, entry, path, value); } diff --git a/app/lib/widgets/components/app/cinematic_view.freezed.dart b/app/lib/widgets/components/app/cinematic_view.freezed.dart index 876138c83d..01037e26b3 100644 --- a/app/lib/widgets/components/app/cinematic_view.freezed.dart +++ b/app/lib/widgets/components/app/cinematic_view.freezed.dart @@ -20,7 +20,9 @@ mixin _$FrameLine { double get offset => throw _privateConstructorUsedError; bool get primary => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of _FrameLine + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$FrameLineCopyWith<_FrameLine> get copyWith => throw _privateConstructorUsedError; } @@ -44,6 +46,8 @@ class __$FrameLineCopyWithImpl<$Res, $Val extends _FrameLine> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of _FrameLine + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -87,6 +91,8 @@ class __$$$__FrameLineImplCopyWithImpl<$Res> _$$__FrameLineImpl _value, $Res Function(_$$__FrameLineImpl) _then) : super(_value, _then); + /// Create a copy of _FrameLine + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -142,7 +148,9 @@ class _$$__FrameLineImpl implements _$__FrameLine { @override int get hashCode => Object.hash(runtimeType, frame, offset, primary); - @JsonKey(ignore: true) + /// Create a copy of _FrameLine + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$$__FrameLineImplCopyWith<_$$__FrameLineImpl> get copyWith => @@ -161,8 +169,11 @@ abstract class _$__FrameLine implements _FrameLine { double get offset; @override bool get primary; + + /// Create a copy of _FrameLine + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$$__FrameLineImplCopyWith<_$$__FrameLineImpl> get copyWith => throw _privateConstructorUsedError; } @@ -173,7 +184,9 @@ mixin _$MoveState { Segment? get nextSegment => throw _privateConstructorUsedError; double get innerPercent => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$MoveStateCopyWith<_MoveState> get copyWith => throw _privateConstructorUsedError; } @@ -201,6 +214,8 @@ class __$MoveStateCopyWithImpl<$Res, $Val extends _MoveState> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -224,6 +239,8 @@ class __$MoveStateCopyWithImpl<$Res, $Val extends _MoveState> ) as $Val); } + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. @override @pragma('vm:prefer-inline') $SegmentCopyWith<$Res>? get previousSegment { @@ -236,6 +253,8 @@ class __$MoveStateCopyWithImpl<$Res, $Val extends _MoveState> }); } + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. @override @pragma('vm:prefer-inline') $SegmentCopyWith<$Res>? get nextSegment { @@ -274,6 +293,8 @@ class __$$$__MoveStateImplCopyWithImpl<$Res> _$$__MoveStateImpl _value, $Res Function(_$$__MoveStateImpl) _then) : super(_value, _then); + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -336,7 +357,9 @@ class _$$__MoveStateImpl implements _$__MoveState { int get hashCode => Object.hash(runtimeType, previousSegment, nextSegment, innerPercent); - @JsonKey(ignore: true) + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$$__MoveStateImplCopyWith<_$$__MoveStateImpl> get copyWith => @@ -355,8 +378,11 @@ abstract class _$__MoveState implements _MoveState { Segment? get nextSegment; @override double get innerPercent; + + /// Create a copy of _MoveState + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$$__MoveStateImplCopyWith<_$$__MoveStateImpl> get copyWith => throw _privateConstructorUsedError; } @@ -372,7 +398,9 @@ mixin _$TrackState { throw _privateConstructorUsedError; // ignore: unused_element double get width => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of _TrackState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$TrackStateCopyWith<_TrackState> get copyWith => throw _privateConstructorUsedError; } @@ -396,6 +424,8 @@ class __$TrackStateCopyWithImpl<$Res, $Val extends _TrackState> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of _TrackState + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -444,6 +474,8 @@ class __$$$__TrackStateImplCopyWithImpl<$Res> _$$__TrackStateImpl _value, $Res Function(_$$__TrackStateImpl) _then) : super(_value, _then); + /// Create a copy of _TrackState + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -516,7 +548,9 @@ class _$$__TrackStateImpl implements _$__TrackState { @override int get hashCode => Object.hash(runtimeType, start, end, totalFrames, width); - @JsonKey(ignore: true) + /// Create a copy of _TrackState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$$__TrackStateImplCopyWith<_$$__TrackStateImpl> get copyWith => @@ -530,16 +564,20 @@ abstract class _$__TrackState implements _TrackState { final int totalFrames, final double width]) = _$$__TrackStateImpl; - @override // ignore: unused_element - double get start; - @override // ignore: unused_element - double get end; - @override // ignore: unused_element - int get totalFrames; - @override // ignore: unused_element +// ignore: unused_element + @override + double get start; // ignore: unused_element + @override + double get end; // ignore: unused_element + @override + int get totalFrames; // ignore: unused_element + @override double get width; + + /// Create a copy of _TrackState + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$$__TrackStateImplCopyWith<_$$__TrackStateImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/widgets/components/app/cinematic_view.g.dart b/app/lib/widgets/components/app/cinematic_view.g.dart index 18730e2000..8e392461f7 100644 --- a/app/lib/widgets/components/app/cinematic_view.g.dart +++ b/app/lib/widgets/components/app/cinematic_view.g.dart @@ -21,7 +21,7 @@ final inspectingSegmentProvider = AutoDisposeProvider.internal( ); typedef InspectingSegmentRef = AutoDisposeProviderRef; -String _$allSegmentsHash() => r'00ddff554f166898f9bb911168a5c18e369887ef'; +String _$allSegmentsHash() => r'cd0016ec442c5c46570cedbdde8893c1a52890df'; /// Copied from Dart SDK class _SystemHash { @@ -729,7 +729,7 @@ final _ignoreEntryFieldsProvider = AutoDisposeProvider>.internal( ); typedef _IgnoreEntryFieldsRef = AutoDisposeProviderRef>; -String _$longestEntryNameHash() => r'5279a4a558d828a7316e5f78a1744316d08b1d7f'; +String _$longestEntryNameHash() => r'e28faa48892dbb64da18b39177390e09c73dc820'; /// See also [_longestEntryName]. @ProviderFor(_longestEntryName) @@ -744,11 +744,11 @@ final _longestEntryNameProvider = AutoDisposeProvider.internal( ); typedef _LongestEntryNameRef = AutoDisposeProviderRef; -String _$segmentFieldsHash() => r'50de8ece747eb6fbdd3c504f30873d7546d54b50'; +String _$segmentFieldsHash() => r'bf02df2288101b0055b4c2376e4f4336b36c8f37'; /// See also [_segmentFields]. @ProviderFor(_segmentFields) -final _segmentFieldsProvider = AutoDisposeProvider.internal( +final _segmentFieldsProvider = AutoDisposeProvider.internal( _segmentFields, name: r'_segmentFieldsProvider', debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') @@ -758,8 +758,8 @@ final _segmentFieldsProvider = AutoDisposeProvider.internal( allTransitiveDependencies: null, ); -typedef _SegmentFieldsRef = AutoDisposeProviderRef; -String _$segmentPathsHash() => r'4456836fe10ea7d1100810e16b819ad4e2f0339c'; +typedef _SegmentFieldsRef = AutoDisposeProviderRef; +String _$segmentPathsHash() => r'14d0fa46d736eab350f85a54908b939acd3562fd'; /// See also [_segmentPaths]. @ProviderFor(_segmentPaths) @@ -888,7 +888,7 @@ class _SegmentPathsProviderElement String get entryId => (origin as _SegmentPathsProvider).entryId; } -String _$segmentsHash() => r'f49571f7d75d0070fcbb69cef364a7cc5c5af448'; +String _$segmentsHash() => r'4b38fe7227d758ce63b80733b122cf3a9676212f'; /// See also [_segments]. @ProviderFor(_segments) @@ -1499,7 +1499,7 @@ class _TimePointOffsetProviderElement extends AutoDisposeProviderElement } String _$totalSequenceFramesHash() => - r'448efbdd8b67500a4a9578b7bf46f83f14456e91'; + r'd4b107ec84c284c4ccc7b90e657979daf30ea139'; /// See also [_totalSequenceFrames]. @ProviderFor(_totalSequenceFrames) diff --git a/app/lib/widgets/components/app/entries_graph.dart b/app/lib/widgets/components/app/entries_graph.dart index a4a190abc2..0e76562b27 100644 --- a/app/lib/widgets/components/app/entries_graph.dart +++ b/app/lib/widgets/components/app/entries_graph.dart @@ -3,8 +3,8 @@ import "package:flutter_hooks/flutter_hooks.dart"; import "package:graphview/GraphView.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/pages/page_editor.dart"; import "package:typewriter/widgets/components/app/empty_screen.dart"; @@ -20,7 +20,7 @@ List graphableEntries(GraphableEntriesRef ref) { if (page == null) return []; return page.entries.where((entry) { - final tags = ref.watch(entryBlueprintTagsProvider(entry.type)); + final tags = ref.watch(entryBlueprintTagsProvider(entry.blueprintId)); return tags.contains("trigger"); }).toList(); } @@ -36,7 +36,7 @@ bool isTriggerEntry(IsTriggerEntryRef ref, String entryId) { final entry = ref.watch(globalEntryProvider(entryId)); if (entry == null) return false; - final tags = ref.watch(entryBlueprintTagsProvider(entry.type)); + final tags = ref.watch(entryBlueprintTagsProvider(entry.blueprintId)); return tags.contains("trigger"); } @@ -45,7 +45,7 @@ bool isTriggerableEntry(IsTriggerableEntryRef ref, String entryId) { final entry = ref.watch(globalEntryProvider(entryId)); if (entry == null) return false; - final tags = ref.watch(entryBlueprintTagsProvider(entry.type)); + final tags = ref.watch(entryBlueprintTagsProvider(entry.blueprintId)); return tags.contains("triggerable"); } @@ -57,11 +57,12 @@ Set? entryTriggers(EntryTriggersRef ref, String entryId) { // Check if this entry is a trigger if (!ref.read(isTriggerEntryProvider(entryId))) return null; - final modifiers = - ref.watch(modifierPathsProvider(entry.type, "entry", "triggerable")); + final modifiers = ref + .watch(modifierPathsProvider(entry.blueprintId, "entry", "triggerable")); return modifiers .expand(entry.getAll) - .map((id) => id as String) + .map((id) => id as String?) + .nonNulls .where((id) => id.isNotEmpty) .toSet(); } @@ -80,8 +81,8 @@ Graph graph(GraphRef ref) { final triggeredEntryIds = ref.watch(entryTriggersProvider(entry.id)); if (triggeredEntryIds == null) continue; - final color = - ref.watch(entryBlueprintProvider(entry.type))?.color ?? Colors.grey; + final color = ref.watch(entryBlueprintProvider(entry.blueprintId))?.color ?? + Colors.grey; for (final triggeredEntryId in triggeredEntryIds) { graph.addEdge( diff --git a/app/lib/widgets/components/app/entries_graph.g.dart b/app/lib/widgets/components/app/entries_graph.g.dart index 923ddf9f7e..66be81fe29 100644 --- a/app/lib/widgets/components/app/entries_graph.g.dart +++ b/app/lib/widgets/components/app/entries_graph.g.dart @@ -6,7 +6,7 @@ part of 'entries_graph.dart'; // RiverpodGenerator // ************************************************************************** -String _$graphableEntriesHash() => r'6cc6e3449a4e3b2c4399cb8dff2349c5e8663828'; +String _$graphableEntriesHash() => r'973172ce3b5839b1749880a2b05113cdbb69dc75'; /// See also [graphableEntries]. @ProviderFor(graphableEntries) @@ -36,7 +36,7 @@ final graphableEntryIdsProvider = AutoDisposeProvider>.internal( ); typedef GraphableEntryIdsRef = AutoDisposeProviderRef>; -String _$isTriggerEntryHash() => r'913bdd694fd2f0903ef873779513b53ba59f44d9'; +String _$isTriggerEntryHash() => r'adf2eb9cfca1541c9f2fa769d4e5d80da3216cbe'; /// Copied from Dart SDK class _SystemHash { @@ -186,7 +186,7 @@ class _IsTriggerEntryProviderElement extends AutoDisposeProviderElement } String _$isTriggerableEntryHash() => - r'1414ae3da6c21972cdaeba7cd92a90ad5ace0a30'; + r'6b76b8651cf5d6a4765bbbf6c667960a3b251c83'; /// See also [isTriggerableEntry]. @ProviderFor(isTriggerableEntry) @@ -314,7 +314,7 @@ class _IsTriggerableEntryProviderElement String get entryId => (origin as IsTriggerableEntryProvider).entryId; } -String _$entryTriggersHash() => r'202d6329486245dd0f1be929ab5f6c076a237fc4'; +String _$entryTriggersHash() => r'9f94cc8f305332fa1eb2e6497eb8e854c0a2f674'; /// See also [entryTriggers]. @ProviderFor(entryTriggers) @@ -442,7 +442,7 @@ class _EntryTriggersProviderElement String get entryId => (origin as EntryTriggersProvider).entryId; } -String _$graphHash() => r'177f6ba5a8480b0e1c89f0214809b14cdf70eecc'; +String _$graphHash() => r'9bc252c6c79cef4f4b7f6e52ad1bba2e72e6c769'; /// See also [graph]. @ProviderFor(graph) diff --git a/app/lib/widgets/components/app/entry_node.dart b/app/lib/widgets/components/app/entry_node.dart index 3fedbd79bf..f19e563f6b 100644 --- a/app/lib/widgets/components/app/entry_node.dart +++ b/app/lib/widgets/components/app/entry_node.dart @@ -5,9 +5,9 @@ import "package:flutter/material.dart" hide ContextMenuController; import "package:flutter_animate/flutter_animate.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/book.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/pages/page_editor.dart"; @@ -31,7 +31,8 @@ List linkablePaths( final entry = ref.read(globalEntryProvider(entryId)); if (entry == null) return []; - final modifiers = ref.read(fieldModifiersProvider(entry.type, "entry")); + final modifiers = + ref.read(fieldModifiersProvider(entry.blueprintId, "entry")); return modifiers.entries.expand((e) => entry.newPaths(e.key)).toList(); } @@ -44,7 +45,8 @@ List linkableDuplicatePaths( if (entry == null) return []; final tags = ref.watch(entryTagsProvider(entryId)); - final modifiers = ref.read(fieldModifiersProvider(entry.type, "entry")); + final modifiers = + ref.read(fieldModifiersProvider(entry.blueprintId, "entry")); return modifiers.entries .where((e) => tags.contains(e.value.data)) .expand((e) => entry.newPaths(e.key)) @@ -62,8 +64,10 @@ List _acceptingPaths( final entry = ref.watch(globalEntryProvider(entryId)); if (entry == null) return []; - final modifiers = ref.watch(fieldModifiersProvider(entry.type, "entry")); - final onlyTags = ref.watch(fieldModifiersProvider(entry.type, "only_tags")); + final modifiers = + ref.watch(fieldModifiersProvider(entry.blueprintId, "entry")); + final onlyTags = + ref.watch(fieldModifiersProvider(entry.blueprintId, "only_tags")); return modifiers.entries .where((e) { @@ -92,18 +96,18 @@ class EntryNode extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final isSelected = ref.watch(inspectingEntryIdProvider.select((e) => e == entryId)); - final entryType = ref.watch(entryTypeProvider(entryId)); - if (entryType == null) return const NonExistentEntry(); + final blueprintId = ref.watch(entryBlueprintIdProvider(entryId)); + if (blueprintId == null) return const NonExistentEntry(); final entryName = ref.watch(entryNameProvider(entryId)); if (entryName == null) return const NonExistentEntry(); - final blueprint = ref.watch(entryBlueprintProvider(entryType)); + final blueprint = ref.watch(entryBlueprintProvider(blueprintId)); if (blueprint == null) return NoBlueprintEntry(entryId: entryId); return _EntryNode( id: entryId, - type: entryType, + type: blueprintId, backgroundColor: blueprint.color, name: entryName.formatted, icon: SizedBox( @@ -170,22 +174,22 @@ void moveEntryToSelectingPage(PassingRef ref, String entryId) { final from = ref.read(entryPageIdProvider(entryId)); if (from == null) return; - final entryType = ref.read(entryTypeProvider(entryId)); - if (entryType == null) return; + final blueprintId = ref.read(entryBlueprintIdProvider(entryId)); + if (blueprintId == null) return; - final pageType = ref.read(entryBlueprintPageTypeProvider(entryType)); + final pageType = ref.read(entryBlueprintPageTypeProvider(blueprintId)); ref.read(searchProvider.notifier).asBuilder() ..pageType(pageType) ..fetchPage( onSelect: (page) { - ref.read(bookProvider.notifier).moveEntry(entryId, from, page.pageName); + ref.read(bookProvider.notifier).moveEntry(entryId, from, page.id); return true; }, ) ..fetchAddPage( onAdded: (page) { - ref.read(bookProvider.notifier).moveEntry(entryId, from, page.pageName); + ref.read(bookProvider.notifier).moveEntry(entryId, from, page.id); }, ) ..open(); @@ -441,13 +445,13 @@ class FakeEntryNode extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final type = ref.watch(entryTypeProvider(entryId)); - if (type == null) return const NonExistentEntry(); + final blueprintId = ref.watch(entryBlueprintIdProvider(entryId)); + if (blueprintId == null) return const NonExistentEntry(); final name = ref.watch(entryNameProvider(entryId)); if (name == null) return const NonExistentEntry(); - final blueprint = ref.watch(entryBlueprintProvider(type)); + final blueprint = ref.watch(entryBlueprintProvider(blueprintId)); if (blueprint == null) return const NonExistentEntry(); final isDeprecated = ref.watch(isEntryDeprecatedProvider(entryId)); @@ -477,7 +481,7 @@ class FakeEntryNode extends HookConsumerWidget { ), ), Text( - type.formatted, + blueprintId.formatted, style: TextStyle( color: Colors.white70, fontSize: 11, @@ -622,7 +626,7 @@ class ExternalEntryNode extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final blueprint = ref.watch(entryBlueprintProvider(entry.type)); + final blueprint = ref.watch(entryBlueprintProvider(entry.blueprintId)); final page = ref.watch(pageProvider(pageId)); final pageName = page?.pageName.formatted ?? "Unknown page"; diff --git a/app/lib/widgets/components/app/entry_node.g.dart b/app/lib/widgets/components/app/entry_node.g.dart index 304f1e8da4..57e72886ec 100644 --- a/app/lib/widgets/components/app/entry_node.g.dart +++ b/app/lib/widgets/components/app/entry_node.g.dart @@ -6,7 +6,7 @@ part of 'entry_node.dart'; // RiverpodGenerator // ************************************************************************** -String _$linkablePathsHash() => r'884f9f6cc3e0c6e6c97dba3088c2d824ff2c1be4'; +String _$linkablePathsHash() => r'3c9be167013d314d75a71729712e367a5a890149'; /// Copied from Dart SDK class _SystemHash { @@ -156,7 +156,7 @@ class _LinkablePathsProviderElement } String _$linkableDuplicatePathsHash() => - r'b2c2a0a1159773985a764adf969dbb3706ceb56a'; + r'8c2866db6d24ba1adfbdf5db004701b73bf1d54f'; /// See also [linkableDuplicatePaths]. @ProviderFor(linkableDuplicatePaths) @@ -285,7 +285,7 @@ class _LinkableDuplicatePathsProviderElement String get entryId => (origin as LinkableDuplicatePathsProvider).entryId; } -String _$acceptingPathsHash() => r'76724dcc043808279bdf1f4aa92687fe87f54446'; +String _$acceptingPathsHash() => r'dc9a8e21fa7a4a25a51c810ac31f7bdc5e804e3c'; /// See also [_acceptingPaths]. @ProviderFor(_acceptingPaths) diff --git a/app/lib/widgets/components/app/entry_search.dart b/app/lib/widgets/components/app/entry_search.dart index 8fa9ce10df..398bcd4453 100644 --- a/app/lib/widgets/components/app/entry_search.dart +++ b/app/lib/widgets/components/app/entry_search.dart @@ -3,8 +3,8 @@ import "package:flutter/material.dart" hide Page; import "package:flutter/services.dart"; import "package:fuzzy/fuzzy.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/pages/page_editor.dart"; import "package:typewriter/utils/extensions.dart"; @@ -87,14 +87,14 @@ Fuzzy _fuzzyEntries(_FuzzyEntriesRef ref) { final pages = ref.watch(pagesProvider); final definitions = pages.expand((page) { return page.entries.map((entry) { - final blueprint = ref.watch(entryBlueprintProvider(entry.type)); + final blueprint = ref.watch(entryBlueprintProvider(entry.blueprintId)); if (blueprint == null) return null; return EntryDefinition( - pageId: page.pageName, + pageId: page.id, blueprint: blueprint, entry: entry, ); - }).whereNotNull(); + }).nonNulls; }).toList(); return Fuzzy( @@ -121,8 +121,8 @@ Fuzzy _fuzzyEntries(_FuzzyEntriesRef ref) { weight: 0.15, ), WeightedKey( - name: "type", - getter: (definition) => definition.entry.type, + name: "blueprint", + getter: (definition) => definition.blueprint.name.formatted, weight: 0.4, ), WeightedKey( @@ -131,8 +131,8 @@ Fuzzy _fuzzyEntries(_FuzzyEntriesRef ref) { weight: 0.3, ), WeightedKey( - name: "adapter", - getter: (definition) => definition.blueprint.adapter, + name: "extension", + getter: (definition) => definition.blueprint.extension, weight: 0.1, ), ], @@ -173,8 +173,8 @@ Fuzzy _fuzzyBlueprints(_FuzzyBlueprintsRef ref) { weight: 0.4, ), WeightedKey( - name: "adapter", - getter: (blueprint) => blueprint.adapter, + name: "extension", + getter: (blueprint) => blueprint.extension, weight: 0.2, ), ], @@ -454,7 +454,7 @@ class AddEntrySearchElement extends SearchElement { final currentPage = ref.read(currentPageProvider); // Had to create/select a new page for the entry - if (page.pageName != currentPage?.pageName) { + if (page.id != currentPage?.id) { ref.read(searchProvider.notifier).endSearch(); } diff --git a/app/lib/widgets/components/app/entry_search.g.dart b/app/lib/widgets/components/app/entry_search.g.dart index 544d0d1945..4c90aad4bd 100644 --- a/app/lib/widgets/components/app/entry_search.g.dart +++ b/app/lib/widgets/components/app/entry_search.g.dart @@ -6,7 +6,7 @@ part of 'entry_search.dart'; // RiverpodGenerator // ************************************************************************** -String _$fuzzyEntriesHash() => r'1d568c290f729be65ce227d120a07a4b08b69880'; +String _$fuzzyEntriesHash() => r'687dbe4174b0e52b9966a9bc3a28a869a9d96f13'; /// See also [_fuzzyEntries]. @ProviderFor(_fuzzyEntries) @@ -21,7 +21,7 @@ final _fuzzyEntriesProvider = ); typedef _FuzzyEntriesRef = AutoDisposeProviderRef>; -String _$fuzzyBlueprintsHash() => r'1ea916702687026ad211c8ee1ba9e4986288d67c'; +String _$fuzzyBlueprintsHash() => r'121f5fcc11a1c7a82c2af498947c42f95d9bce69'; /// See also [_fuzzyBlueprints]. @ProviderFor(_fuzzyBlueprints) diff --git a/app/lib/widgets/components/app/manifest_view.dart b/app/lib/widgets/components/app/manifest_view.dart index 26bd4eee3d..9aaaf9edcf 100644 --- a/app/lib/widgets/components/app/manifest_view.dart +++ b/app/lib/widgets/components/app/manifest_view.dart @@ -3,8 +3,8 @@ import "package:flutter_hooks/flutter_hooks.dart"; import "package:graphview/GraphView.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/pages/page_editor.dart"; import "package:typewriter/widgets/components/app/empty_screen.dart"; @@ -20,7 +20,7 @@ List manifestEntries(ManifestEntriesRef ref) { if (page == null) return []; return page.entries.where((entry) { - final tags = ref.watch(entryBlueprintTagsProvider(entry.type)); + final tags = ref.watch(entryBlueprintTagsProvider(entry.blueprintId)); if (tags.isEmpty) { // Entries without a blueprint are always shown. So that the user can delete them. return true; @@ -40,7 +40,8 @@ Set? entryReferences(EntryReferencesRef ref, String entryId) { final entry = ref.watch(globalEntryProvider(entryId)); if (entry == null) return null; - final modifiers = ref.watch(modifierPathsProvider(entry.type, "entry")); + final modifiers = + ref.watch(modifierPathsProvider(entry.blueprintId, "entry")); return modifiers .expand(entry.getAll) .map((id) => id as String) @@ -62,8 +63,8 @@ Graph manifestGraph(ManifestGraphRef ref) { final referenceEntryIds = ref.watch(entryReferencesProvider(entry.id)); if (referenceEntryIds == null) continue; - final color = - ref.watch(entryBlueprintProvider(entry.type))?.color ?? Colors.grey; + final color = ref.watch(entryBlueprintProvider(entry.blueprintId))?.color ?? + Colors.grey; for (final referenceEntryId in referenceEntryIds) { final referenceTags = ref.watch(entryTagsProvider(referenceEntryId)); diff --git a/app/lib/widgets/components/app/manifest_view.g.dart b/app/lib/widgets/components/app/manifest_view.g.dart index 12c66a80ca..e0c201267e 100644 --- a/app/lib/widgets/components/app/manifest_view.g.dart +++ b/app/lib/widgets/components/app/manifest_view.g.dart @@ -6,7 +6,7 @@ part of 'manifest_view.dart'; // RiverpodGenerator // ************************************************************************** -String _$manifestEntriesHash() => r'ee26b4e5433b9b26aa63771c4915fbb90113cc31'; +String _$manifestEntriesHash() => r'000665d0b4cf549b1875bda9c92ef01b64f1b5ce'; /// See also [manifestEntries]. @ProviderFor(manifestEntries) @@ -36,7 +36,7 @@ final manifestEntryIdsProvider = AutoDisposeProvider>.internal( ); typedef ManifestEntryIdsRef = AutoDisposeProviderRef>; -String _$entryReferencesHash() => r'3586d5429538084a11cd4329d4547dd2346ba02c'; +String _$entryReferencesHash() => r'cde5b6567d34b8c894d75ef53f8a87d5920545b5'; /// Copied from Dart SDK class _SystemHash { @@ -185,7 +185,7 @@ class _EntryReferencesProviderElement String get entryId => (origin as EntryReferencesProvider).entryId; } -String _$manifestGraphHash() => r'8feed62d6e7aacf18404b8159c32080eb9fdd7b3'; +String _$manifestGraphHash() => r'91959e287dc268b2a07695aceb531654673aa878'; /// See also [manifestGraph]. @ProviderFor(manifestGraph) diff --git a/app/lib/widgets/components/app/page_search.dart b/app/lib/widgets/components/app/page_search.dart index cee10d0298..afed8e7f79 100644 --- a/app/lib/widgets/components/app/page_search.dart +++ b/app/lib/widgets/components/app/page_search.dart @@ -239,7 +239,8 @@ class PageSearchElement extends SearchElement { onTrigger: (context, __) async => await showDialog( context: context, - builder: (_) => RenamePageDialogue(old: page.pageName), + builder: (_) => + RenamePageDialogue(pageId: page.id, oldName: page.pageName), ) ?? false, ), @@ -251,7 +252,7 @@ class PageSearchElement extends SearchElement { await showDialog( context: context, builder: (_) => ChangeChapterDialogue( - pageId: page.pageName, + pageId: page.id, chapter: page.chapter, ), ) ?? @@ -263,7 +264,7 @@ class PageSearchElement extends SearchElement { SmartSingleActivator(LogicalKeyboardKey.backspace, control: true), color: Colors.red, onTrigger: (context, ref) => - showPageDeletionDialogue(context, ref, page.pageName), + showPageDeletionDialogue(context, ref, page.id), ), ]; } @@ -278,7 +279,7 @@ class PageSearchElement extends SearchElement { ref.read(searchProvider.notifier).endSearch(); - await navigator.navigateToPage(ref, page.pageName); + await navigator.navigateToPage(ref, page.id); return false; } } @@ -317,21 +318,21 @@ class AddPageSearchElement extends SearchElement { @override Future activate(BuildContext context, PassingRef ref) async { - final pageName = await showDialog( + final pageId = await showDialog( context: context, builder: (context) => AddPageDialogue(fixedType: type, autoNavigate: false), ); - if (pageName == null) return false; - final page = ref.read(pageProvider(pageName)); + if (pageId == null) return false; + final page = ref.read(pageProvider(pageId)); if (page == null) return false; if (onAdded != null) { onAdded?.call(page); } - await ref.read(appRouter).navigateToPage(ref, pageName); + await ref.read(appRouter).navigateToPage(ref, pageId); return true; } } diff --git a/app/lib/widgets/components/app/page_search.g.dart b/app/lib/widgets/components/app/page_search.g.dart index 90b8d00cc1..fb2bdbc257 100644 --- a/app/lib/widgets/components/app/page_search.g.dart +++ b/app/lib/widgets/components/app/page_search.g.dart @@ -6,7 +6,7 @@ part of 'page_search.dart'; // RiverpodGenerator // ************************************************************************** -String _$fuzzyPagesHash() => r'ddc5e584006a43f6159387453a42f260697990c4'; +String _$fuzzyPagesHash() => r'835da172df554f740abdb580832d5be1a90aba00'; /// See also [_fuzzyPages]. @ProviderFor(_fuzzyPages) diff --git a/app/lib/widgets/components/app/search_bar.freezed.dart b/app/lib/widgets/components/app/search_bar.freezed.dart index cf0aecbac7..2052a64953 100644 --- a/app/lib/widgets/components/app/search_bar.freezed.dart +++ b/app/lib/widgets/components/app/search_bar.freezed.dart @@ -21,7 +21,9 @@ mixin _$Search { List get filters => throw _privateConstructorUsedError; dynamic Function()? get onEnd => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of Search + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $SearchCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -47,6 +49,8 @@ class _$SearchCopyWithImpl<$Res, $Val extends Search> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Search + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -98,6 +102,8 @@ class __$$SearchImplCopyWithImpl<$Res> _$SearchImpl _value, $Res Function(_$SearchImpl) _then) : super(_value, _then); + /// Create a copy of Search + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -186,7 +192,9 @@ class _$SearchImpl implements _Search { const DeepCollectionEquality().hash(_filters), onEnd); - @JsonKey(ignore: true) + /// Create a copy of Search + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$SearchImplCopyWith<_$SearchImpl> get copyWith => @@ -208,8 +216,11 @@ abstract class _Search implements Search { List get filters; @override dynamic Function()? get onEnd; + + /// Create a copy of Search + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$SearchImplCopyWith<_$SearchImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/widgets/components/app/static_entries_list.dart b/app/lib/widgets/components/app/static_entries_list.dart index 4430435f87..0ef4e841ab 100644 --- a/app/lib/widgets/components/app/static_entries_list.dart +++ b/app/lib/widgets/components/app/static_entries_list.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/pages/page_editor.dart"; import "package:typewriter/widgets/components/app/empty_screen.dart"; import "package:typewriter/widgets/components/app/entry_node.dart"; @@ -17,7 +17,7 @@ List _staticEntryIds(_StaticEntryIdsRef ref) { return page.entries .where((entry) { - final tags = ref.watch(entryBlueprintTagsProvider(entry.type)); + final tags = ref.watch(entryBlueprintTagsProvider(entry.blueprintId)); return tags.contains("static"); }) .map((entry) => entry.id) diff --git a/app/lib/widgets/components/app/static_entries_list.g.dart b/app/lib/widgets/components/app/static_entries_list.g.dart index c86d3723ec..a9b4a2d24d 100644 --- a/app/lib/widgets/components/app/static_entries_list.g.dart +++ b/app/lib/widgets/components/app/static_entries_list.g.dart @@ -6,7 +6,7 @@ part of 'static_entries_list.dart'; // RiverpodGenerator // ************************************************************************** -String _$staticEntryIdsHash() => r'e5c8d9b663a722566b91821dad77ead02da54894'; +String _$staticEntryIdsHash() => r'dc84b375e482ed7cb8f85addc6daf14e454f8651'; /// See also [_staticEntryIds]. @ProviderFor(_staticEntryIds) diff --git a/app/lib/widgets/components/general/filled_button.dart b/app/lib/widgets/components/general/filled_button.dart index 182e450ee1..66b55ddebb 100644 --- a/app/lib/widgets/components/general/filled_button.dart +++ b/app/lib/widgets/components/general/filled_button.dart @@ -78,9 +78,9 @@ class _FilledButtonWithIconChild extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ IconTheme( - data: IconThemeData( + data: const IconThemeData( size: 18, - color: IconTheme.of(context).color, + color: Colors.white, ), child: icon, ), diff --git a/app/lib/widgets/components/general/outline_button.dart b/app/lib/widgets/components/general/outline_button.dart index 4d83a44697..1b9f22de2f 100644 --- a/app/lib/widgets/components/general/outline_button.dart +++ b/app/lib/widgets/components/general/outline_button.dart @@ -60,7 +60,11 @@ class _OutlineButtonIcon extends OutlineButton { super.color, super.key, }) : super( - child: _OutlineButtonWithIconChild(label: label, icon: icon), + child: _OutlineButtonWithIconChild( + label: label, + icon: icon, + color: color, + ), ); } @@ -68,10 +72,12 @@ class _OutlineButtonWithIconChild extends StatelessWidget { const _OutlineButtonWithIconChild({ required this.label, required this.icon, + required this.color, }); final Widget label; final Widget icon; + final Color? color; @override Widget build(BuildContext context) { @@ -84,7 +90,7 @@ class _OutlineButtonWithIconChild extends StatelessWidget { IconTheme( data: IconThemeData( size: 18, - color: IconTheme.of(context).color, + color: color ?? IconTheme.of(context).color, ), child: icon, ), diff --git a/app/lib/widgets/components/general/toasts.freezed.dart b/app/lib/widgets/components/general/toasts.freezed.dart index 01e8ea4d93..fadf676bae 100644 --- a/app/lib/widgets/components/general/toasts.freezed.dart +++ b/app/lib/widgets/components/general/toasts.freezed.dart @@ -73,7 +73,9 @@ mixin _$Toast { }) => throw _privateConstructorUsedError; - @JsonKey(ignore: true) + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) $ToastCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -101,6 +103,8 @@ class _$ToastCopyWithImpl<$Res, $Val extends Toast> // ignore: unused_field final $Res Function($Val) _then; + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -164,6 +168,8 @@ class __$$ToastImplCopyWithImpl<$Res> _$ToastImpl _value, $Res Function(_$ToastImpl) _then) : super(_value, _then); + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -252,7 +258,9 @@ class _$ToastImpl implements _Toast { int get hashCode => Object.hash(runtimeType, id, message, description, color, icon, shownAt); - @JsonKey(ignore: true) + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$ToastImplCopyWith<_$ToastImpl> get copyWith => @@ -354,8 +362,11 @@ abstract class _Toast implements Toast { String get icon; @override DateTime? get shownAt; + + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$ToastImplCopyWith<_$ToastImpl> get copyWith => throw _privateConstructorUsedError; } @@ -386,6 +397,8 @@ class __$$TemporaryToastImplCopyWithImpl<$Res> _$TemporaryToastImpl _value, $Res Function(_$TemporaryToastImpl) _then) : super(_value, _then); + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -485,7 +498,9 @@ class _$TemporaryToastImpl implements TemporaryToast { int get hashCode => Object.hash( runtimeType, id, message, description, color, icon, duration, shownAt); - @JsonKey(ignore: true) + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$TemporaryToastImplCopyWith<_$TemporaryToastImpl> get copyWith => @@ -592,8 +607,11 @@ abstract class TemporaryToast implements Toast { Duration get duration; @override DateTime? get shownAt; + + /// Create a copy of Toast + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) _$$TemporaryToastImplCopyWith<_$TemporaryToastImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/widgets/components/general/tree_view.freezed.dart b/app/lib/widgets/components/general/tree_view.freezed.dart index 5cac29af03..a60e7b5996 100644 --- a/app/lib/widgets/components/general/tree_view.freezed.dart +++ b/app/lib/widgets/components/general/tree_view.freezed.dart @@ -82,6 +82,9 @@ class _$TreeNodeCopyWithImpl> final $Val _value; // ignore: unused_field final $Res Function($Val) _then; + + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. } /// @nodoc @@ -101,6 +104,8 @@ class __$$RootTreeNodeImplCopyWithImpl _$RootTreeNodeImpl _value, $Res Function(_$RootTreeNodeImpl) _then) : super(_value, _then); + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -146,7 +151,9 @@ class _$RootTreeNodeImpl implements RootTreeNode { int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(_children)); - @JsonKey(ignore: true) + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$RootTreeNodeImplCopyWith> get copyWith => @@ -231,7 +238,10 @@ abstract class RootTreeNode implements TreeNode { _$RootTreeNodeImpl; List> get children; - @JsonKey(ignore: true) + + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$RootTreeNodeImplCopyWith> get copyWith => throw _privateConstructorUsedError; } @@ -253,6 +263,8 @@ class __$$InnerTreeNodeImplCopyWithImpl $Res Function(_$InnerTreeNodeImpl) _then) : super(_value, _then); + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -317,7 +329,9 @@ class _$InnerTreeNodeImpl implements InnerTreeNode { int get hashCode => Object.hash( runtimeType, name, path, const DeepCollectionEquality().hash(_children)); - @JsonKey(ignore: true) + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$InnerTreeNodeImplCopyWith> get copyWith => @@ -406,7 +420,10 @@ abstract class InnerTreeNode implements TreeNode { String get name; String get path; List> get children; - @JsonKey(ignore: true) + + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$InnerTreeNodeImplCopyWith> get copyWith => throw _privateConstructorUsedError; } @@ -428,6 +445,8 @@ class __$$LeafTreeNodeImplCopyWithImpl _$LeafTreeNodeImpl _value, $Res Function(_$LeafTreeNodeImpl) _then) : super(_value, _then); + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -467,7 +486,9 @@ class _$LeafTreeNodeImpl implements LeafTreeNode { int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(value)); - @JsonKey(ignore: true) + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$LeafTreeNodeImplCopyWith> get copyWith => @@ -551,7 +572,10 @@ abstract class LeafTreeNode implements TreeNode { const factory LeafTreeNode({required final T value}) = _$LeafTreeNodeImpl; T get value; - @JsonKey(ignore: true) + + /// Create a copy of TreeNode + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$LeafTreeNodeImplCopyWith> get copyWith => throw _privateConstructorUsedError; } @@ -621,6 +645,9 @@ class __$TreeModificationCopyWithImpl _$TreeAddImpl _value, $Res Function(_$TreeAddImpl) _then) : super(_value, _then); + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -655,6 +684,8 @@ class __$$TreeAddImplCopyWithImpl )); } + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. @override @pragma('vm:prefer-inline') $TreeNodeCopyWith get node { @@ -688,7 +719,9 @@ class _$TreeAddImpl implements _TreeAdd { @override int get hashCode => Object.hash(runtimeType, node); - @JsonKey(ignore: true) + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$TreeAddImplCopyWith> get copyWith => @@ -767,7 +800,10 @@ abstract class _TreeAdd implements _TreeModification { const factory _TreeAdd({required final TreeNode node}) = _$TreeAddImpl; TreeNode get node; - @JsonKey(ignore: true) + + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$TreeAddImplCopyWith> get copyWith => throw _privateConstructorUsedError; } @@ -791,6 +827,8 @@ class __$$TreeUpdateImplCopyWithImpl _$TreeUpdateImpl _value, $Res Function(_$TreeUpdateImpl) _then) : super(_value, _then); + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -809,6 +847,8 @@ class __$$TreeUpdateImplCopyWithImpl )); } + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. @override @pragma('vm:prefer-inline') $TreeNodeCopyWith get node { @@ -845,7 +885,9 @@ class _$TreeUpdateImpl implements _TreeUpdate { @override int get hashCode => Object.hash(runtimeType, path, node); - @JsonKey(ignore: true) + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$TreeUpdateImplCopyWith> get copyWith => @@ -927,7 +969,10 @@ abstract class _TreeUpdate implements _TreeModification { String get path; TreeNode get node; - @JsonKey(ignore: true) + + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$TreeUpdateImplCopyWith> get copyWith => throw _privateConstructorUsedError; } @@ -949,6 +994,8 @@ class __$$TreeRemoveImplCopyWithImpl _$TreeRemoveImpl _value, $Res Function(_$TreeRemoveImpl) _then) : super(_value, _then); + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -987,7 +1034,9 @@ class _$TreeRemoveImpl implements _TreeRemove { @override int get hashCode => Object.hash(runtimeType, path); - @JsonKey(ignore: true) + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$TreeRemoveImplCopyWith> get copyWith => @@ -1066,7 +1115,10 @@ abstract class _TreeRemove implements _TreeModification { const factory _TreeRemove({required final String path}) = _$TreeRemoveImpl; String get path; - @JsonKey(ignore: true) + + /// Create a copy of _TreeModification + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$TreeRemoveImplCopyWith> get copyWith => throw _privateConstructorUsedError; } diff --git a/app/lib/widgets/inspector/editors.dart b/app/lib/widgets/inspector/editors.dart index 539f5a3c6d..e12a092c2b 100644 --- a/app/lib/widgets/inspector/editors.dart +++ b/app/lib/widgets/inspector/editors.dart @@ -1,6 +1,6 @@ import "package:flutter/material.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/widgets/inspector/editors/boolean.dart"; import "package:typewriter/widgets/inspector/editors/color.dart"; @@ -43,7 +43,7 @@ List editorFilters(EditorFiltersRef ref) => [ // Custom Editors MaterialEditorFilter(), OptionalEditorFilter(), - LocationEditorFilter(), + PositionEditorFilter(), VectorEditorFilter(), DurationEditorFilter(), CronEditorFilter(), @@ -66,9 +66,9 @@ List editorFilters(EditorFiltersRef ref) => [ ]; abstract class EditorFilter { - bool canEdit(FieldInfo info); + bool canEdit(DataBlueprint dataBlueprint); - Widget build(String path, FieldInfo info); + Widget build(String path, DataBlueprint dataBlueprint); } @riverpod diff --git a/app/lib/widgets/inspector/editors.g.dart b/app/lib/widgets/inspector/editors.g.dart index 01362e1918..15b94966fc 100644 --- a/app/lib/widgets/inspector/editors.g.dart +++ b/app/lib/widgets/inspector/editors.g.dart @@ -172,7 +172,7 @@ class _FieldValueProviderElement extends AutoDisposeProviderElement dynamic get defaultValue => (origin as FieldValueProvider).defaultValue; } -String _$editorFiltersHash() => r'257c04ecec1da6467c1e408a9bdae5f78a62aceb'; +String _$editorFiltersHash() => r'366b75c5458ea9d05cc8e7e04c03fafe897e70a4'; /// See also [editorFilters]. @ProviderFor(editorFilters) diff --git a/app/lib/widgets/inspector/editors/boolean.dart b/app/lib/widgets/inspector/editors/boolean.dart index 486bf40381..3c0e9a0c72 100644 --- a/app/lib/widgets/inspector/editors/boolean.dart +++ b/app/lib/widgets/inspector/editors/boolean.dart @@ -1,6 +1,6 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/header.dart"; @@ -8,30 +8,33 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class BooleanEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is PrimitiveField && info.type == PrimitiveFieldType.boolean; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is PrimitiveBlueprint && + dataBlueprint.type == PrimitiveType.boolean; @override - Widget build(String path, FieldInfo info) => - BooleanEditor(path: path, field: info as PrimitiveField); + Widget build(String path, DataBlueprint dataBlueprint) => BooleanEditor( + path: path, + primitiveBlueprint: dataBlueprint as PrimitiveBlueprint, + ); } class BooleanEditor extends HookConsumerWidget { const BooleanEditor({ required this.path, - required this.field, + required this.primitiveBlueprint, super.key, }) : super(); final String path; - final PrimitiveField field; + final PrimitiveBlueprint primitiveBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { final value = ref.watch(fieldValueProvider(path, false)); return FieldHeader( - field: field, path: path, + dataBlueprint: primitiveBlueprint, trailing: [ Row( children: [ diff --git a/app/lib/widgets/inspector/editors/color.dart b/app/lib/widgets/inspector/editors/color.dart index 12f2e2b2ff..3b89e9ea55 100644 --- a/app/lib/widgets/inspector/editors/color.dart +++ b/app/lib/widgets/inspector/editors/color.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart"; import "package:flutter_colorpicker/flutter_colorpicker.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/header.dart"; @@ -9,30 +9,34 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class ColorEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is CustomField && info.editor == "color"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "color"; @override - Widget build(String path, FieldInfo info) => - ColorEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => ColorEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class ColorEditor extends HookConsumerWidget { const ColorEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { - final startColor = ref.watch(fieldValueProvider(path, field.defaultValue)); + final startColor = + ref.watch(fieldValueProvider(path, customBlueprint.defaultValue)); final pickerColor = startColor is int ? Color(startColor) : Colors.black; return FieldHeader( path: path, - field: field, + dataBlueprint: customBlueprint, canExpand: true, child: Padding( padding: const EdgeInsets.only(top: 12), diff --git a/app/lib/widgets/inspector/editors/cron.dart b/app/lib/widgets/inspector/editors/cron.dart index f46a352712..fb63850fb8 100644 --- a/app/lib/widgets/inspector/editors/cron.dart +++ b/app/lib/widgets/inspector/editors/cron.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart"; import "package:flutter/services.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/cron.dart"; import "package:typewriter/utils/icons.dart"; @@ -11,21 +11,22 @@ import "package:typewriter/widgets/inspector/validated_inspector_text_field.dart class CronEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is CustomField && info.editor == "cron"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "cron"; @override - Widget build(String path, FieldInfo info) => - CronEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => + CronEditor(path: path, customBlueprint: dataBlueprint as CustomBlueprint); } class CronEditor extends HookConsumerWidget { const CronEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { diff --git a/app/lib/widgets/inspector/editors/duration.dart b/app/lib/widgets/inspector/editors/duration.dart index 4bd9406851..07a49c3619 100644 --- a/app/lib/widgets/inspector/editors/duration.dart +++ b/app/lib/widgets/inspector/editors/duration.dart @@ -3,7 +3,7 @@ import "package:flutter/material.dart"; import "package:flutter/services.dart"; import "package:flutter_animate/flutter_animate.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/widgets/components/app/writers.dart"; @@ -12,21 +12,23 @@ import "package:typewriter/widgets/inspector/validated_inspector_text_field.dart class DurationEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "duration"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "duration"; @override - Widget build(String path, FieldInfo info) => - DurationEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => DurationEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class DurationEditor extends HookConsumerWidget { const DurationEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { return WritersIndicator( diff --git a/app/lib/widgets/inspector/editors/entry_selector.dart b/app/lib/widgets/inspector/editors/entry_selector.dart index 73aed99e53..e749d85bd1 100644 --- a/app/lib/widgets/inspector/editors/entry_selector.dart +++ b/app/lib/widgets/inspector/editors/entry_selector.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart" hide Page; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -16,24 +16,25 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class EntrySelectorEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info.hasModifier("entry"); + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint.hasModifier("entry"); @override - Widget build(String path, FieldInfo info) => - EntrySelectorEditor(path: path, field: info); + Widget build(String path, DataBlueprint dataBlueprint) => + EntrySelectorEditor(path: path, dataBlueprint: dataBlueprint); } class EntrySelectorEditor extends HookConsumerWidget { const EntrySelectorEditor({ required this.path, - required this.field, + required this.dataBlueprint, this.forcedValue, this.onChanged, super.key, }) : super(); final String path; - final FieldInfo field; + final DataBlueprint dataBlueprint; final String? forcedValue; final void Function(String)? onChanged; @@ -62,8 +63,8 @@ class EntrySelectorEditor extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final tag = field.get("entry") ?? ""; - final onlyTags = field.get("only_tags")?.split(",") ?? []; + final tag = dataBlueprint.get("entry") ?? ""; + final onlyTags = dataBlueprint.get("only_tags")?.split(",") ?? []; final id = forcedValue ?? ref.watch(fieldValueProvider(path, "")) as String; final hasEntry = ref.watch(entryExistsProvider(id)); @@ -74,7 +75,7 @@ class EntrySelectorEditor extends HookConsumerWidget { final entry = ref.read(globalEntryProvider(details.data.entryId)); if (entry == null) return false; - final blueprint = ref.read(entryBlueprintProvider(entry.type)); + final blueprint = ref.read(entryBlueprintProvider(entry.blueprintId)); if (blueprint == null) return false; return blueprint.tags.contains(tag); diff --git a/app/lib/widgets/inspector/editors/enum.dart b/app/lib/widgets/inspector/editors/enum.dart index 25da4ca37f..22eba1b505 100644 --- a/app/lib/widgets/inspector/editors/enum.dart +++ b/app/lib/widgets/inspector/editors/enum.dart @@ -1,6 +1,6 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/components/general/dropdown.dart"; @@ -9,26 +9,27 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class EnumEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is EnumField && info.values.isNotEmpty; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is EnumBlueprint && dataBlueprint.values.isNotEmpty; @override - Widget build(String path, FieldInfo info) => EnumEditor( + Widget build(String path, DataBlueprint dataBlueprint) => EnumEditor( path: path, - field: info as EnumField, + enumBlueprint: dataBlueprint as EnumBlueprint, ); } class EnumEditor extends HookConsumerWidget { const EnumEditor({ required this.path, - required this.field, + required this.enumBlueprint, this.forcedValue, this.icon = TWIcons.list, this.onChanged, super.key, }) : super(); final String path; - final EnumField field; + final EnumBlueprint enumBlueprint; final String? forcedValue; final String icon; @@ -36,11 +37,12 @@ class EnumEditor extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final value = ref.watch(fieldValueProvider(path, field.values.first)); + final value = + ref.watch(fieldValueProvider(path, enumBlueprint.values.first)); return Dropdown( icon: icon, value: forcedValue ?? value, - values: field.values, + values: enumBlueprint.values, builder: (context, value) => Padding( padding: const EdgeInsets.only(right: 8), child: Text(value), diff --git a/app/lib/widgets/inspector/editors/field.dart b/app/lib/widgets/inspector/editors/field.dart index 29566f7856..f9f88dc944 100644 --- a/app/lib/widgets/inspector/editors/field.dart +++ b/app/lib/widgets/inspector/editors/field.dart @@ -1,26 +1,26 @@ import "package:collection/collection.dart"; import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/widgets/components/general/error_box.dart"; import "package:typewriter/widgets/inspector/editors.dart"; class FieldEditor extends HookConsumerWidget { const FieldEditor({ required this.path, - required this.type, + required this.dataBlueprint, super.key, }) : super(); final String path; - final FieldInfo type; + final DataBlueprint dataBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { final filters = ref.watch(editorFiltersProvider); final editor = filters - .firstWhereOrNull((filter) => filter.canEdit(type)) - ?.build(path, type); + .firstWhereOrNull((filter) => filter.canEdit(dataBlueprint)) + ?.build(path, dataBlueprint); return editor ?? _NoEditorFound(path: path); } diff --git a/app/lib/widgets/inspector/editors/float_range.dart b/app/lib/widgets/inspector/editors/float_range.dart index 093d3d4a85..3f3f058b77 100644 --- a/app/lib/widgets/inspector/editors/float_range.dart +++ b/app/lib/widgets/inspector/editors/float_range.dart @@ -1,6 +1,6 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/widgets/components/app/cord_property.dart"; import "package:typewriter/widgets/components/general/iconify.dart"; @@ -10,29 +10,31 @@ import "package:typewriter/widgets/inspector/headers/info_action.dart"; class FloatRangeFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "floatRange"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "floatRange"; @override - Widget build(String path, FieldInfo info) => - FloatRangeEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => FloatRangeEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class FloatRangeEditor extends HookConsumerWidget { const FloatRangeEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { return FieldHeader( path: path, - field: field, + dataBlueprint: customBlueprint, trailing: const [ InfoHeaderAction( tooltip: "Max is included in the range.", diff --git a/app/lib/widgets/inspector/editors/item.dart b/app/lib/widgets/inspector/editors/item.dart index ed8938a104..733c936a1f 100644 --- a/app/lib/widgets/inspector/editors/item.dart +++ b/app/lib/widgets/inspector/editors/item.dart @@ -2,7 +2,7 @@ import "package:flutter/material.dart"; import "package:flutter_animate/flutter_animate.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/components/general/error_box.dart"; @@ -14,44 +14,46 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class ItemEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is CustomField && info.editor == "item"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "item"; @override - Widget build(String path, FieldInfo info) => - ItemEditor(path: path, info: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => + ItemEditor(path: path, customBlueprint: dataBlueprint as CustomBlueprint); } class ItemEditor extends HookConsumerWidget { const ItemEditor({ required this.path, - required this.info, + required this.customBlueprint, super.key, }); final String path; - final CustomField info; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { // final value = ref.watch(fieldValueProvider(path)); - final objectField = - info.fieldInfo is ObjectField ? info.fieldInfo as ObjectField? : null; - if (objectField == null) { + final objectBlueprint = customBlueprint.shape is ObjectBlueprint + ? customBlueprint.shape as ObjectBlueprint? + : null; + if (objectBlueprint == null) { return ErrorBox( message: "Could not find subfields for item field: $path", ); } return FieldHeader( path: path, - field: info, + dataBlueprint: customBlueprint, canExpand: true, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 8), - _FieldSelector(path: path, objectField: objectField), - _ItemEditors(path: path, objectField: objectField), + _FieldSelector(path: path, objectBlueprint: objectBlueprint), + _ItemEditors(path: path, objectBlueprint: objectBlueprint), // Text("Item: $value"), - // Text("Info: ${info.fieldInfo}"), + // Text("Info: ${info.DataBlueprint}"), ], ), ); @@ -61,16 +63,16 @@ class ItemEditor extends HookConsumerWidget { class _FieldSelector extends HookConsumerWidget { const _FieldSelector({ required this.path, - required this.objectField, + required this.objectBlueprint, }); final String path; - final ObjectField objectField; + final ObjectBlueprint objectBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { final hovering = useState(false); - final selected = objectField.fields.keys + final selected = objectBlueprint.fields.keys .where( (id) => ref.watch(fieldValueProvider("$path.$id.enabled", false)) == true, @@ -93,15 +95,10 @@ class _FieldSelector extends HookConsumerWidget { spacing: 6, runSpacing: 6, children: [ - for (final MapEntry(key: id, value: info) - in objectField.fields.entries) + for (final MapEntry(key: id, value: dataBlueprint) + in objectBlueprint.fields.entries) if (showAll || selected.contains(id)) - _ItemChip( - key: ValueKey(id), - path: "$path.$id", - id: id, - info: info, - ), + _chip(id, dataBlueprint), ].animate(interval: 40.ms).fadeIn(duration: 250.ms).scaleXY( begin: 0.6, end: 1.0, @@ -113,19 +110,34 @@ class _FieldSelector extends HookConsumerWidget { ), ); } + + Widget _chip(String id, DataBlueprint dataBlueprint) { + if (dataBlueprint is! CustomBlueprint) return const SizedBox(); + final shapeBlueprint = dataBlueprint.shape; + if (shapeBlueprint is! ObjectBlueprint) return const SizedBox(); + if (!shapeBlueprint.fields.containsKey("value")) return const SizedBox(); + final valueBlueprint = shapeBlueprint.fields["value"]; + if (valueBlueprint == null) return const SizedBox(); + return _ItemChip( + key: ValueKey(id), + path: "$path.$id", + id: id, + dataBlueprint: valueBlueprint, + ); + } } class _ItemChip extends HookConsumerWidget { const _ItemChip({ required this.path, required this.id, - required this.info, + required this.dataBlueprint, super.key, }); final String path; final String id; - final FieldInfo info; + final DataBlueprint dataBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { @@ -138,7 +150,7 @@ class _ItemChip extends HookConsumerWidget { return InputChip( label: Text(id.capitalize, style: TextStyle(color: foregroundColor)), avatar: Iconify( - info.get("icon"), + dataBlueprint.get("icon"), size: 14, color: foregroundColor, ), @@ -159,11 +171,11 @@ class _ItemChip extends HookConsumerWidget { class _ItemEditors extends HookConsumerWidget { const _ItemEditors({ required this.path, - required this.objectField, + required this.objectBlueprint, }); final String path; - final ObjectField objectField; + final ObjectBlueprint objectBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { @@ -174,28 +186,38 @@ class _ItemEditors extends HookConsumerWidget { clipBehavior: Clip.none, child: Column( children: [ - for (final MapEntry(key: id, value: info) - in objectField.fields.entries) - _ItemEditor( - key: ValueKey(id), - path: "$path.$id", - field: info, - ), + for (final MapEntry(key: id, value: dataBlueprint) + in objectBlueprint.fields.entries) + _editor(id, dataBlueprint), ], ), ); } + + Widget _editor(String id, DataBlueprint dataBlueprint) { + if (dataBlueprint is! CustomBlueprint) return const SizedBox(); + final shapeBlueprint = dataBlueprint.shape; + if (shapeBlueprint is! ObjectBlueprint) return const SizedBox(); + if (!shapeBlueprint.fields.containsKey("value")) return const SizedBox(); + final valueBlueprint = shapeBlueprint.fields["value"]; + if (valueBlueprint == null) return const SizedBox(); + return _ItemEditor( + key: ValueKey(id), + path: "$path.$id", + dataBlueprint: valueBlueprint, + ); + } } class _ItemEditor extends HookConsumerWidget { const _ItemEditor({ required this.path, - required this.field, + required this.dataBlueprint, super.key, }); final String path; - final FieldInfo field; + final DataBlueprint dataBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { @@ -209,9 +231,9 @@ class _ItemEditor extends HookConsumerWidget { children: [ const SizedBox(height: 8), FieldHeader( - field: field, + dataBlueprint: dataBlueprint, path: path, - child: FieldEditor(path: "$path.value", type: field), + child: FieldEditor(path: "$path.value", dataBlueprint: dataBlueprint), ), ], ).animate().fadeIn(duration: 250.ms).moveY( diff --git a/app/lib/widgets/inspector/editors/list.dart b/app/lib/widgets/inspector/editors/list.dart index f397b71adf..61889f9fa8 100644 --- a/app/lib/widgets/inspector/editors/list.dart +++ b/app/lib/widgets/inspector/editors/list.dart @@ -2,7 +2,7 @@ import "package:flutter/material.dart" hide FilledButton; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/components/general/iconify.dart"; @@ -18,11 +18,11 @@ part "list.g.dart"; class ListEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is ListField; + bool canEdit(DataBlueprint dataBlueprint) => dataBlueprint is ListBlueprint; @override - Widget build(String path, FieldInfo info) => - ListEditor(path: path, field: info as ListField); + Widget build(String path, DataBlueprint dataBlueprint) => + ListEditor(path: path, listBlueprint: dataBlueprint as ListBlueprint); } @riverpod @@ -33,11 +33,11 @@ int _listValueLength(_ListValueLengthRef ref, String path) { class ListEditor extends HookConsumerWidget { const ListEditor({ required this.path, - required this.field, + required this.listBlueprint, super.key, }) : super(); final String path; - final ListField field; + final ListBlueprint listBlueprint; List _get(PassingRef ref) { return ref.read(fieldValueProvider(path)) as List? ?? []; @@ -47,7 +47,7 @@ class ListEditor extends HookConsumerWidget { ref.read(inspectingEntryDefinitionProvider)?.updateField( ref, path, - [..._get(ref), field.type.defaultValue], + [..._get(ref), listBlueprint.type.defaultValue()], ); } @@ -87,8 +87,8 @@ class ListEditor extends HookConsumerWidget { ); return FieldHeader( - field: field, path: path, + dataBlueprint: listBlueprint, canExpand: true, actions: [ AddHeaderAction( @@ -107,7 +107,7 @@ class ListEditor extends HookConsumerWidget { key: globalKeys[index], index: index, path: path, - field: field, + listBlueprint: listBlueprint, ), ), ); @@ -118,13 +118,13 @@ class _ListItem extends HookConsumerWidget { const _ListItem({ required this.index, required this.path, - required this.field, + required this.listBlueprint, super.key, }) : super(); final int index; final String path; - final ListField field; + final ListBlueprint listBlueprint; void _remove(PassingRef ref, int index) { final value = ref.read(fieldValueProvider(path)) as List? ?? []; @@ -137,12 +137,12 @@ class _ListItem extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final type = field.type; + final dataBlueprint = listBlueprint.type; final childPath = "$path.$index"; return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: FieldHeader( - field: type, + dataBlueprint: dataBlueprint, path: childPath, canExpand: true, leading: [ @@ -159,7 +159,11 @@ class _ListItem extends HookConsumerWidget { ), ], actions: [ - DuplicateListItemAction(path, childPath, type), + DuplicateListItemAction( + parentPath: path, + path: childPath, + dataBlueprint: dataBlueprint, + ), RemoveHeaderAction( path: "$path.$index", onRemove: () => _remove(ref.passing, index), @@ -167,7 +171,7 @@ class _ListItem extends HookConsumerWidget { ], child: FieldEditor( path: "$path.$index", - type: field.type, + dataBlueprint: dataBlueprint, ), ), ); diff --git a/app/lib/widgets/inspector/editors/location.dart b/app/lib/widgets/inspector/editors/location.dart index 607f6ab0bf..7f4f72f75a 100644 --- a/app/lib/widgets/inspector/editors/location.dart +++ b/app/lib/widgets/inspector/editors/location.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -12,33 +12,35 @@ import "package:typewriter/widgets/inspector/current_editing_field.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/inspector.dart"; -class LocationEditorFilter extends EditorFilter { +class PositionEditorFilter extends EditorFilter { @override - Widget build(String path, FieldInfo info) => - LocationEditor(path: path, field: info as CustomField); + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "position"; @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "location"; + Widget build(String path, DataBlueprint dataBlueprint) => PositionEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } -class LocationEditor extends HookConsumerWidget { - const LocationEditor({ +class PositionEditor extends HookConsumerWidget { + const PositionEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { - final withRotation = field.hasModifier("with_rotation"); + final withRotation = customBlueprint.hasModifier("with_rotation"); return Column( children: [ - _LocationWorldEditor(path: "$path.world"), + _WorldEditor(path: "$path.world"), const SizedBox(height: 8), Row( children: [ @@ -84,8 +86,8 @@ class LocationEditor extends HookConsumerWidget { } } -class _LocationWorldEditor extends HookConsumerWidget { - const _LocationWorldEditor({ +class _WorldEditor extends HookConsumerWidget { + const _WorldEditor({ required this.path, }); diff --git a/app/lib/widgets/inspector/editors/map.dart b/app/lib/widgets/inspector/editors/map.dart index f5e5dcb5f7..2070026a8d 100644 --- a/app/lib/widgets/inspector/editors/map.dart +++ b/app/lib/widgets/inspector/editors/map.dart @@ -2,7 +2,7 @@ import "package:collection/collection.dart"; import "package:flutter/material.dart" hide FilledButton; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/utils/popups.dart"; @@ -18,30 +18,30 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class MapEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is MapField; + bool canEdit(DataBlueprint dataBlueprint) => dataBlueprint is MapBlueprint; @override - Widget build(String path, FieldInfo info) => - MapEditor(path: path, field: info as MapField); + Widget build(String path, DataBlueprint dataBlueprint) => + MapEditor(path: path, mapBlueprint: dataBlueprint as MapBlueprint); } class MapEditor extends HookConsumerWidget { const MapEditor({ required this.path, - required this.field, + required this.mapBlueprint, super.key, }) : super(); final String path; - final MapField field; + final MapBlueprint mapBlueprint; void _addNew(PassingRef ref, Map value) { - final key = field.key is EnumField - ? (field.key as EnumField) + final key = mapBlueprint.key is EnumBlueprint + ? (mapBlueprint.key as EnumBlueprint) .values .firstWhereOrNull((e) => !value.containsKey(e)) - : field.key.defaultValue; + : mapBlueprint.key.defaultValue(); if (key == null) return; - final val = field.value.defaultValue; + final val = mapBlueprint.value.defaultValue(); ref.read(inspectingEntryDefinitionProvider)?.updateField( ref, path, @@ -74,8 +74,8 @@ class MapEditor extends HookConsumerWidget { ); return FieldHeader( - field: field, path: path, + dataBlueprint: mapBlueprint, canExpand: true, actions: [ AddHeaderAction( @@ -92,7 +92,7 @@ class MapEditor extends HookConsumerWidget { map: value, entry: MapEntry(entry.key, entry.value), path: path, - field: field, + mapBlueprint: mapBlueprint, ), ) .toList(), @@ -107,14 +107,14 @@ class _MapEntry extends HookConsumerWidget { required this.map, required this.entry, required this.path, - required this.field, + required this.mapBlueprint, super.key, }) : super(); final int index; final Map map; final MapEntry entry; final String path; - final MapField field; + final MapBlueprint mapBlueprint; void _changeKeyField(PassingRef ref, String key) { ref.read(inspectingEntryDefinitionProvider)?.updateField( @@ -162,33 +162,33 @@ class _MapEntry extends HookConsumerWidget { } Widget _keyEditor(BuildContext context, WidgetRef ref, String name) { - if (field.key is PrimitiveField && - (field.key as PrimitiveField).type == PrimitiveFieldType.string) { + if (mapBlueprint.key is PrimitiveBlueprint && + (mapBlueprint.key as PrimitiveBlueprint).type == PrimitiveType.string) { return Flexible( child: _StringKey( path: path, - field: field.key as PrimitiveField, + field: mapBlueprint.key as PrimitiveBlueprint, value: entry.key, onChanged: (value) => _changeKey(context, ref.passing, value), ), ); } - if (field.key is EnumField) { + if (mapBlueprint.key is EnumBlueprint) { return Flexible( child: _EnumKey( path: path, - field: field.key as EnumField, + enumBlueprint: mapBlueprint.key as EnumBlueprint, value: entry.key, onChanged: (value) => _changeKey(context, ref.passing, value), ), ); } - if (field.key.hasModifier("entry")) { + if (mapBlueprint.key.hasModifier("entry")) { return Flexible( child: _EntryKey( path: path, - field: field.key, + dataBlueprint: mapBlueprint.key, value: entry.key, onChanged: (value) => _changeKey(context, ref.passing, value), ), @@ -223,7 +223,7 @@ class _MapEntry extends HookConsumerWidget { child: FieldEditor( key: ValueKey("map-$index"), path: "$path.${entry.key}", - type: field.value, + dataBlueprint: mapBlueprint.value, ), ), ], @@ -240,7 +240,7 @@ class _StringKey extends HookConsumerWidget { required this.onChanged, }) : super(); final String path; - final PrimitiveField field; + final PrimitiveBlueprint field; final String value; final Function(String) onChanged; @@ -248,7 +248,7 @@ class _StringKey extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { return StringEditor( path: path, - field: field, + primitiveBlueprint: field, forcedValue: value, icon: TWIcons.key, hint: "Enter a key", @@ -260,12 +260,12 @@ class _StringKey extends HookConsumerWidget { class _EnumKey extends HookConsumerWidget { const _EnumKey({ required this.path, - required this.field, + required this.enumBlueprint, required this.value, required this.onChanged, }); final String path; - final EnumField field; + final EnumBlueprint enumBlueprint; final String value; final Function(String) onChanged; @@ -273,7 +273,7 @@ class _EnumKey extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { return EnumEditor( path: path, - field: field, + enumBlueprint: enumBlueprint, forcedValue: value, icon: TWIcons.key, onChanged: onChanged, @@ -284,12 +284,12 @@ class _EnumKey extends HookConsumerWidget { class _EntryKey extends HookConsumerWidget { const _EntryKey({ required this.path, - required this.field, + required this.dataBlueprint, required this.value, required this.onChanged, }); final String path; - final FieldInfo field; + final DataBlueprint dataBlueprint; final String value; final Function(String) onChanged; @@ -297,7 +297,7 @@ class _EntryKey extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { return EntrySelectorEditor( path: path, - field: field, + dataBlueprint: dataBlueprint, forcedValue: value, onChanged: onChanged, ); diff --git a/app/lib/widgets/inspector/editors/material.dart b/app/lib/widgets/inspector/editors/material.dart index 8253909eba..46932f0398 100644 --- a/app/lib/widgets/inspector/editors/material.dart +++ b/app/lib/widgets/inspector/editors/material.dart @@ -4,7 +4,7 @@ import "package:flutter/services.dart"; import "package:fuzzy/fuzzy.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/materials.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/icons.dart"; @@ -184,22 +184,24 @@ extension _SearchBuilderX on SearchBuilder { class MaterialEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "material"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "material"; @override - Widget build(String path, FieldInfo info) => - MaterialEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => MaterialEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class MaterialEditor extends HookConsumerWidget { const MaterialEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }) : super(); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; bool? _update(WidgetRef ref, String value) { ref @@ -218,7 +220,8 @@ class MaterialEditor extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final value = ref.watch(fieldValueProvider(path, "")); - final propertiesModifier = field.getModifier("material_properties"); + final propertiesModifier = + customBlueprint.getModifier("material_properties"); final properties = propertiesModifier != null ? ref.watch(materialPropertiesProvider(propertiesModifier.data)) : []; diff --git a/app/lib/widgets/inspector/editors/number.dart b/app/lib/widgets/inspector/editors/number.dart index fa6f6fbc42..31cce2f4de 100644 --- a/app/lib/widgets/inspector/editors/number.dart +++ b/app/lib/widgets/inspector/editors/number.dart @@ -2,7 +2,7 @@ import "package:flutter/material.dart"; import "package:flutter/services.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -14,24 +14,26 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class NumberEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is PrimitiveField && - (info.type == PrimitiveFieldType.integer || - info.type == PrimitiveFieldType.double); + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is PrimitiveBlueprint && + (dataBlueprint.type == PrimitiveType.integer || + dataBlueprint.type == PrimitiveType.double); @override - Widget build(String path, FieldInfo info) => - NumberEditor(path: path, field: info as PrimitiveField); + Widget build(String path, DataBlueprint dataBlueprint) => NumberEditor( + path: path, + primitiveBlueprint: dataBlueprint as PrimitiveBlueprint, + ); } class NumberEditor extends HookConsumerWidget { const NumberEditor({ required this.path, - required this.field, + required this.primitiveBlueprint, super.key, }) : super(); final String path; - final PrimitiveField field; + final PrimitiveBlueprint primitiveBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { @@ -40,7 +42,8 @@ class NumberEditor extends HookConsumerWidget { final value = ref.watch(fieldValueProvider(path, 0)); - final isNegativeAllowed = field.get("negative") as bool? ?? true; + final isNegativeAllowed = + primitiveBlueprint.get("negative") as bool? ?? true; return WritersIndicator( provider: fieldWritersProvider(path), @@ -48,24 +51,24 @@ class NumberEditor extends HookConsumerWidget { child: FormattedTextField( focus: focus, icon: TWIcons.hashtag, - hintText: "Enter a ${field.type.name}", + hintText: "Enter a ${primitiveBlueprint.type.name}", text: "$value", keyboardType: TextInputType.number, inputFormatters: [ if (!isNegativeAllowed) ...[ - if (field.type == PrimitiveFieldType.integer) + if (primitiveBlueprint.type == PrimitiveType.integer) FilteringTextInputFormatter.digitsOnly, - if (field.type == PrimitiveFieldType.double) + if (primitiveBlueprint.type == PrimitiveType.double) FilteringTextInputFormatter.allow(RegExp(r"^\d+\.?\d*")), ] else ...[ - if (field.type == PrimitiveFieldType.integer) + if (primitiveBlueprint.type == PrimitiveType.integer) FilteringTextInputFormatter.allow(RegExp(r"^-?\d*")), - if (field.type == PrimitiveFieldType.double) + if (primitiveBlueprint.type == PrimitiveType.double) FilteringTextInputFormatter.allow(RegExp(r"^-?\d*\.?\d*")), ], ], onChanged: (value) { - final number = field.type == PrimitiveFieldType.integer + final number = primitiveBlueprint.type == PrimitiveType.integer ? int.tryParse(value) : double.tryParse(value); ref diff --git a/app/lib/widgets/inspector/editors/object.dart b/app/lib/widgets/inspector/editors/object.dart index 4afa2bab28..df3fb96f63 100644 --- a/app/lib/widgets/inspector/editors/object.dart +++ b/app/lib/widgets/inspector/editors/object.dart @@ -1,69 +1,70 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/editors/field.dart"; import "package:typewriter/widgets/inspector/header.dart"; class ObjectEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => info is ObjectField; + bool canEdit(DataBlueprint dataBlueprint) => dataBlueprint is ObjectBlueprint; @override - Widget build(String path, FieldInfo info) => - ObjectEditor(path: path, object: info as ObjectField); + Widget build(String path, DataBlueprint dataBlueprint) => ObjectEditor( + path: path, + objectBlueprint: dataBlueprint as ObjectBlueprint, + ); } class ObjectEditor extends HookConsumerWidget { const ObjectEditor({ required this.path, - required this.object, + required this.objectBlueprint, this.ignoreFields = const [], this.defaultExpanded = false, super.key, }) : super(); final String path; - final ObjectField object; + final ObjectBlueprint objectBlueprint; final List ignoreFields; final bool defaultExpanded; @override Widget build(BuildContext context, WidgetRef ref) { return FieldHeader( - field: object, path: path, + dataBlueprint: objectBlueprint, canExpand: true, defaultExpanded: defaultExpanded, - child: Padding( - padding: const EdgeInsets.only(bottom: 4), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - for (final field in object.fields.entries) - if (!ignoreFields.contains(field.key)) ...[ - const SizedBox(height: 12), - if (!field.value.hasCustomLayout) - FieldHeader( - field: field.value, - path: path.isNotEmpty ? "$path.${field.key}" : field.key, - child: buildFieldEditor(field), - ) - else - buildFieldEditor(field), - ], - ], - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 12, + children: [ + for (final fieldBlueprint in objectBlueprint.fields.entries) + if (!ignoreFields.contains(fieldBlueprint.key)) ...[ + if (!fieldBlueprint.value.hasCustomLayout) + FieldHeader( + dataBlueprint: fieldBlueprint.value, + path: path.isNotEmpty + ? "$path.${fieldBlueprint.key}" + : fieldBlueprint.key, + child: buildFieldEditor(fieldBlueprint), + ) + else + buildFieldEditor(fieldBlueprint), + ], + ], ), ); } - FieldEditor buildFieldEditor(MapEntry field) { + FieldEditor buildFieldEditor(MapEntry field) { return FieldEditor( key: ValueKey( path.isNotEmpty ? "$path.${field.key}" : field.key, ), path: path.isNotEmpty ? "$path.${field.key}" : field.key, - type: field.value, + dataBlueprint: field.value, ); } } diff --git a/app/lib/widgets/inspector/editors/optional.dart b/app/lib/widgets/inspector/editors/optional.dart index d2186a997d..9a2ab67dc5 100644 --- a/app/lib/widgets/inspector/editors/optional.dart +++ b/app/lib/widgets/inspector/editors/optional.dart @@ -1,7 +1,8 @@ import "package:flutter/material.dart"; import "package:flutter_animate/flutter_animate.dart"; +import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/color_filter.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/inspector/editors.dart"; @@ -11,30 +12,39 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class OptionalEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "optional"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "optional"; @override - Widget build(String path, FieldInfo info) => - OptionalEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => OptionalEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class OptionalEditor extends HookConsumerWidget { const OptionalEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; + + DataBlueprint? get subDataBlueprint { + final shape = customBlueprint.shape; + if (shape is! ObjectBlueprint) return null; + if (!shape.fields.containsKey("value")) return null; + return shape.fields["value"]; + } @override Widget build(BuildContext context, WidgetRef ref) { final enabled = ref.watch(fieldValueProvider("$path.enabled", false)); - final subField = field.fieldInfo; - if (subField == null) { + final subDataBlueprint = useMemoized(() => this.subDataBlueprint); + if (subDataBlueprint == null) { return Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( @@ -51,31 +61,31 @@ class OptionalEditor extends HookConsumerWidget { final subPath = "$path.value"; final headerActionFilters = ref.watch(headerActionFiltersProvider); final subFieldActions = headerActionFilters - .where((filter) => filter.shouldShow(subPath, subField)) + .where((filter) => filter.shouldShow(subPath, subDataBlueprint)) .toList(); return FieldHeader( - field: field, path: path, + dataBlueprint: customBlueprint, leading: _buildActions( HeaderActionLocation.leading, subFieldActions, subPath, - subField, + subDataBlueprint, enabled: enabled, ), trailing: _buildActions( HeaderActionLocation.trailing, subFieldActions, subPath, - subField, + subDataBlueprint, enabled: enabled, ), actions: _buildActions( HeaderActionLocation.actions, subFieldActions, subPath, - subField, + subDataBlueprint, enabled: enabled, ), child: Row( @@ -100,7 +110,7 @@ class OptionalEditor extends HookConsumerWidget { absorbing: !enabled, child: FieldEditor( path: "$path.value", - type: subField, + dataBlueprint: subDataBlueprint, ), ), ), @@ -115,12 +125,12 @@ class OptionalEditor extends HookConsumerWidget { HeaderActionLocation location, List actions, String path, - FieldInfo field, { + DataBlueprint dataBlueprint, { bool enabled = true, }) { final children = actions - .where((action) => action.location(path, field) == location) - .map((action) => action.build(path, field)) + .where((action) => action.location(path, dataBlueprint) == location) + .map((action) => action.build(path, dataBlueprint)) .toList(); if (enabled) { return children; diff --git a/app/lib/widgets/inspector/editors/page_selector.dart b/app/lib/widgets/inspector/editors/page_selector.dart index 2fcac11a21..5b8a07d773 100644 --- a/app/lib/widgets/inspector/editors/page_selector.dart +++ b/app/lib/widgets/inspector/editors/page_selector.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart" hide Page; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:typewriter/app_router.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/pages/pages_list.dart"; import "package:typewriter/utils/extensions.dart"; @@ -15,19 +15,33 @@ import "package:typewriter/widgets/components/general/iconify.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/inspector.dart"; +class PageSelectorEditorFilter extends EditorFilter { + @override + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is PrimitiveBlueprint && + dataBlueprint.type == PrimitiveType.string && + dataBlueprint.hasModifier("page"); + + @override + Widget build(String path, DataBlueprint dataBlueprint) => PageSelectorEditor( + path: path, + primitiveBlueprint: dataBlueprint as PrimitiveBlueprint, + ); +} + class PageSelectorEditor extends HookConsumerWidget { const PageSelectorEditor({ required this.path, - required this.field, + required this.primitiveBlueprint, super.key, }); final String path; - final PrimitiveField field; + final PrimitiveBlueprint primitiveBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { - final typeTag = field.get("page"); + final typeTag = primitiveBlueprint.get("page"); final type = typeTag == null ? null : PageType.fromName(typeTag); if (type == null) { @@ -197,23 +211,11 @@ class PageSelectorEditor extends HookConsumerWidget { if (page == null) return false; ref .read(inspectingEntryDefinitionProvider) - ?.updateField(ref, path, page.pageName); + ?.updateField(ref, path, page.id); return true; } } -class PageSelectorEditorFilter extends EditorFilter { - @override - Widget build(String path, FieldInfo info) => - PageSelectorEditor(path: path, field: info as PrimitiveField); - - @override - bool canEdit(FieldInfo info) => - info is PrimitiveField && - info.type == PrimitiveFieldType.string && - info.hasModifier("page"); -} - class _SelectedPage extends HookConsumerWidget { const _SelectedPage({ required this.id, diff --git a/app/lib/widgets/inspector/editors/potion_effect.dart b/app/lib/widgets/inspector/editors/potion_effect.dart index 71a08781d5..db20e7343d 100644 --- a/app/lib/widgets/inspector/editors/potion_effect.dart +++ b/app/lib/widgets/inspector/editors/potion_effect.dart @@ -5,7 +5,7 @@ import "package:fuzzy/fuzzy.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; import "package:typewriter/main.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/potion_effects.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/icons.dart"; @@ -150,22 +150,26 @@ extension PotionEffectSearchBuilderX on SearchBuilder { class PotionEffectEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "potionEffectType"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && + dataBlueprint.editor == "potionEffectType"; + @override - Widget build(String path, FieldInfo info) => - PotionEffectEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => PotionEffectEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class PotionEffectEditor extends HookConsumerWidget { const PotionEffectEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; bool? _update(WidgetRef ref, String value) { ref diff --git a/app/lib/widgets/inspector/editors/skin.dart b/app/lib/widgets/inspector/editors/skin.dart index 0c676e63fd..06a72c8142 100644 --- a/app/lib/widgets/inspector/editors/skin.dart +++ b/app/lib/widgets/inspector/editors/skin.dart @@ -4,7 +4,7 @@ import "package:flutter/material.dart" hide FilledButton; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:http/http.dart" as http; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -21,22 +21,23 @@ import "package:typewriter/widgets/inspector/section_title.dart"; class SkinEditorFilter extends EditorFilter { @override - Widget build(String path, FieldInfo info) => - SkinEditor(path: path, field: info as CustomField); + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "skin"; @override - bool canEdit(FieldInfo info) => info is CustomField && info.editor == "skin"; + Widget build(String path, DataBlueprint dataBlueprint) => + SkinEditor(path: path, customBlueprint: dataBlueprint as CustomBlueprint); } class SkinEditor extends HookConsumerWidget { const SkinEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; String? _getSkinUrl(String textureData) { if (textureData.isEmpty) return null; @@ -61,7 +62,7 @@ class SkinEditor extends HookConsumerWidget { final url = useMemoized(() => _getSkinUrl(texture), [texture]); return FieldHeader( path: path, - field: field, + dataBlueprint: customBlueprint, canExpand: true, actions: [ HeaderButton( @@ -136,14 +137,16 @@ class SkinEditor extends HookConsumerWidget { const SizedBox(height: 8), StringEditor( path: "$path.texture", - field: const PrimitiveField(type: PrimitiveFieldType.string), + primitiveBlueprint: + const PrimitiveBlueprint(type: PrimitiveType.string), ), const SizedBox(height: 8), const SectionTitle(title: "Signature"), const SizedBox(height: 8), StringEditor( path: "$path.signature", - field: const PrimitiveField(type: PrimitiveFieldType.string), + primitiveBlueprint: + const PrimitiveBlueprint(type: PrimitiveType.string), ), ], ), diff --git a/app/lib/widgets/inspector/editors/sound_id.dart b/app/lib/widgets/inspector/editors/sound_id.dart index b9d626bef6..b511c6d723 100644 --- a/app/lib/widgets/inspector/editors/sound_id.dart +++ b/app/lib/widgets/inspector/editors/sound_id.dart @@ -7,7 +7,7 @@ import "package:flutter_hooks/flutter_hooks.dart"; import "package:fuzzy/fuzzy.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/sound.dart"; import "package:typewriter/models/sounds.dart"; import "package:typewriter/utils/audio_player.dart"; @@ -241,23 +241,25 @@ extension _SearchBuilderX on SearchBuilder { class SoundIdEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "soundId"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "soundId"; @override - Widget build(String path, FieldInfo info) => - SoundSelectorEditor(path: path, field: info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => SoundSelectorEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class SoundSelectorEditor extends HookConsumerWidget { const SoundSelectorEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - final CustomField field; + final CustomBlueprint customBlueprint; bool? _update(PassingRef ref, SoundId soundId) { ref diff --git a/app/lib/widgets/inspector/editors/sound_source.dart b/app/lib/widgets/inspector/editors/sound_source.dart index 0d93c6025e..cc23d7d625 100644 --- a/app/lib/widgets/inspector/editors/sound_source.dart +++ b/app/lib/widgets/inspector/editors/sound_source.dart @@ -1,7 +1,7 @@ import "package:flutter/cupertino.dart"; import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/passing_reference.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/editors/entry_selector.dart"; @@ -10,17 +10,30 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class SoundSourceEditorFilter extends EditorFilter { @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "soundSource"; + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "soundSource"; @override - Widget build(String path, FieldInfo info) => - SoundSourceEditor(path, info as CustomField); + Widget build(String path, DataBlueprint dataBlueprint) => SoundSourceEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class SoundSourceEditor extends HookConsumerWidget { - const SoundSourceEditor(this.path, this.info, {super.key}); + const SoundSourceEditor({ + required this.path, + required this.customBlueprint, + super.key, + }); final String path; - final CustomField info; + final CustomBlueprint customBlueprint; + + DataBlueprint? get locationShape { + final shape = customBlueprint.shape; + if (shape is! ObjectBlueprint) return null; + if (!shape.fields.containsKey("location")) return null; + return shape.fields["location"]; + } @override Widget build(BuildContext context, WidgetRef ref) { @@ -49,17 +62,19 @@ class SoundSourceEditor extends HookConsumerWidget { if (sourceType == SoundSourceType.emitter) EntrySelectorEditor( path: "$path.entryId", - field: const PrimitiveField( - type: PrimitiveFieldType.string, + dataBlueprint: const PrimitiveBlueprint( + type: PrimitiveType.string, modifiers: [Modifier(name: "entry", data: "sound_source")], ), ), if (sourceType == SoundSourceType.location) - LocationEditor( + PositionEditor( path: "$path.location", - field: CustomField( + customBlueprint: CustomBlueprint( editor: "location", - defaultValue: info.defaultValue["location"] ?? {}, + internalDefaultValue: + customBlueprint.defaultValue()["location"] ?? {}, + shape: locationShape!, ), ), ], diff --git a/app/lib/widgets/inspector/editors/string.dart b/app/lib/widgets/inspector/editors/string.dart index aa65341282..1d19655200 100644 --- a/app/lib/widgets/inspector/editors/string.dart +++ b/app/lib/widgets/inspector/editors/string.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/icons.dart"; @@ -14,18 +14,21 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class StringEditorFilter extends EditorFilter { @override - Widget build(String path, FieldInfo info) => - StringEditor(path: path, field: info as PrimitiveField); + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is PrimitiveBlueprint && + dataBlueprint.type == PrimitiveType.string; @override - bool canEdit(FieldInfo info) => - info is PrimitiveField && info.type == PrimitiveFieldType.string; + Widget build(String path, DataBlueprint dataBlueprint) => StringEditor( + path: path, + primitiveBlueprint: dataBlueprint as PrimitiveBlueprint, + ); } class StringEditor extends HookConsumerWidget { const StringEditor({ required this.path, - required this.field, + required this.primitiveBlueprint, this.forcedValue, this.icon = TWIcons.pencil, this.hint = "", @@ -34,7 +37,7 @@ class StringEditor extends HookConsumerWidget { }) : super(); final String path; - final PrimitiveField field; + final PrimitiveBlueprint primitiveBlueprint; final String? forcedValue; final String icon; @@ -47,7 +50,7 @@ class StringEditor extends HookConsumerWidget { useFocusedBasedCurrentEditingField(focus, ref.passing, path); final value = ref.watch(fieldValueProvider(path, "")); - final singleLine = !field.hasModifier("multiline"); + final singleLine = !primitiveBlueprint.hasModifier("multiline"); return WritersIndicator( provider: fieldWritersProvider(path, exact: true), @@ -55,12 +58,14 @@ class StringEditor extends HookConsumerWidget { child: FormattedTextField( focus: focus, icon: icon, - hintText: hint.isNotEmpty ? hint : "Enter a ${field.type.name}", + hintText: + hint.isNotEmpty ? hint : "Enter a ${primitiveBlueprint.type.name}", text: forcedValue ?? value, singleLine: singleLine, keyboardType: singleLine ? TextInputType.text : TextInputType.multiline, inputFormatters: [ - if (field.hasModifier("snake_case")) snakeCaseFormatter(), + if (primitiveBlueprint.hasModifier("snake_case")) + snakeCaseFormatter(), ], onChanged: onChanged ?? (value) => ref diff --git a/app/lib/widgets/inspector/editors/vector.dart b/app/lib/widgets/inspector/editors/vector.dart index 7c0d633545..f71ddc8f06 100644 --- a/app/lib/widgets/inspector/editors/vector.dart +++ b/app/lib/widgets/inspector/editors/vector.dart @@ -1,28 +1,29 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/widgets/components/app/cord_property.dart"; import "package:typewriter/widgets/inspector/editors.dart"; class VectorEditorFilter extends EditorFilter { @override - Widget build(String path, FieldInfo info) => - VectorEditor(path: path, field: info as CustomField); + bool canEdit(DataBlueprint dataBlueprint) => + dataBlueprint is CustomBlueprint && dataBlueprint.editor == "vector"; @override - bool canEdit(FieldInfo info) => - info is CustomField && info.editor == "vector"; + Widget build(String path, DataBlueprint dataBlueprint) => VectorEditor( + path: path, + customBlueprint: dataBlueprint as CustomBlueprint, + ); } class VectorEditor extends HookConsumerWidget { const VectorEditor({ required this.path, - required this.field, + required this.customBlueprint, super.key, }); final String path; - - final CustomField field; + final CustomBlueprint customBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { diff --git a/app/lib/widgets/inspector/header.dart b/app/lib/widgets/inspector/header.dart index 75b70ce54d..cdbc5664d5 100644 --- a/app/lib/widgets/inspector/header.dart +++ b/app/lib/widgets/inspector/header.dart @@ -3,7 +3,7 @@ import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/writers.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/widgets/components/app/writers.dart"; @@ -21,7 +21,7 @@ part "header.g.dart"; class FieldHeader extends HookConsumerWidget { const FieldHeader({ required this.child, - required this.field, + required this.dataBlueprint, required this.path, this.leading = const [], this.trailing = const [], @@ -32,7 +32,7 @@ class FieldHeader extends HookConsumerWidget { }) : super(); final Widget child; - final FieldInfo field; + final DataBlueprint dataBlueprint; final String path; final List leading; @@ -52,7 +52,7 @@ class FieldHeader extends HookConsumerWidget { final headerActionFilters = ref.watch(headerActionFiltersProvider); final availableActions = headerActionFilters - .where((filter) => filter.shouldShow(path, field)) + .where((filter) => filter.shouldShow(path, dataBlueprint)) .toList(); final name = ref.watch(pathDisplayNameProvider(path)).nullIfEmpty ?? "Fields"; @@ -104,8 +104,12 @@ class FieldHeader extends HookConsumerWidget { availableActions, HeaderActionLocation.leading, ), - SectionTitle( - title: name, + Padding( + padding: + EdgeInsets.symmetric(vertical: canExpand ? 10 : 0), + child: SectionTitle( + title: name, + ), ), ...createActions( availableActions, @@ -147,7 +151,8 @@ class FieldHeader extends HookConsumerWidget { if (location == HeaderActionLocation.leading) ...leading, if (location == HeaderActionLocation.trailing) ...trailing, for (final filter in filters) - if (filter.location(path, field) == location) filter.build(path, field), + if (filter.location(path, dataBlueprint) == location) + filter.build(path, dataBlueprint), if (location == HeaderActionLocation.actions) ...actions, ].joinWith(() => const SizedBox(width: 8)); @@ -196,10 +201,10 @@ List headerActionFilters(HeaderActionFiltersRef ref) => [ ]; abstract class HeaderActionFilter { - bool shouldShow(String path, FieldInfo field); + bool shouldShow(String path, DataBlueprint dataBlueprint); - HeaderActionLocation location(String path, FieldInfo field); - Widget build(String path, FieldInfo field); + HeaderActionLocation location(String path, DataBlueprint dataBlueprint); + Widget build(String path, DataBlueprint dataBlueprint); } enum HeaderActionLocation { diff --git a/app/lib/widgets/inspector/headers/colored_action.dart b/app/lib/widgets/inspector/headers/colored_action.dart index 108eae9a79..33d6cb5ae3 100644 --- a/app/lib/widgets/inspector/headers/colored_action.dart +++ b/app/lib/widgets/inspector/headers/colored_action.dart @@ -1,31 +1,31 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/widgets/inspector/header.dart"; import "package:typewriter/widgets/inspector/headers/info_action.dart"; class ColoredHeaderActionFilter extends HeaderActionFilter { @override - bool shouldShow(String path, FieldInfo field) => - field.getModifier("colored") != null; + bool shouldShow(String path, DataBlueprint dataBlueprint) => + dataBlueprint.getModifier("colored") != null; @override - HeaderActionLocation location(String path, FieldInfo field) => + HeaderActionLocation location(String path, DataBlueprint dataBlueprint) => HeaderActionLocation.trailing; @override - Widget build(String path, FieldInfo field) => - ColoredHeaderAction(field: field); + Widget build(String path, DataBlueprint dataBlueprint) => + ColoredHeaderAction(dataBlueprint: dataBlueprint); } class ColoredHeaderAction extends HookConsumerWidget { const ColoredHeaderAction({ - required this.field, + required this.dataBlueprint, super.key, }) : super(); - final FieldInfo field; + final DataBlueprint dataBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { diff --git a/app/lib/widgets/inspector/headers/content_mode_action.dart b/app/lib/widgets/inspector/headers/content_mode_action.dart index f48c1aa6a0..667c5308ca 100644 --- a/app/lib/widgets/inspector/headers/content_mode_action.dart +++ b/app/lib/widgets/inspector/headers/content_mode_action.dart @@ -1,7 +1,7 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/communicator.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/segment.dart"; import "package:typewriter/models/staging.dart"; import "package:typewriter/pages/page_editor.dart"; @@ -16,31 +16,31 @@ import "package:typewriter/widgets/inspector/inspector.dart"; class ContentModeHeaderActionFilter extends HeaderActionFilter { @override - bool shouldShow(String path, FieldInfo field) => - (field.getModifier("contentMode")?.data as String?) != null; + bool shouldShow(String path, DataBlueprint dataBlueprint) => + (dataBlueprint.getModifier("contentMode")?.data as String?) != null; @override - HeaderActionLocation location(String path, FieldInfo field) => + HeaderActionLocation location(String path, DataBlueprint dataBlueprint) => HeaderActionLocation.actions; @override - Widget build(String path, FieldInfo field) => - ContentModeHeaderAction(path, field); + Widget build(String path, DataBlueprint dataBlueprint) => + ContentModeHeaderAction(path: path, dataBlueprint: dataBlueprint); } class ContentModeHeaderAction extends HookConsumerWidget { - const ContentModeHeaderAction( - this.path, - this.field, { + const ContentModeHeaderAction({ + required this.path, + required this.dataBlueprint, super.key, }); final String path; - final FieldInfo field; + final DataBlueprint dataBlueprint; Future _requestContentMode(PassingRef ref, Header? header) async { final contentModeClassPath = - field.getModifier("contentMode")?.data as String?; + dataBlueprint.getModifier("contentMode")?.data as String?; if (contentModeClassPath == null) return; /// ------- Entry ID ------- diff --git a/app/lib/widgets/inspector/headers/duplicate_list_item_action.dart b/app/lib/widgets/inspector/headers/duplicate_list_item_action.dart index 403a5ceff5..a51e9d8f87 100644 --- a/app/lib/widgets/inspector/headers/duplicate_list_item_action.dart +++ b/app/lib/widgets/inspector/headers/duplicate_list_item_action.dart @@ -1,6 +1,6 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -9,20 +9,21 @@ import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/inspector.dart"; class DuplicateListItemAction extends HookConsumerWidget { - const DuplicateListItemAction( - this.parentPath, - this.path, - this.field, { + const DuplicateListItemAction({ + required this.parentPath, + required this.path, + required this.dataBlueprint, super.key, }); final String parentPath; final String path; - final FieldInfo field; + final DataBlueprint dataBlueprint; void _duplicate(PassingRef ref) { final parentValue = ref.read(fieldValueProvider(parentPath, [])); - final value = ref.read(fieldValueProvider(path, field.defaultValue)); + final value = + ref.read(fieldValueProvider(path, dataBlueprint.defaultValue())); ref.read(inspectingEntryDefinitionProvider)?.updateField( ref, diff --git a/app/lib/widgets/inspector/headers/help_action.dart b/app/lib/widgets/inspector/headers/help_action.dart index 934cd8e987..1052e0c7f3 100644 --- a/app/lib/widgets/inspector/headers/help_action.dart +++ b/app/lib/widgets/inspector/headers/help_action.dart @@ -1,32 +1,33 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/widgets/inspector/header.dart"; class HelpHeaderActionFilter extends HeaderActionFilter { @override - bool shouldShow(String path, FieldInfo field) => - (field.getModifier("help")?.data as String?) != null; + bool shouldShow(String path, DataBlueprint dataBlueprint) => + (dataBlueprint.getModifier("help")?.data as String?) != null; @override - HeaderActionLocation location(String path, FieldInfo field) => + HeaderActionLocation location(String path, DataBlueprint dataBlueprint) => HeaderActionLocation.trailing; @override - Widget build(String path, FieldInfo field) => HelpHeaderAction(field: field); + Widget build(String path, DataBlueprint dataBlueprint) => + HelpHeaderAction(dataBlueprint: dataBlueprint); } class HelpHeaderAction extends HookConsumerWidget { const HelpHeaderAction({ - required this.field, + required this.dataBlueprint, super.key, }); - final FieldInfo field; + final DataBlueprint dataBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { - final help = field.getModifier("help"); + final help = dataBlueprint.getModifier("help"); final helpText = help?.data as String?; if (helpText == null) { return const SizedBox(); diff --git a/app/lib/widgets/inspector/headers/length_action.dart b/app/lib/widgets/inspector/headers/length_action.dart index ec652ba585..ebef9e47f9 100644 --- a/app/lib/widgets/inspector/headers/length_action.dart +++ b/app/lib/widgets/inspector/headers/length_action.dart @@ -1,32 +1,33 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/widgets/inspector/editors.dart"; import "package:typewriter/widgets/inspector/header.dart"; class LengthHeaderActionFilter extends HeaderActionFilter { @override - bool shouldShow(String path, FieldInfo field) { - return field is ListField || field is MapField; + bool shouldShow(String path, DataBlueprint dataBlueprint) { + return dataBlueprint is ListBlueprint || dataBlueprint is MapBlueprint; } @override - HeaderActionLocation location(String path, FieldInfo field) => + HeaderActionLocation location(String path, DataBlueprint dataBlueprint) => HeaderActionLocation.trailing; @override - Widget build(String path, FieldInfo field) => LengthHeaderAction(path, field); + Widget build(String path, DataBlueprint dataBlueprint) => + LengthHeaderAction(path: path, dataBlueprint: dataBlueprint); } class LengthHeaderAction extends HookConsumerWidget { - const LengthHeaderAction( - this.path, - this.field, { + const LengthHeaderAction({ + required this.path, + required this.dataBlueprint, super.key, }); final String path; - final FieldInfo field; + final DataBlueprint dataBlueprint; @override Widget build(BuildContext context, WidgetRef ref) { diff --git a/app/lib/widgets/inspector/headers/placeholder_action.dart b/app/lib/widgets/inspector/headers/placeholder_action.dart index 9ed676b6c8..72f491caf5 100644 --- a/app/lib/widgets/inspector/headers/placeholder_action.dart +++ b/app/lib/widgets/inspector/headers/placeholder_action.dart @@ -1,21 +1,22 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/widgets/inspector/header.dart"; import "package:typewriter/widgets/inspector/headers/info_action.dart"; class PlaceholderHeaderActionFilter extends HeaderActionFilter { @override - bool shouldShow(String path, FieldInfo field) => - field.getModifier("placeholder") != null; + bool shouldShow(String path, DataBlueprint dataBlueprint) => + dataBlueprint.getModifier("placeholder") != null; @override - HeaderActionLocation location(String path, FieldInfo field) => + HeaderActionLocation location(String path, DataBlueprint dataBlueprint) => HeaderActionLocation.trailing; @override - Widget build(String path, FieldInfo field) => const PlaceholderHeaderAction(); + Widget build(String path, DataBlueprint dataBlueprint) => + const PlaceholderHeaderAction(); } class PlaceholderHeaderAction extends HookConsumerWidget { diff --git a/app/lib/widgets/inspector/headers/regex_action.dart b/app/lib/widgets/inspector/headers/regex_action.dart index 5b8ba4fb9f..43241b5fe4 100644 --- a/app/lib/widgets/inspector/headers/regex_action.dart +++ b/app/lib/widgets/inspector/headers/regex_action.dart @@ -1,21 +1,22 @@ import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/icons.dart"; import "package:typewriter/widgets/inspector/header.dart"; import "package:typewriter/widgets/inspector/headers/info_action.dart"; class RegexHeaderActionFilter extends HeaderActionFilter { @override - bool shouldShow(String path, FieldInfo field) => - field.getModifier("regex") != null; + bool shouldShow(String path, DataBlueprint dataBlueprint) => + dataBlueprint.getModifier("regex") != null; @override - HeaderActionLocation location(String path, FieldInfo field) => + HeaderActionLocation location(String path, DataBlueprint dataBlueprint) => HeaderActionLocation.trailing; @override - Widget build(String path, FieldInfo field) => const RegexHeaderInfo(); + Widget build(String path, DataBlueprint dataBlueprint) => + const RegexHeaderInfo(); } class RegexHeaderInfo extends HookConsumerWidget { diff --git a/app/lib/widgets/inspector/heading.dart b/app/lib/widgets/inspector/heading.dart index f0ba9fe045..4a3039d5f7 100644 --- a/app/lib/widgets/inspector/heading.dart +++ b/app/lib/widgets/inspector/heading.dart @@ -3,8 +3,8 @@ import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/utils/extensions.dart"; import "package:typewriter/widgets/components/general/admonition.dart"; import "package:typewriter/widgets/inspector/inspector.dart"; @@ -27,7 +27,7 @@ String _entryName(_EntryNameRef ref) { @riverpod String _entryType(_EntryTypeRef ref) { final def = ref.watch(inspectingEntryDefinitionProvider); - return def?.blueprint.name ?? ""; + return def?.blueprint.id ?? ""; } @riverpod @@ -70,7 +70,7 @@ class Heading extends HookConsumerWidget { direction: Axis.horizontal, alignment: WrapAlignment.start, children: [ - EntryType(type: type, url: url, color: color), + EntryBlueprintDisplay(blueprintId: type, url: url, color: color), EntryIdentifier(id: id), ], ), @@ -129,14 +129,14 @@ class EntryIdentifier extends StatelessWidget { } } -class EntryType extends HookWidget { - const EntryType({ - required this.type, +class EntryBlueprintDisplay extends HookConsumerWidget { + const EntryBlueprintDisplay({ + required this.blueprintId, required this.url, required this.color, super.key, }); - final String type; + final String blueprintId; final String url; final Color color; @@ -147,7 +147,11 @@ class EntryType extends HookWidget { } @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { + final blueprintName = + ref.watch(entryBlueprintProvider(blueprintId).select((e) => e?.name)); + if (blueprintName == null) return const SizedBox(); + final hovering = useState(false); return MouseRegion( cursor: SystemMouseCursors.click, @@ -156,7 +160,7 @@ class EntryType extends HookWidget { child: GestureDetector( onTap: url.isNotEmpty ? _launceUrl : null, child: Text( - type.formatted, + blueprintName.formatted, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: color.withOpacity(0.9), decoration: hovering.value ? TextDecoration.underline : null, diff --git a/app/lib/widgets/inspector/heading.g.dart b/app/lib/widgets/inspector/heading.g.dart index 44e32c8cc4..d27d2c0516 100644 --- a/app/lib/widgets/inspector/heading.g.dart +++ b/app/lib/widgets/inspector/heading.g.dart @@ -34,7 +34,7 @@ final _entryNameProvider = AutoDisposeProvider.internal( ); typedef _EntryNameRef = AutoDisposeProviderRef; -String _$entryTypeHash() => r'bd6249329b29f059236a50796065cf9ed6b51b5c'; +String _$entryTypeHash() => r'b8db383dacb169526f823865fb2c90e478a4b4ee'; /// See also [_entryType]. @ProviderFor(_entryType) diff --git a/app/lib/widgets/inspector/inspector.dart b/app/lib/widgets/inspector/inspector.dart index 0950b80137..e752fb6079 100644 --- a/app/lib/widgets/inspector/inspector.dart +++ b/app/lib/widgets/inspector/inspector.dart @@ -120,11 +120,13 @@ class EntryInspector extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final object = ref.watch( - inspectingEntryDefinitionProvider.select((def) => def?.blueprint.fields), + final objectBlueprint = ref.watch( + inspectingEntryDefinitionProvider.select( + (def) => def?.blueprint.dataBlueprint, + ), ); - if (object == null) { + if (objectBlueprint == null) { return const NoBlueprintEntryInspector(); } @@ -139,7 +141,7 @@ class EntryInspector extends HookConsumerWidget { const Divider(), ObjectEditor( path: "", - object: object, + objectBlueprint: objectBlueprint, ignoreFields: ["id", "name", ...ignoreFields], defaultExpanded: true, ), @@ -181,7 +183,11 @@ class NoBlueprintEntryInspector extends HookConsumerWidget { direction: Axis.horizontal, alignment: WrapAlignment.start, children: [ - EntryType(type: entry.type, url: "", color: Colors.redAccent), + EntryBlueprintDisplay( + blueprintId: entry.blueprintId, + url: "", + color: Colors.redAccent, + ), EntryIdentifier(id: entry.id), ], ), @@ -190,11 +196,11 @@ class NoBlueprintEntryInspector extends HookConsumerWidget { """ |The blueprint for this entry does not exist. | - |This can happen if the adapter for this entry is no longer installed. - |Or if the adapter removed the entry type. + |This can happen if the extension for this entry is no longer installed. + |Or if the extension removed the entry type. | |To fix this, you can either: - | - Install the adapter again. + | - Install the extension again. | - Remove the entry. """ .trimMargin(), diff --git a/app/lib/widgets/inspector/operations.dart b/app/lib/widgets/inspector/operations.dart index 13ccc83239..3940fcb559 100644 --- a/app/lib/widgets/inspector/operations.dart +++ b/app/lib/widgets/inspector/operations.dart @@ -23,8 +23,6 @@ class Operations extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final type = ref.watch(inspectingEntryProvider.select((e) => e?.type)); - if (type == null) return const SizedBox(); final entryId = ref.read(inspectingEntryIdProvider); if (entryId == null) return const SizedBox(); final linkablePaths = ref.watch(linkablePathsProvider(entryId)); diff --git a/app/macos/Runner/AppDelegate.swift b/app/macos/Runner/AppDelegate.swift index 8e02df2888..b3c1761412 100644 --- a/app/macos/Runner/AppDelegate.swift +++ b/app/macos/Runner/AppDelegate.swift @@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/app/macos/RunnerTests/RunnerTests.swift b/app/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000000..61f3bd1fc5 --- /dev/null +++ b/app/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/app/pubspec.lock b/app/pubspec.lock index 794c7bf2f9..590123584f 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -5,18 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: "45cfa8471b89fb6643fe9bf51bd7931a76b8f5ec2d65de4fb176dba8d4f22c77" url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "73.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: "4959fec185fe70cce007c57e9ab6983101dbe593d2bf8bbfb4453aaec0cf470a" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.8.0" analyzer_plugin: dependency: transitive description: @@ -109,18 +114,18 @@ packages: dependency: "direct main" description: name: auto_route - sha256: "6cad3f408863ffff2b5757967c802b18415dac4acb1b40c5cdd45d0a26e5080f" + sha256: a9001a90539ca3effc168f7e1029a5885c7326b9032c09ac895e303c1d137704 url: "https://pub.dev" source: hosted - version: "8.1.3" + version: "8.3.0" auto_route_generator: dependency: "direct dev" description: name: auto_route_generator - sha256: ba28133d3a3bf0a66772bcc98dade5843753cd9f1a8fb4802b842895515b67d3 + sha256: a21d7a936c917488653c972f62d884d8adcf8c5d37acc7cd24da33cf784546c0 url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "8.1.0" auto_size_text: dependency: "direct main" description: @@ -157,10 +162,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" build_resolvers: dependency: transitive description: @@ -173,18 +178,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04 url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.12" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 url: "https://pub.dev" source: hosted - version: "7.3.0" + version: "7.3.2" built_collection: dependency: transitive description: @@ -269,10 +274,10 @@ packages: dependency: "direct main" description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" collection_ext: dependency: "direct main" description: @@ -301,34 +306,34 @@ packages: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" custom_lint: dependency: "direct dev" description: name: custom_lint - sha256: "7c0aec12df22f9082146c354692056677f1e70bc43471644d1fdb36c6fdda799" + sha256: "4939d89e580c36215e48a7de8fd92f22c79dcc3eb11fda84f3402b3b45aec663" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" custom_lint_builder: dependency: transitive description: name: custom_lint_builder - sha256: d7dc41e709dde223806660268678be7993559e523eb3164e2a1425fd6f7615a9 + sha256: d9e5bb63ed52c1d006f5a1828992ba6de124c27a531e8fba0a31afffa81621b3 url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: a85e8f78f4c52f6c63cdaf8c872eb573db0231dcdf3c3a5906d493c1f8bc20e6 + sha256: "4ddbbdaa774265de44c97054dcec058a83d9081d071785ece601e348c18c267d" url: "https://pub.dev" source: hosted - version: "0.6.3" + version: "0.6.5" dart_style: dependency: transitive description: @@ -349,10 +354,10 @@ packages: dependency: "direct main" description: name: duration - sha256: "0548a12d235dab185c677ef660995f23fdc06a02a2b984aa23805f6a03d82815" + sha256: "8b9020df63d2894f29fe250b60ca5b7f9e943d4a3cf766c2b161efeb617a0ea3" url: "https://pub.dev" source: hosted - version: "3.0.13" + version: "3.0.15" fake_async: dependency: transitive description: @@ -365,10 +370,10 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" file: dependency: transitive description: @@ -466,18 +471,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: a434911f643466d78462625df76fd9eb13e57348ff43fe1f77bbe909522c67a1 + sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" url: "https://pub.dev" source: hosted - version: "2.5.2" + version: "2.5.7" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.4" frontend_server_client: dependency: transitive description: @@ -511,10 +516,10 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" graphview: dependency: "direct main" description: @@ -527,10 +532,10 @@ packages: dependency: "direct main" description: name: hooks_riverpod - sha256: "45b2030a18bcd6dbd680c2c91bc3b33e3fe7c323e3acb5ecec93a613e2fbaa8a" + sha256: "97266a91c994951a06ef0ff3a1c7fb261e52ec7f74e87f0614ea0b7411b859b2" url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.5.2" hotreloader: dependency: transitive description: @@ -543,10 +548,10 @@ packages: dependency: "direct main" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -559,10 +564,10 @@ packages: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "40f592dd352890c3b60fec1b68e786cefb9603e05ff303dbc4dda49b304ecdf4" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.0" icons_launcher: dependency: "direct dev" description: @@ -672,6 +677,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -692,10 +705,10 @@ packages: dependency: transitive description: name: meta - sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.14.0" + version: "1.15.0" mime: dependency: transitive description: @@ -740,18 +753,18 @@ packages: dependency: transitive description: name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d + sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.10" path_provider_foundation: dependency: transitive description: @@ -780,10 +793,10 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" petitparser: dependency: transitive description: @@ -804,10 +817,10 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -852,18 +865,18 @@ packages: dependency: "direct main" description: name: rive - sha256: "03bae056e67a5c98f9523c34f8ea63c15b323426a7e8d76d7ebb93066d4df6dc" + sha256: b45de4f0053e380302a7c37c0e7c7e734127d238eed23a85fe3a4b0b6faa8a5a url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.12" rive_common: dependency: transitive description: name: rive_common - sha256: "3fe76ba4680787741688ee393e47b63417e8643816795e4eac01021683af1d84" + sha256: "77311538b149263d34dc29cde4e608953c2d4451233efdb874ea9f08910769ac" url: "https://pub.dev" source: hosted - version: "0.4.9" + version: "0.4.10" riverpod: dependency: transitive description: @@ -876,10 +889,10 @@ packages: dependency: transitive description: name: riverpod_analyzer_utils - sha256: "8b71f03fc47ae27d13769496a1746332df4cec43918aeba9aff1e232783a780f" + sha256: ac28d7bc678471ec986b42d88e5a0893513382ff7542c7ac9634463b044ac72c url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.5.4" riverpod_annotation: dependency: "direct main" description: @@ -892,42 +905,42 @@ packages: dependency: "direct dev" description: name: riverpod_generator - sha256: d451608bf17a372025fc36058863737636625dfdb7e3cbf6142e0dfeb366ab22 + sha256: "63311e361ffc578d655dfc31b48dfa4ed3bc76fd06f9be845e9bf97c5c11a429" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.3" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "3c67c14ccd16f0c9d53e35ef70d06cd9d072e2fb14557326886bbde903b230a5" + sha256: a35a92f2c2a4b7a5d95671c96c5432b42c20f26bb3e985e83d0b186471b61a85 url: "https://pub.dev" source: hosted - version: "2.3.10" + version: "2.3.13" rxdart: dependency: transitive description: name: rxdart - sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" url: "https://pub.dev" source: hosted - version: "0.27.7" + version: "0.28.0" shelf: dependency: transitive description: name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -1017,10 +1030,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" stringr: dependency: transitive description: @@ -1041,10 +1054,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" + sha256: a824e842b8a054f91a728b783c177c1e4731f6b124f9192468457a8913371255 url: "https://pub.dev" source: hosted - version: "3.1.0+1" + version: "3.2.0" term_glyph: dependency: transitive description: @@ -1057,10 +1070,10 @@ packages: dependency: transitive description: name: test_api - sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.7.3" text_scroll: dependency: "direct main" description: @@ -1113,34 +1126,34 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" + sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" url: "https://pub.dev" source: hosted - version: "6.2.6" + version: "6.3.0" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "17cd5e205ea615e2c6ea7a77323a11712dffa0720a8a90540db57a01347f9ad9" + sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.10" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89" + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.3.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 + sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.2.0" url_launcher_macos: dependency: transitive description: @@ -1161,26 +1174,26 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a" + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 + sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" uuid: dependency: "direct main" description: name: uuid - sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" + sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.4.2" vector_graphics: dependency: transitive description: @@ -1217,10 +1230,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.2" + version: "14.2.4" watcher: dependency: transitive description: @@ -1237,14 +1250,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "3.0.1" webdriver: dependency: transitive description: @@ -1253,14 +1274,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" - win32: - dependency: transitive - description: - name: win32 - sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb" - url: "https://pub.dev" - source: hosted - version: "5.5.0" xdg_directories: dependency: transitive description: @@ -1286,5 +1299,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 86081e11b7..b8d207babd 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -12,34 +12,34 @@ dependencies: sdk: flutter collection: stack_trace: - freezed_annotation: ^2.4.1 - json_annotation: ^4.8.1 + freezed_annotation: ^2.4.4 + json_annotation: ^4.9.0 graphview: ^1.2.0 flutter_hooks: hooks_riverpod: ^2.5.1 auto_size_text: ^3.0.0 # google_fonts: ^4.0.4 - rive: ^0.13.1 + rive: ^0.13.12 fuzzy: ^0.5.1 auto_route: ^8.0.3 collapsible: ^1.0.0 - riverpod_annotation: ^2.1.2 + riverpod_annotation: ktx: ^1.1.6 # Keep this as the older one since we use SocketIO v2 on the server. socket_io_client: 1.0.2 clipboard: ^0.1.3 dotted_border: ^2.1.0 - flutter_svg: ^2.0.9 + flutter_svg: ^2.0.10 color: ^3.0.0 duration: ^3.0.13 flutter_animate: ^4.3.0 text_scroll: ^0.2.0 - url_launcher: ^6.1.12 + url_launcher: http: audioplayers: ^6.0.0 collection_ext: ^1.0.0 tinycolor2: ^3.0.1 - uuid: ^4.2.1 + uuid: flutter_colorpicker: git: url: https://github.com/mchome/flutter_colorpicker @@ -53,8 +53,8 @@ dev_dependencies: build_runner: freezed: json_serializable: - icons_launcher: ^2.1.3 - auto_route_generator: ^8.0.0 + icons_launcher: + auto_route_generator: riverpod_generator: custom_lint: riverpod_lint: diff --git a/app/test/entry_test.dart b/app/test/entry_test.dart index 4be49865b8..4c24395d66 100644 --- a/app/test/entry_test.dart +++ b/app/test/entry_test.dart @@ -5,7 +5,7 @@ void main() { final rawDynamicEntry = { "id": "1", "name": "test", - "type": "test_type", + "type": "test_blueprint_id", "simple_list": [1, 2, 3], "complex_list": [ {"id": "1", "name": "test1"}, @@ -42,7 +42,7 @@ void main() { expect(entry.id, "1"); expect(entry.name, "test"); - expect(entry.type, "test_type"); + expect(entry.blueprintId, "test_blueprint_id"); expect(entry.get("simple_list"), [1, 2, 3]); expect(entry.get("simple_list.1"), 2); diff --git a/app/test/page_test.dart b/app/test/page_test.dart index 4cdda2e5b9..d431707eaf 100644 --- a/app/test/page_test.dart +++ b/app/test/page_test.dart @@ -1,8 +1,8 @@ import "package:flutter_test/flutter_test.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:typewriter/models/adapter.dart"; import "package:typewriter/models/book.dart"; import "package:typewriter/models/entry.dart"; +import "package:typewriter/models/entry_blueprint.dart"; import "package:typewriter/models/page.dart"; import "package:typewriter/utils/passing_reference.dart"; @@ -22,29 +22,29 @@ const testEntryData = { ], }; -const entryBlueprintFields = ObjectField( +const entryBlueprintFields = ObjectBlueprint( fields: { - "id": FieldInfo.primitive(type: PrimitiveFieldType.string), - "name": FieldInfo.primitive(type: PrimitiveFieldType.string), - "type": FieldInfo.primitive(type: PrimitiveFieldType.string), - "simpleMap": FieldInfo.map( - key: FieldInfo.primitive(type: PrimitiveFieldType.string), - value: FieldInfo.primitive(type: PrimitiveFieldType.string), + "id": DataBlueprint.primitive(type: PrimitiveType.string), + "name": DataBlueprint.primitive(type: PrimitiveType.string), + "type": DataBlueprint.primitive(type: PrimitiveType.string), + "simpleMap": DataBlueprint.map( + key: DataBlueprint.primitive(type: PrimitiveType.string), + value: DataBlueprint.primitive(type: PrimitiveType.string), ), - "simpleList": FieldInfo.list( - type: FieldInfo.primitive(type: PrimitiveFieldType.string), + "simpleList": DataBlueprint.list( + type: DataBlueprint.primitive(type: PrimitiveType.string), ), - "complexMap": FieldInfo.map( - key: FieldInfo.primitive(type: PrimitiveFieldType.string), - value: FieldInfo.map( - key: FieldInfo.primitive(type: PrimitiveFieldType.string), - value: FieldInfo.primitive(type: PrimitiveFieldType.string), + "complexMap": DataBlueprint.map( + key: DataBlueprint.primitive(type: PrimitiveType.string), + value: DataBlueprint.map( + key: DataBlueprint.primitive(type: PrimitiveType.string), + value: DataBlueprint.primitive(type: PrimitiveType.string), ), ), - "complexList": FieldInfo.list( - type: FieldInfo.map( - key: FieldInfo.primitive(type: PrimitiveFieldType.string), - value: FieldInfo.primitive(type: PrimitiveFieldType.string), + "complexList": DataBlueprint.list( + type: DataBlueprint.map( + key: DataBlueprint.primitive(type: PrimitiveType.string), + value: DataBlueprint.primitive(type: PrimitiveType.string), ), ), }, @@ -70,7 +70,8 @@ void main() { expect(newPage.entries[0].id, "test"); }); - test("When creating an entry form a blueprint expect the entry to be created", () async { + test("When creating an entry form a blueprint expect the entry to be created", + () async { final container = ProviderContainer(); await container.read(bookProvider.notifier).createPage("test_page"); @@ -80,10 +81,11 @@ void main() { expect(page!.entries.length, 0); const entry = EntryBlueprint( + id: "test", name: "test_type", description: "Some test", - adapter: "test_adapter", - fields: entryBlueprintFields, + extension: "Test", + dataBlueprint: entryBlueprintFields, ); await page.createEntryFromBlueprint(container.passing, entry); diff --git a/documentation/docs/adapters/README.mdx b/documentation/docs/adapters/README.mdx index 14fc172dcd..c4b7d13e88 100644 --- a/documentation/docs/adapters/README.mdx +++ b/documentation/docs/adapters/README.mdx @@ -2,5 +2,9 @@ sidebar_position: 1 --- -# Adapters -Typewriter allows developers to create adapters to use with their own custom entries. This allows Typewriter to be used with different plugins and can be extended to what ever you need. \ No newline at end of file +# Extensions +Typewriter allows developers to create extensions to use with their own custom entries. This allows Typewriter to be used with different plugins and can be extended to what ever you need. + +:::danger Outdated +These pages are outdated. As Typewriter is moving from `Adapters` to `Extensions`, the documentation generator needs to be updated. +::: diff --git a/documentation/docs/develop/02-adapters/02-getting_started.mdx b/documentation/docs/develop/02-adapters/02-getting_started.mdx deleted file mode 100644 index 6c6c7a0ea6..0000000000 --- a/documentation/docs/develop/02-adapters/02-getting_started.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: Getting Started ---- - -import CodeSnippet from "@site/src/components/CodeSnippet"; - - -# Creating an Adapter -## Introduction -Typewriter is a dynamic platform that supports the development of adapters, which are modular components enhancing the overall functionality. -Adapters are self-contained, easily shareable, and integrate smoothly into the TypeWriter system. -They allow you to create custom entries and have them show up in the web panel. -This guide is tailored to guide you through the process of creating an adapter, suitable for both beginners and experienced developers. - -## Prerequisites - - Java Development Kit (JDK) 21 or higher. - - An Integrated Development Environment (IDE) such as IntelliJ IDEA or Eclipse. - - A basic understanding of Gradle and the Spigot API. - -## Step 1: Setting Up a Gradle Project -Begin by establishing a Gradle project for your Typewriter adapter. Below is a comprehensive setup for your `build.gradle.kts`: - -```kotlin title="build.gradle.kts" -plugins { - kotlin("jvm") version "2.0.0" - id("io.github.goooler.shadow") version "8.1.7" -} - -// Replace with your own information -group = "me.yourusername" -version = "0.0.1" - -repositories { - // Typewriter required repositories - mavenCentral() - maven("https://repo.papermc.io/repository/maven-public/") - maven("https://repo.codemc.io/repository/maven-releases/") - maven("https://repo.opencollab.dev/maven-snapshots/") - maven("https://jitpack.io") - - // Add other necessary repositories -} - -dependencies { - compileOnly("com.github.gabber235:typewriter:main-SNAPSHOT") // Latest release version - - // Add other dependencies as needed -} - -tasks.withType { - exclude("kotlin/**") - exclude("META-INF/maven/**") - // Important: Use the relocated commandapi which is shadowed by the plugin - relocate("dev.jorel.commandapi", "com.github.gabber235.typewriter.extensions.commandapi") { - include("dev.jorel.commandapi.**") - } -} - -kotlin { - jvmToolchain(21) -} -``` - -Ensure to replace placeholders like `me.yourusername` with your project details. - -### Choosing the TypeWriter Version -Select the appropriate TypeWriter dependency version: -For stable and tested features, use the latest release version: -```kotlin -compileOnly("com.github.gabber235:typewriter:main-SNAPSHOT") -``` -This is suitable for most development needs and is recommended for general adapter creation. - -If you need the latest features and improvements (which might be unstable), use the latest development version: -```kotlin -compileOnly("com.github.gabber235:typewriter:develop-SNAPSHOT") -``` -Note that this version may include changes that are not yet fully tested or documented. - -If you need a specific version, visit the [JitPack page](https://jitpack.io/#gabber235/typewriter) and select the version you need. - -## Step 2: Creating an Adapter Class -After setting up your project, create an adapter class. Here's an example: - - - -## Step 3: Building the Adapter -After creating the adapter class, build the adapter. This can be done by running the `shadowJar` Gradle task. -This will generate a JAR file in the `build/libs` directory. -This JAR file can be used as an adapter in TypeWriter. -Place the JAR file in the `plugins/TypeWriter/adapters` directory and restart the server. -Typewriter will automatically load the adapter and run it. - -If any problems occur, check the console for errors and ensure that the adapter is properly configured. -If you need help, join the [Discord server](https://discord.gg/HtbKyuDDBw) and ask for help. - -## What's Next? -After creating an adapter, you can start adding features to it. -Check out the [Creating Entries](entries) guide to learn how to add entries to your adapter. diff --git a/documentation/docs/develop/02-adapters/index.mdx b/documentation/docs/develop/02-adapters/index.mdx deleted file mode 100644 index 7d94ed4e79..0000000000 --- a/documentation/docs/develop/02-adapters/index.mdx +++ /dev/null @@ -1,10 +0,0 @@ -# Adapters -## Introduction -TypeWriter is a dynamic platform that supports the development of adapters, which are modular components enhancing the overall functionality. -Adapters are self-contained, easily shareable, and integrate smoothly into the TypeWriter system. -They allow you to create custom entries and have them show up in the web panel. -This guide is tailored to guide you through the process of creating an adapter, suitable for both beginners and experienced developers. - -:::info -It is highly recommended to write adapters in Kotlin, as it is the primary language of TypeWriter. **Though, it is currently possible to write adapters in Java, this will no longer be possible in v0.6.** -::: diff --git a/documentation/docs/develop/02-extensions/02-getting_started.mdx b/documentation/docs/develop/02-extensions/02-getting_started.mdx new file mode 100644 index 0000000000..4e31686011 --- /dev/null +++ b/documentation/docs/develop/02-extensions/02-getting_started.mdx @@ -0,0 +1,138 @@ +--- +title: Getting Started +--- + +import CodeSnippet from "@site/src/components/CodeSnippet"; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + +# Creating an Extension +## Introduction +Typewriter is a dynamic platform that supports the development of extensions, which are modular components enhancing the overall functionality. +Extensions are self-contained, easily shareable, and integrate smoothly into the TypeWriter system. +They allow you to create custom entries and have them show up in the web panel. +This guide is tailored to guide you through the process of creating an extension. + +## Prerequisites + - Java Development Kit (JDK) 21 or higher. + - An Integrated Development Environment (IDE) such as IntelliJ IDEA or Eclipse. + - A basic understanding of Gradle and the Spigot API. + +## Setting Up a Gradle Project +Begin by establishing a Gradle project for your Typewriter extension. Below is a comprehensive setup for your Gradle project: + + + + Add the following to your `settings.gradle.kts` file: + ```kotlin title="settings.gradle.kts" + pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://maven.typewritermc.com/releases") + } + } + ``` + + Add the following to your `build.gradle.kts` file: + ```kotlin title="build.gradle.kts" + plugins { + kotlin("jvm") version "2.0.20" + id("com.typewritermc.module-plugin") version "" + } + + // Replace with your own information + group = "me.yourusername" + version = "0.0.1" + + typewriter { + engine { + version = "" + } + namespace = "" + + extension { + name = "" + shortDescription = "" + description = "" + + paper { + // Optional - If you want to make sure a plugin is required to be installed to use this extension + dependency("") + } + } + } + + kotlin { + jvmToolchain(21) + } + ``` + + + Add the following to your `settings.gradle.kts` file: + ```kotlin title="settings.gradle.kts" + pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://maven.typewritermc.com/beta") + } + } + ``` + + Add the following to your `build.gradle.kts` file: + ```kotlin title="build.gradle.kts" + plugins { + kotlin("jvm") version "2.0.20" + id("com.typewritermc.module-plugin") version "" + } + + typewriter { + engine { + version = "" + channel = com.typewritermc.moduleplugin.ReleaseChannel.BETA + } + namespace = "" + + extension { + name = "" + shortDescription = "" + description = "" + + paper { + // Optional - If you want to make sure a plugin is required to be installed to use this extension + dependency("") + } + } + } + + kotlin { + jvmToolchain(21) + } + ``` + + + +:::info Replace your information +Ensure to replace placeholders like `me.yourusername` with your project details. +::: + +## Building the Extension +After creating the extension class, build the extension. This can be done by running the `build` Gradle task. +This will generate a JAR file in the `build/libs` directory. +This JAR file can be used as an extension in TypeWriter. +Place the JAR file in the `plugins/TypeWriter/extensions` directory. +Typewriter will automatically load the extension and run it. + +:::tip Reloading Extensions +You can either restart the Minecraft server or reload Typewriter with `/typewriter reload` to reload the extensions. +::: + + +If any problems occur, check the console for errors and ensure that the extension is properly configured. +If you need help, join the [Discord server](https://discord.gg/HtbKyuDDBw) and ask for help. + +## What's Next? +After creating an extension, you can start adding features to it. +Check out the [Creating Entries](entries) guide to learn how to add entries to your extension. diff --git a/documentation/docs/develop/02-extensions/03-initializers.mdx b/documentation/docs/develop/02-extensions/03-initializers.mdx new file mode 100644 index 0000000000..9da369be5b --- /dev/null +++ b/documentation/docs/develop/02-extensions/03-initializers.mdx @@ -0,0 +1,19 @@ +import CodeSnippet from "@site/src/components/CodeSnippet"; + +# Initializers + +Sometimes your extension needs to do some initialization before it can be used. +For example, you might need to add a hook to a plugin to make it work with your extension. + +## Declaring an Initializer +To declare an initializer, you need to create a **object** that implements the `Initializable` interface. +And add the `@Initializer` annotation to the class. + + + +:::danger Ensure Cleanup +The `shutdown` method is called when the extension is unloaded. +You should make sure that no resources are leaked when the extension is unloaded. +::: + +Typewriter will automatically register and call the control flow methods when the extension is loaded and unloaded. diff --git a/documentation/docs/develop/02-adapters/03-entries/cinematic/index.mdx b/documentation/docs/develop/02-extensions/04-entries/cinematic/index.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/cinematic/index.mdx rename to documentation/docs/develop/02-extensions/04-entries/cinematic/index.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/index.mdx b/documentation/docs/develop/02-extensions/04-entries/index.mdx similarity index 94% rename from documentation/docs/develop/02-adapters/03-entries/index.mdx rename to documentation/docs/develop/02-extensions/04-entries/index.mdx index 6104f501f5..d24882924a 100644 --- a/documentation/docs/develop/02-adapters/03-entries/index.mdx +++ b/documentation/docs/develop/02-extensions/04-entries/index.mdx @@ -1,6 +1,5 @@ # Create Entries -Creating adapters for the TypeWriter Spigot plugin involves working with various entry types, each serving a specific -purpose in crafting immersive player experiences. +Creating extensions for the TypeWriter plugin involves working with various entry types, each serving a specific purpose in crafting immersive player experiences. This documentation explains the roles and functionalities of these entry types, providing clear guidance for developers on how to effectively use them. ## Base Entry Interfaces @@ -60,7 +59,9 @@ Similarly, an ActionEntry can be used to create dynamic effects that change base ### Defining a Entry Typewriter takes care of the heavy lifting when it comes to creating and using entries. -Developers only need to define the entry's class and its fields (and sometimes additional methods). The rest is handled by Typewriter. From scanning the adapters jar file for all the different entry classes to triggering them. +Developers only need to define the entry's class and its fields (and sometimes additional methods). +The rest is handled by Typewriter. +From scanning the extensions jar file for all the different entry classes to triggering them. To define an entry, it needs to meet the following requirements: 1. It must be a class that implements one of the base entry interfaces. diff --git a/documentation/docs/develop/02-adapters/03-entries/manifest/_category_.yml b/documentation/docs/develop/02-extensions/04-entries/manifest/_category_.yml similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/manifest/_category_.yml rename to documentation/docs/develop/02-extensions/04-entries/manifest/_category_.yml diff --git a/documentation/docs/develop/02-adapters/03-entries/manifest/audience.mdx b/documentation/docs/develop/02-extensions/04-entries/manifest/audience.mdx similarity index 98% rename from documentation/docs/develop/02-adapters/03-entries/manifest/audience.mdx rename to documentation/docs/develop/02-extensions/04-entries/manifest/audience.mdx index fe077ddcb1..5e75fef618 100644 --- a/documentation/docs/develop/02-adapters/03-entries/manifest/audience.mdx +++ b/documentation/docs/develop/02-extensions/04-entries/manifest/audience.mdx @@ -2,7 +2,7 @@ import CodeSnippet from "@site/src/components/CodeSnippet"; # AudienceEntry -`AudienceEntry` is a crucial component in Typewriter that allows adapter developers to display content to a group of players. +`AudienceEntry` is a crucial component in Typewriter that allows extension developers to display content to a group of players. Typewriter manages the players in the audience, providing hooks that developers can use to show information or interact with the players in the audience. The `AudienceEntry` is the most used `ManifestEntry` in Typewriter. diff --git a/documentation/docs/develop/02-adapters/03-entries/static/_category_.yml b/documentation/docs/develop/02-extensions/04-entries/static/_category_.yml similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/static/_category_.yml rename to documentation/docs/develop/02-extensions/04-entries/static/_category_.yml diff --git a/documentation/docs/develop/02-adapters/03-entries/static/artifact.mdx b/documentation/docs/develop/02-extensions/04-entries/static/artifact.mdx similarity index 96% rename from documentation/docs/develop/02-adapters/03-entries/static/artifact.mdx rename to documentation/docs/develop/02-extensions/04-entries/static/artifact.mdx index 76ccbf8270..5cc65234cf 100644 --- a/documentation/docs/develop/02-adapters/03-entries/static/artifact.mdx +++ b/documentation/docs/develop/02-extensions/04-entries/static/artifact.mdx @@ -3,7 +3,7 @@ import CodeSnippet from "@site/src/components/CodeSnippet"; # ArtifactEntry The `ArtifactEntry` is a specialized interface derived from `AssetEntry`. -Its primary purpose is to handle artifacts, which are assets generated by the plugins/adapters itself. +Its primary purpose is to handle artifacts, which are assets generated by the extensions. Unlike standard assets, artifacts are usually dynamic and created during runtime. This makes them particularly useful for storing data that changes based on player interactions or game events. diff --git a/documentation/docs/develop/02-adapters/03-entries/static/asset.mdx b/documentation/docs/develop/02-extensions/04-entries/static/asset.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/static/asset.mdx rename to documentation/docs/develop/02-extensions/04-entries/static/asset.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/static/sound_id.mdx b/documentation/docs/develop/02-extensions/04-entries/static/sound_id.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/static/sound_id.mdx rename to documentation/docs/develop/02-extensions/04-entries/static/sound_id.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/static/sound_source.mdx b/documentation/docs/develop/02-extensions/04-entries/static/sound_source.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/static/sound_source.mdx rename to documentation/docs/develop/02-extensions/04-entries/static/sound_source.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/static/speaker.mdx b/documentation/docs/develop/02-extensions/04-entries/static/speaker.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/static/speaker.mdx rename to documentation/docs/develop/02-extensions/04-entries/static/speaker.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/trigger/_category_.yml b/documentation/docs/develop/02-extensions/04-entries/trigger/_category_.yml similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/trigger/_category_.yml rename to documentation/docs/develop/02-extensions/04-entries/trigger/_category_.yml diff --git a/documentation/docs/develop/02-adapters/03-entries/trigger/action.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/action.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/trigger/action.mdx rename to documentation/docs/develop/02-extensions/04-entries/trigger/action.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/trigger/custom_triggering_action.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/custom_triggering_action.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/trigger/custom_triggering_action.mdx rename to documentation/docs/develop/02-extensions/04-entries/trigger/custom_triggering_action.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/trigger/dialogue.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/dialogue.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/trigger/dialogue.mdx rename to documentation/docs/develop/02-extensions/04-entries/trigger/dialogue.mdx diff --git a/documentation/docs/develop/02-adapters/03-entries/trigger/event.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/event.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/03-entries/trigger/event.mdx rename to documentation/docs/develop/02-extensions/04-entries/trigger/event.mdx diff --git a/documentation/docs/develop/02-adapters/04-querying.mdx b/documentation/docs/develop/02-extensions/05-querying.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/04-querying.mdx rename to documentation/docs/develop/02-extensions/05-querying.mdx diff --git a/documentation/docs/develop/02-adapters/05-triggering.mdx b/documentation/docs/develop/02-extensions/06-triggering.mdx similarity index 100% rename from documentation/docs/develop/02-adapters/05-triggering.mdx rename to documentation/docs/develop/02-extensions/06-triggering.mdx diff --git a/documentation/docs/develop/02-adapters/06-api-changes/0.5.0.mdx b/documentation/docs/develop/02-extensions/07-api-changes/0.5.mdx similarity index 95% rename from documentation/docs/develop/02-adapters/06-api-changes/0.5.0.mdx rename to documentation/docs/develop/02-extensions/07-api-changes/0.5.mdx index f5a6fa84fc..de07510129 100644 --- a/documentation/docs/develop/02-adapters/06-api-changes/0.5.0.mdx +++ b/documentation/docs/develop/02-extensions/07-api-changes/0.5.mdx @@ -1,9 +1,13 @@ +--- +title: 0.5.X API Changes +--- + import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -# All api changes to 0.5.0 +# All API changes to 0.5.X -This document lists all the API changes introduced in version `0.5.0` of the TypeWriter plugin. If you are upgrading from an older version, please read this document before upgrading. +This document lists all the API changes introduced in version `0.5` of the TypeWriter plugin. If you are upgrading from an older version, please read this document before upgrading. ## New type: Ref diff --git a/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx b/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx new file mode 100644 index 0000000000..966a86d1e3 --- /dev/null +++ b/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx @@ -0,0 +1,10 @@ +--- +title: 0.6.X API Changes +--- + +# All API changes to 0.6.X + +As Typewriter changed from `Adapters` to `Extensions`, the API has changed significantly. +It is recommended to reread the [Getting Started](getting_started) guide to get a better understanding of how to create extensions. + + diff --git a/documentation/docs/develop/02-adapters/06-api-changes/index.mdx b/documentation/docs/develop/02-extensions/07-api-changes/index.mdx similarity index 97% rename from documentation/docs/develop/02-adapters/06-api-changes/index.mdx rename to documentation/docs/develop/02-extensions/07-api-changes/index.mdx index ef9a5e0338..fc36030005 100644 --- a/documentation/docs/develop/02-adapters/06-api-changes/index.mdx +++ b/documentation/docs/develop/02-extensions/07-api-changes/index.mdx @@ -1,2 +1,2 @@ # API Changes -The TypeWriter plugin frequently undergoes updates, and these changes can impact the functionality of the API. Here, you can find a list of API changes for each version of TypeWriter, providing info about the modifications made to improve development experiences. \ No newline at end of file +The TypeWriter plugin frequently undergoes updates, and these changes can impact the functionality of the API. Here, you can find a list of API changes for each version of TypeWriter, providing info about the modifications made to improve development experiences. diff --git a/documentation/docs/develop/02-extensions/index.mdx b/documentation/docs/develop/02-extensions/index.mdx new file mode 100644 index 0000000000..20ce53ea52 --- /dev/null +++ b/documentation/docs/develop/02-extensions/index.mdx @@ -0,0 +1,10 @@ +# Extensions +## Introduction +TypeWriter is a dynamic platform that supports the development of extensions, which are modular components enhancing the overall functionality. +Extensions are self-contained, easily shareable, and integrate smoothly into the TypeWriter system. +They allow you to create custom entries and have them show up in the web panel. +This guide is tailored to guide you through the process of creating an extension, suitable for both beginners and experienced developers. + +:::info +It is required to write extensions in Kotlin, as it is the primary language of TypeWriter. **It is not possible to create extensions in Java.** +::: diff --git a/documentation/docs/develop/README.mdx b/documentation/docs/develop/README.mdx index 2079e10db9..f55c44f5c6 100644 --- a/documentation/docs/develop/README.mdx +++ b/documentation/docs/develop/README.mdx @@ -4,7 +4,7 @@ sidebar_position: 1 # Development Typewriter has different parts that can be developed upon. -- **Adapters:** These are self-containted building blocks that can easaly be shared and added to the system. +- **Extensions:** These are self-containted building blocks that can easaly be shared and added to the system. - **Plugin:** These are core parts of how Typewriter works. All help is welcome, but please discuss it first as there changes might impact a lot of users. - **UI:** This is written in Flutter and is the most complex part of Typewriter. It is also the most fun to work on, as this is where you can really see the results of your work. diff --git a/documentation/docs/docs/01-home.md b/documentation/docs/docs/01-home.md index a5bd9ad8f7..788a86e078 100644 --- a/documentation/docs/docs/01-home.md +++ b/documentation/docs/docs/01-home.md @@ -4,8 +4,8 @@ Typewriter is a plugin that allows you to create and manage player interactions quests, NPC dialogues, and more. It also allows you to manage your server's existing player interactions. In this wiki there are several pages that will help you get started with Typewriter. The first page is -the [Installation Guide](./02-getting-started/01-installation.mdx). This page will help you install Typewriter and the basic adapter. Then you -can follow the [First Interaction](./03-creating-stories/01-interactions/index.mdx) guide to create your first interaction. +the [Installation Guide](./02-getting-started/01-installation.mdx). This page will help you install Typewriter and the `BasicExtension`. +Then you can follow the [First Interaction](./03-creating-stories/01-interactions/index.mdx) guide to create your first interaction. :::caution[In beta] Typewriter is currently in beta. This means that the plugin is still in development and may contain bugs. If you find diff --git a/documentation/docs/docs/02-getting-started/01-installation.mdx b/documentation/docs/docs/02-getting-started/01-installation.mdx index 932fe7ca9c..babe591441 100644 --- a/documentation/docs/docs/02-getting-started/01-installation.mdx +++ b/documentation/docs/docs/02-getting-started/01-installation.mdx @@ -28,18 +28,18 @@ TypeWriter relies on additional plugins that need to be installed for proper fun 4. Verify that you **don't** have the [InteractiveChat](https://www.spigotmc.org/resources/interactivechat-show-items-inventory-in-chat-custom-chat-keywords-bungee-velocity-support.75870/) or [Eco](https://polymart.org/resource/eco.773) plugin installed, as it may cause conflicts with TypeWriter. -### Basic Adapter +### Basic Extension -The TypeWriter offers various adapters for customization, but it's crucial to have the basic adapter installed. +The TypeWriter offers various extensions for customization, but it's crucial to have the `BasicExtension` installed. -5. Download the latest basic adapter from and add it to the `plugins/TypeWriter/adapters` folder. +5. Download the latest `BasicExtension` from and add it to the `plugins/TypeWriter/extensions` folder. -For a comprehensive list of available adapters, refer to the [adapters section](../../adapters). +For a comprehensive list of available extensions, refer to the [extensions section](../../adapters). 6. With all components in place, restart your Minecraft server to complete the TypeWriter installation. :::danger[Out of Sync] -When updating the plugin, it's crucial to **always** install the corresponding adapters for that update. Failure to match the versions of the adapter and plugin can result in the plugin not functioning correctly! +When updating the plugin, it's crucial to **always** install the corresponding extensions for that update. Failure to match the versions of the extension and plugin can result in the plugin not functioning correctly! ::: ## Configuring the Web Panel diff --git a/documentation/docs/docs/03-creating-stories/01-interactions/index.mdx b/documentation/docs/docs/03-creating-stories/01-interactions/index.mdx index feedddd198..39b9021d12 100644 --- a/documentation/docs/docs/03-creating-stories/01-interactions/index.mdx +++ b/documentation/docs/docs/03-creating-stories/01-interactions/index.mdx @@ -8,7 +8,7 @@ import EntrySearch from "@site/src/components/EntrySearch"; # First Interaction :::info[Before starting] -This guide assumes that you have already installed the [Basic Adapter](../../02-getting-started/01-installation.mdx#basic-adapter).\ +This guide assumes that you have already installed the [Basic Extension](../../02-getting-started/01-installation.mdx#basic-extension).\ Also, make sure you have read the [layout](../../02-getting-started/02-layout.mdx) documentation and created a **sequence** page. ::: diff --git a/documentation/docs/docs/03-creating-stories/02-cinematics/03-entities.mdx b/documentation/docs/docs/03-creating-stories/02-cinematics/03-entities.mdx index ca937b309a..0f5f9536cc 100644 --- a/documentation/docs/docs/03-creating-stories/02-cinematics/03-entities.mdx +++ b/documentation/docs/docs/03-creating-stories/02-cinematics/03-entities.mdx @@ -23,7 +23,7 @@ Now in the inspector, click on `Select a entity_definition` and select the type -Then inside that NPC Definition you can follow the [entity-adapter](../04-entity-adapter/index.mdx) Tutorial to create a Beautiful NPC. +Then inside that NPC Definition you can follow the [entity-extension](../04-entity-extension/index.mdx) Tutorial to create a Beautiful NPC. ### Adding segments Now we need to add a segment to our track. You can do this by clicking in the inspector at Operations on `Add Segment`. This will add a segment to your track. diff --git a/documentation/docs/docs/03-creating-stories/02-cinematics/index.mdx b/documentation/docs/docs/03-creating-stories/02-cinematics/index.mdx index 4f9a1395b6..54a2488d47 100644 --- a/documentation/docs/docs/03-creating-stories/02-cinematics/index.mdx +++ b/documentation/docs/docs/03-creating-stories/02-cinematics/index.mdx @@ -9,7 +9,7 @@ import EntrySearch from "@site/src/components/EntrySearch"; # Cinematics :::info[Before starting] -This guide assumes that you have already installed the [Basic Adapter](../../02-getting-started/01-installation.mdx#basic-adapter).\ +This guide assumes that you have already installed the [Basic Extension](../../02-getting-started/01-installation.mdx#basic-extension).\ Also, make sure you have read the [layout](../../02-getting-started/02-layout.mdx) documentation and created a **cinematic** page. ::: diff --git a/documentation/docs/docs/03-creating-stories/03-facts/index.mdx b/documentation/docs/docs/03-creating-stories/03-facts/index.mdx index abc2413870..9b7510c0f6 100644 --- a/documentation/docs/docs/03-creating-stories/03-facts/index.mdx +++ b/documentation/docs/docs/03-creating-stories/03-facts/index.mdx @@ -10,7 +10,7 @@ import Image from "@site/src/components/Image"; Facts are essentially variables. They store information that can be modified by other entries. All facts are numbers and are treated as such. -The [`Basic Adapter`](../../../adapters/BasicAdapter/BasicAdapter.mdx) encompasses numerous facts available for use. However, it's important to note that [`adapters`](../../../adapters/README.mdx) have the capability to further augment the array of available facts. +The [`Basic Extension`](../../../adapters/BasicAdapter/BasicAdapter.mdx) encompasses numerous facts available for use. However, it's important to note that [`extensions`](../../../adapters/README.mdx) have the capability to further augment the array of available facts. ## Why Use Facts? @@ -136,5 +136,5 @@ There are many possibilities with the fact's system. Here are some examples: :::tip -To see all the available facts, check out the [Adapters section](../../../adapters/README.mdx). +To see all the available facts, check out the [Extensions section](../../../adapters/README.mdx). ::: diff --git a/documentation/docs/docs/03-creating-stories/04-entity-adapter/02-interacting.mdx b/documentation/docs/docs/03-creating-stories/04-entity-extension/02-interacting.mdx similarity index 92% rename from documentation/docs/docs/03-creating-stories/04-entity-adapter/02-interacting.mdx rename to documentation/docs/docs/03-creating-stories/04-entity-extension/02-interacting.mdx index c21ef934f0..1b99e746bc 100644 --- a/documentation/docs/docs/03-creating-stories/04-entity-adapter/02-interacting.mdx +++ b/documentation/docs/docs/03-creating-stories/04-entity-extension/02-interacting.mdx @@ -20,7 +20,7 @@ First, we need to add the `Add On Entity Interact Event` entry to our sequence. ### Selecting the definition Now inside the inspector of the `New Entity Interact Event` at the definition field, select the definition of the entity you want to interact with. (For this tutorial that will be Oliver) -Entity Interact Event Fields +Entity Interact Event Fields ## Adding the event. Now we need to add an event that gets triggered when the player interacts with the entity (For this tutorial we will use a spoken). Right-click on the `New Entity Interact Event` entry and click on `+ link with ...` to open the search menu. Search for `Add Spoken` and add it to the page. @@ -34,4 +34,4 @@ You can now publish your pages, and in-game, it should look like this when inter :::warning[Mc-Auth servers] So while writing this page the auth servers of minecraft are down and i couldn't access my tw server. So i can't provide a video of the result as of right now.(This will hopefully be fixed soon) -::: \ No newline at end of file +::: diff --git a/documentation/docs/docs/03-creating-stories/04-entity-adapter/index.mdx b/documentation/docs/docs/03-creating-stories/04-entity-extension/index.mdx similarity index 80% rename from documentation/docs/docs/03-creating-stories/04-entity-adapter/index.mdx rename to documentation/docs/docs/03-creating-stories/04-entity-extension/index.mdx index 8765010c83..220c1554e1 100644 --- a/documentation/docs/docs/03-creating-stories/04-entity-adapter/index.mdx +++ b/documentation/docs/docs/03-creating-stories/04-entity-extension/index.mdx @@ -7,16 +7,16 @@ import Image from "@site/src/components/Image"; import EntrySearch from "@site/src/components/EntrySearch"; # Entities & NPC's -:::danger[Entity-Adapter] -You must have installed the Entity-Adapter before starting this tutorial. +:::danger[Entity Extension] +You must have installed the Entity Extension before starting this tutorial. ::: Any good storytelling requires other characters to be present in the world. -Typewriter has its own entity adapter that allows you to create and control entities like NPCs. +Typewriter has its own entity extension, that allows you to create and control entities like NPCs. -## What is the Entity Adapter? -The Entity Adapter is a feature that makes it easy to spawn, manage and control entities like NPCs on your server. +## What is the Entity Extension? +The Entity Extension is a feature that makes it easy to spawn, manage and control entities like NPCs on your server. These are some of the features: - **Defining an entity**: create a new entity with custom data and spawn it in the world, which can be re-used across multiple servers @@ -53,7 +53,7 @@ Let's rename the entry to `Oliver Definition`. To change the display name above the head, we can change the `Display Name` field to `Oliver`. -Rename Entry and Entity +Rename Entry and Entity ## Setting the NPC's skin @@ -67,7 +67,7 @@ We can click on the chain icon to the right of the `Skin` field to `Fetch from u Then, we can enter the url `https://s.namemc.com/i/b2319359e305d7a2.png` and click `Fetch`. - + ## Creating an npc instance We have now defined the NPC, but it has not yet spawned in the world. @@ -81,14 +81,14 @@ First, select the NPC definition you want to spawn from the `Definition` dropdow In this case, we will select the `Oliver Definition` we just created. This will act as a base for our NPC instance -Definition Select +Definition Select Finally, we need to set the spawn location of the NPC. This is the location where the NPC will always spawn when the first player may view the NPC. We can do this with the content mode selector and fetch the location of your logged-in Minecraft client. - + That's it! @@ -96,8 +96,8 @@ You have now created an entity definition and spawned an instance of it in the w You can now see the NPC in-game with the custom name, skin and data you provided! The same principle applies to all other entities, such as **Cows** or **Villagers**. -You can define and spawn any entity you want using the Entity Adapter; just make sure the type of your definition matches the type of instance you want to spawn. +You can define and spawn any entity you want using the Entity Extension; just make sure the type of your definition matches the type of instance you want to spawn. :::info Since not all entities have a definition or instance, when you need to create an entity with a type that has no definition or instance, request it from the [Discord](https://discord.gg/HtbKyuDDBw). -::: \ No newline at end of file +::: diff --git a/documentation/docs/docs/03-creating-stories/06-road-network/index.mdx b/documentation/docs/docs/03-creating-stories/06-road-network/index.mdx index 15f58dc1bf..c6184de132 100644 --- a/documentation/docs/docs/03-creating-stories/06-road-network/index.mdx +++ b/documentation/docs/docs/03-creating-stories/06-road-network/index.mdx @@ -11,7 +11,7 @@ import Admonition from '@theme/Admonition'; # Road Network :::info[Before starting] -This guide assumes that you have already installed the [Basic Adapter](../../02-getting-started/01-installation.mdx#basic-adapter).\ +This guide assumes that you have already installed the [Basic Extension](../../02-getting-started/01-installation.mdx#basic-extension).\ Also, make sure you have read the [layout](../../02-getting-started/02-layout.mdx) documentation and created a **static** page. ::: diff --git a/documentation/docs/docs/05-helpfull-features/05-snippets.mdx b/documentation/docs/docs/05-helpfull-features/05-snippets.mdx index 0dd5ffe588..61b33bd6a0 100644 --- a/documentation/docs/docs/05-helpfull-features/05-snippets.mdx +++ b/documentation/docs/docs/05-helpfull-features/05-snippets.mdx @@ -4,8 +4,8 @@ difficulty: Normal --- # What are Snippets? -Snippets are small pieces of information that the adapters can use. Mostly related with how things are displayed to the users. -Snippets allow you to customize all sorts of parts of different adpaters. For example, you can customize the way messages are displayed in the `Basic Adapter`. +Snippets are small pieces of information that the extensions can use. Mostly related with how things are displayed to the users. +Snippets allow you to customize all sorts of parts of different adpaters. For example, you can customize the way messages are displayed in the `Basic Extension`. # How do I customize Snippets? Snippets can be customized by editing the `plugin/Typewriter/snippets.yml` file. @@ -14,7 +14,7 @@ Snippets can be customized by editing the `plugin/Typewriter/snippets.yml` file. Note that Snippets are only written the first time they are used. So if you want to customize a snippet, you will need to trigger the entry that uses the snippet first. ::: -So for the `Basic Adapter`, after the first person reiceves a `MessageDialogueEntry`, the `snippets.yml` file will look like this: +So for the `Basic Extension`, after the first person reiceves a `MessageDialogueEntry`, the `snippets.yml` file will look like this: ```yaml title="plugin/Typewriter/snippets.yml" dialogue: @@ -38,4 +38,4 @@ dialogue: | | ``` -The `|2` indicates that the text is a multi-line string, and has `2` new-lines at the end of the string. If you don't want the new-lines, you can remove the `2` to make it `|`. \ No newline at end of file +The `|2` indicates that the text is a multi-line string, and has `2` new-lines at the end of the string. If you don't want the new-lines, you can remove the `2` to make it `|`. diff --git a/documentation/docs/docs/06-troubleshooting/adapters.mdx b/documentation/docs/docs/06-troubleshooting/adapters.mdx deleted file mode 100644 index 53c2d7f441..0000000000 --- a/documentation/docs/docs/06-troubleshooting/adapters.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -difficulty: Normal ---- - -# Adapters Troubleshooting - -Experiencing issues with your Typewriter plugin adapters? This guide provides step-by-step instructions to ensure your adapters are set up correctly and functioning optimally with the Typewriter plugin. - -## Correct Adapter Placement - -It's important to note that adapters for the Typewriter plugin are not standard Spigot plugins. They are special JAR files exclusively for Typewriter, and thus need to be stored separately. To ensure proper functioning: - -1. Navigate to the plugin directory: `/plugins/Typewriter/adapters`. -2. If an "adapters" folder does not exist within this directory, create one. -3. Place your adapter files inside this "adapters" folder. - -This dedicated folder ensures that Typewriter can correctly read and use these adapters without confusing them with regular Spigot plugins. - -## Adapter and Plugin Version Compatibility - -For the Typewriter plugin and its adapters to work harmoniously, they must be on the same version. This is crucial for both updating and downgrading: - -1. When updating the `typewriter.jar` file, simultaneously update all the adapters to the same version. -2. The same rule applies when downgrading; ensure that both the plugin and the adapters are reverted to matching versions. - -Maintaining version consistency between the Typewriter plugin and its adapters is key to preventing compatibility issues and ensuring a smooth operation. - ---- - -For further assistance, please reach out to our community on [Discord](https://discord.gg/HtbKyuDDBw). We're here to help make your experience with the Typewriter plugin as smooth as possible! - diff --git a/documentation/docs/docs/06-troubleshooting/extensions.mdx b/documentation/docs/docs/06-troubleshooting/extensions.mdx new file mode 100644 index 0000000000..6d6ebd7325 --- /dev/null +++ b/documentation/docs/docs/06-troubleshooting/extensions.mdx @@ -0,0 +1,31 @@ +--- +difficulty: Normal +--- + +# Extensions Troubleshooting + +Experiencing issues with your Typewriter Extensions? This guide provides step-by-step instructions to ensure your extensions are set up correctly and functioning optimally with the Typewriter plugin. + +## Correct Extension Placement + +It's important to note that extensions for the Typewriter plugin are not standard Paper plugins. They are special JAR files exclusively for Typewriter, and thus need to be stored separately. To ensure proper functioning: + +1. Navigate to the plugin directory: `/plugins/Typewriter/extensions`. +2. If an "extensions" folder does not exist, create one to store your new extensions. +3. Place your extension files inside this "extensions" folder. + +This dedicated folder ensures that Typewriter can correctly read and use these extensions without confusing them with regular Paper plugins. + +## Extension and Plugin Version Compatibility + +For the Typewriter plugin and its extensions to work harmoniously, they must be on the same version. This is crucial for both updating and downgrading: + +1. When updating the `typewriter.jar` file, simultaneously update all the extensions to the same version. +2. The same rule applies when downgrading; ensure that both the plugin and the extensions are reverted to matching versions. + +Maintaining version consistency between the Typewriter plugin and its extensions is key to preventing compatibility issues and ensuring a smooth operation. + +--- + +For further assistance, please reach out to our community on [Discord](https://discord.gg/HtbKyuDDBw). We're here to help make your experience with the Typewriter plugin as smooth as possible! + diff --git a/documentation/docs/docs/06-troubleshooting/index.mdx b/documentation/docs/docs/06-troubleshooting/index.mdx index b333f374fe..4920c533bb 100644 --- a/documentation/docs/docs/06-troubleshooting/index.mdx +++ b/documentation/docs/docs/06-troubleshooting/index.mdx @@ -22,20 +22,20 @@ For more detailed troubleshooting steps, refer to: [Panel not loading](troublesh No Entries -This issue typically occurs when no adapters are installed. To resolve this, ensure that adapters are correctly installed by following the steps outlined in the **[Basic Adapter Installation Tutorial](../02-getting-started/01-installation.mdx#basic-adapter)**. +This issue typically occurs when no extensions are installed. To resolve this, ensure that extensions are correctly installed by following the steps outlined in the **[Basic Extension Installation Tutorial](../02-getting-started/01-installation.mdx#basic-extension)**. -## Error: "plugin.yml not found" When Installing an Adapter +## Error: "plugin.yml not found" When Installing an Extension -If you encounter an error message similar to the following when installing an adapter: +If you encounter an error message similar to the following when installing an extension: ```log -[08:49:35 ERROR]: [DirectoryProviderSource] Error loading plugin: Directory 'plugins/BasicAdapter.jar' failed to load! -java.lang.RuntimeException: Directory 'plugins/BasicAdapter.jar' failed to load! +[08:49:35 ERROR]: [DirectoryProviderSource] Error loading plugin: Directory 'plugins/BasicExtension.jar' failed to load! +java.lang.RuntimeException: Directory 'plugins/BasicExtension.jar' failed to load! ... -Caused by: java.lang.IllegalArgumentException: Directory 'plugins/BasicAdapter.jar' does not contain a paper-plugin.yml or plugin.yml! Could not determine plugin type, cannot load a plugin from it! +Caused by: java.lang.IllegalArgumentException: Directory 'plugins/BasicExtension.jar' does not contain a paper-plugin.yml or plugin.yml! Could not determine plugin type, cannot load a plugin from it! ``` -This typically indicates that the adapter is not placed in the correct folder. For instructions on proper placement, see [Correct Adapter Placement](./adapters.mdx#correct-adapter-placement). +This typically indicates that the extension is not placed in the correct folder. For instructions on proper placement, see [Correct Extension Placement](./extensions.mdx#correct-extension-placement). ## Placeholders Not Parsing Correctly diff --git a/documentation/docs/docs/assets/entity-adapter/definition_select.png b/documentation/docs/docs/assets/entity-extension/definition_select.png similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/definition_select.png rename to documentation/docs/docs/assets/entity-extension/definition_select.png diff --git a/documentation/docs/docs/assets/entity-adapter/entity-interact-event-fields.png b/documentation/docs/docs/assets/entity-extension/entity-interact-event-fields.png similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/entity-interact-event-fields.png rename to documentation/docs/docs/assets/entity-extension/entity-interact-event-fields.png diff --git a/documentation/docs/docs/assets/entity-adapter/entity_location.webm b/documentation/docs/docs/assets/entity-extension/entity_location.webm similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/entity_location.webm rename to documentation/docs/docs/assets/entity-extension/entity_location.webm diff --git a/documentation/docs/docs/assets/entity-adapter/entity_name_change.png b/documentation/docs/docs/assets/entity-extension/entity_name_change.png similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/entity_name_change.png rename to documentation/docs/docs/assets/entity-extension/entity_name_change.png diff --git a/documentation/docs/docs/assets/entity-adapter/fetch_skin.webm b/documentation/docs/docs/assets/entity-extension/fetch_skin.webm similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/fetch_skin.webm rename to documentation/docs/docs/assets/entity-extension/fetch_skin.webm diff --git a/documentation/docs/docs/assets/entity-adapter/glow_editor.png b/documentation/docs/docs/assets/entity-extension/glow_editor.png similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/glow_editor.png rename to documentation/docs/docs/assets/entity-extension/glow_editor.png diff --git a/documentation/docs/docs/assets/entity-adapter/glow_effect.png b/documentation/docs/docs/assets/entity-extension/glow_effect.png similarity index 100% rename from documentation/docs/docs/assets/entity-adapter/glow_effect.png rename to documentation/docs/docs/assets/entity-extension/glow_effect.png diff --git a/documentation/docusaurus.config.js b/documentation/docusaurus.config.js index a277c41dd3..1ae08ce989 100644 --- a/documentation/docusaurus.config.js +++ b/documentation/docusaurus.config.js @@ -123,7 +123,7 @@ const config = { type: 'docSidebar', sidebarId: 'adapters', position: 'left', - label: 'Adapters', + label: 'Extensions', }, { type: 'docSidebar', diff --git a/documentation/plugins/code-snippets/codeSnippets.js b/documentation/plugins/code-snippets/codeSnippets.js index 6485dfed8b..4d6f16e26d 100644 --- a/documentation/plugins/code-snippets/codeSnippets.js +++ b/documentation/plugins/code-snippets/codeSnippets.js @@ -64,7 +64,7 @@ module.exports = function() { } // Assuming the adapters directory is at the root of your project - const adaptersDir = path.resolve(__dirname, '../../../adapters/_DocsAdapter'); + const adaptersDir = path.resolve(__dirname, '../../../extensions/_DocsExtension'); traverseDirectory(adaptersDir, adaptersDir); // console.log(`Exporting ${Object.keys(snippets).length} snippets: ${Object.keys(snippets)}`); diff --git a/documentation/plugins/code-snippets/snippets.json b/documentation/plugins/code-snippets/snippets.json index eb6f68eb83..09b958319a 100644 --- a/documentation/plugins/code-snippets/snippets.json +++ b/documentation/plugins/code-snippets/snippets.json @@ -1,98 +1,98 @@ { + "initializer": { + "file": "src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt", + "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Initializer\n\n@Initializer\nobject ExampleInitializer : Initializable {\n override fun initialize() {\n // Do something when the extension is initialized\n }\n\n override fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" + }, "cinematic_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", "content": "@Entry(\"example_cinematic\", \"An example cinematic entry\", Colors.BLUE, \"material-symbols:cinematic-blur\")\nclass ExampleCinematicEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n val segments: List = emptyList(),\n) : CinematicEntry {\n override fun create(player: Player): CinematicAction {\n return ExampleCinematicAction(player, this)\n }\n}" }, "cinematic_segment_with_min_max": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", "content": " @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n @InnerMin(Min(10))\n @InnerMax(Max(20))\n val segments: List = emptyList()," }, "cinematic_create_actions": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", "content": " // This will be used when the cinematic is normally displayed to the player.\n override fun create(player: Player): CinematicAction {\n return DefaultCinematicAction(player, this)\n }\n\n // This is used during content mode to display the cinematic to the player.\n // It may be null to not show it during simulation.\n override fun createSimulating(player: Player): CinematicAction? {\n return SimulatedCinematicAction(player, this)\n }\n\n // This is used during content mode to record the cinematic.\n // It may be null to not record it during simulation.\n override fun createRecording(player: Player): CinematicAction? {\n return RecordingCinematicAction(player, this)\n }" }, "cinematic_segment": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", "content": "data class ExampleSegment(\n override val startFrame: Int = 0,\n override val endFrame: Int = 0,\n) : Segment" }, "cinematic_action": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", "content": "class ExampleCinematicAction(\n val player: Player,\n val entry: ExampleCinematicEntry,\n) : CinematicAction {\n override suspend fun setup() {\n // Initialize variables, spawn entities, etc.\n }\n\n override suspend fun tick(frame: Int) {\n val segment = entry.segments activeSegmentAt frame\n // Can be null if no segment is active\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n\n // Execute tick logic for the segment\n }\n\n override suspend fun teardown() {\n // Remove entities, etc.\n }\n\n override fun canFinish(frame: Int): Boolean = entry.segments canFinishAt frame\n}" }, "cinematic_simple_action": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", "content": "class ExampleSimpleCinematicAction(\n val player: Player,\n entry: ExampleCinematicEntry,\n) : SimpleCinematicAction() {\n override val segments: List = entry.segments\n\n override suspend fun startSegment(segment: ExampleSegment) {\n super.startSegment(segment) // Keep this\n // Called when a segment starts\n }\n\n override suspend fun tickSegment(segment: ExampleSegment, frame: Int) {\n super.tickSegment(segment, frame) // Keep this\n // Called every tick while the segment is active\n // Will always be called after startSegment and never after stopSegment\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n }\n\n override suspend fun stopSegment(segment: ExampleSegment) {\n super.stopSegment(segment) // Keep this\n // Called when the segment ends\n // Will also be called if the cinematic is stopped early\n }\n}" }, "audience_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", "content": "@Entry(\"example_audience\", \"An example audience entry.\", Colors.GREEN, \"material-symbols:chat-rounded\")\nclass ExampleAudienceEntry(\n override val id: String,\n override val name: String,\n) : AudienceEntry {\n override fun display(): AudienceDisplay {\n return ExampleAudienceDisplay()\n }\n}" }, "audience_display": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", "content": "class ExampleAudienceDisplay : AudienceDisplay() {\n override fun initialize() {\n // This is called when the first player is added to the audience.\n super.initialize()\n // Do something when the audience is initialized\n }\n\n override fun onPlayerAdd(player: Player) {\n // Do something when a player gets added to the audience\n }\n\n override fun onPlayerRemove(player: Player) {\n // Do something when a player gets removed from the audience\n }\n\n override fun dispose() {\n super.dispose()\n // Do something when the audience is disposed\n // It will always call onPlayerRemove for all players.\n // So no player cleanup is needed here.\n }\n}" }, "tickable_audience_display": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", "content": "// highlight-next-line\nclass TickableAudienceDisplay : AudienceDisplay(), TickableDisplay {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n override fun tick() {\n // Do something when the audience is ticked\n players.forEach { player ->\n // Do something with the player\n }\n\n // This is running asynchronously\n // If you need to do something on the main thread\n ThreadType.SYNC.launch {\n // Though this will run a tick later, to sync with the bukkit scheduler.\n }\n }\n // highlight-end\n}" }, "audience_display_with_events": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", "content": "class AudienceDisplayWithEvents : AudienceDisplay() {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n @EventHandler\n fun onSomeEvent(event: SomeBukkitEvent) {\n // Do something when the event is triggered\n // This will trigger for all players, not just the ones in the audience.\n // So we need to check if the player is in the audience.\n if (event.player in this) {\n // Do something with the player\n }\n }\n // highlight-end\n}" }, "artifact_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleArtifactEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", "content": "@Entry(\"example_artifact\", \"An example artifact entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleArtifactEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val artifactId: String = \"\",\n) : ArtifactEntry" }, "artifact_access": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleArtifactEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", "content": "suspend fun accessArtifactData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" }, "asset_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleAssetEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", "content": "@Entry(\"example_asset\", \"An example asset entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleAssetEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val path: String = \"\",\n) : AssetEntry" }, "asset_access": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleAssetEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", "content": "suspend fun accessAssetData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" }, "sound_id_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundIdEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt", "content": "@Entry(\"example_sound\", \"An example sound entry.\", Colors.BLUE, \"icon-park-solid:volume-up\")\nclass ExampleSoundIdEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val soundId: String = \"\",\n) : SoundIdEntry" }, "sound_source_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundSourceEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt", "content": "@Entry(\"example_sound_source\", \"An example sound source entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSoundSourceEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n) : SoundSourceEntry {\n override fun getEmitter(): Sound.Emitter {\n // Return the emitter that should be used for the sound.\n // A bukkit entity can be used here.\n return Sound.Emitter.self()\n }\n}" }, "speaker_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSpeakerEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt", "content": "@Entry(\"example_speaker\", \"An example speaker entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSpeakerEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val displayName: String = \"\",\n override val sound: Sound = Sound.EMPTY,\n) : SpeakerEntry" }, "action_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleActionEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt", "content": "@Entry(\"example_action\", \"An example action entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n) : ActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply all the modifiers.\n // Do something with the player\n }\n}" }, "custom_triggering_action_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleCustomTriggeringActionEntry.kt", - "content": "@Entry(\"example_custom_triggering_action\", \"An example custom triggering entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleCustomTriggeringActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n @SerializedName(\"triggers\")\n override val customTriggers: List> = emptyList(),\n) : CustomTriggeringActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply the modifiers.\n // Do something with the player\n player.triggerCustomTriggers() // Can be called later to trigger the next entries.\n }\n}" + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt", + "content": "@Entry(\n \"example_custom_triggering_action\",\n \"An example custom triggering entry.\",\n Colors.RED,\n \"material-symbols:touch-app-rounded\"\n)\nclass ExampleCustomTriggeringActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n @SerializedName(\"triggers\")\n override val customTriggers: List> = emptyList(),\n) : CustomTriggeringActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply the modifiers.\n // Do something with the player\n player.triggerCustomTriggers() // Can be called later to trigger the next entries.\n }\n}" }, "dialogue_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleDialogueEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", "content": "@Entry(\"example_dialogue\", \"An example dialogue entry.\", Colors.BLUE, \"material-symbols:chat-rounded\")\nclass ExampleDialogueEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n override val speaker: Ref = emptyRef(),\n @MultiLine\n @Placeholder\n @Colored\n @Help(\"The text to display to the player.\")\n val text: String = \"\",\n) : DialogueEntry" }, "dialogue_messenger": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleDialogueEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", "content": "@Messenger(ExampleDialogueEntry::class)\nclass ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) :\n DialogueMessenger(player, entry) {\n\n companion object : MessengerFilter {\n override fun filter(player: Player, entry: DialogueEntry): Boolean = true\n }\n\n // Called every game tick (20 times per second).\n // The cycle is a parameter that is incremented every tick, starting at 0.\n override fun tick(playTime: Duration) {\n super.tick(playTime)\n if (state != MessengerState.RUNNING) return\n\n player.sendMessage(\"${entry.speakerDisplayName}: ${entry.text}\".parsePlaceholders(player).asMini())\n\n // When we want the dialogue to end, we can set the state to FINISHED.\n state = MessengerState.FINISHED\n }\n}" }, "event_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleEventEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", "content": "@Entry(\"example_event\", \"An example event entry.\", Colors.YELLOW, \"material-symbols:bigtop-updates\")\nclass ExampleEventEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n) : EventEntry" }, "event_entry_listener": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleEventEntry.kt", + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", "content": "// Must be scoped to be public\n@EntryListener(ExampleEventEntry::class)\nfun onEvent(event: SomeBukkitEvent, query: Query) {\n // Do something\n val entries = query.find() // Find all the entries of this type, for more information see the Query section\n // Do something with the entries, for example trigger them\n entries triggerAllFor event.player\n}" - }, - "adapter": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\ExampleAdapter.kt", - "content": "import me.gabber235.typewriter.adapters.Adapter\nimport me.gabber235.typewriter.adapters.TypewriterAdapter\n\n@Adapter(\"Example\", \"An example adapter for documentation purposes\", \"0.0.1\")\nobject ExampleAdapter : TypewriterAdapter() {\n override fun initialize() {\n // Do something when the adapter is initialized\n }\n\n override fun shutdown() {\n // Do something when the adapter is shutdown\n }\n}" } } \ No newline at end of file diff --git a/engine/build.gradle.kts b/engine/build.gradle.kts new file mode 100644 index 0000000000..8da425e3e7 --- /dev/null +++ b/engine/build.gradle.kts @@ -0,0 +1,78 @@ +plugins { + id("java") + kotlin("jvm") version "2.0.20" + id("java-library") + `maven-publish` + id("io.github.goooler.shadow") version "8.1.7" apply false +} + +group = "com.typewritermc" +val versionFile = if (file("version.txt").exists()) file("version.txt") else file("../version.txt") +version = versionFile.readText().trim() + +allprojects { + apply(plugin = "java") + apply(plugin = "kotlin") + + repositories { + mavenCentral() + // PacketEvents + maven("https://repo.codemc.io/repository/maven-snapshots/") + } + + + tasks.test { + useJUnitPlatform() + } + kotlin { + jvmToolchain(21) + } +} + +subprojects { + apply(plugin = "io.github.goooler.shadow") + apply(plugin = "java-library") + apply(plugin = "maven-publish") + + group = rootProject.group + version = rootProject.version + + dependencies { + api("io.insert-koin:koin-core:3.5.6") + compileOnly("com.google.code.gson:gson:2.11.0") + testImplementation(kotlin("test")) + } + + + publishing { + repositories { + maven { + name = "TypewriterReleases" + url = uri("https://maven.typewritermc.com/releases") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } + } + maven { + name = "TypewriterBeta" + url = uri("https://maven.typewritermc.com/beta") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } + } + } + publications { + create("maven") { + group = project.group + // Remove everything after the beta. So 1.0.0-beta-1 becomes 1.0.0 + version = project.version.toString().substringBefore("-beta") + artifactId = project.name + + from(components["kotlin"]) + artifact(tasks["shadowJar"]) + } + } + } +} diff --git a/engine/engine-core/build.gradle.kts b/engine/engine-core/build.gradle.kts new file mode 100644 index 0000000000..b64c5a10c9 --- /dev/null +++ b/engine/engine-core/build.gradle.kts @@ -0,0 +1,4 @@ +repositories {} +dependencies { + api(project(":engine-loader")) +} \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/TypewriterCore.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/TypewriterCore.kt new file mode 100644 index 0000000000..22e376edf6 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/TypewriterCore.kt @@ -0,0 +1,33 @@ +package com.typewritermc.core + +import com.typewritermc.core.entries.Library +import com.typewritermc.core.extension.Initializable +import com.typewritermc.core.extension.InitializableManager +import com.typewritermc.core.utils.Reloadable +import com.typewritermc.loader.ExtensionLoader +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import org.koin.core.qualifier.named +import java.io.File + +class TypewriterCore : KoinComponent, Reloadable { + private val directory by inject(named("baseDir")) + private val extensionLoader by inject() + private val library by inject() + private val initializableManager by inject() + + override fun load() { + val extensionJars = directory.resolve("extensions").listFiles()?.filter { it.name.endsWith(".jar") } ?: emptyList() + // Needs to be loaded first as it will load the classLoader + extensionLoader.load(extensionJars) + library.load() + initializableManager.load() + } + + override fun unload() { + initializableManager.unload() + library.unload() + // Needs to be last, as it will unload the classLoader + extensionLoader.unload() + } +} \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/Colors.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/Colors.kt new file mode 100644 index 0000000000..25fc6e952b --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/Colors.kt @@ -0,0 +1,19 @@ +package com.typewritermc.core.books.pages + +object Colors { + const val RED = "#D32F2F" + const val GREEN = "#4CAF50" + const val MEDIUM_SEA_GREEN = "#3CB371" + const val PALATINATE_BLUE = "#3366CC" + const val BLUE = "#1E88E5" + const val MYRTLE_GREEN = "#297373" + const val YELLOW = "#FBB612" + const val PURPLE = "#5843e6" + const val MEDIUM_PURPLE = "#9370DB" + const val BLUE_VIOLET = "#8A2BE2" + const val ORANGE = "#F57C00" + const val DARK_ORANGE = "#FF8C00" + const val ORANGE_RED = "#FF4500" + const val PINK = "#eb4bb8" + const val CYAN = "#0abab5" +} diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/PageType.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/PageType.kt new file mode 100644 index 0000000000..e06a9b2edb --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/books/pages/PageType.kt @@ -0,0 +1,22 @@ +package com.typewritermc.core.books.pages + +import com.google.gson.annotations.SerializedName + +enum class PageType(val id: String) { + @SerializedName("sequence") + SEQUENCE("sequence"), + + @SerializedName("static") + STATIC("static"), + + @SerializedName("cinematic") + CINEMATIC("cinematic"), + + @SerializedName("manifest") + MANIFEST("manifest"), + ; + + companion object { + fun fromId(id: String) = entries.firstOrNull { it.id == id } + } +} diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Entry.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Entry.kt new file mode 100644 index 0000000000..bbee8ec524 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Entry.kt @@ -0,0 +1,26 @@ +package com.typewritermc.core.entries + +import com.typewritermc.core.extension.annotations.Help +import java.util.* + +val Entry.formattedName: String + get() = name.split(".") + .joinToString(" | ") { part -> part.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } } + .split("_") + .joinToString(" ") { part -> part.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } } + +interface Entry { + val id: String + val name: String +} + +interface PriorityEntry : Entry { + /** + * Normally, the priority of an entry is determined by the priority of the page it is on. + * Subtypes may want to allow the user to override the priority for that specific entry. + * This is useful when entries need to have fine-grained control over their priority. + */ + @Help("The priority of the entry. If not set, the priority of the page will be used.") + val priorityOverride: Optional +} + diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryReference.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/EntryReference.kt similarity index 77% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryReference.kt rename to engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/EntryReference.kt index eae167277c..82cfb2f19a 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryReference.kt +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/EntryReference.kt @@ -1,6 +1,5 @@ -package me.gabber235.typewriter.entry +package com.typewritermc.core.entries -import me.gabber235.typewriter.utils.reloadable import org.koin.java.KoinJavaComponent import kotlin.reflect.KClass @@ -42,15 +41,15 @@ class Ref( return id == other.id } - override fun hashCode(): Int { - return id.hashCode() - } + override fun hashCode(): Int = id.hashCode() } fun List>.get(): List = mapNotNull { it.get() } val Ref.pageId: String? - get() { - val entryDatabase = KoinJavaComponent.get(EntryDatabase::class.java) - return entryDatabase.pageIdByEntryId(id) - } \ No newline at end of file + get() = KoinJavaComponent.get(Library::class.java) + .pages + .firstNotNullOfOrNull { page -> + if (page.entries.none { it.id == id }) return@firstNotNullOfOrNull null + page.id + } \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Library.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Library.kt new file mode 100644 index 0000000000..e337a1bc84 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Library.kt @@ -0,0 +1,98 @@ +package com.typewritermc.core.entries + +import com.google.gson.Gson +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import com.typewritermc.core.books.pages.PageType +import com.typewritermc.core.utils.Reloadable +import com.typewritermc.loader.ExtensionLoader +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import org.koin.core.qualifier.named +import java.io.File +import java.util.logging.Logger + +class Library : KoinComponent, Reloadable { + internal var pages: List = emptyList() + private set + internal var entries: List = emptyList() + private set + + internal var entryPriority = emptyMap, Int>() + private set + + private val logger: Logger by inject() + private val extensionLoader by inject() + private val directory by inject(named("baseDir")) + private val gson by inject(named("dataSerializer")) + + override fun load() { + pages = directory.resolve("pages").listFiles().orEmpty() + .filter { it.isFile && it.canRead() && it.name.endsWith(".json") } + .map { + val json = JsonParser.parseString(it.readText()) + if (!json.isJsonObject) throw IllegalArgumentException("Page ${it.name} does not contain a valid json object") + val obj = json.asJsonObject + obj.addProperty("id", it.name.removeSuffix(".json")) + obj + } + .map { parsePage(it) } + + entries = pages.flatMap { it.entries } + entryPriority = pages.flatMap { page -> + page.entries.map { entry -> + if (entry !is PriorityEntry) return@map entry.ref() to page.priority + entry.ref() to entry.priorityOverride.orElse(page.priority) + } + }.toMap() + + logger.info("Loaded ${entries.size} entries from ${pages.size} pages.") + } + + override fun unload() { + pages = emptyList() + entries = emptyList() + entryPriority = emptyMap() + } + + private fun parsePage(obj: JsonObject): Page { + val id = obj.getAsJsonPrimitive("id")?.asString ?: throw IllegalArgumentException("Page does not have an id") + val name = + obj.getAsJsonPrimitive("name")?.asString ?: throw IllegalArgumentException("Page $id does not have a name") + val type = obj.getAsJsonPrimitive("type")?.asString + ?: throw IllegalArgumentException("Page $name ($id) does not have a type ") + val pageType = + PageType.fromId(type) ?: throw IllegalArgumentException("Page $name ($id) has an invalid type $type") + val priority = obj.getAsJsonPrimitive("priority")?.asInt ?: 0 + + val entries = obj.getAsJsonArray("entries").mapNotNull { parseEntry(it.asJsonObject, name) } + + return Page(id, name, entries, pageType, priority) + } + + private fun parseEntry(obj: JsonObject, pageName: String): Entry? { + val id = obj.getAsJsonPrimitive("id")?.asString.logErrorIfNull("Entry does not have an id") ?: return null + // TODO: Remove type as valid field + val blueprintId = obj.getAsJsonPrimitive("blueprintId")?.asString ?: + obj.getAsJsonPrimitive("type")?.asString.logErrorIfNull("Entry '$id' does not have a blueprintId or type") ?: return null + val clazz = extensionLoader.entryClass(blueprintId) + .logErrorIfNull("Could not find entry class for '$id' on page '${pageName}' with type '$blueprintId' in any extension.") ?: return null + try { + return gson.fromJson(obj, clazz) + } catch (e: Exception) { + logger.warning("Failed to parse entry '$id' with blueprintId '$blueprintId' on page '${pageName}': ${e.message}") + return null + } + } + + private fun T?.logErrorIfNull(message: String): T? { + if (this == null) { + logger.severe(message) + } + return this + } +} + +val Entry.priority: Int get() = ref().priority +val Ref.priority: Int + get() = org.koin.java.KoinJavaComponent.get(Library::class.java).entryPriority[this] ?: 0 diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Page.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Page.kt new file mode 100644 index 0000000000..a78aef63c7 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Page.kt @@ -0,0 +1,12 @@ +package com.typewritermc.core.entries + +import com.typewritermc.core.books.pages.PageType + +data class Page( + val id: String = "", + val name: String = "", + val entries: List = emptyList(), + val type: PageType = PageType.SEQUENCE, + val priority: Int = 0 +) + diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Query.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Query.kt new file mode 100644 index 0000000000..f503adeb03 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/entries/Query.kt @@ -0,0 +1,246 @@ +package com.typewritermc.core.entries + +import com.typewritermc.core.books.pages.PageType +import org.koin.java.KoinJavaComponent.get +import kotlin.reflect.KClass + +/** + * A query can be used to search for entries. + * This is useful for events where you want to invoke all triggers for a specific entry given a query. + * + * @param klass The class of the entry. + */ +class Query(private val klass: KClass) { + + /** + * Find all entries that match the given a filter + * + * Example: + * ```kotlin + * val query: Query = ... + * query findWhere { it.someValue == "hello" } + * ``` + * + * It can be used in combination with [triggerAllFor] to invoke all triggers for all entries that match the filter. + * Example: + * ```kotlin + * val query: Query = ... + * query findWhere { it.someValue == "hello" } triggerAllFor player + * ``` + * + * @param filter The filter to apply to the entries. + */ + infix fun findWhere(filter: (E) -> Boolean): Sequence = findWhere(klass, filter) + + /** + * Find the first entry that matches the given a filter + * @see findWhere + */ + infix fun firstWhere(filter: (E) -> Boolean): E? = firstWhere(klass, filter) + + /** + * Find all the entries for the given class. + * + * Example: + * ```kotlin + * val query: Query = ... + * query.find() + * ``` + */ + fun find() = findWhere { true } + + /** + * Find entry by [name]. + * + * Example: + * ```kotlin + * val query: Query = ... + * query findByName "someName" + * ``` + */ + infix fun findByName(name: String) = firstWhere { it.name == name } + + /** + * Find entry by [id]. + * + * Example: + * ```kotlin + * val query: Query = ... + * query findById "someId" + * ``` + */ + infix fun findById(id: String): E? = findById(klass, id) + + /** + * Find entry all entries that are on the given page [pageId] with the given [filter]. + * @see findWhere + */ + fun findWhereFromPage(pageId: String, filter: (E) -> Boolean): Sequence = + findWhereFromPage(klass, pageId, filter) + + companion object { + /** + * Find all entries that match the given a filter + * + * Example: + * ```kotlin + * Query findWhere { it.someValue == "hello" } + * ``` + * + * It can be used in combination with [triggerAllFor] to invoke all triggers for all entries that match the filter. + * Example: + * ```kotlin + * Query findWhere { it.someValue == "hello" } triggerAllFor player + * ``` + * + * @param filter The filter to apply to the entries. + */ + inline infix fun findWhere(noinline filter: (E) -> Boolean): Sequence { + return findWhere(E::class, filter) + } + + /** + * Find all entries that match the given a filter + * + * Example: + * ```kotlin + * Query.findWhere(SomeEntry::class) { it.someValue == "hello" } + * ``` + * + * It can be used in combination with [triggerAllFor] to invoke all triggers for all entries that match the filter. + * Example: + * ```kotlin + * Query.findWhere(SomeEntry::class) { it.someValue == "hello" } triggerAllFor player + * ``` + * + * @param filter The filter to apply to the entries. + */ + fun findWhere(klass: KClass, filter: (E) -> Boolean): Sequence { + return get(Library::class.java).entries + .asSequence() + .filterIsInstance(klass.java) + .filter(filter) + } + + /** + * Find the first entry that matches the given a filter + * @see findWhere + */ + inline infix fun firstWhere(noinline filter: (E) -> Boolean): E? { + return firstWhere(E::class, filter) + } + + /** + * Find the first entry that matches the given a filter + * @see findWhere + */ + fun firstWhere(klass: KClass, filter: (E) -> Boolean): E? { + return get(Library::class.java).entries + .asSequence() + .filterIsInstance(klass.java) + .filter(filter) + .firstOrNull() + } + + + /** + * Find all the entries for the given class. + * + * Example: + * ```kotlin + * Query.find() + * ``` + */ + inline fun find() = findWhere { true } + + /** + * Find all the entries for the given class. + * + * Example: + * ```kotlin + * Query.find(SomeEntry::class) + * ``` + */ + fun find(klass: KClass) = findWhere(klass) { true } + + /** + * Find entry by [name]. + * + * Example: + * ```kotlin + * Query findByName "someName" + * ``` + */ + inline infix fun findByName(name: String) = firstWhere { it.name == name } + + /** + * Find entry by [name]. + * + * Example: + * ```kotlin + * Query.findByName(SomeEntry::class, "someName") + * ``` + */ + fun findByName(klass: KClass, name: String) = firstWhere(klass) { it.name == name } + + inline infix fun findById(id: String): E? = findById(E::class, id) + + /** + * Find entry by [id]. + * @see findByName + */ + fun findById(klass: KClass, id: String): E? = + get(Library::class.java).entries + .asSequence() + .filterIsInstance(klass.java) + .firstOrNull { it.id == id } + + /** + * Find entry all entries that are on the given page [pageId] with the given [filter]. + * @see findWhere + */ + inline fun findWhereFromPage(pageId: String, noinline filter: (E) -> Boolean): Sequence { + return findWhereFromPage(E::class, pageId, filter) + } + + /** + * Find entry all entries that are on the given page [pageId] with the given [filter]. + * @see findWhere + */ + fun findWhereFromPage(klass: KClass, pageId: String, filter: (E) -> Boolean): Sequence { + return get(Library::class.java).pages + .asSequence() + .filter { it.id == pageId } + .flatMap { it.entries } + .filterIsInstance(klass.java) + .filter(filter) + } + + /** + * Finds all pages which are of the given [type]. + * + * Example: + * ```kotlin + * Query.findPagesOfType(PageType.STATIC) + * ``` + */ + fun findPagesOfType(type: PageType): Sequence { + return get(Library::class.java).pages + .asSequence() + .filter { it.type == type } + } + + /** + * Finds a page by its [id]. + * + * Example: + * ```kotlin + * Query.findPageById("some_page_id") + * ``` + */ + fun findPageById(id: String): Page? { + return get(Library::class.java).pages + .firstOrNull { it.id == id } + } + } +} diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/Initializable.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/Initializable.kt new file mode 100644 index 0000000000..727e69edee --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/Initializable.kt @@ -0,0 +1,56 @@ +package com.typewritermc.core.extension + +import com.typewritermc.core.utils.Reloadable +import com.typewritermc.loader.ExtensionLoader +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import java.util.logging.Logger + +interface Initializable { + fun initialize() + fun shutdown() +} + +class InitializableManager : KoinComponent, Reloadable { + private val logger: Logger by inject() + private val extensionLoader: ExtensionLoader by inject() + + private var initializables: List = emptyList() + + override fun load() { + initializables = extensionLoader.extensions.flatMap { it.initializers } + .map { extensionLoader.loadClass(it.className).kotlin } + .mapNotNull { + val obj = it.objectInstance + if (obj == null) { + logger.warning("Initializer ${it.simpleName} is not an object. Make sure that it is a object class.") + return@mapNotNull null + } + val initializer = obj as? Initializable + if (initializer == null) { + logger.warning("Initializer ${it.simpleName} is not an Initializable. Make sure that it inherits from Initializable.") + return@mapNotNull null + } + initializer + } + + initializables.forEach { + try { + it.initialize() + } catch (e: Exception) { + logger.severe("Failed to initialize ${it.javaClass.simpleName}: ${e.message}") + } + } + } + + override fun unload() { + initializables.forEach { + try { + it.shutdown() + } catch (e: Exception) { + logger.severe("Failed to shutdown ${it.javaClass.simpleName}: ${e.message}") + } + } + initializables = emptyList() + } +} \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Default.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Default.kt new file mode 100644 index 0000000000..11f050a905 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Default.kt @@ -0,0 +1,14 @@ +package com.typewritermc.core.extension.annotations + +import org.intellij.lang.annotations.Language + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.SOURCE) +/** + * This allows you to specify a default value for the field. + * The default value must be a valid JSON string. + */ +annotation class Default( + @Language("JSON") + val json: String +) diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Entry.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Entry.kt new file mode 100644 index 0000000000..a4e37ee7d7 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Entry.kt @@ -0,0 +1,10 @@ +package com.typewritermc.core.extension.annotations + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +annotation class Entry( + val name: String, + val description: String, + val color: String, // Hex color + val icon: String, // Any https://icon-sets.iconify.design/ icon +) \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/EntryListener.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/EntryListener.kt new file mode 100644 index 0000000000..96068355ec --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/EntryListener.kt @@ -0,0 +1,34 @@ +package com.typewritermc.core.extension.annotations + +import com.typewritermc.core.entries.Entry +import com.typewritermc.loader.ListenerPriority +import kotlin.reflect.KClass + +/** + * Annotate a function to let Typewriter know that it should be called when a specific event occurs. + * + * When no entry of the specified class is registered, the bukkit listener will not be registered. + * + * The function must have at least one parameter, which is the event that occurred. + * Other parameters are optional and can be used to inject dependencies. + * Such as [Query]. + * + * Example: + * ```kotlin + * @EventListener(InteractEventEntry::class) + * fun onEntryCreated(event: PlayerInteractEvent, query: Query) { + * // ... + * } + * ``` + * + * IMPORTANT: The function must be a top-level function. + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class EntryListener( + // TODO: Make this only accept EventEntry + val entry: KClass, + val priority: ListenerPriority = ListenerPriority.NORMAL, + val ignoreCancelled: Boolean = false +) + diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Initializer.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Initializer.kt new file mode 100644 index 0000000000..20ed1ae13b --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Initializer.kt @@ -0,0 +1,3 @@ +package com.typewritermc.core.extension.annotations + +annotation class Initializer() diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Messenger.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Messenger.kt new file mode 100644 index 0000000000..c1c24b4b6f --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Messenger.kt @@ -0,0 +1,19 @@ +package com.typewritermc.core.extension.annotations + +import com.typewritermc.core.entries.Entry +import kotlin.reflect.KClass + +@Target(AnnotationTarget.CLASS) +/** + * The [Messenger] annotation is used to mark a class as a messenger for a specific [DialogueEntry]. + * Messengers are responsible for displaying the dialogue to the player. + * + * Only one messenger will be selected to display a given [DialogueEntry] to a player. + * The [priority] property is used to determine which messenger to use. + * The higher the value, the earlier the messenger will be looked for. + */ +annotation class Messenger( + // TODO: Only allow DialogueEntry + val dialogue: KClass, + val priority: Int = 0, +) \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Modifiers.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Modifiers.kt new file mode 100644 index 0000000000..440c2a6806 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Modifiers.kt @@ -0,0 +1,160 @@ +package com.typewritermc.core.extension.annotations + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.books.pages.PageType +import kotlin.reflect.KClass + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * Allows you to specify a way to capture the content of the field in game. + * TODO: Make the capturer a KClass + */ +annotation class ContentEditor(val capturer: KClass<*>) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This field allows [Adventure MiniMessages](https://docs.advntr.dev/minimessage/format.html) to be used in the field. + */ +annotation class Colored + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This will generate a random UUID as default value for the field. + */ +annotation class Generated + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to add a tooltip to the field. + */ +annotation class Help(val text: String) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify an icon from [Iconify](https://iconify.design/) for the field. + */ +annotation class Icon(val icon: String) + + +enum class MaterialProperty { + ITEM, + BLOCK, + SOLID, + TRANSPARENT, + FLAMMABLE, + BURNABLE, + EDIBLE, + FUEL, + INTRACTABLE, + OCCLUDING, + RECORD, + TOOL, + WEAPON, + ARMOR, + ORE, +} + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify the properties of the material. + */ +annotation class MaterialProperties(vararg val properties: MaterialProperty) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify that the field allows multiple lines. + */ +annotation class MultiLine + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows for negative numbers to be used in the field. + */ +annotation class Negative + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify which tags the entries must have to be accepted. + */ +annotation class OnlyTags(vararg val tags: String) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify the type of the page for the field. + */ +annotation class Page(val type: PageType) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to use [PlaceholderAPI](https://www.spigotmc.org/reRUNTIMEs/placeholderapi.6245/) placeholders in the field. + */ +annotation class Placeholder + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify a [Regex](https://www.autoregex.xyz/) for the field. + */ +annotation class Regex + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you mark this field as a Segment for a cinematic. + */ +annotation class Segments(val color: String = Colors.CYAN, val icon: String = "fa6-solid:star") + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify a minimum value for the field. + */ +annotation class Min(val value: Int) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify a minimum value on the inner field. + * This is useful for lists and maps. + */ +annotation class InnerMin(val annotation: Min) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify a maximum value for the field. + */ +annotation class Max(val value: Int) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows you to specify a maximum value on the inner field. + * This is useful for lists and maps. + */ +annotation class InnerMax(val annotation: Max) + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This requires the field to only accept snake_case. + */ +annotation class SnakeCase + +@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.RUNTIME) +/** + * This allows the yaw, pitch of the location to be specified. + */ +annotation class WithRotation diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Tags.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Tags.kt new file mode 100644 index 0000000000..4c165bdf85 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/extension/annotations/Tags.kt @@ -0,0 +1,4 @@ +package com.typewritermc.core.extension.annotations + +@Target(AnnotationTarget.CLASS) +annotation class Tags(vararg val tags: String) \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Looping.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Looping.kt similarity index 94% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Looping.kt rename to engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Looping.kt index b9dfd47716..8a3b317a80 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Looping.kt +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Looping.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.core.utils import kotlin.math.max import kotlin.math.min diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Reloadable.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Reloadable.kt new file mode 100644 index 0000000000..99404aa8d4 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Reloadable.kt @@ -0,0 +1,6 @@ +package com.typewritermc.core.utils + +interface Reloadable { + fun load() + fun unload() +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Result.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Result.kt similarity index 92% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Result.kt rename to engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Result.kt index 79c9480c18..bd6c1e8b04 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Result.kt +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/Result.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.core.utils fun ok(value: T): Result = Result.success(value) diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Coordinate.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Coordinate.kt new file mode 100644 index 0000000000..38a1bf6220 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Coordinate.kt @@ -0,0 +1,100 @@ +package com.typewritermc.core.utils.point + +import kotlin.math.atan2 +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt + +data class Coordinate( + override val x: Double = 0.0, + override val y: Double = 0.0, + override val z: Double = 0.0, + override val yaw: Float = 0f, + override val pitch: Float = 0f, +) : com.typewritermc.core.utils.point.Point, com.typewritermc.core.utils.point.Rotatable { + + override fun withX(x: Double): com.typewritermc.core.utils.point.Coordinate = copy(x = x) + + override fun withY(y: Double): com.typewritermc.core.utils.point.Coordinate = copy(y = y) + + override fun withZ(z: Double): com.typewritermc.core.utils.point.Coordinate = copy(z = z) + + override fun withYaw(yaw: Float): com.typewritermc.core.utils.point.Coordinate = copy(yaw = yaw) + + override fun withPitch(pitch: Float): com.typewritermc.core.utils.point.Coordinate = copy(pitch = pitch) + + override fun rotateYaw(angle: Float): com.typewritermc.core.utils.point.Coordinate = copy(yaw = this.yaw + angle) + + override fun rotatePitch(angle: Float): com.typewritermc.core.utils.point.Coordinate = copy(pitch = this.pitch + angle) + + override fun rotate(yaw: Float, pitch: Float): com.typewritermc.core.utils.point.Coordinate = copy(yaw = this.yaw + yaw, pitch = this.pitch + pitch) + + override fun add(x: Double, y: Double, z: Double): com.typewritermc.core.utils.point.Coordinate { + return copy(x = this.x + x, y = this.y + y, z = this.z + z) + } + + override fun add(point: com.typewritermc.core.utils.point.Point) = add(point.x, point.y, point.z) + + override fun add(value: Double) = add(value, value, value) + + override fun plus(point: com.typewritermc.core.utils.point.Point) = add(point) + + override fun plus(value: Double) = add(value) + + override fun sub(x: Double, y: Double, z: Double): com.typewritermc.core.utils.point.Coordinate { + return copy(x = this.x - x, y = this.y - y, z = this.z - z) + } + + override fun sub(point: com.typewritermc.core.utils.point.Point) = sub(point.x, point.y, point.z) + + override fun sub(value: Double) = sub(value, value, value) + + override fun minus(point: com.typewritermc.core.utils.point.Point) = sub(point) + + override fun minus(value: Double) = sub(value) + + override fun mul(x: Double, y: Double, z: Double): com.typewritermc.core.utils.point.Coordinate { + return copy(x = this.x * x, y = this.y * y, z = this.z * z) + } + + override fun mul(point: com.typewritermc.core.utils.point.Point) = mul(point.x, point.y, point.z) + + override fun mul(value: Double) = mul(value, value, value) + + override fun times(point: com.typewritermc.core.utils.point.Point) = mul(point) + + override fun times(value: Double) = mul(value) + + override fun div(x: Double, y: Double, z: Double): com.typewritermc.core.utils.point.Coordinate { + return copy(x = this.x / x, y = this.y / y, z = this.z / z) + } + + override fun div(point: com.typewritermc.core.utils.point.Point) = div(point.x, point.y, point.z) + + override fun div(value: Double) = div(value, value, value) + + override fun lookAt(point: com.typewritermc.core.utils.point.Point): com.typewritermc.core.utils.point.Coordinate { + val x = point.x - this.x + val y = point.y - this.y + val z = point.z - this.z + + val yaw = Math.toDegrees(atan2(x, z)).toFloat() + val pitch = Math.toDegrees(atan2(y, sqrt(x.squared() + z.squared()))).toFloat() + + return copy(yaw = yaw, pitch = pitch) + } + + override fun resetRotation(): com.typewritermc.core.utils.point.Coordinate = copy(yaw = 0f, pitch = 0f) + + override fun directionVector(): com.typewritermc.core.utils.point.Vector { + val radYaw = Math.toRadians(yaw.toDouble()) + val radPitch = Math.toRadians(pitch.toDouble()) + val x = -cos(radPitch) * sin(radYaw) + val y = -sin(radPitch) + val z = cos(radPitch) * cos(radYaw) + return com.typewritermc.core.utils.point.Vector(x, y, z) + } +} + +fun com.typewritermc.core.utils.point.Coordinate.toPosition(world: com.typewritermc.core.utils.point.World) = + com.typewritermc.core.utils.point.Position(world, x, y, z, yaw, pitch) \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Point.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Point.kt similarity index 80% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Point.kt rename to engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Point.kt index d33bbf0f8f..74aeb7b04e 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Point.kt +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Point.kt @@ -1,6 +1,5 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.core.utils.point -import org.bukkit.util.NumberConversions.square import org.jetbrains.annotations.Contract import java.util.function.DoubleUnaryOperator import kotlin.math.floor @@ -117,7 +116,7 @@ interface Point { fun withZ(z: Double): Point @Contract(pure = true) - fun add(x: Double, y: Double, z: Double): Point + fun add(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Point @Contract(pure = true) fun add(point: Point): Point @@ -130,7 +129,7 @@ interface Point { operator fun plus(value: Double): Point @Contract(pure = true) - fun sub(x: Double, y: Double, z: Double): Point + fun sub(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Point @Contract(pure = true) fun sub(point: Point): Point @@ -143,7 +142,7 @@ interface Point { operator fun minus(value: Double): Point @Contract(pure = true) - fun mul(x: Double, y: Double, z: Double): Point + fun mul(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0): Point @Contract(pure = true) fun mul(point: Point): Point @@ -156,7 +155,7 @@ interface Point { operator fun times(value: Double): Point @Contract(pure = true) - fun div(x: Double, y: Double, z: Double): Point + fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0): Point @Contract(pure = true) operator fun div(point: Point): Point @@ -166,7 +165,7 @@ interface Point { @Contract(pure = true) fun distanceSquared(x: Double, y: Double, z: Double): Double { - return square(this.x - x) + square(this.y - y) + square(this.z - z) + return (this.x - x).squared() + (this.y - y).squared() + (this.z - z).squared() } /** @@ -236,5 +235,30 @@ interface Point { fun sameBlock(point: Point): Boolean { return sameBlock(point.blockX, point.blockY, point.blockZ) } + + /** + * Checks if two points are in range of each other. + * + * @param point the point to compare to + * @param range the range to check + * @return true if the distance between the two points is less than or equal to the range + */ + fun isInRange(point: Point, range: Double): Boolean { + return isInRange(point.x, point.y, point.z, range) + } + + /** + * Checks if two points are in range of each other. + * + * @param x the x coordinate of the point to compare to + * @param y the y coordinate of the point to compare to + * @param z the z coordinate of the point to compare to + * @param range the range to check + * @return true if the distance between the two points is less than or equal to the range + */ + fun isInRange(x: Double, y: Double, z: Double, range: Double): Boolean { + return distanceSquared(x, y, z) <= range * range + } } +fun Double.squared(): Double = this * this \ No newline at end of file diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Position.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Position.kt new file mode 100644 index 0000000000..6d42c93df6 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Position.kt @@ -0,0 +1,137 @@ +package com.typewritermc.core.utils.point + +import java.util.Objects +import kotlin.math.atan2 +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt + +open class Position( + val world: World, + override val x: Double = 0.0, + override val y: Double = 0.0, + override val z: Double = 0.0, + override val yaw: Float = 0f, + override val pitch: Float = 0f, +) : Point, Rotatable { + companion object { + val ORIGIN = Position(World(""), 0.0, 0.0, 0.0, 0f, 0f) + } + + override fun withX(x: Double): Position = copy(x = x) + + override fun withY(y: Double): Position = copy(y = y) + + override fun withZ(z: Double): Position = copy(z = z) + + override fun withYaw(yaw: Float): Position = copy(yaw = yaw) + + override fun withPitch(pitch: Float): Position = copy(pitch = pitch) + + override fun rotateYaw(angle: Float): Position = copy(yaw = this.yaw + angle) + + override fun rotatePitch(angle: Float): Position = copy(pitch = this.pitch + angle) + + override fun rotate(yaw: Float, pitch: Float): Position = copy(yaw = this.yaw + yaw, pitch = this.pitch + pitch) + + override fun add(x: Double, y: Double, z: Double): Position { + return copy(x = this.x + x, y = this.y + y, z = this.z + z) + } + + override fun add(point: Point) = add(point.x, point.y, point.z) + + override fun add(value: Double) = add(value, value, value) + + override fun plus(point: Point) = add(point) + + override fun plus(value: Double) = add(value) + + override fun sub(x: Double, y: Double, z: Double): Position { + return copy(x = this.x - x, y = this.y - y, z = this.z - z) + } + + override fun sub(point: Point) = sub(point.x, point.y, point.z) + + override fun sub(value: Double) = sub(value, value, value) + + override fun minus(point: Point) = sub(point) + + override fun minus(value: Double) = sub(value) + + override fun mul(x: Double, y: Double, z: Double): Position { + return copy(x = this.x * x, y = this.y * y, z = this.z * z) + } + + override fun mul(point: Point) = mul(point.x, point.y, point.z) + + override fun mul(value: Double) = mul(value, value, value) + + override fun times(point: Point) = mul(point) + + override fun times(value: Double) = mul(value) + + override fun div(x: Double, y: Double, z: Double): Position { + return copy(x = this.x / x, y = this.y / y, z = this.z / z) + } + + override fun div(point: Point) = div(point.x, point.y, point.z) + + override fun div(value: Double) = div(value, value, value) + + override fun lookAt(point: Point): Position { + val x = point.x - this.x + val y = point.y - this.y + val z = point.z - this.z + + val yaw = Math.toDegrees(atan2(x, z)).toFloat() + val pitch = Math.toDegrees(atan2(y, sqrt(x.squared() + z.squared()))).toFloat() + + return copy(yaw = yaw, pitch = pitch) + } + + override fun resetRotation(): Position = copy(yaw = 0f, pitch = 0f) + + override fun directionVector(): Vector { + val radYaw = Math.toRadians(yaw.toDouble()) + val radPitch = Math.toRadians(pitch.toDouble()) + val x = -cos(radPitch) * sin(radYaw) + val y = -sin(radPitch) + val z = cos(radPitch) * cos(radYaw) + return Vector(x, y, z) + } + + fun isInRange(point: Position, range: Double): Boolean { + if (this.world != point.world) return false + return isInRange(point.x, point.y, point.z, range) + } + + open fun copy( + world: World = this.world, + x: Double = this.x, + y: Double = this.y, + z: Double = this.z, + yaw: Float = this.yaw, + pitch: Float = this.pitch, + ): Position { + return Position(world, x, y, z, yaw, pitch) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Position) return false + + if (world != other.world) return false + if (x != other.x) return false + if (y != other.y) return false + if (z != other.z) return false + if (yaw != other.yaw) return false + if (pitch != other.pitch) return false + + return true + } + + override fun hashCode(): Int = Objects.hash(world, x, y, z, yaw, pitch) + override fun toString(): String { + return "Position(world=$world, x=$x, y=$y, z=$z, yaw=$yaw, pitch=$pitch)" + } +} diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Rotatable.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Rotatable.kt new file mode 100644 index 0000000000..6a03469de0 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Rotatable.kt @@ -0,0 +1,79 @@ +package com.typewritermc.core.utils.point + +/** + * Interface representing a rotatable object with yaw and pitch angles. + */ +interface Rotatable { + /** + * The yaw angle in degrees. + */ + val yaw: Float + + /** + * The pitch angle in degrees. + */ + val pitch: Float + + /** + * Creates a new instance with the specified yaw angle. + * + * @param yaw the new yaw angle + * @return a new instance with the updated yaw angle + */ + fun withYaw(yaw: Float): Rotatable + + /** + * Creates a new instance with the specified pitch angle. + * + * @param pitch the new pitch angle + * @return a new instance with the updated pitch angle + */ + fun withPitch(pitch: Float): Rotatable + + /** + * Rotates the yaw angle by the specified amount. + * + * @param angle the amount to rotate the yaw angle by + * @return a new instance with the updated yaw angle + */ + fun rotateYaw(angle: Float): Rotatable + + /** + * Rotates the pitch angle by the specified amount. + * + * @param angle the amount to rotate the pitch angle by + * @return a new instance with the updated pitch angle + */ + fun rotatePitch(angle: Float): Rotatable + + /** + * Rotates both the yaw and pitch angles by the specified amounts. + * + * @param yaw the amount to rotate the yaw angle by + * @param pitch the amount to rotate the pitch angle by + * @return a new instance with the updated yaw and pitch angles + */ + fun rotate(yaw: Float, pitch: Float): Rotatable + + /** + * Rotates to look at the specified point. + * + * @param point the point to look at + * @return a new instance with the updated yaw and pitch angles + */ + fun lookAt(point: Point): Rotatable + + /** + * Resets the rotation to the default values (yaw = 0, pitch = 0). + * + * @return a new instance with the default yaw and pitch angles + */ + fun resetRotation(): Rotatable + + /** + * Gets the direction vector based on the current yaw and pitch angles. + * + * @return the direction vector + */ + fun directionVector(): Vector +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Vector.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Vector.kt similarity index 81% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Vector.kt rename to engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Vector.kt index e93df89bf8..8d6be48204 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Vector.kt +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/Vector.kt @@ -1,7 +1,5 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.core.utils.point -import com.github.retrooper.packetevents.util.Vector3d -import com.github.retrooper.packetevents.util.Vector3f import kotlin.math.sqrt data class Vector( @@ -9,7 +7,6 @@ data class Vector( override val y: Double = 0.0, override val z: Double = 0.0, ) : Point { - constructor(x: Int, y: Int, z: Int) : this(x.toDouble(), y.toDouble(), z.toDouble()) companion object { @@ -23,9 +20,6 @@ data class Vector( val length: Double get() = sqrt(lengthSquared) - fun toPacketVector3f() = Vector3f(x.toFloat(), y.toFloat(), z.toFloat()) - fun toPacketVector3d() = Vector3d(x, y, z) - fun toBukkitVector(): org.bukkit.util.Vector = org.bukkit.util.Vector(x, y, z) fun lerp(other: Vector, alpha: Double): Vector { return Vector( @@ -35,7 +29,6 @@ data class Vector( ) } - override fun withX(x: Double): Vector = copy(x = x) override fun withY(y: Double): Vector = copy(y = y) @@ -95,15 +88,13 @@ data class Vector( } } - fun mid(): Vector = add(0.5, 0.0, 0.5) -} - -fun org.bukkit.util.Vector.toVector(): Vector { - return Vector(x, y, z) -} + private fun lerp(a: Double, b: Double, alpha: Double): Double { + return a + alpha * (b - a) + } -private fun lerp(a: Double, b: Double, alpha: Double): Double { - return a + alpha * (b - a) + fun mid(): Vector { + return Vector(x.toInt() + 0.5, y.toInt().toDouble(), z.toInt() + 0.5) + } } fun Point.toVector(): Vector { diff --git a/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/World.kt b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/World.kt new file mode 100644 index 0000000000..2d2adf8244 --- /dev/null +++ b/engine/engine-core/src/main/kotlin/com/typewritermc/core/utils/point/World.kt @@ -0,0 +1,5 @@ +package com.typewritermc.core.utils.point + +data class World( + val identifier: String, +) \ No newline at end of file diff --git a/engine/engine-loader/build.gradle.kts b/engine/engine-loader/build.gradle.kts new file mode 100644 index 0000000000..6c2a477268 --- /dev/null +++ b/engine/engine-loader/build.gradle.kts @@ -0,0 +1,4 @@ +repositories {} +dependencies { + compileOnly("org.jetbrains.kotlin:kotlin-reflect:2.0.10") +} \ No newline at end of file diff --git a/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DataSerializer.kt b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DataSerializer.kt new file mode 100644 index 0000000000..9074439715 --- /dev/null +++ b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DataSerializer.kt @@ -0,0 +1,22 @@ +package com.typewritermc.loader + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.google.gson.JsonDeserializer +import com.google.gson.JsonSerializer +import java.lang.reflect.Type + +interface DataSerializer : JsonSerializer, JsonDeserializer { + val type: Type +} + +fun createDataSerializerGson(serializers: List>): Gson { + var builder = GsonBuilder() + + serializers.forEach { + builder = builder.registerTypeAdapter(it.type, it) + } + + return builder + .create() +} diff --git a/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DependencyChecker.kt b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DependencyChecker.kt new file mode 100644 index 0000000000..753e492a5f --- /dev/null +++ b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/DependencyChecker.kt @@ -0,0 +1,5 @@ +package com.typewritermc.loader + +interface DependencyChecker { + fun hasDependency(dependency: String): Boolean +} \ No newline at end of file diff --git a/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ExtensionLoader.kt b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ExtensionLoader.kt new file mode 100644 index 0000000000..e5de8fefbd --- /dev/null +++ b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ExtensionLoader.kt @@ -0,0 +1,245 @@ +package com.typewritermc.loader + +import com.google.gson.Gson +import com.google.gson.JsonArray +import com.google.gson.JsonParser +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import org.koin.core.qualifier.named +import java.io.File +import java.net.URLClassLoader +import java.util.logging.Logger +import java.util.zip.ZipFile +import kotlin.math.abs +import kotlin.math.log10 + +class ExtensionLoader : KoinComponent { + private val logger: Logger by inject() + private val dependencyChecker: DependencyChecker by inject() + private val gson: Gson by inject(named("dataSerializer")) + private var classLoader: URLClassLoader? = null + var extensions: List = emptyList() + private set + private var entryClasses: Map> = emptyMap() + + // This value is not reset when the extensions are reloaded. Since we don't want to show the big message every time. + private var hasShownLoadedMessage = false + + + // TODO: Remove this when the database update is implemented + var extensionJson: JsonArray = JsonArray() + + fun load(jars: List) { + jars.forEach { assert(it.exists() && it.canRead() && it.endsWith(".jar")) } + + if (classLoader != null) { + unload() + } + classLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), this::class.java.classLoader) + + // In all the jars, there is a file called "extension.json" + val extensionJsonTexts = jars.mapNotNull { jar -> + ZipFile(jar).use { zip -> + val jsonEntry = zip.getEntry("extension.json") + if (jsonEntry == null) { + logger.severe("No extension.json file found in jar: ${jar.name}, is this a valid Typewriter extension?") + return@mapNotNull null + } + zip.getInputStream(jsonEntry).bufferedReader().use { it.readText() } + } + } + + + // TODO: Remove this when the database update is implemented + extensionJson = JsonArray() + + extensions = extensionJsonTexts.map { extensionJson -> + gson.fromJson(extensionJson, Extension::class.java) to extensionJson + }.filter { (extension, _) -> + val paper = extension.extension.paper + if (paper == null) { + logger.warning("Extension '${extension.extension.name}Extension' does not seem to be a paper extension. Ignoring extension.") + return@filter false + } + + val dependencies = paper.dependencies + val missingDependencies = dependencies.filter { !dependencyChecker.hasDependency(it) } + if (missingDependencies.isNotEmpty()) { + val missing = missingDependencies.joinToString(", ") + logger.warning( + "Extension '${extension.extension.name}Extension' is missing dependencies: '${missing}'. Ignoring extension." + ) + return@filter false + } + + true + }.map { (extension, extensionJson) -> + // TODO: Remove this when the database update is implemented + this.extensionJson.add(JsonParser.parseString(extensionJson)) + + extension + } + + if (hasShownLoadedMessage) return + hasShownLoadedMessage = true + + if (extensions.isEmpty()) { + logger.warning( + """ + | + |${"-".repeat(15)}{ No Extensions Loaded }${"-".repeat(15)} + | + |No extensions were loaded. + |You should always have at least the BasicExtension loaded. + | + |${"-".repeat(50)} + """.trimMargin() + ) + } else { + val unsupportedMessage = if (extensions.any { it.extension.flags.contains(ExtensionFlag.Unsupported) }) { + "\nThere are unsupported extensions loaded. You won't get any support for these and should migrate them away from.\n" + } else { + "" + } + val maxExtensionLength = extensions.maxOf { it.extension.name.length } + val maxVersionLength = extensions.maxOf { it.extension.version.length } + val maxDigits = extensions.maxOf { it.entries.size.digits } + val extensionsDisplay = extensions.sortedBy { it.extension.name } + .joinToString("\n") { it.displayString(maxExtensionLength, maxVersionLength, maxDigits) } + logger.info( + """ + | + |${"-".repeat(15)}{ Loaded Extensions }${"-".repeat(15)} + | + |${extensionsDisplay} + |$unsupportedMessage + |${"-".repeat(50)} + """.trimMargin() + ) + } + } + + fun entryClass(blueprintId: String): Class<*>? { + val entryClass = entryClasses[blueprintId] + if (entryClass != null) return entryClass + + val entryClassName = extensions.firstNotNullOfOrNull { extension -> + extension.entries.firstOrNull { it.id == blueprintId }?.className + } + + if (entryClassName == null) { + return null + } + + return loadClass(entryClassName) + } + + fun loadClass(className: String): Class<*> { + classLoader?.let { + return it.loadClass(className) + } + throw IllegalStateException("ExtensionLoader tried to load a class before it was initialized") + } + + fun unload() { + classLoader?.close() + classLoader = null + extensions = emptyList() + entryClasses = emptyMap() + } +} + +data class Extension( + val extension: ExtensionInfo, + val entries: List, + val entryListeners: List, + val dialogueMessengers: List, + val initializers: List, +) + +data class ExtensionInfo( + val name: String = "", + val shortDescription: String = "", + val description: String = "", + val version: String = "", + val flags: List = emptyList(), + val paper: PaperExtensionInfo? = null, +) + +data class PaperExtensionInfo( + val dependencies: List = emptyList(), +) + +/** + * Returns a string that can be used to display information about the adapter. + * It is nicely formatted to align the information between adapters. + */ +fun Extension.displayString(maxAdapterLength: Int, maxVersionLength: Int, maxDigits: Int): String { + var display = "${extension.name}Extension".rightPad(maxAdapterLength + "Extension".length) + display += " (${extension.version})".rightPad(maxVersionLength + 2) + display += padCount("πŸ“š", entries.size, maxDigits) + display += padCount("πŸ‘‚", entryListeners.size, maxDigits) + display += padCount("πŸ’¬", dialogueMessengers.size, maxDigits) + + extension.flags.filter { it.warning.isNotBlank() }.joinToString { it.warning }.let { + if (it.isNotBlank()) { + display += " ($it)" + } + } + + return display +} + +private fun padCount(prefix: String, count: Int, maxDigits: Int): String { + return " ${prefix}: ${" ".repeat((maxDigits - count.digits).coerceAtLeast(0))}$count" +} + +private fun String.rightPad(length: Int, padChar: Char = ' '): String { + return if (this.length >= length) this else this + padChar.toString().repeat(length - this.length) +} + +private val Int.digits: Int + get() = if (this == 0) 1 else log10(abs(this.toDouble())).toInt() + 1 + +data class EntryInfo( + val id: String, + val className: String, +) + +data class EntryListenerInfo( + val entryBlueprintId: String, + val entryClassName: String, + val className: String, + val methodName: String, + val priority: ListenerPriority, + val ignoreCancelled: Boolean, + val arguments: List, +) + +data class DialogueMessengerInfo( + val entryBlueprintId: String, + val entryClassName: String, + val className: String, + val priority: Int, +) + +data class InitializerInfo( + val className: String, +) + +enum class ExtensionFlag(val warning: String) { + /** + * The extension is not tested and may not work. + */ + Untested("⚠\uFE0F UNTESTED"), + + /** + * The extension is deprecated and should not be used. + */ + Deprecated("⚠\uFE0F DEPRECATED"), + + /** + * The extension is not supported and should be migrated away from. + */ + Unsupported("⚠\uFE0F UNSUPPORTED"), +} diff --git a/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ListenerPriority.kt b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ListenerPriority.kt new file mode 100644 index 0000000000..e8f1b7a867 --- /dev/null +++ b/engine/engine-loader/src/main/kotlin/com/typewritermc/loader/ListenerPriority.kt @@ -0,0 +1,10 @@ +package com.typewritermc.loader + +enum class ListenerPriority { + LOWEST, + LOW, + NORMAL, + HIGH, + HIGHEST, + MONITOR, +} diff --git a/plugin/build.gradle.kts b/engine/engine-paper/build.gradle.kts similarity index 66% rename from plugin/build.gradle.kts rename to engine/engine-paper/build.gradle.kts index 7a4825a0fe..ab7eea8364 100644 --- a/plugin/build.gradle.kts +++ b/engine/engine-paper/build.gradle.kts @@ -1,28 +1,12 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import io.papermc.hangarpublishplugin.model.Platforms -import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly import java.io.ByteArrayOutputStream plugins { - id("java") - kotlin("jvm") version "2.0.0" - `maven-publish` - id("io.github.goooler.shadow") version "8.1.7" - id("java-library") + id("xyz.jpenilla.resource-factory-bukkit-convention") version "1.1.2" id("io.papermc.hangar-publish-plugin") version "0.1.2" } -fun Project.findPropertyOr(property: String, default: String): String { - val prop = findProperty(property)?.toString() ?: "" - if (prop.isBlank()) return default - if (prop == "unspecified") return default - return prop -} - -group = project.findPropertyOr("group", "com.github.gabber235") -val versionFile = if (file("version.txt").exists()) file("version.txt") else file("../version.txt") -version = project.findPropertyOr("version", versionFile.readText().trim()) - repositories { mavenCentral() // Floodgate @@ -34,12 +18,12 @@ repositories { // PaperMC maven("https://repo.papermc.io/repository/maven-public/") // EntityLib - maven("https://jitpack.io") + maven("https://maven.evokegames.gg/snapshots") } val centralDependencies = listOf( - "org.jetbrains.kotlin:kotlin-stdlib:2.0.0", - "org.jetbrains.kotlin:kotlin-reflect:2.0.0", + "org.jetbrains.kotlin:kotlin-stdlib:2.0.20", + "org.jetbrains.kotlin:kotlin-reflect:2.0.20", "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC", "com.corundumstudio.socketio:netty-socketio:1.7.19", // Keep this on a lower version as the newer version breaks the ping ) @@ -50,16 +34,18 @@ dependencies { } compileOnlyApi("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") - api("com.github.Tofaa2.EntityLib:spigot:2.4.9-SNAPSHOT") + api(project(":engine-core")) + api(project(":engine-loader")) + + api("me.tofaa.entitylib:spigot:2.4.9-SNAPSHOT") api("com.github.shynixn.mccoroutine:mccoroutine-bukkit-api:2.17.0") api("com.github.shynixn.mccoroutine:mccoroutine-bukkit-core:2.17.0") - api("dev.jorel:commandapi-bukkit-shade:9.5.2") - api("dev.jorel:commandapi-bukkit-kotlin:9.5.2") + api("dev.jorel:commandapi-bukkit-shade:9.5.3") + api("dev.jorel:commandapi-bukkit-kotlin:9.5.3") // Doesn't want to load properly using the spigot api. implementation("io.ktor:ktor-server-core-jvm:2.3.12") implementation("io.ktor:ktor-server-netty-jvm:2.3.12") - api("io.insert-koin:koin-core:3.5.6") implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.0") implementation("org.bstats:bstats-bukkit:3.0.2") implementation("com.extollit.gaming:hydrazine-path-engine:1.8.1") @@ -70,46 +56,18 @@ dependencies { compileOnlyApi("net.kyori:adventure-text-serializer-plain:$adventureVersion") compileOnlyApi("net.kyori:adventure-text-serializer-legacy:$adventureVersion") compileOnlyApi("net.kyori:adventure-text-serializer-gson:$adventureVersion") + + compileOnlyApi("com.github.retrooper:packetevents-api:2.5.0-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.6") - compileOnly("com.google.code.gson:gson:2.11.0") - compileOnlyApi("com.github.retrooper:packetevents-spigot:2.4.0") + compileOnlyApi("com.github.retrooper:packetevents-spigot:2.5.0-SNAPSHOT") compileOnlyApi("org.geysermc.floodgate:api:2.2.0-SNAPSHOT") testImplementation("org.junit.jupiter:junit-jupiter:5.9.0") } -val targetJavaVersion = 21 -// TODO: Sync versions back up to 21. This is a temporary fix to allow 1.20.4 servers to still use java 17. -val languageJavaVersion = 17 -java { - val javaVersion = JavaVersion.toVersion(targetJavaVersion) - val languageVersion = JavaVersion.toVersion(languageJavaVersion) - sourceCompatibility = javaVersion - targetCompatibility = languageVersion - toolchain.languageVersion.set(JavaLanguageVersion.of(targetJavaVersion)) - withSourcesJar() - - disableAutoTargetJvm() -} - -kotlin { - jvmToolchain(languageJavaVersion) -} - -tasks.test { - useJUnitPlatform() -} - -tasks.processResources { - filteringCharset = "UTF-8" - filesMatching("plugin.yml") { - expand("version" to version, "libraries" to centralDependencies) - } -} - tasks.withType { - relocate("org.bstats", "${project.group}.${project.name}.extensions.bstats") - relocate("dev.jorel.commandapi", "${project.group}.${project.name}.extensions.commandapi") { + relocate("org.bstats", "com.typewritermc.engine.paper.extensions.bstats") + relocate("dev.jorel.commandapi", "com.typewritermc.engine.paper.extensions.commandapi") { include("dev.jorel.commandapi.**") } minimize { @@ -131,7 +89,7 @@ task("buildAndMove") { // Move the jar from the build/libs folder to the server/plugins folder doLast { val jar = file("build/libs/%s-%s-all.jar".format(project.name, project.version)) - val server = file("server/plugins/%s.jar".format(project.name.capitalizeAsciiOnly())) + val server = file("../../server/plugins/Typewriter.jar") jar.copyTo(server, overwrite = true) } } @@ -141,7 +99,7 @@ task("copyFlutterWebFiles") { description = "Copies the flutter web files to the resources folder" doLast { - val flutterWeb = file("../app/build/web") + val flutterWeb = file("../../app/build/web") val flutterWebDest = file("src/main/resources/web") flutterWeb.copyRecursively(flutterWebDest, overwrite = true) } @@ -164,25 +122,11 @@ task("buildRelease") { if (!jar.exists()) { throw IllegalStateException("Jar does not exist: ${jar.absolutePath}") } - jar.renameTo(file("build/libs/%s.jar".format(project.name))) + jar.renameTo(file("build/libs/Typewriter.jar".format(project.name))) file("build/libs/%s-%s.jar".format(project.name, project.version)).delete() } } -publishing { - publications { - create("main") { - group = project.group - version = project.version.toString() - artifactId = project.name - - from(components["kotlin"]) - artifact(tasks["sourcesJar"]) - artifact(tasks["shadowJar"]) - } - } -} - fun executeGitCommand(vararg command: String): String { val byteOut = ByteArrayOutputStream() exec { @@ -226,4 +170,18 @@ hangarPublish { } } } +} + +bukkitPluginYaml { + name = "Typewriter" + description = "Next Generation Story Telling Plugin" + authors = listOf("gabber235") + website = "https://docs.typewritermc.com" + version = project.version.toString() + + main = "com.typewritermc.engine.paper.TypewriterPaperPlugin" + apiVersion = "1.21" + depend = listOf("packetevents") + softDepend = listOf("PlaceholderAPI", "floodgate") + libraries = centralDependencies } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/TypewriterCommand.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterCommand.kt similarity index 85% rename from plugin/src/main/kotlin/me/gabber235/typewriter/TypewriterCommand.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterCommand.kt index 434d9ab9c8..88e9522277 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/TypewriterCommand.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterCommand.kt @@ -1,5 +1,20 @@ -package me.gabber235.typewriter - +package com.typewritermc.engine.paper + +import com.typewritermc.core.books.pages.PageType +import com.typewritermc.core.entries.* +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.CINEMATIC_END +import com.typewritermc.engine.paper.entry.quest.trackQuest +import com.typewritermc.engine.paper.entry.quest.unTrackQuest +import com.typewritermc.engine.paper.entry.roadnetwork.content.RoadNetworkContentMode +import com.typewritermc.engine.paper.interaction.chatHistory +import com.typewritermc.engine.paper.ui.CommunicationHandler +import com.typewritermc.engine.paper.utils.ThreadType +import com.typewritermc.engine.paper.utils.asMini +import com.typewritermc.engine.paper.utils.msg +import com.typewritermc.engine.paper.utils.sendMini import dev.jorel.commandapi.CommandTree import dev.jorel.commandapi.StringTooltip import dev.jorel.commandapi.arguments.Argument @@ -10,20 +25,6 @@ import dev.jorel.commandapi.arguments.CustomArgument.MessageBuilder import dev.jorel.commandapi.arguments.StringArgument import dev.jorel.commandapi.executors.CommandArguments import dev.jorel.commandapi.kotlindsl.* -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.entries.SystemTrigger.CINEMATIC_END -import me.gabber235.typewriter.entry.quest.trackQuest -import me.gabber235.typewriter.entry.quest.unTrackQuest -import me.gabber235.typewriter.entry.roadnetwork.content.RoadNetworkContentMode -import me.gabber235.typewriter.events.TypewriterReloadEvent -import me.gabber235.typewriter.interaction.chatHistory -import me.gabber235.typewriter.ui.CommunicationHandler -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.asMini -import me.gabber235.typewriter.utils.msg -import me.gabber235.typewriter.utils.sendMini import net.kyori.adventure.inventory.Book import org.bukkit.command.CommandSender import org.bukkit.entity.Player @@ -49,8 +50,6 @@ fun typeWriterCommand() = commandTree("typewriter") { questCommands() - assetsCommands() - roadNetworkCommands() manifestCommands() @@ -60,8 +59,10 @@ private fun CommandTree.reloadCommands() = literalArgument("reload") { withPermission("typewriter.reload") anyExecutor { sender, _ -> sender.msg("Reloading configuration...") - TypewriterReloadEvent().callEvent() - sender.msg("Configuration reloaded!") + ThreadType.DISPATCHERS_ASYNC.launch { + plugin.reload() + sender.msg("Configuration reloaded!") + } } } @@ -191,12 +192,12 @@ private fun CommandTree.cinematicCommand() = literalArgument("cinematic") { literalArgument("start") { withPermission("typewriter.cinematic.start") - argument(pageNames("cinematic", PageType.CINEMATIC)) { + argument(pages("cinematic", PageType.CINEMATIC)) { optionalTarget { anyExecutor { sender, args -> val target = args.targetOrSelfPlayer(sender) ?: return@anyExecutor - val pageName = args["cinematic"] as String - CinematicStartTrigger(pageName, emptyList()) triggerFor target + val page = args["cinematic"] as Page + CinematicStartTrigger(page.id, emptyList()) triggerFor target } } } @@ -271,19 +272,6 @@ private fun CommandTree.questCommands() = literalArgument("quest") { } } -private fun CommandTree.assetsCommands() = literalArgument("assets") { - literalArgument("clean") { - withPermission("typewriter.assets.clean") - anyExecutor { sender, _ -> - sender.msg("Cleaning unused assets...") - ThreadType.DISPATCHERS_ASYNC.launch { - val deleted = get(AssetManager::class.java).removeUnusedAssets() - sender.msg("Cleaned ${deleted} assets.") - } - } - } -} - private fun CommandTree.roadNetworkCommands() = literalArgument("roadNetwork") { literalArgument("edit") { withPermission("typewriter.roadNetwork.edit") @@ -332,23 +320,23 @@ private fun CommandTree.manifestCommands() = literalArgument("manifest") { } literalArgument("page") { - argument(pageNames("page", PageType.MANIFEST)) { + argument(pages("page", PageType.MANIFEST)) { optionalTarget { anyExecutor { sender, args -> val target = args.targetOrSelfPlayer(sender) ?: return@anyExecutor - val pageName = args["page"] as String + val page = args["page"] as Page val audienceEntries = - Query.findWhereFromPage(pageName) { true }.sortedBy { it.name }.toList() + Query.findWhereFromPage(page.id) { true }.sortedBy { it.name }.toList() if (audienceEntries.isEmpty()) { - sender.msg("No audience entries found on page $pageName") + sender.msg("No audience entries found on page ${page.name}") return@anyExecutor } val entryStates = audienceEntries.groupBy { target.audienceState(it) } sender.sendMini("\n\n") - sender.msg("These are the audience entries on page $pageName:") + sender.msg("These are the audience entries on page ${page.name}:") for (state in AudienceDisplayState.entries) { val entries = entryStates[state] ?: continue val color = state.color @@ -387,16 +375,16 @@ inline fun entryArgument(name: String): Argument = Custom }.toList().toTypedArray() }) -fun pageNames(name: String, type: PageType): Argument = CustomArgument(StringArgument(name)) { info -> - val entryDatabase = get(EntryDatabase::class.java) - val pageNames = entryDatabase.getPageNames(type) - if (info.input !in pageNames) { +fun pages(name: String, type: PageType): Argument = CustomArgument(StringArgument(name)) { info -> + val pages = Query.findPagesOfType(type).toList() + val page = pages.firstOrNull { it.id == info.input || it.name == info.input } + if (page == null) { throw CustomArgumentException.fromMessageBuilder(MessageBuilder("Page does not exist.")) } - info.input + page }.replaceSuggestions(ArgumentSuggestions.stringsWithTooltips { _ -> - val entryDatabase = get(EntryDatabase::class.java) - entryDatabase.getPageNames(type).map { - StringTooltip.ofString(it, it) + val pages = Query.findPagesOfType(type).toList() + pages.map { + StringTooltip.ofString(it.name, it.name) }.toList().toTypedArray() }) \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/Typewriter.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterPaperPlugin.kt similarity index 54% rename from plugin/src/main/kotlin/me/gabber235/typewriter/Typewriter.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterPaperPlugin.kt index 9d1dc2ff99..0f1c5a8fed 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/Typewriter.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/TypewriterPaperPlugin.kt @@ -1,36 +1,47 @@ -package me.gabber235.typewriter +package com.typewritermc.engine.paper import com.github.retrooper.packetevents.PacketEvents import com.github.shynixn.mccoroutine.bukkit.launch +import com.github.shynixn.mccoroutine.bukkit.registerSuspendingEvents import com.google.gson.Gson +import com.typewritermc.core.TypewriterCore +import com.typewritermc.core.entries.Library +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.dialogue.MessengerFinder +import com.typewritermc.engine.paper.entry.entity.EntityHandler +import com.typewritermc.engine.paper.entry.entries.CustomCommandEntry +import com.typewritermc.engine.paper.entry.entries.createRoadNetworkParser +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkManager +import com.typewritermc.engine.paper.events.TypewriterUnloadEvent +import com.typewritermc.engine.paper.extensions.bstats.BStatsMetrics +import com.typewritermc.engine.paper.extensions.modrinth.Modrinth +import com.typewritermc.engine.paper.extensions.placeholderapi.PlaceholderExpansion +import com.typewritermc.engine.paper.facts.FactDatabase +import com.typewritermc.engine.paper.facts.FactStorage +import com.typewritermc.engine.paper.facts.storage.FileFactStorage +import com.typewritermc.engine.paper.interaction.ActionBarBlockerHandler +import com.typewritermc.engine.paper.interaction.ChatHistoryHandler +import com.typewritermc.engine.paper.interaction.InteractionHandler +import com.typewritermc.engine.paper.interaction.PacketInterceptor +import com.typewritermc.engine.paper.loader.dataSerializers +import com.typewritermc.engine.paper.snippets.SnippetDatabase +import com.typewritermc.engine.paper.snippets.SnippetDatabaseImpl +import com.typewritermc.engine.paper.ui.ClientSynchronizer +import com.typewritermc.engine.paper.ui.CommunicationHandler +import com.typewritermc.engine.paper.ui.PanelHost +import com.typewritermc.engine.paper.ui.Writers +import com.typewritermc.engine.paper.utils.createBukkitDataParser +import com.typewritermc.engine.paper.utils.registerAll +import com.typewritermc.engine.paper.utils.unregisterAll +import com.typewritermc.loader.DependencyChecker +import com.typewritermc.loader.ExtensionLoader +import com.typewritermc.loader.createDataSerializerGson import dev.jorel.commandapi.CommandAPI import dev.jorel.commandapi.CommandAPIBukkitConfig import kotlinx.coroutines.delay import lirand.api.architecture.KotlinPlugin -import me.gabber235.typewriter.adapters.AdapterLoader -import me.gabber235.typewriter.adapters.AdapterLoaderImpl -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.dialogue.MessengerFinder -import me.gabber235.typewriter.entry.entity.EntityHandler -import me.gabber235.typewriter.entry.entries.createRoadNetworkParser -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkManager -import me.gabber235.typewriter.extensions.bstats.BStatsMetrics -import me.gabber235.typewriter.extensions.modrinth.Modrinth -import me.gabber235.typewriter.extensions.placeholderapi.PlaceholderExpansion -import me.gabber235.typewriter.facts.FactDatabase -import me.gabber235.typewriter.facts.FactStorage -import me.gabber235.typewriter.facts.storage.FileFactStorage -import me.gabber235.typewriter.interaction.ActionBarBlockerHandler -import me.gabber235.typewriter.interaction.ChatHistoryHandler -import me.gabber235.typewriter.interaction.InteractionHandler -import me.gabber235.typewriter.interaction.PacketInterceptor -import me.gabber235.typewriter.snippets.SnippetDatabase -import me.gabber235.typewriter.snippets.SnippetDatabaseImpl -import me.gabber235.typewriter.ui.ClientSynchronizer -import me.gabber235.typewriter.ui.CommunicationHandler -import me.gabber235.typewriter.ui.PanelHost -import me.gabber235.typewriter.ui.Writers -import me.gabber235.typewriter.utils.createBukkitDataParser +import org.bukkit.event.HandlerList +import org.bukkit.event.Listener import org.bukkit.plugin.Plugin import org.bukkit.plugin.java.JavaPlugin import org.koin.core.component.KoinComponent @@ -45,24 +56,42 @@ import org.koin.core.module.dsl.withOptions import org.koin.core.qualifier.named import org.koin.dsl.module import org.koin.java.KoinJavaComponent +import java.io.File import java.util.logging.Logger import kotlin.time.Duration.Companion.seconds +import com.typewritermc.core.extension.InitializableManager +import com.typewritermc.engine.paper.loader.PaperDependencyChecker -class Typewriter : KotlinPlugin(), KoinComponent { - +class TypewriterPaperPlugin : KotlinPlugin(), KoinComponent, Listener { override fun onLoad() { super.onLoad() val modules = module { - single { this@Typewriter } withOptions + single { this@TypewriterPaperPlugin } withOptions { named("plugin") bind() bind() + bind() createdAtStart() } - singleOf(::AdapterLoaderImpl) - singleOf(::EntryDatabaseImpl) + single { this@TypewriterPaperPlugin.logger } withOptions { + named("logger") + createdAtStart() + } + + singleOf(::TypewriterCore) + factory(named("baseDir")) { plugin.dataFolder } + singleOf(::ExtensionLoader) + singleOf(::Library) + singleOf(::InitializableManager) + single { PaperDependencyChecker() } withOptions { + named("dependencyChecker") + bind() + bind() + createdAtStart() + } + singleOf(::StagingManagerImpl) singleOf(::ClientSynchronizer) singleOf(::InteractionHandler) @@ -82,7 +111,8 @@ class Typewriter : KotlinPlugin(), KoinComponent { singleOf(::PacketInterceptor) singleOf(::EntityHandler) singleOf(::RoadNetworkManager) - factory(named("entryParser")) { createEntryParserGson(get()) } + dataSerializers() + factory(named("dataSerializer")) { createDataSerializerGson(getAll()) } factory(named("bukkitDataParser")) { createBukkitDataParser() } factory(named("roadNetworkParser")) { createRoadNetworkParser() } } @@ -92,8 +122,6 @@ class Typewriter : KotlinPlugin(), KoinComponent { } CommandAPI.onLoad(CommandAPIBukkitConfig(this).usePluginNamespace().skipReloadDatapacks(true)) - - get().loadAdapters() } override suspend fun onEnableAsync() { @@ -108,12 +136,8 @@ class Typewriter : KotlinPlugin(), KoinComponent { PacketEvents.getAPI().settings.downsampleColors(false) - - get().initialize() - get().initialize() get().initialize() get().initialize() - get().initialize() get().initialize() get().initialize() get().initialize() @@ -127,14 +151,13 @@ class Typewriter : KotlinPlugin(), KoinComponent { } BStatsMetrics.registerMetrics() + server.pluginManager.registerSuspendingEvents(this, this) - // We want to initialize all the adapters after all the plugins have been enabled to make - // sure + // We want to initialize all the extensions after all the plugins have been enabled to make sure // that all the plugins are loaded. launch { delay(1) - get().initializeAdapters() - get().loadEntries() + load() get().initialize() delay(5.seconds) @@ -142,11 +165,41 @@ class Typewriter : KotlinPlugin(), KoinComponent { } } + fun load() { + // Needs to be first, as it will load the classLoader + get().load() + + get().loadState() + get().load() + get().load() + get().load() + get().load() + CustomCommandEntry.registerAll() + } + + suspend fun unload() { + TypewriterUnloadEvent().callEvent() + CustomCommandEntry.unregisterAll() + get().unload() + get().unload() + get().unload() + get().unload() + get().unload() + + // Needs to be last, as it will unload the classLoader + get().unload() + } + + suspend fun reload() { + unload() + load() + } + val isFloodgateInstalled: Boolean by lazy { server.pluginManager.isPluginEnabled("Floodgate") } override suspend fun onDisableAsync() { + HandlerList.unregisterAll(this as Listener) CommandAPI.onDisable() - get().shutdown() get().shutdown() get().shutdown() get().shutdown() @@ -155,10 +208,11 @@ class Typewriter : KotlinPlugin(), KoinComponent { get().shutdown() get().shutdown() get().shutdown() - get().unregister() get().shutdown() get().shutdown() get().shutdown() + + unload() } } @@ -190,4 +244,4 @@ fun java.util.logging.Level?.convertLogger(): Level { val logger: Logger by lazy { plugin.logger } -val plugin: JavaPlugin by lazy { KoinJavaComponent.get(JavaPlugin::class.java) } +val plugin: TypewriterPaperPlugin by lazy { KoinJavaComponent.get(JavaPlugin::class.java) } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentComponent.kt similarity index 80% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentComponent.kt index d9396ff6ad..602b1c426e 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentComponent.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.content +package com.typewritermc.engine.paper.content import org.bukkit.entity.Player diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentContext.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentContext.kt similarity index 97% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentContext.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentContext.kt index 84c0b6a7b9..e1f7a7b938 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentContext.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentContext.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.content +package com.typewritermc.engine.paper.content import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KClass diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentEditor.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentEditor.kt similarity index 77% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentEditor.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentEditor.kt index e0ba566a7c..ff073fd26f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentEditor.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentEditor.kt @@ -1,21 +1,21 @@ -package me.gabber235.typewriter.content - +package com.typewritermc.engine.paper.content + +import com.typewritermc.engine.paper.content.components.IntractableItem +import com.typewritermc.engine.paper.content.components.ItemInteraction +import com.typewritermc.engine.paper.content.components.ItemInteractionType +import com.typewritermc.engine.paper.entry.entries.SystemTrigger +import com.typewritermc.engine.paper.entry.forceTriggerFor +import com.typewritermc.engine.paper.events.ContentEditorEndEvent +import com.typewritermc.engine.paper.events.ContentEditorStartEvent +import com.typewritermc.engine.paper.interaction.InteractionHandler +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.msg +import com.typewritermc.engine.paper.utils.playSound import lirand.api.extensions.events.unregister import lirand.api.extensions.server.registerEvents import lirand.api.extensions.world.clearAll -import me.gabber235.typewriter.content.components.IntractableItem -import me.gabber235.typewriter.content.components.ItemInteraction -import me.gabber235.typewriter.content.components.ItemInteractionType -import me.gabber235.typewriter.entry.entries.SystemTrigger -import me.gabber235.typewriter.entry.forceTriggerFor -import me.gabber235.typewriter.events.ContentEditorEndEvent -import me.gabber235.typewriter.events.ContentEditorStartEvent -import me.gabber235.typewriter.interaction.InteractionHandler -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.msg -import me.gabber235.typewriter.utils.playSound import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.Listener @@ -23,8 +23,8 @@ import org.bukkit.event.block.Action import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.PlayerInteractEvent -import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.event.player.PlayerSwapHandItemsEvent +import org.bukkit.inventory.ItemStack import org.koin.java.KoinJavaComponent import java.util.concurrent.ConcurrentLinkedDeque @@ -33,9 +33,9 @@ class ContentEditor( val player: Player, mode: ContentMode, ) : Listener { - val cachedInventory = player.inventory.contents.copyOf() private val stack = ConcurrentLinkedDeque(listOf(mode)) private var items = emptyMap() + private val cachedOriginalItems = mutableMapOf() private val mode: ContentMode? get() = stack.peek() @@ -44,7 +44,6 @@ class ContentEditor( player.playSound("block.beacon.activate") SYNC.switchContext { ContentEditorStartEvent(player).callEvent() - player.inventory.clearAll() } plugin.registerEvents(this) val mode = mode @@ -70,13 +69,21 @@ class ContentEditor( private suspend fun applyInventory() { val previousSlots = items.keys items = mode?.items() ?: emptyMap() - val newSlots = items.keys - val toRemove = previousSlots - newSlots + val currentSlots = items.keys + val newSlots = currentSlots - previousSlots + val removedSlots = previousSlots - currentSlots SYNC.switchContext { + newSlots.forEach { slot -> + val originalItem = player.inventory.getItem(slot) ?: return@forEach + cachedOriginalItems.putIfAbsent(slot, originalItem) + } items.forEach { (slot, item) -> player.inventory.setItem(slot, item.item) } - toRemove.forEach { player.inventory.setItem(it, null) } + removedSlots.forEach { slot -> + val originalItem = cachedOriginalItems.remove(slot) + player.inventory.setItem(slot, originalItem) + } } } @@ -107,11 +114,10 @@ class ContentEditor( suspend fun dispose() { unregister() - val cache = stack.toList() + val cache = stack.toList() stack.clear() cache.forEach { it.dispose() } SYNC.switchContext { - player.inventory.contents = cachedInventory player.playSound("block.beacon.deactivate") ContentEditorEndEvent(player).callEvent() } @@ -181,7 +187,4 @@ val Player.isInContent: Boolean get() = content != null val Player.inLastContentMode: Boolean - get() = content?.isInLastMode() == true - -val Player.contentEditorCachedInventory: Array? - get() = content?.cachedInventory \ No newline at end of file + get() = content?.isInLastMode() == true \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentMode.kt similarity index 83% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentMode.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentMode.kt index d69e6ae74a..0df13e25eb 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/ContentMode.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/ContentMode.kt @@ -1,7 +1,7 @@ -package me.gabber235.typewriter.content +package com.typewritermc.engine.paper.content -import me.gabber235.typewriter.content.components.IntractableItem -import me.gabber235.typewriter.content.components.ItemsComponent +import com.typewritermc.engine.paper.content.components.IntractableItem +import com.typewritermc.engine.paper.content.components.ItemsComponent import org.bukkit.entity.Player abstract class ContentMode( diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/BossBarComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/BossBarComponent.kt similarity index 84% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/components/BossBarComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/BossBarComponent.kt index 329d5add78..b32aac2826 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/BossBarComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/BossBarComponent.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.content.components +package com.typewritermc.engine.paper.content.components -import me.gabber235.typewriter.content.ComponentContainer -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.engine.paper.content.ComponentContainer +import com.typewritermc.engine.paper.content.ContentComponent +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import net.kyori.adventure.bossbar.BossBar import org.bukkit.entity.Player diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CompoundContentComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/CompoundContentComponent.kt similarity index 74% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CompoundContentComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/CompoundContentComponent.kt index 218f369576..7056878408 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CompoundContentComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/CompoundContentComponent.kt @@ -1,7 +1,7 @@ -package me.gabber235.typewriter.content.components +package com.typewritermc.engine.paper.content.components -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.content.ComponentContainer +import com.typewritermc.engine.paper.content.ContentComponent +import com.typewritermc.engine.paper.content.ComponentContainer import org.bukkit.entity.Player abstract class CompoundContentComponent : ContentComponent, ComponentContainer { diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/ExitComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/ExitComponent.kt similarity index 70% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/components/ExitComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/ExitComponent.kt index aa1bfe6410..3fe42a46e8 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/ExitComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/ExitComponent.kt @@ -1,20 +1,18 @@ -package me.gabber235.typewriter.content.components +package com.typewritermc.engine.paper.content.components +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.inLastContentMode +import com.typewritermc.engine.paper.entry.entries.SystemTrigger +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.loreString +import com.typewritermc.engine.paper.utils.name import lirand.api.extensions.events.unregister -import lirand.api.extensions.inventory.meta import lirand.api.extensions.server.registerEvents -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.inLastContentMode -import me.gabber235.typewriter.entry.entries.SystemTrigger -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.loreString -import me.gabber235.typewriter.utils.name import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerSwapHandItemsEvent import org.bukkit.event.player.PlayerToggleSneakEvent import org.bukkit.inventory.ItemStack import java.util.* @@ -56,22 +54,26 @@ class ExitComponent( "" } val item = if (player.inLastContentMode) { - ItemStack(Material.BARRIER).meta { - name = "Exit Editor" - loreString = """ + ItemStack(Material.BARRIER).apply { + editMeta { meta -> + meta.name = "Exit Editor" + meta.loreString = """ | | Click to exit the editor. |$sneakingLine """.trimMargin() + } } } else { - ItemStack(Material.END_CRYSTAL).meta { - name = "Previous Editor" - loreString = """ + ItemStack(Material.END_CRYSTAL).apply { + editMeta { meta -> + meta.name = "Previous Editor" + meta.loreString = """ | | Click to go back to the previous editor. |$sneakingLine """.trimMargin() + } } } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/ItemsComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/ItemsComponent.kt similarity index 91% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/components/ItemsComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/ItemsComponent.kt index a21b4b8389..86aae78dab 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/ItemsComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/ItemsComponent.kt @@ -1,6 +1,6 @@ -package me.gabber235.typewriter.content.components +package com.typewritermc.engine.paper.content.components -import me.gabber235.typewriter.content.ContentComponent +import com.typewritermc.engine.paper.content.ContentComponent import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/NodesComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/NodesComponent.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/components/NodesComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/NodesComponent.kt index 018f016e86..7d308520e4 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/NodesComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/NodesComponent.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.content.components +package com.typewritermc.engine.paper.content.components import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes import com.github.retrooper.packetevents.protocol.player.InteractionHand @@ -6,14 +6,14 @@ import com.github.retrooper.packetevents.util.Vector3f import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity import lirand.api.extensions.events.unregister import lirand.api.extensions.server.registerEvents -import me.gabber235.typewriter.content.ComponentContainer -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.events.AsyncFakeEntityInteract -import me.gabber235.typewriter.extensions.packetevents.meta -import me.gabber235.typewriter.extensions.packetevents.toPacketItem -import me.gabber235.typewriter.extensions.packetevents.toPacketLocation -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.distanceSqrt +import com.typewritermc.engine.paper.content.ComponentContainer +import com.typewritermc.engine.paper.content.ContentComponent +import com.typewritermc.engine.paper.events.AsyncFakeEntityInteract +import com.typewritermc.engine.paper.extensions.packetevents.meta +import com.typewritermc.engine.paper.extensions.packetevents.toPacketItem +import com.typewritermc.engine.paper.extensions.packetevents.toPacketLocation +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.distanceSqrt import me.tofaa.entitylib.meta.display.ItemDisplayMeta import me.tofaa.entitylib.meta.other.InteractionMeta import me.tofaa.entitylib.wrapper.WrapperEntity diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/SimulateCinematicComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/SimulateCinematicComponent.kt similarity index 80% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/components/SimulateCinematicComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/SimulateCinematicComponent.kt index 70793171ce..6ad05b7c45 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/SimulateCinematicComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/components/SimulateCinematicComponent.kt @@ -1,26 +1,29 @@ -package me.gabber235.typewriter.content.components - +package com.typewritermc.engine.paper.content.components + +import com.typewritermc.core.books.pages.PageType +import com.typewritermc.core.entries.Page +import com.typewritermc.core.entries.Query +import com.typewritermc.core.utils.loopingDistance +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.components.ItemInteractionType.* +import com.typewritermc.engine.paper.content.pageId +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.maxFrame +import com.typewritermc.engine.paper.interaction.startBlockingActionBar +import com.typewritermc.engine.paper.interaction.stopBlockingActionBar +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.digits +import com.typewritermc.engine.paper.utils.loreString +import com.typewritermc.engine.paper.utils.name +import com.typewritermc.engine.paper.utils.playSound import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import lirand.api.extensions.events.unregister -import lirand.api.extensions.inventory.meta import lirand.api.extensions.server.registerEvents -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.components.ItemInteractionType.* -import me.gabber235.typewriter.content.pageId -import me.gabber235.typewriter.entry.EntryDatabase -import me.gabber235.typewriter.entry.Page -import me.gabber235.typewriter.entry.PageType -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.maxFrame -import me.gabber235.typewriter.interaction.startBlockingActionBar -import me.gabber235.typewriter.interaction.stopBlockingActionBar -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.* import net.kyori.adventure.bossbar.BossBar import org.bukkit.Material import org.bukkit.entity.Player @@ -28,7 +31,6 @@ import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerItemHeldEvent import org.bukkit.inventory.ItemStack -import org.koin.java.KoinJavaComponent import java.util.* fun ContentMode.cinematic(context: ContentContext) = +SimulateCinematicComponent(context) @@ -133,15 +135,17 @@ class SimulateCinematicComponent( } override fun items(player: Player): Map { - val playbackSpeed = ItemStack(Material.CLOCK).meta { - name = "Playback Speed" - loreString = """ + val playbackSpeed = ItemStack(Material.CLOCK).apply { + editMeta { meta -> + meta.name = "Playback Speed" + meta.loreString = """ | Right Click: Increases speed by 1 | Shift + Right Click: Increases speed by 0.25 | Left Click: Decreases speed by 1 | Shift + Left Click: Decreases speed by 0.25 | : Pause/Resume """.trimMargin() + } } onInteract { (type) -> when (type) { RIGHT_CLICK -> playbackSpeed += 1 @@ -156,9 +160,10 @@ class SimulateCinematicComponent( player.playSound("ui.button.click") } - val skip = ItemStack(Material.AMETHYST_SHARD).meta { - name = "Skip Frame" - loreString = """ + val skip = ItemStack(Material.AMETHYST_SHARD).apply { + editMeta { meta -> + meta.name = "Skip Frame" + meta.loreString = """ | Right Click: Goes forward 20 frames | Shift + Right Click: Goes forward 1 frames | Left Click: Goes backwards 20 frames @@ -166,6 +171,7 @@ class SimulateCinematicComponent( | : Rewind to start | : Go into advanced playback control mode """.trimMargin() + } } onInteract { (type) -> when (type) { RIGHT_CLICK -> partialFrame += 20 @@ -202,8 +208,8 @@ fun findCinematicPageById(pageId: String?): Page? { logger.warning("Can only simulate cinematic for a page") return null } - val entryDatabase = KoinJavaComponent.get(EntryDatabase::class.java) - val page = entryDatabase.findPageById(pageId) + + val page = Query.findPageById(pageId) if (page == null) { logger.warning("Page $pageId not found, make sure to publish before using content mode") return null diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/ImmediateFieldValueContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/ImmediateFieldValueContentMode.kt new file mode 100644 index 0000000000..c81e5ddb39 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/ImmediateFieldValueContentMode.kt @@ -0,0 +1,50 @@ +package com.typewritermc.engine.paper.content.modes + +import com.github.shynixn.mccoroutine.bukkit.launch +import kotlinx.coroutines.delay +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.entryId +import com.typewritermc.engine.paper.content.fieldPath +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.CONTENT_END +import com.typewritermc.engine.paper.entry.fieldValue +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.plugin +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.engine.paper.logger +import org.bukkit.entity.Player +import kotlin.time.Duration.Companion.milliseconds + +abstract class ImmediateFieldValueContentMode(context: ContentContext, player: Player) : + ContentMode(context, player) { + + override suspend fun setup(): Result { + val entryId = context.entryId + ?: return failure("No entryId found for ${this::class.simpleName}. This is a bug. Please report it.") + + val fieldPath = context.fieldPath + ?: return failure("No fieldPath found for ${this::class.simpleName}. This is a bug. Please report it.") + + // Needs to complete the initialisation so that we can properly get the value and end the content mode + plugin.launch { + delay(200.milliseconds) + try { + val value = value() + Ref(entryId, Entry::class).fieldValue(fieldPath, value) + } catch (e: Exception) { + logger.severe("Failed to set field value for ${this::class.simpleName}, with context: $context. This is a bug. Please report it.") + e.printStackTrace() + } finally { + CONTENT_END triggerFor player + } + } + + return ok(Unit) + } + + abstract fun value(): T + +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/RecordingCinematicContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/RecordingCinematicContentMode.kt similarity index 88% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/RecordingCinematicContentMode.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/RecordingCinematicContentMode.kt index c8f132681f..72e82d76ac 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/RecordingCinematicContentMode.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/RecordingCinematicContentMode.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.content.modes +package com.typewritermc.engine.paper.content.modes import com.google.gson.Gson import com.google.gson.JsonElement @@ -7,22 +7,21 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import lirand.api.extensions.events.unregister -import lirand.api.extensions.inventory.meta import lirand.api.extensions.server.registerEvents -import me.gabber235.typewriter.content.* -import me.gabber235.typewriter.content.components.* -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.forceTriggerFor -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.interaction.startBlockingActionBar -import me.gabber235.typewriter.interaction.stopBlockingActionBar -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.loreString -import me.gabber235.typewriter.utils.name -import me.gabber235.typewriter.utils.ok +import com.typewritermc.engine.paper.content.* +import com.typewritermc.engine.paper.content.components.* +import com.typewritermc.engine.paper.entry.AssetManager +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.forceTriggerFor +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.interaction.startBlockingActionBar +import com.typewritermc.engine.paper.interaction.stopBlockingActionBar +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.core.utils.failure +import com.typewritermc.engine.paper.utils.loreString +import com.typewritermc.engine.paper.utils.name +import com.typewritermc.core.utils.ok import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.key.Key import net.kyori.adventure.sound.Sound @@ -58,22 +57,26 @@ class RecordingCinematicComponent( override fun items(player: Player): Map { if (frameFetcher() > (context.endFrame ?: 0)) { - val item = ItemStack(Material.BARRIER).meta { - name = "Cannot Start Recording" - loreString = """ + val item = ItemStack(Material.BARRIER).apply { + editMeta { meta -> + meta.name = "Cannot Start Recording" + meta.loreString = """ | Recording cannot start | because the frame is out of range. | | Make sure that the cinematic frame | is before the end frame of the segment. """.trimMargin() + } } onInteract {} return mapOf(slot to item) } - val item = ItemStack(Material.BOOK).meta { - name = "Start Recording" - loreString = " Click to start recording the cinematic." + val item = ItemStack(Material.BOOK).apply { + editMeta { meta -> + meta.name = "Start Recording" + meta.loreString = " Click to start recording the cinematic." + } } onInteract { ContentModeTrigger(context, modeCreator(context, player, frameFetcher(), klass)) triggerFor player } @@ -108,7 +111,7 @@ abstract class RecordingCinematicContentMode( |Context: $context | |RecordingCinematicContentMode can only be used for segments of a cinematic. - |Report this to the adapter developer. + |Report this to the extension developer. """.trimMargin() ) } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/Tape.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/Tape.kt similarity index 97% rename from plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/Tape.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/Tape.kt index d90a54e8ca..5d534b3caf 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/Tape.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/Tape.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.content.modes +package com.typewritermc.engine.paper.content.modes /** * Tape is a map of ticks to values. diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/HoldingItemContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/HoldingItemContentMode.kt new file mode 100644 index 0000000000..45c381c003 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/HoldingItemContentMode.kt @@ -0,0 +1,17 @@ +package com.typewritermc.engine.paper.content.modes.custom + +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.modes.ImmediateFieldValueContentMode +import com.typewritermc.engine.paper.utils.Item +import com.typewritermc.engine.paper.utils.toItem +import org.bukkit.entity.Player + +class HoldingItemContentMode(context: ContentContext, player: Player) : + ImmediateFieldValueContentMode(context, player) { + + override fun value(): Item { + val item = player.inventory.itemInMainHand + item.persistentDataContainer + return item.toItem() + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/PositionContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/PositionContentMode.kt new file mode 100644 index 0000000000..0c7312f7cb --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/content/modes/custom/PositionContentMode.kt @@ -0,0 +1,23 @@ +package com.typewritermc.engine.paper.content.modes.custom + +import com.typewritermc.core.utils.point.Position +import com.typewritermc.core.utils.point.World +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.modes.ImmediateFieldValueContentMode +import com.typewritermc.engine.paper.utils.round +import org.bukkit.entity.Player + +class PositionContentMode(context: ContentContext, player: Player) : + ImmediateFieldValueContentMode(context, player) { + override fun value(): Position { + val location = player.location + return Position( + World(location.world.name), + location.x.round(2), + location.y.round(2), + location.z.round(2), + location.yaw.round(2), + location.pitch.round(2), + ) + } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/AssetManager.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/AssetManager.kt similarity index 56% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/AssetManager.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/AssetManager.kt index 34682bfc17..a08ba7a5cb 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/AssetManager.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/AssetManager.kt @@ -1,13 +1,9 @@ -package me.gabber235.typewriter.entry +package com.typewritermc.engine.paper.entry -import com.google.gson.Gson -import com.google.gson.stream.JsonReader -import me.gabber235.typewriter.entry.entries.AssetEntry -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.entry.entries.AssetEntry +import com.typewritermc.engine.paper.plugin import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import org.koin.core.qualifier.named -import java.io.StringReader interface AssetStorage { suspend fun storeAsset(path: String, content: String) @@ -20,53 +16,10 @@ interface AssetStorage { class AssetManager : KoinComponent { private val storage: AssetStorage by inject() - private val stagingManager: StagingManager by inject() - private val gson: Gson by inject(named("entryParser")) fun initialize() { } - internal suspend fun removeUnusedAssets(): Int { - val usedPaths = usedPaths() - if (usedPaths.isFailure) { - plugin.logger.severe("Failed to remove unused assets: ${usedPaths.exceptionOrNull()?.message}") - return 0 - } - - val unusedPaths = storage.fetchAllAssetPaths().subtract((usedPaths.getOrNull() ?: emptySet()).toSet()) - unusedPaths.forEach { - storage.deleteAsset(it) - } - return unusedPaths.size - } - - /** - * Find all the paths that either have a reference in the database or are in the staging area. - */ - private fun usedPaths(): Result> { - val stagingPages = stagingManager.fetchPages().map { (id, data) -> - id to JsonReader(StringReader(data.toString())) - }.map { (id, reader) -> - reader.parsePage(id, gson) - } - - if (stagingPages.any { it.isFailure }) { - return Result.failure(stagingPages.first { it.isFailure }.exceptionOrNull()!!) - } - - val stagingPaths = stagingPages.flatMap { - it.getOrThrow().entries - }.filterIsInstance().map { - it.path - }.toSet() - - val productionPaths = Query.find().map { - it.path - }.toSet() - - return Result.success(stagingPaths.union(productionPaths)) - } - suspend fun storeAsset(entry: AssetEntry, content: String) { storage.storeAsset(entry.path, content) } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/AudienceManager.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/AudienceManager.kt similarity index 89% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/AudienceManager.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/AudienceManager.kt index 99c0717562..9a1c4b8ae5 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/AudienceManager.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/AudienceManager.kt @@ -1,13 +1,17 @@ -package me.gabber235.typewriter.entry +package com.typewritermc.engine.paper.entry +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.ref +import com.typewritermc.core.utils.Reloadable import kotlinx.coroutines.Job import kotlinx.coroutines.delay import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.interaction.AVERAGE_SCHEDULING_DELAY_MS -import me.gabber235.typewriter.interaction.TICK_MS -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.interaction.AVERAGE_SCHEDULING_DELAY_MS +import com.typewritermc.engine.paper.interaction.TICK_MS +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.HandlerList @@ -18,7 +22,7 @@ import org.koin.java.KoinJavaComponent.get import kotlin.reflect.KClass import kotlin.reflect.full.hasAnnotation -class AudienceManager : Listener { +class AudienceManager : Listener, Reloadable { private var displays = emptyMap, AudienceDisplay>() private var parents = emptyMap, List>>() private var roots = emptyList>() @@ -47,8 +51,8 @@ class AudienceManager : Listener { } } - fun register() { - unregister() + override fun load() { + unload() val entries = Query.find() @@ -114,7 +118,7 @@ class AudienceManager : Listener { fun getParents(ref: Ref): List> = parents[ref] ?: emptyList() - fun unregister() { + override fun unload() { val displays = displays this.displays = emptyMap() displays.values.forEach { it.dispose() } @@ -133,7 +137,7 @@ class AudienceManager : Listener { fun shutdown() { job?.cancel() job = null - unregister() + unload() HandlerList.unregisterAll(this) } } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/Entry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/BaseEntry.kt similarity index 50% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/Entry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/BaseEntry.kt index 482aa25aba..abe6c5f341 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/Entry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/BaseEntry.kt @@ -1,35 +1,16 @@ -package me.gabber235.typewriter.entry +package com.typewritermc.engine.paper.entry import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Negative -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.entry.entries.WritableFactEntry -import me.gabber235.typewriter.facts.FactData +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Negative +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.entry.entries.WritableFactEntry +import com.typewritermc.engine.paper.facts.FactData import org.bukkit.entity.Player -import java.util.* - -val Entry.formattedName: String - get() = name.split(".") - .joinToString(" | ") { part -> part.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } } - .split("_") - .joinToString(" ") { part -> part.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } } - -interface Entry { - val id: String - val name: String -} - -interface PriorityEntry : Entry { - /** - * Normally, the priority of an entry is determined by the priority of the page it is on. - * Subtypes may want to allow the user to override the priority for that specific entry. - * This is useful when entries need to have fine-grained control over their priority. - */ - @Help("The priority of the entry. If not set, the priority of the page will be used.") - val priorityOverride: Optional -} @Tags("static") interface StaticEntry : Entry @@ -37,25 +18,6 @@ interface StaticEntry : Entry @Tags("manifest") interface ManifestEntry : Entry -@Tags("trigger") -interface TriggerEntry : Entry { - @Help("The entries that will be fired after this entry.") - val triggers: List> -} - -@Tags("triggerable") -interface TriggerableEntry : TriggerEntry { - @Help("The criteria that must be met before this entry is triggered") - val criteria: List - - @Help("The modifiers that will be applied when this entry is triggered") - val modifiers: List -} - -@Tags("placeholder") -interface PlaceholderEntry : Entry { - fun display(player: Player?): String? -} enum class CriteriaOperator { @SerializedName("==") @@ -105,6 +67,12 @@ data class Criteria( } } +infix fun Iterable.matches(player: Player): Boolean = all { + val entry = it.fact.get() + val fact = entry?.readForPlayersGroup(player) + it.isValid(fact) +} + enum class ModifierOperator { @SerializedName("=") SET, diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/EntryListeners.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/EntryListeners.kt new file mode 100644 index 0000000000..7ee7106d72 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/EntryListeners.kt @@ -0,0 +1,145 @@ +package com.typewritermc.engine.paper.entry + +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Query +import com.typewritermc.core.utils.Reloadable +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.logErrorIfNull +import com.typewritermc.loader.EntryListenerInfo +import com.typewritermc.loader.ExtensionLoader +import com.typewritermc.loader.ListenerPriority +import lirand.api.extensions.events.listen +import lirand.api.extensions.events.unregister +import org.bukkit.event.Event +import org.bukkit.event.EventPriority +import org.bukkit.event.Listener +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import org.koin.java.KoinJavaComponent.get +import java.lang.reflect.Method +import java.lang.reflect.Parameter +import kotlin.reflect.KClass +import kotlin.reflect.full.isSubclassOf + +/** + * Manages all the active entry listeners. + */ +class EntryListeners : KoinComponent, Reloadable { + private val extensionLoader: ExtensionLoader by inject() + private val listener = object : Listener {} + + + private fun onEvent(event: Event, info: EntryListenerInfo, generators: List, method: Method) { + val parameters = generators.map { it.generate(event, info) } + try { + method.invoke(null, *parameters.toTypedArray()) + } catch (e: Exception) { + logger.severe("Failed to invoke entry listener ${method.name} for event ${event::class.simpleName}") + e.printStackTrace() + } + } + + /** + * Registers all the entry listeners. + */ + override fun load() { + unload() + + val entryListeners = extensionLoader.extensions.flatMap { it.entryListeners } + + val activeEventEntries = Query.find().map { it::class }.distinct() + + val activeEntryListeners = entryListeners.filter { + activeEventEntries.any { activeEventEntry -> it.entryClassName == activeEventEntry.qualifiedName } + } + activeEntryListeners.forEach { + val method = it.method + val eventClass = findEventFromMethod(method).logErrorIfNull("Could not find bukkit event class for ${method.name}") ?: return@forEach + + listener.listen(plugin, eventClass, it.priority.toBukkitPriority(), it.ignoreCancelled) { event -> + onEvent(event, it, ParameterGenerator.getGenerators(method.parameters), method) + } + } + + logger.info("Loaded ${activeEntryListeners.size} entry listeners") + } + + private fun findEventFromMethod(method: Method): KClass? { + return method.parameters.firstNotNullOfOrNull { it.type.kotlin.takeIf { type -> type.isSubclassOf(Event::class) } } as? KClass + } + + private val EntryListenerInfo.method: Method + get() { + val clazz = extensionLoader.loadClass(className) + val arguments = arguments.map { extensionLoader.loadClass(it) }.toTypedArray() + return clazz.getDeclaredMethod(methodName, *arguments) + } + + private fun ListenerPriority.toBukkitPriority(): EventPriority { + return when (this) { + ListenerPriority.HIGHEST -> EventPriority.HIGHEST + ListenerPriority.HIGH -> EventPriority.HIGH + ListenerPriority.NORMAL -> EventPriority.NORMAL + ListenerPriority.LOW -> EventPriority.LOW + ListenerPriority.LOWEST -> EventPriority.LOWEST + ListenerPriority.MONITOR -> EventPriority.MONITOR + } + } + + /** + * Unregisters all the entry listeners. + */ + override fun unload() { + listener.unregister() + } +} + +sealed interface ParameterGenerator { + fun isApplicable(parameter: Parameter): Boolean + fun generate(event: Event, entryListenerInfo: EntryListenerInfo): Any + + data object EventParameterGenerator : ParameterGenerator { + override fun isApplicable(parameter: Parameter): Boolean { + // It and all superclasses must be Event + return Event::class.java.isAssignableFrom(parameter.type) + } + + override fun generate(event: Event, entryListenerInfo: EntryListenerInfo): Any = event + } + + data object QueryParameterGenerator : ParameterGenerator { + override fun isApplicable(parameter: Parameter): Boolean { + // It can only be Query + return parameter.type.isAssignableFrom(Query::class.java) + } + + override fun generate(event: Event, entryListenerInfo: EntryListenerInfo): Any { + val extensionLoader = get(ExtensionLoader::class.java) + val entryClass = extensionLoader.loadClass(entryListenerInfo.entryClassName) + val klass = entryClass.kotlin as KClass + return Query(klass) + } + } + + companion object { + private val generators = listOf(EventParameterGenerator, QueryParameterGenerator) + + private fun getGenerator(parameter: Parameter): ParameterGenerator? { + return generators.firstOrNull { it.isApplicable(parameter) } + } + + /** + * Creates a list of ParameterGenerators for the given method. + * @throws IllegalArgumentException if the parameter is not applicable to any generator + */ + @Throws(IllegalArgumentException::class) + fun getGenerators(parameters: Array): List { + return parameters.map { parameter -> + getGenerator(parameter) + ?: throw IllegalArgumentException("There is no way to create a parameter for ${parameter.name} (${parameter.type}) in ${parameter.declaringExecutable}") + } + } + } +} diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/FactWatcher.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/FactWatcher.kt similarity index 91% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/FactWatcher.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/FactWatcher.kt index 9bba1ba6ef..4780f4bd6c 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/FactWatcher.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/FactWatcher.kt @@ -1,10 +1,11 @@ -package me.gabber235.typewriter.entry +package com.typewritermc.engine.paper.entry +import com.typewritermc.core.entries.Ref import io.ktor.util.collections.* -import me.gabber235.typewriter.entry.entries.EventTrigger -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.interaction.InteractionHandler -import me.gabber235.typewriter.utils.logErrorIfNull +import com.typewritermc.engine.paper.entry.entries.EventTrigger +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.interaction.InteractionHandler +import com.typewritermc.engine.paper.utils.logErrorIfNull import org.bukkit.entity.Player import org.koin.java.KoinJavaComponent import java.util.* diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/PlaceholderEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/PlaceholderEntry.kt new file mode 100644 index 0000000000..3c4a3e946a --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/PlaceholderEntry.kt @@ -0,0 +1,10 @@ +package com.typewritermc.engine.paper.entry + +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.extension.annotations.Tags +import org.bukkit.entity.Player + +@Tags("placeholder") +interface PlaceholderEntry : Entry { + fun display(player: Player?): String? +} diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/StagingManager.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/StagingManager.kt similarity index 73% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/StagingManager.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/StagingManager.kt index 7d6f7d9dca..4671debd5c 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/StagingManager.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/StagingManager.kt @@ -1,34 +1,57 @@ -package me.gabber235.typewriter.entry +package com.typewritermc.engine.paper.entry import com.google.gson.* -import lirand.api.extensions.events.listen -import me.gabber235.typewriter.entry.StagingState.* -import me.gabber235.typewriter.events.PublishedBookEvent -import me.gabber235.typewriter.events.StagingChangeEvent -import me.gabber235.typewriter.events.TypewriterReloadEvent -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.ui.ClientSynchronizer -import me.gabber235.typewriter.utils.* -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.pageId +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.core.utils.onFail +import com.typewritermc.engine.paper.entry.StagingState.* +import com.typewritermc.engine.paper.events.StagingChangeEvent +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.ui.ClientSynchronizer +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.utils.Timeout +import com.typewritermc.engine.paper.utils.get import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koin.core.qualifier.named import org.koin.java.KoinJavaComponent import java.io.File +import java.text.SimpleDateFormat +import java.util.* import java.util.concurrent.ConcurrentHashMap +import kotlin.collections.Map +import kotlin.collections.any +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.emptyList +import kotlin.collections.filter +import kotlin.collections.find +import kotlin.collections.forEach +import kotlin.collections.forEachIndexed +import kotlin.collections.indexOfFirst +import kotlin.collections.isNotEmpty +import kotlin.collections.joinToString +import kotlin.collections.mutableMapOf +import kotlin.collections.removeAll +import kotlin.collections.set +import kotlin.collections.toList import kotlin.time.Duration.Companion.seconds interface StagingManager { val stagingState: StagingState - fun initialize() + fun loadState() + fun unload() fun fetchPages(): Map fun createPage(data: JsonObject): Result - fun renamePage(oldName: String, newName: String): Result + fun renamePage(pageId: String, newName: String): Result fun changePageValue(pageId: String, path: String, value: JsonElement): Result - fun deletePage(name: String): Result - fun moveEntry(entryId: String, fromPage: String, toPage: String): Result + fun deletePage(pageId: String): Result + fun moveEntry(entryId: String, fromPageId: String, toPageId: String): Result fun createEntry(pageId: String, data: JsonObject): Result fun updateEntryField(pageId: String, entryId: String, path: String, value: JsonElement): Result fun updateEntry(pageId: String, data: JsonObject): Result @@ -66,38 +89,23 @@ class StagingManagerImpl : StagingManager, KoinComponent { StagingChangeEvent(value).callEvent() } - override fun initialize() { - loadState() - - plugin.listen { loadState() } - } - - private fun loadState() { - stagingState = if (stagingDir.exists()) { - // Migrate staging directory to use the new format - stagingDir.migrateIfNecessary() - - val stagingPages = fetchPages(stagingDir) - val publishedPages = fetchPages(publishedDir) - - if (stagingPages == publishedPages) PUBLISHED else STAGING - } else PUBLISHED + override fun loadState() { + stagingState = if (stagingDir.exists()) STAGING else PUBLISHED // Read the pages from the file - val dir = - if (stagingState == STAGING) stagingDir else publishedDir + val dir = if (stagingState == STAGING) stagingDir else publishedDir pages.putAll(fetchPages(dir)) } private fun fetchPages(dir: File): Map { val pages = mutableMapOf() - dir.pages().forEach { file -> + dir.listFiles()?.filter { it.extension == "json" }?.forEach { file -> val page = file.readText() - val pageName = file.nameWithoutExtension + val pageId = file.nameWithoutExtension val pageJson = gson.fromJson(page, JsonObject::class.java) - // Sometimes the name of the page is out of sync with the file name, so we need to update it - pageJson.addProperty("name", pageName) - pages[pageName] = pageJson + // Always force the id to be the same as the file name + pageJson.addProperty("id", pageId) + pages[pageId] = pageJson } return pages } @@ -106,31 +114,35 @@ class StagingManagerImpl : StagingManager, KoinComponent { return pages } + override fun unload() { + autoSaver.force() + pages.clear() + } + override fun createPage(data: JsonObject): Result { + if (!data.has("id")) return failure("Id is required") if (!data.has("name")) return failure("Name is required") - val nameJson = data["name"] - if (!nameJson.isJsonPrimitive || !nameJson.asJsonPrimitive.isString) return failure("Name must be a string") - val name = nameJson.asString + val idJson = data["id"] + if (!idJson.isJsonPrimitive || !idJson.asJsonPrimitive.isString) return failure("Id must be a string") + val id = idJson.asString - if (pages.containsKey(name)) return failure("Page with that name already exists") + if (pages.containsKey(id)) return failure("Page with that id already exists") // Add the version of this page to track migrations data.addProperty("version", plugin.pluginMeta.version) - pages[name] = data + pages[id] = data autoSaver() - return ok("Successfully created page with name $name") + return ok("Successfully created page with name $id") } - override fun renamePage(oldName: String, newName: String): Result { - if (pages.containsKey(newName)) return failure("Page with that name already exists") - val oldPage = pages.remove(oldName) ?: return failure("Page '$oldName' does not exist") + override fun renamePage(pageId: String, newName: String): Result { + val page = getPage(pageId) onFail { return it } - oldPage.addProperty("name", newName) + page.addProperty("name", newName) - pages[newName] = oldPage autoSaver() - return ok("Successfully renamed page from $oldName to $newName") + return ok("Successfully renamed page from $pageId to $newName") } override fun changePageValue(pageId: String, path: String, value: JsonElement): Result { @@ -142,19 +154,19 @@ class StagingManagerImpl : StagingManager, KoinComponent { return ok("Successfully updated field") } - override fun deletePage(name: String): Result { - pages.remove(name) ?: return failure("Page does not exist") + override fun deletePage(pageId: String): Result { + pages.remove(pageId) ?: return failure("Page does not exist") autoSaver() - return ok("Successfully deleted page with name $name") + return ok("Successfully deleted page with name $pageId") } - override fun moveEntry(entryId: String, fromPage: String, toPage: String): Result { - val from = pages[fromPage] ?: return failure("Page '$fromPage' does not exist") - val to = pages[toPage] ?: return failure("Page '$toPage' does not exist") + override fun moveEntry(entryId: String, fromPageId: String, toPageId: String): Result { + val from = pages[fromPageId] ?: return failure("Page '$fromPageId' does not exist") + val to = pages[toPageId] ?: return failure("Page '$toPageId' does not exist") val entry = from["entries"].asJsonArray.find { it.asJsonObject["id"].asString == entryId } - ?: return failure("Entry does not exist in page '$fromPage'") + ?: return failure("Entry does not exist in page '$fromPageId'") from["entries"].asJsonArray.remove(entry) to["entries"].asJsonArray.add(entry) @@ -296,8 +308,7 @@ class StagingManagerImpl : StagingManager, KoinComponent { // Delete the staging folder stagingDir.deleteRecursively() - PublishedBookEvent().callEvent() - logger.info("Published the staging state") + plugin.reload() stagingState = PUBLISHED ok("Successfully published the staging state") } catch (e: Exception) { @@ -350,7 +361,7 @@ enum class StagingState { fun Ref.fieldValue(path: String, value: Any) { val stagingManager = KoinJavaComponent.get(StagingManager::class.java) - val gson = KoinJavaComponent.get(Gson::class.java, named("entryParser")) + val gson = KoinJavaComponent.get(Gson::class.java, named("dataSerializer")) val pageId = pageId if (pageId == null) { @@ -367,4 +378,21 @@ fun Ref.fieldValue(path: String, value: Any) { val clientSynchronizer = KoinJavaComponent.get(ClientSynchronizer::class.java) clientSynchronizer.sendEntryFieldUpdate(pageId, id, path, json) +} + +fun List.backup() { + if (isEmpty()) { + // Nothing to back up + return + } + val date = Date() + val dateFormat = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss") + + val backupFolder = plugin.dataFolder["backup/${dateFormat.format(date)}"] + backupFolder.mkdirs() + forEach { + val file = it + val backupFile = File(backupFolder, file.name) + file.copyTo(backupFile, overwrite = true) + } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/Query.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/TriggerEntry.kt similarity index 54% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/Query.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/TriggerEntry.kt index 9e4831bfe1..386b331aca 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/Query.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/TriggerEntry.kt @@ -1,210 +1,29 @@ -package me.gabber235.typewriter.entry - -import me.gabber235.typewriter.entry.entries.EntryTrigger -import me.gabber235.typewriter.entry.entries.EventTrigger -import me.gabber235.typewriter.entry.entries.SystemTrigger -import me.gabber235.typewriter.interaction.InteractionHandler +package com.typewritermc.engine.paper.entry + +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entries.EntryTrigger +import com.typewritermc.engine.paper.entry.entries.EventTrigger +import com.typewritermc.engine.paper.entry.entries.SystemTrigger +import com.typewritermc.engine.paper.interaction.InteractionHandler import org.bukkit.entity.Player import org.koin.java.KoinJavaComponent.get -import kotlin.reflect.KClass - -/** - * A query can be used to search for entries. - * This is useful for events where you want to invoke all triggers for a specific entry given a query. - * - * @param klass The class of the entry. - */ -class Query(private val klass: KClass) { - - /** - * Find all entries that match the given a filter - * - * Example: - * ```kotlin - * val query: Query = ... - * query findWhere { it.someValue == "hello" } - * ``` - * - * It can be used in combination with [triggerAllFor] to invoke all triggers for all entries that match the filter. - * Example: - * ```kotlin - * val query: Query = ... - * query findWhere { it.someValue == "hello" } triggerAllFor player - * ``` - * - * @param filter The filter to apply to the entries. - */ - infix fun findWhere(filter: (E) -> Boolean): Sequence = findWhere(klass, filter) - - /** - * Find the first entry that matches the given a filter - * @see findWhere - */ - infix fun firstWhere(filter: (E) -> Boolean): E? = firstWhere(klass, filter) - - /** - * Find all the entries for the given class. - * - * Example: - * ```kotlin - * val query: Query = ... - * query.find() - * ``` - */ - fun find() = findWhere { true } - - /** - * Find entry by [name]. - * - * Example: - * ```kotlin - * val query: Query = ... - * query findByName "someName" - * ``` - */ - infix fun findByName(name: String) = firstWhere { it.name == name } - - /** - * Find entry by [id]. - * - * Example: - * ```kotlin - * val query: Query = ... - * query findById "someId" - * ``` - */ - infix fun findById(id: String): E? = findById(klass, id) - - /** - * Find entry all entries that are on the given page [pageId] with the given [filter]. - * @see findWhere - */ - fun findWhereFromPage(pageId: String, filter: (E) -> Boolean): Sequence = - findWhereFromPage(klass, pageId, filter) - companion object { - /** - * Find all entries that match the given a filter - * - * Example: - * ```kotlin - * Query findWhere { it.someValue == "hello" } - * ``` - * - * It can be used in combination with [triggerAllFor] to invoke all triggers for all entries that match the filter. - * Example: - * ```kotlin - * Query findWhere { it.someValue == "hello" } triggerAllFor player - * ``` - * - * @param filter The filter to apply to the entries. - */ - inline infix fun findWhere(noinline filter: (E) -> Boolean): Sequence { - return findWhere(E::class, filter) - } - - /** - * Find all entries that match the given a filter - * - * Example: - * ```kotlin - * Query.findWhere(SomeEntry::class) { it.someValue == "hello" } - * ``` - * - * It can be used in combination with [triggerAllFor] to invoke all triggers for all entries that match the filter. - * Example: - * ```kotlin - * Query.findWhere(SomeEntry::class) { it.someValue == "hello" } triggerAllFor player - * ``` - * - * @param filter The filter to apply to the entries. - */ - fun findWhere(klass: KClass, filter: (E) -> Boolean): Sequence { - return get(EntryDatabase::class.java).findEntries(klass, filter) - } - - /** - * Find the first entry that matches the given a filter - * @see findWhere - */ - inline infix fun firstWhere(noinline filter: (E) -> Boolean): E? { - return firstWhere(E::class, filter) - } - - /** - * Find the first entry that matches the given a filter - * @see findWhere - */ - fun firstWhere(klass: KClass, filter: (E) -> Boolean): E? { - return get(EntryDatabase::class.java).findEntry(klass, filter) - } - - - /** - * Find all the entries for the given class. - * - * Example: - * ```kotlin - * Query.find() - * ``` - */ - inline fun find() = findWhere { true } - - /** - * Find all the entries for the given class. - * - * Example: - * ```kotlin - * Query.find(SomeEntry::class) - * ``` - */ - fun find(klass: KClass) = findWhere(klass) { true } - - /** - * Find entry by [name]. - * - * Example: - * ```kotlin - * Query findByName "someName" - * ``` - */ - inline infix fun findByName(name: String) = firstWhere { it.name == name } - - /** - * Find entry by [name]. - * - * Example: - * ```kotlin - * Query.findByName(SomeEntry::class, "someName") - * ``` - */ - fun findByName(klass: KClass, name: String) = firstWhere(klass) { it.name == name } - - inline infix fun findById(id: String): E? = findById(E::class, id) - - /** - * Find entry by [id]. - * @see findByName - */ - fun findById(klass: KClass, id: String): E? = - get(EntryDatabase::class.java).findEntryById(klass, id) +@Tags("trigger") +interface TriggerEntry : Entry { + @Help("The entries that will be fired after this entry.") + val triggers: List> +} - /** - * Find entry all entries that are on the given page [pageId] with the given [filter]. - * @see findWhere - */ - inline fun findWhereFromPage(pageId: String, noinline filter: (E) -> Boolean): Sequence { - return findWhereFromPage(E::class, pageId, filter) - } +@Tags("triggerable") +interface TriggerableEntry : TriggerEntry { + @Help("The criteria that must be met before this entry is triggered") + val criteria: List - /** - * Find entry all entries that are on the given page [pageId] with the given [filter]. - * @see findWhere - */ - fun findWhereFromPage(klass: KClass, pageId: String, filter: (E) -> Boolean): Sequence { - return get(EntryDatabase::class.java).findEntriesFromPage(klass, pageId, filter) - } - } + @Help("The modifiers that will be applied when this entry is triggered") + val modifiers: List } /** diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/cinematic/CinematicSequence.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/cinematic/CinematicSequence.kt similarity index 75% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/cinematic/CinematicSequence.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/cinematic/CinematicSequence.kt index e6ecc32dc9..b78a352582 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/cinematic/CinematicSequence.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/cinematic/CinematicSequence.kt @@ -1,18 +1,20 @@ -package me.gabber235.typewriter.entry.cinematic - +package com.typewritermc.engine.paper.entry.cinematic + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.cinematic.CinematicState.* +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicSettings +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.CINEMATIC_END +import com.typewritermc.engine.paper.events.AsyncCinematicEndEvent +import com.typewritermc.engine.paper.events.AsyncCinematicStartEvent +import com.typewritermc.engine.paper.events.AsyncCinematicTickEvent +import com.typewritermc.engine.paper.interaction.* +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.cinematic.CinematicState.* -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicSettings -import me.gabber235.typewriter.entry.entries.SystemTrigger.CINEMATIC_END -import me.gabber235.typewriter.events.AsyncCinematicEndEvent -import me.gabber235.typewriter.events.AsyncCinematicStartEvent -import me.gabber235.typewriter.events.AsyncCinematicTickEvent -import me.gabber235.typewriter.interaction.* -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC import org.bukkit.entity.Player import org.koin.java.KoinJavaComponent import java.time.Duration @@ -27,9 +29,9 @@ class CinematicSequence( ) { private var state = STARTING private var playTime = Duration.ofMillis(-1) - private val frame: Int get() = (playTime.toMillis()/50).toInt() + private val frame: Int get() = (playTime.toMillis() / 50).toInt() - val priority by lazy { KoinJavaComponent.get(EntryDatabase::class.java).pagePriority(pageId) } + val priority by lazy { Query.findPageById(pageId)?.priority ?: 0 } suspend fun start() { if (state != STARTING) return diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/cinematic/SimpleCinematicAction.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/cinematic/SimpleCinematicAction.kt similarity index 78% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/cinematic/SimpleCinematicAction.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/cinematic/SimpleCinematicAction.kt index b5c2339b96..bdb32f8b64 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/cinematic/SimpleCinematicAction.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/cinematic/SimpleCinematicAction.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.entry.cinematic +package com.typewritermc.engine.paper.entry.cinematic -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.entry.entries.activeSegmentAt -import me.gabber235.typewriter.entry.entries.canFinishAt +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.entry.entries.activeSegmentAt +import com.typewritermc.engine.paper.entry.entries.canFinishAt abstract class SimpleCinematicAction : CinematicAction { protected var lastFrame = 0 diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/dialogue/DialogueSequence.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/dialogue/DialogueSequence.kt similarity index 77% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/dialogue/DialogueSequence.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/dialogue/DialogueSequence.kt index 3890dcd552..75a153904f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/dialogue/DialogueSequence.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/dialogue/DialogueSequence.kt @@ -1,20 +1,20 @@ -package me.gabber235.typewriter.entry.dialogue - -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.entry.entries.SystemTrigger.DIALOGUE_END -import me.gabber235.typewriter.entry.entries.SystemTrigger.DIALOGUE_NEXT -import me.gabber235.typewriter.entry.priority -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.events.AsyncDialogueEndEvent -import me.gabber235.typewriter.events.AsyncDialogueStartEvent -import me.gabber235.typewriter.events.AsyncDialogueSwitchEvent -import me.gabber235.typewriter.facts.FactDatabase -import me.gabber235.typewriter.interaction.* -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC -import me.gabber235.typewriter.utils.playSound +package com.typewritermc.engine.paper.entry.dialogue + +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.priority +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.DialogueEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.DIALOGUE_END +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.DIALOGUE_NEXT +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.events.AsyncDialogueEndEvent +import com.typewritermc.engine.paper.events.AsyncDialogueStartEvent +import com.typewritermc.engine.paper.events.AsyncDialogueSwitchEvent +import com.typewritermc.engine.paper.facts.FactDatabase +import com.typewritermc.engine.paper.interaction.* +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.utils.playSound import org.bukkit.entity.Player import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/dialogue/MessengerFinder.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/dialogue/MessengerFinder.kt similarity index 69% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/dialogue/MessengerFinder.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/dialogue/MessengerFinder.kt index 13a2669956..2a7a32ab09 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/dialogue/MessengerFinder.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/dialogue/MessengerFinder.kt @@ -1,25 +1,26 @@ -package me.gabber235.typewriter.entry.dialogue +package com.typewritermc.engine.paper.entry.dialogue import com.destroystokyo.paper.event.player.PlayerJumpEvent import com.github.shynixn.mccoroutine.bukkit.ticks +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.utils.Reloadable +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.DialogueEntry +import com.typewritermc.engine.paper.interaction.chatHistory +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.config +import com.typewritermc.engine.paper.utils.reloadable +import com.typewritermc.loader.ExtensionLoader import kotlinx.coroutines.delay import lirand.api.extensions.events.listen import lirand.api.extensions.events.unregister import lirand.api.extensions.server.registerEvents -import me.gabber235.typewriter.adapters.AdapterLoader -import me.gabber235.typewriter.adapters.MessengerData -import me.gabber235.typewriter.adapters.MessengerFilter -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.interaction.chatHistory -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.config -import me.gabber235.typewriter.utils.reloadable import org.bukkit.entity.Player -import org.bukkit.event.* +import org.bukkit.event.Cancellable +import org.bukkit.event.EventPriority +import org.bukkit.event.Listener import org.bukkit.event.player.PlayerEvent import org.bukkit.event.player.PlayerSwapHandItemsEvent import org.bukkit.event.player.PlayerToggleSneakEvent @@ -27,35 +28,39 @@ import org.koin.core.component.KoinComponent import org.koin.core.component.inject import java.time.Duration import java.util.* -import kotlin.reflect.full.createInstance +import kotlin.reflect.KClass +import kotlin.reflect.full.companionObjectInstance import kotlin.reflect.full.primaryConstructor -class MessengerFinder : KoinComponent { - private val adapterLoader: AdapterLoader by inject() - - private var messengers = emptyMap() - - fun initialize() { - messengers = adapterLoader.adapters.flatMap { it.messengers }.associateBy({ it }, ::instantiateFilter) +class MessengerFinder : KoinComponent, Reloadable { + private val extensionLoader: ExtensionLoader by inject() + private var messengers = listOf() + + override fun load() { + messengers = extensionLoader.extensions.flatMap { it.dialogueMessengers }.map { + val messenger = extensionLoader.loadClass(it.className).kotlin + MessengerData( + dialogue = extensionLoader.loadClass(it.entryClassName).kotlin as KClass, + messenger = messenger as KClass>, + filter = messenger.companionObjectInstance as? MessengerFilter ?: EmptyMessengerFilter(), + priority = it.priority, + ) + } } - private fun instantiateFilter(data: MessengerData): MessengerFilter { - return if (data.filter.kotlin.isCompanion) { - data.filter.kotlin.objectInstance as MessengerFilter - } else { - data.filter.kotlin.createInstance() - } + override fun unload() { + messengers = emptyList() } fun findMessenger(player: Player, entry: DialogueEntry): DialogueMessenger { val messenger = messengers - .filter { it.key.dialogue.isInstance(entry) } - .filter { it.value.filter(player, entry) } - .maxByOrNull { it.key.priority }?.key?.messenger + .filter { it.dialogue.isInstance(entry) } + .filter { it.filter.filter(player, entry) } + .maxByOrNull { it.priority }?.messenger ?: return EmptyDialogueMessenger(player, entry) - return messenger.kotlin.primaryConstructor!!.call(player, entry) + return messenger.primaryConstructor!!.call(player, entry) } } @@ -97,6 +102,21 @@ open class DialogueMessenger(val player: Player, val entry: get() = entry.modifiers } +class MessengerData( + val messenger: KClass>, + val dialogue: KClass, + val filter: MessengerFilter, + val priority: Int +) + +interface MessengerFilter { + fun filter(player: Player, entry: DialogueEntry): Boolean +} + +class EmptyMessengerFilter : MessengerFilter { + override fun filter(player: Player, entry: DialogueEntry): Boolean = true +} + class EmptyDialogueMessenger(player: Player, entry: DialogueEntry) : DialogueMessenger(player, entry) { override fun init() { state = MessengerState.FINISHED diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/ActivityEntityDisplay.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/ActivityEntityDisplay.kt similarity index 74% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/ActivityEntityDisplay.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/ActivityEntityDisplay.kt index 02623f6576..2c486f8290 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/ActivityEntityDisplay.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/ActivityEntityDisplay.kt @@ -1,6 +1,7 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry import org.bukkit.Location import java.util.UUID @@ -14,7 +15,7 @@ interface ActivityEntityDisplay { /** * The location of the entity for the player. */ - fun location(playerId: UUID): Location? + fun position(playerId: UUID): Position? /** * Whether the player can view the entity. diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/ActivityManager.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/ActivityManager.kt similarity index 69% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/ActivityManager.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/ActivityManager.kt index 95751c2b24..84a0356db2 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/ActivityManager.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/ActivityManager.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.EntityProperty class ActivityManager( private val activity: EntityActivity, ) { - val location: LocationProperty - get() = activity.currentLocation + val position: PositionProperty + get() = activity.currentPosition val activeProperties: List get() = activity.currentProperties diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/AdvancedEntity.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/AdvancedEntity.kt similarity index 81% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/AdvancedEntity.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/AdvancedEntity.kt index 65067b3ad4..39f751b22d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/AdvancedEntity.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/AdvancedEntity.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entry.entity - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.descendants -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.priority -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.logger -import org.bukkit.Location +package com.typewritermc.engine.paper.entry.entity + +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.priority +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.descendants +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.logger @Tags("shared_entity_instance") interface SharedAdvancedEntityInstance : EntityInstanceEntry { @@ -60,7 +60,7 @@ interface IndividualAdvancedEntityInstance : EntityInstanceEntry { private fun EntityInstanceEntry.toAdvancedEntityDisplay( activityCreator: ActivityCreator, - creator: (Ref, EntityDefinitionEntry, ActivityCreator, List, Int>>, Location) -> AudienceFilter, + creator: (Ref, EntityDefinitionEntry, ActivityCreator, List, Int>>, Position) -> AudienceFilter, ): AudienceFilter { val definition = definition.get() if (definition == null) { diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/DisplayEntity.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/DisplayEntity.kt similarity index 70% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/DisplayEntity.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/DisplayEntity.kt index c7c5513867..d0d39a29b1 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/DisplayEntity.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/DisplayEntity.kt @@ -1,9 +1,10 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.PropertyCollector -import me.gabber235.typewriter.entry.entries.PropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.PropertySupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.PropertyCollector +import com.typewritermc.engine.paper.entry.entries.PropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.PropertySupplier +import com.typewritermc.engine.paper.utils.toBukkitLocation import org.bukkit.SoundCategory import org.bukkit.entity.Player import kotlin.reflect.full.companionObjectInstance @@ -16,13 +17,13 @@ internal class DisplayEntity( ) { private val entity = creator.create(player) - private var lastSoundLocation = activityManager.location + private var lastSoundLocation = activityManager.position val state: EntityState get() = entity.state init { - entity.spawn(activityManager.location) + entity.spawn(activityManager.position) applyProperties() } @@ -32,10 +33,10 @@ internal class DisplayEntity( // When the entity has moved far enough, play a sound // FIXME: Magic number - if ((lastSoundLocation.distanceSqrt(activityManager.location) ?: 0.0) > 1.7) { - lastSoundLocation = activityManager.location - val sound = lastSoundLocation.toLocation().block.blockData.soundGroup.stepSound - player.playSound(lastSoundLocation.toLocation(), sound, SoundCategory.PLAYERS, 0.4f, 1.0f) + if ((lastSoundLocation.distanceSqrt(activityManager.position) ?: 0.0) > 1.7) { + lastSoundLocation = activityManager.position + val sound = lastSoundLocation.toBukkitLocation().block.blockData.soundGroup.stepSound + player.playSound(lastSoundLocation.toBukkitLocation(), sound, SoundCategory.PLAYERS, 0.4f, 1.0f) } } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityActivity.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityActivity.kt similarity index 77% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityActivity.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityActivity.kt index 02ba73720d..268f2dc64f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityActivity.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityActivity.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.EntityActivityEntry -import me.gabber235.typewriter.entry.entries.EntityInstanceEntry -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.EntityActivityEntry +import com.typewritermc.engine.paper.entry.entries.EntityInstanceEntry +import com.typewritermc.engine.paper.entry.entries.EntityProperty import org.bukkit.entity.Player interface ActivityCreator { - fun create(context: ActivityContext, currentLocation: LocationProperty): EntityActivity + fun create(context: ActivityContext, currentLocation: PositionProperty): EntityActivity } interface EntityActivity { @@ -16,8 +16,8 @@ interface EntityActivity { fun tick(context: Context): TickResult fun dispose(context: Context) - val currentLocation: LocationProperty - val currentProperties: List get() = listOf(currentLocation) + val currentPosition: PositionProperty + val currentProperties: List get() = listOf(currentPosition) } /** @@ -37,7 +37,7 @@ interface SharedEntityActivity : EntityActivity interface IndividualEntityActivity : EntityActivity interface GenericEntityActivity : EntityActivity -class IdleActivity(override var currentLocation: LocationProperty) : GenericEntityActivity { +class IdleActivity(override var currentPosition: PositionProperty) : GenericEntityActivity { override fun initialize(context: ActivityContext) {} override fun tick(context: ActivityContext): TickResult = TickResult.IGNORED @@ -45,19 +45,19 @@ class IdleActivity(override var currentLocation: LocationProperty) : GenericEnti override fun dispose(context: ActivityContext) {} companion object : ActivityCreator { - override fun create(context: ActivityContext, currentLocation: LocationProperty): EntityActivity = IdleActivity(currentLocation) + override fun create(context: ActivityContext, currentLocation: PositionProperty): EntityActivity = IdleActivity(currentLocation) } } abstract class SingleChildActivity( - private val startLocation: LocationProperty, + private val startLocation: PositionProperty, ) : EntityActivity { private var child: Ref = emptyRef() private var currentActivity: EntityActivity? = null override fun initialize(context: Context) { child = currentChild(context) - currentActivity = child.get()?.create(context, currentLocation) + currentActivity = child.get()?.create(context, currentPosition) currentActivity?.initialize(context) } @@ -65,7 +65,7 @@ abstract class SingleChildActivity( val correctChild = currentChild(context) if (child != correctChild) { child = correctChild - val currentLocation = this.currentLocation + val currentLocation = this.currentPosition currentActivity?.dispose(context) currentActivity = child.get()?.create(context, currentLocation) currentActivity?.initialize(context) @@ -79,8 +79,8 @@ abstract class SingleChildActivity( child = emptyRef() } - override val currentLocation: LocationProperty - get() = currentActivity?.currentLocation ?: startLocation + override val currentPosition: PositionProperty + get() = currentActivity?.currentPosition ?: startLocation abstract fun currentChild(context: Context): Ref } diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityAttribute.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityAttribute.kt new file mode 100644 index 0000000000..4b24b47318 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityAttribute.kt @@ -0,0 +1,4 @@ +package com.typewritermc.engine.paper.entry.entity + +interface EntityAttribute { +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityHandler.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityHandler.kt similarity index 82% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityHandler.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityHandler.kt index a0d50cb076..526c33929b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityHandler.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityHandler.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity import com.github.retrooper.packetevents.PacketEvents import com.github.retrooper.packetevents.event.PacketListenerAbstract @@ -6,10 +6,10 @@ import com.github.retrooper.packetevents.event.PacketReceiveEvent import com.github.retrooper.packetevents.protocol.packettype.PacketType.Play import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.AudienceManager -import me.gabber235.typewriter.events.AsyncEntityDefinitionInteract -import me.gabber235.typewriter.events.AsyncFakeEntityInteract -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.entry.AudienceManager +import com.typewritermc.engine.paper.events.AsyncEntityDefinitionInteract +import com.typewritermc.engine.paper.events.AsyncFakeEntityInteract +import com.typewritermc.engine.paper.plugin import me.tofaa.entitylib.APIConfig import me.tofaa.entitylib.EntityLib import me.tofaa.entitylib.spigot.SpigotEntityLibPlatform @@ -35,7 +35,7 @@ class EntityHandler : PacketListenerAbstract(), KoinComponent { val packet = WrapperPlayClientInteractEntity(event) val entityId = packet.entityId - val player = event.player as? Player ?: server.getPlayer(event.user.uuid) ?: return + val player = event.getPlayer() ?: server.getPlayer(event.user.uuid) ?: return AsyncFakeEntityInteract(player, entityId, packet.hand, packet.action).callEvent() diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityStorage.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityStorage.kt new file mode 100644 index 0000000000..6b14c5fc83 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/EntityStorage.kt @@ -0,0 +1,10 @@ +package com.typewritermc.engine.paper.entry.entity + +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.EntityInstanceEntry +import java.util.concurrent.ConcurrentHashMap + +class EntityStorage { + val location = ConcurrentHashMap, PositionProperty>() + +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/FakeEntity.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/FakeEntity.kt similarity index 86% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/FakeEntity.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/FakeEntity.kt index b45ce198e2..d6b9a51841 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/FakeEntity.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/FakeEntity.kt @@ -1,6 +1,6 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.EntityProperty import org.bukkit.entity.Player import kotlin.reflect.KClass import kotlin.reflect.full.safeCast @@ -37,8 +37,8 @@ abstract class FakeEntity( open fun tick() {} - open fun spawn(location: LocationProperty) { - properties[LocationProperty::class] = location + open fun spawn(location: PositionProperty) { + properties[PositionProperty::class] = location } abstract fun addPassenger(entity: FakeEntity) diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/GroupActivityEntityDisplay.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/GroupActivityEntityDisplay.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/GroupActivityEntityDisplay.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/GroupActivityEntityDisplay.kt index 440a629f32..625b5a3d9c 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/GroupActivityEntityDisplay.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/GroupActivityEntityDisplay.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.* import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import org.bukkit.Location import org.bukkit.entity.Player import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -13,7 +13,7 @@ class GroupActivityEntityDisplay( override val creator: EntityCreator, private val activityCreators: ActivityCreator, private val suppliers: List, Int>>, - private val spawnLocation: Location, + private val spawnPosition: Position, private val group: GroupEntry, ) : AudienceFilter(ref), TickableDisplay, ActivityEntityDisplay { private val activityManagers = ConcurrentHashMap>() @@ -25,7 +25,7 @@ class GroupActivityEntityDisplay( override fun filter(player: Player): Boolean { val groupId = group.groupId(player) ?: GroupId(player.uniqueId) - val npcLocation = activityManagers[groupId]?.location ?: return false + val npcLocation = activityManagers[groupId]?.position ?: return false val distance = npcLocation.distanceSqrt(player.location) ?: return false return distance <= entityShowRange * entityShowRange } @@ -35,7 +35,7 @@ class GroupActivityEntityDisplay( activityManagers.computeIfAbsent(groupId) { val viewers = groupViewers(groupId) val context = SharedActivityContext(ref, viewers) - val activity = activityCreators.create(context, spawnLocation.toProperty()) + val activity = activityCreators.create(context, spawnPosition.toProperty()) val activityManager = ActivityManager(activity) activityManager.initialize(context) activityManager @@ -101,10 +101,10 @@ class GroupActivityEntityDisplay( return entities[playerId]?.contains(entityId) ?: false } - override fun location(playerId: UUID): Location? { + override fun position(playerId: UUID): Position? { val player = server.getPlayer(playerId) ?: return null val groupId = group.groupId(player) ?: GroupId(player.uniqueId) - return activityManagers[groupId]?.location?.toLocation() + return activityManagers[groupId]?.position } override fun canView(playerId: UUID): Boolean = canConsider(playerId) diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/IndividualActivityEntityDisplay.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/IndividualActivityEntityDisplay.kt similarity index 81% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/IndividualActivityEntityDisplay.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/IndividualActivityEntityDisplay.kt index 22a2f5455d..38fd5f977f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/IndividualActivityEntityDisplay.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/IndividualActivityEntityDisplay.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.EntityInstanceEntry -import me.gabber235.typewriter.entry.entries.PropertySupplier -import me.gabber235.typewriter.entry.entries.TickableDisplay -import org.bukkit.Location +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.AudienceFilter +import com.typewritermc.engine.paper.entry.entries.EntityInstanceEntry +import com.typewritermc.engine.paper.entry.entries.PropertySupplier +import com.typewritermc.engine.paper.entry.entries.TickableDisplay import org.bukkit.entity.Player import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -16,22 +16,22 @@ class IndividualActivityEntityDisplay( override val creator: EntityCreator, private val activityCreator: ActivityCreator, private val suppliers: List, Int>>, - private val spawnLocation: Location, + private val spawnPosition: Position, ) : AudienceFilter(ref), TickableDisplay, ActivityEntityDisplay { private val activityManagers = ConcurrentHashMap>() private val entities = ConcurrentHashMap() override fun filter(player: Player): Boolean { val activityManager = activityManagers[player.uniqueId] ?: return false - val npcLocation = activityManager.location - val distance = npcLocation.distanceSqrt(player.location) ?: return false + val npcPosition = activityManager.position + val distance = npcPosition.distanceSqrt(player.location) ?: return false return distance <= entityShowRange * entityShowRange } override fun onPlayerAdd(player: Player) { activityManagers.computeIfAbsent(player.uniqueId) { val context = IndividualActivityContext(ref, player) - val activity = activityCreator.create(context, spawnLocation.toProperty()) + val activity = activityCreator.create(context, spawnPosition.toProperty()) val activityManager = ActivityManager(activity) activityManager.initialize(context) activityManager @@ -83,6 +83,6 @@ class IndividualActivityEntityDisplay( return entities[playerId]?.contains(entityId) ?: false } - override fun location(playerId: UUID): Location? = activityManagers[playerId]?.location?.toLocation() + override fun position(playerId: UUID): Position? = activityManagers[playerId]?.position override fun canView(playerId: UUID): Boolean = canConsider(playerId) } \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/PositionProperty.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/PositionProperty.kt new file mode 100644 index 0000000000..51bee8f489 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/PositionProperty.kt @@ -0,0 +1,99 @@ +package com.typewritermc.engine.paper.entry.entity + +import com.typewritermc.core.utils.point.Point +import com.typewritermc.core.utils.point.Position +import com.typewritermc.core.utils.point.World +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.utils.toPosition + +class PositionProperty( + world: World, + x: Double, + y: Double, + z: Double, + yaw: Float, + pitch: Float, +) : EntityProperty, Position(world, x, y, z, yaw, pitch) { + fun distanceSqrt(other: org.bukkit.Location): Double? { + if (world.identifier != other.world.uid.toString()) return null + return distanceSqrt(other.toPosition()) + } + + fun distanceSqrt(other: Position): Double? { + if (world.identifier != other.world.identifier) return null + return distanceSquared(other) + } + + // Returns the x, z centered location + fun mid(): PositionProperty { + return copy(x = x.toInt() + 0.5, y = y.toInt().toDouble(), z = z.toInt() + 0.5) + } + + override fun withX(x: Double) = copy(x = x) + + override fun withY(y: Double) = copy(y = y) + + override fun withZ(z: Double) = copy(z = z) + + override fun add(x: Double, y: Double, z: Double): PositionProperty { + return copy(x = this.x + x, y = this.y + y, z = this.z + z) + } + + override fun add(point: Point) = add(point.x, point.y, point.z) + + override fun add(value: Double) = add(value, value, value) + + override fun plus(point: Point) = add(point) + + override fun plus(value: Double) = add(value) + + override fun sub(x: Double, y: Double, z: Double) = copy(x = this.x - x, y = this.y - y, z = this.z - z) + + override fun sub(point: Point) = sub(point.x, point.y, point.z) + + override fun sub(value: Double) = sub(value, value, value) + + override fun minus(point: Point) = sub(point) + + override fun minus(value: Double) = sub(value) + + override fun mul(x: Double, y: Double, z: Double) = copy(x = this.x * x, y = this.y * y, z = this.z * z) + + override fun mul(point: Point) = mul(point.x, point.y, point.z) + + override fun mul(value: Double) = mul(value, value, value) + + override fun times(point: Point) = mul(point) + + override fun times(value: Double) = mul(value) + + override fun div(x: Double, y: Double, z: Double) = copy(x = this.x / x, y = this.y / y, z = this.z / z) + + override fun div(point: Point) = div(point.x, point.y, point.z) + + override fun div(value: Double) = div(value, value, value) + + override fun copy( + world: World, + x: Double, + y: Double, + z: Double, + yaw: Float, + pitch: Float, + ): PositionProperty = PositionProperty( + world, + x, + y, + z, + yaw, + pitch + ) +} + +fun org.bukkit.Location.toProperty(): PositionProperty { + return PositionProperty(World(world.uid.toString()), x, y, z, yaw, pitch) +} + +fun Position.toProperty(): PositionProperty { + return PositionProperty(world, x, y, z, yaw, pitch) +} diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SharedActivityEntityDisplay.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SharedActivityEntityDisplay.kt similarity index 79% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SharedActivityEntityDisplay.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SharedActivityEntityDisplay.kt index 14115a88ac..bc62ddb88d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SharedActivityEntityDisplay.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SharedActivityEntityDisplay.kt @@ -1,11 +1,12 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.EntityInstanceEntry -import me.gabber235.typewriter.entry.entries.PropertySupplier -import me.gabber235.typewriter.entry.entries.TickableDisplay -import me.gabber235.typewriter.utils.config +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.AudienceFilter +import com.typewritermc.engine.paper.entry.entries.EntityInstanceEntry +import com.typewritermc.engine.paper.entry.entries.PropertySupplier +import com.typewritermc.engine.paper.entry.entries.TickableDisplay +import com.typewritermc.engine.paper.utils.config import org.bukkit.Location import org.bukkit.entity.Player import java.util.* @@ -18,13 +19,13 @@ class SharedActivityEntityDisplay( override val creator: EntityCreator, private val activityCreators: ActivityCreator, private val suppliers: List, Int>>, - private val spawnLocation: Location, + private val spawnPosition: Position, ) : AudienceFilter(ref), TickableDisplay, ActivityEntityDisplay { private var activityManager: ActivityManager? = null private val entities = ConcurrentHashMap() override fun filter(player: Player): Boolean { - val npcLocation = activityManager?.location ?: return false + val npcLocation = activityManager?.position ?: return false val distance = npcLocation.distanceSqrt(player.location) ?: return false return distance <= entityShowRange * entityShowRange } @@ -33,7 +34,7 @@ class SharedActivityEntityDisplay( super.initialize() val context = SharedActivityContext(ref, players) activityManager = - ActivityManager(activityCreators.create(context, spawnLocation.toProperty())) + ActivityManager(activityCreators.create(context, spawnPosition.toProperty())) activityManager?.initialize(context) } @@ -74,7 +75,7 @@ class SharedActivityEntityDisplay( return entities[playerId]?.contains(entityId) ?: false } - override fun location(playerId: UUID): Location? = activityManager?.location?.toLocation() + override fun position(playerId: UUID): Position? = activityManager?.position override fun canView(playerId: UUID): Boolean = canConsider(playerId) } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SimpleEntity.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SimpleEntity.kt similarity index 75% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SimpleEntity.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SimpleEntity.kt index 1e5b1fb533..5fa5f3efad 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SimpleEntity.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SimpleEntity.kt @@ -1,13 +1,13 @@ -package me.gabber235.typewriter.entry.entity - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.priority -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.logErrorIfNull +package com.typewritermc.engine.paper.entry.entity + +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.priority +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.utils.logErrorIfNull interface SimpleEntityDefinition : EntityDefinitionEntry diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SinglePropertyCollector.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SinglePropertyCollector.kt similarity index 68% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SinglePropertyCollector.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SinglePropertyCollector.kt index 4bab5d742f..ac717b321e 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SinglePropertyCollector.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SinglePropertyCollector.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.PropertyCollector -import me.gabber235.typewriter.entry.entries.PropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.PropertySupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.PropertyCollector +import com.typewritermc.engine.paper.entry.entries.PropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.PropertySupplier import org.bukkit.entity.Player import kotlin.reflect.KClass diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SkinProperty.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SkinProperty.kt similarity index 82% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SkinProperty.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SkinProperty.kt index ff5597a8fb..cf90b3a354 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/SkinProperty.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entity/SkinProperty.kt @@ -1,6 +1,6 @@ -package me.gabber235.typewriter.entry.entity +package com.typewritermc.engine.paper.entry.entity -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.EntityProperty import org.bukkit.entity.Player data class SkinProperty( diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/ActionEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/ActionEntry.kt similarity index 66% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/ActionEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/ActionEntry.kt index decd886ec9..38ef23e45b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/ActionEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/ActionEntry.kt @@ -1,11 +1,11 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.triggerEntriesFor -import me.gabber235.typewriter.facts.FactDatabase +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.triggerEntriesFor +import com.typewritermc.engine.paper.facts.FactDatabase import org.bukkit.entity.Player import org.koin.java.KoinJavaComponent.get diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/AssetEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/AssetEntry.kt similarity index 74% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/AssetEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/AssetEntry.kt index 9b6b9164fe..3d37ba01a8 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/AssetEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/AssetEntry.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entry.entries - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Generated -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.entry.StaticEntry -import me.gabber235.typewriter.utils.failure +package com.typewritermc.engine.paper.entry.entries + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.extension.annotations.Generated +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.failure +import com.typewritermc.engine.paper.entry.AssetManager +import com.typewritermc.engine.paper.entry.StaticEntry import org.koin.java.KoinJavaComponent @Tags("asset") diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/AudienceEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/AudienceEntry.kt similarity index 94% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/AudienceEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/AudienceEntry.kt index 0784775258..c192bad013 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/AudienceEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/AudienceEntry.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entry.entries - +package com.typewritermc.engine.paper.entry.entries + +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.priority +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.AudienceManager +import com.typewritermc.engine.paper.entry.ManifestEntry +import com.typewritermc.engine.paper.plugin import lirand.api.extensions.events.unregister import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.AudienceManager -import me.gabber235.typewriter.entry.ManifestEntry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.priority -import me.gabber235.typewriter.plugin import org.bukkit.entity.Player import org.bukkit.event.Listener import org.koin.core.component.KoinComponent diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/CinematicEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/CinematicEntry.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/CinematicEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/CinematicEntry.kt index 48aee15cf3..eac7fe647c 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/CinematicEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/CinematicEntry.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Entry +import com.typewritermc.engine.paper.entry.Criteria import org.bukkit.entity.Player @Tags("cinematic") diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/DialogueEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/DialogueEntry.kt new file mode 100644 index 0000000000..4eec22684b --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/DialogueEntry.kt @@ -0,0 +1,16 @@ +package com.typewritermc.engine.paper.entry.entries + +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry + +@Tags("dialogue") +interface DialogueEntry : TriggerableEntry { + @Help("The speaker of the dialogue") + val speaker: Ref + + val speakerDisplayName: String + get() = speaker.get()?.displayName ?: "" +} + diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/EntityEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/EntityEntry.kt similarity index 82% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/EntityEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/EntityEntry.kt index fb409e63a0..1274f33f1f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/EntityEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/EntityEntry.kt @@ -1,14 +1,15 @@ -package me.gabber235.typewriter.entry.entries - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.WithRotation -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entity.* -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +package com.typewritermc.engine.paper.entry.entries + +import com.typewritermc.core.entries.PriorityEntry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.WithRotation +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entity.* +import com.typewritermc.engine.paper.utils.Sound import org.bukkit.entity.Player -import org.checkerframework.checker.units.qual.A import kotlin.reflect.KClass @Tags("speaker") @@ -69,7 +70,7 @@ interface EntityInstanceEntry : AudienceFilterEntry { val definition: Ref @WithRotation - val spawnLocation: Location + val spawnLocation: Position } @Tags("entity_activity") @@ -79,43 +80,43 @@ interface EntityActivityEntry : ActivityCreator, ManifestEntry interface SharedEntityActivityEntry : EntityActivityEntry { override fun create( context: ActivityContext, - currentLocation: LocationProperty + currentLocation: PositionProperty ): EntityActivity { if (context !is SharedActivityContext) throw WrongActivityContextException(context, SharedActivityContext::class, this) return create(context, currentLocation) as EntityActivity } - fun create(context: SharedActivityContext, currentLocation: LocationProperty): EntityActivity + fun create(context: SharedActivityContext, currentLocation: PositionProperty): EntityActivity } @Tags("individual_entity_activity") interface IndividualEntityActivityEntry : EntityActivityEntry { override fun create( context: ActivityContext, - currentLocation: LocationProperty + currentLocation: PositionProperty ): EntityActivity { if (context !is IndividualActivityContext) throw WrongActivityContextException(context, IndividualActivityContext::class, this) return create(context, currentLocation) as EntityActivity } - fun create(context: IndividualActivityContext, currentLocation: LocationProperty): EntityActivity + fun create(context: IndividualActivityContext, currentLocation: PositionProperty): EntityActivity } @Tags("generic_entity_activity") interface GenericEntityActivityEntry : SharedEntityActivityEntry, IndividualEntityActivityEntry { override fun create( context: ActivityContext, - currentLocation: LocationProperty + currentLocation: PositionProperty ): EntityActivity override fun create( context: SharedActivityContext, - currentLocation: LocationProperty + currentLocation: PositionProperty ): EntityActivity { return create(context as ActivityContext, currentLocation) as EntityActivity } override fun create( context: IndividualActivityContext, - currentLocation: LocationProperty + currentLocation: PositionProperty ): EntityActivity { return create(context as ActivityContext, currentLocation) as EntityActivity } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/EventEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/EventEntry.kt similarity index 83% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/EventEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/EventEntry.kt index 66ec7b4a11..2a8ded060b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/EventEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/EventEntry.kt @@ -1,13 +1,16 @@ -package me.gabber235.typewriter.entry.entries - +package com.typewritermc.engine.paper.entry.entries + +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.entry.TriggerEntry +import com.typewritermc.engine.paper.entry.TriggerableEntry import dev.jorel.commandapi.CommandTree -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.entry.* import org.bukkit.entity.Player -import org.koin.java.KoinJavaComponent @Tags("event") interface EventEntry : TriggerEntry @@ -92,7 +95,7 @@ data class CinematicStartTrigger( val triggers: List> = emptyList(), val settings: CinematicSettings = CinematicSettings(), ) : EventTrigger { - val priority: Int = KoinJavaComponent.get(EntryDatabase::class.java).pagePriority(pageId) + val priority: Int by lazy(LazyThreadSafetyMode.NONE) { Query.findPageById(pageId)?.priority ?: 0 } override val id: String get() = "system.cinematic.start.$pageId" diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/FactEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/FactEntry.kt similarity index 71% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/FactEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/FactEntry.kt index 1f18e3acb2..620041dc18 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/FactEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/FactEntry.kt @@ -1,15 +1,15 @@ -package me.gabber235.typewriter.entry.entries - +package com.typewritermc.engine.paper.entry.entries + +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.PlaceholderEntry +import com.typewritermc.engine.paper.entry.StaticEntry +import com.typewritermc.engine.paper.facts.FactData +import com.typewritermc.engine.paper.facts.FactDatabase +import com.typewritermc.engine.paper.facts.FactId import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.entry.PlaceholderEntry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.StaticEntry -import me.gabber235.typewriter.facts.FactData -import me.gabber235.typewriter.facts.FactDatabase -import me.gabber235.typewriter.facts.FactId import org.bukkit.entity.Player import org.koin.java.KoinJavaComponent.get import java.util.* @@ -31,7 +31,7 @@ interface FactEntry : StaticEntry { entry.groupId(player) ?: return null } else { // If no group entry is set, we assume that the player is the group for backwards compatibility - GroupId(player.uniqueId) + com.typewritermc.engine.paper.entry.entries.GroupId(player.uniqueId) } return FactId(id, groupId) @@ -68,7 +68,7 @@ interface ReadableFactEntry : FactEntry, PlaceholderEntry { } @Tags("writable-fact") -interface WritableFactEntry : FactEntry { +interface WritableFactEntry : com.typewritermc.engine.paper.entry.entries.FactEntry { fun write(player: Player, value: Int) { val factId = identifier(player) ?: return write(factId, value) @@ -78,9 +78,10 @@ interface WritableFactEntry : FactEntry { } @Tags("cachable-fact") -interface CachableFactEntry : ReadableFactEntry, WritableFactEntry { +interface CachableFactEntry : com.typewritermc.engine.paper.entry.entries.ReadableFactEntry, + com.typewritermc.engine.paper.entry.entries.WritableFactEntry { - override fun readForGroup(groupId: GroupId): FactData { + override fun readForGroup(groupId: com.typewritermc.engine.paper.entry.entries.GroupId): FactData { return read(FactId(id, groupId)) } @@ -103,11 +104,11 @@ interface CachableFactEntry : ReadableFactEntry, WritableFactEntry { } @Tags("persistable-fact") -interface PersistableFactEntry : CachableFactEntry { +interface PersistableFactEntry : com.typewritermc.engine.paper.entry.entries.CachableFactEntry { fun canPersist(id: FactId, data: FactData): Boolean = true } @Tags("expirable-fact") -interface ExpirableFactEntry : CachableFactEntry { +interface ExpirableFactEntry : com.typewritermc.engine.paper.entry.entries.CachableFactEntry { fun hasExpired(id: FactId, data: FactData): Boolean = false } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/GroupEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/GroupEntry.kt similarity index 84% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/GroupEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/GroupEntry.kt index 96569c7233..6d82b11ae6 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/GroupEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/GroupEntry.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.StaticEntry import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.StaticEntry import org.bukkit.entity.Player import java.util.* diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/LinesEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/LinesEntry.kt similarity index 83% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/LinesEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/LinesEntry.kt index dc0c17f32b..20692aa4e1 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/LinesEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/LinesEntry.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.PlaceholderEntry -import me.gabber235.typewriter.entry.PriorityEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.core.entries.PriorityEntry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.PlaceholderEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders import org.bukkit.entity.Player import kotlin.reflect.KClass diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/QuestEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/QuestEntry.kt similarity index 82% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/QuestEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/QuestEntry.kt index 00ee4956d0..18ab285072 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/QuestEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/QuestEntry.kt @@ -1,20 +1,21 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries +import com.typewritermc.core.entries.* import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.quest.QuestStatus -import me.gabber235.typewriter.entry.quest.isQuestActive -import me.gabber235.typewriter.entry.quest.trackQuest -import me.gabber235.typewriter.entry.quest.trackedQuest -import me.gabber235.typewriter.events.AsyncQuestStatusUpdate -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.asMini -import me.gabber235.typewriter.utils.asMiniWithResolvers +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.quest.QuestStatus +import com.typewritermc.engine.paper.entry.quest.isQuestActive +import com.typewritermc.engine.paper.entry.quest.trackQuest +import com.typewritermc.engine.paper.entry.quest.trackedQuest +import com.typewritermc.engine.paper.events.AsyncQuestStatusUpdate +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.asMini +import com.typewritermc.engine.paper.utils.asMiniWithResolvers import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed import org.bukkit.entity.Player import org.bukkit.event.EventHandler diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/RoadNetworkEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/RoadNetworkEntry.kt similarity index 84% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/RoadNetworkEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/RoadNetworkEntry.kt index 04e1aa281b..d489159684 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/RoadNetworkEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/RoadNetworkEntry.kt @@ -1,29 +1,38 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries import com.github.retrooper.packetevents.util.Vector3f import com.google.gson.Gson import com.google.gson.GsonBuilder -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.ContentEditor -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.components.bossBar -import me.gabber235.typewriter.content.components.exit -import me.gabber235.typewriter.content.components.nodes -import me.gabber235.typewriter.content.entryId -import me.gabber235.typewriter.content.fieldPath -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.roadnetwork.content.RoadNetworkEditorComponent -import me.gabber235.typewriter.entry.roadnetwork.content.material -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.* +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.ContentEditor +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.core.utils.point.World +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.components.bossBar +import com.typewritermc.engine.paper.content.components.exit +import com.typewritermc.engine.paper.content.components.nodes +import com.typewritermc.engine.paper.content.entryId +import com.typewritermc.engine.paper.content.fieldPath +import com.typewritermc.engine.paper.entry.fieldValue +import com.typewritermc.engine.paper.entry.roadnetwork.content.RoadNetworkEditorComponent +import com.typewritermc.engine.paper.entry.roadnetwork.content.material +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.loader.serializers.WorldSerializer +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.LocationSerializer +import com.typewritermc.engine.paper.utils.RuntimeTypeAdapterFactory +import com.typewritermc.engine.paper.utils.playSound import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.Location import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack -import org.koin.java.KoinJavaComponent -import java.util.Map.entry val roadNetworkMaxDistance by snippet("road_network.distance.max", 30.0) @@ -148,6 +157,7 @@ fun Collection.containsAddition(start: RoadNodeId, end: RoadNo fun createRoadNetworkParser(): Gson = GsonBuilder() .registerTypeAdapter(Location::class.java, LocationSerializer()) + .registerTypeAdapter(World::class.java, WorldSerializer()) .registerTypeAdapterFactory( RuntimeTypeAdapterFactory.of(RoadModification::class.java) .registerSubtype(RoadModification.EdgeAddition::class.java) diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/SidebarEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/SidebarEntry.kt similarity index 87% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/SidebarEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/SidebarEntry.kt index aaed1dd047..2adc03b2f4 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/SidebarEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/SidebarEntry.kt @@ -1,18 +1,22 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries import com.github.retrooper.packetevents.protocol.score.ScoreFormat import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisplayScoreboard import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerResetScore import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerScoreboardObjective import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateScore -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.entries.PriorityEntry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.priority +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import net.kyori.adventure.text.Component import org.bukkit.entity.Player import java.util.* diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/SoundEntry.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/SoundEntry.kt similarity index 60% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/SoundEntry.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/SoundEntry.kt index c7ae295c8c..7436b543a4 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/SoundEntry.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/entries/SoundEntry.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.entry.entries +package com.typewritermc.engine.paper.entry.entries -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.PlaceholderEntry -import me.gabber235.typewriter.entry.StaticEntry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.PlaceholderEntry +import com.typewritermc.engine.paper.entry.StaticEntry import net.kyori.adventure.sound.Sound import org.bukkit.entity.Player diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/quest/QuestTracker.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/quest/QuestTracker.kt similarity index 87% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/quest/QuestTracker.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/quest/QuestTracker.kt index 1d513af3f3..ff40697580 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/quest/QuestTracker.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/quest/QuestTracker.kt @@ -1,17 +1,15 @@ -package me.gabber235.typewriter.entry.quest - -import com.github.shynixn.mccoroutine.bukkit.launch -import com.github.shynixn.mccoroutine.bukkit.ticks -import kotlinx.coroutines.delay -import lirand.api.extensions.events.SimpleListener -import lirand.api.extensions.events.unregister -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.QuestEntry -import me.gabber235.typewriter.events.AsyncQuestStatusUpdate -import me.gabber235.typewriter.events.AsyncTrackedQuestUpdate -import me.gabber235.typewriter.interaction.InteractionHandler -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +package com.typewritermc.engine.paper.entry.quest + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.entry.FactListenerSubscription +import com.typewritermc.engine.paper.entry.entries.QuestEntry +import com.typewritermc.engine.paper.entry.listenForFacts +import com.typewritermc.engine.paper.events.AsyncQuestStatusUpdate +import com.typewritermc.engine.paper.events.AsyncTrackedQuestUpdate +import com.typewritermc.engine.paper.interaction.InteractionHandler +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import org.bukkit.entity.Player import org.koin.java.KoinJavaComponent.get import java.util.concurrent.ConcurrentHashMap diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/RoadNetworkEditor.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/RoadNetworkEditor.kt similarity index 92% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/RoadNetworkEditor.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/RoadNetworkEditor.kt index fe7c013d05..29051e0bf9 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/RoadNetworkEditor.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/RoadNetworkEditor.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entry.roadnetwork +package com.typewritermc.engine.paper.entry.roadnetwork import co.touchlab.stately.concurrency.AtomicInt import com.github.shynixn.mccoroutine.bukkit.launch @@ -8,12 +8,12 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.roadnetwork.gps.roadNetworkFindPath -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFInstanceSpace -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.roadnetwork.gps.roadNetworkFindPath +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import org.koin.core.component.KoinComponent import org.koin.core.component.inject import java.util.concurrent.Executors diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/RoadNetworkManager.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/RoadNetworkManager.kt similarity index 87% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/RoadNetworkManager.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/RoadNetworkManager.kt index 96203704ad..db792d5cf3 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/RoadNetworkManager.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/RoadNetworkManager.kt @@ -1,19 +1,19 @@ -package me.gabber235.typewriter.entry.roadnetwork +package com.typewritermc.engine.paper.entry.roadnetwork import com.google.common.cache.CacheBuilder import com.google.common.cache.CacheLoader import com.google.gson.Gson +import com.typewritermc.core.entries.Query import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.delay -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.RoadNetwork -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.RoadNetwork +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koin.core.qualifier.named diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/RoadNetworkContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/RoadNetworkContentMode.kt similarity index 86% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/RoadNetworkContentMode.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/RoadNetworkContentMode.kt index 652b7040ed..c5ff4fc03e 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/RoadNetworkContentMode.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/RoadNetworkContentMode.kt @@ -1,24 +1,25 @@ -package me.gabber235.typewriter.entry.roadnetwork.content +package com.typewritermc.engine.paper.entry.roadnetwork.content import com.github.retrooper.packetevents.protocol.particle.Particle import com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes import com.github.retrooper.packetevents.util.Vector3f import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle -import lirand.api.extensions.inventory.meta -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.components.* -import me.gabber235.typewriter.content.entryId -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkEditorState -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toVector3d -import me.gabber235.typewriter.utils.* -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.engine.paper.content.ContentComponent +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.components.* +import com.typewritermc.engine.paper.content.entryId +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkEditorState +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.extensions.packetevents.toVector3d +import com.typewritermc.engine.paper.utils.* +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.Color @@ -187,19 +188,23 @@ private class NetworkAddNodeComponent( private val onAddNegative: () -> Unit = {}, ) : ContentComponent, ItemsComponent { override fun items(player: Player): Map { - val addNodeItem = ItemStack(Material.DIAMOND).meta { - name = "Add Node" - loreString = " Click to add a new node to the road network" + val addNodeItem = ItemStack(Material.DIAMOND).apply { + editMeta { meta -> + meta.name = "Add Node" + meta.loreString = " Click to add a new node to the road network" + } } onInteract { if (it.type.isClick) onAdd() } - val addNegativeNodeItem = ItemStack(Material.NETHERITE_INGOT).meta { - name = "Add Negative Node" - loreString = """ + val addNegativeNodeItem = ItemStack(Material.NETHERITE_INGOT).apply { + editMeta { meta -> + meta.name = "Add Negative Node" + meta.loreString = """ | Click to add a new negative node to the road network | Blocking pathfinding through its radius """.trimMargin() + } } onInteract { if (it.type.isClick) onAddNegative() } @@ -219,9 +224,11 @@ private class NetworkHighlightComponent( private val onHighlight: () -> Unit = {} ) : ItemComponent { override fun item(player: Player): Pair { - val item = ItemStack(Material.GLOWSTONE_DUST).meta { - name = "Highlight Nodes" - loreString = " Click to highlight all nodes" + val item = ItemStack(Material.GLOWSTONE_DUST).apply { + editMeta { meta -> + meta.name = "Highlight Nodes" + meta.loreString = " Click to highlight all nodes" + } } onInteract { if (!it.type.isClick) return@onInteract onHighlight() @@ -236,9 +243,11 @@ private class NetworkRecalculateAllEdgesComponent( private val onRecalculate: () -> Unit = {} ) : ItemComponent { override fun item(player: Player): Pair { - val item = ItemStack(Material.REDSTONE).meta { - name = "Recalculate Edges" - loreString = " Click to recalculate all edges, this might take a while." + val item = ItemStack(Material.REDSTONE).apply { + editMeta { meta -> + meta.name = "Recalculate Edges" + meta.loreString = " Click to recalculate all edges, this might take a while." + } } onInteract { if (!it.type.isClick) return@onInteract onRecalculate() diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/RoadNetworkEditorComponent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/RoadNetworkEditorComponent.kt similarity index 67% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/RoadNetworkEditorComponent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/RoadNetworkEditorComponent.kt index 29dca71c59..d5e24e205e 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/RoadNetworkEditorComponent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/RoadNetworkEditorComponent.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entry.roadnetwork.content - -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.RoadNetwork -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkEditorState -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkManager -import me.gabber235.typewriter.utils.ThreadType +package com.typewritermc.engine.paper.entry.roadnetwork.content + +import com.typewritermc.engine.paper.content.ContentComponent +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.RoadNetwork +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkEditorState +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkManager +import com.typewritermc.engine.paper.utils.ThreadType import org.bukkit.entity.Player import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt similarity index 82% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt index 3f6378eb90..7b4c9aeb16 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/SelectedNegativeNodeContentMode.kt @@ -1,17 +1,17 @@ -package me.gabber235.typewriter.entry.roadnetwork.content +package com.typewritermc.engine.paper.entry.roadnetwork.content import com.github.retrooper.packetevents.util.Vector3f -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.components.bossBar -import me.gabber235.typewriter.content.components.exit -import me.gabber235.typewriter.content.components.nodes -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.forceTriggerFor -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkEditorState -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.utils.ok +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.components.bossBar +import com.typewritermc.engine.paper.content.components.exit +import com.typewritermc.engine.paper.content.components.nodes +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.forceTriggerFor +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkEditorState +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.core.utils.ok import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.Color diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt similarity index 86% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt index c06ef4bd1b..f18e5f569b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/content/SelectedRoadNodeContentMode.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entry.roadnetwork.content +package com.typewritermc.engine.paper.entry.roadnetwork.content import com.extollit.gaming.ai.path.model.IPath import com.github.retrooper.packetevents.protocol.particle.Particle @@ -7,26 +7,25 @@ import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes import com.github.retrooper.packetevents.util.Vector3d import com.github.retrooper.packetevents.util.Vector3f import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle +import com.typewritermc.core.utils.loopingDistance +import com.typewritermc.core.utils.ok import lirand.api.extensions.events.unregister -import lirand.api.extensions.inventory.meta import lirand.api.extensions.server.registerEvents -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.components.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entity.toProperty -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.forceTriggerFor -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkEditorState -import me.gabber235.typewriter.entry.roadnetwork.gps.roadNetworkFindPath -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFEmptyEntity -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFInstanceSpace -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.* -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.content.ContentComponent +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.content.components.* +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.forceTriggerFor +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkEditorState +import com.typewritermc.engine.paper.entry.roadnetwork.gps.roadNetworkFindPath +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.* +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.format.TextColor @@ -266,9 +265,11 @@ class RemoveNodeComponent( private val onRemove: () -> Unit, ) : ItemComponent { override fun item(player: Player): Pair { - return slot to (ItemStack(Material.REDSTONE_BLOCK).meta { - name = "Remove Node" - loreString = " Careful! This action is irreversible." + return slot to (ItemStack(Material.REDSTONE_BLOCK).apply { + editMeta { meta -> + meta.name = "Remove Node" + meta.loreString = " Careful! This action is irreversible." + } } onInteract { onRemove() }) @@ -358,14 +359,18 @@ class NodeRadiusComponent( private var scrolling: UUID? = null override fun item(player: Player): Pair { - val item = if (scrolling != null) ItemStack(Material.CALIBRATED_SCULK_SENSOR).meta { - name = "Selecting Radius" - loreString = " Right click to set the radius of the node." - unClickable() - } else ItemStack(Material.SCULK_SENSOR).meta { - name = "Change Radius" - loreString = " Current radius: ${nodeFetcher()?.radius}" - unClickable() + val item = if (scrolling != null) ItemStack(Material.CALIBRATED_SCULK_SENSOR).apply { + editMeta { meta -> + meta.name = "Selecting Radius" + meta.loreString = " Right click to set the radius of the node." + meta.unClickable() + } + } else ItemStack(Material.SCULK_SENSOR).apply { + editMeta { meta -> + meta.name = "Change Radius" + meta.loreString = " Current radius: ${nodeFetcher()?.radius}" + meta.unClickable() + } } return slot to (item onInteract { scrolling = if (scrolling == player.uniqueId) { @@ -430,28 +435,32 @@ private class ModificationComponent( val node = nodeFetcher() ?: return map val network = networkFetcher() - map[5] = ItemStack(Material.EMERALD).meta { - name = "Add Fast Travel Connection" - loreString = """ + map[5] = ItemStack(Material.EMERALD).apply { + editMeta { meta -> + meta.name = "Add Fast Travel Connection" + meta.loreString = """ | Click on a unconnected node to add a fast travel connection to it. | Click on a modified node to remove the connection. | | If you only want to connect one way, hold Shift while clicking. |""".trimMargin() - unClickable() + meta.unClickable() + } } onInteract {} val hasEdges = network.edges.any { it.start == node.id } if (hasEdges) { - map[6] = ItemStack(Material.REDSTONE).meta { - name = "Remove Edge" - loreString = """ + map[6] = ItemStack(Material.REDSTONE).apply { + editMeta { meta -> + meta.name = "Remove Edge" + meta.loreString = """ | Click on a connected node to force remove the edge between them. | Click on a modified node to allow the edge to be added again. | | If you only want to remove one way, hold Shift while clicking. """.trimMargin() - unClickable() + meta.unClickable() + } } onInteract { } } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/GPS.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt similarity index 80% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/GPS.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt index 60e4f3d1ad..1c5c6eecb9 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/GPS.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt @@ -1,15 +1,14 @@ -package me.gabber235.typewriter.entry.roadnetwork.gps +package com.typewritermc.engine.paper.entry.roadnetwork.gps import com.extollit.gaming.ai.path.HydrazinePathFinder -import com.extollit.gaming.ai.path.SchedulingPriority import com.extollit.gaming.ai.path.model.* -import me.gabber235.typewriter.entry.entity.toProperty -import me.gabber235.typewriter.entry.entries.RoadNode -import me.gabber235.typewriter.entry.entries.roadNetworkMaxDistance -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFEmptyEntity -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFInstanceSpace -import me.gabber235.typewriter.utils.Vector -import me.gabber235.typewriter.utils.distanceSqrt +import com.typewritermc.engine.paper.entry.entity.toProperty +import com.typewritermc.engine.paper.entry.entries.RoadNode +import com.typewritermc.engine.paper.entry.entries.roadNetworkMaxDistance +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFEmptyEntity +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.engine.paper.utils.distanceSqrt import org.bukkit.Location interface GPS { diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/PathStreamDisplay.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/PathStreamDisplay.kt similarity index 86% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/PathStreamDisplay.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/PathStreamDisplay.kt index f9d16d80a8..f12b67f8bd 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/PathStreamDisplay.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/PathStreamDisplay.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entry.roadnetwork.gps +package com.typewritermc.engine.paper.entry.roadnetwork.gps import com.extollit.gaming.ai.path.HydrazinePathFinder import com.extollit.linalg.immutable.Vec3d @@ -11,20 +11,20 @@ import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entity.toProperty -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.entries.TickableDisplay -import me.gabber235.typewriter.entry.entries.roadNetworkMaxDistance -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFEmptyEntity -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFInstanceSpace -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toVector3d -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC -import me.gabber235.typewriter.utils.distanceSqrt -import me.gabber235.typewriter.utils.firstWalkableLocationBelow +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entity.toProperty +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.entries.TickableDisplay +import com.typewritermc.engine.paper.entry.entries.roadNetworkMaxDistance +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFEmptyEntity +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.extensions.packetevents.toVector3d +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.utils.distanceSqrt +import com.typewritermc.engine.paper.utils.firstWalkableLocationBelow import org.bukkit.Location import org.bukkit.entity.Player import java.util.* diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/PointToPointGPS.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/PointToPointGPS.kt similarity index 95% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/PointToPointGPS.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/PointToPointGPS.kt index b54f82f12f..c2fa77f237 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/gps/PointToPointGPS.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/PointToPointGPS.kt @@ -1,17 +1,17 @@ -package me.gabber235.typewriter.entry.roadnetwork.gps +package com.typewritermc.engine.paper.entry.roadnetwork.gps import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.roadnetwork.RoadNetworkManager -import me.gabber235.typewriter.entry.roadnetwork.pathfinding.PFInstanceSpace -import me.gabber235.typewriter.utils.ComputedMap -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC -import me.gabber235.typewriter.utils.distanceSqrt -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkManager +import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace +import com.typewritermc.engine.paper.utils.ComputedMap +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.utils.distanceSqrt +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok import org.bukkit.Location import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFBlock.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFBlock.kt similarity index 97% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFBlock.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFBlock.kt index 66b5b22d3b..50d9c1997d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFBlock.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFBlock.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entry.roadnetwork.pathfinding +package com.typewritermc.engine.paper.entry.roadnetwork.pathfinding import com.extollit.gaming.ai.path.model.IBlockDescription import com.extollit.gaming.ai.path.model.IBlockObject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFColumnarSpace.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFColumnarSpace.kt similarity index 88% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFColumnarSpace.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFColumnarSpace.kt index 97c01116d5..a109776c9d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFColumnarSpace.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFColumnarSpace.kt @@ -1,7 +1,6 @@ -package me.gabber235.typewriter.entry.roadnetwork.pathfinding +package com.typewritermc.engine.paper.entry.roadnetwork.pathfinding import com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList -import com.extollit.gaming.ai.path.model.IBlockDescription import com.extollit.gaming.ai.path.model.IColumnarSpace import com.extollit.gaming.ai.path.model.IInstanceSpace import org.bukkit.ChunkSnapshot diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFEmptyEntity.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFEmptyEntity.kt similarity index 94% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFEmptyEntity.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFEmptyEntity.kt index 9e661c73d0..f157a18f1d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFEmptyEntity.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFEmptyEntity.kt @@ -1,10 +1,10 @@ -package me.gabber235.typewriter.entry.roadnetwork.pathfinding +package com.typewritermc.engine.paper.entry.roadnetwork.pathfinding import com.extollit.gaming.ai.path.model.Gravitation import com.extollit.gaming.ai.path.model.IPathingEntity import com.extollit.gaming.ai.path.model.Passibility import com.extollit.linalg.immutable.Vec3d -import me.gabber235.typewriter.utils.Point +import com.typewritermc.core.utils.point.Point class PFEmptyEntity( private val position: Point, diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFInstanceSpace.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFInstanceSpace.kt similarity index 94% rename from plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFInstanceSpace.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFInstanceSpace.kt index 245ff2c7b9..b2e1dba429 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/roadnetwork/pathfinding/PFInstanceSpace.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/pathfinding/PFInstanceSpace.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entry.roadnetwork.pathfinding +package com.typewritermc.engine.paper.entry.roadnetwork.pathfinding import com.extollit.gaming.ai.path.model.IBlockObject import com.extollit.gaming.ai.path.model.IInstanceSpace diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicEndEvent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicEndEvent.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicEndEvent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicEndEvent.kt index 157e470829..a9c91004d0 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicEndEvent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicEndEvent.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import org.bukkit.entity.Player import org.bukkit.event.HandlerList diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicStartEvent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicStartEvent.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicStartEvent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicStartEvent.kt index 2e26efcbdb..b97219aee2 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicStartEvent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicStartEvent.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import org.bukkit.entity.Player import org.bukkit.event.HandlerList diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicTickEvent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicTickEvent.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicTickEvent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicTickEvent.kt index 95711d5f1b..48f189f60f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncCinematicTickEvent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncCinematicTickEvent.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import org.bukkit.entity.Player import org.bukkit.event.HandlerList diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncDialogueEvents.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncDialogueEvents.kt similarity index 95% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncDialogueEvents.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncDialogueEvents.kt index f58421e29e..c7d241a28b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncDialogueEvents.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncDialogueEvents.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import org.bukkit.entity.Player import org.bukkit.event.HandlerList diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncEntityDefinitionInteract.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncEntityDefinitionInteract.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncEntityDefinitionInteract.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncEntityDefinitionInteract.kt index 1df8c55e0d..1259979d5d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncEntityDefinitionInteract.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncEntityDefinitionInteract.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import com.github.retrooper.packetevents.protocol.player.InteractionHand import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity.InteractAction -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry import org.bukkit.entity.Player import org.bukkit.event.HandlerList import org.bukkit.event.player.PlayerEvent diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncQuestStatusUpdate.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncQuestStatusUpdate.kt similarity index 70% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncQuestStatusUpdate.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncQuestStatusUpdate.kt index a5b168d18a..4ec45ed709 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncQuestStatusUpdate.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncQuestStatusUpdate.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.QuestEntry -import me.gabber235.typewriter.entry.quest.QuestStatus +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.QuestEntry +import com.typewritermc.engine.paper.entry.quest.QuestStatus import org.bukkit.entity.Player import org.bukkit.event.HandlerList import org.bukkit.event.player.PlayerEvent diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncTrackedQuestUpdate.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncTrackedQuestUpdate.kt similarity index 76% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncTrackedQuestUpdate.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncTrackedQuestUpdate.kt index 222af871bd..92be33c676 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/AsyncTrackedQuestUpdate.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/AsyncTrackedQuestUpdate.kt @@ -1,7 +1,7 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.QuestEntry +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.QuestEntry import org.bukkit.entity.Player import org.bukkit.event.HandlerList import org.bukkit.event.player.PlayerEvent diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/ContentEditorEvents.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/ContentEditorEvents.kt similarity index 94% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/ContentEditorEvents.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/ContentEditorEvents.kt index 5644fa0098..06309c76dd 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/ContentEditorEvents.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/ContentEditorEvents.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import org.bukkit.entity.Player import org.bukkit.event.HandlerList diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/StagingChangeEvent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/StagingChangeEvent.kt similarity index 81% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/StagingChangeEvent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/StagingChangeEvent.kt index 4b96237a5a..f231997995 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/StagingChangeEvent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/StagingChangeEvent.kt @@ -1,7 +1,7 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.StagingState +import com.typewritermc.engine.paper.entry.StagingState import org.bukkit.event.Event import org.bukkit.event.HandlerList diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/PublishedBookEvent.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/TypewriterUnloadEvent.kt similarity index 75% rename from plugin/src/main/kotlin/me/gabber235/typewriter/events/PublishedBookEvent.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/TypewriterUnloadEvent.kt index 518a202771..687bbf833b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/PublishedBookEvent.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/events/TypewriterUnloadEvent.kt @@ -1,10 +1,10 @@ -package me.gabber235.typewriter.events +package com.typewritermc.engine.paper.events import lirand.api.extensions.server.server import org.bukkit.event.Event import org.bukkit.event.HandlerList -class PublishedBookEvent : Event(!server.isPrimaryThread) { +class TypewriterUnloadEvent : Event(!server.isPrimaryThread) { override fun getHandlers(): HandlerList = HANDLER_LIST companion object { diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/bstats/BStatsMetrics.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/bstats/BStatsMetrics.kt new file mode 100644 index 0000000000..37da3ab5d2 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/bstats/BStatsMetrics.kt @@ -0,0 +1,30 @@ +package com.typewritermc.engine.paper.extensions.bstats + +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Query +import com.typewritermc.engine.paper.plugin +import com.typewritermc.loader.ExtensionLoader +import org.bstats.bukkit.Metrics +import org.bstats.charts.AdvancedPie +import org.koin.java.KoinJavaComponent.get +import kotlin.reflect.full.findAnnotation + +object BStatsMetrics { + private const val ID = 17839 + fun registerMetrics() { + val metrics = Metrics(plugin, ID) + + metrics.addCustomChart(AdvancedPie("extensions") { + get(ExtensionLoader::class.java).extensions.associate { it.extension.name to 1 }.toMap() + }) + + metrics.addCustomChart(AdvancedPie("entries") { + val entries = Query.find() + entries.groupBy { + it::class.findAnnotation()?.name + ?: it::class.simpleName + ?: "Unknown" + }.mapValues { it.value.size }.toMap() + }) + } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/modrinth/Modrinth.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/modrinth/Modrinth.kt similarity index 70% rename from plugin/src/main/kotlin/me/gabber235/typewriter/extensions/modrinth/Modrinth.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/modrinth/Modrinth.kt index cc1324f605..a1787040a1 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/modrinth/Modrinth.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/modrinth/Modrinth.kt @@ -1,15 +1,14 @@ -package me.gabber235.typewriter.extensions.modrinth +package com.typewritermc.engine.paper.extensions.modrinth import com.google.gson.GsonBuilder import com.google.gson.annotations.SerializedName +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.asMini import kotlinx.coroutines.delay import kotlinx.coroutines.future.await import lirand.api.extensions.events.SimpleListener import lirand.api.extensions.events.listen -import me.gabber235.typewriter.entry.v -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.asMini import org.bukkit.entity.Player import org.bukkit.event.player.PlayerJoinEvent import java.net.URI @@ -151,4 +150,78 @@ data class Dependency( @SerializedName("project_id") val projectId: String = "", @SerializedName("file_name") val fileName: String? = "", @SerializedName("dependency_type") val dependencyType: String = "", -) \ No newline at end of file +) + +internal val String.v get() = SemanticVersion.fromString(this) + +data class SemanticVersion( + val major: Int, + val minor: Int, + val patch: Int, + val type: VersionType = VersionType.RELEASE, + val buildNumber: Int = 0, +) : Comparable { + companion object { + fun fromString(version: String): SemanticVersion { + val versionParts = version.split("-") + val versionPart = versionParts[0] + val parts = versionPart.split(".") + if (parts.size != 3) { + throw IllegalArgumentException("Invalid version format: $version") + } + + val (major, minor, patch) = parts.map { it.toInt() } + + if (versionParts.size == 1) { + return SemanticVersion(major, minor, patch) + } + + val type = when (versionParts[1]) { + "dev" -> VersionType.DEVELOPMENT + else -> VersionType.RELEASE + } + + val buildNumber = if (versionParts.size == 3) { + versionParts[2].toInt() + } else { + 0 + } + + return SemanticVersion(major, minor, patch, type, buildNumber) + } + } + + override operator fun compareTo(other: SemanticVersion): Int { + if (major != other.major) { + return major - other.major + } + if (minor != other.minor) { + return minor - other.minor + } + if (patch != other.patch) { + return patch - other.patch + } + + if (type != other.type) { + return when (type) { + VersionType.RELEASE -> 1 + VersionType.DEVELOPMENT -> -1 + } + } + + return buildNumber - other.buildNumber + } + + override fun toString(): String { + if (type == VersionType.RELEASE) { + return "$major.$minor.$patch" + } + + return "$major.$minor.$patch-${type.suffix}-$buildNumber" + } +} + +enum class VersionType(val suffix: String) { + RELEASE(""), + DEVELOPMENT("dev"), +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/packetevents/PlayerPackets.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/packetevents/PlayerPackets.kt similarity index 98% rename from plugin/src/main/kotlin/me/gabber235/typewriter/extensions/packetevents/PlayerPackets.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/packetevents/PlayerPackets.kt index e88fccee3e..f1c4185ebb 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/packetevents/PlayerPackets.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/packetevents/PlayerPackets.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.extensions.packetevents +package com.typewritermc.engine.paper.extensions.packetevents import com.github.retrooper.packetevents.PacketEvents import com.github.retrooper.packetevents.util.Vector3d diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/placeholderapi/PlaceholderExpansion.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/placeholderapi/PlaceholderExpansion.kt similarity index 82% rename from plugin/src/main/kotlin/me/gabber235/typewriter/extensions/placeholderapi/PlaceholderExpansion.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/placeholderapi/PlaceholderExpansion.kt index db16d9094e..335b158acc 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/placeholderapi/PlaceholderExpansion.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/extensions/placeholderapi/PlaceholderExpansion.kt @@ -1,15 +1,13 @@ -package me.gabber235.typewriter.extensions.placeholderapi +package com.typewritermc.engine.paper.extensions.placeholderapi +import com.typewritermc.core.entries.Query +import com.typewritermc.engine.paper.entry.PlaceholderEntry import lirand.api.extensions.server.server import me.clip.placeholderapi.PlaceholderAPI import me.clip.placeholderapi.expansion.PlaceholderExpansion -import me.gabber235.typewriter.entry.PlaceholderEntry -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.entry.entries.trackedShowingObjectives -import me.gabber235.typewriter.entry.quest.trackedQuest -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.snippets.snippet +import com.typewritermc.engine.paper.entry.entries.trackedShowingObjectives +import com.typewritermc.engine.paper.entry.quest.trackedQuest +import com.typewritermc.engine.paper.snippets.snippet import org.bukkit.OfflinePlayer import org.bukkit.entity.Player import org.bukkit.plugin.Plugin diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/Fact.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/Fact.kt similarity index 65% rename from plugin/src/main/kotlin/me/gabber235/typewriter/facts/Fact.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/Fact.kt index cf6284fe31..1a2329f054 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/Fact.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/Fact.kt @@ -1,6 +1,6 @@ -package me.gabber235.typewriter.facts +package com.typewritermc.engine.paper.facts -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.engine.paper.entry.entries.GroupId import java.time.LocalDateTime data class FactData(val value: Int, val lastUpdate: LocalDateTime = LocalDateTime.now()) diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/FactDatabase.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/FactDatabase.kt similarity index 84% rename from plugin/src/main/kotlin/me/gabber235/typewriter/facts/FactDatabase.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/FactDatabase.kt index 05bf10c3b0..2fbd4bc1ad 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/FactDatabase.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/FactDatabase.kt @@ -1,15 +1,21 @@ -package me.gabber235.typewriter.facts - +package com.typewritermc.engine.paper.facts + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.ModifierOperator +import com.typewritermc.engine.paper.entry.RefreshFactTrigger +import com.typewritermc.engine.paper.entry.entries.ExpirableFactEntry +import com.typewritermc.engine.paper.entry.entries.PersistableFactEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.entry.entries.WritableFactEntry +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.utils.logErrorIfNull import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ExpirableFactEntry -import me.gabber235.typewriter.entry.entries.PersistableFactEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.entry.entries.WritableFactEntry -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC -import me.gabber235.typewriter.utils.logErrorIfNull import org.bukkit.entity.Player import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/FactStorage.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/FactStorage.kt similarity index 93% rename from plugin/src/main/kotlin/me/gabber235/typewriter/facts/FactStorage.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/FactStorage.kt index 99743c6179..2c59b1e695 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/FactStorage.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/FactStorage.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.facts +package com.typewritermc.engine.paper.facts /** diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/storage/FileFactStorage.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/storage/FileFactStorage.kt similarity index 91% rename from plugin/src/main/kotlin/me/gabber235/typewriter/facts/storage/FileFactStorage.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/storage/FileFactStorage.kt index 52de65da81..c58e580092 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/facts/storage/FileFactStorage.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/facts/storage/FileFactStorage.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.facts.storage +package com.typewritermc.engine.paper.facts.storage import com.google.gson.* import com.google.gson.reflect.TypeToken @@ -7,13 +7,13 @@ import com.google.gson.stream.JsonWriter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext -import me.gabber235.typewriter.entry.entries.GroupId -import me.gabber235.typewriter.facts.FactData -import me.gabber235.typewriter.facts.FactId -import me.gabber235.typewriter.facts.FactStorage -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.get +import com.typewritermc.engine.paper.entry.entries.GroupId +import com.typewritermc.engine.paper.facts.FactData +import com.typewritermc.engine.paper.facts.FactId +import com.typewritermc.engine.paper.facts.FactStorage +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.get import org.koin.core.component.KoinComponent import java.lang.reflect.Type import java.time.LocalDateTime diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/ActionBarBlocker.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/ActionBarBlocker.kt similarity index 97% rename from plugin/src/main/kotlin/me/gabber235/typewriter/interaction/ActionBarBlocker.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/ActionBarBlocker.kt index 34203d8b45..7af2d40472 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/ActionBarBlocker.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/ActionBarBlocker.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.interaction +package com.typewritermc.engine.paper.interaction import com.github.retrooper.packetevents.PacketEvents import com.github.retrooper.packetevents.event.PacketListenerAbstract @@ -9,7 +9,7 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAc import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage import com.github.shynixn.mccoroutine.bukkit.registerSuspendingEvents import lirand.api.extensions.server.server -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.plugin import net.kyori.adventure.text.Component import org.bukkit.entity.Player import org.bukkit.event.EventHandler diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/ChatHistoryHandler.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/ChatHistoryHandler.kt similarity index 96% rename from plugin/src/main/kotlin/me/gabber235/typewriter/interaction/ChatHistoryHandler.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/ChatHistoryHandler.kt index 8259124529..b82cb35636 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/ChatHistoryHandler.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/ChatHistoryHandler.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.interaction +package com.typewritermc.engine.paper.interaction import com.github.retrooper.packetevents.PacketEvents import com.github.retrooper.packetevents.event.PacketListenerAbstract @@ -8,9 +8,9 @@ import com.github.retrooper.packetevents.protocol.packettype.PacketType import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage import com.github.shynixn.mccoroutine.bukkit.registerSuspendingEvents import lirand.api.extensions.server.server -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.plainText +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.plainText import net.kyori.adventure.text.Component import net.kyori.adventure.text.TextComponent import net.kyori.adventure.text.format.TextColor diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/Interaction.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/Interaction.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/interaction/Interaction.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/Interaction.kt index cb61a19e83..5c7dd60341 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/Interaction.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/Interaction.kt @@ -1,19 +1,24 @@ -package me.gabber235.typewriter.interaction - +package com.typewritermc.engine.paper.interaction + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.priority +import com.typewritermc.engine.paper.content.ContentEditor +import com.typewritermc.engine.paper.entry.FactWatcher +import com.typewritermc.engine.paper.entry.RefreshFactTrigger +import com.typewritermc.engine.paper.entry.cinematic.CinematicSequence +import com.typewritermc.engine.paper.entry.dialogue.DialogueSequence +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.* +import com.typewritermc.engine.paper.entry.matches +import com.typewritermc.engine.paper.entry.quest.QuestTracker +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import me.gabber235.typewriter.content.ContentEditor -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.cinematic.CinematicSequence -import me.gabber235.typewriter.entry.dialogue.DialogueSequence -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.entries.SystemTrigger.* -import me.gabber235.typewriter.entry.quest.QuestTracker -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC import org.bukkit.entity.Player import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/InteractionHandler.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt similarity index 81% rename from plugin/src/main/kotlin/me/gabber235/typewriter/interaction/InteractionHandler.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt index 2d89a7fd46..a4b50b1c2d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/InteractionHandler.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt @@ -1,19 +1,19 @@ -package me.gabber235.typewriter.interaction - +package com.typewritermc.engine.paper.interaction + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.utils.Reloadable +import com.typewritermc.engine.paper.entry.entries.CustomCommandEntry +import com.typewritermc.engine.paper.entry.entries.Event +import com.typewritermc.engine.paper.entry.entries.EventTrigger +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.DIALOGUE_END +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import kotlinx.coroutines.runBlocking import lirand.api.extensions.server.registerSuspendingEvents import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.entry.entries.CustomCommandEntry -import me.gabber235.typewriter.entry.entries.Event -import me.gabber235.typewriter.entry.entries.EventTrigger -import me.gabber235.typewriter.entry.entries.SystemTrigger.DIALOGUE_END -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.events.PublishedBookEvent -import me.gabber235.typewriter.events.TypewriterReloadEvent -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -26,6 +26,7 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap internal const val TICK_MS = 50L +// This is the most magic value I have ever seen. internal const val AVERAGE_SCHEDULING_DELAY_MS = 5L class InteractionHandler : Listener, KoinComponent { @@ -115,27 +116,18 @@ class InteractionHandler : Listener, KoinComponent { } } - // When the plugin reloads, we need to end all interactions and create new ones. - @EventHandler(priority = EventPriority.LOWEST) - suspend fun onReloadTypewriter(event: TypewriterReloadEvent) { - resetAllInteractions() - } - - // When a book is published, we need to end all interactions. - @EventHandler(priority = EventPriority.LOWEST) - suspend fun onPublishBook(event: PublishedBookEvent) { - resetAllInteractions() + fun load() { + interactions.putAll(server.onlinePlayers.map { it.uniqueId to Interaction(it) }) + interactions.forEach { (_, interaction) -> + interaction.setup() + } } - private suspend fun resetAllInteractions() { + suspend fun unload() { interactions.forEach { (_, interaction) -> interaction.end() } interactions.clear() - interactions.putAll(server.onlinePlayers.map { it.uniqueId to Interaction(it) }) - interactions.forEach { (_, interaction) -> - interaction.setup() - } } // When a player tries to execute a command, we need to end the dialogue. diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/PacketInterceptor.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/PacketInterceptor.kt similarity index 92% rename from plugin/src/main/kotlin/me/gabber235/typewriter/interaction/PacketInterceptor.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/PacketInterceptor.kt index 921d1ec05c..10df4fb75b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/interaction/PacketInterceptor.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/PacketInterceptor.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.interaction +package com.typewritermc.engine.paper.interaction import com.github.retrooper.packetevents.PacketEvents import com.github.retrooper.packetevents.event.PacketListenerAbstract @@ -22,7 +22,7 @@ class PacketInterceptor : PacketListenerAbstract() { override fun onPacketReceive(event: PacketReceiveEvent?) { if (event == null) return - val player = event.player + val player = event.getPlayer() if (player !is Player) return val interceptor = blockers[player.uniqueId] ?: return interceptor.trigger(event) @@ -30,7 +30,7 @@ class PacketInterceptor : PacketListenerAbstract() { override fun onPacketSend(event: PacketSendEvent?) { if (event == null) return - val player = event.player + val player = event.getPlayer() if (player !is Player) return val interceptor = blockers[player.uniqueId] ?: return interceptor.trigger(event) @@ -75,7 +75,7 @@ private data class PlayerPacketInterceptor( return interceptions.isEmpty() } - fun trigger(event: ProtocolPacketEvent) { + fun trigger(event: ProtocolPacketEvent) { interceptions.values .asSequence() .filter { it.type == event.packetType } @@ -89,13 +89,13 @@ data class PacketInterceptionSubscription( interface PacketInterception { val type: PacketTypeCommon - fun onIntercept(event: ProtocolPacketEvent) + fun onIntercept(event: ProtocolPacketEvent) } class PacketBlocker( override val type: PacketTypeCommon, ) : PacketInterception { - override fun onIntercept(event: ProtocolPacketEvent) { + override fun onIntercept(event: ProtocolPacketEvent) { event.isCancelled = true } } @@ -104,7 +104,7 @@ class CustomPacketReceiveInterception( override val type: PacketTypeCommon, private val intercept: (PacketReceiveEvent) -> Unit ) : PacketInterception { - override fun onIntercept(event: ProtocolPacketEvent) { + override fun onIntercept(event: ProtocolPacketEvent) { if (event !is PacketReceiveEvent) return intercept(event) } @@ -114,7 +114,7 @@ class CustomPacketSendInterception( override val type: PacketTypeCommon, private val intercept: (PacketSendEvent) -> Unit ) : PacketInterception { - override fun onIntercept(event: ProtocolPacketEvent) { + override fun onIntercept(event: ProtocolPacketEvent) { if (event !is PacketSendEvent) return intercept(event) } diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/DataSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/DataSerializer.kt new file mode 100644 index 0000000000..4fad25a75c --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/DataSerializer.kt @@ -0,0 +1,22 @@ +package com.typewritermc.engine.paper.loader + +import com.typewritermc.engine.paper.loader.serializers.* +import com.typewritermc.loader.DataSerializer +import org.koin.core.module.Module +import org.koin.core.qualifier.named + + +fun Module.dataSerializers() { + single>(named("color")) { ColorSerializer() } + single>(named("cronExpression")) { CronExpressionSerializer() } + single>(named("duration")) { DurationSerializer() } + single>(named("entryReference")) { EntryReferenceSerializer() } + single>(named("floatRange")) { FloatRangeSerializer() } + single>(named("optional")) { OptionalSerializer() } + single>(named("potionEffectType")) { PotionEffectTypeSerializer() } + single>(named("skinProperty")) { SkinPropertySerializer() } + single>(named("soundId")) { SoundIdSerializer() } + single>(named("soundSource")) { SoundSourceSerializer() } + single>(named("vector")) { VectorSerializer() } + single>(named("world")) { WorldSerializer() } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/PaperDependencyChecker.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/PaperDependencyChecker.kt new file mode 100644 index 0000000000..584b5c1a83 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/PaperDependencyChecker.kt @@ -0,0 +1,8 @@ +package com.typewritermc.engine.paper.loader + +import com.typewritermc.loader.DependencyChecker +import lirand.api.extensions.server.server + +class PaperDependencyChecker : DependencyChecker { + override fun hasDependency(dependency: String): Boolean = server.pluginManager.isPluginEnabled(dependency) +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/ColorSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/ColorSerializer.kt new file mode 100644 index 0000000000..f8ee54deb7 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/ColorSerializer.kt @@ -0,0 +1,21 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.typewritermc.engine.paper.utils.Color +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type + +class ColorSerializer : DataSerializer { + override val type: Type = Color::class.java + + override fun serialize(src: Color?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + return JsonPrimitive(src?.color ?: 0) + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Color { + return Color(json?.asInt ?: 0) + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/CronExpressionSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/CronExpressionSerializer.kt new file mode 100644 index 0000000000..06a7715e40 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/CronExpressionSerializer.kt @@ -0,0 +1,25 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.typewritermc.engine.paper.utils.CronExpression +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type + +class CronExpressionSerializer : DataSerializer { + override val type: Type = CronExpression::class.java + + override fun serialize(src: CronExpression?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + return JsonPrimitive(src?.expression ?: CronExpression.default().expression) + } + + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext? + ): CronExpression { + return CronExpression.createDynamic(json?.asString ?: CronExpression.default().expression) + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/DurationSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/DurationSerializer.kt new file mode 100644 index 0000000000..22e4e88a96 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/DurationSerializer.kt @@ -0,0 +1,25 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type +import java.time.Duration + +class DurationSerializer : DataSerializer { + override val type: Type = Duration::class.java + + override fun serialize(src: Duration?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + return JsonPrimitive(src?.toMillis() ?: 0) + } + + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext? + ): Duration { + return Duration.ofMillis(json?.asLong ?: 0) + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/EntryReferenceSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/EntryReferenceSerializer.kt new file mode 100644 index 0000000000..3690d5d02d --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/EntryReferenceSerializer.kt @@ -0,0 +1,38 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.common.reflect.TypeToken +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type +import kotlin.reflect.KClass + +class EntryReferenceSerializer : DataSerializer> { + override val type: Type = Ref::class.java + + override fun serialize(src: Ref<*>?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + return JsonPrimitive(src?.id ?: "") + } + + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext? + ): Ref<*> { + val subType = (typeOfT as ParameterizedType).actualTypeArguments[0] + val clazz = TypeToken.of(subType).rawType + val klass = clazz.kotlin as KClass + + if (json?.isJsonNull == true) { + return Ref("", klass) + } + + val id = json?.asString ?: "" + return Ref(id, klass) + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/FloatRangeSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/FloatRangeSerializer.kt new file mode 100644 index 0000000000..a707cf0b87 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/FloatRangeSerializer.kt @@ -0,0 +1,35 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonSerializationContext +import com.google.gson.reflect.TypeToken +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type + +class FloatRangeSerializer : DataSerializer> { + override val type: Type = object : TypeToken>() {}.type + + override fun serialize( + src: ClosedFloatingPointRange?, + typeOfSrc: Type?, + context: JsonSerializationContext? + ): JsonElement { + val obj = JsonObject() + obj.addProperty("start", src?.start ?: 0f) + obj.addProperty("end", src?.endInclusive ?: 0f) + return obj + } + + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext? + ): ClosedFloatingPointRange { + val obj = json?.asJsonObject ?: JsonObject() + val start = obj.get("start")?.asFloat ?: 0f + val end = obj.get("end")?.asFloat ?: 0f + return start..end + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/OptionalSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/OptionalSerializer.kt new file mode 100644 index 0000000000..fa1932c804 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/OptionalSerializer.kt @@ -0,0 +1,39 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonSerializationContext +import com.google.gson.reflect.TypeToken +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type +import java.util.* + +class OptionalSerializer : DataSerializer> { + override val type: Type = Optional::class.java + + override fun serialize(src: Optional<*>?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + val obj = JsonObject() + obj.addProperty("enabled", src?.isPresent ?: false) + + if (src?.isPresent == true) { + val value = src.get() + val valueElement = context?.serialize(value) + obj.add("value", valueElement) + } + + return obj + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Optional<*> { + val obj = json?.asJsonObject ?: JsonObject() + val enabled = obj.get("enabled")?.asBoolean ?: false + if (!enabled) return Optional.empty() + + val valueElement = obj.get("value") + val actualType = (typeOfT as? ParameterizedType)?.actualTypeArguments?.get(0) + val value: Any? = context?.deserialize(valueElement, actualType) + return Optional.ofNullable(value) + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/PotionEffectTypeSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/PotionEffectTypeSerializer.kt new file mode 100644 index 0000000000..263101edd8 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/PotionEffectTypeSerializer.kt @@ -0,0 +1,25 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.typewritermc.loader.DataSerializer +import org.bukkit.potion.PotionEffectType +import java.lang.reflect.Type + +class PotionEffectTypeSerializer : DataSerializer { + override val type: Type = PotionEffectType::class.java + + override fun serialize(src: PotionEffectType?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + return JsonPrimitive(src?.name ?: "speed") + } + + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext? + ): PotionEffectType { + return PotionEffectType.getByName(json?.asString ?: "speed") ?: PotionEffectType.SPEED + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SkinPropertySerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SkinPropertySerializer.kt new file mode 100644 index 0000000000..e77a9909ad --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SkinPropertySerializer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonSerializationContext +import com.typewritermc.engine.paper.entry.entity.SkinProperty +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type + +class SkinPropertySerializer : DataSerializer { + override val type: Type = SkinProperty::class.java + + override fun serialize(src: SkinProperty?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + val obj = JsonObject() + obj.addProperty("texture", src?.texture ?: "") + obj.addProperty("signature", src?.signature ?: "") + return obj + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): SkinProperty { + val obj = json?.asJsonObject ?: JsonObject() + return if (obj.has("texture") && obj.has("signature")) { + SkinProperty(obj.get("texture").asString, obj.get("signature").asString) + } else { + SkinProperty() + } + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundIdSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundIdSerializer.kt new file mode 100644 index 0000000000..32e46c5412 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundIdSerializer.kt @@ -0,0 +1,48 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonSerializationContext +import com.typewritermc.engine.paper.utils.DefaultSoundId +import com.typewritermc.engine.paper.utils.EntrySoundId +import com.typewritermc.engine.paper.utils.SoundId +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type + +class SoundIdSerializer : DataSerializer { + override val type: Type = SoundId::class.java + + override fun serialize(src: SoundId?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + val obj = JsonObject() + when (src) { + is DefaultSoundId -> { + obj.addProperty("type", "default") + obj.addProperty("value", src.namespacedKey.toString()) + } + + is EntrySoundId -> { + obj.addProperty("type", "entry") + obj.addProperty("value", src.entryId) + } + + null -> { + obj.addProperty("type", "default") + obj.addProperty("value", "") + } + } + return obj + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): SoundId { + val obj = json?.asJsonObject ?: JsonObject() + val type = obj.get("type")?.asString ?: "default" + val value = obj.get("value")?.asString ?: "" + + return when (type) { + "default" -> DefaultSoundId(value) + "entry" -> EntrySoundId(value) + else -> throw IllegalArgumentException("Invalid sound id type: $type") + } + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundSourceSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundSourceSerializer.kt new file mode 100644 index 0000000000..a9c1f1a10e --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/SoundSourceSerializer.kt @@ -0,0 +1,59 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.* +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.utils.EmitterSoundSource +import com.typewritermc.engine.paper.utils.LocationSoundSource +import com.typewritermc.engine.paper.utils.SelfSoundSource +import com.typewritermc.engine.paper.utils.SoundSource +import com.typewritermc.loader.DataSerializer +import java.lang.reflect.Type + +class SoundSourceSerializer : DataSerializer { + override val type: Type = SoundSource::class.java + + override fun serialize(src: SoundSource?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + val obj = JsonObject() + when (src) { + is SelfSoundSource -> { + obj.addProperty("type", "self") + } + + is EmitterSoundSource -> { + obj.addProperty("type", "emitter") + obj.addProperty("entryId", src.entryId) + } + + is LocationSoundSource -> { + obj.addProperty("type", "location") + obj.add("location", context?.serialize(src.position)) + } + + null -> { + obj.addProperty("type", "self") + } + } + return obj + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): SoundSource { + val obj = json?.asJsonObject ?: JsonObject() + val type = obj.get("type")?.asString ?: "self" + + return when (type) { + "self" -> SelfSoundSource + "emitter" -> { + val value = obj.get("entryId")?.asString ?: "" + EmitterSoundSource(value) + } + + "location" -> { + val position: Position = context?.deserialize(obj.get("location"), Position::class.java) + ?: throw JsonParseException("Invalid location for LocationSoundSource") + LocationSoundSource(position) + } + + else -> throw JsonParseException("Invalid sound source type: $type") + } + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/VectorSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/VectorSerializer.kt new file mode 100644 index 0000000000..b59af3f81d --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/VectorSerializer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonSerializationContext +import com.typewritermc.loader.DataSerializer +import org.bukkit.util.Vector +import java.lang.reflect.Type + +class VectorSerializer : DataSerializer { + override val type: Type = Vector::class.java + + override fun serialize(src: Vector?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + val obj = JsonObject() + obj.addProperty("x", src?.x ?: 0.0) + obj.addProperty("y", src?.y ?: 0.0) + obj.addProperty("z", src?.z ?: 0.0) + return obj + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Vector { + val obj = json?.asJsonObject ?: JsonObject() + val x = obj.getAsJsonPrimitive("x")?.asDouble ?: 0.0 + val y = obj.getAsJsonPrimitive("y")?.asDouble ?: 0.0 + val z = obj.getAsJsonPrimitive("z")?.asDouble ?: 0.0 + return Vector(x, y, z) + } +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/WorldSerializer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/WorldSerializer.kt new file mode 100644 index 0000000000..607b8ea8ce --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/loader/serializers/WorldSerializer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.engine.paper.loader.serializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import com.typewritermc.core.utils.point.World +import com.typewritermc.loader.DataSerializer +import lirand.api.extensions.server.server +import java.lang.reflect.Type + +class WorldSerializer : DataSerializer { + override val type: Type = World::class.java + + override fun serialize(src: World?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { + return JsonPrimitive(src?.identifier ?: "") + } + + override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): World { + val world = json?.asString ?: "" + + val bukkitWorld = server.getWorld(world) + ?: server.worlds.firstOrNull { it.name.equals(world, true) } + ?: server.worlds.firstOrNull() + ?: throw IllegalArgumentException("Could not find world '$world' for location, and no default world available.") + + return World(bukkitWorld.uid.toString()) + } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/snippets/Snippet.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/snippets/Snippet.kt similarity index 95% rename from plugin/src/main/kotlin/me/gabber235/typewriter/snippets/Snippet.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/snippets/Snippet.kt index 3cbe121813..0af0d2cda0 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/snippets/Snippet.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/snippets/Snippet.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.snippets +package com.typewritermc.engine.paper.snippets import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/snippets/SnippetDatabase.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/snippets/SnippetDatabase.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/snippets/SnippetDatabase.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/snippets/SnippetDatabase.kt index 7aa1d3d20a..9b47088ac3 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/snippets/SnippetDatabase.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/snippets/SnippetDatabase.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.snippets +package com.typewritermc.engine.paper.snippets -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.get -import me.gabber235.typewriter.utils.reloadable +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.get +import com.typewritermc.engine.paper.utils.reloadable import org.bukkit.configuration.file.YamlConfiguration import org.koin.core.component.KoinComponent import kotlin.reflect.KClass diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/ClientSynchronizer.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/ClientSynchronizer.kt similarity index 88% rename from plugin/src/main/kotlin/me/gabber235/typewriter/ui/ClientSynchronizer.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/ClientSynchronizer.kt index a44c8a0246..f48ffa66c8 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/ClientSynchronizer.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/ClientSynchronizer.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.ui +package com.typewritermc.engine.paper.ui import com.corundumstudio.socketio.AckRequest import com.corundumstudio.socketio.SocketIOClient @@ -8,27 +8,25 @@ import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.annotations.SerializedName import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.AdapterLoader -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.entry.StagingManager -import me.gabber235.typewriter.entry.entries.ContentModeTrigger -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.content.ContentContext +import com.typewritermc.engine.paper.content.ContentMode +import com.typewritermc.engine.paper.entry.StagingManager +import com.typewritermc.engine.paper.entry.entries.ContentModeTrigger +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.loader.ExtensionLoader import org.bukkit.entity.Player import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koin.core.qualifier.named -import kotlin.reflect.KClass class ClientSynchronizer : KoinComponent { private val stagingManager: StagingManager by inject() private val communicationHandler: CommunicationHandler by inject() private val writers: Writers by inject() - private val adapterLoader: AdapterLoader by inject() - private val adapters by adapterLoader::adaptersJson + private val extensionLoader: ExtensionLoader by inject() + private val extensionJson by extensionLoader::extensionJson private val gson: Gson by inject(named("bukkitDataParser")) fun handleFetchRequest(client: SocketIOClient, data: String, ack: AckRequest) { @@ -38,8 +36,8 @@ class ClientSynchronizer : KoinComponent { array.add(page) } ack.sendAckData(array.toString()) - } else if (data == "adapters") { - ack.sendAckData(adapters.toString()) + } else if (data == "extensions") { + ack.sendAckData(extensionJson.toString()) } ack.sendAckData("No data found") @@ -72,16 +70,16 @@ class ClientSynchronizer : KoinComponent { } } - fun handleDeletePage(client: SocketIOClient, name: String, ack: AckRequest) { - val result = stagingManager.deletePage(name) + fun handleDeletePage(client: SocketIOClient, pageId: String, ack: AckRequest) { + val result = stagingManager.deletePage(pageId) ack.sendResult(result) { - communicationHandler.server?.broadcastOperations?.sendEvent("deletePage", client, name) + communicationHandler.server?.broadcastOperations?.sendEvent("deletePage", client, pageId) } } fun handleMoveEntry(client: SocketIOClient, data: String, ack: AckRequest) { - val (entryId, fromPage, toPage) = gson.fromJson(data, MoveEntry::class.java) - val result = stagingManager.moveEntry(entryId, fromPage, toPage) + val (entryId, fromPageId, toPageId) = gson.fromJson(data, MoveEntry::class.java) + val result = stagingManager.moveEntry(entryId, fromPageId, toPageId) ack.sendResult(result) { communicationHandler.server?.broadcastOperations?.sendEvent("moveEntry", client, data) } @@ -178,7 +176,7 @@ class ClientSynchronizer : KoinComponent { val context = ContentContext(request.data) try { - val clazz = Class.forName(request.contentModeClassName, true, adapterLoader.loader) + val clazz = extensionLoader.loadClass(request.contentModeClassName) // Find the constructor with a context and player parameter val constructor = clazz.getConstructor(ContentContext::class.java, Player::class.java) val mode = constructor.newInstance(context, player) @@ -235,8 +233,8 @@ private data class PageValueUpdate( private data class MoveEntry( val entryId: String, - val fromPage: String, - val toPage: String, + val fromPageId: String, + val toPageId: String, ) diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/CommunicationHandler.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/CommunicationHandler.kt similarity index 95% rename from plugin/src/main/kotlin/me/gabber235/typewriter/ui/CommunicationHandler.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/CommunicationHandler.kt index 35bed93c24..6806f409b0 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/CommunicationHandler.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/CommunicationHandler.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.ui +package com.typewritermc.engine.paper.ui import com.corundumstudio.socketio.Configuration import com.corundumstudio.socketio.HandshakeData @@ -6,12 +6,12 @@ import com.corundumstudio.socketio.SocketIOClient import com.corundumstudio.socketio.SocketIOServer import lirand.api.extensions.events.listen import lirand.api.extensions.server.server -import me.gabber235.typewriter.entry.StagingManager -import me.gabber235.typewriter.events.StagingChangeEvent -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.config -import me.gabber235.typewriter.utils.logErrorIfNull +import com.typewritermc.engine.paper.entry.StagingManager +import com.typewritermc.engine.paper.events.StagingChangeEvent +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.config +import com.typewritermc.engine.paper.utils.logErrorIfNull import org.bukkit.entity.Player import org.koin.core.component.KoinComponent import org.koin.core.component.inject diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/PanelHost.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/PanelHost.kt similarity index 92% rename from plugin/src/main/kotlin/me/gabber235/typewriter/ui/PanelHost.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/PanelHost.kt index 3c3676d403..41e03d3a7b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/PanelHost.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/PanelHost.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.ui +package com.typewritermc.engine.paper.ui import io.ktor.server.application.* @@ -6,8 +6,8 @@ import io.ktor.server.engine.* import io.ktor.server.http.content.* import io.ktor.server.response.* import io.ktor.server.routing.* -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.utils.config +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.utils.config import org.koin.core.component.KoinComponent import java.io.File diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/Writers.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/Writers.kt similarity index 98% rename from plugin/src/main/kotlin/me/gabber235/typewriter/ui/Writers.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/Writers.kt index a563142b72..a4b05cf8f4 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/ui/Writers.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/ui/Writers.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.ui +package com.typewritermc.engine.paper.ui import com.corundumstudio.socketio.SocketIOServer import com.google.gson.Gson diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/BlockPhysics.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/BlockPhysics.kt similarity index 98% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/BlockPhysics.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/BlockPhysics.kt index bd8cb86893..3a6a132b98 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/BlockPhysics.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/BlockPhysics.kt @@ -3,9 +3,12 @@ * * I have made some modifications to the original file to change the types. */ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils -import me.gabber235.typewriter.entry.entity.LocationProperty +import com.typewritermc.core.utils.point.Point +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.core.utils.point.toVector +import com.typewritermc.engine.paper.entry.entity.PositionProperty import org.bukkit.World import org.bukkit.block.Block import org.bukkit.util.BoundingBox @@ -17,6 +20,7 @@ import kotlin.math.sign object BlockCollision { private const val STEP_HEIGHT = 0.5 + /** * Moves an entity with physics applied (ie checking against blocks) * @@ -26,7 +30,7 @@ object BlockCollision { */ fun handlePhysics( boundingBox: BoundingBox, - velocity: Vector, entityPosition: LocationProperty, + velocity: Vector, entityPosition: PositionProperty, getter: BukkitBlockGetter, singleCollision: Boolean ): PhysicsResult { @@ -36,7 +40,7 @@ object BlockCollision { private fun stepPhysics( boundingBox: BoundingBox, - velocity: Vector, entityPosition: LocationProperty, + velocity: Vector, entityPosition: PositionProperty, getter: BukkitBlockGetter, singleCollision: Boolean ): PhysicsResult { // Allocate once and update values @@ -118,7 +122,7 @@ object BlockCollision { private fun computePhysics( boundingBox: BoundingBox, velocity: Vector, - entityPosition: LocationProperty, + entityPosition: PositionProperty, getter: BukkitBlockGetter, allFaces: Array, finalResult: SweepResult @@ -143,10 +147,11 @@ object BlockCollision { if (abs(deltaY) < Vector.EPSILON) deltaY = 0.0 if (abs(deltaZ) < Vector.EPSILON) deltaZ = 0.0 - var finalPos: LocationProperty = entityPosition.add(deltaX, deltaY, deltaZ) + var finalPos: PositionProperty = entityPosition.add(deltaX, deltaY, deltaZ) val hasHorizontalOnlyCollision = (collisionX || collisionZ) && !collisionY - var step = hasHorizontalOnlyCollision && finalResult.collidedHeightDiff > 0 && finalResult.collidedHeightDiff <= STEP_HEIGHT + var step = + hasHorizontalOnlyCollision && finalResult.collidedHeightDiff > 0 && finalResult.collidedHeightDiff <= STEP_HEIGHT // If the entity is colliding with x or z and the block is below step height, we move the entity up to the block if (step) { finalPos = finalPos.add(0.0, finalResult.collidedHeightDiff + Vector.EPSILON, 0.0) @@ -167,7 +172,7 @@ object BlockCollision { private fun slowPhysics( boundingBox: BoundingBox, velocity: Vector, - entityPosition: LocationProperty, + entityPosition: PositionProperty, getter: BukkitBlockGetter, allFaces: Array, finalResult: SweepResult @@ -203,7 +208,7 @@ object BlockCollision { private fun fastPhysics( boundingBox: BoundingBox, velocity: Vector, - entityPosition: LocationProperty, + entityPosition: PositionProperty, getter: BukkitBlockGetter, allFaces: Array, finalResult: SweepResult @@ -454,7 +459,7 @@ object BlockCollision { */ fun checkBoundingBox( blockX: Int, blockY: Int, blockZ: Int, - entityVelocity: Vector, entityPosition: LocationProperty, boundingBox: BoundingBox, + entityVelocity: Vector, entityPosition: PositionProperty, boundingBox: BoundingBox, getter: BukkitBlockGetter, finalResult: SweepResult, ): Boolean { val currentBlock: Block = getter.getBlock(blockX, blockY, blockZ) @@ -521,7 +526,7 @@ object BlockCollision { private fun shouldCheckLower( entityVelocity: Vector, - entityPosition: LocationProperty, + entityPosition: PositionProperty, blockX: Int, blockY: Int, blockZ: Int @@ -701,7 +706,7 @@ object BlockCollision { * @param collisionShapes the shapes the entity collided with */ data class PhysicsResult( - val newPosition: LocationProperty, + val newPosition: PositionProperty, val newVelocity: Vector, val isOnGround: Boolean, val collisionX: Boolean, diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/BukkitDataParser.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/BukkitDataParser.kt similarity index 95% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/BukkitDataParser.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/BukkitDataParser.kt index 40e42a80f1..33bdb2b060 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/BukkitDataParser.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/BukkitDataParser.kt @@ -1,7 +1,7 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import com.google.gson.* -import me.gabber235.typewriter.logger +import com.typewritermc.engine.paper.logger import org.bukkit.Bukkit import org.bukkit.Location import org.bukkit.Material diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Color.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Color.kt similarity index 92% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Color.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Color.kt index 40d3ede253..79b4ae0835 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Color.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Color.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils class Color( val color: Int, diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ComputedMap.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ComputedMap.kt similarity index 88% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/ComputedMap.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ComputedMap.kt index c3c1fdc90d..39ec3a1ba0 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ComputedMap.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ComputedMap.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils class ComputedMap( private val map: MutableMap = mutableMapOf(), diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Config.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Config.kt similarity index 89% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Config.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Config.kt index be1caa4748..0ecd73642d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Config.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Config.kt @@ -1,7 +1,7 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin import kotlin.reflect.KClass import kotlin.reflect.KProperty import kotlin.reflect.safeCast diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/CronExpression.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/CronExpression.kt similarity index 99% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/CronExpression.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/CronExpression.kt index 786d143dba..ff26f10920 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/CronExpression.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/CronExpression.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import java.time.* import java.util.* diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/DurationParser.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/DurationParser.kt similarity index 97% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/DurationParser.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/DurationParser.kt index 0d866eda02..66ee137ac7 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/DurationParser.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/DurationParser.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import java.util.* import java.util.regex.Pattern diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Extensions.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Extensions.kt similarity index 88% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Extensions.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Extensions.kt index 4189c748aa..8c951cbe40 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Extensions.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Extensions.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import com.destroystokyo.paper.profile.PlayerProfile import com.github.retrooper.packetevents.protocol.particle.Particle @@ -7,16 +7,17 @@ import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes import com.github.retrooper.packetevents.util.Vector3d import com.github.retrooper.packetevents.util.Vector3f import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle +import com.typewritermc.engine.paper.TypewriterPaperPlugin +import com.typewritermc.engine.paper.entry.roadnetwork.content.toPacketColor +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.logger import lirand.api.extensions.server.server -import me.gabber235.typewriter.Typewriter -import me.gabber235.typewriter.entry.roadnetwork.content.toPacketColor -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.logger import net.kyori.adventure.audience.Audience import net.kyori.adventure.key.Key import net.kyori.adventure.sound.Sound import net.kyori.adventure.text.Component import org.bukkit.Color +import org.bukkit.GameMode import org.bukkit.Location import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player @@ -28,7 +29,7 @@ import org.geysermc.floodgate.api.FloodgateApi import org.koin.java.KoinJavaComponent.get import java.io.File import java.net.MalformedURLException -import java.net.URL +import java.net.URI import java.time.Duration import java.util.* import kotlin.math.* @@ -38,10 +39,15 @@ operator fun File.get(name: String): File = File(this, name) val Player.isFloodgate: Boolean get() { - if (!get(Typewriter::class.java).isFloodgateInstalled) return false + if (!get(TypewriterPaperPlugin::class.java).isFloodgateInstalled) return false return FloodgateApi.getInstance().isFloodgatePlayer(this.uniqueId) } +/** + * Can an entity look at this player? + */ +val Player.isLookable: Boolean + get() = this.isValid && this.gameMode != GameMode.SPECTATOR && !this.isInvisible fun T?.logErrorIfNull(message: String): T? { if (this == null) logger.severe(message) @@ -156,9 +162,6 @@ fun Float.round(decimals: Int): Float { val Int.digits: Int get() = if (this == 0) 1 else log10(abs(this.toDouble())).toInt() + 1 -fun String.rightPad(length: Int, padChar: Char = ' '): String { - return if (this.length >= length) this else this + padChar.toString().repeat(length - this.length) -} val String.lineCount: Int get() = this.count { it == '\n' } + 1 @@ -189,7 +192,8 @@ private fun getProfile(url: String): PlayerProfile { val profile: PlayerProfile = server.createProfile(RANDOM_UUID) // Get a new player profile val textures: PlayerTextures = profile.textures textures.skin = try { - URL(url) // The URL to the skin, for example: https://textures.minecraft.net/texture/18813764b2abc94ec3c3bc67b9147c21be850cdf996679703157f4555997ea63a + // The URL to the skin, for example: https://textures.minecraft.net/texture/18813764b2abc94ec3c3bc67b9147c21be850cdf996679703157f4555997ea63a + URI(url).toURL() } catch (exception: MalformedURLException) { throw RuntimeException("Invalid URL", exception) } diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Interpolation.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Interpolation.kt similarity index 90% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Interpolation.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Interpolation.kt index ce4e66ebae..e11618d440 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Interpolation.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Interpolation.kt @@ -1,12 +1,11 @@ -package me.gabber235.typewriter.utils - -import org.bukkit.Location +package com.typewritermc.engine.paper.utils +import com.typewritermc.core.utils.point.Position /** * Use catmull-rom interpolation to get a point between a list of points. */ -fun List.interpolate(percentage: Double): Location { +fun List.interpolate(percentage: Double): Position { val currentPart = percentage * (size - 1) val index = currentPart.toInt() val subPercentage = currentPart - index @@ -23,12 +22,12 @@ fun List.interpolate(percentage: Double): Location { * Use catmull-rom interpolation to get a point between four points. */ fun interpolatePoints( - previousPoint: Location, - currentPoint: Location, - nextPoint: Location, - nextNextPoint: Location, + previousPoint: Position, + currentPoint: Position, + nextPoint: Position, + nextNextPoint: Position, percentage: Double, -): Location { +): Position { val x = interpolatePoints( previousPoint.x, currentPoint.x, @@ -71,7 +70,7 @@ fun interpolatePoints( percentage, ) - return Location( + return Position( currentPoint.world, x, y, diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Item.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Item.kt similarity index 69% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Item.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Item.kt index ab9745235b..aeb4c384b9 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Item.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Item.kt @@ -1,15 +1,11 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils -import lirand.api.extensions.inventory.meta -import lirand.api.nbt.NbtData -import lirand.api.nbt.tagNbtData -import me.gabber235.typewriter.adapters.modifiers.* -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.core.extension.annotations.* +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.inventory.ItemFlag import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.ItemMeta import java.util.* import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -17,30 +13,22 @@ import kotlin.contracts.contract open class Item( @MaterialProperties(MaterialProperty.ITEM) @Icon("fa6-solid:cube") - @Help("The material of the item.") private val material: Optional = Optional.empty(), @InnerMin(Min(0)) @Icon("fa6-solid:hashtag") - @Help("The amount of items.") val amount: Optional = Optional.empty(), @Placeholder @Colored @Icon("fa6-solid:tag") - @Help("The display name of the item.") private val name: Optional = Optional.empty(), @Placeholder @Colored @MultiLine @Icon("flowbite:file-lines-solid") - @Help("The lore of the item.") private val lore: Optional = Optional.empty(), // private val enchantments: Optional>, - @Icon("fa6-solid:flag") - @Help("Special flags for the item.") + @Icon("material-symbols:flag") private val flags: Optional> = Optional.empty(), - @Icon("mingcute:code-fill") - @Help("The serialized NBT data of the item.") - private val nbt: Optional = Optional.empty(), ) { companion object Empty : Item( @@ -50,25 +38,19 @@ open class Item( Optional.empty(), // Optional.empty(), Optional.empty(), - Optional.empty(), ) fun build(player: Player?): ItemStack { val material = material.orElse(Material.STONE) if (material == Material.AIR) return ItemStack.empty() val item = ItemStack(material, amount.orElse(1)) - // Nbt needs to be done first because it will not include the display name and lore. - // Otherwise, it will overwrite the display name and lore. - if (nbt.isPresent) { - item.tagNbtData = NbtData(nbt.get()) - } item - .meta { + .editMeta { meta -> if (this@Item.name.isPresent) { - displayName(this@Item.name.get().parsePlaceholders(player).asMini()) + meta.displayName(this@Item.name.get().parsePlaceholders(player).asMini()) } if (this@Item.lore.isPresent) { - lore(this@Item.lore.get().parsePlaceholders(player).split("\n").map { it.asMini() }) + meta.lore(this@Item.lore.get().parsePlaceholders(player).split("\n").map { it.asMini() }) } // if (enchantments.isPresent) { // enchantments.get().forEach { (enchantment, level) -> @@ -77,7 +59,7 @@ open class Item( // } if (flags.isPresent) { flags.get().forEach { flag -> - addItemFlags(flag) + meta.addItemFlags(flag) } } @@ -102,7 +84,6 @@ open class Item( } // if (enchantments.isPresent && item.itemMeta?.enchants != enchantments.get()) return false if (flags.isPresent && item.itemMeta?.itemFlags?.toList() != flags.get()) return false - if (nbt.isPresent && item.strippedTagNbtData.toString() != nbt.get()) return false return true } @@ -113,7 +94,6 @@ open class Item( lore: Optional? = null, // enchantments: Optional>? = null, flags: Optional>? = null, - nbt: Optional? = null, ): Item { return Item( material = material ?: this.material, @@ -122,13 +102,11 @@ open class Item( lore = lore ?: this.lore, // enchantments = enchantments ?: this.enchantments, flags = flags ?: this.flags, - nbt = nbt ?: this.nbt, ) } } fun ItemStack.toItem(): Item { - val nbt = strippedTagNbtData return Item( material = Optional.ofNullable(type), amount = Optional.ofNullable(amount), @@ -136,14 +114,5 @@ fun ItemStack.toItem(): Item { lore = Optional.ofNullable(itemMeta?.lore()?.joinToString("\n") { it.asMini() }), // enchantments = Optional.ofNullable(itemMeta?.enchants), flags = if (itemMeta?.itemFlags?.isNotEmpty() == true) Optional.ofNullable(itemMeta?.itemFlags?.toList()) else Optional.empty(), - nbt = if (nbt.keys.isNotEmpty()) Optional.ofNullable(nbt.toString()) else Optional.empty(), ) -} - -/// Returns the NBT data of the item without the display name and lore. -val ItemStack.strippedTagNbtData: NbtData - get() { - val nbt = tagNbtData - nbt -= "display" - return nbt - } \ No newline at end of file +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Memoized.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Memoized.kt similarity index 93% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Memoized.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Memoized.kt index 0fc9cb9ed2..4482bed3a2 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Memoized.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Memoized.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/MiniMessages.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/MiniMessages.kt similarity index 97% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/MiniMessages.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/MiniMessages.kt index 777e465d0b..d86482dc05 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/MiniMessages.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/MiniMessages.kt @@ -1,6 +1,6 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils -import me.gabber235.typewriter.entry.dialogue.confirmationKey +import com.typewritermc.engine.paper.entry.dialogue.confirmationKey import net.kyori.adventure.text.Component import net.kyori.adventure.text.TextComponent import net.kyori.adventure.text.TextReplacementConfig diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/PlayerState.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/PlayerState.kt similarity index 96% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/PlayerState.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/PlayerState.kt index f43355feb1..780fedb38d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/PlayerState.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/PlayerState.kt @@ -1,9 +1,9 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot import io.github.retrooper.packetevents.util.SpigotReflectionUtil -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.plugin import org.bukkit.GameMode import org.bukkit.Location import org.bukkit.entity.Player diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Point.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Point.kt new file mode 100644 index 0000000000..3d945da53e --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Point.kt @@ -0,0 +1,38 @@ +package com.typewritermc.engine.paper.utils + +import com.github.retrooper.packetevents.protocol.world.Location +import com.github.retrooper.packetevents.util.Vector3d +import com.github.retrooper.packetevents.util.Vector3f +import com.github.retrooper.packetevents.util.Vector3i +import com.typewritermc.core.utils.point.Point +import com.typewritermc.core.utils.point.Position +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.core.utils.point.World +import io.github.retrooper.packetevents.util.SpigotConversionUtil +import lirand.api.extensions.server.server +import org.bukkit.entity.Player +import java.util.* + +fun org.bukkit.util.Vector.toVector(): Vector { + return Vector(x, y, z) +} + +fun Point.toPacketVector3f() = Vector3f(x.toFloat(), y.toFloat(), z.toFloat()) +fun Point.toPacketVector3d() = Vector3d(x, y, z) +fun Point.toPacketVector3i() = Vector3i(blockX, blockY, blockZ) +fun Point.toBukkitVector(): org.bukkit.util.Vector = org.bukkit.util.Vector(x, y, z) + +fun World.toBukkitWorld(): org.bukkit.World = server.getWorld(UUID.fromString(identifier)) + ?: throw IllegalArgumentException("Could not find world '$identifier' for location, and no default world available.") + +fun Position.toBukkitLocation(): org.bukkit.Location = org.bukkit.Location(world.toBukkitWorld(), x, y, z, yaw, pitch) +fun Position.toPacketLocation(): Location = toBukkitLocation().toPacketLocation() + +fun org.bukkit.Location.toPosition(): Position = Position(World(world.uid.toString()), x, y, z, yaw, pitch) +fun org.bukkit.Location.toPacketLocation(): Location = SpigotConversionUtil.fromBukkitLocation(this) + +fun Location.toCoordinate(): com.typewritermc.core.utils.point.Coordinate = + com.typewritermc.core.utils.point.Coordinate(x, y, z, yaw, pitch) + +val Player.position: Position + get() = location.toPosition() \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Reloadable.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Reloadable.kt similarity index 76% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Reloadable.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Reloadable.kt index ecbb59da08..e967f6905d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Reloadable.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Reloadable.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils +import com.typewritermc.engine.paper.events.TypewriterUnloadEvent import lirand.api.extensions.events.listen -import me.gabber235.typewriter.events.TypewriterReloadEvent -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.plugin import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -11,7 +11,7 @@ class Reloadable(private val loader: () -> T) : ReadOnlyProperty { private var value: T? = null init { - plugin.listen { reload() } + plugin.listen { reload() } } fun get(): T { diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/RuntimeTypeAdapterFactory.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/RuntimeTypeAdapterFactory.kt similarity index 99% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/RuntimeTypeAdapterFactory.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/RuntimeTypeAdapterFactory.kt index 05be39257a..81e711473a 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/RuntimeTypeAdapterFactory.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/RuntimeTypeAdapterFactory.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import com.google.gson.* import com.google.gson.reflect.TypeToken diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ServerCommandMap.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ServerCommandMap.kt new file mode 100644 index 0000000000..ea9716921f --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ServerCommandMap.kt @@ -0,0 +1,33 @@ +package com.typewritermc.engine.paper.utils + +import com.typewritermc.core.entries.Query +import com.typewritermc.engine.paper.entry.entries.CustomCommandEntry +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import dev.jorel.commandapi.CommandAPI +import dev.jorel.commandapi.CommandTree + +fun CustomCommandEntry.Companion.registerAll() { + val entries = Query.find() + entries.forEach { it.register() } +} + +fun CustomCommandEntry.Companion.unregisterAll() { + val entries = Query.find() + entries.forEach { it.unregister() } +} + +fun CustomCommandEntry.register() { + if (command.isBlank()) { + logger.warning("Command for $name is blank. Skipping registration.") + return + } + CommandTree(command).apply { builder() }.register(plugin) + + logger.info("Registered command $command for $name (${id})") +} + +fun CustomCommandEntry.unregister() { + if (command.isBlank()) return + CommandAPI.unregister(command) +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Sound.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Sound.kt similarity index 85% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Sound.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Sound.kt index edd1bdb987..be3686e77d 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Sound.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Sound.kt @@ -1,13 +1,13 @@ -package me.gabber235.typewriter.utils - -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.entry.entries.SoundIdEntry -import me.gabber235.typewriter.entry.entries.SoundSourceEntry -import me.gabber235.typewriter.logger +package com.typewritermc.engine.paper.utils + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.SoundIdEntry +import com.typewritermc.engine.paper.entry.entries.SoundSourceEntry +import com.typewritermc.engine.paper.logger import net.kyori.adventure.audience.Audience import net.kyori.adventure.sound.SoundStop -import org.bukkit.Location import org.bukkit.NamespacedKey import net.kyori.adventure.sound.Sound as AdventureSound @@ -50,7 +50,7 @@ data class Sound( } is LocationSoundSource -> { - val location = soundSource.location + val location = soundSource.position audience.playSound(sound, location.x, location.y, location.z) } } @@ -89,4 +89,4 @@ sealed interface SoundSource data object SelfSoundSource : SoundSource class EmitterSoundSource(val entryId: String) : SoundSource -class LocationSoundSource(val location: Location) : SoundSource +class LocationSoundSource(val position: Position) : SoundSource diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ThreadType.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ThreadType.kt similarity index 94% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/ThreadType.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ThreadType.kt index b97c7e6177..95c1585c0f 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ThreadType.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/ThreadType.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import com.github.shynixn.mccoroutine.bukkit.asyncDispatcher import com.github.shynixn.mccoroutine.bukkit.launch @@ -8,7 +8,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import lirand.api.extensions.server.server -import me.gabber235.typewriter.plugin +import com.typewritermc.engine.paper.plugin enum class ThreadType { SYNC, diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Timeout.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Timeout.kt similarity index 78% rename from plugin/src/main/kotlin/me/gabber235/typewriter/utils/Timeout.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Timeout.kt index f7dda387e5..8846bed86b 100644 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/Timeout.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/utils/Timeout.kt @@ -1,8 +1,8 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.engine.paper.utils import kotlinx.coroutines.Job import kotlinx.coroutines.delay -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import org.koin.core.component.KoinComponent import kotlin.time.Duration @@ -23,6 +23,11 @@ class Timeout( } } + fun force() { + cancel() + invoker() + } + fun cancel() { job?.cancel() job = null diff --git a/plugin/src/main/kotlin/lirand/api/LirandAPI.kt b/engine/engine-paper/src/main/kotlin/lirand/api/LirandAPI.kt similarity index 75% rename from plugin/src/main/kotlin/lirand/api/LirandAPI.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/LirandAPI.kt index dc01260815..298f72996e 100644 --- a/plugin/src/main/kotlin/lirand/api/LirandAPI.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/LirandAPI.kt @@ -1,6 +1,5 @@ package lirand.api -import lirand.api.extensions.server.commands.CommandController import org.bukkit.plugin.Plugin class LirandAPI internal constructor(internal val plugin: Plugin) { @@ -16,11 +15,7 @@ class LirandAPI internal constructor(internal val plugin: Plugin) { } } - internal val commandController = CommandController(plugin) - init { _instances[plugin] = this - - commandController.initialize() } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt b/engine/engine-paper/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt similarity index 99% rename from plugin/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt index eedfbdb71e..b702bbf17f 100644 --- a/plugin/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/architecture/KotlinPlugin.kt @@ -4,7 +4,6 @@ import com.github.shynixn.mccoroutine.bukkit.SuspendingJavaPlugin import lirand.api.LirandAPI abstract class KotlinPlugin : SuspendingJavaPlugin() { - override fun onEnable() { try { LirandAPI.register(this) diff --git a/plugin/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt similarity index 99% rename from plugin/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt index 35974e1dc1..9e2b4368b9 100644 --- a/plugin/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/events/ListenerExtensions.kt @@ -12,12 +12,8 @@ data class ListenerWithPlugin(val listener: Listener, val plugin: Plugin) class SimpleListener : Listener - - fun Listener.unregister() = HandlerList.unregisterAll(this) - - inline fun Listener.listen( plugin: Plugin, priority: EventPriority = EventPriority.NORMAL, diff --git a/plugin/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt similarity index 51% rename from plugin/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt index ff4a7160f6..98b15e7207 100644 --- a/plugin/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/inventory/InventoryExtensions.kt @@ -1,7 +1,7 @@ package lirand.api.extensions.inventory import lirand.api.extensions.server.server -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.engine.paper.utils.asMini import org.bukkit.Material import org.bukkit.event.inventory.InventoryType import org.bukkit.inventory.Inventory @@ -30,46 +30,8 @@ fun Inventory( server.createInventory(owner, size) } - -val Inventory.hasSpace: Boolean - get() = contents.any { it == null || it.type == Material.AIR } - -fun Inventory.hasSpace( - itemStack: ItemStack, - amount: Int = itemStack.amount -): Boolean = getSpaceOf(itemStack) >= amount - -fun Inventory.getSpaceOf(itemStack: ItemStack): Int { - return contents.filterNotNull().map { - if (it.amount < it.maxStackSize && it.isSimilar(itemStack)) - it.maxStackSize - it.amount - else 0 - }.count() -} - - operator fun Inventory.get(slot: Int): ItemStack? = getItem(slot) operator fun Inventory.set(slot: Int, itemStack: ItemStack?) { setItem(slot, itemStack) -} - - -fun Inventory.clone( - cloneItemStacks: Boolean = true, - owner: InventoryHolder? = holder, - title: String? = null -): Inventory { - val inventory = if (type == InventoryType.CHEST) - Inventory(size, owner, title) - else - Inventory(type, owner, title) - - inventory.contents = if (cloneItemStacks) - contents.map { it?.clone() }.toTypedArray() - else - contents - - - return inventory } \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt new file mode 100644 index 0000000000..f72f8fdf87 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt @@ -0,0 +1,24 @@ +package lirand.api.extensions.math + +import org.bukkit.Axis +import org.bukkit.Location +import org.bukkit.World +import org.bukkit.util.Vector + +/* + * LOCATION + */ + +operator fun Location.component1() = x +operator fun Location.component2() = y +operator fun Location.component3() = z +operator fun Location.component4() = yaw +operator fun Location.component5() = pitch + +fun Location(world: World?, x: Number, y: Number, z: Number) = Location(world, x.toDouble(), y.toDouble(), z.toDouble()) + +// extensions +fun Location.add(x: Number = 0.0, y: Number = 0.0, z: Number = 0.0) = add(x.toDouble(), y.toDouble(), z.toDouble()) + + +val Location.blockLocation: Location get() = Location(world, blockX, blockY, blockZ) \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/math/Positions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/Positions.kt similarity index 83% rename from plugin/src/main/kotlin/lirand/api/extensions/math/Positions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/Positions.kt index 40c0d0d04a..17f3f636ed 100644 --- a/plugin/src/main/kotlin/lirand/api/extensions/math/Positions.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/Positions.kt @@ -8,18 +8,12 @@ import kotlin.math.sqrt fun Location.asPosition() = LocationPosition(x, y, z, yaw, pitch) -fun LocationPosition.asBlock(world: World) = world.getBlockAt(x.toInt(), y.toInt(), z.toInt()) -fun LocationPosition.asLocation(world: World? = null) = Location(world, x, y, z, yaw, pitch) -fun LocationPosition.asBlockPosition() = BlockPosition(x.toInt(), y.toInt(), z.toInt()) - fun Block.asPosition() = BlockPosition(x, y, z) fun Location.asBlockPosition() = BlockPosition(blockX, blockY, blockZ) fun BlockPosition.asBlock(world: World) = world.getBlockAt(x, y, z) fun BlockPosition.asLocation(world: World? = null) = Location(world, x.toDouble(), y.toDouble(), z.toDouble()) -fun BlockPosition.asLocationPosition() = LocationPosition(x.toDouble(), y.toDouble(), z.toDouble(), 0f, 0f) -fun BlockPosition.asChunkPosition() = ChunkPosition(x shr 4, z shr 4) fun Chunk.asPosition() = ChunkPosition(x, z) fun ChunkPosition.asBukkitChunk(world: World) = world.getChunkAt(x, z) diff --git a/plugin/src/main/kotlin/lirand/api/extensions/math/Ranges.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/Ranges.kt similarity index 100% rename from plugin/src/main/kotlin/lirand/api/extensions/math/Ranges.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/math/Ranges.kt diff --git a/plugin/src/main/kotlin/lirand/api/extensions/other/JsonExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/other/JsonExtensions.kt similarity index 100% rename from plugin/src/main/kotlin/lirand/api/extensions/other/JsonExtensions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/other/JsonExtensions.kt diff --git a/plugin/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt similarity index 51% rename from plugin/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt index 963c8c39ad..edb49ec9c4 100644 --- a/plugin/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/PermissionExtensions.kt @@ -2,9 +2,5 @@ package lirand.api.extensions.server import org.bukkit.permissions.Permissible -fun Permissible.anyPermission(vararg permissions: String): Boolean = permissions.any { hasPermission(it) } - -fun Permissible.allPermissions(vararg permissions: String): Boolean = permissions.all { hasPermission(it) } - fun Permissible.hasPermissionOrStar(permission: String): Boolean = hasPermission(permission) || hasPermission(permission.replaceAfterLast('.', "*")) \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt similarity index 72% rename from plugin/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt index f24d187138..9978372a25 100644 --- a/plugin/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/PluginExtensions.kt @@ -4,10 +4,6 @@ import com.github.shynixn.mccoroutine.bukkit.registerSuspendingEvents import org.bukkit.NamespacedKey import org.bukkit.event.Listener import org.bukkit.plugin.Plugin -import java.io.File -import java.net.URL -import java.net.URLDecoder -import java.util.jar.JarFile fun Plugin.registerEvents( vararg listeners: Listener @@ -15,7 +11,4 @@ fun Plugin.registerEvents( fun Plugin.registerSuspendingEvents( vararg listeners: Listener -) = listeners.forEach { server.pluginManager.registerSuspendingEvents(it, this) } - - -fun Plugin.getKey(name: String) = NamespacedKey(this, name) \ No newline at end of file +) = listeners.forEach { server.pluginManager.registerSuspendingEvents(it, this) } \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/server/ServerExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/ServerExtensions.kt similarity index 100% rename from plugin/src/main/kotlin/lirand/api/extensions/server/ServerExtensions.kt rename to engine/engine-paper/src/main/kotlin/lirand/api/extensions/server/ServerExtensions.kt diff --git a/engine/engine-paper/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt new file mode 100644 index 0000000000..8eb5fae20a --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt @@ -0,0 +1,24 @@ +package lirand.api.extensions.world + +import org.bukkit.Effect +import org.bukkit.Instrument +import org.bukkit.Location +import org.bukkit.Note +import org.bukkit.Particle +import org.bukkit.Sound +import org.bukkit.SoundCategory +import org.bukkit.block.data.BlockData +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.PlayerInventory +import org.bukkit.plugin.Plugin +import org.bukkit.util.Vector + +fun PlayerInventory.clearArmor() { + armorContents = arrayOfNulls(4) +} + +fun PlayerInventory.clearAll() { + clear() + clearArmor() +} \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/lirand/api/utilities/Reflection.kt b/engine/engine-paper/src/main/kotlin/lirand/api/utilities/Reflection.kt new file mode 100644 index 0000000000..ca81b9a5c3 --- /dev/null +++ b/engine/engine-paper/src/main/kotlin/lirand/api/utilities/Reflection.kt @@ -0,0 +1,15 @@ +package lirand.api.utilities + +import java.lang.reflect.Field +import java.lang.reflect.Method + + +val Class<*>.allFields: List + get() = buildList { + var currentClass: Class<*>? = this@allFields + while (currentClass != null) { + val declaredFields = currentClass.declaredFields + addAll(declaredFields) + currentClass = currentClass.superclass + } + } \ No newline at end of file diff --git a/plugin/src/test/kotlin/me/gabber235/typewriter/utils/CronParserTest.kt b/engine/engine-paper/src/test/kotlin/com/typewritermc/utils/CronParserTest.kt similarity index 99% rename from plugin/src/test/kotlin/me/gabber235/typewriter/utils/CronParserTest.kt rename to engine/engine-paper/src/test/kotlin/com/typewritermc/utils/CronParserTest.kt index 22301e6f2b..1d361cc8eb 100644 --- a/plugin/src/test/kotlin/me/gabber235/typewriter/utils/CronParserTest.kt +++ b/engine/engine-paper/src/test/kotlin/com/typewritermc/utils/CronParserTest.kt @@ -1,6 +1,7 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.utils -import me.gabber235.typewriter.utils.CronExpression.* +import com.typewritermc.engine.paper.utils.CronExpression +import com.typewritermc.engine.paper.utils.CronExpression.* import org.junit.jupiter.api.* import org.junit.jupiter.api.Assertions.* import java.time.* diff --git a/plugin/src/test/kotlin/me/gabber235/typewriter/utils/DurationParserTest.kt b/engine/engine-paper/src/test/kotlin/com/typewritermc/utils/DurationParserTest.kt similarity index 95% rename from plugin/src/test/kotlin/me/gabber235/typewriter/utils/DurationParserTest.kt rename to engine/engine-paper/src/test/kotlin/com/typewritermc/utils/DurationParserTest.kt index 7dc1a38c47..9598315dae 100644 --- a/plugin/src/test/kotlin/me/gabber235/typewriter/utils/DurationParserTest.kt +++ b/engine/engine-paper/src/test/kotlin/com/typewritermc/utils/DurationParserTest.kt @@ -1,5 +1,6 @@ -package me.gabber235.typewriter.utils +package com.typewritermc.utils +import com.typewritermc.engine.paper.utils.DurationParser import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test diff --git a/plugin/gradle.properties b/engine/gradle.properties similarity index 100% rename from plugin/gradle.properties rename to engine/gradle.properties diff --git a/engine/gradle/wrapper/gradle-wrapper.jar b/engine/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 zcma&N1CXTcmMvW9vTb(Rwr$&4wr$(C?dmSu>@vG-+vuvg^_??!{yS%8zW-#zn-LkA z5&1^$^{lnmUON?}LBF8_K|(?T0Ra(xUH{($5eN!MR#ZihR#HxkUPe+_R8Cn`RRs(P z_^*#_XlXmGv7!4;*Y%p4nw?{bNp@UZHv1?Um8r6)Fei3p@ClJn0ECfg1hkeuUU@Or zDaPa;U3fE=3L}DooL;8f;P0ipPt0Z~9P0)lbStMS)ag54=uL9ia-Lm3nh|@(Y?B`; zx_#arJIpXH!U{fbCbI^17}6Ri*H<>OLR%c|^mh8+)*h~K8Z!9)DPf zR2h?lbDZQ`p9P;&DQ4F0sur@TMa!Y}S8irn(%d-gi0*WxxCSk*A?3lGh=gcYN?FGl z7D=Js!i~0=u3rox^eO3i@$0=n{K1lPNU zwmfjRVmLOCRfe=seV&P*1Iq=^i`502keY8Uy-WNPwVNNtJFx?IwAyRPZo2Wo1+S(xF37LJZ~%i)kpFQ3Fw=mXfd@>%+)RpYQLnr}B~~zoof(JVm^^&f zxKV^+3D3$A1G;qh4gPVjhrC8e(VYUHv#dy^)(RoUFM?o%W-EHxufuWf(l*@-l+7vt z=l`qmR56K~F|v<^Pd*p~1_y^P0P^aPC##d8+HqX4IR1gu+7w#~TBFphJxF)T$2WEa zxa?H&6=Qe7d(#tha?_1uQys2KtHQ{)Qco)qwGjrdNL7thd^G5i8Os)CHqc>iOidS} z%nFEDdm=GXBw=yXe1W-ShHHFb?Cc70+$W~z_+}nAoHFYI1MV1wZegw*0y^tC*s%3h zhD3tN8b=Gv&rj}!SUM6|ajSPp*58KR7MPpI{oAJCtY~JECm)*m_x>AZEu>DFgUcby z1Qaw8lU4jZpQ_$;*7RME+gq1KySGG#Wql>aL~k9tLrSO()LWn*q&YxHEuzmwd1?aAtI zBJ>P=&$=l1efe1CDU;`Fd+_;&wI07?V0aAIgc(!{a z0Jg6Y=inXc3^n!U0Atk`iCFIQooHqcWhO(qrieUOW8X(x?(RD}iYDLMjSwffH2~tB z)oDgNBLB^AJBM1M^c5HdRx6fBfka`(LD-qrlh5jqH~);#nw|iyp)()xVYak3;Ybik z0j`(+69aK*B>)e_p%=wu8XC&9e{AO4c~O1U`5X9}?0mrd*m$_EUek{R?DNSh(=br# z#Q61gBzEpmy`$pA*6!87 zSDD+=@fTY7<4A?GLqpA?Pb2z$pbCc4B4zL{BeZ?F-8`s$?>*lXXtn*NC61>|*w7J* z$?!iB{6R-0=KFmyp1nnEmLsA-H0a6l+1uaH^g%c(p{iT&YFrbQ$&PRb8Up#X3@Zsk zD^^&LK~111%cqlP%!_gFNa^dTYT?rhkGl}5=fL{a`UViaXWI$k-UcHJwmaH1s=S$4 z%4)PdWJX;hh5UoK?6aWoyLxX&NhNRqKam7tcOkLh{%j3K^4Mgx1@i|Pi&}<^5>hs5 zm8?uOS>%)NzT(%PjVPGa?X%`N2TQCKbeH2l;cTnHiHppPSJ<7y-yEIiC!P*ikl&!B z%+?>VttCOQM@ShFguHVjxX^?mHX^hSaO_;pnyh^v9EumqSZTi+#f&_Vaija0Q-e*| z7ulQj6Fs*bbmsWp{`auM04gGwsYYdNNZcg|ph0OgD>7O}Asn7^Z=eI>`$2*v78;sj-}oMoEj&@)9+ycEOo92xSyY344^ z11Hb8^kdOvbf^GNAK++bYioknrpdN>+u8R?JxG=!2Kd9r=YWCOJYXYuM0cOq^FhEd zBg2puKy__7VT3-r*dG4c62Wgxi52EMCQ`bKgf*#*ou(D4-ZN$+mg&7$u!! z-^+Z%;-3IDwqZ|K=ah85OLwkO zKxNBh+4QHh)u9D?MFtpbl)us}9+V!D%w9jfAMYEb>%$A;u)rrI zuBudh;5PN}_6J_}l55P3l_)&RMlH{m!)ai-i$g)&*M`eN$XQMw{v^r@-125^RRCF0 z^2>|DxhQw(mtNEI2Kj(;KblC7x=JlK$@78`O~>V!`|1Lm-^JR$-5pUANAnb(5}B}JGjBsliK4& zk6y(;$e&h)lh2)L=bvZKbvh@>vLlreBdH8No2>$#%_Wp1U0N7Ank!6$dFSi#xzh|( zRi{Uw%-4W!{IXZ)fWx@XX6;&(m_F%c6~X8hx=BN1&q}*( zoaNjWabE{oUPb!Bt$eyd#$5j9rItB-h*5JiNi(v^e|XKAj*8(k<5-2$&ZBR5fF|JA z9&m4fbzNQnAU}r8ab>fFV%J0z5awe#UZ|bz?Ur)U9bCIKWEzi2%A+5CLqh?}K4JHi z4vtM;+uPsVz{Lfr;78W78gC;z*yTch~4YkLr&m-7%-xc ztw6Mh2d>_iO*$Rd8(-Cr1_V8EO1f*^@wRoSozS) zy1UoC@pruAaC8Z_7~_w4Q6n*&B0AjOmMWa;sIav&gu z|J5&|{=a@vR!~k-OjKEgPFCzcJ>#A1uL&7xTDn;{XBdeM}V=l3B8fE1--DHjSaxoSjNKEM9|U9#m2<3>n{Iuo`r3UZp;>GkT2YBNAh|b z^jTq-hJp(ebZh#Lk8hVBP%qXwv-@vbvoREX$TqRGTgEi$%_F9tZES@z8Bx}$#5eeG zk^UsLBH{bc2VBW)*EdS({yw=?qmevwi?BL6*=12k9zM5gJv1>y#ML4!)iiPzVaH9% zgSImetD@dam~e>{LvVh!phhzpW+iFvWpGT#CVE5TQ40n%F|p(sP5mXxna+Ev7PDwA zamaV4m*^~*xV+&p;W749xhb_X=$|LD;FHuB&JL5?*Y2-oIT(wYY2;73<^#46S~Gx| z^cez%V7x$81}UWqS13Gz80379Rj;6~WdiXWOSsdmzY39L;Hg3MH43o*y8ibNBBH`(av4|u;YPq%{R;IuYow<+GEsf@R?=@tT@!}?#>zIIn0CoyV!hq3mw zHj>OOjfJM3F{RG#6ujzo?y32m^tgSXf@v=J$ELdJ+=5j|=F-~hP$G&}tDZsZE?5rX ztGj`!S>)CFmdkccxM9eGIcGnS2AfK#gXwj%esuIBNJQP1WV~b~+D7PJTmWGTSDrR` zEAu4B8l>NPuhsk5a`rReSya2nfV1EK01+G!x8aBdTs3Io$u5!6n6KX%uv@DxAp3F@{4UYg4SWJtQ-W~0MDb|j-$lwVn znAm*Pl!?Ps&3wO=R115RWKb*JKoexo*)uhhHBncEDMSVa_PyA>k{Zm2(wMQ(5NM3# z)jkza|GoWEQo4^s*wE(gHz?Xsg4`}HUAcs42cM1-qq_=+=!Gk^y710j=66(cSWqUe zklbm8+zB_syQv5A2rj!Vbw8;|$@C!vfNmNV!yJIWDQ>{+2x zKjuFX`~~HKG~^6h5FntRpnnHt=D&rq0>IJ9#F0eM)Y-)GpRjiN7gkA8wvnG#K=q{q z9dBn8_~wm4J<3J_vl|9H{7q6u2A!cW{bp#r*-f{gOV^e=8S{nc1DxMHFwuM$;aVI^ zz6A*}m8N-&x8;aunp1w7_vtB*pa+OYBw=TMc6QK=mbA-|Cf* zvyh8D4LRJImooUaSb7t*fVfih<97Gf@VE0|z>NcBwBQze);Rh!k3K_sfunToZY;f2 z^HmC4KjHRVg+eKYj;PRN^|E0>Gj_zagfRbrki68I^#~6-HaHg3BUW%+clM1xQEdPYt_g<2K+z!$>*$9nQ>; zf9Bei{?zY^-e{q_*|W#2rJG`2fy@{%6u0i_VEWTq$*(ZN37|8lFFFt)nCG({r!q#9 z5VK_kkSJ3?zOH)OezMT{!YkCuSSn!K#-Rhl$uUM(bq*jY? zi1xbMVthJ`E>d>(f3)~fozjg^@eheMF6<)I`oeJYx4*+M&%c9VArn(OM-wp%M<-`x z7sLP1&3^%Nld9Dhm@$3f2}87!quhI@nwd@3~fZl_3LYW-B?Ia>ui`ELg z&Qfe!7m6ze=mZ`Ia9$z|ARSw|IdMpooY4YiPN8K z4B(ts3p%2i(Td=tgEHX z0UQ_>URBtG+-?0E;E7Ld^dyZ;jjw0}XZ(}-QzC6+NN=40oDb2^v!L1g9xRvE#@IBR zO!b-2N7wVfLV;mhEaXQ9XAU+>=XVA6f&T4Z-@AX!leJ8obP^P^wP0aICND?~w&NykJ#54x3_@r7IDMdRNy4Hh;h*!u(Ol(#0bJdwEo$5437-UBjQ+j=Ic>Q2z` zJNDf0yO6@mr6y1#n3)s(W|$iE_i8r@Gd@!DWDqZ7J&~gAm1#~maIGJ1sls^gxL9LLG_NhU!pTGty!TbhzQnu)I*S^54U6Yu%ZeCg`R>Q zhBv$n5j0v%O_j{QYWG!R9W?5_b&67KB$t}&e2LdMvd(PxN6Ir!H4>PNlerpBL>Zvyy!yw z-SOo8caEpDt(}|gKPBd$qND5#a5nju^O>V&;f890?yEOfkSG^HQVmEbM3Ugzu+UtH zC(INPDdraBN?P%kE;*Ae%Wto&sgw(crfZ#Qy(<4nk;S|hD3j{IQRI6Yq|f^basLY; z-HB&Je%Gg}Jt@={_C{L$!RM;$$|iD6vu#3w?v?*;&()uB|I-XqEKqZPS!reW9JkLewLb!70T7n`i!gNtb1%vN- zySZj{8-1>6E%H&=V}LM#xmt`J3XQoaD|@XygXjdZ1+P77-=;=eYpoEQ01B@L*a(uW zrZeZz?HJsw_4g0vhUgkg@VF8<-X$B8pOqCuWAl28uB|@r`19DTUQQsb^pfqB6QtiT z*`_UZ`fT}vtUY#%sq2{rchyfu*pCg;uec2$-$N_xgjZcoumE5vSI{+s@iLWoz^Mf; zuI8kDP{!XY6OP~q5}%1&L}CtfH^N<3o4L@J@zg1-mt{9L`s^z$Vgb|mr{@WiwAqKg zp#t-lhrU>F8o0s1q_9y`gQNf~Vb!F%70f}$>i7o4ho$`uciNf=xgJ>&!gSt0g;M>*x4-`U)ysFW&Vs^Vk6m%?iuWU+o&m(2Jm26Y(3%TL; zA7T)BP{WS!&xmxNw%J=$MPfn(9*^*TV;$JwRy8Zl*yUZi8jWYF>==j~&S|Xinsb%c z2?B+kpet*muEW7@AzjBA^wAJBY8i|#C{WtO_or&Nj2{=6JTTX05}|H>N2B|Wf!*3_ z7hW*j6p3TvpghEc6-wufFiY!%-GvOx*bZrhZu+7?iSrZL5q9}igiF^*R3%DE4aCHZ zqu>xS8LkW+Auv%z-<1Xs92u23R$nk@Pk}MU5!gT|c7vGlEA%G^2th&Q*zfg%-D^=f z&J_}jskj|Q;73NP4<4k*Y%pXPU2Thoqr+5uH1yEYM|VtBPW6lXaetokD0u z9qVek6Q&wk)tFbQ8(^HGf3Wp16gKmr>G;#G(HRBx?F`9AIRboK+;OfHaLJ(P>IP0w zyTbTkx_THEOs%Q&aPrxbZrJlio+hCC_HK<4%f3ZoSAyG7Dn`=X=&h@m*|UYO-4Hq0 z-Bq&+Ie!S##4A6OGoC~>ZW`Y5J)*ouaFl_e9GA*VSL!O_@xGiBw!AF}1{tB)z(w%c zS1Hmrb9OC8>0a_$BzeiN?rkPLc9%&;1CZW*4}CDDNr2gcl_3z+WC15&H1Zc2{o~i) z)LLW=WQ{?ricmC`G1GfJ0Yp4Dy~Ba;j6ZV4r{8xRs`13{dD!xXmr^Aga|C=iSmor% z8hi|pTXH)5Yf&v~exp3o+sY4B^^b*eYkkCYl*T{*=-0HniSA_1F53eCb{x~1k3*`W zr~};p1A`k{1DV9=UPnLDgz{aJH=-LQo<5%+Em!DNN252xwIf*wF_zS^!(XSm(9eoj z=*dXG&n0>)_)N5oc6v!>-bd(2ragD8O=M|wGW z!xJQS<)u70m&6OmrF0WSsr@I%T*c#Qo#Ha4d3COcX+9}hM5!7JIGF>7<~C(Ear^Sn zm^ZFkV6~Ula6+8S?oOROOA6$C&q&dp`>oR-2Ym3(HT@O7Sd5c~+kjrmM)YmgPH*tL zX+znN>`tv;5eOfX?h{AuX^LK~V#gPCu=)Tigtq9&?7Xh$qN|%A$?V*v=&-2F$zTUv z`C#WyIrChS5|Kgm_GeudCFf;)!WH7FI60j^0o#65o6`w*S7R@)88n$1nrgU(oU0M9 zx+EuMkC>(4j1;m6NoGqEkpJYJ?vc|B zOlwT3t&UgL!pX_P*6g36`ZXQ; z9~Cv}ANFnJGp(;ZhS(@FT;3e)0)Kp;h^x;$*xZn*k0U6-&FwI=uOGaODdrsp-!K$Ac32^c{+FhI-HkYd5v=`PGsg%6I`4d9Jy)uW0y%) zm&j^9WBAp*P8#kGJUhB!L?a%h$hJgQrx!6KCB_TRo%9{t0J7KW8!o1B!NC)VGLM5! zpZy5Jc{`r{1e(jd%jsG7k%I+m#CGS*BPA65ZVW~fLYw0dA-H_}O zrkGFL&P1PG9p2(%QiEWm6x;U-U&I#;Em$nx-_I^wtgw3xUPVVu zqSuKnx&dIT-XT+T10p;yjo1Y)z(x1fb8Dzfn8e yu?e%!_ptzGB|8GrCfu%p?(_ zQccdaaVK$5bz;*rnyK{_SQYM>;aES6Qs^lj9lEs6_J+%nIiuQC*fN;z8md>r_~Mfl zU%p5Dt_YT>gQqfr@`cR!$NWr~+`CZb%dn;WtzrAOI>P_JtsB76PYe*<%H(y>qx-`Kq!X_; z<{RpAqYhE=L1r*M)gNF3B8r(<%8mo*SR2hu zccLRZwGARt)Hlo1euqTyM>^!HK*!Q2P;4UYrysje@;(<|$&%vQekbn|0Ruu_Io(w4#%p6ld2Yp7tlA`Y$cciThP zKzNGIMPXX%&Ud0uQh!uQZz|FB`4KGD?3!ND?wQt6!n*f4EmCoJUh&b?;B{|lxs#F- z31~HQ`SF4x$&v00@(P+j1pAaj5!s`)b2RDBp*PB=2IB>oBF!*6vwr7Dp%zpAx*dPr zb@Zjq^XjN?O4QcZ*O+8>)|HlrR>oD*?WQl5ri3R#2?*W6iJ>>kH%KnnME&TT@ZzrHS$Q%LC?n|e>V+D+8D zYc4)QddFz7I8#}y#Wj6>4P%34dZH~OUDb?uP%-E zwjXM(?Sg~1!|wI(RVuxbu)-rH+O=igSho_pDCw(c6b=P zKk4ATlB?bj9+HHlh<_!&z0rx13K3ZrAR8W)!@Y}o`?a*JJsD+twZIv`W)@Y?Amu_u zz``@-e2X}27$i(2=9rvIu5uTUOVhzwu%mNazS|lZb&PT;XE2|B&W1>=B58#*!~D&) zfVmJGg8UdP*fx(>Cj^?yS^zH#o-$Q-*$SnK(ZVFkw+er=>N^7!)FtP3y~Xxnu^nzY zikgB>Nj0%;WOltWIob|}%lo?_C7<``a5hEkx&1ku$|)i>Rh6@3h*`slY=9U}(Ql_< zaNG*J8vb&@zpdhAvv`?{=zDedJ23TD&Zg__snRAH4eh~^oawdYi6A3w8<Ozh@Kw)#bdktM^GVb zrG08?0bG?|NG+w^&JvD*7LAbjED{_Zkc`3H!My>0u5Q}m!+6VokMLXxl`Mkd=g&Xx z-a>m*#G3SLlhbKB!)tnzfWOBV;u;ftU}S!NdD5+YtOjLg?X}dl>7m^gOpihrf1;PY zvll&>dIuUGs{Qnd- zwIR3oIrct8Va^Tm0t#(bJD7c$Z7DO9*7NnRZorrSm`b`cxz>OIC;jSE3DO8`hX955ui`s%||YQtt2 z5DNA&pG-V+4oI2s*x^>-$6J?p=I>C|9wZF8z;VjR??Icg?1w2v5Me+FgAeGGa8(3S z4vg*$>zC-WIVZtJ7}o9{D-7d>zCe|z#<9>CFve-OPAYsneTb^JH!Enaza#j}^mXy1 z+ULn^10+rWLF6j2>Ya@@Kq?26>AqK{A_| zQKb*~F1>sE*=d?A?W7N2j?L09_7n+HGi{VY;MoTGr_)G9)ot$p!-UY5zZ2Xtbm=t z@dpPSGwgH=QtIcEulQNI>S-#ifbnO5EWkI;$A|pxJd885oM+ zGZ0_0gDvG8q2xebj+fbCHYfAXuZStH2j~|d^sBAzo46(K8n59+T6rzBwK)^rfPT+B zyIFw)9YC-V^rhtK`!3jrhmW-sTmM+tPH+;nwjL#-SjQPUZ53L@A>y*rt(#M(qsiB2 zx6B)dI}6Wlsw%bJ8h|(lhkJVogQZA&n{?Vgs6gNSXzuZpEyu*xySy8ro07QZ7Vk1!3tJphN_5V7qOiyK8p z#@jcDD8nmtYi1^l8ml;AF<#IPK?!pqf9D4moYk>d99Im}Jtwj6c#+A;f)CQ*f-hZ< z=p_T86jog%!p)D&5g9taSwYi&eP z#JuEK%+NULWus;0w32-SYFku#i}d~+{Pkho&^{;RxzP&0!RCm3-9K6`>KZpnzS6?L z^H^V*s!8<>x8bomvD%rh>Zp3>Db%kyin;qtl+jAv8Oo~1g~mqGAC&Qi_wy|xEt2iz zWAJEfTV%cl2Cs<1L&DLRVVH05EDq`pH7Oh7sR`NNkL%wi}8n>IXcO40hp+J+sC!W?!krJf!GJNE8uj zg-y~Ns-<~D?yqbzVRB}G>0A^f0!^N7l=$m0OdZuqAOQqLc zX?AEGr1Ht+inZ-Qiwnl@Z0qukd__a!C*CKuGdy5#nD7VUBM^6OCpxCa2A(X;e0&V4 zM&WR8+wErQ7UIc6LY~Q9x%Sn*Tn>>P`^t&idaOEnOd(Ufw#>NoR^1QdhJ8s`h^|R_ zXX`c5*O~Xdvh%q;7L!_!ohf$NfEBmCde|#uVZvEo>OfEq%+Ns7&_f$OR9xsihRpBb z+cjk8LyDm@U{YN>+r46?nn{7Gh(;WhFw6GAxtcKD+YWV?uge>;+q#Xx4!GpRkVZYu zzsF}1)7$?%s9g9CH=Zs+B%M_)+~*j3L0&Q9u7!|+T`^O{xE6qvAP?XWv9_MrZKdo& z%IyU)$Q95AB4!#hT!_dA>4e@zjOBD*Y=XjtMm)V|+IXzjuM;(l+8aA5#Kaz_$rR6! zj>#&^DidYD$nUY(D$mH`9eb|dtV0b{S>H6FBfq>t5`;OxA4Nn{J(+XihF(stSche7$es&~N$epi&PDM_N`As;*9D^L==2Q7Z2zD+CiU(|+-kL*VG+&9!Yb3LgPy?A zm7Z&^qRG_JIxK7-FBzZI3Q<;{`DIxtc48k> zc|0dmX;Z=W$+)qE)~`yn6MdoJ4co;%!`ddy+FV538Y)j(vg}5*k(WK)KWZ3WaOG!8 z!syGn=s{H$odtpqFrT#JGM*utN7B((abXnpDM6w56nhw}OY}0TiTG1#f*VFZr+^-g zbP10`$LPq_;PvrA1XXlyx2uM^mrjTzX}w{yuLo-cOClE8MMk47T25G8M!9Z5ypOSV zAJUBGEg5L2fY)ZGJb^E34R2zJ?}Vf>{~gB!8=5Z) z9y$>5c)=;o0HeHHSuE4U)#vG&KF|I%-cF6f$~pdYJWk_dD}iOA>iA$O$+4%@>JU08 zS`ep)$XLPJ+n0_i@PkF#ri6T8?ZeAot$6JIYHm&P6EB=BiaNY|aA$W0I+nz*zkz_z zkEru!tj!QUffq%)8y0y`T&`fuus-1p>=^hnBiBqD^hXrPs`PY9tU3m0np~rISY09> z`P3s=-kt_cYcxWd{de@}TwSqg*xVhp;E9zCsnXo6z z?f&Sv^U7n4`xr=mXle94HzOdN!2kB~4=%)u&N!+2;z6UYKUDqi-s6AZ!haB;@&B`? z_TRX0%@suz^TRdCb?!vNJYPY8L_}&07uySH9%W^Tc&1pia6y1q#?*Drf}GjGbPjBS zbOPcUY#*$3sL2x4v_i*Y=N7E$mR}J%|GUI(>WEr+28+V z%v5{#e!UF*6~G&%;l*q*$V?&r$Pp^sE^i-0$+RH3ERUUdQ0>rAq2(2QAbG}$y{de( z>{qD~GGuOk559Y@%$?N^1ApVL_a704>8OD%8Y%8B;FCt%AoPu8*D1 zLB5X>b}Syz81pn;xnB}%0FnwazlWfUV)Z-~rZg6~b z6!9J$EcE&sEbzcy?CI~=boWA&eeIa%z(7SE^qgVLz??1Vbc1*aRvc%Mri)AJaAG!p z$X!_9Ds;Zz)f+;%s&dRcJt2==P{^j3bf0M=nJd&xwUGlUFn?H=2W(*2I2Gdu zv!gYCwM10aeus)`RIZSrCK=&oKaO_Ry~D1B5!y0R=%!i2*KfXGYX&gNv_u+n9wiR5 z*e$Zjju&ODRW3phN925%S(jL+bCHv6rZtc?!*`1TyYXT6%Ju=|X;6D@lq$8T zW{Y|e39ioPez(pBH%k)HzFITXHvnD6hw^lIoUMA;qAJ^CU?top1fo@s7xT13Fvn1H z6JWa-6+FJF#x>~+A;D~;VDs26>^oH0EI`IYT2iagy23?nyJ==i{g4%HrAf1-*v zK1)~@&(KkwR7TL}L(A@C_S0G;-GMDy=MJn2$FP5s<%wC)4jC5PXoxrQBFZ_k0P{{s@sz+gX`-!=T8rcB(=7vW}^K6oLWMmp(rwDh}b zwaGGd>yEy6fHv%jM$yJXo5oMAQ>c9j`**}F?MCry;T@47@r?&sKHgVe$MCqk#Z_3S z1GZI~nOEN*P~+UaFGnj{{Jo@16`(qVNtbU>O0Hf57-P>x8Jikp=`s8xWs^dAJ9lCQ z)GFm+=OV%AMVqVATtN@|vp61VVAHRn87}%PC^RAzJ%JngmZTasWBAWsoAqBU+8L8u z4A&Pe?fmTm0?mK-BL9t+{y7o(7jm+RpOhL9KnY#E&qu^}B6=K_dB}*VlSEiC9fn)+V=J;OnN)Ta5v66ic1rG+dGAJ1 z1%Zb_+!$=tQ~lxQrzv3x#CPb?CekEkA}0MYSgx$Jdd}q8+R=ma$|&1a#)TQ=l$1tQ z=tL9&_^vJ)Pk}EDO-va`UCT1m#Uty1{v^A3P~83_#v^ozH}6*9mIjIr;t3Uv%@VeW zGL6(CwCUp)Jq%G0bIG%?{_*Y#5IHf*5M@wPo6A{$Um++Co$wLC=J1aoG93&T7Ho}P z=mGEPP7GbvoG!uD$k(H3A$Z))+i{Hy?QHdk>3xSBXR0j!11O^mEe9RHmw!pvzv?Ua~2_l2Yh~_!s1qS`|0~0)YsbHSz8!mG)WiJE| z2f($6TQtt6L_f~ApQYQKSb=`053LgrQq7G@98#igV>y#i==-nEjQ!XNu9 z~;mE+gtj4IDDNQJ~JVk5Ux6&LCSFL!y=>79kE9=V}J7tD==Ga+IW zX)r7>VZ9dY=V&}DR))xUoV!u(Z|%3ciQi_2jl}3=$Agc(`RPb z8kEBpvY>1FGQ9W$n>Cq=DIpski};nE)`p3IUw1Oz0|wxll^)4dq3;CCY@RyJgFgc# zKouFh!`?Xuo{IMz^xi-h=StCis_M7yq$u) z?XHvw*HP0VgR+KR6wI)jEMX|ssqYvSf*_3W8zVTQzD?3>H!#>InzpSO)@SC8q*ii- z%%h}_#0{4JG;Jm`4zg};BPTGkYamx$Xo#O~lBirRY)q=5M45n{GCfV7h9qwyu1NxOMoP4)jjZMxmT|IQQh0U7C$EbnMN<3)Kk?fFHYq$d|ICu>KbY_hO zTZM+uKHe(cIZfEqyzyYSUBZa8;Fcut-GN!HSA9ius`ltNebF46ZX_BbZNU}}ZOm{M2&nANL9@0qvih15(|`S~z}m&h!u4x~(%MAO$jHRWNfuxWF#B)E&g3ghSQ9|> z(MFaLQj)NE0lowyjvg8z0#m6FIuKE9lDO~Glg}nSb7`~^&#(Lw{}GVOS>U)m8bF}x zVjbXljBm34Cs-yM6TVusr+3kYFjr28STT3g056y3cH5Tmge~ASxBj z%|yb>$eF;WgrcOZf569sDZOVwoo%8>XO>XQOX1OyN9I-SQgrm;U;+#3OI(zrWyow3 zk==|{lt2xrQ%FIXOTejR>;wv(Pb8u8}BUpx?yd(Abh6? zsoO3VYWkeLnF43&@*#MQ9-i-d0t*xN-UEyNKeyNMHw|A(k(_6QKO=nKMCxD(W(Yop zsRQ)QeL4X3Lxp^L%wzi2-WVSsf61dqliPUM7srDB?Wm6Lzn0&{*}|IsKQW;02(Y&| zaTKv|`U(pSzuvR6Rduu$wzK_W-Y-7>7s?G$)U}&uK;<>vU}^^ns@Z!p+9?St1s)dG zK%y6xkPyyS1$~&6v{kl?Md6gwM|>mt6Upm>oa8RLD^8T{0?HC!Z>;(Bob7el(DV6x zi`I)$&E&ngwFS@bi4^xFLAn`=fzTC;aimE^!cMI2n@Vo%Ae-ne`RF((&5y6xsjjAZ zVguVoQ?Z9uk$2ON;ersE%PU*xGO@T*;j1BO5#TuZKEf(mB7|g7pcEA=nYJ{s3vlbg zd4-DUlD{*6o%Gc^N!Nptgay>j6E5;3psI+C3Q!1ZIbeCubW%w4pq9)MSDyB{HLm|k zxv-{$$A*pS@csolri$Ge<4VZ}e~78JOL-EVyrbxKra^d{?|NnPp86!q>t<&IP07?Z z^>~IK^k#OEKgRH+LjllZXk7iA>2cfH6+(e&9ku5poo~6y{GC5>(bRK7hwjiurqAiZ zg*DmtgY}v83IjE&AbiWgMyFbaRUPZ{lYiz$U^&Zt2YjG<%m((&_JUbZcfJ22(>bi5 z!J?<7AySj0JZ&<-qXX;mcV!f~>G=sB0KnjWca4}vrtunD^1TrpfeS^4dvFr!65knK zZh`d;*VOkPs4*-9kL>$GP0`(M!j~B;#x?Ba~&s6CopvO86oM?-? zOw#dIRc;6A6T?B`Qp%^<U5 z19x(ywSH$_N+Io!6;e?`tWaM$`=Db!gzx|lQ${DG!zb1Zl&|{kX0y6xvO1o z220r<-oaS^^R2pEyY;=Qllqpmue|5yI~D|iI!IGt@iod{Opz@*ml^w2bNs)p`M(Io z|E;;m*Xpjd9l)4G#KaWfV(t8YUn@A;nK^#xgv=LtnArX|vWQVuw3}B${h+frU2>9^ z!l6)!Uo4`5k`<<;E(ido7M6lKTgWezNLq>U*=uz&s=cc$1%>VrAeOoUtA|T6gO4>UNqsdK=NF*8|~*sl&wI=x9-EGiq*aqV!(VVXA57 zw9*o6Ir8Lj1npUXvlevtn(_+^X5rzdR>#(}4YcB9O50q97%rW2me5_L=%ffYPUSRc z!vv?Kv>dH994Qi>U(a<0KF6NH5b16enCp+mw^Hb3Xs1^tThFpz!3QuN#}KBbww`(h z7GO)1olDqy6?T$()R7y%NYx*B0k_2IBiZ14&8|JPFxeMF{vSTxF-Vi3+ZOI=Thq2} zyQgjYY1_7^ZQHh{?P))4+qUiQJLi1&{yE>h?~jU%tjdV0h|FENbM3X(KnJdPKc?~k zh=^Ixv*+smUll!DTWH!jrV*wSh*(mx0o6}1@JExzF(#9FXgmTXVoU+>kDe68N)dkQ zH#_98Zv$}lQwjKL@yBd;U(UD0UCl322=pav<=6g>03{O_3oKTq;9bLFX1ia*lw;#K zOiYDcBJf)82->83N_Y(J7Kr_3lE)hAu;)Q(nUVydv+l+nQ$?|%MWTy`t>{havFSQloHwiIkGK9YZ79^9?AZo0ZyQlVR#}lF%dn5n%xYksXf8gnBm=wO7g_^! zauQ-bH1Dc@3ItZ-9D_*pH}p!IG7j8A_o94#~>$LR|TFq zZ-b00*nuw|-5C2lJDCw&8p5N~Z1J&TrcyErds&!l3$eSz%`(*izc;-?HAFD9AHb-| z>)id`QCrzRws^9(#&=pIx9OEf2rmlob8sK&xPCWS+nD~qzU|qG6KwA{zbikcfQrdH z+ zQg>O<`K4L8rN7`GJB0*3<3`z({lWe#K!4AZLsI{%z#ja^OpfjU{!{)x0ZH~RB0W5X zTwN^w=|nA!4PEU2=LR05x~}|B&ZP?#pNgDMwD*ajI6oJqv!L81gu=KpqH22avXf0w zX3HjbCI!n9>l046)5rr5&v5ja!xkKK42zmqHzPx$9Nn_MZk`gLeSLgC=LFf;H1O#B zn=8|^1iRrujHfbgA+8i<9jaXc;CQBAmQvMGQPhFec2H1knCK2x!T`e6soyrqCamX% zTQ4dX_E*8so)E*TB$*io{$c6X)~{aWfaqdTh=xEeGvOAN9H&-t5tEE-qso<+C!2>+ zskX51H-H}#X{A75wqFe-J{?o8Bx|>fTBtl&tcbdR|132Ztqu5X0i-pisB-z8n71%q%>EF}yy5?z=Ve`}hVh{Drv1YWL zW=%ug_&chF11gDv3D6B)Tz5g54H0mDHNjuKZ+)CKFk4Z|$RD zfRuKLW`1B>B?*RUfVd0+u8h3r-{@fZ{k)c!93t1b0+Q9vOaRnEn1*IL>5Z4E4dZ!7 ztp4GP-^1d>8~LMeb}bW!(aAnB1tM_*la=Xx)q(I0Y@__Zd$!KYb8T2VBRw%e$iSdZ zkwdMwd}eV9q*;YvrBFTv1>1+}{H!JK2M*C|TNe$ZSA>UHKk);wz$(F$rXVc|sI^lD zV^?_J!3cLM;GJuBMbftbaRUs$;F}HDEDtIeHQ)^EJJ1F9FKJTGH<(Jj`phE6OuvE) zqK^K`;3S{Y#1M@8yRQwH`?kHMq4tHX#rJ>5lY3DM#o@or4&^_xtBC(|JpGTfrbGkA z2Tu+AyT^pHannww!4^!$5?@5v`LYy~T`qs7SYt$JgrY(w%C+IWA;ZkwEF)u5sDvOK zGk;G>Mh&elvXDcV69J_h02l&O;!{$({fng9Rlc3ID#tmB^FIG^w{HLUpF+iB`|

NnX)EH+Nua)3Y(c z&{(nX_ht=QbJ%DzAya}!&uNu!4V0xI)QE$SY__m)SAKcN0P(&JcoK*Lxr@P zY&P=}&B3*UWNlc|&$Oh{BEqwK2+N2U$4WB7Fd|aIal`FGANUa9E-O)!gV`((ZGCc$ zBJA|FFrlg~9OBp#f7aHodCe{6= zay$6vN~zj1ddMZ9gQ4p32(7wD?(dE>KA2;SOzXRmPBiBc6g`eOsy+pVcHu=;Yd8@{ zSGgXf@%sKKQz~;!J;|2fC@emm#^_rnO0esEn^QxXgJYd`#FPWOUU5b;9eMAF zZhfiZb|gk8aJIw*YLp4!*(=3l8Cp{(%p?ho22*vN9+5NLV0TTazNY$B5L6UKUrd$n zjbX%#m7&F#U?QNOBXkiiWB*_tk+H?N3`vg;1F-I+83{M2!8<^nydGr5XX}tC!10&e z7D36bLaB56WrjL&HiiMVtpff|K%|*{t*ltt^5ood{FOG0<>k&1h95qPio)2`eL${YAGIx(b4VN*~nKn6E~SIQUuRH zQ+5zP6jfnP$S0iJ@~t!Ai3o`X7biohli;E zT#yXyl{bojG@-TGZzpdVDXhbmF%F9+-^YSIv|MT1l3j zrxOFq>gd2%U}?6}8mIj?M zc077Zc9fq(-)4+gXv?Az26IO6eV`RAJz8e3)SC7~>%rlzDwySVx*q$ygTR5kW2ds- z!HBgcq0KON9*8Ff$X0wOq$`T7ml(@TF)VeoF}x1OttjuVHn3~sHrMB++}f7f9H%@f z=|kP_?#+fve@{0MlbkC9tyvQ_R?lRdRJ@$qcB(8*jyMyeME5ns6ypVI1Xm*Zr{DuS zZ!1)rQfa89c~;l~VkCiHI|PCBd`S*2RLNQM8!g9L6?n`^evQNEwfO@&JJRme+uopQX0%Jo zgd5G&#&{nX{o?TQwQvF1<^Cg3?2co;_06=~Hcb6~4XWpNFL!WU{+CK;>gH%|BLOh7@!hsa(>pNDAmpcuVO-?;Bic17R}^|6@8DahH)G z!EmhsfunLL|3b=M0MeK2vqZ|OqUqS8npxwge$w-4pFVXFq$_EKrZY?BuP@Az@(k`L z`ViQBSk`y+YwRT;&W| z2e3UfkCo^uTA4}Qmmtqs+nk#gNr2W4 zTH%hhErhB)pkXR{B!q5P3-OM+M;qu~f>}IjtF%>w{~K-0*jPVLl?Chz&zIdxp}bjx zStp&Iufr58FTQ36AHU)0+CmvaOpKF;W@sMTFpJ`j;3d)J_$tNQI^c<^1o<49Z(~K> z;EZTBaVT%14(bFw2ob@?JLQ2@(1pCdg3S%E4*dJ}dA*v}_a4_P(a`cHnBFJxNobAv zf&Zl-Yt*lhn-wjZsq<9v-IsXxAxMZ58C@e0!rzhJ+D@9^3~?~yllY^s$?&oNwyH!#~6x4gUrfxplCvK#!f z$viuszW>MFEcFL?>ux*((!L$;R?xc*myjRIjgnQX79@UPD$6Dz0jutM@7h_pq z0Zr)#O<^y_K6jfY^X%A-ip>P%3saX{!v;fxT-*0C_j4=UMH+Xth(XVkVGiiKE#f)q z%Jp=JT)uy{&}Iq2E*xr4YsJ5>w^=#-mRZ4vPXpI6q~1aFwi+lQcimO45V-JXP;>(Q zo={U`{=_JF`EQj87Wf}{Qy35s8r1*9Mxg({CvOt}?Vh9d&(}iI-quvs-rm~P;eRA@ zG5?1HO}puruc@S{YNAF3vmUc2B4!k*yi))<5BQmvd3tr}cIs#9)*AX>t`=~{f#Uz0 z0&Nk!7sSZwJe}=)-R^$0{yeS!V`Dh7w{w5rZ9ir!Z7Cd7dwZcK;BT#V0bzTt>;@Cl z#|#A!-IL6CZ@eHH!CG>OO8!%G8&8t4)Ro@}USB*k>oEUo0LsljsJ-%5Mo^MJF2I8- z#v7a5VdJ-Cd%(a+y6QwTmi+?f8Nxtm{g-+WGL>t;s#epv7ug>inqimZCVm!uT5Pf6 ziEgQt7^%xJf#!aPWbuC_3Nxfb&CFbQy!(8ANpkWLI4oSnH?Q3f?0k1t$3d+lkQs{~(>06l&v|MpcFsyAv zin6N!-;pggosR*vV=DO(#+}4ps|5$`udE%Kdmp?G7B#y%H`R|i8skKOd9Xzx8xgR$>Zo2R2Ytktq^w#ul4uicxW#{ zFjG_RNlBroV_n;a7U(KIpcp*{M~e~@>Q#Av90Jc5v%0c>egEdY4v3%|K1XvB{O_8G zkTWLC>OZKf;XguMH2-Pw{BKbFzaY;4v2seZV0>^7Q~d4O=AwaPhP3h|!hw5aqOtT@ z!SNz}$of**Bl3TK209@F=Tn1+mgZa8yh(Png%Zd6Mt}^NSjy)etQrF zme*llAW=N_8R*O~d2!apJnF%(JcN??=`$qs3Y+~xs>L9x`0^NIn!8mMRFA_tg`etw z3k{9JAjnl@ygIiJcNHTy02GMAvBVqEss&t2<2mnw!; zU`J)0>lWiqVqo|ex7!+@0i>B~BSU1A_0w#Ee+2pJx0BFiZ7RDHEvE*ptc9md(B{&+ zKE>TM)+Pd>HEmdJao7U@S>nL(qq*A)#eLOuIfAS@j`_sK0UEY6OAJJ-kOrHG zjHx`g!9j*_jRcJ%>CE9K2MVf?BUZKFHY?EpV6ai7sET-tqk=nDFh-(65rhjtlKEY% z@G&cQ<5BKatfdA1FKuB=i>CCC5(|9TMW%K~GbA4}80I5%B}(gck#Wlq@$nO3%@QP_ z8nvPkJFa|znk>V92cA!K1rKtr)skHEJD;k8P|R8RkCq1Rh^&}Evwa4BUJz2f!2=MH zo4j8Y$YL2313}H~F7@J7mh>u%556Hw0VUOz-Un@ZASCL)y8}4XXS`t1AC*^>PLwIc zUQok5PFS=*#)Z!3JZN&eZ6ZDP^-c@StY*t20JhCnbMxXf=LK#;`4KHEqMZ-Ly9KsS zI2VUJGY&PmdbM+iT)zek)#Qc#_i4uH43 z@T5SZBrhNCiK~~esjsO9!qBpaWK<`>!-`b71Y5ReXQ4AJU~T2Njri1CEp5oKw;Lnm)-Y@Z3sEY}XIgSy%xo=uek(kAAH5MsV$V3uTUsoTzxp_rF=tx zV07vlJNKtJhCu`b}*#m&5LV4TAE&%KtHViDAdv#c^x`J7bg z&N;#I2GkF@SIGht6p-V}`!F_~lCXjl1BdTLIjD2hH$J^YFN`7f{Q?OHPFEM$65^!u zNwkelo*5+$ZT|oQ%o%;rBX$+?xhvjb)SHgNHE_yP%wYkkvXHS{Bf$OiKJ5d1gI0j< zF6N}Aq=(WDo(J{e-uOecxPD>XZ@|u-tgTR<972`q8;&ZD!cep^@B5CaqFz|oU!iFj zU0;6fQX&~15E53EW&w1s9gQQ~Zk16X%6 zjG`j0yq}4deX2?Tr(03kg>C(!7a|b9qFI?jcE^Y>-VhudI@&LI6Qa}WQ>4H_!UVyF z((cm&!3gmq@;BD#5P~0;_2qgZhtJS|>WdtjY=q zLnHH~Fm!cxw|Z?Vw8*~?I$g#9j&uvgm7vPr#&iZgPP~v~BI4jOv;*OQ?jYJtzO<^y z7-#C={r7CO810!^s(MT!@@Vz_SVU)7VBi(e1%1rvS!?PTa}Uv`J!EP3s6Y!xUgM^8 z4f!fq<3Wer_#;u!5ECZ|^c1{|q_lh3m^9|nsMR1#Qm|?4Yp5~|er2?W^7~cl;_r4WSme_o68J9p03~Hc%X#VcX!xAu%1`R!dfGJCp zV*&m47>s^%Ib0~-2f$6oSgn3jg8m%UA;ArcdcRyM5;}|r;)?a^D*lel5C`V5G=c~k zy*w_&BfySOxE!(~PI$*dwG><+-%KT5p?whOUMA*k<9*gi#T{h3DAxzAPxN&Xws8o9Cp*`PA5>d9*Z-ynV# z9yY*1WR^D8|C%I@vo+d8r^pjJ$>eo|j>XiLWvTWLl(^;JHCsoPgem6PvegHb-OTf| zvTgsHSa;BkbG=(NgPO|CZu9gUCGr$8*EoH2_Z#^BnxF0yM~t`|9ws_xZ8X8iZYqh! zAh;HXJ)3P&)Q0(&F>!LN0g#bdbis-cQxyGn9Qgh`q+~49Fqd2epikEUw9caM%V6WgP)532RMRW}8gNS%V%Hx7apSz}tn@bQy!<=lbhmAH=FsMD?leawbnP5BWM0 z5{)@EEIYMu5;u)!+HQWhQ;D3_Cm_NADNeb-f56}<{41aYq8p4=93d=-=q0Yx#knGYfXVt z+kMxlus}t2T5FEyCN~!}90O_X@@PQpuy;kuGz@bWft%diBTx?d)_xWd_-(!LmVrh**oKg!1CNF&LX4{*j|) zIvjCR0I2UUuuEXh<9}oT_zT#jOrJAHNLFT~Ilh9hGJPI1<5`C-WA{tUYlyMeoy!+U zhA#=p!u1R7DNg9u4|QfED-2TuKI}>p#2P9--z;Bbf4Op*;Q9LCbO&aL2i<0O$ByoI z!9;Ght733FC>Pz>$_mw(F`zU?`m@>gE`9_p*=7o=7av`-&ifU(^)UU`Kg3Kw`h9-1 z6`e6+im=|m2v`pN(2dE%%n8YyQz;#3Q-|x`91z?gj68cMrHl}C25|6(_dIGk*8cA3 zRHB|Nwv{@sP4W+YZM)VKI>RlB`n=Oj~Rzx~M+Khz$N$45rLn6k1nvvD^&HtsMA4`s=MmuOJID@$s8Ph4E zAmSV^+s-z8cfv~Yd(40Sh4JG#F~aB>WFoX7ykaOr3JaJ&Lb49=B8Vk-SQT9%7TYhv z?-Pprt{|=Y5ZQ1?od|A<_IJU93|l4oAfBm?3-wk{O<8ea+`}u%(kub(LFo2zFtd?4 zwpN|2mBNywv+d^y_8#<$r>*5+$wRTCygFLcrwT(qc^n&@9r+}Kd_u@Ithz(6Qb4}A zWo_HdBj#V$VE#l6pD0a=NfB0l^6W^g`vm^sta>Tly?$E&{F?TTX~DsKF~poFfmN%2 z4x`Dc{u{Lkqz&y!33;X}weD}&;7p>xiI&ZUb1H9iD25a(gI|`|;G^NwJPv=1S5e)j z;U;`?n}jnY6rA{V^ zxTd{bK)Gi^odL3l989DQlN+Zs39Xe&otGeY(b5>rlIqfc7Ap4}EC?j<{M=hlH{1+d zw|c}}yx88_xQr`{98Z!d^FNH77=u(p-L{W6RvIn40f-BldeF-YD>p6#)(Qzf)lfZj z?3wAMtPPp>vMehkT`3gToPd%|D8~4`5WK{`#+}{L{jRUMt zrFz+O$C7y8$M&E4@+p+oV5c%uYzbqd2Y%SSgYy#xh4G3hQv>V*BnuKQhBa#=oZB~w{azUB+q%bRe_R^ z>fHBilnRTUfaJ201czL8^~Ix#+qOHSO)A|xWLqOxB$dT2W~)e-r9;bm=;p;RjYahB z*1hegN(VKK+ztr~h1}YP@6cfj{e#|sS`;3tJhIJK=tVJ-*h-5y9n*&cYCSdg#EHE# zSIx=r#qOaLJoVVf6v;(okg6?*L_55atl^W(gm^yjR?$GplNP>BZsBYEf_>wM0Lc;T zhf&gpzOWNxS>m+mN92N0{;4uw`P+9^*|-1~$uXpggj4- z^SFc4`uzj2OwdEVT@}Q`(^EcQ_5(ZtXTql*yGzdS&vrS_w>~~ra|Nb5abwf}Y!uq6R5f&6g2ge~2p(%c< z@O)cz%%rr4*cRJ5f`n@lvHNk@lE1a*96Kw6lJ~B-XfJW%?&-y?;E&?1AacU@`N`!O z6}V>8^%RZ7SQnZ-z$(jsX`amu*5Fj8g!3RTRwK^`2_QHe;_2y_n|6gSaGyPmI#kA0sYV<_qOZc#-2BO%hX)f$s-Z3xlI!ub z^;3ru11DA`4heAu%}HIXo&ctujzE2!6DIGE{?Zs>2}J+p&C$rc7gJC35gxhflorvsb%sGOxpuWhF)dL_&7&Z99=5M0b~Qa;Mo!j&Ti_kXW!86N%n= zSC@6Lw>UQ__F&+&Rzv?gscwAz8IP!n63>SP)^62(HK98nGjLY2*e^OwOq`3O|C92? z;TVhZ2SK%9AGW4ZavTB9?)mUbOoF`V7S=XM;#3EUpR+^oHtdV!GK^nXzCu>tpR|89 zdD{fnvCaN^^LL%amZ^}-E+214g&^56rpdc@yv0b<3}Ys?)f|fXN4oHf$six)-@<;W&&_kj z-B}M5U*1sb4)77aR=@%I?|Wkn-QJVuA96an25;~!gq(g1@O-5VGo7y&E_srxL6ZfS z*R%$gR}dyONgju*D&?geiSj7SZ@ftyA|}(*Y4KbvU!YLsi1EDQQCnb+-cM=K1io78o!v*);o<XwjaQH%)uIP&Zm?)Nfbfn;jIr z)d#!$gOe3QHp}2NBak@yYv3m(CPKkwI|{;d=gi552u?xj9ObCU^DJFQp4t4e1tPzM zvsRIGZ6VF+{6PvqsplMZWhz10YwS={?`~O0Ec$`-!klNUYtzWA^f9m7tkEzCy<_nS z=&<(awFeZvt51>@o_~>PLs05CY)$;}Oo$VDO)?l-{CS1Co=nxjqben*O1BR>#9`0^ zkwk^k-wcLCLGh|XLjdWv0_Hg54B&OzCE^3NCP}~OajK-LuRW53CkV~Su0U>zN%yQP zH8UH#W5P3-!ToO-2k&)}nFe`t+mdqCxxAHgcifup^gKpMObbox9LFK;LP3}0dP-UW z?Zo*^nrQ6*$FtZ(>kLCc2LY*|{!dUn$^RW~m9leoF|@Jy|M5p-G~j%+P0_#orRKf8 zvuu5<*XO!B?1E}-*SY~MOa$6c%2cM+xa8}_8x*aVn~57v&W(0mqN1W`5a7*VN{SUH zXz98DDyCnX2EPl-`Lesf`=AQT%YSDb`$%;(jUTrNen$NPJrlpPDP}prI>Ml!r6bCT;mjsg@X^#&<}CGf0JtR{Ecwd&)2zuhr#nqdgHj+g2n}GK9CHuwO zk>oZxy{vcOL)$8-}L^iVfJHAGfwN$prHjYV0ju}8%jWquw>}_W6j~m<}Jf!G?~r5&Rx)!9JNX!ts#SGe2HzobV5); zpj@&`cNcO&q+%*<%D7za|?m5qlmFK$=MJ_iv{aRs+BGVrs)98BlN^nMr{V_fcl_;jkzRju+c-y?gqBC_@J0dFLq-D9@VN&-`R9U;nv$Hg?>$oe4N&Ht$V_(JR3TG^! zzJsbQbi zFE6-{#9{G{+Z}ww!ycl*7rRdmU#_&|DqPfX3CR1I{Kk;bHwF6jh0opI`UV2W{*|nn zf_Y@%wW6APb&9RrbEN=PQRBEpM(N1w`81s=(xQj6 z-eO0k9=Al|>Ej|Mw&G`%q8e$2xVz1v4DXAi8G};R$y)ww638Y=9y$ZYFDM$}vzusg zUf+~BPX>(SjA|tgaFZr_e0{)+z9i6G#lgt=F_n$d=beAt0Sa0a7>z-?vcjl3e+W}+ z1&9=|vC=$co}-Zh*%3588G?v&U7%N1Qf-wNWJ)(v`iO5KHSkC5&g7CrKu8V}uQGcfcz zmBz#Lbqwqy#Z~UzHgOQ;Q-rPxrRNvl(&u6ts4~0=KkeS;zqURz%!-ERppmd%0v>iRlEf+H$yl{_8TMJzo0 z>n)`On|7=WQdsqhXI?#V{>+~}qt-cQbokEbgwV3QvSP7&hK4R{Z{aGHVS3;+h{|Hz z6$Js}_AJr383c_+6sNR|$qu6dqHXQTc6?(XWPCVZv=)D#6_;D_8P-=zOGEN5&?~8S zl5jQ?NL$c%O)*bOohdNwGIKM#jSAC?BVY={@A#c9GmX0=T(0G}xs`-%f3r=m6-cpK z!%waekyAvm9C3%>sixdZj+I(wQlbB4wv9xKI*T13DYG^T%}zZYJ|0$Oj^YtY+d$V$ zAVudSc-)FMl|54n=N{BnZTM|!>=bhaja?o7s+v1*U$!v!qQ%`T-6fBvmdPbVmro&d zk07TOp*KuxRUSTLRrBj{mjsnF8`d}rMViY8j`jo~Hp$fkv9F_g(jUo#Arp;Xw0M$~ zRIN!B22~$kx;QYmOkos@%|5k)!QypDMVe}1M9tZfkpXKGOxvKXB!=lo`p?|R1l=tA zp(1}c6T3Fwj_CPJwVsYtgeRKg?9?}%oRq0F+r+kdB=bFUdVDRPa;E~~>2$w}>O>v=?|e>#(-Lyx?nbg=ckJ#5U6;RT zNvHhXk$P}m9wSvFyU3}=7!y?Y z=fg$PbV8d7g25&-jOcs{%}wTDKm>!Vk);&rr;O1nvO0VrU&Q?TtYVU=ir`te8SLlS zKSNmV=+vF|ATGg`4$N1uS|n??f}C_4Sz!f|4Ly8#yTW-FBfvS48Tef|-46C(wEO_%pPhUC5$-~Y?!0vFZ^Gu`x=m7X99_?C-`|h zfmMM&Y@zdfitA@KPw4Mc(YHcY1)3*1xvW9V-r4n-9ZuBpFcf{yz+SR{ zo$ZSU_|fgwF~aakGr(9Be`~A|3)B=9`$M-TWKipq-NqRDRQc}ABo*s_5kV%doIX7LRLRau_gd@Rd_aLFXGSU+U?uAqh z8qusWWcvgQ&wu{|sRXmv?sl=xc<$6AR$+cl& zFNh5q1~kffG{3lDUdvEZu5c(aAG~+64FxdlfwY^*;JSS|m~CJusvi-!$XR`6@XtY2 znDHSz7}_Bx7zGq-^5{stTRy|I@N=>*y$zz>m^}^{d&~h;0kYiq8<^Wq7Dz0w31ShO^~LUfW6rfitR0(=3;Uue`Y%y@ex#eKPOW zO~V?)M#AeHB2kovn1v=n^D?2{2jhIQd9t|_Q+c|ZFaWt+r&#yrOu-!4pXAJuxM+Cx z*H&>eZ0v8Y`t}8{TV6smOj=__gFC=eah)mZt9gwz>>W$!>b3O;Rm^Ig*POZP8Rl0f zT~o=Nu1J|lO>}xX&#P58%Yl z83`HRs5#32Qm9mdCrMlV|NKNC+Z~ z9OB8xk5HJ>gBLi+m@(pvpw)1(OaVJKs*$Ou#@Knd#bk+V@y;YXT?)4eP9E5{J%KGtYinNYJUH9PU3A}66c>Xn zZ{Bn0<;8$WCOAL$^NqTjwM?5d=RHgw3!72WRo0c;+houoUA@HWLZM;^U$&sycWrFd zE7ekt9;kb0`lps{>R(}YnXlyGY}5pPd9zBpgXeJTY_jwaJGSJQC#-KJqmh-;ad&F- z-Y)E>!&`Rz!HtCz>%yOJ|v(u7P*I$jqEY3}(Z-orn4 zlI?CYKNl`6I){#2P1h)y(6?i;^z`N3bxTV%wNvQW+eu|x=kbj~s8rhCR*0H=iGkSj zk23lr9kr|p7#qKL=UjgO`@UnvzU)`&fI>1Qs7ubq{@+lK{hH* zvl6eSb9%yngRn^T<;jG1SVa)eA>T^XX=yUS@NCKpk?ovCW1D@!=@kn;l_BrG;hOTC z6K&H{<8K#dI(A+zw-MWxS+~{g$tI7|SfP$EYKxA}LlVO^sT#Oby^grkdZ^^lA}uEF zBSj$weBJG{+Bh@Yffzsw=HyChS(dtLE3i*}Zj@~!_T-Ay7z=B)+*~3|?w`Zd)Co2t zC&4DyB!o&YgSw+fJn6`sn$e)29`kUwAc+1MND7YjV%lO;H2}fNy>hD#=gT ze+-aFNpyKIoXY~Vq-}OWPBe?Rfu^{ps8>Xy%42r@RV#*QV~P83jdlFNgkPN=T|Kt7 zV*M`Rh*30&AWlb$;ae130e@}Tqi3zx2^JQHpM>j$6x`#{mu%tZlwx9Gj@Hc92IuY* zarmT|*d0E~vt6<+r?W^UW0&#U&)8B6+1+;k^2|FWBRP9?C4Rk)HAh&=AS8FS|NQaZ z2j!iZ)nbEyg4ZTp-zHwVlfLC~tXIrv(xrP8PAtR{*c;T24ycA-;auWsya-!kF~CWZ zw_uZ|%urXgUbc@x=L=_g@QJ@m#5beS@6W195Hn7>_}z@Xt{DIEA`A&V82bc^#!q8$ zFh?z_Vn|ozJ;NPd^5uu(9tspo8t%&-U9Ckay-s@DnM*R5rtu|4)~e)`z0P-sy?)kc zs_k&J@0&0!q4~%cKL)2l;N*T&0;mqX5T{Qy60%JtKTQZ-xb%KOcgqwJmb%MOOKk7N zgq})R_6**{8A|6H?fO+2`#QU)p$Ei2&nbj6TpLSIT^D$|`TcSeh+)}VMb}LmvZ{O| ze*1IdCt3+yhdYVxcM)Q_V0bIXLgr6~%JS<<&dxIgfL=Vnx4YHuU@I34JXA|+$_S3~ zy~X#gO_X!cSs^XM{yzDGNM>?v(+sF#<0;AH^YrE8smx<36bUsHbN#y57K8WEu(`qHvQ6cAZPo=J5C(lSmUCZ57Rj6cx!e^rfaI5%w}unz}4 zoX=nt)FVNV%QDJH`o!u9olLD4O5fl)xp+#RloZlaA92o3x4->?rB4`gS$;WO{R;Z3>cG3IgFX2EA?PK^M}@%1%A;?f6}s&CV$cIyEr#q5;yHdNZ9h{| z-=dX+a5elJoDo?Eq&Og!nN6A)5yYpnGEp}?=!C-V)(*~z-+?kY1Q7qs#Rsy%hu_60rdbB+QQNr?S1 z?;xtjUv|*E3}HmuNyB9aFL5H~3Ho0UsmuMZELp1a#CA1g`P{-mT?BchuLEtK}!QZ=3AWakRu~?f9V~3F;TV`5%9Pcs_$gq&CcU}r8gOO zC2&SWPsSG{&o-LIGTBqp6SLQZPvYKp$$7L4WRRZ0BR$Kf0I0SCFkqveCp@f)o8W)! z$%7D1R`&j7W9Q9CGus_)b%+B#J2G;l*FLz#s$hw{BHS~WNLODV#(!u_2Pe&tMsq={ zdm7>_WecWF#D=?eMjLj=-_z`aHMZ=3_-&E8;ibPmM}61i6J3is*=dKf%HC>=xbj4$ zS|Q-hWQ8T5mWde6h@;mS+?k=89?1FU<%qH9B(l&O>k|u_aD|DY*@~(`_pb|B#rJ&g zR0(~(68fpUPz6TdS@4JT5MOPrqDh5_H(eX1$P2SQrkvN8sTxwV>l0)Qq z0pzTuvtEAKRDkKGhhv^jk%|HQ1DdF%5oKq5BS>szk-CIke{%js?~%@$uaN3^Uz6Wf z_iyx{bZ(;9y4X&>LPV=L=d+A}7I4GkK0c1Xts{rrW1Q7apHf-))`BgC^0^F(>At1* za@e7{lq%yAkn*NH8Q1{@{lKhRg*^TfGvv!Sn*ed*x@6>M%aaqySxR|oNadYt1mpUZ z6H(rupHYf&Z z29$5g#|0MX#aR6TZ$@eGxxABRKakDYtD%5BmKp;HbG_ZbT+=81E&=XRk6m_3t9PvD zr5Cqy(v?gHcYvYvXkNH@S#Po~q(_7MOuCAB8G$a9BC##gw^5mW16cML=T=ERL7wsk zzNEayTG?mtB=x*wc@ifBCJ|irFVMOvH)AFRW8WE~U()QT=HBCe@s$dA9O!@`zAAT) zaOZ7l6vyR+Nk_OOF!ZlZmjoImKh)dxFbbR~z(cMhfeX1l7S_`;h|v3gI}n9$sSQ>+3@AFAy9=B_y$)q;Wdl|C-X|VV3w8 z2S#>|5dGA8^9%Bu&fhmVRrTX>Z7{~3V&0UpJNEl0=N32euvDGCJ>#6dUSi&PxFW*s zS`}TB>?}H(T2lxBJ!V#2taV;q%zd6fOr=SGHpoSG*4PDaiG0pdb5`jelVipkEk%FV zThLc@Hc_AL1#D&T4D=w@UezYNJ%0=f3iVRuVL5H?eeZM}4W*bomebEU@e2d`M<~uW zf#Bugwf`VezG|^Qbt6R_=U0}|=k;mIIakz99*>FrsQR{0aQRP6ko?5<7bkDN8evZ& zB@_KqQG?ErKL=1*ZM9_5?Pq%lcS4uLSzN(Mr5=t6xHLS~Ym`UgM@D&VNu8e?_=nSFtF$u@hpPSmI4Vo_t&v?>$~K4y(O~Rb*(MFy_igM7 z*~yYUyR6yQgzWnWMUgDov!!g=lInM+=lOmOk4L`O?{i&qxy&D*_qorRbDwj6?)!ef z#JLd7F6Z2I$S0iYI={rZNk*<{HtIl^mx=h>Cim*04K4+Z4IJtd*-)%6XV2(MCscPiw_a+y*?BKbTS@BZ3AUao^%Zi#PhoY9Vib4N>SE%4>=Jco0v zH_Miey{E;FkdlZSq)e<{`+S3W=*ttvD#hB8w=|2aV*D=yOV}(&p%0LbEWH$&@$X3x~CiF-?ejQ*N+-M zc8zT@3iwkdRT2t(XS`d7`tJQAjRmKAhiw{WOqpuvFp`i@Q@!KMhwKgsA}%@sw8Xo5Y=F zhRJZg)O4uqNWj?V&&vth*H#je6T}}p_<>!Dr#89q@uSjWv~JuW(>FqoJ5^ho0%K?E z9?x_Q;kmcsQ@5=}z@tdljMSt9-Z3xn$k)kEjK|qXS>EfuDmu(Z8|(W?gY6-l z@R_#M8=vxKMAoi&PwnaIYw2COJM@atcgfr=zK1bvjW?9B`-+Voe$Q+H$j!1$Tjn+* z&LY<%)L@;zhnJlB^Og6I&BOR-m?{IW;tyYC%FZ!&Z>kGjHJ6cqM-F z&19n+e1=9AH1VrVeHrIzqlC`w9=*zfmrerF?JMzO&|Mmv;!4DKc(sp+jy^Dx?(8>1 zH&yS_4yL7m&GWX~mdfgH*AB4{CKo;+egw=PrvkTaoBU+P-4u?E|&!c z)DKc;>$$B6u*Zr1SjUh2)FeuWLWHl5TH(UHWkf zLs>7px!c5n;rbe^lO@qlYLzlDVp(z?6rPZel=YB)Uv&n!2{+Mb$-vQl=xKw( zve&>xYx+jW_NJh!FV||r?;hdP*jOXYcLCp>DOtJ?2S^)DkM{{Eb zS$!L$e_o0(^}n3tA1R3-$SNvgBq;DOEo}fNc|tB%%#g4RA3{|euq)p+xd3I8^4E&m zFrD%}nvG^HUAIKe9_{tXB;tl|G<%>yk6R;8L2)KUJw4yHJXUOPM>(-+jxq4R;z8H#>rnJy*)8N+$wA$^F zN+H*3t)eFEgxLw+Nw3};4WV$qj&_D`%ADV2%r zJCPCo%{=z7;`F98(us5JnT(G@sKTZ^;2FVitXyLe-S5(hV&Ium+1pIUB(CZ#h|g)u zSLJJ<@HgrDiA-}V_6B^x1>c9B6%~847JkQ!^KLZ2skm;q*edo;UA)~?SghG8;QbHh z_6M;ouo_1rq9=x$<`Y@EA{C%6-pEV}B(1#sDoe_e1s3^Y>n#1Sw;N|}8D|s|VPd+g z-_$QhCz`vLxxrVMx3ape1xu3*wjx=yKSlM~nFgkNWb4?DDr*!?U)L_VeffF<+!j|b zZ$Wn2$TDv3C3V@BHpSgv3JUif8%hk%OsGZ=OxH@8&4`bbf$`aAMchl^qN>Eyu3JH} z9-S!x8-s4fE=lad%Pkp8hAs~u?|uRnL48O|;*DEU! zuS0{cpk%1E0nc__2%;apFsTm0bKtd&A0~S3Cj^?72-*Owk3V!ZG*PswDfS~}2<8le z5+W^`Y(&R)yVF*tU_s!XMcJS`;(Tr`J0%>p=Z&InR%D3@KEzzI+-2)HK zuoNZ&o=wUC&+*?ofPb0a(E6(<2Amd6%uSu_^-<1?hsxs~0K5^f(LsGqgEF^+0_H=uNk9S0bb!|O8d?m5gQjUKevPaO+*VfSn^2892K~%crWM8+6 z25@V?Y@J<9w%@NXh-2!}SK_(X)O4AM1-WTg>sj1{lj5@=q&dxE^9xng1_z9w9DK>| z6Iybcd0e zyi;Ew!KBRIfGPGytQ6}z}MeXCfLY0?9%RiyagSp_D1?N&c{ zyo>VbJ4Gy`@Fv+5cKgUgs~na$>BV{*em7PU3%lloy_aEovR+J7TfQKh8BJXyL6|P8un-Jnq(ghd!_HEOh$zlv2$~y3krgeH;9zC}V3f`uDtW(%mT#944DQa~^8ZI+zAUu4U(j0YcDfKR$bK#gvn_{JZ>|gZ5+)u?T$w7Q%F^;!Wk?G z(le7r!ufT*cxS}PR6hIVtXa)i`d$-_1KkyBU>qmgz-=T};uxx&sKgv48akIWQ89F{ z0XiY?WM^~;|T8zBOr zs#zuOONzH?svv*jokd5SK8wG>+yMC)LYL|vLqm^PMHcT=`}V$=nIRHe2?h)8WQa6O zPAU}d`1y(>kZiP~Gr=mtJLMu`i<2CspL|q2DqAgAD^7*$xzM`PU4^ga`ilE134XBQ z99P(LhHU@7qvl9Yzg$M`+dlS=x^(m-_3t|h>S}E0bcFMn=C|KamQ)=w2^e)35p`zY zRV8X?d;s^>Cof2SPR&nP3E+-LCkS0J$H!eh8~k0qo$}00b=7!H_I2O+Ro@3O$nPdm ztmbOO^B+IHzQ5w>@@@J4cKw5&^_w6s!s=H%&byAbUtczPQ7}wfTqxxtQNfn*u73Qw zGuWsrky_ajPx-5`R<)6xHf>C(oqGf_Fw|-U*GfS?xLML$kv;h_pZ@Kk$y0X(S+K80 z6^|z)*`5VUkawg}=z`S;VhZhxyDfrE0$(PMurAxl~<>lfZa>JZ288ULK7D` zl9|#L^JL}Y$j*j`0-K6kH#?bRmg#5L3iB4Z)%iF@SqT+Lp|{i`m%R-|ZE94Np7Pa5 zCqC^V3}B(FR340pmF*qaa}M}+h6}mqE~7Sh!9bDv9YRT|>vBNAqv09zXHMlcuhKD| zcjjA(b*XCIwJ33?CB!+;{)vX@9xns_b-VO{i0y?}{!sdXj1GM8+$#v>W7nw;+O_9B z_{4L;C6ol?(?W0<6taGEn1^uG=?Q3i29sE`RfYCaV$3DKc_;?HsL?D_fSYg}SuO5U zOB_f4^vZ_x%o`5|C@9C5+o=mFy@au{s)sKw!UgC&L35aH(sgDxRE2De%(%OT=VUdN ziVLEmdOvJ&5*tCMKRyXctCwQu_RH%;m*$YK&m;jtbdH#Ak~13T1^f89tn`A%QEHWs~jnY~E}p_Z$XC z=?YXLCkzVSK+Id`xZYTegb@W8_baLt-Fq`Tv|=)JPbFsKRm)4UW;yT+J`<)%#ue9DPOkje)YF2fsCilK9MIIK>p*`fkoD5nGfmLwt)!KOT+> zOFq*VZktDDyM3P5UOg`~XL#cbzC}eL%qMB=Q5$d89MKuN#$6|4gx_Jt0Gfn8w&q}%lq4QU%6#jT*MRT% zrLz~C8FYKHawn-EQWN1B75O&quS+Z81(zN)G>~vN8VwC+e+y(`>HcxC{MrJ;H1Z4k zZWuv$w_F0-Ub%MVcpIc){4PGL^I7M{>;hS?;eH!;gmcOE66z3;Z1Phqo(t zVP(Hg6q#0gIKgsg7L7WE!{Y#1nI(45tx2{$34dDd#!Z0NIyrm)HOn5W#7;f4pQci# zDW!FI(g4e668kI9{2+mLwB+=#9bfqgX%!B34V-$wwSN(_cm*^{y0jQtv*4}eO^sOV z*9xoNvX)c9isB}Tgx&ZRjp3kwhTVK?r9;n!x>^XYT z@Q^7zp{rkIs{2mUSE^2!Gf6$6;j~&4=-0cSJJDizZp6LTe8b45;{AKM%v99}{{FfC zz709%u0mC=1KXTo(=TqmZQ;c?$M3z(!xah>aywrj40sc2y3rKFw4jCq+Y+u=CH@_V zxz|qeTwa>+<|H%8Dz5u>ZI5MmjTFwXS-Fv!TDd*`>3{krWoNVx$<133`(ftS?ZPyY z&4@ah^3^i`vL$BZa>O|Nt?ucewzsF)0zX3qmM^|waXr=T0pfIb0*$AwU=?Ipl|1Y; z*Pk6{C-p4MY;j@IJ|DW>QHZQJcp;Z~?8(Q+Kk3^0qJ}SCk^*n4W zu9ZFwLHUx-$6xvaQ)SUQcYd6fF8&x)V`1bIuX@>{mE$b|Yd(qomn3;bPwnDUc0F=; zh*6_((%bqAYQWQ~odER?h>1mkL4kpb3s7`0m@rDKGU*oyF)$j~Ffd4fXV$?`f~rHf zB%Y)@5SXZvfwm10RY5X?TEo)PK_`L6qgBp=#>fO49$D zDq8Ozj0q6213tV5Qq=;fZ0$|KroY{Dz=l@lU^J)?Ko@ti20TRplXzphBi>XGx4bou zEWrkNjz0t5j!_ke{g5I#PUlEU$Km8g8TE|XK=MkU@PT4T><2OVamoK;wJ}3X0L$vX zgd7gNa359*nc)R-0!`2X@FOTB`+oETOPc=ubp5R)VQgY+5BTZZJ2?9QwnO=dnulIUF3gFn;BODC2)65)HeVd%t86sL7Rv^Y+nbn+&l z6BAJY(ETvwI)Ts$aiE8rht4KD*qNyE{8{x6R|%akbTBzw;2+6Echkt+W+`u^XX z_z&x%n '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/engine/gradlew.bat b/engine/gradlew.bat new file mode 100644 index 0000000000..25da30dbde --- /dev/null +++ b/engine/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/adapters/EntityAdapter/settings.gradle.kts b/engine/settings.gradle.kts similarity index 54% rename from adapters/EntityAdapter/settings.gradle.kts rename to engine/settings.gradle.kts index 6e0d9d2aee..44dd01f3c0 100644 --- a/adapters/EntityAdapter/settings.gradle.kts +++ b/engine/settings.gradle.kts @@ -1,9 +1,8 @@ -rootProject.name = "EntityAdapter" - -includeBuild("../../plugin") +rootProject.name = "engine" plugins { id("com.gradle.enterprise") version ("3.13.3") + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } gradleEnterprise { @@ -12,3 +11,6 @@ gradleEnterprise { termsOfServiceAgree = "yes" } } +include("engine-paper") +include("engine-core") +include("engine-loader") diff --git a/extensions/BasicExtension/build.gradle.kts b/extensions/BasicExtension/build.gradle.kts new file mode 100644 index 0000000000..82a86c04ac --- /dev/null +++ b/extensions/BasicExtension/build.gradle.kts @@ -0,0 +1,24 @@ +repositories { } +dependencies { } + +typewriter { + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + namespace = "typewritermc" + + extension { + name = "Basic" + shortDescription = "For all the most basic entries" + description = """ + The Basic Extension contains all the essential entries for any server. + In most cases, it should be installed with Typewriter. + If you haven't installed Typewriter or the Basic Extension, + please follow the [Installation Guide](https://docs.typewritermc.com/docs/getting-started/installation) + first. + """.trimIndent() + + paper() + } +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/AddPotionEffectActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/AddPotionEffectActionEntry.kt similarity index 56% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/AddPotionEffectActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/AddPotionEffectActionEntry.kt index fb71874b64..6d8a7302fd 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/AddPotionEffectActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/AddPotionEffectActionEntry.kt @@ -1,22 +1,27 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.toTicks +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Default +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.toTicks import org.bukkit.entity.Player import org.bukkit.potion.PotionEffect import org.bukkit.potion.PotionEffectType import java.time.Duration -@Entry("add_potion_effect", "Add a potion effect to the player", Colors.RED, "fa6-solid:flask-vial") +@Entry( + "add_potion_effect", + "Add a potion effect to the player", + Colors.RED, + "fa6-solid:flask-vial" +) /** * The `Add Potion Effect Action` is an action that adds a potion effect to the player. * @@ -30,17 +35,16 @@ class AddPotionEffectActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The potion effect to add.") val potionEffect: PotionEffectType = PotionEffectType.SPEED, - @Help("The duration of the potion effect.") - val duration: Duration = Duration.ofSeconds(1), - @Help("The amplifier of the potion effect.") + @Default("10000") + val duration: Duration = Duration.ofSeconds(10), + @Default("1") val amplifier: Int = 1, - @Help("Whether or not the effect is ambient") val ambient: Boolean = false, - @Help("Whether or not to show the potion effect particles.") + @Default("true") val particles: Boolean = true, @Help("Whether or not to show the potion effect icon in the player's inventory.") + @Default("true") val icon: Boolean = true, ) : ActionEntry { override fun execute(player: Player) { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ApplyVelocityActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ApplyVelocityActionEntry.kt similarity index 63% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ApplyVelocityActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ApplyVelocityActionEntry.kt index 2050f53ca0..1bf322791c 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ApplyVelocityActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ApplyVelocityActionEntry.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Vector +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.toBukkitVector import org.bukkit.entity.Player @Entry("apply_velocity", "Apply a velocity to the player", Colors.RED, "fa-solid:wind") @@ -25,7 +25,6 @@ class ApplyVelocityActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The force to apply to the player.") val force: Vector = Vector(0.0, 0.0, 0.0), ) : ActionEntry { override fun execute(player: Player) { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/CinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/CinematicEntry.kt similarity index 62% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/CinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/CinematicEntry.kt index ffb03ed9a7..f8a6331c04 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/CinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/CinematicEntry.kt @@ -1,13 +1,18 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Page -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.CinematicStartTrigger -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.books.pages.PageType +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Page +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.CinematicStartTrigger +import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry import org.bukkit.entity.Player diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ConsoleCommandActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ConsoleCommandActionEntry.kt similarity index 58% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ConsoleCommandActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ConsoleCommandActionEntry.kt index 37062d914c..46f907c92b 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ConsoleCommandActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ConsoleCommandActionEntry.kt @@ -1,18 +1,18 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import lirand.api.extensions.server.commands.dispatchCommand -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import lirand.api.extensions.server.server import org.bukkit.Bukkit import org.bukkit.entity.Player @@ -32,8 +32,7 @@ class ConsoleCommandActionEntry( override val triggers: List> = emptyList(), @Placeholder @MultiLine - @Help("The command(s) to run.") - // Every line is a different command. Commands should not be prefixed with /. + @Help("Every line is a different command. Commands should not be prefixed with /.") private val command: String = "", ) : ActionEntry { override fun execute(player: Player) { @@ -42,7 +41,7 @@ class ConsoleCommandActionEntry( SYNC.launch { val commands = command.parsePlaceholders(player).lines() for (cmd in commands) { - Bukkit.getConsoleSender().dispatchCommand(cmd) + server.dispatchCommand(Bukkit.getConsoleSender(), cmd) } } } diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DelayedActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DelayedActionEntry.kt similarity index 64% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DelayedActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DelayedActionEntry.kt index 0f5b82952d..3043a32232 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DelayedActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DelayedActionEntry.kt @@ -1,18 +1,16 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.google.gson.annotations.SerializedName import kotlinx.coroutines.delay -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC -import me.gabber235.typewriter.utils.ThreadType.SYNC +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry +import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC import org.bukkit.entity.Player import java.time.Duration @@ -32,8 +30,7 @@ class DelayedActionEntry( override val modifiers: List = emptyList(), @SerializedName("triggers") override val customTriggers: List> = emptyList(), - @Help("The time to delay the action for.") - // The duration before the next triggers are fired. + @Help("The duration before the next triggers are fired.") private val duration: Duration = Duration.ZERO, ) : CustomTriggeringActionEntry { diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DropItemActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DropItemActionEntry.kt new file mode 100644 index 0000000000..f7b6897f3f --- /dev/null +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/DropItemActionEntry.kt @@ -0,0 +1,52 @@ +package com.typewritermc.basic.entries.action + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.Item +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.toBukkitLocation +import org.bukkit.entity.Player +import java.util.* + +@Entry("drop_item", "Drop an item at location, or on player", Colors.RED, "fa-brands:dropbox") +/** + * The `Drop Item Action` is an action that drops an item in the world. + * This action provides you with the ability to drop an item with a specified Minecraft material, amount, display name, lore, and location. + * + * ## How could this be used? + * + * This action can be useful in a variety of situations. + * You can use it to create treasure chests with randomized items, drop loot from defeated enemies, or spawn custom items in the world. + * The possibilities are endless! + */ +class DropItemActionEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List, + override val modifiers: List, + override val triggers: List> = emptyList(), + val item: Item = Item.Empty, + @Help("The location to drop the item. (Defaults to the player's location)") + private val location: Optional = Optional.empty(), +) : ActionEntry { + override fun execute(player: Player) { + super.execute(player) + // Run on main thread + SYNC.launch { + if (location.isPresent) { + val position = location.get() + val bukkitLocation = position.toBukkitLocation() + bukkitLocation.world.dropItem(bukkitLocation, item.build(player)) + } else { + player.location.world.dropItem(player.location, item.build(player)) + } + } + } +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/FireworkActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/FireworkActionEntry.kt similarity index 70% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/FireworkActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/FireworkActionEntry.kt index f2e6ae8095..2e67092f2d 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/FireworkActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/FireworkActionEntry.kt @@ -1,26 +1,24 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityStatus -import lirand.api.extensions.inventory.meta -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toPacketItem -import me.gabber235.typewriter.extensions.packetevents.toPacketLocation -import me.gabber235.typewriter.utils.Color +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.extensions.packetevents.toPacketItem +import com.typewritermc.engine.paper.utils.Color +import com.typewritermc.engine.paper.utils.toPacketLocation import me.tofaa.entitylib.EntityLib import me.tofaa.entitylib.meta.Metadata import me.tofaa.entitylib.meta.other.FireworkRocketMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.FireworkEffect -import org.bukkit.Location import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack @@ -42,21 +40,19 @@ class FireworkActionEntry( override val triggers: List> = emptyList(), override val criteria: List = emptyList(), override val modifiers: List = emptyList(), - @Help("The location to spawn the firework.") - val location: Location = Location(null, 0.0, 0.0, 0.0), - @Help("The effects to display on the firework.") + val location: Position = Position.ORIGIN, val effects: List = emptyList(), - @Help("The power of the firework.") val power: Int = 0, ) : ActionEntry { override fun execute(player: Player) { super.execute(player) - val item = ItemStack(Material.FIREWORK_ROCKET).meta { + val item = ItemStack(Material.FIREWORK_ROCKET) + item.editMeta (FireworkMeta::class.java) { meta -> this@FireworkActionEntry.effects.forEach { effect -> - addEffect(effect.toBukkitEffect()) + meta.addEffect(effect.toBukkitEffect()) } - power = this@FireworkActionEntry.power + meta.power = this@FireworkActionEntry.power } val uuid = UUID.randomUUID() diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GiveItemActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GiveItemActionEntry.kt new file mode 100644 index 0000000000..f07096c960 --- /dev/null +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GiveItemActionEntry.kt @@ -0,0 +1,37 @@ +package com.typewritermc.basic.entries.action + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.Item +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import org.bukkit.entity.Player + +@Entry("give_item", "Give an item to the player", Colors.RED, "streamline:give-gift-solid") +/** + * The `Give Item Action` is an action that gives a player an item. This action provides you with the ability to give an item with a specified Minecraft material, amount, display name, and lore. + * + * ## How could this be used? + * + * This action can be useful in a variety of situations. You can use it to give players rewards for completing quests, unlockables for reaching certain milestones, or any other custom items you want to give players. The possibilities are endless! + */ +class GiveItemActionEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List, + override val modifiers: List, + override val triggers: List> = emptyList(), + val item: Item = Item.Empty, +) : ActionEntry { + override fun execute(player: Player) { + super.execute(player) + + SYNC.launch { + player.inventory.addItem(item.build(player)) + } + } +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GroupTriggerActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GroupTriggerActionEntry.kt similarity index 73% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GroupTriggerActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GroupTriggerActionEntry.kt index fd13b9c7ff..69d63ae80f 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GroupTriggerActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/GroupTriggerActionEntry.kt @@ -1,13 +1,17 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.GroupId import org.bukkit.entity.Player import java.util.* diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/MessageActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/MessageActionEntry.kt similarity index 67% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/MessageActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/MessageActionEntry.kt index acd86bbd6e..5bd66c0191 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/MessageActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/MessageActionEntry.kt @@ -1,17 +1,19 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.dialogue.playSpeakerSound -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.sendMiniWithResolvers +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.* +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.dialogue.playSpeakerSound +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.sendMiniWithResolvers import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed import org.bukkit.entity.Player @@ -40,9 +42,7 @@ class MessageActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The speaker of the message") val speaker: Ref = emptyRef(), - @Help("The message to send") @Placeholder @MultiLine val message: String = "", diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlaySoundActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlaySoundActionEntry.kt new file mode 100644 index 0000000000..91b85ece57 --- /dev/null +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlaySoundActionEntry.kt @@ -0,0 +1,35 @@ +package com.typewritermc.basic.entries.action + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.engine.paper.utils.playSound +import org.bukkit.entity.Player + +@Entry("play_sound", "Play sound at player, or location", Colors.RED, "fa6-solid:volume-high") +/** + * The `Play Sound Action` is an action that plays a sound for the player. This action provides you with the ability to play any sound that is available in Minecraft, at a specified location. + * + * ## How could this be used? + * + * This action can be useful in a variety of situations. You can use it to provide audio feedback to players, such as when they successfully complete a challenge, or to create ambiance in your Minecraft world, such as by playing background music or sound effects. The possibilities are endless! + */ +class PlaySoundActionEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + override val modifiers: List = emptyList(), + override val triggers: List> = emptyList(), + val sound: Sound = Sound.EMPTY, +) : ActionEntry { + override fun execute(player: Player) { + super.execute(player) + + player.playSound(sound) + } +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlayerCommandActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlayerCommandActionEntry.kt similarity index 60% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlayerCommandActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlayerCommandActionEntry.kt index 7728860b96..5dd6bf9559 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlayerCommandActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/PlayerCommandActionEntry.kt @@ -1,18 +1,18 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import lirand.api.extensions.server.commands.dispatchCommand -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import lirand.api.extensions.server.server import org.bukkit.entity.Player @Entry("player_run_command", "Make player run command", Colors.RED, "mingcute:terminal-fill") @@ -37,8 +37,7 @@ class PlayerCommandActionEntry( override val triggers: List> = emptyList(), @Placeholder @MultiLine - @Help("The command(s) to run.") - // Every line is a different command. Commands should not be prefixed with /. + @Help("Every line is a different command. Commands should not be prefixed with /.") private val command: String = "", ) : ActionEntry { override fun execute(player: Player) { @@ -47,7 +46,7 @@ class PlayerCommandActionEntry( SYNC.launch { val commands = command.parsePlaceholders(player).lines() for (cmd in commands) { - player.dispatchCommand(cmd) + server.dispatchCommand(player, cmd) } } } diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RandomTriggerGateEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/RandomTriggerGateEntry.kt similarity index 71% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RandomTriggerGateEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/RandomTriggerGateEntry.kt index b0cc2d12c5..50f736b131 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RandomTriggerGateEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/RandomTriggerGateEntry.kt @@ -1,11 +1,15 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry import org.bukkit.entity.Player @Entry("random_trigger", "Randomly selects its connected triggers", Colors.PINK, "mdi:clover") @@ -23,7 +27,7 @@ class RandomTriggerGateEntry( override val customTriggers: List> = emptyList(), override val criteria: List, override val modifiers: List, - @Help("The amount of triggers to fire.") + @Help("The number of triggers to fire next.") private val amount: Int = 1, ) : CustomTriggeringActionEntry { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RemoveItemActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/RemoveItemActionEntry.kt similarity index 64% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RemoveItemActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/RemoveItemActionEntry.kt index cb190ec829..af2419334c 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RemoveItemActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/RemoveItemActionEntry.kt @@ -1,16 +1,14 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.optional -import org.bukkit.Material +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.Item +import com.typewritermc.engine.paper.utils.ThreadType import org.bukkit.entity.Player import java.util.* @@ -35,7 +33,6 @@ class RemoveItemActionEntry( override val criteria: List, override val modifiers: List, override val triggers: List> = emptyList(), - @Help("The item to remove.") val item: Item = Item.Empty, ) : ActionEntry { override fun execute(player: Player) { @@ -68,26 +65,4 @@ class RemoveItemActionEntry( } } } -} - -@EntryMigration(RemoveItemActionEntry::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "amount", "itemName"]) -fun migrate040RemoveItemAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "amount", "itemName") - - val material = json.getAndParse("material", context.gson).optional - val amount = json.getAndParse("amount", context.gson).optional - val displayName = json.getAndParse>("itemName", context.gson).optional - - val item = Item( - material = material, - amount = amount, - name = displayName, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} - - +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetBlockActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SetBlockActionEntry.kt similarity index 60% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetBlockActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SetBlockActionEntry.kt index 30386c9db0..b6e90ce6fd 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetBlockActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SetBlockActionEntry.kt @@ -1,15 +1,15 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.toBukkitLocation import org.bukkit.Material import org.bukkit.entity.Player @@ -32,16 +32,15 @@ class SetBlockActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The material of the block to set.") val material: Material = Material.AIR, - @Help("The location to set the block at.") - val location: Location = Location(null, 0.0, 0.0, 0.0), + val location: Position = Position.ORIGIN, ) : ActionEntry { override fun execute(player: Player) { super.execute(player) SYNC.launch { - location.block.type = material + val bukkitLocation = location.toBukkitLocation() + bukkitLocation.block.type = material } } } \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetItemActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SetItemActionEntry.kt similarity index 56% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetItemActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SetItemActionEntry.kt index e026334f68..b8bc8d6bbc 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetItemActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SetItemActionEntry.kt @@ -1,16 +1,14 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.SYNC +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.Item +import com.typewritermc.engine.paper.utils.ThreadType.SYNC import org.bukkit.entity.Player @Entry("set_item", "Set an item in a specific slot", Colors.RED, "fluent:tray-item-add-24-filled") @@ -27,9 +25,7 @@ class SetItemActionEntry( override val criteria: List, override val modifiers: List, override val triggers: List> = emptyList(), - @Help("The item to set.") val item: Item = Item.Empty, - @Help("The slot to set the item in.") val slot: Int = 0, ) : ActionEntry { override fun execute(player: Player) { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ShowTitleActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ShowTitleActionEntry.kt similarity index 70% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ShowTitleActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ShowTitleActionEntry.kt index b37bf0921c..0c87604328 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ShowTitleActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/ShowTitleActionEntry.kt @@ -1,17 +1,17 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import net.kyori.adventure.title.Title import org.bukkit.entity.Player import java.time.Duration @@ -33,14 +33,11 @@ class ShowTitleActionEntry( override val triggers: List> = emptyList(), @Placeholder @Colored - @Help("The title text to show.") val title: String = "", @Placeholder @Colored - @Help("The subtitle text to show.") val subtitle: String = "", - @Help("Optional duration settings for the title.") - // Duration of the title: Fade in, how long it stays, fade out. + @Help("Optional duration settings for the title. Duration of the title: Fade in, how long it stays, fade out.") val durations: Optional = Optional.empty(), ) : ActionEntry { override fun execute(player: Player) { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SimpleActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SimpleActionEntry.kt similarity index 62% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SimpleActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SimpleActionEntry.kt index 656eb3e6df..5d0ce2f03e 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SimpleActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SimpleActionEntry.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry @Entry("simple_action", "Simple action to modify facts", Colors.RED, "heroicons:bolt-16-solid") /** diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SpawnParticleActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SpawnParticleActionEntry.kt similarity index 63% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SpawnParticleActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SpawnParticleActionEntry.kt index 3cc4dd5179..2e65ec1406 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SpawnParticleActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SpawnParticleActionEntry.kt @@ -1,15 +1,16 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Negative -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Negative +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.toBukkitLocation import org.bukkit.Particle import org.bukkit.entity.Player import java.util.* @@ -29,19 +30,14 @@ class SpawnParticleActionEntry( override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), @Help("The location to spawn the particles at. (Defaults to player's location)") - val location: Optional = Optional.empty(), - @Help("The particle to spawn.") + val location: Optional = Optional.empty(), val particle: Particle = Particle.FLAME, - @Help("The amount of particles to spawn.") val count: Int = 1, @Negative - @Help("The offset from the location on the X axis.") val offsetX: Double = 0.0, @Negative - @Help("The offset from the location on the Y axis.") val offsetY: Double = 0.0, @Negative - @Help("The offset from the location on the Z axis.") val offsetZ: Double = 0.0, @Help("The speed of the particles. For some particles, this is the \"extra\" data value to control particle behavior.") val speed: Double = 0.0, @@ -50,7 +46,8 @@ class SpawnParticleActionEntry( super.execute(player) if (location.isPresent) { - location.get().world?.spawnParticle(particle, location.get(), count, offsetX, offsetY, offsetZ, speed) + val bukkitLocation = location.get().toBukkitLocation() + bukkitLocation.world?.spawnParticle(particle, bukkitLocation, count, offsetX, offsetY, offsetZ, speed) } else { player.world.spawnParticle(particle, player.location, count, offsetX, offsetY, offsetZ, speed) } diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/StopSoundActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/StopSoundActionEntry.kt similarity index 65% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/StopSoundActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/StopSoundActionEntry.kt index fdeb3a8e06..bfc5992538 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/StopSoundActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/StopSoundActionEntry.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.SoundId +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.utils.SoundId import net.kyori.adventure.sound.SoundStop import org.bukkit.entity.Player import java.util.* @@ -28,8 +28,7 @@ class StopSoundActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The sound to stop.") - // The sound to stop. If this field is left blank, all sounds will be stopped. + @Help("The sound to stop. If this field is left blank, all sounds will be stopped.") val sound: Optional = Optional.empty(), ) : ActionEntry { override fun execute(player: Player) { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SwitchServerActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SwitchServerActionEntry.kt similarity index 67% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SwitchServerActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SwitchServerActionEntry.kt index d9dc8e482d..c64cd32bfd 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SwitchServerActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/SwitchServerActionEntry.kt @@ -1,15 +1,15 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.google.common.io.ByteStreams -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.plugin +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.plugin import org.bukkit.entity.Player @Entry("switch_server_action", "Switches the player to another server", Colors.RED, "fluent:server-link-16-filled") @@ -26,7 +26,7 @@ class SwitchServerActionEntry( override val criteria: List, override val modifiers: List, override val triggers: List> = emptyList(), - @Help("The server the player has switched to") + @Help("The server the player will connect to.") val server: String = "", ): ActionEntry { override fun execute(player: Player) { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TeleportActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/TeleportActionEntry.kt similarity index 55% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TeleportActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/TeleportActionEntry.kt index 0c5b07f4cf..dbbeb37af6 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TeleportActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/TeleportActionEntry.kt @@ -1,18 +1,17 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.WithRotation -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.WithRotation +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.toBukkitLocation import org.bukkit.entity.Player @Entry("teleport", "Teleport a player", Colors.RED, "teenyicons:google-streetview-solid") @@ -31,12 +30,11 @@ class TeleportActionEntry( @SerializedName("triggers") override val customTriggers: List>, @WithRotation - @Help("The location to teleport the player to.") - val location: Location = Location(null, 0.0, 0.0, 0.0), + val location: Position = Position.ORIGIN, ) : CustomTriggeringActionEntry { override fun execute(player: Player) { SYNC.launch { - player.teleport(location) + player.teleport(location.toBukkitLocation()) super.execute(player) player.triggerCustomTriggers() } diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TrackQuestActionEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/TrackQuestActionEntry.kt similarity index 62% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TrackQuestActionEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/TrackQuestActionEntry.kt index 6cf38e3342..785bea785a 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TrackQuestActionEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/action/TrackQuestActionEntry.kt @@ -1,11 +1,14 @@ -package me.gabber235.typewriter.entries.action +package com.typewritermc.basic.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.entry.entries.QuestEntry -import me.gabber235.typewriter.entry.quest.trackQuest +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.* +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.entry.entries.QuestEntry +import com.typewritermc.engine.paper.entry.quest.trackQuest import org.bukkit.entity.Player @Entry("track_quest", "Start tracking a quest for a player", Colors.RED, "material-symbols:bookmark") diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/BossBarEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/BossBarEntry.kt similarity index 75% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/BossBarEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/BossBarEntry.kt index da11fd515a..9f7fea8f1c 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/BossBarEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/BossBarEntry.kt @@ -1,15 +1,15 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.TickableDisplay -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.TickableDisplay +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import net.kyori.adventure.bossbar.BossBar import org.bukkit.entity.Player import java.util.* diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CinematicAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CinematicAudienceEntry.kt similarity index 67% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CinematicAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CinematicAudienceEntry.kt index 431eb240b1..53532acf32 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CinematicAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CinematicAudienceEntry.kt @@ -1,20 +1,20 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Page -import me.gabber235.typewriter.entry.PageType -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.cinematic.isPlayingCinematic -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.AudienceFilterEntry -import me.gabber235.typewriter.entry.entries.Invertible -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.events.AsyncCinematicEndEvent -import me.gabber235.typewriter.events.AsyncCinematicStartEvent +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.books.pages.PageType +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Page +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.cinematic.isPlayingCinematic +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.AudienceFilter +import com.typewritermc.engine.paper.entry.entries.AudienceFilterEntry +import com.typewritermc.engine.paper.entry.entries.Invertible +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.events.AsyncCinematicEndEvent +import com.typewritermc.engine.paper.events.AsyncCinematicStartEvent import org.bukkit.entity.Player import org.bukkit.event.EventHandler diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ClosestGroupMemberPathStream.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ClosestGroupMemberPathStream.kt similarity index 70% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ClosestGroupMemberPathStream.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ClosestGroupMemberPathStream.kt index d865ba1a24..8113a4b900 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ClosestGroupMemberPathStream.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ClosestGroupMemberPathStream.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.PathStreamDisplay +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.roadnetwork.gps.PathStreamDisplay @Entry( "closest_group_member_path_stream", diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CriteriaAudience.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CriteriaAudience.kt similarity index 83% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CriteriaAudience.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CriteriaAudience.kt index 76ec4b46a0..18fe82b30d 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CriteriaAudience.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CriteriaAudience.kt @@ -1,10 +1,13 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.* +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.* import org.bukkit.entity.Player import java.util.* import java.util.concurrent.ConcurrentHashMap diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CronAudience.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CronAudience.kt similarity index 76% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CronAudience.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CronAudience.kt index 12f36279e7..b69ff313db 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CronAudience.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/CronAudience.kt @@ -1,15 +1,15 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.AudienceFilterEntry -import me.gabber235.typewriter.entry.entries.TickableDisplay -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.CronExpression +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.AudienceFilter +import com.typewritermc.engine.paper.entry.entries.AudienceFilterEntry +import com.typewritermc.engine.paper.entry.entries.TickableDisplay +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.utils.CronExpression import org.bukkit.entity.Player import java.time.LocalDateTime diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/DirectLocationPathStream.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/DirectLocationPathStream.kt new file mode 100644 index 0000000000..ad0882e16b --- /dev/null +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/DirectLocationPathStream.kt @@ -0,0 +1,34 @@ +package com.typewritermc.basic.entries.audience + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.roadnetwork.gps.PathStreamDisplay +import com.typewritermc.engine.paper.utils.toBukkitLocation + +@Entry( + "direct_location_path_stream", + "A Path Stream to a Direct Location", + Colors.GREEN, + "material-symbols:conversion-path" +) +/** + * The `Direct Location Path Stream` entry is a path stream that shows the path to a specific location. + * When the player has this entry, a path stream will be displayed to the specified location. + * + * ## How could this be used? + * This could be used to show a path to a specific location in the world. + */ +class DirectLocationPathStream( + override val id: String = "", + override val name: String = "", + val road: Ref = emptyRef(), + val targetLocation: Position = Position.ORIGIN, +) : AudienceEntry { + override fun display(): AudienceDisplay = PathStreamDisplay(road, endLocation = { targetLocation.toBukkitLocation() }) +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GameTimeAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/GameTimeAudienceEntry.kt similarity index 88% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GameTimeAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/GameTimeAudienceEntry.kt index 5205fd5cee..efe47677d2 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GameTimeAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/GameTimeAudienceEntry.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.logger +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.logger import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.player.PlayerChangedWorldEvent diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GroupMembersPathStream.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/GroupMembersPathStream.kt similarity index 65% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GroupMembersPathStream.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/GroupMembersPathStream.kt index af17e46b0a..d5264891bd 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GroupMembersPathStream.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/GroupMembersPathStream.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.MultiPathStreamDisplay +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.roadnetwork.gps.MultiPathStreamDisplay @Entry( "group_members_path_stream", diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/HoldingItemAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/HoldingItemAudienceEntry.kt similarity index 80% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/HoldingItemAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/HoldingItemAudienceEntry.kt index 33bb9560f1..4459459318 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/HoldingItemAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/HoldingItemAudienceEntry.kt @@ -1,22 +1,21 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience import io.papermc.paper.event.player.PlayerPickItemEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.AudienceFilterEntry -import me.gabber235.typewriter.entry.entries.Invertible -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.Item +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.AudienceFilter +import com.typewritermc.engine.paper.entry.entries.AudienceFilterEntry +import com.typewritermc.engine.paper.entry.entries.Invertible +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.utils.Item import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.inventory.* import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.PlayerItemHeldEvent -import org.bukkit.inventory.PlayerInventory @Entry( "holding_item_audience", diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInInventoryAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ItemInInventoryAudienceEntry.kt similarity index 60% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInInventoryAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ItemInInventoryAudienceEntry.kt index f24627f8bc..0cd3212f3a 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInInventoryAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ItemInInventoryAudienceEntry.kt @@ -1,22 +1,13 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import com.github.shynixn.mccoroutine.bukkit.ticks -import kotlinx.coroutines.delay -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.utils.Item import org.bukkit.entity.Player -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.entity.EntityPickupItemEvent -import org.bukkit.event.inventory.* -import org.bukkit.event.player.PlayerDropItemEvent -import org.bukkit.event.player.PlayerPickupItemEvent @Entry( "item_in_inventory_audience", @@ -34,7 +25,6 @@ class ItemInInventoryAudienceEntry( override val id: String = "", override val name: String = "", override val children: List> = emptyList(), - @Help("The item to check for in the inventory.") val item: Item = Item.Empty, override val inverted: Boolean = false, ) : AudienceFilterEntry, Invertible { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInSlotAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ItemInSlotAudienceEntry.kt similarity index 64% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInSlotAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ItemInSlotAudienceEntry.kt index 65b4ff5c33..3a54b74895 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInSlotAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/ItemInSlotAudienceEntry.kt @@ -1,21 +1,13 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import io.papermc.paper.event.player.PlayerPickItemEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.Item +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.core.entries.ref +import com.typewritermc.engine.paper.utils.Item import org.bukkit.entity.Player -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.entity.EntityPickupItemEvent -import org.bukkit.event.inventory.* -import org.bukkit.event.inventory.InventoryAction.* -import org.bukkit.event.player.PlayerDropItemEvent -import org.bukkit.event.player.PlayerSwapHandItemsEvent @Entry( "item_in_slot_audience", diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LocationObjectivesPathStream.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/LocationObjectivesPathStream.kt similarity index 51% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LocationObjectivesPathStream.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/LocationObjectivesPathStream.kt index d5a4fdd97e..cb969bb73c 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LocationObjectivesPathStream.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/LocationObjectivesPathStream.kt @@ -1,16 +1,16 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.entry.entries.trackedShowingObjectives - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.MultiPathStreamDisplay -import me.gabber235.typewriter.entries.quest.LocationObjectiveEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.basic.entries.quest.LocationObjectiveEntry +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.entries.trackedShowingObjectives +import com.typewritermc.engine.paper.entry.roadnetwork.gps.MultiPathStreamDisplay +import com.typewritermc.engine.paper.utils.toBukkitLocation @Entry( "location_objectives_path_stream", @@ -31,6 +31,7 @@ class LocationObjectivesPathStream( val road: Ref = emptyRef(), ) : AudienceEntry { override fun display(): AudienceDisplay = MultiPathStreamDisplay(road, endLocations = { player -> - player.trackedShowingObjectives().filterIsInstance().map { it.targetLocation }.toList() + player.trackedShowingObjectives().filterIsInstance() + .map { it.targetLocation.toBukkitLocation() }.toList() }) } \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LoopingCinematicAudience.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/LoopingCinematicAudience.kt similarity index 87% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LoopingCinematicAudience.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/LoopingCinematicAudience.kt index a8180c8296..a25a19a54a 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LoopingCinematicAudience.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/LoopingCinematicAudience.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Page -import me.gabber235.typewriter.entry.PageType -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.matches -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.utils.ThreadType +package com.typewritermc.basic.entries.audience + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.books.pages.PageType +import com.typewritermc.core.entries.Query +import com.typewritermc.core.extension.annotations.Page +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.matches +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.utils.ThreadType import org.bukkit.entity.Player import java.util.* import java.util.concurrent.ConcurrentHashMap diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SidebarEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/SidebarEntry.kt similarity index 59% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SidebarEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/SidebarEntry.kt index a87978f458..cc7c5855b9 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SidebarEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/SidebarEntry.kt @@ -1,13 +1,10 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.PassThroughFilter -import me.gabber235.typewriter.entry.entries.SidebarEntry -import me.gabber235.typewriter.entry.ref +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.SidebarEntry import java.util.* @Entry("sidebar", "Display a sidebar for players", Colors.DARK_ORANGE, "mdi:page-layout-sidebar-right") diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SimpleLinesEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/SimpleLinesEntry.kt similarity index 64% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SimpleLinesEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/SimpleLinesEntry.kt index e3d8c25a32..71f7c26bbe 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SimpleLinesEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/SimpleLinesEntry.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.entries.LinesEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.entries.LinesEntry import org.bukkit.entity.Player import java.util.* diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TabListHeaderFooterEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TabListHeaderFooterEntry.kt similarity index 85% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TabListHeaderFooterEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TabListHeaderFooterEntry.kt index 4ba254f21d..f35cfb51bd 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TabListHeaderFooterEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TabListHeaderFooterEntry.kt @@ -1,12 +1,16 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.PriorityEntry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.priority +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import net.kyori.adventure.text.Component import org.bukkit.entity.Player import java.util.* diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TimerAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TimerAudienceEntry.kt similarity index 74% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TimerAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TimerAudienceEntry.kt index da409e8527..21e276b96f 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TimerAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TimerAudienceEntry.kt @@ -1,15 +1,17 @@ +package com.typewritermc.basic.entries.audience + import kotlinx.coroutines.Job import kotlinx.coroutines.delay -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.utils.ThreadType +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.utils.ThreadType import org.bukkit.entity.Player import java.time.Duration import java.util.* diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TriggerAudienceEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TriggerAudienceEntry.kt similarity index 69% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TriggerAudienceEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TriggerAudienceEntry.kt index 9b1711f4ea..1af221f6e2 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TriggerAudienceEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/audience/TriggerAudienceEntry.kt @@ -1,14 +1,14 @@ -package me.gabber235.typewriter.entries.audience +package com.typewritermc.basic.entries.audience -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.triggerFor +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.triggerFor import org.bukkit.entity.Player @Entry( diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ActionBarDialogueCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ActionBarDialogueCinematicEntry.kt similarity index 78% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ActionBarDialogueCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ActionBarDialogueCinematicEntry.kt index 56c8ea6ee4..b720a5470a 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ActionBarDialogueCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ActionBarDialogueCinematicEntry.kt @@ -1,19 +1,18 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.interaction.acceptActionBarMessage -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.* +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.interaction.acceptActionBarMessage +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.* import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import org.bukkit.entity.Player @@ -32,7 +31,6 @@ class ActionBarDialogueCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The speaker of the dialogue") val speaker: Ref = emptyRef(), @Segments(icon = "fa6-solid:xmarks-lines") val segments: List = emptyList(), @@ -59,7 +57,6 @@ data class RandomActionBarDialogueCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The speaker of the dialogue") val speaker: Ref = emptyRef(), @Segments(icon = "fa6-solid:xmarks-lines") val segments: List = emptyList(), diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/BlindingCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt similarity index 73% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/BlindingCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt index 18d344aaca..6a9ce1c422 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/BlindingCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt @@ -1,18 +1,18 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChangeGameState import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCloseWindow -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.EmptyCinematicAction -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.utils.isFloodgate +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.EmptyCinematicAction +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.utils.isFloodgate import org.bukkit.entity.Player @Entry("blinding_cinematic", "Blind the player so the screen looks black", Colors.CYAN, "heroicons-solid:eye-off") diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/CameraCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt similarity index 86% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/CameraCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt index 74cf3bb70b..4a1b0a4a1f 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/CameraCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt @@ -1,4 +1,4 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes import com.github.retrooper.packetevents.protocol.packettype.PacketType @@ -7,28 +7,26 @@ import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPl import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerPositionAndLook import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.* +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.extensions.packetevents.meta +import com.typewritermc.engine.paper.extensions.packetevents.spectateEntity +import com.typewritermc.engine.paper.extensions.packetevents.stopSpectatingEntity +import com.typewritermc.engine.paper.interaction.InterceptionBundle +import com.typewritermc.engine.paper.interaction.interceptPackets +import com.typewritermc.engine.paper.logger +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.* +import com.typewritermc.engine.paper.utils.GenericPlayerStateProvider.* +import com.typewritermc.engine.paper.utils.ThreadType.SYNC import io.github.retrooper.packetevents.util.SpigotConversionUtil import lirand.api.extensions.events.SimpleListener import lirand.api.extensions.events.listen import lirand.api.extensions.events.unregister -import lirand.api.extensions.inventory.meta -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.* -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.meta -import me.gabber235.typewriter.extensions.packetevents.spectateEntity -import me.gabber235.typewriter.extensions.packetevents.stopSpectatingEntity -import me.gabber235.typewriter.extensions.packetevents.toPacketLocation -import me.gabber235.typewriter.interaction.InterceptionBundle -import me.gabber235.typewriter.interaction.interceptPackets -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.* -import me.gabber235.typewriter.utils.GenericPlayerStateProvider.* -import me.gabber235.typewriter.utils.ThreadType.SYNC import me.tofaa.entitylib.meta.display.ItemDisplayMeta import me.tofaa.entitylib.meta.display.TextDisplayMeta import me.tofaa.entitylib.wrapper.WrapperEntity @@ -104,7 +102,7 @@ data class CameraSegment( data class PathPoint( @WithRotation - val location: Location = Location(null, 0.0, 0.0, 0.0), + val location: Position = Position.ORIGIN, @Help("The duration of the path point in frames.") /** * The duration of the path point in frames. @@ -287,7 +285,7 @@ private suspend inline fun Player.teleportIfNeeded( private data class PointSegment( override val startFrame: Int, override val endFrame: Int, - val location: Location, + val position: Position, ) : Segment private interface CameraAction { @@ -316,9 +314,7 @@ private class DisplayCameraAction( private fun setupPath(segment: CameraSegment) { path = segment.path.transform(segment.duration - BASE_INTERPOLATION) { - it.clone().apply { - y += player.eyeHeight - } + it.add(y = player.eyeHeight) } } @@ -326,10 +322,10 @@ private class DisplayCameraAction( setupPath(segment) SYNC.switchContext { - player.teleport(path.first().location) + player.teleport(path.first().position.toBukkitLocation()) } - entity.spawn(path.first().location.toPacketLocation()) + entity.spawn(path.first().position.toPacketLocation()) entity.addViewer(player.uniqueId) player.spectateEntity(entity) } @@ -338,12 +334,12 @@ private class DisplayCameraAction( val location = path.interpolate(frame) entity.rotateHead(location.yaw, location.pitch) entity.teleport(location.toPacketLocation()) - player.teleportIfNeeded(frame, location) + player.teleportIfNeeded(frame, location.toBukkitLocation()) } override suspend fun switchSegment(newSegment: CameraSegment) { - val oldWorld = path.first().location.world.uid - val newWorld = newSegment.path.first().location.world.uid + val oldWorld = path.first().position.world.identifier + val newWorld = newSegment.path.first().location.world.identifier setupPath(newSegment) if (oldWorld == newWorld) { @@ -355,11 +351,11 @@ private class DisplayCameraAction( private suspend fun switchSeamless() { val newEntity = createEntity() - newEntity.spawn(path.first().location.toPacketLocation()) + newEntity.spawn(path.first().position.toPacketLocation()) newEntity.addViewer(player.uniqueId) SYNC.switchContext { - player.teleport(path.first().location) + player.teleport(path.first().position.toBukkitLocation()) player.spectateEntity(newEntity) } @@ -373,8 +369,8 @@ private class DisplayCameraAction( entity.despawn() entity.addViewer(player.uniqueId) SYNC.switchContext { - player.teleport(path.first().location) - entity.spawn(path.first().location.toPacketLocation()) + player.teleport(path.first().position.toBukkitLocation()) + entity.spawn(path.first().position.toPacketLocation()) player.spectateEntity(entity) } } @@ -392,20 +388,20 @@ private class TeleportCameraAction( private var path = emptyList() override suspend fun startSegment(segment: CameraSegment) { - path = segment.path.transform(segment.duration, Location::clone) + path = segment.path.transform(segment.duration, Position::copy) } override suspend fun tickSegment(frame: Int) { - val location = path.interpolate(frame) + val position = path.interpolate(frame) SYNC.switchContext { - player.teleport(location) + player.teleport(position.toBukkitLocation()) player.allowFlight = true player.isFlying = true } } override suspend fun switchSegment(newSegment: CameraSegment) { - path = newSegment.path.transform(newSegment.duration, Location::clone) + path = newSegment.path.transform(newSegment.duration, Position::copy) } override suspend fun stop() { @@ -420,9 +416,7 @@ class SimulatedCameraCinematicAction( private val paths = entry.segments.associateWith { segment -> segment.path.transform(segment.duration) { - it.clone().apply { - y += player.eyeHeight - } + it.add(y = player.eyeHeight) } } @@ -436,9 +430,13 @@ class SimulatedCameraCinematicAction( .meta { positionRotationInterpolationDuration = 3 displayType = ItemDisplayMeta.DisplayType.HEAD - item = SpigotConversionUtil.fromBukkitItemStack(ItemStack(Material.PLAYER_HEAD).meta { - applySkinUrl("https://textures.minecraft.net/texture/427066e899358b1185460f867fc6dc434c7b4c82fbe70e1919ce74b8bacf80a1") - }) + item = SpigotConversionUtil.fromBukkitItemStack(ItemStack(Material.PLAYER_HEAD) + .apply { + editMeta(SkullMeta::class.java) { meta -> + meta.applySkinUrl("https://textures.minecraft.net/texture/427066e899358b1185460f867fc6dc434c7b4c82fbe70e1919ce74b8bacf80a1") + } + } + ) } val path = paths[segment] ?: return val location = path.interpolate(lastFrame - segment.startFrame) @@ -465,7 +463,7 @@ class SimulatedCameraCinematicAction( private fun List.transform( totalDuration: Int, - locationTransformer: (Location) -> Location + locationTransformer: (Position) -> Position ): List { if (isEmpty()) { throw IllegalArgumentException("The path points cannot be empty.") @@ -526,10 +524,10 @@ private fun List.transform( /** * Use catmull-rom interpolation to get a point between a list of points. */ -private fun List.interpolate(frame: Int): Location { +private fun List.interpolate(frame: Int): Position { val index = indexOfFirst { it isActiveAt frame } if (index == -1) { - return last().location + return last().position } val segment = this[index] @@ -537,10 +535,10 @@ private fun List.interpolate(frame: Int): Location { val currentFrame = frame - segment.startFrame val percentage = currentFrame.toDouble() / totalFrames - val currentLocation = segment.location - val previousLocation = getOrNull(index - 1)?.location ?: currentLocation - val nextLocation = getOrNull(index + 1)?.location ?: currentLocation - val nextNextLocation = getOrNull(index + 2)?.location ?: nextLocation + val currentLocation = segment.position + val previousLocation = getOrNull(index - 1)?.position ?: currentLocation + val nextLocation = getOrNull(index + 1)?.position ?: currentLocation + val nextNextLocation = getOrNull(index + 2)?.position ?: nextLocation return interpolatePoints(previousLocation, currentLocation, nextLocation, nextNextLocation, percentage) } \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/CinematicCommandEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt similarity index 77% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/CinematicCommandEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt index 7b2c740a1d..79be5f05c0 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/CinematicCommandEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt @@ -1,15 +1,15 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.* -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.* +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.ThreadType.SYNC import org.bukkit.entity.Player interface CinematicCommandEntry : CinematicEntry { @@ -83,10 +83,9 @@ class CinematicPlayerCommandEntry( data class CommandSegment( override val startFrame: Int, override val endFrame: Int, - @Help("The command(s) to run.") + @Help("Each line is a different command. Commands should not be prefixed with /.") @Placeholder @MultiLine - // Every line is a different command. Commands should not be prefixed with /. val command: String, ) : Segment diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/DisplayDialogueCinematicAction.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/DisplayDialogueCinematicAction.kt similarity index 80% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/DisplayDialogueCinematicAction.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/DisplayDialogueCinematicAction.kt index cc4f5e296f..db272bbd66 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/DisplayDialogueCinematicAction.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/DisplayDialogueCinematicAction.kt @@ -1,18 +1,18 @@ -package me.gabber235.typewriter.entries.cinematic - -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.dialogue.playSpeakerSound -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.GenericPlayerStateProvider.EXP -import me.gabber235.typewriter.utils.GenericPlayerStateProvider.LEVEL -import me.gabber235.typewriter.utils.PlayerState -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.restore -import me.gabber235.typewriter.utils.state +package com.typewritermc.basic.entries.cinematic + +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.dialogue.playSpeakerSound +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.GenericPlayerStateProvider.EXP +import com.typewritermc.engine.paper.utils.GenericPlayerStateProvider.LEVEL +import com.typewritermc.engine.paper.utils.PlayerState +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.restore +import com.typewritermc.engine.paper.utils.state import org.bukkit.entity.Player data class SingleLineDisplayDialogueSegment( @@ -57,7 +57,7 @@ data class MultiLineRandomDisplayDialogueSegment( } interface RandomDisplayDialogueSegment : Segment { - @Help("Possible texts to display to the player.") + @Help("One of the possible texts is chosen randomly, and displayed to the player.") val texts: List fun toDisplaySegment(): DisplayDialogueSegment diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ParticleCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ParticleCinematicEntry.kt similarity index 64% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ParticleCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ParticleCinematicEntry.kt index 79a6fbdab8..76f15ceec7 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ParticleCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ParticleCinematicEntry.kt @@ -1,13 +1,14 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Negative -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.entries.* -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Negative +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.utils.toBukkitLocation import org.bukkit.Particle import org.bukkit.entity.Player @@ -25,23 +26,17 @@ class ParticleCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The location to spawn the particles at.") - val location: Location = Location(null, 0.0, 0.0, 0.0), - @Help("The particle to spawn.") + val location: Position = Position.ORIGIN, val particle: Particle = Particle.FLAME, - @Help("The amount of particles to spawn.") + @Help("The amount of particles to spawn every tick.") val count: Int = 1, @Negative - @Help("The offset from the location on the X axis.") val offsetX: Double = 0.0, @Negative - @Help("The offset from the location on the Y axis.") val offsetY: Double = 0.0, @Negative - @Help("The offset from the location on the Z axis.") val offsetZ: Double = 0.0, - @Help("The speed of the particles.") - // The speed of the particles. For some particles, this is the "extra" data value to control particle behavior. + @Help("The speed of the particles. For some particles, this is the \"extra\" data value to control particle behavior.") val speed: Double = 0.0, @Segments(icon = "fa6-solid:fire-flame-simple") val segments: List = emptyList(), @@ -70,7 +65,7 @@ class ParticleCinematicAction( player.spawnParticle( entry.particle, - entry.location, + entry.location.toBukkitLocation(), entry.count, entry.offsetX, entry.offsetY, diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PotionEffectCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt similarity index 70% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PotionEffectCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt index 0acca47737..2af30bf115 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PotionEffectCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt @@ -1,20 +1,20 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.utils.EffectStateProvider -import me.gabber235.typewriter.utils.PlayerState -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.restore -import me.gabber235.typewriter.utils.state +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Default +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.utils.EffectStateProvider +import com.typewritermc.engine.paper.utils.PlayerState +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.restore +import com.typewritermc.engine.paper.utils.state import org.bukkit.entity.Player import org.bukkit.potion.PotionEffect import org.bukkit.potion.PotionEffectType @@ -51,15 +51,12 @@ class PotionEffectCinematicEntry( data class PotionEffectSegment( override val startFrame: Int = 0, override val endFrame: Int = 0, - @Help("The type of potion effect to apply") val potionEffectType: PotionEffectType = PotionEffectType.BLINDNESS, - @Help("The strength of the potion effect") + @Default("1") val strength: Int = 1, - @Help("Whether the potion effect should be ambient") val ambient: Boolean = false, - @Help("Whether the potion effect should have particles") val particles: Boolean = false, - @Help("Whether the potion effect should display an icon") + @Help("Whether the icon should be displayed in the top left corner of the screen.") val icon: Boolean = false, ) : Segment diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PumpkinHatCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt similarity index 69% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PumpkinHatCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt index 4238cd0131..6d6029f218 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PumpkinHatCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt @@ -1,25 +1,21 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic import com.github.retrooper.packetevents.protocol.player.Equipment import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment -import lirand.api.extensions.inventory.meta -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toPacketItem -import me.gabber235.typewriter.utils.name -import me.gabber235.typewriter.utils.unClickable +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.extensions.packetevents.toPacketItem +import com.typewritermc.engine.paper.utils.name +import com.typewritermc.engine.paper.utils.unClickable import org.bukkit.Material -import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player -import org.bukkit.inventory.ItemFlag import org.bukkit.inventory.ItemStack @Entry("pumpkin_hat_cinematic", "Show a pumpkin hat during a cinematic", Colors.CYAN, "mingcute:hat-fill") @@ -35,7 +31,7 @@ class PumpkinHatCinematicEntry( override val criteria: List = emptyList(), @Segments(icon = "mingcute:hat-fill") val segments: List = emptyList(), - ) : PrimaryCinematicEntry { +) : PrimaryCinematicEntry { override fun create(player: Player): CinematicAction { return PumpkinHatCinematicAction( player, @@ -64,9 +60,11 @@ class PumpkinHatCinematicAction( Equipment( com.github.retrooper.packetevents.protocol.player.EquipmentSlot.HELMET, ItemStack(Material.CARVED_PUMPKIN) - .meta { - name = " " - unClickable() + .apply { + editMeta { meta -> + meta.name = " " + meta.unClickable() + } } .toPacketItem() ) diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ScreenShakeCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ScreenShakeCinematicEntry.kt similarity index 71% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ScreenShakeCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ScreenShakeCinematicEntry.kt index fa28c0e413..17f999da6d 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ScreenShakeCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/ScreenShakeCinematicEntry.kt @@ -1,13 +1,13 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerHurtAnimation -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo import org.bukkit.entity.Player import kotlin.random.Random @@ -39,10 +39,10 @@ class ScreenShakeCinematicEntry( } data class ScreenShakeSegment( - override val startFrame: Int, - override val endFrame: Int, - @Help("The amount of frames to wait before the next shake.") - val frameDelay: Int, + override val startFrame: Int = 0, + override val endFrame: Int = 0, + @Help("The number of frames to wait before the next shake.") + val frameDelay: Int = 0, ) : Segment class ScreenShakeCinematicAction( diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SetFakeBlockCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt similarity index 60% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SetFakeBlockCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt index 4f2de83f13..0e42e00475 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SetFakeBlockCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt @@ -1,21 +1,20 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState -import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockChange +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.utils.toBukkitLocation +import com.typewritermc.engine.paper.utils.toPacketVector3i import io.github.retrooper.packetevents.util.SpigotConversionUtil -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toVector3i -import org.bukkit.Location import org.bukkit.Material import org.bukkit.entity.Player @@ -36,7 +35,7 @@ class SetFakeBlockCinematicEntry( data class SetFakeBlockSegment( override val startFrame: Int = 0, override val endFrame: Int = 0, - val location: Location = Location(null, 0.0, 0.0, 0.0), + val location: Position = Position.ORIGIN, val block: Material = Material.AIR, ) : Segment @@ -50,14 +49,15 @@ class SetFakeBlockCinematicAction( super.startSegment(segment) val state = SpigotConversionUtil.fromBukkitBlockData(segment.block.createBlockData()) - val packet = WrapperPlayServerBlockChange(segment.location.toVector3i(), state.globalId) + val packet = WrapperPlayServerBlockChange(segment.location.toPacketVector3i(), state.globalId) packet.sendPacketTo(player) } override suspend fun stopSegment(segment: SetFakeBlockSegment) { super.stopSegment(segment) - player.sendBlockChange(segment.location, segment.location.block.blockData) + val bukkitLocation = segment.location.toBukkitLocation() + player.sendBlockChange(bukkitLocation, bukkitLocation.block.blockData) } } diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt new file mode 100644 index 0000000000..f5604e98bd --- /dev/null +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt @@ -0,0 +1,58 @@ +package com.typewritermc.basic.entries.cinematic + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.utils.* +import org.bukkit.entity.Player + +@Entry("sound_cinematic", "Play a sound during a cinematic", Colors.YELLOW, "fa6-solid:music") +/** + * The `Sound Cinematic` entry plays a sound during a cinematic. + * + * ## How could this be used? + * + * This entry could be used to play a sound during a cinematic, such as a sound effect for a cutscene. + */ +class SoundCinematicEntry( + override val id: String, + override val name: String, + override val criteria: List, + @Segments(icon = "fa6-solid:music", color = Colors.YELLOW) + val segments: List, +) : CinematicEntry { + override fun create(player: Player): CinematicAction { + return SoundCinematicAction( + player, + this, + ) + } +} + +data class SoundSegment( + override val startFrame: Int, + override val endFrame: Int, + val sound: Sound, +) : Segment + +class SoundCinematicAction( + private val player: Player, + private val entry: SoundCinematicEntry, +) : SimpleCinematicAction() { + override val segments: List = entry.segments + + override suspend fun startSegment(segment: SoundSegment) { + super.startSegment(segment) + player.playSound(segment.sound) + } + + override suspend fun stopSegment(segment: SoundSegment) { + super.stopSegment(segment) + player.stopSound(segment.sound) + } +} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SpokenDialogueCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SpokenDialogueCinematicEntry.kt similarity index 76% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SpokenDialogueCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SpokenDialogueCinematicEntry.kt index 33bcd93e55..3c6000ae39 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SpokenDialogueCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SpokenDialogueCinematicEntry.kt @@ -1,24 +1,23 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.entry.entries.SystemTrigger.DIALOGUE_END -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.interaction.acceptActionBarMessage -import me.gabber235.typewriter.interaction.chatHistory -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.asMiniWithResolvers -import me.gabber235.typewriter.utils.asPartialFormattedMini -import me.gabber235.typewriter.utils.isFloodgate +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.entry.entries.SystemTrigger.DIALOGUE_END +import com.typewritermc.engine.paper.entry.triggerFor +import com.typewritermc.engine.paper.interaction.acceptActionBarMessage +import com.typewritermc.engine.paper.interaction.chatHistory +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.asMiniWithResolvers +import com.typewritermc.engine.paper.utils.asPartialFormattedMini +import com.typewritermc.engine.paper.utils.isFloodgate import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import org.bukkit.entity.Player @@ -34,7 +33,6 @@ class SpokenDialogueCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The speaker of the dialogue") val speaker: Ref = emptyRef(), @Segments(icon = "mingcute:message-4-fill") val segments: List = emptyList(), @@ -65,7 +63,6 @@ data class RandomSpokenDialogueCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The speaker of the dialogue") val speaker: Ref = emptyRef(), @Segments(icon = "mingcute:message-4-fill") val segments: List = emptyList(), diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SubtitleDialgueCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SubtitleDialgueCinematicEntry.kt similarity index 76% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SubtitleDialgueCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SubtitleDialgueCinematicEntry.kt index 7947966bc7..4f24a5ee1a 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SubtitleDialgueCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SubtitleDialgueCinematicEntry.kt @@ -1,23 +1,21 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.interaction.acceptActionBarMessage -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.asMini -import me.gabber235.typewriter.utils.asMiniWithResolvers -import me.gabber235.typewriter.utils.splitPercentage +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.interaction.acceptActionBarMessage +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.asMini +import com.typewritermc.engine.paper.utils.asMiniWithResolvers +import com.typewritermc.engine.paper.utils.splitPercentage import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import net.kyori.adventure.title.Title import net.kyori.adventure.title.Title.Times @@ -37,7 +35,6 @@ class SubtitleDialogueCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The speaker of the dialogue") val speaker: Ref = emptyRef(), @Segments(icon = "fa6-solid:diagram-next") val segments: List = emptyList(), @@ -63,7 +60,6 @@ data class RandomSubtitleDialogueCinematicEntry( override val id: String = "", override val name: String = "", override val criteria: List = emptyList(), - @Help("The speaker of the dialogue") val speaker: Ref = emptyRef(), @Segments(icon = "fa6-solid:diagram-next") val segments: List = emptyList(), diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt similarity index 71% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt index 22118baac0..000745ff7f 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt @@ -1,18 +1,16 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic import io.papermc.paper.util.Tick -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import net.kyori.adventure.title.Title import org.bukkit.entity.Player import java.time.Duration @@ -43,13 +41,9 @@ class TitleCinematicEntry( data class TitleSegment( override val startFrame: Int = 0, override val endFrame: Int = 0, - @Help("The title to show") val title: String = "", - @Help("The subtitle to show") val subtitle: String = "", - @Help("The fade in time") val fadeIn: Long = 20, - @Help("The fade out time") val fadeOut: Long = 20, ) : Segment diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TriggerSequenceCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt similarity index 66% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TriggerSequenceCinematicEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt index 33baf6bd1d..ed5fd3d723 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TriggerSequenceCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt @@ -1,17 +1,20 @@ -package me.gabber235.typewriter.entries.cinematic +package com.typewritermc.basic.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.InnerMax -import me.gabber235.typewriter.adapters.modifiers.Max -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.EntryTrigger -import me.gabber235.typewriter.entry.entries.Segment +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.InnerMax +import com.typewritermc.core.extension.annotations.Max +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.EntryTrigger +import com.typewritermc.engine.paper.entry.entries.Segment import org.bukkit.entity.Player @Entry("trigger_sequence_cinematic", "A sequence of triggers to run", Colors.PURPLE, "fa-solid:play") @@ -33,7 +36,6 @@ class TriggerSequenceCinematicEntry( override val criteria: List = emptyList(), @Segments @InnerMax(Max(1)) - @Help("The sequence of triggers to run") val segments: List = emptyList(), ) : CinematicEntry { override fun create(player: Player): CinematicAction { diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/MessageDialogue.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/dialogue/MessageDialogue.kt similarity index 61% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/MessageDialogue.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/dialogue/MessageDialogue.kt index e338c0e3d6..0b3f893c6f 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/MessageDialogue.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/dialogue/MessageDialogue.kt @@ -1,13 +1,15 @@ -package me.gabber235.typewriter.entries.dialogue +package com.typewritermc.basic.entries.dialogue -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry +import com.typewritermc.core.entries.* +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.DialogueEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry @Entry("message", "Display a single message to the player", "#1c4da3", "ic:baseline-comment-bank") /** @@ -27,6 +29,5 @@ class MessageDialogueEntry( @MultiLine @Placeholder @Colored - @Help("The text to display to the player.") val text: String = "", ) : DialogueEntry \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/OptionDialogueEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/dialogue/OptionDialogueEntry.kt similarity index 72% rename from adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/OptionDialogueEntry.kt rename to extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/dialogue/OptionDialogueEntry.kt index 423e4aef70..8618d630f0 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/OptionDialogueEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/dialogue/OptionDialogueEntry.kt @@ -1,12 +1,15 @@ -package me.gabber235.typewriter.entries.dialogue +package com.typewritermc.basic.entries.dialogue -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry +import com.typewritermc.core.entries.* +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.DialogueEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry import java.time.Duration @Entry("option", "Display a list of options to the player", "#4CAF50", "fa6-solid:list") @@ -26,9 +29,7 @@ class OptionDialogueEntry( override val speaker: Ref = emptyRef(), @Placeholder @Colored - @Help("The text to display to the player.") val text: String = "", - @Help("The options for the player to choose from.") val options: List ); @@ -95,12 +118,16 @@ function Bar({ progress, onSeek }: BarProps) { value={progress} onChange={onSeek} className="absolute top-0 left-0 w-full h-[5px] opacity-0 cursor-pointer" - style={{ WebkitAppearance: "none" }} + style={{ + WebkitAppearance: "none", + MozAppearance: "none", + appearance: "none", + }} />
); -} \ No newline at end of file +} From ee9545bb5704d7b07724883081a5500d56818b10 Mon Sep 17 00:00:00 2001 From: Marten Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Wed, 4 Sep 2024 20:20:46 +0200 Subject: [PATCH 06/32] [Docs] Revert some changes This reverts commit 79979b47e4e645e1107221228e89e74278bcf1d9. --- .../plugins/code-snippets/codeSnippets.js | 71 ++++++------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/documentation/plugins/code-snippets/codeSnippets.js b/documentation/plugins/code-snippets/codeSnippets.js index 11edeb8b21..4d6f16e26d 100644 --- a/documentation/plugins/code-snippets/codeSnippets.js +++ b/documentation/plugins/code-snippets/codeSnippets.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); -const codeBlockRegex = /\/\/<(?\/)?code-block:(?[a-zA-Z0-9_]*)>$/; +const codeBockRegex = /\/\/<(?\/)?code-block:(?[a-zA-Z0-9_]*)>$/; module.exports = function() { const snippets = {}; @@ -10,48 +10,26 @@ module.exports = function() { const content = fs.readFileSync(filePath, 'utf8'); const lines = content.split('\n'); const blocks = {}; - const blockStartLines = {}; lines.forEach((line, index) => { - const match = line.match(codeBlockRegex); + const match = line.match(codeBockRegex); if (match) { const { closing, tag } = match.groups; if (closing) { const code = blocks[tag]; if (!code) { - // Handle the case where a closing tag does not have an opening tag - snippets[tag] = { - file: relativeFilePath, - content: "Not found", // Temporary fix so the docs can be build... - startLine: "N/A", - endLine: index + 1 - }; - } else { - // Close the block and save the snippet - blocks[tag] = null; - snippets[tag] = { - file: relativeFilePath, - content: code.join('\n'), - startLine: blockStartLines[tag] + 1, - endLine: index + 1 - }; + throw new Error(`Code block not closed: ${tag} (${relativeFilePath}:${index + 1})`); } - } else { - if (blocks[tag]) { - // Handle the case where an opening tag already exists - snippets[tag] = { - file: relativeFilePath, - content: "Not found", // Temporary fix so the docs can be build... - startLine: blockStartLines[tag] + 1, - endLine: index + 1 - }; - } - // Start a new block - blocks[tag] = []; - blockStartLines[tag] = index; + blocks[tag] = null; + snippets[tag] = { + file: relativeFilePath, + content: code.join('\n') + }; + return; } + + blocks[tag] = []; } else { - // Add lines to the current blocks for (const tag in blocks) { const code = blocks[tag]; if (!code) continue; @@ -63,14 +41,11 @@ module.exports = function() { // Handle any unclosed blocks for (const tag in blocks) { const code = blocks[tag]; - if (code) { - snippets[tag] = { - file: relativeFilePath, - content: "Not found", // Temporary fix so the docs can be build... - startLine: blockStartLines[tag] + 1, - endLine: "N/A" - }; - } + if (!code) continue; + snippets[tag] = { + file: relativeFilePath, + content: code.join('\n') + }; } } @@ -83,13 +58,7 @@ module.exports = function() { if (stat.isDirectory()) { traverseDirectory(filePath, baseDir); } else if (path.extname(filePath) === '.kt') { - try { - processFile(filePath, relativeFilePath); - } catch (error) { - // Improve error handling by showing which file failed - console.error(`Error processing file: ${relativeFilePath}`); - throw error; - } + processFile(filePath, relativeFilePath); } }); } @@ -98,11 +67,13 @@ module.exports = function() { const adaptersDir = path.resolve(__dirname, '../../../extensions/_DocsExtension'); traverseDirectory(adaptersDir, adaptersDir); + // console.log(`Exporting ${Object.keys(snippets).length} snippets: ${Object.keys(snippets)}`); + this.cacheable(false); const code = `${JSON.stringify(snippets, null, 2)}`; - fs.writeFileSync(path.resolve(__dirname, 'snippets.json'), code); + fs.writeSync(fs.openSync(path.resolve(__dirname, 'snippets.json'), 'w'), code); return `export default ${JSON.stringify(snippets, null, 2)}`; -}; \ No newline at end of file +}; From f7609a2c17052f2d17d7363f91f5b2383acc2d7f Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Wed, 4 Sep 2024 21:40:13 +0200 Subject: [PATCH 07/32] Create Typewriter Runner Image --- .github/runners/Dockerfile | 3 ++ .github/workflows/build-runner-image.yml | 53 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 .github/runners/Dockerfile create mode 100644 .github/workflows/build-runner-image.yml diff --git a/.github/runners/Dockerfile b/.github/runners/Dockerfile new file mode 100644 index 0000000000..1edbf13807 --- /dev/null +++ b/.github/runners/Dockerfile @@ -0,0 +1,3 @@ +FROM ghcr.io/actions/actions-runner:latest + +RUN sudo apt update && sudo apt install git -y diff --git a/.github/workflows/build-runner-image.yml b/.github/workflows/build-runner-image.yml new file mode 100644 index 0000000000..d1974b85b2 --- /dev/null +++ b/.github/workflows/build-runner-image.yml @@ -0,0 +1,53 @@ +# +name: Create and publish a Docker image + +on: + push: + branches: + - develop + paths: + - .github/workflows/build-runner-image.yml + - .github/runners/Dockerfile + +env: + REGISTRY: ghcr.io + IMAGE_NAME: typewriter-runner + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: .github/runners + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true + + From 33a2e93427ff5de0e19af9e3608733f9fae20d2d Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Wed, 4 Sep 2024 21:51:27 +0200 Subject: [PATCH 08/32] Add username to path --- .github/workflows/build-runner-image.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-runner-image.yml b/.github/workflows/build-runner-image.yml index d1974b85b2..e390bfb585 100644 --- a/.github/workflows/build-runner-image.yml +++ b/.github/workflows/build-runner-image.yml @@ -34,7 +34,7 @@ jobs: id: meta uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: ${{ env.REGISTRY }}/${{ github.actor }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image id: push uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 @@ -42,12 +42,10 @@ jobs: context: .github/runners push: true tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + labels: latest - name: Generate artifact attestation uses: actions/attest-build-provenance@v1 with: - subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-name: ${{ env.REGISTRY }}/${{ github.actor }}/${{ env.IMAGE_NAME }} subject-digest: ${{ steps.push.outputs.digest }} push-to-registry: true - - From bbbec313a8019e8476cc195352b5a4ca7425b78a Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Wed, 4 Sep 2024 21:57:03 +0200 Subject: [PATCH 09/32] Add label --- .github/workflows/build-runner-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-runner-image.yml b/.github/workflows/build-runner-image.yml index e390bfb585..0765e0469a 100644 --- a/.github/workflows/build-runner-image.yml +++ b/.github/workflows/build-runner-image.yml @@ -25,24 +25,24 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ github.actor }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image id: push - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + uses: docker/build-push-action@v6 with: context: .github/runners push: true tags: ${{ steps.meta.outputs.tags }} - labels: latest + labels: ${{ github.actor }}/${{ env.IMAGE_NAME }}:latest - name: Generate artifact attestation uses: actions/attest-build-provenance@v1 with: From 39c80f43a2a3dcce80ef9f04a741044a4e6318b8 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 07:32:41 +0200 Subject: [PATCH 10/32] Add libvips-dev dependency --- .github/runners/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/runners/Dockerfile b/.github/runners/Dockerfile index 1edbf13807..2fa4ac92e8 100644 --- a/.github/runners/Dockerfile +++ b/.github/runners/Dockerfile @@ -1,3 +1,3 @@ FROM ghcr.io/actions/actions-runner:latest -RUN sudo apt update && sudo apt install git -y +RUN sudo apt update && sudo apt install git libvips-dev -y From a66e54166c4c56116bf45b86067bcb96991d8f96 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 09:17:56 +0200 Subject: [PATCH 11/32] Change to github runner with image --- .github/workflows/build-documentation.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml index a57097772e..ba8d0a9f3e 100644 --- a/.github/workflows/build-documentation.yml +++ b/.github/workflows/build-documentation.yml @@ -1,4 +1,4 @@ -name: Deploy to GitHub Pages +name: Deploy Documentation on: push: @@ -11,7 +11,9 @@ on: jobs: deploy: name: Deploy to GitHub Pages - runs-on: arc-runner-set + runs-on: ubuntu-latest + container: + image: ghcr.io/gabber235/typewriter-runner:latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 From f52fb069899a3469e7d79c502e5194cc97c3e2ca Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 09:34:42 +0200 Subject: [PATCH 12/32] Install libvips-dev manually --- .github/workflows/build-documentation.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml index ba8d0a9f3e..96e36c7ba8 100644 --- a/.github/workflows/build-documentation.yml +++ b/.github/workflows/build-documentation.yml @@ -12,10 +12,9 @@ jobs: deploy: name: Deploy to GitHub Pages runs-on: ubuntu-latest - container: - image: ghcr.io/gabber235/typewriter-runner:latest steps: - uses: actions/checkout@v3 + - run: apt update && apt install libvips-dev -y - uses: actions/setup-node@v3 with: node-version: 18 From 483e9b1c2a9b02d28f34ecfdf58b1bef45901be3 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 09:35:29 +0200 Subject: [PATCH 13/32] Add sudo --- .github/workflows/build-documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml index 96e36c7ba8..98411e37e5 100644 --- a/.github/workflows/build-documentation.yml +++ b/.github/workflows/build-documentation.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - run: apt update && apt install libvips-dev -y + - run: sudo apt update && sudo apt install libvips-dev -y - uses: actions/setup-node@v3 with: node-version: 18 From 7917ce3d02c2e47f9caa416deff6e8de45771ab5 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 10:27:28 +0200 Subject: [PATCH 14/32] Change image generation --- documentation/package-lock.json | 215 +++++++++++++++--- documentation/package.json | 4 +- .../plugins/code-snippets/snippets.json | 118 ++++++---- documentation/plugins/compression/index.js | 17 +- documentation/src/components/Image/index.tsx | 32 ++- 5 files changed, 297 insertions(+), 89 deletions(-) diff --git a/documentation/package-lock.json b/documentation/package-lock.json index b522731ab2..7d82419db7 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -27,14 +27,14 @@ "devDependencies": { "@docusaurus/lqip-loader": "^3.5.1", "@docusaurus/module-type-aliases": "^3.5.1", - "@docusaurus/responsive-loader": "^1.7.0", "@docusaurus/tsconfig": "^3.5.1", "@docusaurus/types": "^3.5.1", "@iconify/react": "^5.0.2", "@types/react": "^18.3.3", "autoprefixer": "^10.4.20", "postcss": "^8.4.41", - "sharp": "^0.33.4", + "responsive-loader": "^3.1.2", + "sharp": "^0.33.5", "tailwindcss": "^3.4.9", "typescript": "^5.5.4" }, @@ -2868,31 +2868,6 @@ "react-dom": "^18.0.0" } }, - "node_modules/@docusaurus/responsive-loader": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@docusaurus/responsive-loader/-/responsive-loader-1.7.0.tgz", - "integrity": "sha512-N0cWuVqTRXRvkBxeMQcy/OF2l7GN8rmni5EzR3HpwR+iU2ckYPnziceojcxvvxQ5NqZg1QfEW0tycQgHp+e+Nw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "loader-utils": "^2.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "jimp": "*", - "sharp": "*" - }, - "peerDependenciesMeta": { - "jimp": { - "optional": true - }, - "sharp": { - "optional": true - } - } - }, "node_modules/@docusaurus/theme-classic": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", @@ -6369,6 +6344,13 @@ "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", "license": "ISC" }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -10783,6 +10765,32 @@ "yallist": "^3.0.2" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/markdown-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", @@ -16307,6 +16315,159 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/responsive-loader": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/responsive-loader/-/responsive-loader-3.1.2.tgz", + "integrity": "sha512-6UOrSdEkifzxnQPnUFwa3HqXlnHmYEWBIg3zRveuk7VbLhnuNCiKbx0jGs7071Gm10rhSb6seEC+bApSjkX3wA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/node": "^18.11.9", + "find-cache-dir": "^3.3.2", + "json5": "^2.2.1", + "loader-utils": "^3.2.1", + "make-dir": "^3.1.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.22.1" + }, + "peerDependencies": { + "webpack": "^5.73.0" + }, + "peerDependenciesMeta": { + "jimp": { + "optional": true + }, + "sharp": { + "optional": true + } + } + }, + "node_modules/responsive-loader/node_modules/@types/node": { + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/responsive-loader/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/responsive-loader/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/responsive-loader/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/responsive-loader/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/responsive-loader/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/responsive-loader/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/responsive-loader/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/responsive-loader/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/responsive-loader/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", diff --git a/documentation/package.json b/documentation/package.json index 787e18e505..4e44c0479b 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -34,14 +34,14 @@ "devDependencies": { "@docusaurus/lqip-loader": "^3.5.1", "@docusaurus/module-type-aliases": "^3.5.1", - "@docusaurus/responsive-loader": "^1.7.0", "@docusaurus/tsconfig": "^3.5.1", "@docusaurus/types": "^3.5.1", "@iconify/react": "^5.0.2", "@types/react": "^18.3.3", "autoprefixer": "^10.4.20", "postcss": "^8.4.41", - "sharp": "^0.33.4", + "responsive-loader": "^3.1.2", + "sharp": "^0.33.5", "tailwindcss": "^3.4.9", "typescript": "^5.5.4" }, diff --git a/documentation/plugins/code-snippets/snippets.json b/documentation/plugins/code-snippets/snippets.json index 4a27ba930a..09b958319a 100644 --- a/documentation/plugins/code-snippets/snippets.json +++ b/documentation/plugins/code-snippets/snippets.json @@ -1,62 +1,98 @@ { + "initializer": { + "file": "src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt", + "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Initializer\n\n@Initializer\nobject ExampleInitializer : Initializable {\n override fun initialize() {\n // Do something when the extension is initialized\n }\n\n override fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" + }, + "cinematic_entry": { + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "content": "@Entry(\"example_cinematic\", \"An example cinematic entry\", Colors.BLUE, \"material-symbols:cinematic-blur\")\nclass ExampleCinematicEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n val segments: List = emptyList(),\n) : CinematicEntry {\n override fun create(player: Player): CinematicAction {\n return ExampleCinematicAction(player, this)\n }\n}" + }, + "cinematic_segment_with_min_max": { + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "content": " @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n @InnerMin(Min(10))\n @InnerMax(Max(20))\n val segments: List = emptyList()," + }, + "cinematic_create_actions": { + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "content": " // This will be used when the cinematic is normally displayed to the player.\n override fun create(player: Player): CinematicAction {\n return DefaultCinematicAction(player, this)\n }\n\n // This is used during content mode to display the cinematic to the player.\n // It may be null to not show it during simulation.\n override fun createSimulating(player: Player): CinematicAction? {\n return SimulatedCinematicAction(player, this)\n }\n\n // This is used during content mode to record the cinematic.\n // It may be null to not record it during simulation.\n override fun createRecording(player: Player): CinematicAction? {\n return RecordingCinematicAction(player, this)\n }" + }, + "cinematic_segment": { + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "content": "data class ExampleSegment(\n override val startFrame: Int = 0,\n override val endFrame: Int = 0,\n) : Segment" + }, + "cinematic_action": { + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "content": "class ExampleCinematicAction(\n val player: Player,\n val entry: ExampleCinematicEntry,\n) : CinematicAction {\n override suspend fun setup() {\n // Initialize variables, spawn entities, etc.\n }\n\n override suspend fun tick(frame: Int) {\n val segment = entry.segments activeSegmentAt frame\n // Can be null if no segment is active\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n\n // Execute tick logic for the segment\n }\n\n override suspend fun teardown() {\n // Remove entities, etc.\n }\n\n override fun canFinish(frame: Int): Boolean = entry.segments canFinishAt frame\n}" + }, + "cinematic_simple_action": { + "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "content": "class ExampleSimpleCinematicAction(\n val player: Player,\n entry: ExampleCinematicEntry,\n) : SimpleCinematicAction() {\n override val segments: List = entry.segments\n\n override suspend fun startSegment(segment: ExampleSegment) {\n super.startSegment(segment) // Keep this\n // Called when a segment starts\n }\n\n override suspend fun tickSegment(segment: ExampleSegment, frame: Int) {\n super.tickSegment(segment, frame) // Keep this\n // Called every tick while the segment is active\n // Will always be called after startSegment and never after stopSegment\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n }\n\n override suspend fun stopSegment(segment: ExampleSegment) {\n super.stopSegment(segment) // Keep this\n // Called when the segment ends\n // Will also be called if the cinematic is stopped early\n }\n}" + }, + "audience_entry": { + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "content": "@Entry(\"example_audience\", \"An example audience entry.\", Colors.GREEN, \"material-symbols:chat-rounded\")\nclass ExampleAudienceEntry(\n override val id: String,\n override val name: String,\n) : AudienceEntry {\n override fun display(): AudienceDisplay {\n return ExampleAudienceDisplay()\n }\n}" + }, + "audience_display": { + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "content": "class ExampleAudienceDisplay : AudienceDisplay() {\n override fun initialize() {\n // This is called when the first player is added to the audience.\n super.initialize()\n // Do something when the audience is initialized\n }\n\n override fun onPlayerAdd(player: Player) {\n // Do something when a player gets added to the audience\n }\n\n override fun onPlayerRemove(player: Player) {\n // Do something when a player gets removed from the audience\n }\n\n override fun dispose() {\n super.dispose()\n // Do something when the audience is disposed\n // It will always call onPlayerRemove for all players.\n // So no player cleanup is needed here.\n }\n}" + }, + "tickable_audience_display": { + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "content": "// highlight-next-line\nclass TickableAudienceDisplay : AudienceDisplay(), TickableDisplay {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n override fun tick() {\n // Do something when the audience is ticked\n players.forEach { player ->\n // Do something with the player\n }\n\n // This is running asynchronously\n // If you need to do something on the main thread\n ThreadType.SYNC.launch {\n // Though this will run a tick later, to sync with the bukkit scheduler.\n }\n }\n // highlight-end\n}" + }, "audience_display_with_events": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 90 + "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "content": "class AudienceDisplayWithEvents : AudienceDisplay() {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n @EventHandler\n fun onSomeEvent(event: SomeBukkitEvent) {\n // Do something when the event is triggered\n // This will trigger for all players, not just the ones in the audience.\n // So we need to check if the player is in the audience.\n if (event.player in this) {\n // Do something with the player\n }\n }\n // highlight-end\n}" + }, + "artifact_entry": { + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", + "content": "@Entry(\"example_artifact\", \"An example artifact entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleArtifactEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val artifactId: String = \"\",\n) : ArtifactEntry" }, "artifact_access": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleArtifactEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 26 + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", + "content": "suspend fun accessArtifactData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" + }, + "asset_entry": { + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", + "content": "@Entry(\"example_asset\", \"An example asset entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleAssetEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val path: String = \"\",\n) : AssetEntry" }, "asset_access": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleAssetEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 26 + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", + "content": "suspend fun accessAssetData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" }, "sound_id_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundIdEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 14 + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt", + "content": "@Entry(\"example_sound\", \"An example sound entry.\", Colors.BLUE, \"icon-park-solid:volume-up\")\nclass ExampleSoundIdEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val soundId: String = \"\",\n) : SoundIdEntry" }, "sound_source_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundSourceEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 20 + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt", + "content": "@Entry(\"example_sound_source\", \"An example sound source entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSoundSourceEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n) : SoundSourceEntry {\n override fun getEmitter(): Sound.Emitter {\n // Return the emitter that should be used for the sound.\n // A bukkit entity can be used here.\n return Sound.Emitter.self()\n }\n}" }, "speaker_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSpeakerEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 16 + "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt", + "content": "@Entry(\"example_speaker\", \"An example speaker entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSpeakerEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val displayName: String = \"\",\n override val sound: Sound = Sound.EMPTY,\n) : SpeakerEntry" }, "action_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleActionEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 26 + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt", + "content": "@Entry(\"example_action\", \"An example action entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n) : ActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply all the modifiers.\n // Do something with the player\n }\n}" }, "custom_triggering_action_entry": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleCustomTriggeringActionEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 34 + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt", + "content": "@Entry(\n \"example_custom_triggering_action\",\n \"An example custom triggering entry.\",\n Colors.RED,\n \"material-symbols:touch-app-rounded\"\n)\nclass ExampleCustomTriggeringActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n @SerializedName(\"triggers\")\n override val customTriggers: List> = emptyList(),\n) : CustomTriggeringActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply the modifiers.\n // Do something with the player\n player.triggerCustomTriggers() // Can be called later to trigger the next entries.\n }\n}" + }, + "dialogue_entry": { + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", + "content": "@Entry(\"example_dialogue\", \"An example dialogue entry.\", Colors.BLUE, \"material-symbols:chat-rounded\")\nclass ExampleDialogueEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n override val speaker: Ref = emptyRef(),\n @MultiLine\n @Placeholder\n @Colored\n @Help(\"The text to display to the player.\")\n val text: String = \"\",\n) : DialogueEntry" }, "dialogue_messenger": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleDialogueEntry.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 58 + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", + "content": "@Messenger(ExampleDialogueEntry::class)\nclass ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) :\n DialogueMessenger(player, entry) {\n\n companion object : MessengerFilter {\n override fun filter(player: Player, entry: DialogueEntry): Boolean = true\n }\n\n // Called every game tick (20 times per second).\n // The cycle is a parameter that is incremented every tick, starting at 0.\n override fun tick(playTime: Duration) {\n super.tick(playTime)\n if (state != MessengerState.RUNNING) return\n\n player.sendMessage(\"${entry.speakerDisplayName}: ${entry.text}\".parsePlaceholders(player).asMini())\n\n // When we want the dialogue to end, we can set the state to FINISHED.\n state = MessengerState.FINISHED\n }\n}" }, - "initializer": { - "file": "src\\main\\kotlin\\com\\typewritermc\\example\\ExampleInitializer.kt", - "content": "Not found", - "startLine": "N/A", - "endLine": 17 + "event_entry": { + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", + "content": "@Entry(\"example_event\", \"An example event entry.\", Colors.YELLOW, \"material-symbols:bigtop-updates\")\nclass ExampleEventEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n) : EventEntry" + }, + "event_entry_listener": { + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", + "content": "// Must be scoped to be public\n@EntryListener(ExampleEventEntry::class)\nfun onEvent(event: SomeBukkitEvent, query: Query) {\n // Do something\n val entries = query.find() // Find all the entries of this type, for more information see the Query section\n // Do something with the entries, for example trigger them\n entries triggerAllFor event.player\n}" } } \ No newline at end of file diff --git a/documentation/plugins/compression/index.js b/documentation/plugins/compression/index.js index d0856465e2..46423e84b7 100644 --- a/documentation/plugins/compression/index.js +++ b/documentation/plugins/compression/index.js @@ -17,20 +17,19 @@ export default function pluginMediaOptimizer(context, options) { module: { rules: [ { - test: /\.(png|jpe?g)$/i, + test: /\.(png|jpe?g|webp)$/i, use: [ - require.resolve('@docusaurus/lqip-loader'), { - loader: require.resolve("@docusaurus/responsive-loader"), + loader: 'responsive-loader', options: { - emitFile: !isServer, - adapter: require("@docusaurus/responsive-loader/sharp"), - name: "assets/optimized-img/[name].[hash:hex:7].[width].[ext]", + adapter: require('responsive-loader/sharp'), + name: 'assets/optimized-img/[name].[hash:hex:7].[width].[ext]', sizes: [320, 640, 960, 1280, 1600, 1920], - format: "avif", - progressive: true, + format: 'avif', quality: 60, - ...loaderOptions.image, + placeholder: true, + placeholderSize: 40, + emitFile: !isServer, }, }, ], diff --git a/documentation/src/components/Image/index.tsx b/documentation/src/components/Image/index.tsx index e763fe3467..2d0b0531a8 100644 --- a/documentation/src/components/Image/index.tsx +++ b/documentation/src/components/Image/index.tsx @@ -1,23 +1,22 @@ -import { ComponentProps } from "react"; +import { ComponentProps, useState } from "react"; export type SrcType = { width: number; path?: string; - size?: number; - format?: 'webp' | 'jpeg' | 'png' | 'gif'; + height?: number; }; export type SrcImage = { height?: number; width?: number; - preSrc: string; src: string; srcSet: string; + placeholder?: string; images: SrcType[]; }; export interface Props extends ComponentProps<'img'> { - readonly img: { default: string } | { src: SrcImage; preSrc: string } | string; + readonly img: { default: string } | SrcImage | string; } export default function Image(props: Props) { const { img, ...propsRest } = props; @@ -32,15 +31,28 @@ export default function Image(props: Props) { ); } + const [loaded, setLoaded] = useState(false); + + return ( -
+
+ onLoad={() => setLoaded(true)} + className={`rounded-md transition-opacity duration-300 ${loaded ? 'opacity-100' : 'opacity-0' + }`} + {...propsRest} + /> + {!loaded && ( +
+ )}
); } From 8d772b30a1ff74278f33e7b6479807c69017f5bd Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 11:11:03 +0200 Subject: [PATCH 15/32] Fix page tests --- app/pubspec.lock | 36 ++++++++++++++++++------------------ app/test/page_test.dart | 20 ++++++++------------ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/app/pubspec.lock b/app/pubspec.lock index 590123584f..dacbec3b54 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -58,10 +58,10 @@ packages: dependency: "direct main" description: name: audioplayers - sha256: "752039d6aa752597c98ec212e9759519061759e402e7da59a511f39d43aa07d2" + sha256: c346ba5a39dc208f1bab55fc239855f573d69b0e832402114bf0b793622adc4d url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "6.1.0" audioplayers_android: dependency: transitive description: @@ -98,10 +98,10 @@ packages: dependency: transitive description: name: audioplayers_web - sha256: db8fc420dadf80da18e2286c18e746fb4c3b2c5adbf0c963299dde046828886d + sha256: "3609bdf0e05e66a3d9750ee40b1e37f2a622c4edb796cc600b53a90a30a2ace4" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.1" audioplayers_windows: dependency: transitive description: @@ -114,18 +114,18 @@ packages: dependency: "direct main" description: name: auto_route - sha256: a9001a90539ca3effc168f7e1029a5885c7326b9032c09ac895e303c1d137704 + sha256: "8de4a280ce7861ef24a6baa14c2b02b77a8c31b4a4c4f12d7b608678cc657c7f" url: "https://pub.dev" source: hosted - version: "8.3.0" + version: "8.1.4" auto_route_generator: dependency: "direct dev" description: name: auto_route_generator - sha256: a21d7a936c917488653c972f62d884d8adcf8c5d37acc7cd24da33cf784546c0 + sha256: ba28133d3a3bf0a66772bcc98dade5843753cd9f1a8fb4802b842895515b67d3 url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.0.0" auto_size_text: dependency: "direct main" description: @@ -713,10 +713,10 @@ packages: dependency: transitive description: name: mime - sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.6" package_config: dependency: transitive description: @@ -865,18 +865,18 @@ packages: dependency: "direct main" description: name: rive - sha256: b45de4f0053e380302a7c37c0e7c7e734127d238eed23a85fe3a4b0b6faa8a5a + sha256: daa5394a7d064b4997b39e9afa02f6882c479c38b19fa0dd60f052b99c105400 url: "https://pub.dev" source: hosted - version: "0.13.12" + version: "0.13.13" rive_common: dependency: transitive description: name: rive_common - sha256: "77311538b149263d34dc29cde4e608953c2d4451233efdb874ea9f08910769ac" + sha256: c7bf0781b1621629361579c300ac2f8aa1a238227a242202a596e82becc244d7 url: "https://pub.dev" source: hosted - version: "0.4.10" + version: "0.4.11" riverpod: dependency: transitive description: @@ -1190,10 +1190,10 @@ packages: dependency: "direct main" description: name: uuid - sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" + sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77 url: "https://pub.dev" source: hosted - version: "4.4.2" + version: "4.5.0" vector_graphics: dependency: transitive description: @@ -1246,10 +1246,10 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.0.0" web_socket: dependency: transitive description: diff --git a/app/test/page_test.dart b/app/test/page_test.dart index d431707eaf..b5d7eaa84c 100644 --- a/app/test/page_test.dart +++ b/app/test/page_test.dart @@ -53,18 +53,16 @@ const entryBlueprintFields = ObjectBlueprint( void main() { test("When creating an entry expect the entry to be created", () async { final container = ProviderContainer(); - await container.read(bookProvider.notifier).createPage("test_page"); + final page = + await container.read(bookProvider.notifier).createPage("test_page"); - final page = container.read(pageProvider("test_page")); - - expect(page, isNotNull, reason: "The page has not been created"); - expect(page!.entries.length, 0); + expect(page.entries.length, 0); final entry = Entry(testEntryData); await page.createEntry(container.passing, entry); - final newPage = container.read(pageProvider("test_page")); + final newPage = container.read(pageProvider(page.id)); expect(newPage!.entries.length, 1); expect(newPage.entries[0].id, "test"); @@ -73,12 +71,10 @@ void main() { test("When creating an entry form a blueprint expect the entry to be created", () async { final container = ProviderContainer(); - await container.read(bookProvider.notifier).createPage("test_page"); - - final page = container.read(pageProvider("test_page")); + final page = + await container.read(bookProvider.notifier).createPage("test_page"); - expect(page, isNotNull, reason: "The page has not been created"); - expect(page!.entries.length, 0); + expect(page.entries.length, 0); const entry = EntryBlueprint( id: "test", @@ -90,7 +86,7 @@ void main() { await page.createEntryFromBlueprint(container.passing, entry); - final newPage = container.read(pageProvider("test_page")); + final newPage = container.read(pageProvider(page.id)); expect(newPage!.entries.length, 1); expect(newPage.entries[0].id, isNot("test")); From 3354d84e385af06c1a3cdbd9c730abe2fdd8bfa6 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 11:16:26 +0200 Subject: [PATCH 16/32] Fix Typo in build script --- .github/actions/build-engine/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/build-engine/action.yml b/.github/actions/build-engine/action.yml index b4a66bf0b3..a53007bc96 100644 --- a/.github/actions/build-engine/action.yml +++ b/.github/actions/build-engine/action.yml @@ -27,11 +27,11 @@ runs: - name: Test Paper Engine uses: gradle/gradle-build-action@v2 with: - arguments: paper-engine:test --scan + arguments: engine-paper:test --scan build-root-directory: ./engine - name: Build Plugin uses: gradle/gradle-build-action@v2 with: - arguments: paper-engine:buildRelease --scan + arguments: engine-paper:buildRelease --scan build-root-directory: ./engine From fec1538ce68f25bf52de369ecbcc26abb91c428e Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 11:49:19 +0200 Subject: [PATCH 17/32] Fix versioning requirements for extensions --- .../build-development-jars-and-publish.yml | 39 +------- extensions/BasicExtension/build.gradle.kts | 2 +- extensions/CitizensExtension/build.gradle.kts | 2 +- .../CombatLogXExtension/build.gradle.kts | 2 +- extensions/EntityExtension/build.gradle.kts | 2 +- .../MythicMobsExtension/build.gradle.kts | 2 +- .../RPGRegionsExtension/build.gradle.kts | 2 +- .../build.gradle.kts | 2 +- extensions/VaultExtension/build.gradle.kts | 2 +- .../WorldGuardExtension/build.gradle.kts | 2 +- extensions/_DocsExtension/build.gradle.kts | 2 +- extensions/build.gradle.kts | 95 ++++++++++--------- 12 files changed, 63 insertions(+), 91 deletions(-) diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 6f2f9ef0f3..8765da6850 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -27,42 +27,11 @@ jobs: - name: Build Engine uses: ./.github/actions/build-engine # ---------------------------------------------------------------------------------------------------- - - name: Build Basic Extension - uses: ./.github/actions/build-extension - with: - extension: BasicExtension - - name: Build Citizens Extension - uses: ./.github/actions/build-extension - with: - extension: CitizensExtension - - name: Build CombatLogX Extension - uses: ./.github/actions/build-extension - with: - extension: CombatLogXExtension - - name: Build MythicMobs Extension - uses: ./.github/actions/build-extension - with: - extension: MythicMobsExtension - - name: Build EntityExtension - uses: ./.github/actions/build-extension - with: - extension: EntityExtension - - name: Build RPGRegions Extension - uses: ./.github/actions/build-extension - with: - extension: RPGRegionsExtension - - name: Build SuperiorSkyblock Extension - uses: ./.github/actions/build-extension - with: - extension: SuperiorSkyblockExtension - - name: Build Vault Extension - uses: ./.github/actions/build-extension - with: - extension: VaultExtension - - name: Build WorldGuard Extension - uses: ./.github/actions/build-extension + - name: Build Extensions + uses: gradle/gradle-build-action@v2 with: - extension: WorldGuardExtension + arguments: test buildRelease --scan + build-root-directory: ./extensions # ---------------------------------------------------------------------------------------------------- - name: Publish Engine to Beta Maven Repository uses: gradle/gradle-build-action@v2 diff --git a/extensions/BasicExtension/build.gradle.kts b/extensions/BasicExtension/build.gradle.kts index 82a86c04ac..c30bfc6cc1 100644 --- a/extensions/BasicExtension/build.gradle.kts +++ b/extensions/BasicExtension/build.gradle.kts @@ -3,7 +3,7 @@ dependencies { } typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/CitizensExtension/build.gradle.kts b/extensions/CitizensExtension/build.gradle.kts index 1fa0e5f017..7b12069cff 100644 --- a/extensions/CitizensExtension/build.gradle.kts +++ b/extensions/CitizensExtension/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/CombatLogXExtension/build.gradle.kts b/extensions/CombatLogXExtension/build.gradle.kts index 74d4c56008..50ea6843e1 100644 --- a/extensions/CombatLogXExtension/build.gradle.kts +++ b/extensions/CombatLogXExtension/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/EntityExtension/build.gradle.kts b/extensions/EntityExtension/build.gradle.kts index 646daf0c89..0f2ffb17a9 100644 --- a/extensions/EntityExtension/build.gradle.kts +++ b/extensions/EntityExtension/build.gradle.kts @@ -5,7 +5,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/MythicMobsExtension/build.gradle.kts b/extensions/MythicMobsExtension/build.gradle.kts index 251db84839..d97f8ec18b 100644 --- a/extensions/MythicMobsExtension/build.gradle.kts +++ b/extensions/MythicMobsExtension/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/RPGRegionsExtension/build.gradle.kts b/extensions/RPGRegionsExtension/build.gradle.kts index 4fff6947c3..0f3e6dfe41 100644 --- a/extensions/RPGRegionsExtension/build.gradle.kts +++ b/extensions/RPGRegionsExtension/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/SuperiorSkyblockExtension/build.gradle.kts b/extensions/SuperiorSkyblockExtension/build.gradle.kts index 8991d6475f..5f3d842dd4 100644 --- a/extensions/SuperiorSkyblockExtension/build.gradle.kts +++ b/extensions/SuperiorSkyblockExtension/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/VaultExtension/build.gradle.kts b/extensions/VaultExtension/build.gradle.kts index de94a2d2ea..8360ab06c9 100644 --- a/extensions/VaultExtension/build.gradle.kts +++ b/extensions/VaultExtension/build.gradle.kts @@ -7,7 +7,7 @@ dependencies { typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/WorldGuardExtension/build.gradle.kts b/extensions/WorldGuardExtension/build.gradle.kts index 707c2746ab..90d45e8fc4 100644 --- a/extensions/WorldGuardExtension/build.gradle.kts +++ b/extensions/WorldGuardExtension/build.gradle.kts @@ -9,7 +9,7 @@ dependencies { typewriter { namespace = "typewritermc" engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } diff --git a/extensions/_DocsExtension/build.gradle.kts b/extensions/_DocsExtension/build.gradle.kts index 80d0efaf29..4599cf0a18 100644 --- a/extensions/_DocsExtension/build.gradle.kts +++ b/extensions/_DocsExtension/build.gradle.kts @@ -3,7 +3,7 @@ dependencies {} typewriter { engine { - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE } namespace = "typewritermc" diff --git a/extensions/build.gradle.kts b/extensions/build.gradle.kts index 578ec350d9..592e3eaf6f 100644 --- a/extensions/build.gradle.kts +++ b/extensions/build.gradle.kts @@ -47,63 +47,66 @@ subprojects { } } - tasks.register("buildAndMove") { - dependsOn("shadowJar") + if (!project.name.startsWith("_")) { + tasks.register("buildAndMove") { + dependsOn("shadowJar") - group = "build" - description = "Builds the jar and moves it to the server folder" - outputs.upToDateWhen { false } + group = "build" + description = "Builds the jar and moves it to the server folder" + outputs.upToDateWhen { false } - // Move the jar from the build/libs folder to the server/plugins folder - doLast { - val jar = file("build/libs/%s-%s-all.jar".format(project.name, project.version)) - val server = - file("../../server/plugins/Typewriter/extensions/%s.jar".format(project.name.capitalizeAsciiOnly())) - jar.copyTo(server, overwrite = true) + // Move the jar from the build/libs folder to the server/plugins folder + doLast { + val jar = file("build/libs/%s-%s-all.jar".format(project.name, project.version)) + val server = + file("../../server/plugins/Typewriter/extensions/%s.jar".format(project.name.capitalizeAsciiOnly())) + jar.copyTo(server, overwrite = true) + } } - } - tasks.register("buildRelease") { - dependsOn("shadowJar") - group = "build" - description = "Builds the jar and renames it" + tasks.register("buildRelease") { + onlyIf { !project.name.startsWith("_") } + dependsOn("shadowJar") + group = "build" + description = "Builds the jar and renames it" - doLast { - // Rename the jar to remove the version and -all - val jar = file("build/libs/%s-%s-all.jar".format(project.name, project.version)) - jar.renameTo(file("build/libs/%s.jar".format(project.name))) - file("build/libs/%s-%s.jar".format(project.name, project.version)).delete() + doLast { + // Rename the jar to remove the version and -all + val jar = file("build/libs/%s-%s-all.jar".format(project.name, project.version)) + jar.renameTo(file("build/libs/%s.jar".format(project.name))) + file("build/libs/%s-%s.jar".format(project.name, project.version)).delete() + } } - } - publishing { - repositories { - maven { - name = "TypewriterReleases" - url = uri("https://maven.typewritermc.com/releases") - credentials(PasswordCredentials::class) - authentication { - create("basic") + publishing { + repositories { + maven { + name = "TypewriterReleases" + url = uri("https://maven.typewritermc.com/releases") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } } - } - maven { - name = "TypewriterBeta" - url = uri("https://maven.typewritermc.com/beta") - credentials(PasswordCredentials::class) - authentication { - create("basic") + maven { + name = "TypewriterBeta" + url = uri("https://maven.typewritermc.com/beta") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } } } - } - publications { - create("maven") { - group = project.group - // Remove everything after the beta. So 1.0.0-beta-1 becomes 1.0.0 - version = project.version.toString().substringBefore("-beta") - artifactId = project.name + publications { + create("maven") { + group = project.group + // Remove everything after the beta. So 1.0.0-beta-1 becomes 1.0.0 + version = project.version.toString().substringBefore("-beta") + artifactId = project.name - from(components["kotlin"]) - artifact(tasks["shadowJar"]) + from(components["kotlin"]) + artifact(tasks["shadowJar"]) + } } } } From 827dfa5254b3e182840c6f8b71f6644d2bc3577c Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 12:18:40 +0200 Subject: [PATCH 18/32] Clean before maven publish --- extensions/build.gradle.kts | 9 ++++++--- .../moduleplugin/TypewriterModuleConfiguration.kt | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/extensions/build.gradle.kts b/extensions/build.gradle.kts index 592e3eaf6f..1092c98b69 100644 --- a/extensions/build.gradle.kts +++ b/extensions/build.gradle.kts @@ -32,7 +32,7 @@ allprojects { subprojects { group = "com.typewritermc" - version = file("../../version.txt").readText().trim() + version = file("../../version.txt").readText().trim().substringBefore("-beta") apply(plugin = "io.github.goooler.shadow") apply(plugin = "com.typewritermc.module-plugin") @@ -78,6 +78,10 @@ subprojects { } } + tasks.withType { + dependsOn("clean") + } + publishing { repositories { maven { @@ -100,8 +104,7 @@ subprojects { publications { create("maven") { group = project.group - // Remove everything after the beta. So 1.0.0-beta-1 becomes 1.0.0 - version = project.version.toString().substringBefore("-beta") + version = project.version.toString() artifactId = project.name from(components["kotlin"]) diff --git a/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt b/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt index 45a7ae22d8..9ccc07d0be 100644 --- a/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt +++ b/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt @@ -1,7 +1,6 @@ package com.typewritermc.moduleplugin import com.typewritermc.loader.ExtensionFlag -import kotlinx.serialization.MissingFieldException import kotlinx.serialization.Serializable @Serializable @@ -109,6 +108,7 @@ private const val MIN_SHORT_DESCRIPTION_LENGTH = 10 private const val MAX_SHORT_DESCRIPTION_LENGTH = 80 private const val MIN_DESCRIPTION_LENGTH = 100 private const val MAX_DESCRIPTION_LENGTH = 2000 +private val FORBIDDEN_WORDS = listOf("Adapter", "Extension") internal fun TypewriterExtensionConfiguration.validate() { if (name.isBlank()) { @@ -120,8 +120,10 @@ internal fun TypewriterExtensionConfiguration.validate() { if (!Regex("^[a-zA-Z0-9]+$").matches(name)) { throw IllegalArgumentException("Extension name '$name' must be alphanumeric.") } - if (name.contains("Extension")) { - throw IllegalArgumentException("Extension name '$name' cannot contain 'Extension'") + for (word in FORBIDDEN_WORDS) { + if (name.contains(word, ignoreCase = true)) { + throw IllegalArgumentException("Extension name '$name' cannot contain '$word'") + } } if (shortDescription.isBlank()) { From c3a1979f2cf68b393a6d4db5406630a3ce648504 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 12:27:29 +0200 Subject: [PATCH 19/32] Move Extension build after publish to repository --- .../workflows/build-development-jars-and-publish.yml | 11 +++++++++-- extensions/build.gradle.kts | 4 ---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 8765da6850..5000a347ac 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -27,10 +27,10 @@ jobs: - name: Build Engine uses: ./.github/actions/build-engine # ---------------------------------------------------------------------------------------------------- - - name: Build Extensions + - name: Test Extensions uses: gradle/gradle-build-action@v2 with: - arguments: test buildRelease --scan + arguments: test --scan build-root-directory: ./extensions # ---------------------------------------------------------------------------------------------------- - name: Publish Engine to Beta Maven Repository @@ -48,6 +48,13 @@ jobs: with: arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan build-root-directory: ./module-plugin +# ---------------------------------------------------------------------------------------------------- + # Has to be after the publish, because it needs to delete the slim jars and only keep the shadowed jars for the modrinth upload + - name: Build Extensions + uses: gradle/gradle-build-action@v2 + with: + arguments: buildRelease --scan + build-root-directory: ./extensions # ---------------------------------------------------------------------------------------------------- - name: Publish Modrinth uses: Kir-Antipov/mc-publish@v3.3 diff --git a/extensions/build.gradle.kts b/extensions/build.gradle.kts index 1092c98b69..3352b3674d 100644 --- a/extensions/build.gradle.kts +++ b/extensions/build.gradle.kts @@ -78,10 +78,6 @@ subprojects { } } - tasks.withType { - dependsOn("clean") - } - publishing { repositories { maven { From 7e4f20ed088f8dc3692a17a681a94cd80005232b Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 12:40:33 +0200 Subject: [PATCH 20/32] Get the paper engine --- .github/workflows/build-development-jars-and-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 5000a347ac..df7c54f52e 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -64,9 +64,9 @@ jobs: modrinth-token: ${{ secrets.MODRINTH_TOKEN }} modrinth-featured: false files: | - plugin/build/libs/typewriter.jar + engine/engine-paper/build/libs/Typewriter.jar extensions/**/build/libs/*.jar - name: "Typewriter v${{ steps.vars.outputs.version }} Development Build" + name: "Typewriter v${{ steps.vars.outputs.version }} Beta Build" version: "${{ steps.vars.outputs.version }}" version-type: "beta" loaders: | From 6869a0d011085b4dbf15f0c229919f5f76c9d520 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 16:34:17 +0200 Subject: [PATCH 21/32] Publish engine-paper to hangar --- .github/workflows/build-development-jars-and-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index df7c54f52e..0bf8b5e128 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -82,8 +82,8 @@ jobs: env: HANGAR_API_TOKEN: ${{ secrets.HANGAR_API_TOKEN }} with: - arguments: publishPluginPublicationToHangar --scan - build-root-directory: ./plugin + arguments: engine-paper:publishPluginPublicationToHangar --scan + build-root-directory: ./engine - name: Add Tag uses: mathieudutour/github-tag-action@v6.2 with: From f44b9bda6252fe6f5ef82562541cee2f44ebf327 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 16:36:51 +0200 Subject: [PATCH 22/32] Bump mc support version to 1.21.1 --- .github/workflows/build-development-jars-and-publish.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 0bf8b5e128..2dfaf8e95b 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -66,13 +66,13 @@ jobs: files: | engine/engine-paper/build/libs/Typewriter.jar extensions/**/build/libs/*.jar - name: "Typewriter v${{ steps.vars.outputs.version }} Beta Build" + name: "Typewriter v${{ steps.vars.outputs.version }} Build" version: "${{ steps.vars.outputs.version }}" version-type: "beta" loaders: | paper game-versions: | - [1.21] + [1.21, 1.21.1] dependencies: | packetevents @@ -96,9 +96,9 @@ jobs: with: webhook: ${{ secrets.DISCORD_WEBHOOK }} nodetail: true - title: Published Development Build + title: Published Beta Build description: | - I have published a development build of Typewriter. + I have published a beta build of Typewriter. Version: ${{ steps.vars.outputs.version }} [Download](https://modrinth.com/plugin/typewriter/version/${{ steps.publish.outputs.modrinth-version }}) - name: Notify Winston From 4e5f7ced161d2e55365d70adc5fd0524afa1d6ff Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Thu, 5 Sep 2024 16:40:43 +0200 Subject: [PATCH 23/32] Include github token --- .github/workflows/build-development-jars-and-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 2dfaf8e95b..bdd761edd8 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -87,7 +87,7 @@ jobs: - name: Add Tag uses: mathieudutour/github-tag-action@v6.2 with: - github_token: ${{ env.github-token }} + github_token: ${{ secrets.GITHUB_TOKEN }} default_bump: false custom_tag: "${{ steps.vars.outputs.version }}" release_branches: develop From ff65c4eaadd8ef5f2ba51f4435a2e59b6fd499fc Mon Sep 17 00:00:00 2001 From: Marten Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Thu, 5 Sep 2024 18:13:39 +0200 Subject: [PATCH 24/32] [Docs] Small changes --- documentation/.vscode/settings.json | 3 ++- documentation/docusaurus.config.js | 4 ++-- documentation/src/theme/MDXComponents/Img/index.tsx | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/documentation/.vscode/settings.json b/documentation/.vscode/settings.json index 7cac7fdb2e..ed71be179a 100644 --- a/documentation/.vscode/settings.json +++ b/documentation/.vscode/settings.json @@ -12,5 +12,6 @@ "triggerable" ], "todo-tree.tree.showBadges": true, - "todo-tree.tree.showCountsInTree": true + "todo-tree.tree.showCountsInTree": true, + "files.eol": "\n" } diff --git a/documentation/docusaurus.config.js b/documentation/docusaurus.config.js index 7948440af8..b0ef12557e 100644 --- a/documentation/docusaurus.config.js +++ b/documentation/docusaurus.config.js @@ -120,9 +120,9 @@ const config = { label: 'Documentation', }, { - type: 'docsVersion', + type: 'docSidebar', label: 'Extensions', - to: '/adapters', + sidebarId: 'adapters', position: 'left', }, { diff --git a/documentation/src/theme/MDXComponents/Img/index.tsx b/documentation/src/theme/MDXComponents/Img/index.tsx index 45a6dcb213..a3bfe55097 100644 --- a/documentation/src/theme/MDXComponents/Img/index.tsx +++ b/documentation/src/theme/MDXComponents/Img/index.tsx @@ -10,7 +10,7 @@ function transformImgClassName(className?: string): string { export default function MDXImg(props: Props): JSX.Element { // If the type is not gif. We should use the Image component - if (!props.src.endsWith(".gif")) { + if (!(props.src ?? "").endsWith(".gif")) { return ( Image component not found, please report this in the
TypeWriter Discord. From c1c04717180d424ca1ed1d07dffbc1e538b720e9 Mon Sep 17 00:00:00 2001 From: Marten Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Thu, 5 Sep 2024 18:13:50 +0200 Subject: [PATCH 25/32] [Docs] Navbar changes --- .../src/theme/NavbarItem/ComponentTypes.tsx | 25 +++ .../theme/NavbarItem/DefaultNavbarItem.tsx | 59 ++++++ .../src/theme/NavbarItem/DocNavbarItem.tsx | 36 ++++ .../theme/NavbarItem/DocSidebarNavbarItem.tsx | 47 +++++ .../DocsVersionDropdownNavbarItem.tsx | 108 +++++++++++ .../theme/NavbarItem/DocsVersionNavbarItem.js | 16 -- .../NavbarItem/DocsVersionNavbarItem.tsx | 20 ++ .../NavbarItem/DropdownNavbarItem/index.tsx | 176 ++++++++++++++++++ .../DropdownNavbarItem/styles.module.css | 3 + .../src/theme/NavbarItem/HtmlNavbarItem.tsx | 25 +++ .../LocaleDropdownNavbarItem/index.tsx | 76 ++++++++ .../styles.module.css | 4 + .../src/theme/NavbarItem/NavbarNavLink.tsx | 67 +++++++ .../src/theme/NavbarItem/SearchNavbarItem.tsx | 19 ++ documentation/src/theme/NavbarItem/index.tsx | 21 +++ 15 files changed, 686 insertions(+), 16 deletions(-) create mode 100644 documentation/src/theme/NavbarItem/ComponentTypes.tsx create mode 100644 documentation/src/theme/NavbarItem/DefaultNavbarItem.tsx create mode 100644 documentation/src/theme/NavbarItem/DocNavbarItem.tsx create mode 100644 documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx create mode 100644 documentation/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx delete mode 100644 documentation/src/theme/NavbarItem/DocsVersionNavbarItem.js create mode 100644 documentation/src/theme/NavbarItem/DocsVersionNavbarItem.tsx create mode 100644 documentation/src/theme/NavbarItem/DropdownNavbarItem/index.tsx create mode 100644 documentation/src/theme/NavbarItem/DropdownNavbarItem/styles.module.css create mode 100644 documentation/src/theme/NavbarItem/HtmlNavbarItem.tsx create mode 100644 documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx create mode 100644 documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css create mode 100644 documentation/src/theme/NavbarItem/NavbarNavLink.tsx create mode 100644 documentation/src/theme/NavbarItem/SearchNavbarItem.tsx create mode 100644 documentation/src/theme/NavbarItem/index.tsx diff --git a/documentation/src/theme/NavbarItem/ComponentTypes.tsx b/documentation/src/theme/NavbarItem/ComponentTypes.tsx new file mode 100644 index 0000000000..df6a5f2b5a --- /dev/null +++ b/documentation/src/theme/NavbarItem/ComponentTypes.tsx @@ -0,0 +1,25 @@ +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; +import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem'; +import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem'; +import HtmlNavbarItem from '@theme/NavbarItem/HtmlNavbarItem'; +import DocNavbarItem from '@theme/NavbarItem/DocNavbarItem'; +import DocSidebarNavbarItem from '@theme/NavbarItem/DocSidebarNavbarItem'; +import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem'; +import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; + +import type {ComponentTypesObject} from '@theme/NavbarItem/ComponentTypes'; + +const ComponentTypes: ComponentTypesObject = { + default: DefaultNavbarItem, + localeDropdown: LocaleDropdownNavbarItem, + search: SearchNavbarItem, + dropdown: DropdownNavbarItem, + html: HtmlNavbarItem, + doc: DocNavbarItem, + docSidebar: DocSidebarNavbarItem, + docsVersion: DocsVersionNavbarItem, + docsVersionDropdown: DocsVersionDropdownNavbarItem, +}; + +export default ComponentTypes; diff --git a/documentation/src/theme/NavbarItem/DefaultNavbarItem.tsx b/documentation/src/theme/NavbarItem/DefaultNavbarItem.tsx new file mode 100644 index 0000000000..b63d9711ec --- /dev/null +++ b/documentation/src/theme/NavbarItem/DefaultNavbarItem.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import clsx from 'clsx'; +import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink'; +import type { + DesktopOrMobileNavBarItemProps, + Props, +} from '@theme/NavbarItem/DefaultNavbarItem'; + +function DefaultNavbarItemDesktop({ + className, + isDropdownItem = false, + ...props +}: DesktopOrMobileNavBarItemProps) { + const element = ( + + ); + + if (isDropdownItem) { + return
  • {element}
  • ; + } + + return element; +} + +function DefaultNavbarItemMobile({ + className, + isDropdownItem, + ...props +}: DesktopOrMobileNavBarItemProps) { + return ( +
  • + +
  • + ); +} + +export default function DefaultNavbarItem({ + mobile = false, + position, // Need to destructure position from props so that it doesn't get passed on. + ...props +}: Props): JSX.Element { + const Comp = mobile ? DefaultNavbarItemMobile : DefaultNavbarItemDesktop; + return ( + + ); +} diff --git a/documentation/src/theme/NavbarItem/DocNavbarItem.tsx b/documentation/src/theme/NavbarItem/DocNavbarItem.tsx new file mode 100644 index 0000000000..b6daeae5ee --- /dev/null +++ b/documentation/src/theme/NavbarItem/DocNavbarItem.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { + useActiveDocContext, + useLayoutDoc, +} from '@docusaurus/plugin-content-docs/client'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import type {Props} from '@theme/NavbarItem/DocNavbarItem'; + +export default function DocNavbarItem({ + docId, + label: staticLabel, + docsPluginId, + ...props +}: Props): JSX.Element | null { + const {activeDoc} = useActiveDocContext(docsPluginId); + const doc = useLayoutDoc(docId, docsPluginId); + const pageActive = activeDoc?.path === doc?.path; + + // Draft and unlisted items are not displayed in the navbar. + if (doc === null || (doc.unlisted && !pageActive)) { + return null; + } + + return ( + + pageActive || + (!!activeDoc?.sidebar && activeDoc.sidebar === doc.sidebar) + } + label={staticLabel ?? doc.id} + to={doc.path} + /> + ); +} diff --git a/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx b/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx new file mode 100644 index 0000000000..6432ccdab7 --- /dev/null +++ b/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { + useActiveDocContext, + useLayoutDocsSidebar, + useActiveVersion, + useLatestVersion, +} from '@docusaurus/plugin-content-docs/client'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import type {Props} from '@theme/NavbarItem/DocSidebarNavbarItem'; + +export default function DocSidebarNavbarItem({ + sidebarId, + label, + docsPluginId, + ...props +}: Props): JSX.Element { + const {activeDoc} = useActiveDocContext(docsPluginId); + const sidebarLink = useLayoutDocsSidebar(sidebarId, docsPluginId).link; + + const activeVersion = useActiveVersion(docsPluginId)?.name; + + if (!sidebarLink) { + throw new Error( + `DocSidebarNavbarItem: Sidebar with ID "${sidebarId}" doesn't have anything to be linked to.`, + ); + } + + // Adjust label based on the active version + console.log(activeVersion); + console.log(label); + console.log(activeVersion <= '0.5.0'); + console.log(sidebarLink.path); + const adjustedLabel = + label === 'Extensions' && activeVersion && activeVersion <= '0.5.0' + ? 'Adapters' + : label; + + return ( + activeDoc?.sidebar === sidebarId} + label={adjustedLabel ?? sidebarLink.label} + to={sidebarLink.path} + /> + ); +} diff --git a/documentation/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/documentation/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx new file mode 100644 index 0000000000..34538cf2e0 --- /dev/null +++ b/documentation/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -0,0 +1,108 @@ +import React from 'react'; +import { + useVersions, + useActiveDocContext, + useDocsVersionCandidates, + useDocsPreferredVersion, +} from '@docusaurus/plugin-content-docs/client'; +import {translate} from '@docusaurus/Translate'; +import {useLocation} from '@docusaurus/router'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; +import type {Props} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; +import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; +import type { + GlobalVersion, + GlobalDoc, + ActiveDocContext, +} from '@docusaurus/plugin-content-docs/client'; + +function getVersionMainDoc(version: GlobalVersion): GlobalDoc { + return version.docs.find((doc) => doc.id === version.mainDocId)!; +} + +function getVersionTargetDoc( + version: GlobalVersion, + activeDocContext: ActiveDocContext, +): GlobalDoc { + // We try to link to the same doc, in another version + // When not possible, fallback to the "main doc" of the version + return ( + activeDocContext.alternateDocVersions[version.name] ?? + getVersionMainDoc(version) + ); +} + +export default function DocsVersionDropdownNavbarItem({ + mobile, + docsPluginId, + dropdownActiveClassDisabled, + dropdownItemsBefore, + dropdownItemsAfter, + ...props +}: Props): JSX.Element { + const {search, hash} = useLocation(); + const activeDocContext = useActiveDocContext(docsPluginId); + const versions = useVersions(docsPluginId); + const {savePreferredVersionName} = useDocsPreferredVersion(docsPluginId); + + function versionToLink(version: GlobalVersion): LinkLikeNavbarItemProps { + const targetDoc = getVersionTargetDoc(version, activeDocContext); + return { + label: version.label, + // preserve ?search#hash suffix on version switches + to: `${targetDoc.path}${search}${hash}`, + isActive: () => version === activeDocContext.activeVersion, + onClick: () => savePreferredVersionName(version.name), + }; + } + + const items: LinkLikeNavbarItemProps[] = [ + ...dropdownItemsBefore, + ...versions.map(versionToLink), + ...dropdownItemsAfter, + ]; + + const dropdownVersion = useDocsVersionCandidates(docsPluginId)[0]; + + // Mobile dropdown is handled a bit differently + const dropdownLabel = + mobile && items.length > 1 + ? translate({ + id: 'theme.navbar.mobileVersionsDropdown.label', + message: 'Versions', + description: + 'The label for the navbar versions dropdown on mobile view', + }) + : dropdownVersion.label; + const dropdownTo = + mobile && items.length > 1 + ? undefined + : getVersionTargetDoc(dropdownVersion, activeDocContext).path; + + // We don't want to render a version dropdown with 0 or 1 item. If we build + // the site with a single docs version (onlyIncludeVersions: ['1.0.0']), + // We'd rather render a button instead of a dropdown + if (items.length <= 1) { + return ( + false : undefined} + /> + ); + } + + return ( + false : undefined} + /> + ); +} diff --git a/documentation/src/theme/NavbarItem/DocsVersionNavbarItem.js b/documentation/src/theme/NavbarItem/DocsVersionNavbarItem.js deleted file mode 100644 index 7f155ac228..0000000000 --- a/documentation/src/theme/NavbarItem/DocsVersionNavbarItem.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import { useDocsVersionCandidates } from '@docusaurus/plugin-content-docs/client'; -import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; -const getVersionMainDoc = (version) => - version.docs.find((doc) => doc.id === version.mainDocId); -export default function DocsVersionNavbarItem({ - label: staticLabel, - to: staticTo, - docsPluginId, - ...props -}) { - const version = useDocsVersionCandidates(docsPluginId)[0]; - const label = staticLabel ?? version.label; - const path = staticTo ?? getVersionMainDoc(version).path; - return ; -} diff --git a/documentation/src/theme/NavbarItem/DocsVersionNavbarItem.tsx b/documentation/src/theme/NavbarItem/DocsVersionNavbarItem.tsx new file mode 100644 index 0000000000..54b760e0fc --- /dev/null +++ b/documentation/src/theme/NavbarItem/DocsVersionNavbarItem.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import {useDocsVersionCandidates} from '@docusaurus/plugin-content-docs/client'; +import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; +import type {Props} from '@theme/NavbarItem/DocsVersionNavbarItem'; +import type {GlobalVersion} from '@docusaurus/plugin-content-docs/client'; + +const getVersionMainDoc = (version: GlobalVersion) => + version.docs.find((doc) => doc.id === version.mainDocId)!; + +export default function DocsVersionNavbarItem({ + label: staticLabel, + to: staticTo, + docsPluginId, + ...props +}: Props): JSX.Element { + const version = useDocsVersionCandidates(docsPluginId)[0]; + const label = staticLabel ?? version.label; + const path = staticTo ?? getVersionMainDoc(version).path; + return ; +} diff --git a/documentation/src/theme/NavbarItem/DropdownNavbarItem/index.tsx b/documentation/src/theme/NavbarItem/DropdownNavbarItem/index.tsx new file mode 100644 index 0000000000..faf2513d7e --- /dev/null +++ b/documentation/src/theme/NavbarItem/DropdownNavbarItem/index.tsx @@ -0,0 +1,176 @@ +import React, {useState, useRef, useEffect} from 'react'; +import clsx from 'clsx'; +import { + isRegexpStringMatch, + useCollapsible, + Collapsible, +} from '@docusaurus/theme-common'; +import {isSamePath, useLocalPathname} from '@docusaurus/theme-common/internal'; +import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink'; +import NavbarItem, {type LinkLikeNavbarItemProps} from '@theme/NavbarItem'; +import type { + DesktopOrMobileNavBarItemProps, + Props, +} from '@theme/NavbarItem/DropdownNavbarItem'; +import styles from './styles.module.css'; + +function isItemActive( + item: LinkLikeNavbarItemProps, + localPathname: string, +): boolean { + if (isSamePath(item.to, localPathname)) { + return true; + } + if (isRegexpStringMatch(item.activeBaseRegex, localPathname)) { + return true; + } + if (item.activeBasePath && localPathname.startsWith(item.activeBasePath)) { + return true; + } + return false; +} + +function containsActiveItems( + items: readonly LinkLikeNavbarItemProps[], + localPathname: string, +): boolean { + return items.some((item) => isItemActive(item, localPathname)); +} + +function DropdownNavbarItemDesktop({ + items, + position, + className, + onClick, + ...props +}: DesktopOrMobileNavBarItemProps) { + const dropdownRef = useRef(null); + const [showDropdown, setShowDropdown] = useState(false); + + useEffect(() => { + const handleClickOutside = ( + event: MouseEvent | TouchEvent | FocusEvent, + ) => { + if ( + !dropdownRef.current || + dropdownRef.current.contains(event.target as Node) + ) { + return; + } + setShowDropdown(false); + }; + + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('touchstart', handleClickOutside); + document.addEventListener('focusin', handleClickOutside); + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('touchstart', handleClickOutside); + document.removeEventListener('focusin', handleClickOutside); + }; + }, [dropdownRef]); + + return ( +
    + tag focusable in case no link target + // See https://github.com/facebook/docusaurus/pull/6003 + // There's probably a better solution though... + href={props.to ? undefined : '#'} + className={clsx('navbar__link', className)} + {...props} + onClick={props.to ? undefined : (e) => e.preventDefault()} + onKeyDown={(e) => { + if (e.key === 'Enter') { + e.preventDefault(); + setShowDropdown(!showDropdown); + } + }}> + {props.children ?? props.label} + +
      + {items.map((childItemProps, i) => ( + + ))} +
    +
    + ); +} + +function DropdownNavbarItemMobile({ + items, + className, + position, // Need to destructure position from props so that it doesn't get passed on. + onClick, + ...props +}: DesktopOrMobileNavBarItemProps) { + const localPathname = useLocalPathname(); + const containsActive = containsActiveItems(items, localPathname); + + const {collapsed, toggleCollapsed, setCollapsed} = useCollapsible({ + initialState: () => !containsActive, + }); + + // Expand/collapse if any item active after a navigation + useEffect(() => { + if (containsActive) { + setCollapsed(!containsActive); + } + }, [localPathname, containsActive, setCollapsed]); + + return ( +
  • + { + e.preventDefault(); + toggleCollapsed(); + }}> + {props.children ?? props.label} + + + {items.map((childItemProps, i) => ( + + ))} + +
  • + ); +} + +export default function DropdownNavbarItem({ + mobile = false, + ...props +}: Props): JSX.Element { + const Comp = mobile ? DropdownNavbarItemMobile : DropdownNavbarItemDesktop; + return ; +} diff --git a/documentation/src/theme/NavbarItem/DropdownNavbarItem/styles.module.css b/documentation/src/theme/NavbarItem/DropdownNavbarItem/styles.module.css new file mode 100644 index 0000000000..10ee92f520 --- /dev/null +++ b/documentation/src/theme/NavbarItem/DropdownNavbarItem/styles.module.css @@ -0,0 +1,3 @@ +.dropdownNavbarItemMobile { + cursor: pointer; +} diff --git a/documentation/src/theme/NavbarItem/HtmlNavbarItem.tsx b/documentation/src/theme/NavbarItem/HtmlNavbarItem.tsx new file mode 100644 index 0000000000..0cf87193c2 --- /dev/null +++ b/documentation/src/theme/NavbarItem/HtmlNavbarItem.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import clsx from 'clsx'; + +import type {Props} from '@theme/NavbarItem/HtmlNavbarItem'; + +export default function HtmlNavbarItem({ + value, + className, + mobile = false, + isDropdownItem = false, +}: Props): JSX.Element { + const Comp = isDropdownItem ? 'li' : 'div'; + return ( + + ); +} diff --git a/documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx b/documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx new file mode 100644 index 0000000000..c5f877394c --- /dev/null +++ b/documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import {useAlternatePageUtils} from '@docusaurus/theme-common/internal'; +import {translate} from '@docusaurus/Translate'; +import {useLocation} from '@docusaurus/router'; +import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; +import IconLanguage from '@theme/Icon/Language'; +import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; +import type {Props} from '@theme/NavbarItem/LocaleDropdownNavbarItem'; + +import styles from './styles.module.css'; + +export default function LocaleDropdownNavbarItem({ + mobile, + dropdownItemsBefore, + dropdownItemsAfter, + queryString = '', + ...props +}: Props): JSX.Element { + const { + i18n: {currentLocale, locales, localeConfigs}, + } = useDocusaurusContext(); + const alternatePageUtils = useAlternatePageUtils(); + const {search, hash} = useLocation(); + + const localeItems = locales.map((locale): LinkLikeNavbarItemProps => { + const baseTo = `pathname://${alternatePageUtils.createUrl({ + locale, + fullyQualified: false, + })}`; + // preserve ?search#hash suffix on locale switches + const to = `${baseTo}${search}${hash}${queryString}`; + return { + label: localeConfigs[locale]!.label, + lang: localeConfigs[locale]!.htmlLang, + to, + target: '_self', + autoAddBaseUrl: false, + className: + // eslint-disable-next-line no-nested-ternary + locale === currentLocale + ? // Similar idea as DefaultNavbarItem: select the right Infima active + // class name. This cannot be substituted with isActive, because the + // target URLs contain `pathname://` and therefore are not NavLinks! + mobile + ? 'menu__link--active' + : 'dropdown__link--active' + : '', + }; + }); + + const items = [...dropdownItemsBefore, ...localeItems, ...dropdownItemsAfter]; + + // Mobile is handled a bit differently + const dropdownLabel = mobile + ? translate({ + message: 'Languages', + id: 'theme.navbar.mobileLanguageDropdown.label', + description: 'The label for the mobile language switcher dropdown', + }) + : localeConfigs[currentLocale]!.label; + + return ( + + + {dropdownLabel} + + } + items={items} + /> + ); +} diff --git a/documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css b/documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css new file mode 100644 index 0000000000..8804a08ea6 --- /dev/null +++ b/documentation/src/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css @@ -0,0 +1,4 @@ +.iconLanguage { + vertical-align: text-bottom; + margin-right: 5px; +} diff --git a/documentation/src/theme/NavbarItem/NavbarNavLink.tsx b/documentation/src/theme/NavbarItem/NavbarNavLink.tsx new file mode 100644 index 0000000000..a85c8a90e2 --- /dev/null +++ b/documentation/src/theme/NavbarItem/NavbarNavLink.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import isInternalUrl from '@docusaurus/isInternalUrl'; +import {isRegexpStringMatch} from '@docusaurus/theme-common'; +import IconExternalLink from '@theme/Icon/ExternalLink'; +import type {Props} from '@theme/NavbarItem/NavbarNavLink'; + +export default function NavbarNavLink({ + activeBasePath, + activeBaseRegex, + to, + href, + label, + html, + isDropdownLink, + prependBaseUrlToHref, + ...props +}: Props): JSX.Element { + // TODO all this seems hacky + // {to: 'version'} should probably be forbidden, in favor of {to: '/version'} + const toUrl = useBaseUrl(to); + const activeBaseUrl = useBaseUrl(activeBasePath); + const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true}); + const isExternalLink = label && href && !isInternalUrl(href); + + // Link content is set through html XOR label + const linkContentProps = html + ? {dangerouslySetInnerHTML: {__html: html}} + : { + children: ( + <> + {label} + {isExternalLink && ( + + )} + + ), + }; + + if (href) { + return ( + + ); + } + + return ( + + activeBaseRegex + ? isRegexpStringMatch(activeBaseRegex, location.pathname) + : location.pathname.startsWith(activeBaseUrl), + })} + {...props} + {...linkContentProps} + /> + ); +} diff --git a/documentation/src/theme/NavbarItem/SearchNavbarItem.tsx b/documentation/src/theme/NavbarItem/SearchNavbarItem.tsx new file mode 100644 index 0000000000..87c05f3c4e --- /dev/null +++ b/documentation/src/theme/NavbarItem/SearchNavbarItem.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import SearchBar from '@theme/SearchBar'; +import NavbarSearch from '@theme/Navbar/Search'; +import type {Props} from '@theme/NavbarItem/SearchNavbarItem'; + +export default function SearchNavbarItem({ + mobile, + className, +}: Props): JSX.Element | null { + if (mobile) { + return null; + } + + return ( + + + + ); +} diff --git a/documentation/src/theme/NavbarItem/index.tsx b/documentation/src/theme/NavbarItem/index.tsx new file mode 100644 index 0000000000..45bb2bb2ee --- /dev/null +++ b/documentation/src/theme/NavbarItem/index.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import ComponentTypes from '@theme/NavbarItem/ComponentTypes'; +import type {NavbarItemType, Props} from '@theme/NavbarItem'; + +function normalizeComponentType(type: NavbarItemType, props: object) { + // Backward compatibility: navbar item with no type set + // but containing dropdown items should use the type "dropdown" + if (!type || type === 'default') { + return 'items' in props ? 'dropdown' : 'default'; + } + return type; +} + +export default function NavbarItem({type, ...props}: Props): JSX.Element { + const componentType = normalizeComponentType(type, props); + const NavbarItemComponent = ComponentTypes[componentType]; + if (!NavbarItemComponent) { + throw new Error(`No NavbarItem component found for type "${type}".`); + } + return ; +} From e581bfc11656858f2db58fed258adf41b2e86143 Mon Sep 17 00:00:00 2001 From: Marten Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Thu, 5 Sep 2024 18:22:03 +0200 Subject: [PATCH 26/32] =?UTF-8?q?[Docs]=20Forgot=20to=20remove=20debug=20m?= =?UTF-8?q?essages=20=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugins/code-snippets/snippets.json | 54 +++++++++---------- .../theme/NavbarItem/DocSidebarNavbarItem.tsx | 5 -- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/documentation/plugins/code-snippets/snippets.json b/documentation/plugins/code-snippets/snippets.json index 09b958319a..634a0ba7b0 100644 --- a/documentation/plugins/code-snippets/snippets.json +++ b/documentation/plugins/code-snippets/snippets.json @@ -1,98 +1,98 @@ { - "initializer": { - "file": "src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt", - "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Initializer\n\n@Initializer\nobject ExampleInitializer : Initializable {\n override fun initialize() {\n // Do something when the extension is initialized\n }\n\n override fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" - }, "cinematic_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", "content": "@Entry(\"example_cinematic\", \"An example cinematic entry\", Colors.BLUE, \"material-symbols:cinematic-blur\")\nclass ExampleCinematicEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n val segments: List = emptyList(),\n) : CinematicEntry {\n override fun create(player: Player): CinematicAction {\n return ExampleCinematicAction(player, this)\n }\n}" }, "cinematic_segment_with_min_max": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", "content": " @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n @InnerMin(Min(10))\n @InnerMax(Max(20))\n val segments: List = emptyList()," }, "cinematic_create_actions": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", "content": " // This will be used when the cinematic is normally displayed to the player.\n override fun create(player: Player): CinematicAction {\n return DefaultCinematicAction(player, this)\n }\n\n // This is used during content mode to display the cinematic to the player.\n // It may be null to not show it during simulation.\n override fun createSimulating(player: Player): CinematicAction? {\n return SimulatedCinematicAction(player, this)\n }\n\n // This is used during content mode to record the cinematic.\n // It may be null to not record it during simulation.\n override fun createRecording(player: Player): CinematicAction? {\n return RecordingCinematicAction(player, this)\n }" }, "cinematic_segment": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", "content": "data class ExampleSegment(\n override val startFrame: Int = 0,\n override val endFrame: Int = 0,\n) : Segment" }, "cinematic_action": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", "content": "class ExampleCinematicAction(\n val player: Player,\n val entry: ExampleCinematicEntry,\n) : CinematicAction {\n override suspend fun setup() {\n // Initialize variables, spawn entities, etc.\n }\n\n override suspend fun tick(frame: Int) {\n val segment = entry.segments activeSegmentAt frame\n // Can be null if no segment is active\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n\n // Execute tick logic for the segment\n }\n\n override suspend fun teardown() {\n // Remove entities, etc.\n }\n\n override fun canFinish(frame: Int): Boolean = entry.segments canFinishAt frame\n}" }, "cinematic_simple_action": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\cinematic\\ExampleCinematicEntry.kt", "content": "class ExampleSimpleCinematicAction(\n val player: Player,\n entry: ExampleCinematicEntry,\n) : SimpleCinematicAction() {\n override val segments: List = entry.segments\n\n override suspend fun startSegment(segment: ExampleSegment) {\n super.startSegment(segment) // Keep this\n // Called when a segment starts\n }\n\n override suspend fun tickSegment(segment: ExampleSegment, frame: Int) {\n super.tickSegment(segment, frame) // Keep this\n // Called every tick while the segment is active\n // Will always be called after startSegment and never after stopSegment\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n }\n\n override suspend fun stopSegment(segment: ExampleSegment) {\n super.stopSegment(segment) // Keep this\n // Called when the segment ends\n // Will also be called if the cinematic is stopped early\n }\n}" }, "audience_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", "content": "@Entry(\"example_audience\", \"An example audience entry.\", Colors.GREEN, \"material-symbols:chat-rounded\")\nclass ExampleAudienceEntry(\n override val id: String,\n override val name: String,\n) : AudienceEntry {\n override fun display(): AudienceDisplay {\n return ExampleAudienceDisplay()\n }\n}" }, "audience_display": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", "content": "class ExampleAudienceDisplay : AudienceDisplay() {\n override fun initialize() {\n // This is called when the first player is added to the audience.\n super.initialize()\n // Do something when the audience is initialized\n }\n\n override fun onPlayerAdd(player: Player) {\n // Do something when a player gets added to the audience\n }\n\n override fun onPlayerRemove(player: Player) {\n // Do something when a player gets removed from the audience\n }\n\n override fun dispose() {\n super.dispose()\n // Do something when the audience is disposed\n // It will always call onPlayerRemove for all players.\n // So no player cleanup is needed here.\n }\n}" }, "tickable_audience_display": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", "content": "// highlight-next-line\nclass TickableAudienceDisplay : AudienceDisplay(), TickableDisplay {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n override fun tick() {\n // Do something when the audience is ticked\n players.forEach { player ->\n // Do something with the player\n }\n\n // This is running asynchronously\n // If you need to do something on the main thread\n ThreadType.SYNC.launch {\n // Though this will run a tick later, to sync with the bukkit scheduler.\n }\n }\n // highlight-end\n}" }, "audience_display_with_events": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", "content": "class AudienceDisplayWithEvents : AudienceDisplay() {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n @EventHandler\n fun onSomeEvent(event: SomeBukkitEvent) {\n // Do something when the event is triggered\n // This will trigger for all players, not just the ones in the audience.\n // So we need to check if the player is in the audience.\n if (event.player in this) {\n // Do something with the player\n }\n }\n // highlight-end\n}" }, "artifact_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleArtifactEntry.kt", "content": "@Entry(\"example_artifact\", \"An example artifact entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleArtifactEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val artifactId: String = \"\",\n) : ArtifactEntry" }, "artifact_access": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleArtifactEntry.kt", "content": "suspend fun accessArtifactData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" }, "asset_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleAssetEntry.kt", "content": "@Entry(\"example_asset\", \"An example asset entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleAssetEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val path: String = \"\",\n) : AssetEntry" }, "asset_access": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleAssetEntry.kt", "content": "suspend fun accessAssetData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" }, "sound_id_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundIdEntry.kt", "content": "@Entry(\"example_sound\", \"An example sound entry.\", Colors.BLUE, \"icon-park-solid:volume-up\")\nclass ExampleSoundIdEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val soundId: String = \"\",\n) : SoundIdEntry" }, "sound_source_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundSourceEntry.kt", "content": "@Entry(\"example_sound_source\", \"An example sound source entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSoundSourceEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n) : SoundSourceEntry {\n override fun getEmitter(): Sound.Emitter {\n // Return the emitter that should be used for the sound.\n // A bukkit entity can be used here.\n return Sound.Emitter.self()\n }\n}" }, "speaker_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSpeakerEntry.kt", "content": "@Entry(\"example_speaker\", \"An example speaker entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSpeakerEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val displayName: String = \"\",\n override val sound: Sound = Sound.EMPTY,\n) : SpeakerEntry" }, "action_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleActionEntry.kt", "content": "@Entry(\"example_action\", \"An example action entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n) : ActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply all the modifiers.\n // Do something with the player\n }\n}" }, "custom_triggering_action_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleCustomTriggeringActionEntry.kt", "content": "@Entry(\n \"example_custom_triggering_action\",\n \"An example custom triggering entry.\",\n Colors.RED,\n \"material-symbols:touch-app-rounded\"\n)\nclass ExampleCustomTriggeringActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n @SerializedName(\"triggers\")\n override val customTriggers: List> = emptyList(),\n) : CustomTriggeringActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply the modifiers.\n // Do something with the player\n player.triggerCustomTriggers() // Can be called later to trigger the next entries.\n }\n}" }, "dialogue_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleDialogueEntry.kt", "content": "@Entry(\"example_dialogue\", \"An example dialogue entry.\", Colors.BLUE, \"material-symbols:chat-rounded\")\nclass ExampleDialogueEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n override val speaker: Ref = emptyRef(),\n @MultiLine\n @Placeholder\n @Colored\n @Help(\"The text to display to the player.\")\n val text: String = \"\",\n) : DialogueEntry" }, "dialogue_messenger": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleDialogueEntry.kt", "content": "@Messenger(ExampleDialogueEntry::class)\nclass ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) :\n DialogueMessenger(player, entry) {\n\n companion object : MessengerFilter {\n override fun filter(player: Player, entry: DialogueEntry): Boolean = true\n }\n\n // Called every game tick (20 times per second).\n // The cycle is a parameter that is incremented every tick, starting at 0.\n override fun tick(playTime: Duration) {\n super.tick(playTime)\n if (state != MessengerState.RUNNING) return\n\n player.sendMessage(\"${entry.speakerDisplayName}: ${entry.text}\".parsePlaceholders(player).asMini())\n\n // When we want the dialogue to end, we can set the state to FINISHED.\n state = MessengerState.FINISHED\n }\n}" }, "event_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleEventEntry.kt", "content": "@Entry(\"example_event\", \"An example event entry.\", Colors.YELLOW, \"material-symbols:bigtop-updates\")\nclass ExampleEventEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n) : EventEntry" }, "event_entry_listener": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleEventEntry.kt", "content": "// Must be scoped to be public\n@EntryListener(ExampleEventEntry::class)\nfun onEvent(event: SomeBukkitEvent, query: Query) {\n // Do something\n val entries = query.find() // Find all the entries of this type, for more information see the Query section\n // Do something with the entries, for example trigger them\n entries triggerAllFor event.player\n}" + }, + "initializer": { + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\ExampleInitializer.kt", + "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Initializer\n\n@Initializer\nobject ExampleInitializer : Initializable {\n override fun initialize() {\n // Do something when the extension is initialized\n }\n\n override fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" } } \ No newline at end of file diff --git a/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx b/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx index 6432ccdab7..99dee80133 100644 --- a/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx +++ b/documentation/src/theme/NavbarItem/DocSidebarNavbarItem.tsx @@ -3,7 +3,6 @@ import { useActiveDocContext, useLayoutDocsSidebar, useActiveVersion, - useLatestVersion, } from '@docusaurus/plugin-content-docs/client'; import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; import type {Props} from '@theme/NavbarItem/DocSidebarNavbarItem'; @@ -26,10 +25,6 @@ export default function DocSidebarNavbarItem({ } // Adjust label based on the active version - console.log(activeVersion); - console.log(label); - console.log(activeVersion <= '0.5.0'); - console.log(sidebarLink.path); const adjustedLabel = label === 'Extensions' && activeVersion && activeVersion <= '0.5.0' ? 'Adapters' From cd8ac5e57458fa2331c2c5ae196841e186655908 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 6 Sep 2024 09:18:25 +0200 Subject: [PATCH 27/32] Make sure an npc doesn't go through negative nodes --- .../engine/paper/entry/roadnetwork/gps/GPS.kt | 38 +++++++++++++------ .../activity/NavigationActivityTask.kt | 38 ++++++++++++++++--- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt index 1c5c6eecb9..45f1f864a7 100644 --- a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/roadnetwork/gps/GPS.kt @@ -2,16 +2,19 @@ package com.typewritermc.engine.paper.entry.roadnetwork.gps import com.extollit.gaming.ai.path.HydrazinePathFinder import com.extollit.gaming.ai.path.model.* +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.utils.point.Vector import com.typewritermc.engine.paper.entry.entity.toProperty +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry import com.typewritermc.engine.paper.entry.entries.RoadNode import com.typewritermc.engine.paper.entry.entries.roadNetworkMaxDistance import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFEmptyEntity import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace -import com.typewritermc.core.utils.point.Vector import com.typewritermc.engine.paper.utils.distanceSqrt import org.bukkit.Location interface GPS { + val roadNetwork: Ref suspend fun findPath(): Result> } @@ -23,7 +26,6 @@ data class GPSEdge( val isFastTravel: Boolean get() = weight == 0.0 } - fun roadNetworkFindPath( start: RoadNode, end: RoadNode, @@ -31,6 +33,16 @@ fun roadNetworkFindPath( instance: PFInstanceSpace = PFInstanceSpace(start.location.world), nodes: List = emptyList(), negativeNodes: List = emptyList(), +): IPath? { + return roadNetworkFindPath(start, end, HydrazinePathFinder(entity, instance), nodes, negativeNodes) +} + +fun roadNetworkFindPath( + start: RoadNode, + end: RoadNode, + pathfinder: HydrazinePathFinder, + nodes: List = emptyList(), + negativeNodes: List = emptyList(), ): IPath? { val interestingNodes = nodes.filter { if (it.id == start.id) return@filter false @@ -42,25 +54,29 @@ fun roadNetworkFindPath( distance > it.radius * it.radius && distance < roadNetworkMaxDistance * roadNetworkMaxDistance } - val pathfinder = HydrazinePathFinder(entity, instance) - val additionalRadius = entity.width().toDouble() + val additionalRadius = pathfinder.subject().width().toDouble() - // When the pathfinder wants to go through another intermediary node, we know that we probably want to use that. - // So we don't want this edge to be used. - pathfinder.withGraphNodeFilter { node -> - if (node.isInRangeOf(interestingNegativeNodes, additionalRadius)) return@withGraphNodeFilter Passibility.dangerous - node.passibility() + // We want to avoid going through negative nodes + if (interestingNegativeNodes.isNotEmpty()) { + pathfinder.withGraphNodeFilter { node -> + if (node.isInRangeOf(interestingNegativeNodes, additionalRadius)) { + return@withGraphNodeFilter Passibility.dangerous + } + node.passibility() + } } + // When the pathfinder wants to go through another intermediary node, we know that we probably want to use that. + // So we don't want this edge to be used. val path = pathfinder.computePathTo(end.location.x, end.location.y, end.location.z) ?: return null - if (path.any { it.isInRangeOf(interestingNodes, additionalRadius) }) { + if (interestingNodes.isNotEmpty() && path.any { it.isInRangeOf(interestingNodes, additionalRadius) }) { return null } return path } -private fun INode.isInRangeOf(roadNodes: List, additionalRadius: Double = 0.0): Boolean { +fun INode.isInRangeOf(roadNodes: List, additionalRadius: Double = 0.0): Boolean { return roadNodes.any { roadNode -> val point = this.coordinates().toVector().mid() val radius = roadNode.radius + additionalRadius diff --git a/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/activity/NavigationActivityTask.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/activity/NavigationActivityTask.kt index 9236d53a18..1b84d77f04 100644 --- a/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/activity/NavigationActivityTask.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/activity/NavigationActivityTask.kt @@ -6,10 +6,15 @@ import com.extollit.gaming.ai.path.model.IPath import com.extollit.gaming.ai.path.model.IPathingEntity import com.extollit.gaming.ai.path.model.Passibility import com.extollit.linalg.immutable.Vec3d +import com.typewritermc.core.entries.Ref import com.typewritermc.core.utils.point.Vector import com.typewritermc.engine.paper.entry.entity.* +import com.typewritermc.engine.paper.entry.entries.RoadNetworkEntry +import com.typewritermc.engine.paper.entry.entries.roadNetworkMaxDistance +import com.typewritermc.engine.paper.entry.roadnetwork.RoadNetworkManager import com.typewritermc.engine.paper.entry.roadnetwork.gps.GPS import com.typewritermc.engine.paper.entry.roadnetwork.gps.GPSEdge +import com.typewritermc.engine.paper.entry.roadnetwork.gps.isInRangeOf import com.typewritermc.engine.paper.entry.roadnetwork.gps.toVector import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFCapabilities import com.typewritermc.engine.paper.entry.roadnetwork.pathfinding.PFInstanceSpace @@ -17,6 +22,7 @@ import com.typewritermc.engine.paper.logger import com.typewritermc.engine.paper.utils.* import kotlinx.coroutines.Job import org.bukkit.util.BoundingBox +import org.koin.java.KoinJavaComponent.get import kotlin.math.atan2 import kotlin.math.cos import kotlin.math.min @@ -24,7 +30,7 @@ import kotlin.math.sin class NavigationActivity( - gps: GPS, + private val gps: GPS, startLocation: PositionProperty, ) : GenericEntityActivity { private var path: List? = null @@ -49,7 +55,7 @@ class NavigationActivity( state = when { currentEdge.isFastTravel -> NavigationActivityTaskState.FastTravel(currentEdge) - context.isViewed -> NavigationActivityTaskState.Walking(currentEdge, currentPosition) + context.isViewed -> NavigationActivityTaskState.Walking(gps.roadNetwork, currentEdge, currentPosition) else -> NavigationActivityTaskState.FakeNavigation(currentEdge) } @@ -59,7 +65,7 @@ class NavigationActivity( // The fake navigation is used to improve the performance, it however, goes through buildings // So, we switch to walking when the entity is viewed if (state is NavigationActivityTaskState.FakeNavigation && context.isViewed) { - this.state = NavigationActivityTaskState.Walking(state.edge, currentPosition) + this.state = NavigationActivityTaskState.Walking(gps.roadNetwork, state.edge, currentPosition) } // And we switch back to fake navigation when the entity is not viewed @@ -133,7 +139,11 @@ private sealed interface NavigationActivityTaskState { override fun isComplete(): Boolean = true } - class Walking(val edge: GPSEdge, startLocation: PositionProperty) : NavigationActivityTaskState, IPathingEntity { + class Walking( + roadNetwork: Ref, + val edge: GPSEdge, + startLocation: PositionProperty + ) : NavigationActivityTaskState, IPathingEntity { private var location: PositionProperty = startLocation private var path: IPath? @@ -148,7 +158,25 @@ private sealed interface NavigationActivityTaskState { val instance = PFInstanceSpace(startLocation.toBukkitLocation().world) navigator = HydrazinePathFinder(this, instance) - path = navigator.initiatePathTo(edge.end.x, edge.end.y, edge.end.z) + // We want to avoid going through negative nodes + // Since we just queried the network, it is likely that the network is already loaded. + get(RoadNetworkManager::class.java).getNetworkOrNull(roadNetwork)?.let { network -> + val interestingNegativeNodes = network.negativeNodes.filter { + val distance = edge.start.distanceSqrt(it.location) ?: 0.0 + distance > it.radius * it.radius && distance < roadNetworkMaxDistance * roadNetworkMaxDistance + } + val additionalRadius = navigator.subject().width().toDouble() + + navigator.withGraphNodeFilter { node -> + if (node.isInRangeOf(interestingNegativeNodes, additionalRadius)) { + return@withGraphNodeFilter Passibility.dangerous + } + node.passibility() + } + } + + + path = navigator.computePathTo(edge.end.x, edge.end.y, edge.end.z) } override fun location(): PositionProperty = location From a80c494c07e3720f2522d0a20d74ed28558b26c9 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 6 Sep 2024 09:44:13 +0200 Subject: [PATCH 28/32] Rename thread when tied to task --- discord_bot/src/discord/create_task.rs | 6 +++++- discord_bot/src/webhooks/tasks.rs | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/discord_bot/src/discord/create_task.rs b/discord_bot/src/discord/create_task.rs index 2111bb9147..302dc1a904 100644 --- a/discord_bot/src/discord/create_task.rs +++ b/discord_bot/src/discord/create_task.rs @@ -4,7 +4,7 @@ use crate::{ Context, WinstonError, }; use poise::{ - serenity_prelude::{CreateEmbed, CreateMessage}, + serenity_prelude::{CreateEmbed, CreateMessage, EditThread}, CreateReply, }; @@ -79,6 +79,10 @@ pub async fn create_task( ) .await?; + channel + .edit_thread(ctx, EditThread::default().name(title)) + .await?; + Ok(()) } diff --git a/discord_bot/src/webhooks/tasks.rs b/discord_bot/src/webhooks/tasks.rs index 330f8ad8e8..02929d9dc2 100644 --- a/discord_bot/src/webhooks/tasks.rs +++ b/discord_bot/src/webhooks/tasks.rs @@ -91,6 +91,7 @@ async fn update_discord_channel(task_id: &str, moved: bool) -> Result<(), Winsto .edit_thread( &discord, EditThread::default() + .name(task.name) .applied_tags(new_tags) .locked(lock) .archived(lock), From 5c2ac539302c204ae91d743a9ea35e8be9b51ea9 Mon Sep 17 00:00:00 2001 From: Marten-Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:22:43 +0200 Subject: [PATCH 29/32] [Docs] Made browser do not open in dev mode --- documentation/package-lock.json | 5 +++++ documentation/package.json | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/documentation/package-lock.json b/documentation/package-lock.json index 7d82419db7..458553d4e5 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -15,6 +15,7 @@ "@mdx-js/react": "^3.0.1", "@rive-app/react-canvas": "^4.13.5", "clsx": "^2.1.1", + "documentation": "file:", "posthog-docusaurus": "^2.0.1", "prism-react-renderer": "^2.3.1", "react": "^18.3.1", @@ -7792,6 +7793,10 @@ "node": ">=6" } }, + "node_modules/documentation": { + "resolved": "", + "link": true + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", diff --git a/documentation/package.json b/documentation/package.json index 4e44c0479b..b39fd7df46 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "start": "docusaurus start", + "start": "docusaurus start --no-open", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", @@ -22,6 +22,7 @@ "@mdx-js/react": "^3.0.1", "@rive-app/react-canvas": "^4.13.5", "clsx": "^2.1.1", + "documentation": "file:", "posthog-docusaurus": "^2.0.1", "prism-react-renderer": "^2.3.1", "react": "^18.3.1", From 9e1837b0e81ac0764d4acf15802f920c911e412d Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 6 Sep 2024 09:56:33 +0200 Subject: [PATCH 30/32] Only cancel dialogue by command interuption when in dialogue --- .../engine/paper/interaction/InteractionHandler.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt index a4b50b1c2d..6e2a0bc21e 100644 --- a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/interaction/InteractionHandler.kt @@ -144,6 +144,11 @@ class InteractionHandler : Listener, KoinComponent { command.startsWith(it.command) } if (entry != null) return + + // If no dialogue is active, we don't want to cancel any who would be triggered by this. + val inDialogue = event.player.interaction?.hasDialogue ?: false + if (!inDialogue) return + DIALOGUE_END triggerFor event.player } From 1abca7b8865e988764513c10c462cc78bab84d44 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 6 Sep 2024 15:21:16 +0200 Subject: [PATCH 31/32] Update only the thread name when it has changed --- discord_bot/src/webhooks/tasks.rs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/discord_bot/src/webhooks/tasks.rs b/discord_bot/src/webhooks/tasks.rs index 02929d9dc2..c6a1fbcef2 100644 --- a/discord_bot/src/webhooks/tasks.rs +++ b/discord_bot/src/webhooks/tasks.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; use indoc::formatdoc; use itertools::Itertools; use poise::serenity_prelude::{ - ButtonStyle, ChannelId, CreateButton, CreateMessage, EditThread, ForumTag, ForumTagId, - Mentionable, ReactionType, UserId, + futures::TryFutureExt, ButtonStyle, ChannelId, CreateButton, CreateMessage, EditThread, + ForumTag, ForumTagId, Mentionable, ReactionType, UserId, }; use crate::{ @@ -87,16 +87,23 @@ async fn update_discord_channel(task_id: &str, moved: bool) -> Result<(), Winsto let lock = status == TaskStatus::InProduction; - channel - .edit_thread( - &discord, - EditThread::default() - .name(task.name) - .applied_tags(new_tags) - .locked(lock) - .archived(lock), - ) - .await?; + let mut edit_thread = EditThread::default() + .applied_tags(new_tags) + .locked(lock) + .archived(lock); + + // Since discord sends a message in the thread when the name is changed, even if the name is the same. + // We only want to change the name if it is different. + if task.name + != channel + .name(&discord) + .await + .unwrap_or_else(|_| "".to_string()) + { + edit_thread = edit_thread.name(task.name); + } + + channel.edit_thread(&discord, edit_thread).await?; if !moved { return Ok(()); From 85f3873bc68f28823fc4ce99ac80c7c199e0d071 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 6 Sep 2024 16:44:01 +0200 Subject: [PATCH 32/32] Add a new command to indicate to users that they need to us the questions channel --- discord_bot/Cargo.lock | 1 + discord_bot/Cargo.toml | 1 + discord_bot/src/discord/mod.rs | 2 + discord_bot/src/discord/post_in_questions.rs | 95 +++++++++++++++++++ discord_bot/src/discord/thread_archiving.rs | 4 +- discord_bot/src/discord/thread_cleanup.rs | 26 ++--- .../src/discord/thread_closed_blocker.rs | 4 +- discord_bot/src/discord/thread_posted.rs | 4 +- .../src/discord/thread_support_answering.rs | 4 +- discord_bot/src/discord/ticket_reopen.rs | 4 +- discord_bot/src/main.rs | 10 +- discord_bot/src/webhooks/tasks.rs | 4 +- 12 files changed, 132 insertions(+), 27 deletions(-) create mode 100644 discord_bot/src/discord/post_in_questions.rs diff --git a/discord_bot/Cargo.lock b/discord_bot/Cargo.lock index 989f16aa54..bc16c84b87 100644 --- a/discord_bot/Cargo.lock +++ b/discord_bot/Cargo.lock @@ -691,6 +691,7 @@ dependencies = [ "itertools", "once_cell", "poise", + "rand", "reqwest", "serde", "serde_json", diff --git a/discord_bot/Cargo.toml b/discord_bot/Cargo.toml index e4e9005923..e54cf66425 100644 --- a/discord_bot/Cargo.toml +++ b/discord_bot/Cargo.toml @@ -19,6 +19,7 @@ indoc = "2.0.4" itertools = "0.12.0" once_cell = "1.19.0" poise = "0.6.1" +rand = "0.8.5" reqwest = { version = "0.11.23", features = ["json"] } serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" diff --git a/discord_bot/src/discord/mod.rs b/discord_bot/src/discord/mod.rs index b30c30f501..4a1115962e 100644 --- a/discord_bot/src/discord/mod.rs +++ b/discord_bot/src/discord/mod.rs @@ -1,5 +1,6 @@ mod close_ticket; mod create_task; +mod post_in_questions; mod support_answering; mod task_fixed; mod thread_archiving; @@ -11,6 +12,7 @@ mod ticket_reopen; pub use close_ticket::*; pub use create_task::*; +pub use post_in_questions::*; pub use support_answering::*; pub use task_fixed::*; pub use thread_archiving::*; diff --git a/discord_bot/src/discord/post_in_questions.rs b/discord_bot/src/discord/post_in_questions.rs new file mode 100644 index 0000000000..b368096774 --- /dev/null +++ b/discord_bot/src/discord/post_in_questions.rs @@ -0,0 +1,95 @@ +use poise::{serenity_prelude::Mentionable, CreateReply}; +use rand::prelude::*; +use rand::seq::SliceRandom; +use rand::SeedableRng; +use std::time::{SystemTime, UNIX_EPOCH}; + +use crate::{check_is_contributor, Context, WinstonError, QUESTIONS_CHANNEL}; + +#[poise::command( + context_menu_command = "Post In Questions", + ephemeral, + check = "check_is_contributor" +)] +pub async fn post_in_questions( + ctx: Context<'_>, + #[description = "The message to reply to"] message: poise::serenity_prelude::Message, +) -> Result<(), WinstonError> { + let seed = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_nanos(); + let mut rng = StdRng::seed_from_u64(seed as u64); + let reply = REPLIES + .choose(&mut rng) + .unwrap_or(&"Please use the questions channel.") + .replace("{channel}", &QUESTIONS_CHANNEL.mention().to_string()); + + message.reply_ping(ctx, reply).await?; + + ctx.reply("Replied to the question with").await?; + Ok(()) +} + +const REPLIES: &[&str] = &[ +"Oops! Looks like your question took a wrong turn. The {channel} is just around the corner! 🧭", +"Hold up! Your awesome question deserves a spotlight in our dedicated {channel}. It's like VIP treatment for curiosity! ✨", +"Psst... I heard the {channel} is throwing a party, and your question is the guest of honor! πŸŽ‰", +"Alert! Question detected in a question-free zone. Quick, teleport it to the {channel} before it gets lonely! πŸš€", +"Beep boop! My question sensors are tingling. May I suggest a cozy new home for your query in our dedicated {channel}? 🏠", +"Whoa there, curious cat! Your question is purr-fect for our special {channel}. It's feline fine over there! 🐱", +"Holy guacamole! Your question is so good, it deserves its own red carpet in the {channel}. Shall we roll it out? πŸ₯‘", +"Great Scott! Your question has traveled through time and space. Quick, let's redirect it to its true destination: the {channel}! ⏰", +"Woah, easy there, speed racer! Your question's burning rubber in the wrong lane. Want to cruise over to the {channel}? 🏎️", +"Shiver me timbers! Ye be asking questions in strange waters. How about we set sail for the {channel}, matey? ☠️", +"Bazinga! Your question is so smart, it deserves to hang out with its brainy buddies in the {channel}. Wadda ya say? 🧠", +"Kaboom! Your question just exploded with awesomeness. Let's clean up the glitter and move this party to the {channel}! πŸŽ†", +"Abracadabra! Your question's magical, but it needs the special enchanted grounds of the {channel} to truly shine! ✨", +"Cowabunga, dude! Your question's surfing the wrong waves. Let's catch the perfect curl over in the {channel}! πŸ„β€β™‚οΈ", +"Great galaxies! Your question's out of this world, but it's landed in the wrong solar system. Shall we warp to the {channel}? πŸš€", +"Jeepers creepers! Your question's giving me the heebie-jeebies... of excitement! Let's exorcise it over to the {channel}! πŸ‘»", +"Holy moly guacamole! Your question's spicier than a jalapeΓ±o popper. Let's cool it off in the refreshing waters of the {channel}! 🌢️", +"Gadzooks! Your question's got more buzz than a beehive. Let's guide this busy bee to its proper flower in the {channel}! 🐝", +"Jumpin' Jehoshaphat! Your question's bouncing off the walls. Let's give it a proper trampoline in the {channel}! πŸƒβ€β™‚οΈ", +"Lickety-split! Your question's faster than greased lightning. Let's race it over to the {channel} for a photo finish! 🏁", +"Mama mia! Your question's spicier than a pepperoni pizza. Let's serve this hot slice in the {channel}! πŸ•", +"Quibble me timbers! Your question's stirring up a storm in a teacup. Let's sail these choppy waters to the {channel}! β˜•", +"Tally-ho! Your question's on a fox hunt in the wrong field. Let's guide the hounds to the {channel} for the real chase! 🦊", +"Uber-cool! Your question's chillin' like a villain in the wrong hood. Let's cruise over to the {channel} in style! 😎", +"Voila! Your question's appeared like magic, but in the wrong hat! Let's pull this rabbit out in the {channel} instead! 🎩", +"Xtra! Xtra! Read all about it! Your question's making headlines in the wrong paper. Let's print the edition in the {channel}! πŸ“°", +"Zoinks! Your question's got more mystery than a Scooby-Doo episode. Let's unmask this villain in the {channel}! πŸ•΅οΈβ€β™‚οΈ", +"Zing! Your question's sharper than a tack. Let's pin this brilliant idea in the {channel} board! πŸ“Œ", +"Aye aye, captain! Your question's sailing in uncharted waters. Let's navigate to the safe harbor of the {channel}! βš“", +"Bada bing, bada boom! Your question's explosive, but it's in the wrong fireworks show. Let's light it up in the {channel}! πŸ’₯", +"Cha-ching! Your question's worth its weight in gold. Let's cash in this treasure in the {channel}! πŸ’°", +"Gee whiz! Your question's fizzier than a shaken soda. Let's pop the top in the {channel}! πŸ₯€", +"Ipso facto! Your question's presenting its case in the wrong court. Let's adjourn to the {channel} for the verdict! βš–οΈ", +"Mamma mia! Your question's saucier than a pizza with extra toppings. Let's slice and dice in the {channel}! πŸ•", +"Oh my stars and garters! Your question's more shocking than static electricity. Let's ground ourselves in the {channel}! ⚑", +"Pish posh! Your question's fancier than a teacup at the Queen's garden party. Let's sip and chat in the {channel}! β˜•πŸ‘‘", +"Querulous quails! Your question's ruffling feathers in the wrong coop. Let's migrate to the {channel} for nesting! 🐦", +"Razzle dazzle! Your question's shinier than a disco ball. Let's boogie on over to the {channel}! πŸ•Ί", +"Upsy-daisy! Your question's tumbled into the wrong ball pit. Let's bounce over to the fun zone in the {channel}! πŸ€", +"Vroom vroom! Your question's revving its engine at the wrong starting line. Let's zoom to the real race in the {channel}! 🏎️", +"Whoop-de-doo! Your question's doing cartwheels in the wrong circus. Let's flip over to the big top in the {channel}! πŸŽͺ", +"Xylophone! Your question's playing a beautiful tune, but in the wrong orchestra pit. Let's conduct this symphony in the {channel}! 🎼", +"Yum yum! Your question's deliciously intriguing, but it's on the wrong menu. Let's serve this gourmet dish in the {channel}! 🍽️", +"Bazinga! Your question's got more twists than a pretzel factory. Let's unravel this mystery in the {channel}! πŸ₯¨", +"Cowabunga! Your question's riding a gnarly wave, dude. Let's catch the perfect curl in the {channel}! πŸ„β€β™‚οΈ", +"Dagnabbit! Your question's digging for gold in the wrong mine. Let's strike it rich in the {channel}! β›οΈπŸ’°", +"Eureka! Your question's a golden discovery, but it's floating in the wrong bathtub. Let's make a splash in the {channel}! πŸ›", +"Fiddlesticks! Your question's playing a solo when we need a full orchestra. Let's tune up in the {channel}! 🎻", +"Hocus pocus! Your question's casting spells in the wrong wizard's tower. Let's find the right potion in the {channel}! πŸ§™β€β™‚οΈ", +"Inconceivable! Your question's scaling the wrong castle wall. Let's storm the correct fortress in the {channel}! 🏰", +"Jiminy Cricket! Your question's chirping up a storm, but in the wrong garden. Let's find the right leaf in the {channel}! πŸ¦—", +"Merlin's beard! Your question's more magical than a wizard's duel. Let's cast this spell in the {channel}! πŸ§™β€β™‚οΈβœ¨", +"Noodle noggin! Your question's got my brain tied up like spaghetti. Let's untangle this pasta in the {channel}! 🍝", +"Ubiquitous unicorns! Your question's sprouting rainbows in the wrong meadow. Let's prance to the magical {channel}! πŸ¦„", +"Vertigo! Your question's got me spinning like a top. Let's find our balance in the {channel}! πŸ’«", +"Xenon! Your question's glowing brighter than a noble gas. Let's light up the {channel} with this brilliance! πŸ’‘", +"Egad! Your question's more surprising than a jack-in-the-box. Let's pop this lid in the {channel}! 🎁", +"Great Scott! Your question's generating 1.21 gigawatts of curiosity. Let's time travel to the {channel} for answers! βš‘πŸš—", +"Indubitably! Your question's more mysterious than a Sherlock Holmes case. Let's deduce the answer in the {channel}, Watson! πŸ•΅οΈβ€β™‚οΈ", +"Leaping Leprechauns! Your question's luckier than a four-leaf clover. Let's find the pot of gold in the {channel}! πŸ€", +]; diff --git a/discord_bot/src/discord/thread_archiving.rs b/discord_bot/src/discord/thread_archiving.rs index e41cbb3503..ec17ecf16f 100644 --- a/discord_bot/src/discord/thread_archiving.rs +++ b/discord_bot/src/discord/thread_archiving.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use poise::serenity_prelude::{Context, EditThread, EventHandler, GuildChannel}; -use crate::{CloseReason, TICKET_FORUM_ID}; +use crate::{CloseReason, QUESTIONS_FORUM_ID}; pub struct ThreadArchivingHandler; @@ -39,7 +39,7 @@ impl EventHandler for ThreadArchivingHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/thread_cleanup.rs b/discord_bot/src/discord/thread_cleanup.rs index 5e4405b666..87777de174 100644 --- a/discord_bot/src/discord/thread_cleanup.rs +++ b/discord_bot/src/discord/thread_cleanup.rs @@ -6,14 +6,13 @@ use poise::serenity_prelude::{ }; use crate::{ - get_discord, webhooks::GetTagId, CloseReason, WinstonError, GUILD_ID, TICKET_FORUM_ID, + get_discord, webhooks::GetTagId, CloseReason, WinstonError, GUILD_ID, QUESTIONS_CHANNEL, QUESTIONS_FORUM_ID }; pub async fn cleanup_threads() -> Result<(), WinstonError> { let discord = get_discord()?; - let channel_id: ChannelId = TICKET_FORUM_ID.into(); - let guild_channel = channel_id + let guild_channel = QUESTIONS_CHANNEL .to_channel(&discord) .await? .guild() @@ -64,7 +63,7 @@ async fn is_ticket_forum_thread(channel: &channel::GuildChannel) -> bool { return false; }; - parent.get() == TICKET_FORUM_ID + parent.get() == QUESTIONS_FORUM_ID } async fn archive_thread( @@ -109,6 +108,16 @@ async fn resolve_answered_thread( println!("Auto Resolving thread {} ({})", thread.id, thread.name()); + + // Close the thread + let Some(resolved_tag) = available_tags.get_tag_id("resolved") else { + return Err(WinstonError::TagNotFound("resolved".to_string())); + }; + + thread + .edit_thread(&discord, EditThread::default().applied_tags([resolved_tag])) + .await?; + let owner_id = thread.owner_id.ok_or(WinstonError::NotAThreadChannel)?; thread @@ -135,15 +144,6 @@ async fn resolve_answered_thread( ) .await?; - // Close the thread - let Some(resolved_tag) = available_tags.get_tag_id("resolved") else { - return Err(WinstonError::TagNotFound("resolved".to_string())); - }; - - thread - .edit_thread(&discord, EditThread::default().applied_tags([resolved_tag])) - .await?; - Ok(()) } diff --git a/discord_bot/src/discord/thread_closed_blocker.rs b/discord_bot/src/discord/thread_closed_blocker.rs index c2d753da00..9d4d0411a2 100644 --- a/discord_bot/src/discord/thread_closed_blocker.rs +++ b/discord_bot/src/discord/thread_closed_blocker.rs @@ -4,7 +4,7 @@ use poise::serenity_prelude::{ Context, CreateMessage, EditMessage, EventHandler, Mentionable, Message, }; -use crate::{CloseReason, TICKET_FORUM_ID}; +use crate::{CloseReason, QUESTIONS_FORUM_ID}; pub struct ThreadClosedBlockerHandler; @@ -40,7 +40,7 @@ impl EventHandler for ThreadClosedBlockerHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/thread_posted.rs b/discord_bot/src/discord/thread_posted.rs index afe9e8d31d..aa783b9388 100644 --- a/discord_bot/src/discord/thread_posted.rs +++ b/discord_bot/src/discord/thread_posted.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use poise::serenity_prelude::{Context, EditThread, EventHandler, GuildChannel}; -use crate::{webhooks::GetTagId, TICKET_FORUM_ID}; +use crate::{webhooks::GetTagId, QUESTIONS_FORUM_ID}; pub struct ThreadPostedHandler; @@ -23,7 +23,7 @@ impl EventHandler for ThreadPostedHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/thread_support_answering.rs b/discord_bot/src/discord/thread_support_answering.rs index 51f97b90d6..debb8b2213 100644 --- a/discord_bot/src/discord/thread_support_answering.rs +++ b/discord_bot/src/discord/thread_support_answering.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use poise::serenity_prelude::{Context, EditThread, EventHandler, Message}; -use crate::{webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, GUILD_ID, TICKET_FORUM_ID}; +use crate::{webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, GUILD_ID, QUESTIONS_FORUM_ID}; pub struct SupportAnsweringHandler; @@ -37,7 +37,7 @@ impl EventHandler for SupportAnsweringHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/discord/ticket_reopen.rs b/discord_bot/src/discord/ticket_reopen.rs index 222bbc5d95..6b4571dc7c 100644 --- a/discord_bot/src/discord/ticket_reopen.rs +++ b/discord_bot/src/discord/ticket_reopen.rs @@ -5,7 +5,7 @@ use poise::serenity_prelude::{ CreateQuickModal, EditThread, EventHandler, Interaction, Timestamp, }; -use crate::{check_permissions, webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, TICKET_FORUM_ID}; +use crate::{check_permissions, webhooks::GetTagId, CONTRIBUTOR_ROLE_ID, QUESTIONS_FORUM_ID}; pub struct TicketReopenHandler; @@ -79,7 +79,7 @@ impl EventHandler for TicketReopenHandler { return; }; - if parent.id != TICKET_FORUM_ID { + if parent.id != QUESTIONS_FORUM_ID { return; } diff --git a/discord_bot/src/main.rs b/discord_bot/src/main.rs index 678695d837..901818aea6 100644 --- a/discord_bot/src/main.rs +++ b/discord_bot/src/main.rs @@ -26,7 +26,8 @@ pub type ApplicationContext<'a> = poise::ApplicationContext<'a, Data, WinstonErr const GUILD_ID: serenity::GuildId = serenity::GuildId::new(1054708062520360960); const CONTRIBUTOR_ROLE_ID: serenity::RoleId = serenity::RoleId::new(1054708457535713350); -const TICKET_FORUM_ID: u64 = 1199700329948782613; +const QUESTIONS_FORUM_ID: u64 = 1199700329948782613; +const QUESTIONS_CHANNEL: serenity::ChannelId = serenity::ChannelId::new(QUESTIONS_FORUM_ID); const CLICKUP_LIST_ID: &str = "901502296591"; const CLICKUP_USER_ID: u32 = 62541886; @@ -127,7 +128,12 @@ async fn startup_discord_bot() { let framework = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![create_task(), close_ticket(), support_answering()], + commands: vec![ + create_task(), + close_ticket(), + support_answering(), + post_in_questions(), + ], on_error: |error| Box::pin(on_error(error)), ..Default::default() }) diff --git a/discord_bot/src/webhooks/tasks.rs b/discord_bot/src/webhooks/tasks.rs index c6a1fbcef2..3d42c6aed0 100644 --- a/discord_bot/src/webhooks/tasks.rs +++ b/discord_bot/src/webhooks/tasks.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; use indoc::formatdoc; use itertools::Itertools; use poise::serenity_prelude::{ - futures::TryFutureExt, ButtonStyle, ChannelId, CreateButton, CreateMessage, EditThread, - ForumTag, ForumTagId, Mentionable, ReactionType, UserId, + ButtonStyle, ChannelId, CreateButton, CreateMessage, EditThread, ForumTag, ForumTagId, + Mentionable, ReactionType, UserId, }; use crate::{

    diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextLineWidthData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextLineWidthData.kt similarity index 70% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextLineWidthData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextLineWidthData.kt index 25ca8ecaba..ea9f415c64 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextLineWidthData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextLineWidthData.kt @@ -1,12 +1,11 @@ -package me.gabber235.typewriter.entries.data.minecraft.display.text +package com.typewritermc.entity.entries.data.minecraft.display.text -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.display.TextDisplayMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +18,6 @@ import kotlin.reflect.KClass class TextLineWidthData( override val id: String = "", override val name: String = "", - @Help("LineWidth of the TextDisplay.") val lineWidth: Int = 0, override val priorityOverride: Optional = Optional.empty(), ) : TextDisplayEntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextOpacityData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextOpacityData.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextOpacityData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextOpacityData.kt index 315dc544fd..88d04a579a 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextOpacityData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextOpacityData.kt @@ -1,14 +1,13 @@ -package me.gabber235.typewriter.entries.data.minecraft.display.text +package com.typewritermc.entity.entries.data.minecraft.display.text -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Max -import me.gabber235.typewriter.adapters.modifiers.Min -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Max +import com.typewritermc.core.extension.annotations.Min +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.display.TextDisplayMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -20,7 +19,6 @@ import kotlin.reflect.KClass class TextOpacityData( override val id: String = "", override val name: String = "", - @Help("Opacity of the TextDisplay.") @Min(-1) @Max(127) val opacity: Int = -1, @@ -33,7 +31,8 @@ class TextOpacityData( } data class TextOpacityProperty(val opacity: Byte) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(TextOpacityProperty::class, TextOpacityProperty(-1)) + companion object : + SinglePropertyCollectorSupplier(TextOpacityProperty::class, TextOpacityProperty(-1)) } fun applyTextOpacityData(entity: WrapperEntity, property: TextOpacityProperty) { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextSeeThroughData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextSeeThroughData.kt similarity index 71% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextSeeThroughData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextSeeThroughData.kt index a00696dc24..2657d5ee65 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextSeeThroughData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextSeeThroughData.kt @@ -1,12 +1,11 @@ -package me.gabber235.typewriter.entries.data.minecraft.display.text +package com.typewritermc.entity.entries.data.minecraft.display.text -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.display.TextDisplayMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +18,6 @@ import kotlin.reflect.KClass class TextSeeThroughData( override val id: String = "", override val name: String = "", - @Help("If text is see through.") val seeThrough: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : TextDisplayEntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextShadowData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextShadowData.kt similarity index 53% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextShadowData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextShadowData.kt index f21a86b731..376ffa2b70 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/display/text/TextShadowData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/display/text/TextShadowData.kt @@ -1,12 +1,11 @@ -package me.gabber235.typewriter.entries.data.minecraft.display.text +package com.typewritermc.entity.entries.data.minecraft.display.text -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.display.TextDisplayMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -18,21 +17,28 @@ import kotlin.reflect.KClass class TextShadowData( override val id: String = "", override val name: String = "", - @Help("If text has shadow.") val shadow: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : TextDisplayEntityData { - override fun type(): KClass = ShadowProperty::class + override fun type(): KClass = + ShadowProperty::class override fun build(player: Player): ShadowProperty = ShadowProperty(shadow) } data class ShadowProperty(val shadow: Boolean) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(ShadowProperty::class, ShadowProperty(false)) + companion object : + SinglePropertyCollectorSupplier( + ShadowProperty::class, + ShadowProperty(false) + ) } -fun applyShadowData(entity: WrapperEntity, property: ShadowProperty) { +fun applyShadowData( + entity: WrapperEntity, + property: ShadowProperty +) { entity.metas { meta { isShadow = property.shadow } error("Could not apply ShadowData to ${entity.entityType} entity.") diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/AgeableData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/AgeableData.kt similarity index 72% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/AgeableData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/AgeableData.kt index d861a65c2c..2b51e7a688 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/AgeableData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/AgeableData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.monster.ZoglinMeta import me.tofaa.entitylib.meta.mobs.monster.piglin.PiglinMeta import me.tofaa.entitylib.meta.mobs.monster.zombie.ZombieMeta @@ -22,7 +21,6 @@ import kotlin.reflect.KClass class AgeableData( override val id: String = "", override val name: String = "", - @Help("Whether the entity is a baby.") val baby: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/ArrowCountData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/ArrowCountData.kt similarity index 61% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/ArrowCountData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/ArrowCountData.kt index 1fb095153a..bc2fd8fe55 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/ArrowCountData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/ArrowCountData.kt @@ -1,12 +1,11 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.GenericEntityData +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.types.LivingEntityMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -17,7 +16,6 @@ import kotlin.reflect.KClass class ArrowCountData( override val id: String = "", override val name: String = "", - @Help("The amount of arrows in a entity.") val arrowCount: Int = 0, override val priorityOverride: Optional = Optional.empty(), ) : GenericEntityData { @@ -27,7 +25,8 @@ class ArrowCountData( } data class ArrowCountProperty(val arrowCount: Int) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(ArrowCountProperty::class, ArrowCountProperty(0)) + companion object : + SinglePropertyCollectorSupplier(ArrowCountProperty::class, ArrowCountProperty(0)) } fun applyArrowCountData(entity: WrapperEntity, property: ArrowCountProperty) { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/EquipmentData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/EquipmentData.kt similarity index 87% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/EquipmentData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/EquipmentData.kt index 3a97ea860e..e21eda4188 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/EquipmentData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/EquipmentData.kt @@ -1,16 +1,15 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living import com.github.retrooper.packetevents.protocol.item.ItemStack import com.github.retrooper.packetevents.protocol.player.EquipmentSlot -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.toPacketItem -import me.gabber235.typewriter.utils.Item +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.extensions.packetevents.toPacketItem +import com.typewritermc.engine.paper.utils.Item import me.tofaa.entitylib.wrapper.WrapperEntity import me.tofaa.entitylib.wrapper.WrapperLivingEntity -import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.inventory.EntityEquipment import java.util.* @@ -44,8 +43,7 @@ data class EquipmentProperty(val data: Map) : EntityPr fun EntityEquipment.toProperty(): EquipmentProperty { return EquipmentProperty(org.bukkit.inventory.EquipmentSlot.entries.mapNotNull { - // TODO: Replace this with `EquipmentSlot.BODY` when the support for 1.20.4 is dropped. - if (it.name.contains("BODY")) return@mapNotNull null + if (it == org.bukkit.inventory.EquipmentSlot.BODY) return@mapNotNull null val item = getItem(it) if (item.isEmpty) return@mapNotNull null it.toPacketEquipmentSlot() to getItem(it).toPacketItem() diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/FrogVariantData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/FrogVariantData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/FrogVariantData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/FrogVariantData.kt index eb43e126b4..99932ac46d 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/FrogVariantData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/FrogVariantData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.FrogMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -16,10 +15,9 @@ import kotlin.reflect.KClass @Entry("frog_variant_data", "Frog Variant Data", Colors.GREEN, "ph:frog-fill") @Tags("frog_data") -class FrogData ( +class FrogData( override val id: String = "", override val name: String = "", - @Help("If the entity is a frog.") val frogVariant: FrogMeta.Variant = FrogMeta.Variant.TEMPERATE, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/LivingData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/LivingData.kt similarity index 68% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/LivingData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/LivingData.kt index ba1572d4e8..b44222a70b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/LivingData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/LivingData.kt @@ -1,6 +1,6 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.EntityProperty import me.tofaa.entitylib.wrapper.WrapperEntity fun applyLivingEntityData(entity: WrapperEntity, property: EntityProperty): Boolean { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/PotionEffectColorData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/PotionEffectColorData.kt similarity index 63% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/PotionEffectColorData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/PotionEffectColorData.kt index 7695855888..9f5b0cc31e 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/PotionEffectColorData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/PotionEffectColorData.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.GenericEntityData +import com.typewritermc.engine.paper.extensions.packetevents.metas +import com.typewritermc.engine.paper.utils.Color import me.tofaa.entitylib.meta.types.LivingEntityMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -17,8 +17,7 @@ import kotlin.reflect.KClass class PotionEffectColorData( override val id: String = "", override val name: String = "", - @Help("The color of the potion effect particles.") - val color: Int = 0, + val color: Color = Color(0), override val priorityOverride: Optional = Optional.empty(), ) : GenericEntityData { override fun type(): KClass = PotionEffectColorProperty::class @@ -26,13 +25,13 @@ class PotionEffectColorData( override fun build(player: Player): PotionEffectColorProperty = PotionEffectColorProperty(color) } -data class PotionEffectColorProperty(val color: Int) : EntityProperty { +data class PotionEffectColorProperty(val color: Color) : EntityProperty { companion object : SinglePropertyCollectorSupplier(PotionEffectColorProperty::class) } fun applyPotionEffectColorData(entity: WrapperEntity, property: PotionEffectColorProperty) { entity.metas { - meta { potionEffectColor = property.color } + meta { potionEffectColor = property.color.color } error("Could not apply PotionEffectColorData to ${entity.entityType} entity.") } } \ No newline at end of file diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/SaddledData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/SaddledData.kt similarity index 68% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/SaddledData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/SaddledData.kt index 3e84004b6a..928cbce26b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/SaddledData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/SaddledData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.horse.BaseHorseMeta import me.tofaa.entitylib.meta.mobs.passive.PigMeta import me.tofaa.entitylib.wrapper.WrapperEntity @@ -17,10 +16,9 @@ import kotlin.reflect.KClass @Entry("saddled_data", "If the entity has a saddle.", Colors.RED, "game-icons:saddle") @Tags("horse_data", "pig_data", "saddled_data") -class SaddledData ( +class SaddledData( override val id: String = "", override val name: String = "", - @Help("If the entity has a saddle.") val saddled: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/SizeData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/SizeData.kt similarity index 63% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/SizeData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/SizeData.kt index 00b459d0d9..acd4be6408 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/SizeData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/SizeData.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.modifiers.Help - -import me.gabber235.typewriter.adapters.* -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.cuboid.MagmaCubeMeta import me.tofaa.entitylib.meta.mobs.cuboid.SlimeMeta import me.tofaa.entitylib.wrapper.WrapperEntity @@ -19,7 +19,6 @@ import kotlin.reflect.KClass class SizeData( override val id: String = "", override val name: String = "", - @Help("The size of the entity.") val size: Int = 1, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { @@ -34,8 +33,8 @@ data class SizeProperty(val size: Int) : EntityProperty { fun applySizeData(entity: WrapperEntity, property: SizeProperty) { entity.metas { - meta { size = property.size } - meta { size = property.size } + meta { size = property.size } + meta { size = property.size } error("Could not apply SizeData to ${entity.entityType} entity.") } } \ No newline at end of file diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/TremblingData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/TremblingData.kt similarity index 63% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/TremblingData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/TremblingData.kt index 39651ce20e..1c7250c0d3 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/TremblingData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/TremblingData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living +package com.typewritermc.entity.entries.data.minecraft.living -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.HoglinMeta import me.tofaa.entitylib.meta.mobs.monster.piglin.BasePiglinMeta import me.tofaa.entitylib.wrapper.WrapperEntity @@ -20,7 +19,6 @@ import kotlin.reflect.KClass class TremblingData( override val id: String = "", override val name: String = "", - @Help("Whether the entity is trembling.") val trembling: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { @@ -30,7 +28,8 @@ class TremblingData( } data class TremblingProperty(val trembling: Boolean) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(TremblingProperty::class, TremblingProperty(false)) + companion object : + SinglePropertyCollectorSupplier(TremblingProperty::class, TremblingProperty(false)) } fun applyTremblingData(entity: WrapperEntity, property: TremblingProperty) { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/cat/CatVariantData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/cat/CatVariantData.kt similarity index 65% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/cat/CatVariantData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/cat/CatVariantData.kt index c6fb4d5f37..401bc14aeb 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/cat/CatVariantData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/cat/CatVariantData.kt @@ -1,14 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.cat +package com.typewritermc.entity.entries.data.minecraft.living.cat -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.tameable.CatMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -20,7 +18,6 @@ import kotlin.reflect.KClass class CatVariantData ( override val id: String = "", override val name: String = "", - @Help("The variant of the cat.") val catVariant: CatMeta.Variant = CatMeta.Variant.TABBY, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt similarity index 65% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt index 31e6f6fd80..0ade11797f 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/ChestedHorseChestMeta.kt @@ -1,14 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.horse +package com.typewritermc.entity.entries.data.minecraft.living.horse -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.horse.ChestedHorseMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -17,10 +15,9 @@ import kotlin.reflect.KClass @Entry("chested_horse_chest_meta", "If the horse has a chest.", Colors.RED, "mdi:horse") @Tags("chested_horse_data", "chested_horse_chest_meta") -class ChestedHorseChestData ( +class ChestedHorseChestData( override val id: String = "", override val name: String = "", - @Help("If the horse has a chest.") val chestedHorse: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/HorseEatingData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/HorseEatingData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/HorseEatingData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/HorseEatingData.kt index baff7154c7..827b32bcf5 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/HorseEatingData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/HorseEatingData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.horse +package com.typewritermc.entity.entries.data.minecraft.living.horse -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.horse.BaseHorseMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +18,6 @@ import kotlin.reflect.KClass class HorseEatingData( override val id: String = "", override val name: String = "", - @Help("If the horse is eating.") val eating: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/HorseVariantData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/HorseVariantData.kt similarity index 68% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/HorseVariantData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/HorseVariantData.kt index 7ebfc7ba58..3dedeb5cae 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/HorseVariantData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/HorseVariantData.kt @@ -1,13 +1,11 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.horse +package com.typewritermc.entity.entries.data.minecraft.living.horse -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.horse.HorseMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +17,6 @@ import kotlin.reflect.KClass class HorseVariantData( override val id: String = "", override val name: String = "", - @Help("The variant of the horse.") val color: HorseMeta.Color = HorseMeta.Color.WHITE, val marking: HorseMeta.Marking = HorseMeta.Marking.NONE, override val priorityOverride: Optional = Optional.empty(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaVariantData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/LlamaVariantData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaVariantData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/LlamaVariantData.kt index b2e37315ac..1e7adb9be5 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/LlamaVariantData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/LlamaVariantData.kt @@ -1,14 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.horse +package com.typewritermc.entity.entries.data.minecraft.living.horse -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.horse.LlamaMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -20,7 +18,6 @@ import kotlin.reflect.KClass class LlamaVariantData( override val id: String = "", override val name: String = "", - @Help("The variant of the Llama.") val variant: LlamaMeta.Variant = LlamaMeta.Variant.CREAMY, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/RearingData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/RearingData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/RearingData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/RearingData.kt index 3d8eebf0ff..7143d30b79 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/horse/RearingData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/horse/RearingData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.horse +package com.typewritermc.entity.entries.data.minecraft.living.horse -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.horse.BaseHorseMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +18,6 @@ import kotlin.reflect.KClass class RearingData( override val id: String = "", override val name: String = "", - @Help("If the entity is rearing.") val rearing: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/parrot/ParrotColorData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/parrot/ParrotColorData.kt similarity index 57% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/parrot/ParrotColorData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/parrot/ParrotColorData.kt index 0259e61c83..48fbab251a 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/parrot/ParrotColorData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/parrot/ParrotColorData.kt @@ -1,14 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.parrot +package com.typewritermc.entity.entries.data.minecraft.living.parrot -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.GenericEntityData -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.tameable.ParrotMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -16,12 +14,11 @@ import java.util.* import kotlin.reflect.KClass @Entry("parrot_color_data", "The color of the parrot", Colors.RED, "ph:bird-fill") -@Tags("parrot_data", "parrot_color_data") -class ParrotColorData ( +@Tags("parrot_color_data", "parrot_data") +class ParrotColorData( override val id: String = "", override val name: String = "", - @Help("The color of the parrot.") - val parrotColor: ParrotMeta.Color = ParrotMeta.Color.RED_BLUE, + val parrotColor: ParrotMeta.Color = ParrotMeta.Color.RED_BLUE, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { override fun type(): KClass = ParrotColorProperty::class @@ -29,7 +26,7 @@ class ParrotColorData ( override fun build(player: Player): ParrotColorProperty = ParrotColorProperty(parrotColor) } -data class ParrotColorProperty(val parrotColor: ParrotMeta.Color ) : EntityProperty { +data class ParrotColorProperty(val parrotColor: ParrotMeta.Color) : EntityProperty { companion object : SinglePropertyCollectorSupplier(ParrotColorProperty::class) } diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/piglin/DancingData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/piglin/DancingData.kt similarity index 67% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/piglin/DancingData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/piglin/DancingData.kt index c680350c92..b49ffd2ae9 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/piglin/DancingData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/piglin/DancingData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.piglin +package com.typewritermc.entity.entries.data.minecraft.living.piglin -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.monster.piglin.PiglinMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -20,11 +19,10 @@ import kotlin.reflect.KClass Colors.RED, "streamline:travel-wayfinder-man-arm-raises-2-man-raise-arm-scaning-detect-posture-security" ) -@Tags("data", "dancing_data") +@Tags("data", "dancing_data", "piglin_data") class DancingData( override val id: String = "", override val name: String = "", - @Help("Whether the piglin is dancing.") val dancing: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/player/SkinData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/player/SkinData.kt similarity index 61% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/player/SkinData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/player/SkinData.kt index f1107f5451..75ef47f105 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/player/SkinData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/player/SkinData.kt @@ -1,10 +1,10 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.player +package com.typewritermc.entity.entries.data.minecraft.living.player -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.entity.SkinProperty -import me.gabber235.typewriter.entry.entries.EntityData +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SkinProperty +import com.typewritermc.engine.paper.entry.entries.EntityData import org.bukkit.entity.Player import java.util.* import kotlin.reflect.KClass diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/pufferfish/PuffStateData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/pufferfish/PuffStateData.kt similarity index 55% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/pufferfish/PuffStateData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/pufferfish/PuffStateData.kt index ac40047540..c9b051722b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/pufferfish/PuffStateData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/pufferfish/PuffStateData.kt @@ -1,12 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.pufferfish +package com.typewritermc.entity.entries.data.minecraft.living.pufferfish -import me.gabber235.typewriter.adapters.modifiers.Help - -import me.gabber235.typewriter.adapters.* -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.water.PufferFishMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -18,7 +18,6 @@ import kotlin.reflect.KClass class PuffStateData( override val id: String = "", override val name: String = "", - @Help("The state of the Puf entity.") val state: PufferFishMeta.State = PufferFishMeta.State.UNPUFFED, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { @@ -28,12 +27,15 @@ class PuffStateData( } data class PuffStateProperty(val state: PufferFishMeta.State) : EntityProperty { - companion object : SinglePropertyCollectorSupplier(PuffStateProperty::class, PuffStateProperty(PufferFishMeta.State.UNPUFFED)) + companion object : SinglePropertyCollectorSupplier( + PuffStateProperty::class, + PuffStateProperty(PufferFishMeta.State.UNPUFFED) + ) } fun applyPuffStateData(entity: WrapperEntity, property: PuffStateProperty) { - entity.metas { - meta { state = property.state } - error("Could not apply PufStateData to ${entity.entityType} entity.") - } + entity.metas { + meta { state = property.state } + error("Could not apply PufStateData to ${entity.entityType} entity.") + } } \ No newline at end of file diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/rabbit/RabbitTypeData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/rabbit/RabbitTypeData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/rabbit/RabbitTypeData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/rabbit/RabbitTypeData.kt index f7d26df89f..3f26532e29 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/rabbit/RabbitTypeData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/rabbit/RabbitTypeData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.rabbit +package com.typewritermc.entity.entries.data.minecraft.living.rabbit -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.passive.RabbitMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -16,10 +15,9 @@ import kotlin.reflect.KClass @Entry("rabbit_type_data", "The type of the rabbit", Colors.RED, "mdi:rabbit") @Tags("rabbit_data", "rabbit_type_data") -class RabbitTypeData ( +class RabbitTypeData( override val id: String = "", override val name: String = "", - @Help("The type of the rabbit.") val rabbitType: RabbitMeta.Type = RabbitMeta.Type.BROWN, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/scheep/ShearedData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/scheep/ShearedData.kt similarity index 65% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/scheep/ShearedData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/scheep/ShearedData.kt index 0a0f7b09ef..78db797468 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/scheep/ShearedData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/scheep/ShearedData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.scheep +package com.typewritermc.entity.entries.data.minecraft.living.scheep -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.passive.SheepMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -16,10 +15,9 @@ import kotlin.reflect.KClass @Entry("sheared_data", "If the entity is sheared.", Colors.RED, "mdi:sheep") @Tags("sheared_data") -class ShearedData ( +class ShearedData( override val id: String = "", override val name: String = "", - @Help("If the entity is sheared.") val sheared: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/villager/VillagerData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/villager/VillagerData.kt similarity index 83% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/villager/VillagerData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/villager/VillagerData.kt index e083f107b2..0c72fcae45 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/villager/VillagerData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/villager/VillagerData.kt @@ -1,18 +1,17 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.villager +package com.typewritermc.entity.entries.data.minecraft.living.villager import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfession import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfessions import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerType import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.monster.zombie.ZombieVillagerMeta import me.tofaa.entitylib.meta.mobs.villager.VillagerMeta import me.tofaa.entitylib.wrapper.WrapperEntity @@ -25,11 +24,8 @@ import kotlin.reflect.KClass class VillagerData( override val id: String = "", override val name: String = "", - @Help("The type of villager") val villagerType: VillagerTypeData = VillagerTypeData.PLAINS, - @Help("Profession of the villager") val profession: VillagerProfessionData = VillagerProfessionData.NONE, - @Help("The level of the villager") val level: VillagerMeta.Level = VillagerMeta.Level.NOVICE, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/wolf/BeggingData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/wolf/BeggingData.kt similarity index 64% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/wolf/BeggingData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/wolf/BeggingData.kt index 08836228c7..ef3dc9797b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/living/wolf/BeggingData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/living/wolf/BeggingData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.living.wolf +package com.typewritermc.entity.entries.data.minecraft.living.wolf -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.mobs.tameable.WolfMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -15,11 +14,10 @@ import java.util.* import kotlin.reflect.KClass @Entry("begging_data", "The begging state of the wolf", Colors.RED, "game-icons:sitting-dog") -@Tags("begging_data") -class BeggingData ( +@Tags("begging_data", "wolf_data") +class BeggingData( override val id: String = "", override val name: String = "", - @Help("The begging state of the wolf.") val begging: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/other/MarkerData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/other/MarkerData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/other/MarkerData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/other/MarkerData.kt index 0874462cba..4b64ab7037 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/other/MarkerData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/other/MarkerData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.other +package com.typewritermc.entity.entries.data.minecraft.other -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.other.ArmorStandMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +18,6 @@ import kotlin.reflect.KClass class MarkerData( override val id: String = "", override val name: String = "", - @Help("Whether the entity is a marker.") val marker: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/other/SmallData.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/other/SmallData.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/other/SmallData.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/other/SmallData.kt index 89cab1cfc5..30a46fccde 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/data/minecraft/other/SmallData.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/data/minecraft/other/SmallData.kt @@ -1,13 +1,12 @@ -package me.gabber235.typewriter.entries.data.minecraft.other +package com.typewritermc.entity.entries.data.minecraft.other -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entity.SinglePropertyCollectorSupplier -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.metas +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.engine.paper.entry.entity.SinglePropertyCollectorSupplier +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.metas import me.tofaa.entitylib.meta.other.ArmorStandMeta import me.tofaa.entitylib.wrapper.WrapperEntity import org.bukkit.entity.Player @@ -19,7 +18,6 @@ import kotlin.reflect.KClass class SmallData( override val id: String = "", override val name: String = "", - @Help("Whether the entity is small.") val small: Boolean = false, override val priorityOverride: Optional = Optional.empty(), ) : EntityData { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/WrapperFakeEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/WrapperFakeEntity.kt similarity index 81% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/WrapperFakeEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/WrapperFakeEntity.kt index 6238bda74a..e82292526a 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/WrapperFakeEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/WrapperFakeEntity.kt @@ -1,11 +1,12 @@ -package me.gabber235.typewriter.entries.entity +package com.typewritermc.entity.entries.entity import com.github.retrooper.packetevents.protocol.entity.type.EntityType -import me.gabber235.typewriter.entries.entity.custom.state -import me.gabber235.typewriter.entry.entity.EntityState -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.LocationProperty -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entity.EntityState +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.PositionProperty +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.utils.toPacketLocation +import com.typewritermc.entity.entries.entity.custom.state import me.tofaa.entitylib.EntityLib import me.tofaa.entitylib.meta.EntityMeta import me.tofaa.entitylib.meta.projectile.ThrownExpBottleMeta @@ -40,7 +41,7 @@ abstract class WrapperFakeEntity( entity.entityMeta.setNotifyAboutChanges(false) properties.forEach { when (it) { - is LocationProperty -> { + is PositionProperty -> { entity.teleport(it.toPacketLocation()) entity.rotateHead(it.yaw, it.pitch) } @@ -53,7 +54,7 @@ abstract class WrapperFakeEntity( abstract fun applyProperty(property: EntityProperty) - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { entity.spawn(location.toPacketLocation()) entity.addViewer(player.uniqueId) super.spawn(location) diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/EntityTypeProperty.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/EntityTypeProperty.kt similarity index 96% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/EntityTypeProperty.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/EntityTypeProperty.kt index 5c1740c242..e796f08839 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/EntityTypeProperty.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/EntityTypeProperty.kt @@ -1,16 +1,16 @@ -package me.gabber235.typewriter.entries.entity.custom +package com.typewritermc.entity.entries.entity.custom import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose import com.github.retrooper.packetevents.protocol.entity.type.EntityType import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.entries.data.minecraft.PoseProperty -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.SizeProperty -import me.gabber235.typewriter.entries.data.minecraft.living.pufferfish.PuffStateProperty -import me.gabber235.typewriter.entries.data.minecraft.other.MarkerProperty -import me.gabber235.typewriter.entries.data.minecraft.other.SmallProperty -import me.gabber235.typewriter.entry.entity.EntityState -import me.gabber235.typewriter.entry.entries.EntityProperty +import com.typewritermc.entity.entries.data.minecraft.PoseProperty +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.SizeProperty +import com.typewritermc.entity.entries.data.minecraft.living.pufferfish.PuffStateProperty +import com.typewritermc.entity.entries.data.minecraft.other.MarkerProperty +import com.typewritermc.entity.entries.data.minecraft.other.SmallProperty +import com.typewritermc.engine.paper.entry.entity.EntityState +import com.typewritermc.engine.paper.entry.entries.EntityProperty import me.tofaa.entitylib.meta.mobs.water.PufferFishMeta import java.util.* import kotlin.reflect.KClass diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/HitBoxEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/HitBoxEntity.kt similarity index 73% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/HitBoxEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/HitBoxEntity.kt index e90976c3cb..432576a863 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/HitBoxEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/HitBoxEntity.kt @@ -1,20 +1,21 @@ -package me.gabber235.typewriter.entries.entity.custom +package com.typewritermc.entity.entries.entity.custom import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.LocationProperty -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.extensions.packetevents.meta -import me.gabber235.typewriter.utils.Sound -import me.gabber235.typewriter.utils.Vector +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.PositionProperty +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.extensions.packetevents.meta +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.engine.paper.utils.toPacketLocation +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import me.tofaa.entitylib.meta.other.InteractionMeta import org.bukkit.entity.Player @@ -34,11 +35,8 @@ class HitBoxDefinition( override val id: String = "", override val name: String = "", val baseEntity: Ref = emptyRef(), - @Help("The offset of the hit box relative to the base entity.") val offset: Vector = Vector.ZERO, - @Help("The width of the hit box.") val width: Double = 1.0, - @Help("The height of the hit box.") val height: Double = 1.0, ) : EntityDefinitionEntry { override val displayName: String get() = baseEntity.get()?.displayName ?: "" @@ -79,13 +77,13 @@ class HitBoxEntity( override fun applyProperty(property: EntityProperty) { when (property) { - is LocationProperty -> { + is PositionProperty -> { entity.teleport(property.add(offset).toPacketLocation()) } } } - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { super.spawn(location.add(offset)) baseEntity.spawn(location) } diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/InteractionIndicator.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/InteractionIndicator.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/InteractionIndicator.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/InteractionIndicator.kt index 78da28c6d8..8af3426a17 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/InteractionIndicator.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/InteractionIndicator.kt @@ -1,22 +1,25 @@ -package me.gabber235.typewriter.entries.entity.custom +package com.typewritermc.entity.entries.entity.custom -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.entity.minecraft.TextDisplayEntity -import me.gabber235.typewriter.entries.event.EntityInteractEventEntry -import me.gabber235.typewriter.entries.quest.InteractEntityObjective -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry -import me.gabber235.typewriter.entry.entries.LinesProperty -import me.gabber235.typewriter.entry.quest.trackedQuest -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.Sound +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.LinesProperty +import com.typewritermc.engine.paper.entry.inAudience +import com.typewritermc.engine.paper.entry.matches +import com.typewritermc.engine.paper.entry.quest.trackedQuest +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.entity.minecraft.TextDisplayEntity +import com.typewritermc.entity.entries.event.EntityInteractEventEntry +import com.typewritermc.entity.entries.quest.InteractEntityObjective import org.bukkit.entity.Player val trackedInteractIndicator by snippet("objective.entity.indicator.tracked", "❗") diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/NamedEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/NamedEntity.kt similarity index 76% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/NamedEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/NamedEntity.kt index 1f38220baa..49ff409adb 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/NamedEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/NamedEntity.kt @@ -1,24 +1,28 @@ -package me.gabber235.typewriter.entries.entity.custom - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entries.data.minecraft.display.BillboardConstraintProperty -import me.gabber235.typewriter.entries.data.minecraft.display.TranslationProperty -import me.gabber235.typewriter.entries.entity.minecraft.TextDisplayEntity -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.EntityState -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.LocationProperty -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.LinesProperty -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.* +package com.typewritermc.entity.entries.entity.custom + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.engine.paper.entry.entity.EntityState +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.PositionProperty +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.LinesProperty +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.snippets.snippet +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.engine.paper.utils.asMini +import com.typewritermc.engine.paper.utils.asMiniWithResolvers +import com.typewritermc.engine.paper.utils.isFloodgate +import com.typewritermc.entity.entries.data.minecraft.display.BillboardConstraintProperty +import com.typewritermc.entity.entries.data.minecraft.display.TranslationProperty +import com.typewritermc.entity.entries.entity.minecraft.TextDisplayEntity import me.tofaa.entitylib.meta.display.AbstractDisplayMeta import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import org.bukkit.entity.Player @@ -119,7 +123,7 @@ class NamedEntity( return Vector(y = height) } - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { baseEntity.spawn(location) hologram.spawn(location) diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/Npc.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/Npc.kt similarity index 73% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/Npc.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/Npc.kt index 82b6381739..381687386f 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/Npc.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/Npc.kt @@ -1,18 +1,21 @@ -package me.gabber235.typewriter.entries.entity.custom - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.entity.minecraft.PlayerEntity -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.* -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +package com.typewritermc.entity.entries.entity.custom + +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.* +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.entity.minecraft.PlayerEntity import org.bukkit.entity.Player @@ -53,7 +56,7 @@ class NpcInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "lines", "player_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), @@ -89,7 +92,7 @@ class NpcEntity( namePlate.tick() } - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { namePlate.spawn(location) } diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/SelfNpc.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/SelfNpc.kt similarity index 74% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/SelfNpc.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/SelfNpc.kt index 1f12ed8ae2..faf4d08797 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/SelfNpc.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/SelfNpc.kt @@ -1,16 +1,16 @@ -package me.gabber235.typewriter.entries.entity.custom +package com.typewritermc.entity.entries.entity.custom -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.living.toProperty -import me.gabber235.typewriter.entries.entity.minecraft.PlayerEntity -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entity.* -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.utils.Sound +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.entity.entries.data.minecraft.living.toProperty +import com.typewritermc.entity.entries.entity.minecraft.PlayerEntity +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entity.* +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.utils.Sound import org.bukkit.entity.Player import java.util.* @@ -63,7 +63,7 @@ class SelfNpc( playerEntity.tick() } - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { // When in a cinematic, the equipment will be reset to empty. We want to keep the player's equipment. super.spawn(location) setup() diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/StackedEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/StackedEntity.kt similarity index 77% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/StackedEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/StackedEntity.kt index 73061092f9..a3869d1ab7 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/custom/StackedEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/custom/StackedEntity.kt @@ -1,16 +1,16 @@ -package me.gabber235.typewriter.entries.entity.custom +package com.typewritermc.entity.entries.entity.custom -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entity.EntityState -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.LocationProperty -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.utils.Sound +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entity.EntityState +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.PositionProperty +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.utils.Sound import org.bukkit.entity.Player @Entry("stacked_entity_definition", "A stacking of entities", Colors.ORANGE, "ic:baseline-stacked-bar-chart") @@ -55,13 +55,13 @@ class StackedEntity( override fun applyProperties(properties: List) { if (entities.isEmpty()) return - val otherProperties = properties.filter { it !is LocationProperty } + val otherProperties = properties.filter { it !is PositionProperty } // Only the bottom entity will have the location entities.first().consumeProperties(properties) entities.asSequence().drop(1).forEach { it.consumeProperties(otherProperties) } } - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { if (entities.isEmpty()) return val baseEntity = entities.first() for (entity in entities) { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/AllayEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/AllayEntity.kt similarity index 60% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/AllayEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/AllayEntity.kt index cd8c0c80a9..539f872d0b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/AllayEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/AllayEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("allay_definition", "A allay entity", Colors.ORANGE, "ph:allay-fill") @@ -51,13 +51,13 @@ class AllayInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "allay_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), ) : SimpleEntityInstance -private class AllayEntity(player: Player) : WrapperFakeEntity(EntityTypes.ALLAY,player) { +private class AllayEntity(player: Player) : WrapperFakeEntity(EntityTypes.ALLAY, player) { override fun applyProperty(property: EntityProperty) { if (applyGenericEntityData(entity, property)) return if (applyLivingEntityData(entity, property)) return diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/CatEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/CatEntity.kt similarity index 55% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/CatEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/CatEntity.kt index 6e420db559..40dba2759b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/CatEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/CatEntity.kt @@ -1,27 +1,27 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.CollarColorProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyCollarColorData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.cat.CatVariantProperty -import me.gabber235.typewriter.entries.data.minecraft.living.cat.applyCatVariantData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.DyeColorProperty +import com.typewritermc.entity.entries.data.minecraft.applyDyeColorData +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.data.minecraft.living.cat.CatVariantProperty +import com.typewritermc.entity.entries.data.minecraft.living.cat.applyCatVariantData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("cat_definition", "A cat entity", Colors.ORANGE, "ph:cat-fill") @@ -55,17 +55,17 @@ class CatInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "cat_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), ) : SimpleEntityInstance -private class CatEntity(player: Player) : WrapperFakeEntity(EntityTypes.CAT,player) { +private class CatEntity(player: Player) : WrapperFakeEntity(EntityTypes.CAT, player) { override fun applyProperty(property: EntityProperty) { when (property) { is CatVariantProperty -> applyCatVariantData(entity, property) - is CollarColorProperty -> applyCollarColorData(entity, property) + is DyeColorProperty -> applyDyeColorData(entity, property) } if (applyGenericEntityData(entity, property)) return if (applyLivingEntityData(entity, property)) return diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ChickenEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ChickenEntity.kt similarity index 61% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ChickenEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ChickenEntity.kt index 12dc8f380e..0fcc210c9d 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ChickenEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ChickenEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyAgeableData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyAgeableData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("chicken_definition", "A chicken entity", Colors.ORANGE, "ph:chicken-fill") @@ -53,7 +53,7 @@ class ChickenInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data", "chicken_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/CowEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/CowEntity.kt similarity index 58% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/CowEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/CowEntity.kt index d91df75c57..81d7ec47d2 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/CowEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/CowEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyAgeableData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyAgeableData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("cow_definition", "A cow entity", Colors.ORANGE, "fa6-solid:cow") @@ -46,7 +46,7 @@ class CowInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data", "cow_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/EndermanEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/EndermanEntity.kt similarity index 58% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/EndermanEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/EndermanEntity.kt index 4d9433e42c..0b32efc54a 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/EndermanEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/EndermanEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("enderman_definition", "A enderman entity", Colors.ORANGE, "gravity-ui:sphere") @@ -44,7 +44,7 @@ class EndermanInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/FrogEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/FrogEntity.kt similarity index 64% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/FrogEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/FrogEntity.kt index 84ac07437d..e496a66147 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/FrogEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/FrogEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.* +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("frog_definition", "A frog entity", Colors.ORANGE, "ph:frog-fill") @@ -51,7 +51,7 @@ class FrogInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data", "frog_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/HoglinEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/HoglinEntity.kt similarity index 63% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/HoglinEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/HoglinEntity.kt index d0e12978e3..8dd8091a50 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/HoglinEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/HoglinEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.* +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("hoglin_definition", "A hoglin entity", Colors.ORANGE, "icon-park-outline:pig") @@ -44,7 +44,7 @@ class HoglinInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data", "trembling_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/HuskEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/HuskEntity.kt similarity index 58% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/HuskEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/HuskEntity.kt index 1bd2fa9af7..324ba0ff68 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/HuskEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/HuskEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyAgeableData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyAgeableData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("husk_definition", "A husk entity", Colors.ORANGE, "game-icons:shambling-zombie") @@ -46,7 +46,7 @@ class HuskInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/IronGolemEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/IronGolemEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/IronGolemEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/IronGolemEntity.kt index 7d3ce21ff5..2363e10804 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/IronGolemEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/IronGolemEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("iron_golem_definition", "An iron golem entity", Colors.ORANGE, "game-icons:strong") @@ -44,7 +44,7 @@ class IronGolemInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ItemDisplayEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ItemDisplayEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ItemDisplayEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ItemDisplayEntity.kt index ea905e94be..cc9f4d6fa4 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ItemDisplayEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ItemDisplayEntity.kt @@ -1,27 +1,27 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.display.applyDisplayEntityData -import me.gabber235.typewriter.entries.data.minecraft.display.item.DisplayTypeProperty -import me.gabber235.typewriter.entries.data.minecraft.display.item.ItemProperty -import me.gabber235.typewriter.entries.data.minecraft.display.item.applyDisplayTypeData -import me.gabber235.typewriter.entries.data.minecraft.display.item.applyItemData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.display.applyDisplayEntityData +import com.typewritermc.entity.entries.data.minecraft.display.item.DisplayTypeProperty +import com.typewritermc.entity.entries.data.minecraft.display.item.ItemProperty +import com.typewritermc.entity.entries.data.minecraft.display.item.applyDisplayTypeData +import com.typewritermc.entity.entries.data.minecraft.display.item.applyItemData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("item_display_definition", "An item display entity", Colors.ORANGE, "icon-park-solid:holy-sword") @@ -54,7 +54,7 @@ class ItemDisplayInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "display_data", "item_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/MagmaCubeEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/MagmaCubeEntity.kt similarity index 61% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/MagmaCubeEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/MagmaCubeEntity.kt index 5e8a49277c..e43409837c 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/MagmaCubeEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/MagmaCubeEntity.kt @@ -1,23 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.SizeProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applySizeData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("magma_cube_definition", "A magma cube entity", Colors.ORANGE, "ph:magma-cube-fill") @@ -51,7 +53,7 @@ class MagmaCubeInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "slime_data", "magma_cube_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PiglinBruteEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PiglinBruteEntity.kt similarity index 60% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PiglinBruteEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PiglinBruteEntity.kt index 07c8da3d4b..f6520ac898 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PiglinBruteEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PiglinBruteEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.TremblingProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.applyTremblingData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.TremblingProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyTremblingData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("piglin_brute_definition", "A piglin brute entity", Colors.ORANGE, "mdi:axe") @@ -46,7 +46,7 @@ class PiglinBruteInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "trembling_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PiglinEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PiglinEntity.kt similarity index 64% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PiglinEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PiglinEntity.kt index 1d8157edd7..788809ae0b 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PiglinEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PiglinEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.* -import me.gabber235.typewriter.entries.data.minecraft.living.piglin.DancingProperty -import me.gabber235.typewriter.entries.data.minecraft.living.piglin.applyDancingData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.* +import com.typewritermc.entity.entries.data.minecraft.living.piglin.DancingProperty +import com.typewritermc.entity.entries.data.minecraft.living.piglin.applyDancingData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("piglin_definition", "A piglin entity", Colors.ORANGE, "fluent-emoji-high-contrast:pig-nose") @@ -53,7 +53,7 @@ class PiglinInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags( "generic_entity_data", "living_entity_data", diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PlayerEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PlayerEntity.kt similarity index 75% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PlayerEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PlayerEntity.kt index a625e0a6cb..ce8123342c 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/PlayerEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/PlayerEntity.kt @@ -1,28 +1,30 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes import com.github.retrooper.packetevents.protocol.player.TextureProperty import com.github.retrooper.packetevents.protocol.player.UserProfile import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.PoseProperty -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entries.entity.custom.state -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.* -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.extensions.packetevents.meta -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.utils.Sound -import me.gabber235.typewriter.utils.stripped +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.* +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.extensions.packetevents.meta +import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.engine.paper.utils.stripped +import com.typewritermc.engine.paper.utils.toPacketLocation +import com.typewritermc.entity.entries.data.minecraft.PoseProperty +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.custom.state import me.tofaa.entitylib.EntityLib import me.tofaa.entitylib.meta.types.PlayerMeta import me.tofaa.entitylib.spigot.SpigotEntityLibAPI @@ -30,7 +32,6 @@ import me.tofaa.entitylib.wrapper.WrapperEntity import me.tofaa.entitylib.wrapper.WrapperPlayer import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.NamedTextColor -import org.bukkit.Location import org.bukkit.entity.Player import java.util.* @@ -62,7 +63,7 @@ class PlayerInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "player_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), @@ -88,7 +89,7 @@ class PlayerEntity( entityId = EntityLib.getPlatform().entityIdProvider.provide(uuid, EntityTypes.PLAYER) } while (EntityLib.getApi().getEntity(entityId) != null) - entity = WrapperPlayer(UserProfile(uuid, "\u2063${displayName.stripped()}"), entityId) + entity = WrapperPlayer(UserProfile(uuid, "\u2063${displayName.stripped().replace(" ", "_")}"), entityId) entity.isInTablist = false entity.meta { @@ -105,10 +106,14 @@ class PlayerEntity( override fun applyProperties(properties: List) { properties.forEach { property -> when (property) { - is LocationProperty -> { - sitEntity?.teleport(property.toPacketLocation()) - entity.teleport(property.toPacketLocation()) - entity.rotateHead(property.yaw, property.pitch) + is PositionProperty -> { + if (sitEntity?.isSpawned == true) { + sitEntity?.teleport(property.toPacketLocation()) + } + if (entity.isSpawned) { + entity.teleport(property.toPacketLocation()) + entity.rotateHead(property.yaw, property.pitch) + } } is SkinProperty -> entity.textureProperties = @@ -130,7 +135,7 @@ class PlayerEntity( } } - override fun spawn(location: LocationProperty) { + override fun spawn(location: PositionProperty) { if (sitEntity != null) { sitEntity?.spawn(location.toPacketLocation()) sitEntity?.addViewer(player.uniqueId) @@ -193,13 +198,15 @@ class PlayerEntity( sitEntity = null } - private fun sit(location: LocationProperty? = null) { + private fun sit(location: PositionProperty? = null) { if (sitEntity != null) return sitEntity = WrapperEntity(EntityTypes.BLOCK_DISPLAY) - val loc = location ?: property() ?: return + val loc = location ?: property() ?: return sitEntity?.spawn(loc.toPacketLocation()) sitEntity?.addViewer(player.uniqueId) - sitEntity?.addPassengers(this.entity) + if (entity.isSpawned) { + sitEntity?.addPassengers(this.entity) + } } private fun unsit() { diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/SkeletonEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/SkeletonEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/SkeletonEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/SkeletonEntity.kt index 91dd46dbe3..43e73e0eb4 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/SkeletonEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/SkeletonEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("skeleton_definition", "A skeleton entity", Colors.ORANGE, "healthicons:skeleton") @@ -44,7 +44,7 @@ class SkeletonInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/SlimeEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/SlimeEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/SlimeEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/SlimeEntity.kt index d5e41b0f3f..aa303664d1 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/SlimeEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/SlimeEntity.kt @@ -1,23 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.SizeProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applySizeData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("slime_definition", "A slime entity", Colors.ORANGE, "ph:slime-fill") @@ -51,7 +53,7 @@ class SlimeInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "slime_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/TextDisplayEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/TextDisplayEntity.kt similarity index 62% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/TextDisplayEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/TextDisplayEntity.kt index ffaf751770..c5e2116cae 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/TextDisplayEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/TextDisplayEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.display.applyDisplayEntityData -import me.gabber235.typewriter.entries.data.minecraft.display.text.* -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.extensions.packetevents.meta -import me.gabber235.typewriter.utils.Sound -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.extensions.packetevents.meta +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.engine.paper.utils.asMini +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.display.applyDisplayEntityData +import com.typewritermc.entity.entries.data.minecraft.display.text.* +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import me.tofaa.entitylib.meta.display.TextDisplayMeta -import org.bukkit.Location import org.bukkit.entity.Player @Entry("text_display_definition", "A text display entity", Colors.ORANGE, "material-symbols:text-ad-rounded") @@ -51,7 +51,7 @@ class TextDisplayInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "display_data", "lines", "text_display_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), @@ -71,7 +71,11 @@ open class TextDisplayEntity(player: Player) : WrapperFakeEntity( is BackgroundColorProperty -> applyBackgroundColorData(entity, property) is TextOpacityProperty -> applyTextOpacityData(entity, property) is LineWidthProperty -> applyLineWidthData(entity, property) - is ShadowProperty -> applyShadowData(entity, property) + is _root_ide_package_.com.typewritermc.entity.entries.data.minecraft.display.text.ShadowProperty -> _root_ide_package_.com.typewritermc.entity.entries.data.minecraft.display.text.applyShadowData( + entity, + property + ) + is SeeThroughProperty -> applySeeThroughData(entity, property) else -> {} } diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/VillagerEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/VillagerEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/VillagerEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/VillagerEntity.kt index 579333d61d..16246bcae3 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/VillagerEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/VillagerEntity.kt @@ -1,27 +1,27 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyAgeableData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.villager.VillagerProperty -import me.gabber235.typewriter.entries.data.minecraft.living.villager.applyVillagerData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyAgeableData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.data.minecraft.living.villager.VillagerProperty +import com.typewritermc.entity.entries.data.minecraft.living.villager.applyVillagerData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @@ -49,7 +49,7 @@ class VillagerInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data", "villager_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/WardenEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/WardenEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/WardenEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/WardenEntity.kt index a50d1f9259..afa5f04788 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/WardenEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/WardenEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyAgeableData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyAgeableData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("warden_definition", "A warden entity", Colors.ORANGE, "streamline:smiley-surprised-solid") @@ -46,7 +46,7 @@ class WardenInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/WitchEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/WitchEntity.kt similarity index 58% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/WitchEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/WitchEntity.kt index 6989202bc7..645d834cc6 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/WitchEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/WitchEntity.kt @@ -1,23 +1,23 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("witch_definition", "A witch entity", Colors.ORANGE, "game-icons:pointy-hat") @@ -44,7 +44,7 @@ class WitchInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ZombieEntity.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ZombieEntity.kt similarity index 59% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ZombieEntity.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ZombieEntity.kt index c44b24a964..eff690c50d 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/entity/minecraft/ZombieEntity.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/entity/minecraft/ZombieEntity.kt @@ -1,25 +1,25 @@ -package me.gabber235.typewriter.entries.entity.minecraft +package com.typewritermc.entity.entries.entity.minecraft import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.OnlyTags -import me.gabber235.typewriter.entries.data.minecraft.applyGenericEntityData -import me.gabber235.typewriter.entries.data.minecraft.living.AgableProperty -import me.gabber235.typewriter.entries.data.minecraft.living.applyAgeableData -import me.gabber235.typewriter.entries.data.minecraft.living.applyLivingEntityData -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.FakeEntity -import me.gabber235.typewriter.entry.entity.SimpleEntityDefinition -import me.gabber235.typewriter.entry.entity.SimpleEntityInstance -import me.gabber235.typewriter.entries.entity.WrapperFakeEntity -import me.gabber235.typewriter.entry.entries.EntityData -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.entry.entries.SharedEntityActivityEntry -import me.gabber235.typewriter.utils.Sound -import org.bukkit.Location +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.FakeEntity +import com.typewritermc.engine.paper.entry.entity.SimpleEntityDefinition +import com.typewritermc.engine.paper.entry.entity.SimpleEntityInstance +import com.typewritermc.engine.paper.entry.entries.EntityData +import com.typewritermc.engine.paper.entry.entries.EntityProperty +import com.typewritermc.engine.paper.entry.entries.SharedEntityActivityEntry +import com.typewritermc.engine.paper.utils.Sound +import com.typewritermc.entity.entries.data.minecraft.applyGenericEntityData +import com.typewritermc.entity.entries.data.minecraft.living.AgableProperty +import com.typewritermc.entity.entries.data.minecraft.living.applyAgeableData +import com.typewritermc.entity.entries.data.minecraft.living.applyLivingEntityData +import com.typewritermc.entity.entries.entity.WrapperFakeEntity import org.bukkit.entity.Player @Entry("zombie_definition", "A zombie entity", Colors.ORANGE, "game-icons:shambling-zombie") @@ -46,7 +46,7 @@ class ZombieInstance( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, @OnlyTags("generic_entity_data", "living_entity_data", "mob_data", "ageable_data") override val data: List>> = emptyList(), override val activity: Ref = emptyRef(), diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/EntityInteractEventEntry.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/event/EntityInteractEventEntry.kt similarity index 63% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/EntityInteractEventEntry.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/event/EntityInteractEventEntry.kt index bdab50df89..0f68f20c5c 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/event/EntityInteractEventEntry.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/event/EntityInteractEventEntry.kt @@ -1,13 +1,19 @@ -package me.gabber235.typewriter.entries.event +package com.typewritermc.entity.entries.event import com.github.retrooper.packetevents.protocol.player.InteractionHand import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry -import me.gabber235.typewriter.entry.entries.EventEntry -import me.gabber235.typewriter.events.AsyncEntityDefinitionInteract +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.events.AsyncEntityDefinitionInteract @Entry( "entity_interact_event", diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/instance/AdvancedEntityInstanceEntry.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/instance/AdvancedEntityInstanceEntry.kt similarity index 76% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/instance/AdvancedEntityInstanceEntry.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/instance/AdvancedEntityInstanceEntry.kt index 4f3174a655..5cf51ad21d 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/instance/AdvancedEntityInstanceEntry.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/instance/AdvancedEntityInstanceEntry.kt @@ -1,13 +1,14 @@ -package me.gabber235.typewriter.entries.instance +package com.typewritermc.entity.entries.instance -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entity.GroupAdvancedEntityInstance -import me.gabber235.typewriter.entry.entity.IndividualAdvancedEntityInstance -import me.gabber235.typewriter.entry.entity.SharedAdvancedEntityInstance -import me.gabber235.typewriter.entry.entries.* +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.entity.GroupAdvancedEntityInstance +import com.typewritermc.engine.paper.entry.entity.IndividualAdvancedEntityInstance +import com.typewritermc.engine.paper.entry.entity.SharedAdvancedEntityInstance +import com.typewritermc.engine.paper.entry.entries.* import org.bukkit.Location @Entry( @@ -27,7 +28,7 @@ class SharedAdvancedEntityInstanceEntry( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, override val children: List> = emptyList(), override val activity: Ref = emptyRef(), ) : SharedAdvancedEntityInstance @@ -44,7 +45,7 @@ class GroupAdvancedEntityInstanceEntry( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, override val children: List> = emptyList(), override val activity: Ref = emptyRef(), override val group: Ref = emptyRef(), @@ -69,7 +70,7 @@ class IndividualAdvancedEntityInstanceEntry( override val id: String = "", override val name: String = "", override val definition: Ref = emptyRef(), - override val spawnLocation: Location = Location(null, 0.0, 0.0, 0.0), + override val spawnLocation: Position = Position.ORIGIN, override val children: List> = emptyList(), override val activity: Ref = emptyRef(), ) : IndividualAdvancedEntityInstance \ No newline at end of file diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/quest/InteractEntityObjective.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/quest/InteractEntityObjective.kt similarity index 66% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/quest/InteractEntityObjective.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/quest/InteractEntityObjective.kt index 8f672a8d59..8d2810b485 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/quest/InteractEntityObjective.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/quest/InteractEntityObjective.kt @@ -1,16 +1,16 @@ -package me.gabber235.typewriter.entries.quest +package com.typewritermc.entity.entries.quest -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.EntityDefinitionEntry -import me.gabber235.typewriter.entry.entries.ObjectiveEntry -import me.gabber235.typewriter.entry.entries.QuestEntry -import me.gabber235.typewriter.snippets.snippet +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.EntityDefinitionEntry +import com.typewritermc.engine.paper.entry.entries.ObjectiveEntry +import com.typewritermc.engine.paper.entry.entries.QuestEntry +import com.typewritermc.engine.paper.snippets.snippet import java.util.* private val displayTemplate by snippet("quest.objective.interact_entity", "Interact with ") diff --git a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/quest/InteractEntityObjectivesPathStream.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/quest/InteractEntityObjectivesPathStream.kt similarity index 68% rename from adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/quest/InteractEntityObjectivesPathStream.kt rename to extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/quest/InteractEntityObjectivesPathStream.kt index e7414105df..753dd6b5cf 100644 --- a/adapters/EntityAdapter/src/main/kotlin/me/gabber235/typewriter/entries/quest/InteractEntityObjectivesPathStream.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/quest/InteractEntityObjectivesPathStream.kt @@ -1,11 +1,16 @@ -package me.gabber235.typewriter.entries.quest +package com.typewritermc.entity.entries.quest -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entity.ActivityEntityDisplay -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.roadnetwork.gps.MultiPathStreamDisplay +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.AudienceManager +import com.typewritermc.engine.paper.entry.entity.ActivityEntityDisplay +import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.roadnetwork.gps.MultiPathStreamDisplay +import com.typewritermc.engine.paper.utils.toBukkitLocation import org.koin.java.KoinJavaComponent @Entry( @@ -37,7 +42,7 @@ class InteractEntityObjectivesPathStream( .mapNotNull { manager[it.ref()] } .filterIsInstance() .filter { it.canView(player.uniqueId) } - .mapNotNull { it.location(player.uniqueId) } + .mapNotNull { it.position(player.uniqueId)?.toBukkitLocation() } .toList() }) } \ No newline at end of file diff --git a/adapters/CombatLogXAdapter/src/main/templates/App.kt b/extensions/EntityExtension/src/main/templates/App.kt similarity index 100% rename from adapters/CombatLogXAdapter/src/main/templates/App.kt rename to extensions/EntityExtension/src/main/templates/App.kt diff --git a/extensions/MythicMobsExtension/build.gradle.kts b/extensions/MythicMobsExtension/build.gradle.kts new file mode 100644 index 0000000000..251db84839 --- /dev/null +++ b/extensions/MythicMobsExtension/build.gradle.kts @@ -0,0 +1,32 @@ +import com.typewritermc.loader.ExtensionFlag + +repositories { + maven("https://mvn.lumine.io/repository/maven-public/") +} + +dependencies { + compileOnly("io.lumine:Mythic-Dist:5.6.1") +} + +typewriter { + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + namespace = "typewritermc" + + extension { + name = "MythicMobs" + shortDescription = "Integrate MythicMobs with Typewriter." + description = """ + |The MythicMobs Extension allows you to create MyticMobs, and trigger Skills from Typewriter. + |Create cool particles during cinematics or have dialgues triggered when interacting with a MythicMob. + """.trimMargin() + + flag(ExtensionFlag.Deprecated) + + paper { + dependency("MythicMobs") + } + } +} \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/DespawnMobActionEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/DespawnMobActionEntry.kt similarity index 68% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/DespawnMobActionEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/DespawnMobActionEntry.kt index 5d745204ac..f0d4a68215 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/DespawnMobActionEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/DespawnMobActionEntry.kt @@ -1,17 +1,16 @@ -package me.ahdg6.typewriter.mythicmobs.entries.action +package com.typewritermc.mythicmobs.entries.action +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.ThreadType.SYNC import io.lumine.mythic.bukkit.MythicBukkit -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC import org.bukkit.entity.Player @@ -29,7 +28,6 @@ class DespawnMobActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The mob's name") @Placeholder private val mobName: String = "", ) : ActionEntry { @@ -46,7 +44,7 @@ class DespawnMobActionEntry( return@removeIf true } false + } } } -} } \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/ExecuteSkillActionEntry.kt similarity index 63% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/ExecuteSkillActionEntry.kt index a16b3e35df..19fa8f0dc9 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/ExecuteSkillActionEntry.kt @@ -1,20 +1,19 @@ -package me.ahdg6.typewriter.mythicmobs.entries.action +package com.typewritermc.mythicmobs.entries.action +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.logger import io.lumine.mythic.api.mobs.GenericCaster import io.lumine.mythic.bukkit.BukkitAdapter import io.lumine.mythic.bukkit.MythicBukkit import io.lumine.mythic.core.skills.SkillMetadataImpl import io.lumine.mythic.core.skills.SkillTriggers import io.lumine.mythic.core.utils.MythicUtil -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.logger import org.bukkit.entity.Player @Entry("execute_mythicmob_skill", "Executes a MythicMobs skill", Colors.RED, "fa6-solid:bolt-lightning") @@ -31,7 +30,6 @@ class ExecuteSkillActionEntry( override val triggers: List> = emptyList(), override val criteria: List = emptyList(), override val modifiers: List = emptyList(), - @Help("The name of the skill to execute") val skillName: String = "", ) : ActionEntry { override fun execute(player: Player) { @@ -47,8 +45,15 @@ class ExecuteSkillActionEntry( SkillMetadataImpl(SkillTriggers.API, caster, trigger) if (skill.isUsable(skillMeta)) { - MythicBukkit.inst().apiHelper.castSkill(player, skillName, player, player.location, listOf(MythicUtil.getTargetedEntity(player)), null, 1f) - } - else logger.warning("Skill $skillName is not usable at this time (cooldown, etc.)") + MythicBukkit.inst().apiHelper.castSkill( + player, + skillName, + player, + player.location, + listOf(MythicUtil.getTargetedEntity(player)), + null, + 1f + ) + } else logger.warning("Skill $skillName is not usable at this time (cooldown, etc.)") } } \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/SpawnMobActionEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/SpawnMobActionEntry.kt similarity index 58% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/SpawnMobActionEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/SpawnMobActionEntry.kt index 2b289f948b..9ca2957874 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/SpawnMobActionEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/action/SpawnMobActionEntry.kt @@ -1,22 +1,22 @@ -package me.ahdg6.typewriter.mythicmobs.entries.action +package com.typewritermc.mythicmobs.entries.action +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.core.extension.annotations.WithRotation +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.plugin +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.toBukkitLocation import io.lumine.mythic.api.mobs.entities.SpawnReason import io.lumine.mythic.bukkit.BukkitAdapter import io.lumine.mythic.bukkit.MythicBukkit -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.adapters.modifiers.WithRotation -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Location import org.bukkit.entity.Player @@ -34,16 +34,12 @@ class SpawnMobActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The mob's name") @Placeholder private val mobName: String = "", - @Help("The mob's level") private val level: Double = 1.0, - @Help("Whether the mob should be only seen by the player") private val onlyVisibleForPlayer: Boolean = false, - @Help("The mob's spawn location") @WithRotation - private var spawnLocation: Location, + private var spawnLocation: Position = Position.ORIGIN, ) : ActionEntry { override fun execute(player: Player) { super.execute(player) @@ -52,7 +48,7 @@ class SpawnMobActionEntry( if (!mob.isPresent) return SYNC.launch { - mob.get().spawn(BukkitAdapter.adapt(spawnLocation), level, SpawnReason.OTHER) { + mob.get().spawn(BukkitAdapter.adapt(spawnLocation.toBukkitLocation()), level, SpawnReason.OTHER) { if (onlyVisibleForPlayer) { it.isVisibleByDefault = false player.showEntity(plugin, it) diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt similarity index 67% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt index 7d713e2a34..3e8a80cf30 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt @@ -1,5 +1,19 @@ -package me.ahdg6.typewriter.mythicmobs.entries.cinematic +package com.typewritermc.mythicmobs.entries.cinematic +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.core.extension.annotations.WithRotation +import com.typewritermc.core.utils.point.Position +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.ThreadType.SYNC +import com.typewritermc.engine.paper.utils.toBukkitLocation import io.lumine.mythic.api.mobs.GenericCaster import io.lumine.mythic.bukkit.BukkitAdapter import io.lumine.mythic.bukkit.MythicBukkit @@ -7,20 +21,6 @@ import io.lumine.mythic.core.mobs.ActiveMob import io.lumine.mythic.core.skills.SkillMetadataImpl import io.lumine.mythic.core.skills.SkillTriggers import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.adapters.modifiers.WithRotation -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Location import org.bukkit.entity.Player @Entry("mythicmob_cinematic", "Spawn a MythicMob during a cinematic", Colors.PURPLE, "fa6-solid:dragon") @@ -46,12 +46,10 @@ class MythicMobCinematicEntry( data class MythicMobSegment( override val startFrame: Int = 0, override val endFrame: Int = 0, - @Help("The name of the mob to spawn") @Placeholder val mobName: String = "", - @Help("The location to spawn the mob at") @WithRotation - val location: Location = Location(null, 0.0, 0.0, 0.0), + val location: Position = Position.ORIGIN, ) : Segment class MobCinematicAction( @@ -66,7 +64,11 @@ class MobCinematicAction( super.startSegment(segment) SYNC.switchContext { - val mob = MythicBukkit.inst().mobManager.spawnMob(segment.mobName.parsePlaceholders(player), segment.location) + val mob = + MythicBukkit.inst().mobManager.spawnMob( + segment.mobName.parsePlaceholders(player), + segment.location.toBukkitLocation() + ) this@MobCinematicAction.mob = mob val hideMechanic = MythicBukkit.inst().skillManager.getMechanic("hide") diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt similarity index 75% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt index c16d94fc38..2206abec41 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt @@ -1,22 +1,21 @@ -package me.ahdg6.typewriter.mythicmobs.entries.cinematic +package com.typewritermc.mythicmobs.entries.cinematic +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.InnerMax +import com.typewritermc.core.extension.annotations.Max +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicAction +import com.typewritermc.engine.paper.entry.entries.CinematicEntry +import com.typewritermc.engine.paper.entry.entries.Segment +import com.typewritermc.engine.paper.logger import io.lumine.mythic.api.mobs.GenericCaster import io.lumine.mythic.bukkit.BukkitAdapter import io.lumine.mythic.bukkit.MythicBukkit import io.lumine.mythic.core.skills.SkillMetadataImpl import io.lumine.mythic.core.skills.SkillTriggers -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.InnerMax -import me.gabber235.typewriter.adapters.modifiers.Max -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.CinematicAction -import me.gabber235.typewriter.entry.entries.CinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.logger import org.bukkit.entity.Player @Entry("mythicskill_cinematic", "Trigger a MythicSkill during a cinematic", Colors.PURPLE, "fa6-solid:bolt-lightning") @@ -52,7 +51,6 @@ class MythicSkillCinematicEntry( data class MythicSkillSegment( override val startFrame: Int = 0, override val endFrame: Int = 0, - @Help("The name of the skill to trigger") val skillName: String = "", ) : Segment diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobDeathEventEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobDeathEventEntry.kt similarity index 64% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobDeathEventEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobDeathEventEntry.kt index 701699d8c9..71cd0313ef 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobDeathEventEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobDeathEventEntry.kt @@ -1,12 +1,16 @@ -package me.ahdg6.typewriter.mythicmobs.entries.event +package com.typewritermc.mythicmobs.entries.event +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Regex +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import io.lumine.mythic.bukkit.events.MythicMobDeathEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Regex -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry import org.bukkit.entity.Player diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobInteractEventEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobInteractEventEntry.kt similarity index 64% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobInteractEventEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobInteractEventEntry.kt index b540464093..f86e245a44 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobInteractEventEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobInteractEventEntry.kt @@ -1,12 +1,16 @@ -package me.ahdg6.typewriter.mythicmobs.entries.event +package com.typewritermc.mythicmobs.entries.event +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.extension.annotations.Regex +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.startDialogueWithOrNextDialogue import io.lumine.mythic.bukkit.events.MythicMobInteractEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Regex -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry @Entry("mythicmobs_interact_event", "MythicMob Interact Event", Colors.YELLOW, "fa6-solid:dragon") /** diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt similarity index 96% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt index 264bc1453e..cf1da81cdd 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/event/MythicMobKillPlayerEventEntry.kt @@ -1,4 +1,4 @@ -package me.ahdg6.typewriter.mythicmobs.entries.event +package com.typewritermc.mythicmobs.entries.event /** TODO: * Since minecraft 1.20.5 changed how the player death event source is handled, diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/fact/MobCountFact.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/fact/MobCountFact.kt similarity index 72% rename from adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/fact/MobCountFact.kt rename to extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/fact/MobCountFact.kt index 90ce098c3c..b4e393272e 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/fact/MobCountFact.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/fact/MobCountFact.kt @@ -1,14 +1,13 @@ -package me.ahdg6.typewriter.mythicmobs.entries.fact +package com.typewritermc.mythicmobs.entries.fact +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.facts.FactData import io.lumine.mythic.bukkit.MythicBukkit -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData import org.bukkit.entity.Player @Entry( @@ -31,7 +30,6 @@ class MobCountFact( override val name: String = "", override val comment: String = "", override val group: Ref = emptyRef(), - @Help("The id of the mob to count") val mobName: String = "", ) : ReadableFactEntry { override fun readSinglePlayer(player: Player): FactData { diff --git a/adapters/EntityAdapter/src/main/templates/App.kt b/extensions/MythicMobsExtension/src/main/templates/App.kt similarity index 100% rename from adapters/EntityAdapter/src/main/templates/App.kt rename to extensions/MythicMobsExtension/src/main/templates/App.kt diff --git a/extensions/RPGRegionsExtension/build.gradle.kts b/extensions/RPGRegionsExtension/build.gradle.kts new file mode 100644 index 0000000000..4fff6947c3 --- /dev/null +++ b/extensions/RPGRegionsExtension/build.gradle.kts @@ -0,0 +1,32 @@ +import com.typewritermc.loader.ExtensionFlag + +repositories { + maven("https://repo.convallyria.com/releases") +} + +dependencies { + compileOnly("net.islandearth.rpgregions:api:1.4.4") // 1.4.4 +} + +typewriter { + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + namespace = "typewritermc" + + extension { + name = "RPGRegions" + shortDescription = "Integrate RPGRegions with Typewriter." + description = """ + |The RPGRegions Extension is an extension that makes it easy to use RPGRegions in your dialogue. + |Create dialogues that are triggered when the player enters or leaves a region. + """.trimMargin() + + flag(ExtensionFlag.Deprecated) + + paper { + dependency("RPGRegions") + } + } +} \ No newline at end of file diff --git a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/action/DiscoverRegionActionEntry.kt b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/action/DiscoverRegionActionEntry.kt similarity index 71% rename from adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/action/DiscoverRegionActionEntry.kt rename to extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/action/DiscoverRegionActionEntry.kt index ed3b35bf2b..9d7b1c772a 100644 --- a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/action/DiscoverRegionActionEntry.kt +++ b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/action/DiscoverRegionActionEntry.kt @@ -1,13 +1,13 @@ -package me.ahdg6.typewriter.rpgregions.entries.action +package com.typewritermc.rpgregions.entries.action -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import net.islandearth.rpgregions.api.RPGRegionsAPI import net.islandearth.rpgregions.managers.data.region.WorldDiscovery import org.bukkit.entity.Player @@ -28,8 +28,7 @@ class DiscoverRegionActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The region to discover.") - // The region to discover. Make sure that this is the region ID, not the region's display name. + @Help("Make sure that this is the region ID, not the region's display name") private val region: String = "", ) : ActionEntry { override fun execute(player: Player) { @@ -40,7 +39,9 @@ class DiscoverRegionActionEntry( val user = RPGRegionsAPI.getAPI().managers.storageManager.getAccount(player.uniqueId) val date: LocalDateTime = LocalDateTime.now() val format: DateTimeFormatter = - DateTimeFormatter.ofPattern(RPGRegionsAPI.getAPI().config.getString("settings.server.discoveries.date.format")) + DateTimeFormatter.ofPattern( + RPGRegionsAPI.getAPI().config.getString("settings.server.discoveries.date.format") ?: "" + ) val formattedDate = date.format(format) val worldDiscovery = WorldDiscovery(formattedDate, region.get().id) diff --git a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/event/DiscoverRegionEventEntry.kt b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/event/DiscoverRegionEventEntry.kt similarity index 63% rename from adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/event/DiscoverRegionEventEntry.kt rename to extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/event/DiscoverRegionEventEntry.kt index 94dbf285ef..11156187b4 100644 --- a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/event/DiscoverRegionEventEntry.kt +++ b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/event/DiscoverRegionEventEntry.kt @@ -1,11 +1,15 @@ -package me.ahdg6.typewriter.rpgregions.entries.event +package com.typewritermc.rpgregions.entries.event +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry import net.islandearth.rpgregions.api.events.RegionDiscoverEvent @Entry( @@ -26,8 +30,7 @@ class DiscoverRegionEventEntry( override val id: String = "", override val name: String = "", override val triggers: List> = emptyList(), - @Help("The region to check for.") - // The region to check for. Make sure that this is the region ID, not the region's display name. + @Help("Make sure that this is the region ID, not the region's display name.") val region: String = "", ) : EventEntry diff --git a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/event/EnterRegionEventEntry.kt b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/event/EnterRegionEventEntry.kt similarity index 64% rename from adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/event/EnterRegionEventEntry.kt rename to extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/event/EnterRegionEventEntry.kt index eae403bed4..82b2564ff0 100644 --- a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/event/EnterRegionEventEntry.kt +++ b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/event/EnterRegionEventEntry.kt @@ -1,11 +1,15 @@ -package me.ahdg6.typewriter.rpgregions.entries.event +package com.typewritermc.rpgregions.entries.event import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.entries.EventEntry import net.islandearth.rpgregions.api.events.RegionsEnterEvent @@ -22,7 +26,7 @@ class EnterRegionEventEntry( override val id: String = "", override val name: String = "", override val triggers: List> = emptyList(), - @Help("The region to check for.") + @Help("Make sure that this is the region ID, not the region's display name.") // The region to check for. Make sure that this is the region ID, not the region's display name. val region: String = "", ) : EventEntry diff --git a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/fact/InRegionFact.kt b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/fact/InRegionFact.kt similarity index 68% rename from adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/fact/InRegionFact.kt rename to extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/fact/InRegionFact.kt index 185abca25f..fa58ce5f9f 100644 --- a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/entries/fact/InRegionFact.kt +++ b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/fact/InRegionFact.kt @@ -1,13 +1,13 @@ -package me.ahdg6.typewriter.rpgregions.entries.fact +package com.typewritermc.rpgregions.entries.fact -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.facts.FactData import net.islandearth.rpgregions.api.RPGRegionsAPI import org.bukkit.entity.Player @@ -26,8 +26,7 @@ class InRegionFact( override val name: String = "", override val comment: String = "", override val group: Ref = emptyRef(), - @Help("The name of the region which the player must be in") - // The name of the region which the player must be in. Make sure that this is the region ID, not the region's display name. + @Help("Make sure that this is the region ID, not the region's display name.") val region: String = "", ) : ReadableFactEntry { override fun readSinglePlayer(player: Player): FactData { diff --git a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/group/RegionGroup.kt b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/group/RegionGroup.kt similarity index 79% rename from adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/group/RegionGroup.kt rename to extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/group/RegionGroup.kt index 0ea9f96cfb..0adadcdc8a 100644 --- a/adapters/RPGRegionsAdapter/src/main/kotlin/me/ahdg6/typewriter/rpgregions/group/RegionGroup.kt +++ b/extensions/RPGRegionsExtension/src/main/kotlin/com/typewritermc/rpgregions/entries/group/RegionGroup.kt @@ -1,10 +1,10 @@ -package me.ahdg6.typewriter.rpgregions.group +package com.typewritermc.rpgregions.entries.group -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.GroupId import net.islandearth.rpgregions.api.RPGRegionsAPI import org.bukkit.entity.Player import kotlin.jvm.optionals.getOrNull diff --git a/adapters/FancyNpcsAdapter/src/main/templates/App.kt b/extensions/RPGRegionsExtension/src/main/templates/App.kt similarity index 100% rename from adapters/FancyNpcsAdapter/src/main/templates/App.kt rename to extensions/RPGRegionsExtension/src/main/templates/App.kt diff --git a/extensions/SuperiorSkyblockExtension/build.gradle.kts b/extensions/SuperiorSkyblockExtension/build.gradle.kts new file mode 100644 index 0000000000..8991d6475f --- /dev/null +++ b/extensions/SuperiorSkyblockExtension/build.gradle.kts @@ -0,0 +1,32 @@ +import com.typewritermc.loader.ExtensionFlag + +repositories { + maven("https://repo.bg-software.com/repository/api/") +} + +dependencies { + compileOnly("com.bgsoftware:SuperiorSkyblockAPI:1.11.1") +} + +typewriter { + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + namespace = "typewritermc" + + extension { + name = "SuperiorSkyblock" + shortDescription = "Integrate SuperiorSkyblock with Typewriter." + description = """ + |The Superior Skyblock Extension allows you to use the Superior Skyblock plugin with TypeWriter. + |It includes many events for you to use in your dialogue, as well as a few actions and conditions. + """.trimMargin() + + flag(ExtensionFlag.Deprecated) + + paper { + dependency("SuperiorSkyblock2") + } + } +} \ No newline at end of file diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandDisbandActionEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandDisbandActionEntry.kt similarity index 68% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandDisbandActionEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandDisbandActionEntry.kt index 860be5a219..2b65fe7f26 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandDisbandActionEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandDisbandActionEntry.kt @@ -1,13 +1,13 @@ -package com.caleb.typewriter.superiorskyblock.entries.action +package com.typewritermc.superiorskyblock.entries.action import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.entity.Player @Entry("island_disband", "Disbands player's island", Colors.RED, "fa6-solid:trash-alt") diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt similarity index 67% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt index 6078b900a6..4846e1576f 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetBiomeActionEntry.kt @@ -1,14 +1,13 @@ -package com.caleb.typewriter.superiorskyblock.entries.action +package com.typewritermc.superiorskyblock.entries.action import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.block.Biome import org.bukkit.entity.Player @@ -26,7 +25,6 @@ class IslandSetBiomeActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The biome to set the island to") val biome: Biome = Biome.PLAINS ) : ActionEntry { diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt similarity index 65% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt index fee72c3317..e376a88976 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetBorderSizeActionEntry.kt @@ -1,14 +1,13 @@ -package com.caleb.typewriter.superiorskyblock.entries.action +package com.typewritermc.superiorskyblock.entries.action import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.entity.Player @Entry("island_set_border_size", "Set a player's island's border size", Colors.RED, "fa6-solid:border-all") @@ -25,7 +24,6 @@ class IslandSetBorderSizeActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The size to set the island's border to") val size: Int = 0 ) : ActionEntry { diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt similarity index 68% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt index a2c891b641..0572b8322d 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/IslandSetMemberLimitActionEntry.kt @@ -1,14 +1,14 @@ -package com.caleb.typewriter.superiorskyblock.entries.action +package com.typewritermc.superiorskyblock.entries.action import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.entity.Player @Entry("island_set_member_limit", "Set a player's island's member limit", Colors.RED, "fa6-solid:people-group") diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt similarity index 68% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt index e9aff28a71..20b3eae0cb 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/bank/IslandBankDepositActionEntry.kt @@ -1,14 +1,13 @@ -package com.caleb.typewriter.superiorskyblock.entries.action.bank +package com.typewritermc.superiorskyblock.entries.action.bank import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.Bukkit import org.bukkit.entity.Player import java.math.BigDecimal @@ -28,7 +27,6 @@ class IslandBankDepositActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The amount to deposit into the player's Island bank") val amount: Double = 0.0 ) : ActionEntry { diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt similarity index 68% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt index ba6442ad5b..4139d68779 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/action/bank/IslandBankWithdrawActionEntry.kt @@ -1,14 +1,13 @@ -package com.caleb.typewriter.superiorskyblock.entries.action.bank +package com.typewritermc.superiorskyblock.entries.action.bank import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.Bukkit import org.bukkit.entity.Player import java.math.BigDecimal @@ -27,7 +26,6 @@ class IslandBankWithdrawActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The amount to withdraw from the player's Island bank") val amount: Double = 0.0 ) : ActionEntry { diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandCreateEventEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandCreateEventEntry.kt similarity index 62% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandCreateEventEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandCreateEventEntry.kt index f72a07939f..f9ddc2a08e 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandCreateEventEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandCreateEventEntry.kt @@ -1,10 +1,14 @@ -package com.caleb.typewriter.superiorskyblock.entries.event +package com.typewritermc.superiorskyblock.entries.event import com.bgsoftware.superiorskyblock.api.events.IslandCreateEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import org.bukkit.entity.Player @Entry("on_island_create", "When a player creates an Island", Colors.YELLOW, "fa6-solid:globe") diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandDisbandEventEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandDisbandEventEntry.kt similarity index 63% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandDisbandEventEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandDisbandEventEntry.kt index 0fc24d338f..079c857276 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandDisbandEventEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandDisbandEventEntry.kt @@ -1,10 +1,14 @@ -package com.caleb.typewriter.superiorskyblock.entries.event +package com.typewritermc.superiorskyblock.entries.event import com.bgsoftware.superiorskyblock.api.events.IslandDisbandEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import org.bukkit.entity.Player @Entry("on_island_disband", "When a player disbands an Island", Colors.YELLOW, "fa6-solid:globe") diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandInviteEventEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandInviteEventEntry.kt similarity index 65% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandInviteEventEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandInviteEventEntry.kt index ef147caa4b..ca76936a72 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandInviteEventEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandInviteEventEntry.kt @@ -1,11 +1,15 @@ -package com.caleb.typewriter.superiorskyblock.entries.event +package com.typewritermc.superiorskyblock.entries.event import com.bgsoftware.superiorskyblock.api.events.IslandInviteEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor +import com.typewritermc.engine.paper.entry.triggerEntriesFor @Entry("on_island_invite", "When a player is invited to a Skyblock island", Colors.YELLOW, "fa6-solid:envelope") /** @@ -19,7 +23,6 @@ class IslandInviteEventEntry( override val id: String = "", override val name: String = "", override val triggers: List> = emptyList(), - @Help("The triggers for the player who got invited") val inviteeTriggers: List> = emptyList(), ) : EventEntry diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandJoinEventEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandJoinEventEntry.kt similarity index 67% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandJoinEventEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandJoinEventEntry.kt index ff9fbf3e5a..e47a6d1894 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandJoinEventEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandJoinEventEntry.kt @@ -1,11 +1,15 @@ -package com.caleb.typewriter.superiorskyblock.entries.event +package com.typewritermc.superiorskyblock.entries.event import com.bgsoftware.superiorskyblock.api.events.IslandJoinEvent import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import org.bukkit.entity.Player @Entry("on_island_join", "When a player joins a Skyblock island", Colors.YELLOW, "fa6-solid:envelope-open") diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt similarity index 67% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt index 1fc382f84e..37482aa794 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/IslandUpgradeEventEntry.kt @@ -1,11 +1,15 @@ -package com.caleb.typewriter.superiorskyblock.entries.event +package com.typewritermc.superiorskyblock.entries.event import com.bgsoftware.superiorskyblock.api.events.IslandUpgradeEvent import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import org.bukkit.entity.Player @Entry("on_island_upgrade", "When a player upgrades their Skyblock island", Colors.YELLOW, "fa6-solid:arrow-up") diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/MissionCompleteEventEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/MissionCompleteEventEntry.kt similarity index 64% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/MissionCompleteEventEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/MissionCompleteEventEntry.kt index c316c0c6fc..b69115e41a 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/event/MissionCompleteEventEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/event/MissionCompleteEventEntry.kt @@ -1,11 +1,14 @@ -package com.caleb.typewriter.superiorskyblock.entries.event +package com.typewritermc.superiorskyblock.entries.event import com.bgsoftware.superiorskyblock.api.events.MissionCompleteEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor @Entry("on_mission_complete", "When a player completes a mission", Colors.YELLOW, "fa6-solid:clipboard-check") /** @@ -19,7 +22,6 @@ class MissionCompleteEventEntry( override val id: String = "", override val name: String = "", override val triggers: List> = emptyList(), - @Help("The name of the mission that needs to be completed") val missionName: String = "", ) : EventEntry diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/fact/IslandFactEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/fact/IslandFactEntry.kt similarity index 79% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/fact/IslandFactEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/fact/IslandFactEntry.kt index 3d58c841d7..8402335dfb 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/fact/IslandFactEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/fact/IslandFactEntry.kt @@ -1,16 +1,15 @@ -package com.caleb.typewriter.superiorskyblock.entries.fact +package com.typewritermc.superiorskyblock.entries.fact import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI import com.bgsoftware.superiorskyblock.api.island.Island import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.facts.FactData import org.bukkit.entity.Player import kotlin.math.roundToInt @@ -51,8 +50,6 @@ class IslandFactEntry( override val name: String = "", override val comment: String = "", override val group: Ref = emptyRef(), - @Help("The fact to get") - // The specific piece of information to retrieve about the island. val fact: IslandFacts, ) : ReadableFactEntry { override fun readSinglePlayer(player: Player): FactData { diff --git a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/group/IslandGroupEntry.kt b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/group/IslandGroupEntry.kt similarity index 72% rename from adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/group/IslandGroupEntry.kt rename to extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/group/IslandGroupEntry.kt index 79524bc610..871baa74c3 100644 --- a/adapters/SuperiorSkyblockAdapter/src/main/kotlin/com/caleb/typewriter/superiorskyblock/entries/group/IslandGroupEntry.kt +++ b/extensions/SuperiorSkyblockExtension/src/main/kotlin/com/typewritermc/superiorskyblock/entries/group/IslandGroupEntry.kt @@ -1,10 +1,10 @@ -package com.caleb.typewriter.superiorskyblock.entries.group +package com.typewritermc.superiorskyblock.entries.group import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.GroupId import org.bukkit.entity.Player @Entry("island_group", "Group for the whole island", Colors.MYRTLE_GREEN, "fa6-solid:globe") diff --git a/adapters/MythicMobsAdapter/src/main/templates/App.kt b/extensions/SuperiorSkyblockExtension/src/main/templates/App.kt similarity index 100% rename from adapters/MythicMobsAdapter/src/main/templates/App.kt rename to extensions/SuperiorSkyblockExtension/src/main/templates/App.kt diff --git a/extensions/VaultExtension/build.gradle.kts b/extensions/VaultExtension/build.gradle.kts new file mode 100644 index 0000000000..de94a2d2ea --- /dev/null +++ b/extensions/VaultExtension/build.gradle.kts @@ -0,0 +1,26 @@ +repositories { + maven("https://jitpack.io") +} +dependencies { + compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") +} + +typewriter { + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + namespace = "typewritermc" + + extension { + name = "Vault" + shortDescription = "Integrate Vault with Typewriter." + description = """ + |The Vault Extension is an extension that makes it easy to use Vault's economy system in your dialogue. + """.trimMargin() + + paper { + dependency("Vault") + } + } +} \ No newline at end of file diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/VaultAdapter.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/VaultInitializer.kt similarity index 68% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/VaultAdapter.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/VaultInitializer.kt index a3a43674f4..1806782f93 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/VaultAdapter.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/VaultInitializer.kt @@ -1,21 +1,15 @@ -package com.caleb.typewriter.vault +package com.typewritermc.vault -import App -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter -import me.gabber235.typewriter.logger +import com.typewritermc.core.extension.Initializable +import com.typewritermc.core.extension.annotations.Initializer import net.milkbowl.vault.chat.Chat import net.milkbowl.vault.economy.Economy import net.milkbowl.vault.permission.Permission import org.bukkit.Bukkit.getServer import org.bukkit.plugin.RegisteredServiceProvider -@Adapter("Vault", "For Vault", App.VERSION) -/** - * The Vault Adapter is an adapter for the Vault plugin. It allows you to use Vault's economy system in your dialogue. - */ -object VaultAdapter : TypewriterAdapter() { +@Initializer +object VaultInitializer : Initializable { var economy: Economy? = null private set @@ -27,14 +21,15 @@ object VaultAdapter : TypewriterAdapter() { override fun initialize() { - if (!server.pluginManager.isPluginEnabled("Vault")) { - logger.warning("Vault plugin not found, try installing it or disabling the Vault adapter") - return - } - loadVault() } + override fun shutdown() { + economy = null + permissions = null + chat = null + } + private fun loadVault() { setupEconomy() setupPermissions() diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/DepositBalanceActionEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/DepositBalanceActionEntry.kt similarity index 58% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/DepositBalanceActionEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/DepositBalanceActionEntry.kt index cd007e3d67..2f24b19712 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/DepositBalanceActionEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/DepositBalanceActionEntry.kt @@ -1,14 +1,13 @@ -package com.caleb.typewriter.vault.entries.action +package com.typewritermc.vault.entries.action -import com.caleb.typewriter.vault.VaultAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.vault.VaultInitializer import net.milkbowl.vault.economy.Economy import org.bukkit.entity.Player @@ -26,13 +25,12 @@ class DepositBalanceActionEntry( override val criteria: List = emptyList(), override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), - @Help("The amount of money to deposit.") private val amount: Double = 0.0, ) : ActionEntry { override fun execute(player: Player) { super.execute(player) - val economy: Economy = VaultAdapter.economy ?: return + val economy: Economy = VaultInitializer.economy ?: return economy.depositPlayer(player, amount) } diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/SetPrefixActionEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/SetPrefixActionEntry.kt similarity index 61% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/SetPrefixActionEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/SetPrefixActionEntry.kt index 110644eb5e..defa9afa59 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/SetPrefixActionEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/SetPrefixActionEntry.kt @@ -1,14 +1,14 @@ -package com.caleb.typewriter.vault.entries.action +package com.typewritermc.vault.entries.action -import com.caleb.typewriter.vault.VaultAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.vault.VaultInitializer +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import net.milkbowl.vault.chat.Chat import org.bukkit.entity.Player @@ -34,7 +34,7 @@ class SetPrefixActionEntry( override fun execute(player: Player) { super.execute(player) - val chat: Chat = VaultAdapter.chat ?: return + val chat: Chat = VaultInitializer.chat ?: return chat.setPlayerPrefix(player, prefix) } diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/WithdrawBalanceActionEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/WithdrawBalanceActionEntry.kt similarity index 60% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/WithdrawBalanceActionEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/WithdrawBalanceActionEntry.kt index 2f98a26324..534a5a84fe 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/action/WithdrawBalanceActionEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/action/WithdrawBalanceActionEntry.kt @@ -1,14 +1,14 @@ -package com.caleb.typewriter.vault.entries.action +package com.typewritermc.vault.entries.action -import com.caleb.typewriter.vault.VaultAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.vault.VaultInitializer +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import net.milkbowl.vault.economy.Economy import org.bukkit.entity.Player @@ -32,7 +32,7 @@ class WithdrawBalanceActionEntry( override fun execute(player: Player) { super.execute(player) - val economy: Economy = VaultAdapter.economy ?: return + val economy: Economy = VaultInitializer.economy ?: return economy.withdrawPlayer(player, amount) } diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/fact/BalanceFactEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/fact/BalanceFactEntry.kt similarity index 61% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/fact/BalanceFactEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/fact/BalanceFactEntry.kt index 0c8db51ac9..b5ca16ec8e 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/fact/BalanceFactEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/fact/BalanceFactEntry.kt @@ -1,13 +1,13 @@ -package com.caleb.typewriter.vault.entries.fact +package com.typewritermc.vault.entries.fact -import com.caleb.typewriter.vault.VaultAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData +import com.typewritermc.vault.VaultInitializer +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.facts.FactData import org.bukkit.entity.Player @Entry("balance_fact", "The balance of a player's account", Colors.PURPLE, "fa6-solid:money-bill-wave") @@ -27,7 +27,7 @@ class BalanceFactEntry( override val group: Ref = emptyRef(), ) : ReadableFactEntry { override fun readSinglePlayer(player: Player): FactData { - val permissionHandler = VaultAdapter.economy ?: return FactData(0) + val permissionHandler = VaultInitializer.economy ?: return FactData(0) val balance = permissionHandler.getBalance(player) return FactData(balance.toInt()) } diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/fact/PermissionFactEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/fact/PermissionFactEntry.kt similarity index 59% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/fact/PermissionFactEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/fact/PermissionFactEntry.kt index 6bcbfb2a92..7ae750ad1a 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/fact/PermissionFactEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/fact/PermissionFactEntry.kt @@ -1,14 +1,14 @@ -package com.caleb.typewriter.vault.entries.fact +package com.typewritermc.vault.entries.fact -import com.caleb.typewriter.vault.VaultAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData +import com.typewritermc.vault.VaultInitializer +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.facts.FactData import net.milkbowl.vault.permission.Permission import org.bukkit.entity.Player @@ -29,7 +29,7 @@ class PermissionFactEntry( val permission: String = "", ) : ReadableFactEntry { override fun readSinglePlayer(player: Player): FactData { - val permissionHandler: Permission = VaultAdapter.permissions ?: return FactData(0) + val permissionHandler: Permission = VaultInitializer.permissions ?: return FactData(0) val value = if (permissionHandler.playerHas(player, permission)) 1 else 0 return FactData(value) } diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/group/BalanceGroupEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/group/BalanceGroupEntry.kt similarity index 70% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/group/BalanceGroupEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/group/BalanceGroupEntry.kt index 2cc31d4512..2c48c94f99 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/group/BalanceGroupEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/group/BalanceGroupEntry.kt @@ -1,11 +1,11 @@ -package com.caleb.typewriter.vault.entries.group +package com.typewritermc.vault.entries.group -import com.caleb.typewriter.vault.VaultAdapter -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.CriteriaOperator -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.vault.VaultInitializer +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.CriteriaOperator +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.GroupId import org.bukkit.entity.Player @Entry("balance_audience", "Audiences grouped by balance", Colors.MYRTLE_GREEN, "fa6-solid:balance-scale") @@ -23,7 +23,7 @@ class BalanceGroupEntry( val group: List = emptyList(), ) : GroupEntry { override fun groupId(player: Player): GroupId? { - val balance = VaultAdapter.economy?.getBalance(player) ?: return null + val balance = VaultInitializer.economy?.getBalance(player) ?: return null return group .firstOrNull { it.operator.isValid(balance, it.value) } ?.let { GroupId(it.audience) } diff --git a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/group/PermissionGroupEntry.kt b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/group/PermissionGroupEntry.kt similarity index 79% rename from adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/group/PermissionGroupEntry.kt rename to extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/group/PermissionGroupEntry.kt index 276dcbd73f..5e49984208 100644 --- a/adapters/VaultAdapter/src/main/kotlin/com/caleb/typewriter/vault/entries/group/PermissionGroupEntry.kt +++ b/extensions/VaultExtension/src/main/kotlin/com/typewritermc/vault/entries/group/PermissionGroupEntry.kt @@ -1,10 +1,10 @@ -package com.caleb.typewriter.vault.entries.group +package com.typewritermc.vault.entries.group import lirand.api.extensions.server.hasPermissionOrStar -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.GroupId import org.bukkit.entity.Player @Entry("permission_group", "Groups grouped by permission", Colors.MYRTLE_GREEN, "fa6-solid:key") diff --git a/adapters/RPGRegionsAdapter/src/main/templates/App.kt b/extensions/VaultExtension/src/main/templates/App.kt similarity index 100% rename from adapters/RPGRegionsAdapter/src/main/templates/App.kt rename to extensions/VaultExtension/src/main/templates/App.kt diff --git a/extensions/WorldGuardExtension/build.gradle.kts b/extensions/WorldGuardExtension/build.gradle.kts new file mode 100644 index 0000000000..707c2746ab --- /dev/null +++ b/extensions/WorldGuardExtension/build.gradle.kts @@ -0,0 +1,29 @@ +repositories { + maven("https://maven.enginehub.org/repo/") +} + +dependencies { + compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.11-SNAPSHOT") +} + +typewriter { + namespace = "typewritermc" + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + + extension { + name = "WorldGuard" + shortDescription = "Integrate WorldGuard with Typewriter." + description = """ + |The WorldGuard Extension allows you to create dialogue triggered by WorldGuard regions. + |Have dialogues that only show up when a player enters or leaves a specific region. + |Have sidebars that only show when the player is in a specific region. + """.trimMargin() + + paper { + dependency("WorldGuard") + } + } +} \ No newline at end of file diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardHandler.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardHandler.kt similarity index 54% rename from adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardHandler.kt rename to extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardHandler.kt index 7d1b7354a7..8232cb2f29 100644 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/WorldGuardHandler.kt +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardHandler.kt @@ -1,4 +1,4 @@ -package com.caleb.typewriter.worldguard +package com.typewritermc.worldguard import com.sk89q.worldedit.util.Location import com.sk89q.worldguard.LocalPlayer @@ -7,12 +7,15 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion import com.sk89q.worldguard.session.MoveType import com.sk89q.worldguard.session.Session import com.sk89q.worldguard.session.handler.Handler +import lirand.api.extensions.server.server +import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.HandlerList +import org.bukkit.event.player.PlayerEvent class WorldGuardHandler(session: Session?) : Handler(session) { - class Factory : Handler.Factory() { + object Factory : Handler.Factory() { override fun create(session: Session?): WorldGuardHandler { return WorldGuardHandler(session) } @@ -28,38 +31,43 @@ class WorldGuardHandler(session: Session?) : Handler(session) { moveType: MoveType? ): Boolean { if (player == null) return false + val bukkitPlayer = server.getPlayer(player.uniqueId) ?: return false - if (!entered.isNullOrEmpty()) entered.let { RegionsEnterEvent(player, it).callEvent() } - if (!exited.isNullOrEmpty()) exited.let { RegionsExitEvent(player, it).callEvent() } + if (!entered.isNullOrEmpty()) entered.let { + RegionsEnterEvent(bukkitPlayer, it).callEvent() + } + if (!exited.isNullOrEmpty()) exited.let { + RegionsExitEvent(bukkitPlayer, it).callEvent() + } return super.onCrossBoundary(player, from, to, toSet, entered, exited, moveType) } } -class RegionsEnterEvent(val player: LocalPlayer, val regions: Set) : Event() { - +class RegionsEnterEvent(player: Player, val regions: Set) : PlayerEvent(player) { operator fun contains(regionName: String) = regions.any { it.id == regionName } + override fun getHandlers(): HandlerList = HANDLER_LIST + companion object { @JvmStatic - val handlerList = HandlerList() - } + val HANDLER_LIST = HandlerList() - override fun getHandlers(): HandlerList { - return handlerList + @JvmStatic + fun getHandlerList(): HandlerList = HANDLER_LIST } } -class RegionsExitEvent(val player: LocalPlayer, val regions: Set) : Event() { - +class RegionsExitEvent(player: Player, val regions: Set) : PlayerEvent(player) { operator fun contains(regionName: String) = regions.any { it.id == regionName } + override fun getHandlers(): HandlerList = HANDLER_LIST + companion object { @JvmStatic - val handlerList = HandlerList() - } + val HANDLER_LIST = HandlerList() - override fun getHandlers(): HandlerList { - return handlerList + @JvmStatic + fun getHandlerList(): HandlerList = HANDLER_LIST } } \ No newline at end of file diff --git a/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardInitializer.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardInitializer.kt new file mode 100644 index 0000000000..92e9310960 --- /dev/null +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/WorldGuardInitializer.kt @@ -0,0 +1,61 @@ +package com.typewritermc.worldguard + +import com.sk89q.worldguard.WorldGuard +import com.sk89q.worldguard.bukkit.WorldGuardPlugin +import com.typewritermc.core.extension.Initializable +import com.typewritermc.core.extension.annotations.Initializer +import com.typewritermc.engine.paper.logger +import lirand.api.extensions.server.server + +@Initializer +object WorldGuardInitializer : Initializable { + private val factory = WorldGuardHandler.Factory + + override fun initialize() { + val worldGuard = WorldGuard.getInstance() + + val registered = worldGuard.platform.sessionManager.registerHandler(factory, null) + + if (!registered) { + logger.warning("Failed to register WorldGuardHandler. This is a bug, please report it on the Typewriter Discord.") + return + } + val worldGuardPlugin = server.pluginManager.getPlugin("WorldGuard") as? WorldGuardPlugin + if (worldGuardPlugin == null) { + logger.warning("WorldGuard plugin not found, so WorldGuard will not be enabled.") + return + } + + // This is a hack to fix a shortcomming in WorldGuard. + // WorldGuard does not register the handler to ongoing sessions. + // So we need to manually register the handler to all active sessions when the extension is reloaded. + server.onlinePlayers.forEach { player -> + val bukkitPlayer = WorldGuardPlugin.inst().wrapPlayer(player) + worldGuard.platform.sessionManager.getIfPresent(bukkitPlayer)?.let { session -> + val currentHandler = session.getHandler(WorldGuardHandler::class.java) + if (currentHandler != null) { + return@forEach + } + session.register(factory.create(session)) + } + } + } + + override fun shutdown() { + WorldGuard.getInstance().platform.sessionManager.unregisterHandler(factory) + + // This is a hack to fix a shortcomming in WorldGuard. + // WorldGuard does not unregister the handler from ongoing sessions. + // So we need to manually unregister the handler from all sessions. + server.onlinePlayers.forEach { player -> + val bukkitPlayer = WorldGuardPlugin.inst().wrapPlayer(player) + WorldGuard.getInstance().platform.sessionManager.getIfPresent(bukkitPlayer)?.let { session -> + session::class.java.getDeclaredField("handlers").apply { + isAccessible = true + val handlers = get(session) as MutableMap, Any> + handlers.remove(WorldGuardHandler::class.java) + } + } + } + } +} \ No newline at end of file diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/audience/RegionAudienceEntry.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/audience/RegionAudienceEntry.kt similarity index 64% rename from adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/audience/RegionAudienceEntry.kt rename to extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/audience/RegionAudienceEntry.kt index 209d1dcf3e..dddfdb0f33 100644 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/audience/RegionAudienceEntry.kt +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/audience/RegionAudienceEntry.kt @@ -1,19 +1,18 @@ -package com.caleb.typewriter.worldguard.entries.audience +package com.typewritermc.worldguard.entries.audience -import com.caleb.typewriter.worldguard.RegionsEnterEvent -import com.caleb.typewriter.worldguard.RegionsExitEvent import com.sk89q.worldedit.bukkit.BukkitAdapter import com.sk89q.worldguard.WorldGuard +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.AudienceFilter +import com.typewritermc.engine.paper.entry.entries.AudienceFilterEntry +import com.typewritermc.engine.paper.entry.entries.Invertible +import com.typewritermc.worldguard.RegionsEnterEvent +import com.typewritermc.worldguard.RegionsExitEvent import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.AudienceFilterEntry -import me.gabber235.typewriter.entry.entries.Invertible -import me.gabber235.typewriter.entry.ref import org.bukkit.entity.Player import org.bukkit.event.EventHandler @@ -34,7 +33,6 @@ class RegionAudienceEntry( override val id: String = "", override val name: String = "", override val children: List> = emptyList(), - @Help("The region to filter players based on") val region: String = "", override val inverted: Boolean = false, ) : AudienceFilterEntry, Invertible { @@ -51,18 +49,16 @@ class RegionAudienceFilter( @EventHandler fun onRegionEnter(event: RegionsEnterEvent) { - if (!canConsider(event.player.uniqueId)) return + if (!canConsider(event.player)) return if (event.regions.none { it.id == region }) return - val player = server.getPlayer(event.player.uniqueId) ?: return - player.updateFilter(true) + event.player.updateFilter(true) } @EventHandler fun onRegionLeave(event: RegionsExitEvent) { - if (!canConsider(event.player.uniqueId)) return + if (!canConsider(event.player)) return if (event.regions.none { it.id == region }) return - val player = server.getPlayer(event.player.uniqueId) ?: return - player.updateFilter(false) + event.player.updateFilter(false) } override fun filter(player: Player): Boolean { diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/event/EnterRegionEventEntry.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/event/EnterRegionEventEntry.kt similarity index 57% rename from adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/event/EnterRegionEventEntry.kt rename to extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/event/EnterRegionEventEntry.kt index db87b25047..d7cc29bdf4 100644 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/event/EnterRegionEventEntry.kt +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/event/EnterRegionEventEntry.kt @@ -1,12 +1,15 @@ -package com.caleb.typewriter.worldguard.entries.event +package com.typewritermc.worldguard.entries.event -import com.caleb.typewriter.worldguard.RegionsEnterEvent +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor +import com.typewritermc.worldguard.RegionsEnterEvent import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry @Entry("on_enter_region", "When a player enters a WorldGuard region", Colors.YELLOW, "fa6-solid:door-open") /** @@ -21,14 +24,11 @@ class EnterRegionEventEntry( override val id: String = "", override val name: String = "", override val triggers: List> = emptyList(), - @Help("The region to check for.") - // The region that the player must enter to trigger the event. val region: String = "", ) : EventEntry @EntryListener(EnterRegionEventEntry::class) fun onEnterRegions(event: RegionsEnterEvent, query: Query) { - val player = server.getPlayer(event.player.uniqueId) ?: return - query findWhere { it.region in event } triggerAllFor player + query findWhere { it.region in event } triggerAllFor event.player } diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/event/ExitRegionEventEntry.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/event/ExitRegionEventEntry.kt similarity index 59% rename from adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/event/ExitRegionEventEntry.kt rename to extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/event/ExitRegionEventEntry.kt index bb29bfdb36..6958fd05b8 100644 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/event/ExitRegionEventEntry.kt +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/event/ExitRegionEventEntry.kt @@ -1,12 +1,15 @@ -package com.caleb.typewriter.worldguard.entries.event +package com.typewritermc.worldguard.entries.event -import com.caleb.typewriter.worldguard.RegionsExitEvent +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor +import com.typewritermc.worldguard.RegionsExitEvent import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry @Entry("on_exit_region", "When a player exits a WorldGuard region", Colors.YELLOW, "fa6-solid:door-closed") /** @@ -21,14 +24,11 @@ class ExitRegionEventEntry( override val id: String = "", override val name: String = "", override val triggers: List> = emptyList(), - @Help("The region to check for.") - // The region the player must leave to trigger the event. val region: String = "", ) : EventEntry @EntryListener(ExitRegionEventEntry::class) fun onExitRegions(event: RegionsExitEvent, query: Query) { - val player = server.getPlayer(event.player.uniqueId) ?: return - query findWhere { it.region in event } triggerAllFor player + query findWhere { it.region in event } triggerAllFor event.player } diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/fact/InRegionFact.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/fact/InRegionFact.kt similarity index 71% rename from adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/fact/InRegionFact.kt rename to extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/fact/InRegionFact.kt index 27fcc884b4..18859e84cd 100644 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/fact/InRegionFact.kt +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/fact/InRegionFact.kt @@ -1,15 +1,14 @@ -package com.caleb.typewriter.worldguard.entries.fact +package com.typewritermc.worldguard.entries.fact import com.sk89q.worldedit.bukkit.BukkitAdapter import com.sk89q.worldguard.WorldGuard -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.ReadableFactEntry -import me.gabber235.typewriter.facts.FactData +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.ReadableFactEntry +import com.typewritermc.engine.paper.facts.FactData import org.bukkit.entity.Player @Entry("in_region_fact", "If the player is in a WorldGuard region", Colors.PURPLE, "fa6-solid:road-barrier") @@ -27,7 +26,6 @@ class InRegionFact( override val name: String = "", override val comment: String = "", override val group: Ref = emptyRef(), - @Help("The name of the region which the player must be in.") val region: String = "", ) : ReadableFactEntry { override fun readSinglePlayer(player: Player): FactData { diff --git a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/group/RegionGroup.kt b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/group/RegionGroup.kt similarity index 77% rename from adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/group/RegionGroup.kt rename to extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/group/RegionGroup.kt index 09d2add185..c5617f9a77 100644 --- a/adapters/WorldGuardAdapter/src/main/kotlin/com/caleb/typewriter/worldguard/entries/group/RegionGroup.kt +++ b/extensions/WorldGuardExtension/src/main/kotlin/com/typewritermc/worldguard/entries/group/RegionGroup.kt @@ -1,12 +1,11 @@ -package com.caleb.typewriter.worldguard.entries.group +package com.typewritermc.worldguard.entries.group import com.sk89q.worldedit.bukkit.BukkitAdapter import com.sk89q.worldguard.WorldGuard -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.GroupEntry +import com.typewritermc.engine.paper.entry.entries.GroupId import org.bukkit.entity.Player @Entry("region_group", "All players grouped by WorldGuard regions", Colors.MYRTLE_GREEN, "fa6-solid:object-group") @@ -21,7 +20,6 @@ import org.bukkit.entity.Player class RegionGroup( override val id: String = "", override val name: String = "", - @Help("The names of regions to consider for the group") val regions: List = emptyList(), ) : GroupEntry { override fun groupId(player: Player): GroupId? { diff --git a/adapters/SuperiorSkyblockAdapter/src/main/templates/App.kt b/extensions/WorldGuardExtension/src/main/templates/App.kt similarity index 100% rename from adapters/SuperiorSkyblockAdapter/src/main/templates/App.kt rename to extensions/WorldGuardExtension/src/main/templates/App.kt diff --git a/extensions/_DocsExtension/build.gradle.kts b/extensions/_DocsExtension/build.gradle.kts new file mode 100644 index 0000000000..80d0efaf29 --- /dev/null +++ b/extensions/_DocsExtension/build.gradle.kts @@ -0,0 +1,22 @@ +repositories {} +dependencies {} + +typewriter { + engine { + version = file("../../version.txt").readText().trim() + channel = com.typewritermc.moduleplugin.ReleaseChannel.NONE + } + namespace = "typewritermc" + + extension { + name = "Documentation" + shortDescription = "Documentation for Typewriter." + description = """ + |This extension contains the documentation for Typewriter. + |It has examples of how to use the different parts of Typewriter. + |It should not be used as a dependency. + """.trimMargin() + + paper() + } +} diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt new file mode 100644 index 0000000000..4bb597eb32 --- /dev/null +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt @@ -0,0 +1,17 @@ +package com.typewritermc.example + +// +import com.typewritermc.core.extension.Initializable +import com.typewritermc.core.extension.annotations.Initializer + +@Initializer +object ExampleInitializer : Initializable { + override fun initialize() { + // Do something when the extension is initialized + } + + override fun shutdown() { + // Do something when the extension is shutdown + } +} +// \ No newline at end of file diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt similarity index 93% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt index f35d596bba..fbaff964d2 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt @@ -1,11 +1,11 @@ package com.typewritermc.example.entries.cinematic -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.* -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction -import me.gabber235.typewriter.entry.entries.* +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.* +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.cinematic.SimpleCinematicAction +import com.typewritermc.engine.paper.entry.entries.* import org.bukkit.entity.Player // diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt similarity index 88% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt index fad71ec8a5..f903029b87 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt @@ -1,12 +1,12 @@ package com.typewritermc.example.entries.manifest import com.typewritermc.example.entries.trigger.SomeBukkitEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.TickableDisplay -import me.gabber235.typewriter.utils.ThreadType +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.AudienceDisplay +import com.typewritermc.engine.paper.entry.entries.AudienceEntry +import com.typewritermc.engine.paper.entry.entries.TickableDisplay +import com.typewritermc.engine.paper.utils.ThreadType import org.bukkit.entity.Player import org.bukkit.event.EventHandler diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt similarity index 74% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt index 46dd3eca73..99205c84fc 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt @@ -1,10 +1,10 @@ package com.typewritermc.example.entries.static -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.ArtifactEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.AssetManager +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.ArtifactEntry import org.koin.java.KoinJavaComponent // diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt similarity index 73% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt index 5cd21e0d2f..b27989f345 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt @@ -1,10 +1,10 @@ package com.typewritermc.example.entries.static -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.AssetManager -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AssetEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.AssetManager +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.entries.AssetEntry import org.koin.java.KoinJavaComponent // diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt similarity index 67% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt index fd1eecfd12..4dbf9cb1da 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt @@ -1,8 +1,8 @@ package com.typewritermc.example.entries.static -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.entries.SoundIdEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.SoundIdEntry // @Entry("example_sound", "An example sound entry.", Colors.BLUE, "icon-park-solid:volume-up") diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt similarity index 77% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt index c1bf10e1eb..8ebe6ea949 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt @@ -1,8 +1,8 @@ package com.typewritermc.example.entries.static -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.entries.SoundSourceEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.SoundSourceEntry import net.kyori.adventure.sound.Sound // diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt similarity index 65% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt index 6e7a225d86..67835646d2 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt @@ -1,9 +1,9 @@ package com.typewritermc.example.entries.static -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.utils.Sound +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.utils.Sound // @Entry("example_speaker", "An example speaker entry.", Colors.BLUE, "ic:round-spatial-audio-off") diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt similarity index 65% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt index 59f54f04d8..fd5ed764a0 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt @@ -1,12 +1,12 @@ package com.typewritermc.example.entries.trigger -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.core.entries.Ref +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.ActionEntry import org.bukkit.entity.Player // diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt similarity index 60% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt index 86fd230935..f1d674a419 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt @@ -1,17 +1,22 @@ package com.typewritermc.example.entries.trigger import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry import org.bukkit.entity.Player // -@Entry("example_custom_triggering_action", "An example custom triggering entry.", Colors.RED, "material-symbols:touch-app-rounded") +@Entry( + "example_custom_triggering_action", + "An example custom triggering entry.", + Colors.RED, + "material-symbols:touch-app-rounded" +) class ExampleCustomTriggeringActionEntry( override val id: String = "", override val name: String = "", diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt similarity index 66% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt index a37ad4a02d..35f142bd90 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt @@ -1,20 +1,19 @@ package com.typewritermc.example.entries.trigger -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.Messenger -import me.gabber235.typewriter.adapters.MessengerFilter -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.dialogue.DialogueMessenger -import me.gabber235.typewriter.entry.dialogue.MessengerState -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.entries.emptyRef +import com.typewritermc.core.extension.annotations.* +import com.typewritermc.engine.paper.entry.Criteria +import com.typewritermc.engine.paper.entry.Modifier +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.dialogue.DialogueMessenger +import com.typewritermc.engine.paper.entry.dialogue.MessengerFilter +import com.typewritermc.engine.paper.entry.dialogue.MessengerState +import com.typewritermc.engine.paper.entry.entries.DialogueEntry +import com.typewritermc.engine.paper.entry.entries.SpeakerEntry +import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders +import com.typewritermc.engine.paper.utils.asMini import org.bukkit.entity.Player import java.time.Duration diff --git a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt similarity index 69% rename from adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt rename to extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt index f3284f92b9..efc6d194fe 100644 --- a/adapters/_DocsAdapter/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt @@ -1,9 +1,13 @@ package com.typewritermc.example.entries.trigger -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.EventEntry +import com.typewritermc.core.books.pages.Colors +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.engine.paper.entry.TriggerableEntry +import com.typewritermc.engine.paper.entry.entries.EventEntry +import com.typewritermc.engine.paper.entry.triggerAllFor import org.bukkit.entity.Player import org.bukkit.event.HandlerList import org.bukkit.event.player.PlayerEvent @@ -28,7 +32,7 @@ fun onEvent(event: SomeBukkitEvent, query: Query) { } // -class SomeBukkitEvent(val player: Player) : PlayerEvent(player) { +class SomeBukkitEvent(player: Player) : PlayerEvent(player) { override fun getHandlers(): HandlerList = HANDLER_LIST companion object { diff --git a/adapters/VaultAdapter/src/main/templates/App.kt b/extensions/_DocsExtension/src/main/templates/App.kt similarity index 100% rename from adapters/VaultAdapter/src/main/templates/App.kt rename to extensions/_DocsExtension/src/main/templates/App.kt diff --git a/adapters/build.gradle.kts b/extensions/build.gradle.kts similarity index 57% rename from adapters/build.gradle.kts rename to extensions/build.gradle.kts index 3015271490..578ec350d9 100644 --- a/adapters/build.gradle.kts +++ b/extensions/build.gradle.kts @@ -2,41 +2,19 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly plugins { - kotlin("jvm") version "2.0.0" + kotlin("jvm") version "2.0.20" id("io.github.goooler.shadow") version "8.1.7" + id("com.typewritermc.module-plugin") apply false + `maven-publish` } allprojects { - repositories { - // Required - mavenCentral() - maven("https://repo.papermc.io/repository/maven-public/") - maven("https://repo.codemc.io/repository/maven-releases/") - maven("https://repo.opencollab.dev/maven-snapshots/") - maven("https://jitpack.io") - } -} - - -subprojects { - group = "me.gabber235" - version = file("../../version.txt").readText().trim() - apply(plugin = "java") apply(plugin = "kotlin") - apply(plugin = "io.github.goooler.shadow") - dependencies { - compileOnly("com.github.gabber235:typewriter:$version") - } - - tasks.withType { - exclude("kotlin/**") - exclude("META-INF/maven/**") - // Important: Use the relocated commandapi which is shadowed by the plugin - relocate("dev.jorel.commandapi", "com.github.gabber235.typewriter.extensions.commandapi") { - include("dev.jorel.commandapi.**") - } + repositories { + // Required + mavenCentral() } val targetJavaVersion = 21 @@ -46,22 +24,26 @@ subprojects { targetCompatibility = javaVersion toolchain.languageVersion.set(JavaLanguageVersion.of(targetJavaVersion)) } - kotlin { jvmToolchain(targetJavaVersion) } +} - val copyTemplates by tasks.registering(Copy::class) { - filteringCharset = "UTF-8" - from(projectDir.resolve("src/main/templates")) { - expand("version" to version) - } - into(buildDir.resolve("generated-sources/templates/kotlin/main")) - } - sourceSets { - main { - java.srcDirs(copyTemplates) +subprojects { + group = "com.typewritermc" + version = file("../../version.txt").readText().trim() + + apply(plugin = "io.github.goooler.shadow") + apply(plugin = "com.typewritermc.module-plugin") + apply() + + tasks.withType { + exclude("kotlin/**") + exclude("META-INF/maven/**") + // Important: Use the relocated commandapi which is shadowed by the plugin + relocate("dev.jorel.commandapi", "com.typewritermc.engine.paper.extensions.commandapi") { + include("dev.jorel.commandapi.**") } } @@ -76,7 +58,7 @@ subprojects { doLast { val jar = file("build/libs/%s-%s-all.jar".format(project.name, project.version)) val server = - file("../../plugin/server/plugins/Typewriter/adapters/%s.jar".format(project.name.capitalizeAsciiOnly())) + file("../../server/plugins/Typewriter/extensions/%s.jar".format(project.name.capitalizeAsciiOnly())) jar.copyTo(server, overwrite = true) } } @@ -93,6 +75,36 @@ subprojects { file("build/libs/%s-%s.jar".format(project.name, project.version)).delete() } } -} - + publishing { + repositories { + maven { + name = "TypewriterReleases" + url = uri("https://maven.typewritermc.com/releases") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } + } + maven { + name = "TypewriterBeta" + url = uri("https://maven.typewritermc.com/beta") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } + } + } + publications { + create("maven") { + group = project.group + // Remove everything after the beta. So 1.0.0-beta-1 becomes 1.0.0 + version = project.version.toString().substringBefore("-beta") + artifactId = project.name + + from(components["kotlin"]) + artifact(tasks["shadowJar"]) + } + } + } +} diff --git a/adapters/gradle/wrapper/gradle-wrapper.jar b/extensions/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from adapters/gradle/wrapper/gradle-wrapper.jar rename to extensions/gradle/wrapper/gradle-wrapper.jar diff --git a/adapters/gradle/wrapper/gradle-wrapper.properties b/extensions/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from adapters/gradle/wrapper/gradle-wrapper.properties rename to extensions/gradle/wrapper/gradle-wrapper.properties diff --git a/adapters/gradlew b/extensions/gradlew similarity index 100% rename from adapters/gradlew rename to extensions/gradlew diff --git a/adapters/gradlew.bat b/extensions/gradlew.bat similarity index 100% rename from adapters/gradlew.bat rename to extensions/gradlew.bat diff --git a/extensions/settings.gradle.kts b/extensions/settings.gradle.kts new file mode 100644 index 0000000000..e55204a32f --- /dev/null +++ b/extensions/settings.gradle.kts @@ -0,0 +1,34 @@ +includeBuild("../engine") +includeBuild("../module-plugin") + +val ignoringExtensions: List = emptyList() + +val directories = file("./").listFiles()?.filter { + it.name.endsWith("Extension") && it.isDirectory && it.name !in ignoringExtensions +} ?: emptyList() + +for (directory in directories) { + include(directory.name) +} + +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("com.gradle.enterprise") version ("3.13.3") + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} + +gradleEnterprise { + buildScan { + termsOfServiceUrl = "https://gradle.com/terms-of-service" + termsOfServiceAgree = "yes" + } +} + + diff --git a/jitpack.yml b/jitpack.yml deleted file mode 100644 index 09bb5a5474..0000000000 --- a/jitpack.yml +++ /dev/null @@ -1,12 +0,0 @@ -jdk: - - temurin-21 - - temurin-17 -before_install: - - sdk install java 21.0.4-tem - - sdk install java 17.0.12-tem - - sdk use java 21.0.4-tem - - echo "Before install" - # Delete all folders and files, except .git, plugin/, version.txt and move the content of `plugin` folder to the root - - find . ! -name '.git' ! -name 'plugin' ! -name 'version.txt' -maxdepth 1 -exec rm -rf {} \; - - mv plugin/* . - - rm -rf plugin diff --git a/module-plugin/api/build.gradle.kts b/module-plugin/api/build.gradle.kts new file mode 100644 index 0000000000..f406d0d2b5 --- /dev/null +++ b/module-plugin/api/build.gradle.kts @@ -0,0 +1,4 @@ +repositories { } +dependencies { + testImplementation(kotlin("test")) +} \ No newline at end of file diff --git a/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt b/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt new file mode 100644 index 0000000000..45a7ae22d8 --- /dev/null +++ b/module-plugin/api/src/main/kotlin/com/typewritermc/moduleplugin/TypewriterModuleConfiguration.kt @@ -0,0 +1,172 @@ +package com.typewritermc.moduleplugin + +import com.typewritermc.loader.ExtensionFlag +import kotlinx.serialization.MissingFieldException +import kotlinx.serialization.Serializable + +@Serializable +open class TypewriterModuleConfiguration { + /** + * The namespace of the module. + * This must be tied to your organization. + */ + var namespace: String = "" + + val flags: MutableList = mutableListOf() + + var engine: TypewriterEngineConfiguration? = null + var extension: TypewriterExtensionConfiguration? = null + + /** + * Adds a flag to the module. + */ + fun flag(flag: ExtensionFlag) { + flags.add(flag) + } + + fun engine(block: TypewriterEngineConfiguration.() -> Unit) { + engine = TypewriterEngineConfiguration().apply(block) + } + + fun extension(block: TypewriterExtensionConfiguration.() -> Unit) { + extension = TypewriterExtensionConfiguration().apply(block) + } +} + +const val MIN_NAMESPACE_LENGTH = 5 +const val MAX_NAMESPACE_LENGTH = 20 +fun TypewriterModuleConfiguration.validate() { + if (namespace.isBlank()) { + throw MissingFieldException("namespace") + } + if (!Regex("^([a-z0-9])+\$").matches(namespace)) { + throw IllegalArgumentException("Namespace must only contain lowercase letters and numbers.") + } + if (namespace.length !in MIN_NAMESPACE_LENGTH..MAX_NAMESPACE_LENGTH) { + throw FieldOutsideRangeException("namespace", MIN_NAMESPACE_LENGTH, MAX_NAMESPACE_LENGTH) + } + engine?.validate() + extension?.validate() +} + +@Serializable +data class TypewriterEngineConfiguration( + /** + * Version of the engine. + * It follows the [Semantic Versioning](https://semver.org/) format. + */ + var version: String = "", + /** + * Release channel of the engine. + * This is used to determine what repository to download the engine from. + */ + var channel: ReleaseChannel = ReleaseChannel.RELEASE, +) + +enum class ReleaseChannel(val url: String? = null) { + RELEASE("https://maven.typewritermc.com/releases"), + BETA("https://maven.typewritermc.com/beta"), + NONE +} + +private fun TypewriterEngineConfiguration.validate() { + if (version.isBlank()) { + throw MissingFieldException("engine.version") + } + if (!Regex("^([0-9])+\\.([0-9])+\\.([0-9])+\$").matches(version)) { + throw IllegalArgumentException("Version must follow the Semantic Versioning format.") + } +} + +@Serializable +data class TypewriterExtensionConfiguration( + /** + * The name of the extension. + */ + var name: String = "", + /** + * A short description of the extension. + */ + var shortDescription: String = "", + /** + * A longer description of the extension. + */ + var description: String = "", + var paper: PaperExtensionConfiguration? = null +) { + fun paper(block: PaperExtensionConfiguration.() -> Unit) { + paper = PaperExtensionConfiguration().apply(block) + } + + fun paper() { + paper = PaperExtensionConfiguration() + } +} + +private const val MIN_NAME_LENGTH = 5 +private const val MAX_NAME_LENGTH = 25 +private const val MIN_SHORT_DESCRIPTION_LENGTH = 10 +private const val MAX_SHORT_DESCRIPTION_LENGTH = 80 +private const val MIN_DESCRIPTION_LENGTH = 100 +private const val MAX_DESCRIPTION_LENGTH = 2000 + +internal fun TypewriterExtensionConfiguration.validate() { + if (name.isBlank()) { + throw MissingFieldException("extension.name") + } + if (name.length !in MIN_NAME_LENGTH..MAX_NAME_LENGTH) { + throw FieldOutsideRangeException("extension.name", MIN_NAME_LENGTH, MAX_NAME_LENGTH) + } + if (!Regex("^[a-zA-Z0-9]+$").matches(name)) { + throw IllegalArgumentException("Extension name '$name' must be alphanumeric.") + } + if (name.contains("Extension")) { + throw IllegalArgumentException("Extension name '$name' cannot contain 'Extension'") + } + + if (shortDescription.isBlank()) { + throw MissingFieldException("extension.shortDescription") + } + if (shortDescription.length !in MIN_SHORT_DESCRIPTION_LENGTH..MAX_SHORT_DESCRIPTION_LENGTH) { + throw FieldOutsideRangeException( + "extension.shortDescription", + MIN_SHORT_DESCRIPTION_LENGTH, + MAX_SHORT_DESCRIPTION_LENGTH + ) + } + + if (description.isBlank()) { + throw MissingFieldException("extension.description") + } + if (description.length !in MIN_DESCRIPTION_LENGTH..MAX_DESCRIPTION_LENGTH) { + throw FieldOutsideRangeException("extension.description", MIN_DESCRIPTION_LENGTH, MAX_DESCRIPTION_LENGTH) + } + + paper?.validate() +} + +@Serializable +data class PaperExtensionConfiguration( + val dependencies: MutableList = mutableListOf(), +) { + /** + * Adds a dependency to the paper extension. + * If the dependency is not found, the extension will not be loaded. + */ + fun dependency(dependency: String) { + dependencies.add(dependency) + } +} + +internal fun PaperExtensionConfiguration.validate() { + val invalidDependencies = dependencies.filter { + !Regex("^([a-zA-Z0-9])+\$").matches(it) + } + if (invalidDependencies.isNotEmpty()) { + throw IllegalArgumentException("Invalid dependency(s): ${invalidDependencies.joinToString(", ")}") + } +} + +class MissingFieldException(field: String) : Exception("Field '$field' is is not set, yet is required.") +class FieldOutsideRangeException(field: String, min: Int, max: Int) : + Exception("Field '$field' must be between $min and $max characters.") diff --git a/module-plugin/build.gradle.kts b/module-plugin/build.gradle.kts new file mode 100644 index 0000000000..0c8f34aca3 --- /dev/null +++ b/module-plugin/build.gradle.kts @@ -0,0 +1,115 @@ +plugins { + kotlin("jvm") version "2.0.20" + `java-gradle-plugin` + id("com.gradle.plugin-publish") version "1.2.1" + id("com.google.devtools.ksp") version "2.0.20-1.0.24" + kotlin("plugin.serialization") version "2.0.20" apply false + `maven-publish` +} + +group = "com.typewritermc.module-plugin" +version = "1.0.0" + +val engineVersion = file("../version.txt").readText().trim().substringBefore("-beta") + +subprojects { + group = rootProject.group + version = rootProject.version +} + +allprojects { + apply(plugin = "kotlin") + apply(plugin = "kotlinx-serialization") + apply(plugin = "maven-publish") + + repositories { + mavenCentral() + maven("https://plugins.gradle.org/m2/") + } + + dependencies { + implementation(kotlin("stdlib")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") + implementation("com.google.devtools.ksp:symbol-processing-gradle-plugin:2.0.20-1.0.24") + implementation("com.google.devtools.ksp:symbol-processing-api:2.0.20-1.0.24") + + implementation("com.typewritermc:engine-core:$engineVersion") + + + testImplementation(kotlin("test")) + val kotestVersion = "5.9.1" + testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion") + testImplementation("io.kotest:kotest-assertions-core:$kotestVersion") + testImplementation("io.kotest:kotest-property:$kotestVersion") + } + + tasks.test { + useJUnitPlatform() + } + kotlin { + jvmToolchain(21) + } + + publishing { + repositories { + maven { + name = "TypewriterReleases" + url = uri("https://maven.typewritermc.com/releases") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } + } + maven { + name = "TypewriterBeta" + url = uri("https://maven.typewritermc.com/beta") + credentials(PasswordCredentials::class) + authentication { + create("basic") + } + } + } + publications { + create("maven") { + group = project.group + version = project.version.toString() + artifactId = project.name + + from(components["kotlin"]) + } + } + } +} + + +dependencies { + implementation(gradleApi()) + api(project(":api")) + api(project(":extension-processor")) + + testImplementation(kotlin("test")) +} + + +gradlePlugin { + plugins { + create("typewriterModulePlugin") { + id = "com.typewritermc.module-plugin" + implementationClass = "com.typewritermc.TypewriterModulePlugin" + } + } +} + +tasks.register("generateResources") { + val propFile = layout.buildDirectory.file("generated/typewriter-module-plugin.properties").get().asFile + outputs.file(propFile) + + doLast { + propFile.parentFile.mkdirs() + propFile.writeText("version=$version") + } +} + +tasks.named("processResources") { + from(tasks["generateResources"]) +} diff --git a/module-plugin/extension-processor/build.gradle.kts b/module-plugin/extension-processor/build.gradle.kts new file mode 100644 index 0000000000..d3d71ff561 --- /dev/null +++ b/module-plugin/extension-processor/build.gradle.kts @@ -0,0 +1,18 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + id("com.google.devtools.ksp") version "2.0.20-1.0.24" +} + +repositories { + maven("https://repo.codemc.io/repository/maven-snapshots/") +} + +dependencies { + implementation("com.google.code.gson:gson:2.11.0") + implementation(project(":api")) +} + +tasks.withType(KotlinCompile::class.java) { + kotlinOptions.freeCompilerArgs += "-Xcontext-receivers" +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/SharedJsonManager.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/SharedJsonManager.kt new file mode 100644 index 0000000000..40dfae7f4a --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/SharedJsonManager.kt @@ -0,0 +1,25 @@ +package com.typewritermc + +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +class SharedJsonManager { + private var json: MutableMap = mutableMapOf() + + @Synchronized + fun updateSection(sectionName: String, content: JsonElement) { + json[sectionName] = content + } + + @Synchronized + fun updateSection(sectionName: String, content: String) { + json[sectionName] = JsonPrimitive(content) + } + + override fun toString(): String { + return Json.encodeToString(JsonObject.serializer(), JsonObject(json)) + } +} + diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/DialogueMessengerProcessor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/DialogueMessengerProcessor.kt new file mode 100644 index 0000000000..c07a00cb38 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/DialogueMessengerProcessor.kt @@ -0,0 +1,60 @@ +package com.typewritermc.processors + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.typewritermc.SharedJsonManager +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Messenger +import com.typewritermc.processors.entry.blueprintJson +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.encodeToJsonElement + +class DialogueMessengerProcessor( + private val json: SharedJsonManager, + private val logger: KSPLogger, +) : ExtensionPartProcessor { + override fun process(resolver: Resolver): List { + val symbols = resolver.getSymbolsWithAnnotation(Messenger::class.qualifiedName!!) + val messengers = symbols.filterIsInstance() + .map { generateMessengerBlueprint(it) } + .toList() + + logger.warn("Generated blueprints for ${messengers.size} messengers") + + json.updateSection("dialogueMessengers", JsonArray(messengers)) + return symbols.toList() + } + + @OptIn(KspExperimental::class) + private fun generateMessengerBlueprint(clazz: KSClassDeclaration): JsonElement { + logger.info("Generating messenger blueprint for ${clazz.simpleName.asString()}") + val annotation = clazz.getAnnotationsByType(Messenger::class).first() + val entry = annotation.annotationClassValue { dialogue } + val priority = annotation.priority + val entryAnnotation = entry.declaration.getAnnotationsByType(Entry::class).firstOrNull() + ?: throw EntryNotFoundException("Messenger", clazz.fullName, entry.fullName) + + val blueprint = MessengerBlueprint( + entryBlueprintId = entryAnnotation.name, + entryClassName = entry.fullName, + className = clazz.qualifiedName?.asString() ?: throw IllegalClassTypeException(clazz.simpleName.asString()), + priority = priority, + ) + + return blueprintJson.encodeToJsonElement(blueprint) + } +} + +@Serializable +data class MessengerBlueprint( + val entryBlueprintId: String, + val entryClassName: String, + val className: String, + val priority: Int, +) diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/EntryListenerProcessor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/EntryListenerProcessor.kt new file mode 100644 index 0000000000..ada367f688 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/EntryListenerProcessor.kt @@ -0,0 +1,73 @@ +package com.typewritermc.processors + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSFile +import com.google.devtools.ksp.symbol.KSFunctionDeclaration +import com.typewritermc.SharedJsonManager +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.loader.ListenerPriority +import com.typewritermc.processors.entry.blueprintJson +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.encodeToJsonElement + +class EntryListenerProcessor( + private val json: SharedJsonManager, + private val logger: KSPLogger, +) : ExtensionPartProcessor { + override fun process(resolver: Resolver): List { + val symbols = resolver.getSymbolsWithAnnotation(EntryListener::class.qualifiedName!!) + val listeners = symbols.filterIsInstance() + .map { generateListenerBlueprint(it) } + .toList() + + logger.warn("Generated blueprints for ${listeners.size} entry listeners") + + json.updateSection("entryListeners", JsonArray(listeners)) + return symbols.toList() + } + + @OptIn(KspExperimental::class) + private fun generateListenerBlueprint(function: KSFunctionDeclaration): JsonElement { + logger.info("Generating entry listener blueprint for ${function.fullName}") + + val parent = function.parent + if (parent !is KSFile) throw ListenerMustBeTopLevelFunctionException(function.fullName) + + val listener = function.getAnnotationsByType(EntryListener::class).first() + val entry = listener.annotationClassValue { entry } + val entryAnnotation = entry.declaration.getAnnotationsByType(Entry::class).firstOrNull() ?: throw EntryNotFoundException("Listener", function.fullName, entry.fullName) + + val blueprint = EntryListenerBlueprint( + entryBlueprintId = entryAnnotation.name, + entryClassName = entry.fullName, + className = parent.className, + methodName = function.simpleName.asString(), + priority = listener.priority, + ignoreCancelled = listener.ignoreCancelled, + arguments = function.parameters.map { it.type.resolve().fullName }, + ) + + return blueprintJson.encodeToJsonElement(blueprint) + } +} + +@Serializable +data class EntryListenerBlueprint( + val entryBlueprintId: String, + val entryClassName: String, + val className: String, + val methodName: String, + val priority: ListenerPriority, + val ignoreCancelled: Boolean, + val arguments: List, +) + +class ListenerMustBeTopLevelFunctionException(function: String) : + Exception("Function $function is not in a class. Entry listeners must be a top-level function") diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/ExtensionProcessor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/ExtensionProcessor.kt new file mode 100644 index 0000000000..60f36d612d --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/ExtensionProcessor.kt @@ -0,0 +1,100 @@ +package com.typewritermc.processors + +import com.google.devtools.ksp.containingFile +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSFile +import com.typewritermc.SharedJsonManager +import com.typewritermc.moduleplugin.TypewriterModuleConfiguration +import com.typewritermc.processors.entry.EntryProcessor +import kotlinx.serialization.json.* +import java.util.* + +class ExtensionProcessor( + private val sharedJsonManager: SharedJsonManager, + private val codeGenerator: CodeGenerator, + private val logger: KSPLogger, + private val pluginVersion: String, + private val version: String, + private val configuration: TypewriterModuleConfiguration, + private vararg val processors: ExtensionPartProcessor, +) : SymbolProcessor { + private var dependencies = Dependencies(false) + override fun process(resolver: Resolver): List { + val files = mutableSetOf() + for (processor in processors) { + val result = processor.process(resolver) + files.addAll(result.mapNotNull { it.containingFile }) + } + logger.warn("Inspected ${files.size} files") + dependencies = Dependencies(true, *files.toTypedArray()) + + val extension = configuration.extension!! + val extensionInfo = Json.encodeToJsonElement(extension).jsonObject + sharedJsonManager.updateSection( + "extension", JsonObject( + extensionInfo + mapOf( + "engineVersion" to JsonPrimitive(configuration.engine?.version ?: "0.0.0"), + "pluginVersion" to JsonPrimitive(pluginVersion), + "version" to JsonPrimitive(version), + ) + ) + ) + + return emptyList() + } + + override fun finish() { + super.finish() + + logger.info("Writing extension.json") + codeGenerator.createNewFile( + dependencies = dependencies, + packageName = "", + fileName = "extension", + extensionName = "json" + ).use { outputStream -> + outputStream.write(sharedJsonManager.toString().toByteArray()) + } + } +} + +object EmptyProcessor : SymbolProcessor { + override fun process(resolver: Resolver): List = emptyList() + override fun finish() {} +} + +interface ExtensionPartProcessor { + fun process(resolver: Resolver): List +} + +class ExtensionProcessorProvider : SymbolProcessorProvider { + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + val sharedJsonManager = SharedJsonManager() + val logger = environment.logger + + val pluginVersion = environment.options["pluginVersion"] ?: "0.0.0" + val version = environment.options["version"] ?: "0.0.0" + + val configuration = environment.options["configuration"]?.let { + Json.decodeFromString( + TypewriterModuleConfiguration.serializer(), String(Base64.getDecoder().decode(it)) + ) + } ?: throw IllegalArgumentException("No extension configuration found") + + val extension = configuration.extension ?: return EmptyProcessor + + return ExtensionProcessor( + sharedJsonManager = sharedJsonManager, + codeGenerator = environment.codeGenerator, + logger = logger, + pluginVersion = pluginVersion, + version = version, + configuration = configuration, + EntryProcessor(sharedJsonManager, logger, extension), + EntryListenerProcessor(sharedJsonManager, logger), + DialogueMessengerProcessor(sharedJsonManager, logger), + InitializerProcessor(sharedJsonManager, logger), + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/InitializerProcessor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/InitializerProcessor.kt new file mode 100644 index 0000000000..b1c2243503 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/InitializerProcessor.kt @@ -0,0 +1,45 @@ +package com.typewritermc.processors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.typewritermc.SharedJsonManager +import com.typewritermc.core.extension.annotations.Initializer +import com.typewritermc.processors.entry.blueprintJson +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.encodeToJsonElement + +class InitializerProcessor( + private val json: SharedJsonManager, + private val logger: KSPLogger, +) : ExtensionPartProcessor { + override fun process(resolver: Resolver): List { + val symbols = resolver.getSymbolsWithAnnotation(Initializer::class.qualifiedName!!) + val initializers = symbols.filterIsInstance() + .map { generateInitializerBlueprint(it) } + .toList() + + logger.warn("Generated blueprints for ${initializers.size} initializers") + + json.updateSection("initializers", JsonArray(initializers)) + return symbols.toList() + } + + private fun generateInitializerBlueprint(clazz: KSClassDeclaration): JsonElement { + logger.info("Generating initializer blueprint for ${clazz.simpleName.asString()}") + + val blueprint = InitializerBlueprint( + className = clazz.qualifiedName?.asString() ?: throw IllegalClassTypeException(clazz.simpleName.asString()) + ) + + return blueprintJson.encodeToJsonElement(blueprint) + } +} + +@Serializable +data class InitializerBlueprint( + val className: String, +) \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/KSPExtensions.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/KSPExtensions.kt new file mode 100644 index 0000000000..c757ea1956 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/KSPExtensions.kt @@ -0,0 +1,54 @@ +package com.typewritermc.processors + +import com.google.devtools.ksp.KSTypeNotPresentException +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.symbol.* +import com.google.gson.annotations.SerializedName +import kotlin.reflect.KClass + +@OptIn(KspExperimental::class) +val KSDeclaration.serializedName: String + get() { + return getAnnotationsByType(SerializedName::class).firstOrNull()?.value ?: simpleName.asString() + } + +val KSType.fullName: String + get() = declaration.fullName + +val KSDeclaration.fullName: String + get() = qualifiedName?.asString() ?: simpleName.asString() + +val Location.format: String + get() { + return when (this) { + is FileLocation -> "$filePath:$lineNumber" + is NonExistLocation -> "NonExist" + } + } + +@OptIn(KspExperimental::class) +val KSFile.className: String + get() { + val className = + getAnnotationsByType(JvmName::class).firstOrNull()?.name ?: "${fileName.substringBeforeLast(".")}Kt" + return "${packageName.asString()}.$className" + } + +@OptIn(KspExperimental::class) +inline fun KSAnnotated.annotationClassValue(f: T.() -> KClass<*>) = + getAnnotationsByType(T::class).first().annotationClassValue(f) + +@OptIn(KspExperimental::class) +inline fun T.annotationClassValue(f: T.() -> KClass<*>) = try { + f() + throw Exception("Expected to get a KSTypeNotPresentException") +} catch (e: KSTypeNotPresentException) { + e.ksType +} + +class EntryNotFoundException(what: String, who: String, entry: String) : + Exception("$what $who target entry $entry does not have the Entry annotation") + +class IllegalClassTypeException(className: String) : + Exception("Class $className does not have a qualified name. Classes must be full classes.") diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/CustomEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/CustomEditor.kt new file mode 100644 index 0000000000..716be90555 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/CustomEditor.kt @@ -0,0 +1,61 @@ +package com.typewritermc.processors.entry + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.editors.* +import kotlinx.serialization.json.JsonElement +import kotlin.reflect.KClass + +interface CustomEditor { + /// The name of the editor + val id: String + + fun accept(type: KSType): Boolean + + context(KSPLogger) + fun default(type: KSType): JsonElement + + context(KSPLogger) + fun shape(type: KSType): DataBlueprint + + context(KSPLogger) + fun validateDefault(type: KSType, default: JsonElement): Result { + return shape(type).validateDefault(default) + } + + fun modifiers(type: KSType): List { + return emptyList() + } +} + +infix fun KSType.whenClassNameIs(className: String): Boolean { + return this.declaration.qualifiedName?.asString() == className +} + +infix fun KSType.whenClassIs(kclass: KClass<*>): Boolean { + return this.declaration.qualifiedName?.asString() == kclass.qualifiedName +} + +context(KSPLogger) +fun DataModifierComputer.computeModifier(annotation: A, type: KSType): DataModifier { + return this.compute(DataBlueprint.blueprint(type)!!, annotation).getOrThrow() +} + +val customEditors = listOf( + ColorEditor, + CoordinateEditor, + CronEditor, + DurationEditor, + FloatRangeEditor, + ItemEditor, + MaterialEditor, + OptionalEditor, + PositionEditor, + PotionEffectTypeEditor, + RefEditor, + SkinEditor, + SoundIdEditor, + SoundSourceEditor, + VectorEditor, + WorldEditor +) \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataBlueprint.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataBlueprint.kt new file mode 100644 index 0000000000..7b7814e067 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataBlueprint.kt @@ -0,0 +1,336 @@ +package com.typewritermc.processors.entry + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.getDeclaredProperties +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.* +import com.typewritermc.core.extension.annotations.Default +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.format +import com.typewritermc.processors.fullName +import com.typewritermc.processors.serializedName +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerializationException +import kotlinx.serialization.Transient +import kotlinx.serialization.json.* + +val blueprintJson = Json { + classDiscriminator = "kind" + explicitNulls = false +} + +@Serializable +sealed class DataBlueprint { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): DataBlueprint? { + CustomBlueprint.blueprint(type)?.let { return it } + PrimitiveBlueprint.blueprint(type)?.let { return it } + EnumBlueprint.blueprint(type)?.let { return it } + ListBlueprint.blueprint(type)?.let { return it } + MapBlueprint.blueprint(type)?.let { return it } + + ObjectBlueprint.blueprint(type)?.let { return it } + return null + } + } + + val modifiers: MutableList = mutableListOf() + protected var default: JsonElement = JsonNull + abstract fun validateDefault(default: JsonElement): Result + + abstract fun default(): JsonElement + + @Serializable + @SerialName("primitive") + data class PrimitiveBlueprint(val type: PrimitiveType) : DataBlueprint() { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): DataBlueprint? { + return when (type.declaration.qualifiedName?.asString()) { + "kotlin.Boolean" -> PrimitiveBlueprint(PrimitiveType.BOOLEAN) + "java.lang.Boolean" -> PrimitiveBlueprint(PrimitiveType.BOOLEAN) + "kotlin.Double" -> PrimitiveBlueprint(PrimitiveType.DOUBLE) + "java.lang.Double" -> PrimitiveBlueprint(PrimitiveType.DOUBLE) + "kotlin.Float" -> PrimitiveBlueprint(PrimitiveType.DOUBLE) + "java.lang.Float" -> PrimitiveBlueprint(PrimitiveType.DOUBLE) + "kotlin.Int" -> PrimitiveBlueprint(PrimitiveType.INTEGER) + "java.lang.Integer" -> PrimitiveBlueprint(PrimitiveType.INTEGER) + "kotlin.Long" -> PrimitiveBlueprint(PrimitiveType.INTEGER) + "java.lang.Long" -> PrimitiveBlueprint(PrimitiveType.INTEGER) + "kotlin.String" -> PrimitiveBlueprint(PrimitiveType.STRING) + "java.lang.String" -> PrimitiveBlueprint(PrimitiveType.STRING) + else -> null + } + } + } + + override fun validateDefault(default: JsonElement): Result { + if (default !is JsonPrimitive) return failure("Default value for %s needs to be a ${type.name.lowercase()} but is a ${default::class.simpleName}") + if (type == PrimitiveType.BOOLEAN && default.booleanOrNull == null) return failure("Default value for %s is not a boolean") + if (type == PrimitiveType.DOUBLE && default.doubleOrNull == null) return failure("Default value for %s is not a double") + if (type == PrimitiveType.INTEGER && default.intOrNull == null) return failure("Default value for %s is not an integer") + if (type == PrimitiveType.STRING && !default.isString) return failure("Default value for %s is not a string") + return ok(Unit) + } + + override fun default(): JsonElement { + if (default != JsonNull) return default + return type.default + } + } + + @Serializable + @SerialName("enum") + data class EnumBlueprint(val values: List) : DataBlueprint() { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): DataBlueprint? { + // Check if it is an enum. And if so get the values. + val clazz = type.declaration as? KSClassDeclaration ?: return null + if (clazz.classKind != ClassKind.ENUM_CLASS) return null + + val values = clazz.declarations + .filterIsInstance() + .map { it.serializedName } + .toList() + + return EnumBlueprint(values) + } + } + + override fun validateDefault(default: JsonElement): Result { + if (default !is JsonPrimitive) return failure("Default value for %s needs to be a string but is a ${default::class.simpleName}") + if (!values.contains(default.content)) return failure( + "Default value for %s is not one of the enum values, possible values are ${ + values.joinToString( + ", " + ) + }" + ) + return ok(Unit) + } + + override fun default(): JsonElement { + if (default != JsonNull) return default + return JsonPrimitive(values.first()) + } + } + + @Serializable + @SerialName("list") + data class ListBlueprint(val type: DataBlueprint) : DataBlueprint() { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): ListBlueprint? { + when (type.declaration.qualifiedName?.asString()) { + "kotlin.collections.List" -> {} + "java.util.List" -> {} + else -> return null + } + if (type.arguments.size != 1) return null + val subType = type.arguments.firstOrNull()?.type?.resolve() ?: return null + return ListBlueprint(DataBlueprint.blueprint(subType) ?: return null) + } + } + + override fun validateDefault(default: JsonElement): Result { + if (default !is JsonArray) return failure("Default value for %s needs to be a list but is a ${default::class.simpleName}") + default.forEach { + val result = type.validateDefault(it) + if (result.isFailure) return failure("Sub element of %s is not valid, error: ${result.exceptionOrNull()}") + } + return ok(Unit) + } + + override fun default(): JsonElement { + if (default != JsonNull) return default + return JsonArray(emptyList()) + } + } + + @Serializable + @SerialName("map") + data class MapBlueprint(val key: DataBlueprint, val value: DataBlueprint) : DataBlueprint() { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): MapBlueprint? { + when (type.declaration.qualifiedName?.asString()) { + "kotlin.collections.Map" -> {} + "java.util.Map" -> {} + else -> return null + } + if (type.arguments.size != 2) return null + val key = type.arguments.firstOrNull()?.type?.resolve() ?: return null + val keyBlueprint = DataBlueprint.blueprint(key) ?: return null + + // Since not all key types are supported, we check if the key type is a supported type. + // TODO: Remove in favor if linter + when { + keyBlueprint is PrimitiveBlueprint && keyBlueprint.type == PrimitiveType.STRING -> {} + keyBlueprint is EnumBlueprint -> {} + keyBlueprint is CustomBlueprint && keyBlueprint.editor == "ref" -> {} + else -> throw InvalidKeyTypeException(type, keyBlueprint, "Strings, enums, and entry references are supported") + } + + val value = type.arguments.lastOrNull()?.type?.resolve() ?: return null + val valueBlueprint = DataBlueprint.blueprint(value) ?: return null + return MapBlueprint( + keyBlueprint, + valueBlueprint + ) + } + } + + override fun validateDefault(default: JsonElement): Result { + if (default !is JsonObject) return failure("Default value for %s needs to be a map but is a ${default::class.simpleName}") + default.forEach { (k, v) -> + val resultKey = key.validateDefault(JsonPrimitive(k)) + if (resultKey.isFailure) return failure("Key of %s is not valid, error: ${resultKey.exceptionOrNull()}") + val resultValue = value.validateDefault(v) + if (resultValue.isFailure) return failure("Value of %s is not valid, error: ${resultValue.exceptionOrNull()}") + } + return ok(Unit) + } + + override fun default(): JsonElement { + if (default != JsonNull) return default + return JsonObject(emptyMap()) + } + } + + @Serializable + @SerialName("object") + data class ObjectBlueprint(val fields: Map) : DataBlueprint() { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): ObjectBlueprint? { + val clazz = type.declaration as? KSClassDeclaration ?: return null + if (clazz.classKind != ClassKind.CLASS) return null + val order = clazz.primaryConstructor?.parameters?.mapNotNull { it.name?.asString() } ?: emptyList() + val fields = clazz.getDeclaredProperties() + .filter { it.hasBackingField } + .sortedBy { + val index = order.indexOf(it.serializedName) + if (index == -1) Int.MAX_VALUE else index + } + .associateBy { it.serializedName } + .mapValues { (_, property) -> + val parameterType = property.type.resolve() + val blueprint = DataBlueprint.blueprint(parameterType) ?: throw CouldNotFindBlueprintException( + property.fullName, + parameterType, + property.location + ) + + applyModifiers(blueprint, property) + + val default = property.defaultValue() + if (default != null) { + val result = blueprint.validateDefault(default) + if (result.isFailure) { + val annotation = property.annotations.first { it.shortName.asString() == "Default" } + throw InvalidDefaultValueException("${result.exceptionOrNull()?.message?.format(property.simpleName.asString())} at ${annotation.location.format}") + } + blueprint.default = default + } + + + blueprint + } + + return ObjectBlueprint(fields) + } + } + + override fun validateDefault(default: JsonElement): Result { + if (default !is JsonObject) return failure("Default value for %s needs to be an object but is a ${default::class.simpleName}") + fields.forEach { (k, v) -> + val result = v.validateDefault(default.getOrDefault(k, JsonNull)) + if (result.isFailure) return failure("Field $k of %s is not valid, error: ${result.exceptionOrNull()}") + } + return ok(Unit) + } + + override fun default(): JsonElement { + if (default != JsonNull) return default + return JsonObject(emptyMap()) + } + } + + @Serializable + @SerialName("custom") + data class CustomBlueprint( + val editor: String, + val shape: DataBlueprint, + @Transient + val validator: (JsonElement) -> Result = { ok(Unit) } + ) : DataBlueprint() { + companion object { + context(KSPLogger) + fun blueprint(type: KSType): CustomBlueprint? { + val editor = customEditors.firstOrNull { it.accept(type) } ?: return null + return CustomBlueprint(editor.id, editor.shape(type)) { + editor.validateDefault(type, it) + }.also { blueprint -> + blueprint.default = editor.default(type) + editor.modifiers(type).forEach { it.appendModifier(blueprint) } + } + } + } + + override fun validateDefault(default: JsonElement): Result = validator(default) + + override fun default(): JsonElement = default + } +} + + +context(KSPLogger) +@OptIn(KspExperimental::class) +private fun KSPropertyDeclaration.defaultValue(): JsonElement? { + val default = getAnnotationsByType(Default::class).firstOrNull() ?: return null + try { + return Json.parseToJsonElement(default.json) + } catch (e: SerializationException) { + error("The default value for ${this.fullName} is not a valid JSON value, JSON: `$default`", this) + throw e + } +} + +enum class PrimitiveType { + @SerialName("boolean") + BOOLEAN, + + @SerialName("double") + DOUBLE, + + @SerialName("integer") + INTEGER, + + @SerialName("string") + STRING, + ; + + val default: JsonPrimitive + get() = when (this) { + BOOLEAN -> JsonPrimitive(false) + DOUBLE -> JsonPrimitive(0.0) + INTEGER -> JsonPrimitive(0) + STRING -> JsonPrimitive("") + } +} + +class CouldNotFindBlueprintException(val property: String, val parameter: KSType, val location: Location) : + Exception("Could not find blueprint for $property with type ${parameter.fullName} at ${location.format}") + +class CouldNotFindArgumentTypeException(parameter: String, argument: KSTypeArgument) : + Exception("Could not find argument type for type $parameter $argument at ${argument.location.format}, Generics are not yet supported") + +class InvalidDefaultValueException(message: String) : Exception(message) + +class InvalidKeyTypeException(type: KSType, blueprint: DataBlueprint, supported: String) : + Exception("Invalid key type for map ${type.fullName}, supported types are $supported, but found $blueprint") \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifier.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifier.kt new file mode 100644 index 0000000000..fe3f8c0a85 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifier.kt @@ -0,0 +1,62 @@ +package com.typewritermc.processors.entry + +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonPrimitive + +sealed interface DataModifier { + fun appendModifier(blueprint: DataBlueprint) + + @Serializable + data class Modifier(val name: String, val data: JsonElement) : DataModifier { + constructor(name: String) : this(name, JsonNull) + constructor(name: String, data: String) : this(name, JsonPrimitive(data)) + constructor(name: String, data: Int) : this(name, JsonPrimitive(data)) + + override fun appendModifier(blueprint: DataBlueprint) { + blueprint.modifiers.add(this) + } + } + + data class InnerModifier(val modifier: DataModifier) : DataModifier { + override fun appendModifier(blueprint: DataBlueprint) { + when (blueprint) { + is DataBlueprint.ListBlueprint -> { + modifier.appendModifier(blueprint.type) + } + + is DataBlueprint.MapBlueprint -> { + modifier.appendModifier(blueprint.key) + modifier.appendModifier(blueprint.value) + } + + is DataBlueprint.CustomBlueprint -> { + modifier.appendModifier(blueprint.shape) + } + + else -> throw CouldNotAppendModifierException(blueprint, this) + } + } + } + + data class InnerMapModifier(private val key: DataModifier?, private val value: DataModifier?) : DataModifier { + override fun appendModifier(blueprint: DataBlueprint) { + if (blueprint !is DataBlueprint.MapBlueprint) throw CouldNotAppendModifierException(blueprint, this) + key?.appendModifier(blueprint.key) + value?.appendModifier(blueprint.value) + } + } + + data class InnerObjectModifier(private val fields: Map) : DataModifier { + override fun appendModifier(blueprint: DataBlueprint) { + if (blueprint !is DataBlueprint.ObjectBlueprint) throw CouldNotAppendModifierException(blueprint, this) + fields.forEach { (key, modifier) -> + modifier.appendModifier(blueprint.fields[key] ?: throw CouldNotAppendModifierException(blueprint, this)) + } + } + } +} + +class CouldNotAppendModifierException(blueprint: DataBlueprint, modifier: DataModifier) : + Exception("Could not append modifier $modifier to blueprint $blueprint") \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifierComputer.kt new file mode 100644 index 0000000000..a9a6ba5a37 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/DataModifierComputer.kt @@ -0,0 +1,97 @@ +package com.typewritermc.processors.entry + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.symbol.KSPropertyDeclaration +import com.typewritermc.processors.entry.modifiers.* +import kotlin.reflect.KClass +import kotlin.reflect.cast + +interface DataModifierComputer { + val annotationClass: KClass + + @OptIn(KspExperimental::class) + fun applyModifier(blueprint: DataBlueprint, property: KSPropertyDeclaration) { + val annotation = property.getAnnotationsByType(annotationClass).firstOrNull() ?: return + val modifier = compute(blueprint, annotationClass.cast(annotation)).getOrNull() ?: return + modifier.appendModifier(blueprint) + } + + fun compute(blueprint: DataBlueprint, annotation: A): Result + + fun innerListCompute(blueprint: DataBlueprint, annotation: A): DataModifier? { + if (blueprint !is DataBlueprint.ListBlueprint) return null + val modifier = compute(blueprint.type, annotation).getOrNull() ?: return null + return DataModifier.InnerModifier(modifier) + } + + fun innerMapCompute(blueprint: DataBlueprint, annotation: A): DataModifier? { + if (blueprint !is DataBlueprint.MapBlueprint) return null + val keyModifier = compute(blueprint.key, annotation).onFailure { return null }.getOrNull() + val valueModifier = compute(blueprint.value, annotation).onFailure { return null }.getOrNull() + + if (keyModifier == null && valueModifier == null) return null + return DataModifier.InnerMapModifier(keyModifier, valueModifier) + } + + fun innerObjectCompute(blueprint: DataBlueprint, annotation: A): DataModifier? { + if (blueprint !is DataBlueprint.ObjectBlueprint) return null + val modifiers = blueprint.fields.mapNotNull { + val modifier = compute(it.value, annotation).getOrNull() ?: return@mapNotNull null + it.key to modifier + }.toMap() + return DataModifier.InnerObjectModifier(modifiers) + } + + fun innerCustomCompute(blueprint: DataBlueprint, annotation: A): DataModifier? { + if (blueprint !is DataBlueprint.CustomBlueprint) return null + val modifier = superInnerCompute(blueprint.shape, annotation) ?: return null + return DataModifier.InnerModifier(modifier) + } + + fun innerCompute(blueprint: DataBlueprint, annotation: A): DataModifier? { + return when (blueprint) { + is DataBlueprint.ListBlueprint -> innerListCompute(blueprint, annotation) + is DataBlueprint.MapBlueprint -> innerMapCompute(blueprint, annotation) + is DataBlueprint.CustomBlueprint -> innerCustomCompute(blueprint, annotation) + else -> null + } + } + + fun superInnerCompute(blueprint: DataBlueprint, annotation: A): DataModifier? { + return innerCompute(blueprint, annotation) ?: innerObjectCompute(blueprint, annotation) + } +} + +private val computers: List> = listOf( + ColoredModifierComputer, + ContentEditorModifierComputer, + GeneratedModifierComputer, + HelpModifierComputer, + IconModifierComputer, + MaterialPropertiesModifierComputer, + MultiLineModifierComputer, + NegativeModifierComputer, + OnlyTagsModifierComputer, + PageModifierComputer, + PlaceholderModifierComputer, + RegexModifierComputer, + SegmentModifierComputer, + SnakeCaseModifierComputer, + WithRotationModifierComputer, + MinModifierComputer, + MaxModifierComputer, + InnerMinModifierComputer, + InnerMaxModifierComputer, +) + +fun applyModifiers(blueprint: DataBlueprint, property: KSPropertyDeclaration) { + for (computer in computers) { + computer.applyModifier(blueprint, property) + } + + property.findOverridee()?.let { + applyModifiers(blueprint, it) + } +} + diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/EntryProcessor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/EntryProcessor.kt new file mode 100644 index 0000000000..41defeda28 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/EntryProcessor.kt @@ -0,0 +1,117 @@ +package com.typewritermc.processors.entry + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAllSuperTypes +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.typewritermc.SharedJsonManager +import com.typewritermc.moduleplugin.TypewriterExtensionConfiguration +import com.typewritermc.core.extension.annotations.Entry +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.processors.ExtensionPartProcessor +import com.typewritermc.processors.fullName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.encodeToJsonElement + +class EntryProcessor( + private val json: SharedJsonManager, + private val logger: KSPLogger, + private val configuration: TypewriterExtensionConfiguration, +) : ExtensionPartProcessor { + override fun process(resolver: Resolver): List { + val symbols = resolver.getSymbolsWithAnnotation(Entry::class.qualifiedName!!) + val entries = symbols.filterIsInstance() + .map { generateEntryBlueprint(it) } + .toList() + + logger.warn("Generated blueprints for ${entries.size} entries") + + json.updateSection("entries", JsonArray(entries)) + + return symbols.toList() + } + + @OptIn(KspExperimental::class) + private fun generateEntryBlueprint(clazz: KSClassDeclaration): JsonElement { + logger.info("Generating entry blueprint for ${clazz.simpleName.asString()}") + val annotation = clazz.getAnnotationsByType(Entry::class).first() + + val blueprint = EntryBlueprint( + id = annotation.name, + name = annotation.name, + description = annotation.description, + color = annotation.color, + icon = annotation.icon, + tags = clazz.tags, + dataBlueprint = clazz.fieldBlueprints(), + className = clazz.qualifiedName?.asString() ?: throw IllegalClassTypeException(clazz.simpleName.asString()), + extension = configuration.name, + ) + + return blueprintJson.encodeToJsonElement(blueprint) + } + + @OptIn(KspExperimental::class) + private val KSClassDeclaration.tags: List + get() { + val clazzTags = getAnnotationsByType(Tags::class).firstOrNull()?.tags?.toList() ?: emptyList() + val superTags: List = + getAllSuperTypes().map { it.declaration }.filterIsInstance().flatMap { + it.getAnnotationsByType(Tags::class).firstOrNull()?.tags?.toList() ?: emptyList() + }.toList() + + return clazzTags + superTags + } + + private fun KSClassDeclaration.fieldBlueprints(): DataBlueprint { + with(logger) { + try { + return DataBlueprint.blueprint(this@fieldBlueprints.asStarProjectedType()) + ?: throw CouldNotBuildBlueprintException(fullName) + } catch (e: Exception) { + throw FailedToGenerateBlueprintException(this@fieldBlueprints, e) + } + } + } +} + +@Serializable +private data class EntryBlueprint( + val id: String, + val name: String, + val description: String, + val color: String, + val icon: String, + val tags: List, + val dataBlueprint: DataBlueprint, + val className: String, + val extension: String, +) + +class IllegalClassTypeException(className: String) : + Exception("Class $className does not have a qualified name. Entry classes must be full classes.") + +class CouldNotBuildBlueprintException(className: String) : + Exception("Could not build blueprint for class $className") + +class FailedToGenerateBlueprintException( + klass: KSClassDeclaration, + cause: Exception, +) : Exception( + """Failed Generating Blueprint for ${klass.fullName} + | + |Failed to generate blueprint for ${klass.fullName}: + |${cause.message} + | + |Not all types are possible to be serialized to JSON. + |Most platform specific types are not supported. Some examples are: + | - org.bukkit.Location + | + |If you think this is a mistake, or don't know how to fix it, please open an issue on the Typewriter Discord. +|""".trimMargin() +) \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ColorEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ColorEditor.kt new file mode 100644 index 0000000000..5ac2676d11 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ColorEditor.kt @@ -0,0 +1,20 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive + +object ColorEditor : CustomEditor { + override val id: String = "color" + + override fun accept(type: KSType): Boolean = type whenClassNameIs "com.typewritermc.engine.paper.utils.Color" + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonPrimitive(0xFFFFFFFF) + context(KSPLogger) override fun shape(type: KSType): DataBlueprint = PrimitiveBlueprint(PrimitiveType.INTEGER) +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CoordinateEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CoordinateEditor.kt new file mode 100644 index 0000000000..47af491387 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CoordinateEditor.kt @@ -0,0 +1,46 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.core.utils.point.Coordinate +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object CoordinateEditor : CustomEditor { + override val id: String = "coordinate" + + override fun accept(type: KSType): Boolean { + return type whenClassIs com.typewritermc.core.utils.point.Coordinate::class + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "x" to JsonPrimitive(0.0), + "y" to JsonPrimitive(0.0), + "z" to JsonPrimitive(0.0), + "yaw" to JsonPrimitive(0.0), + "pitch" to JsonPrimitive(0.0), + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "x" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "y" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "z" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "yaw" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "pitch" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CronEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CronEditor.kt new file mode 100644 index 0000000000..d766039a1e --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/CronEditor.kt @@ -0,0 +1,21 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive + +object CronEditor : CustomEditor { + override val id: String = "cron" + override fun accept(type: KSType): Boolean { + return type whenClassNameIs "com.typewritermc.engine.paper.utils.CronExpression" + } + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonPrimitive("0 0 0 1 1 *") + context(KSPLogger) override fun shape(type: KSType): DataBlueprint = PrimitiveBlueprint(PrimitiveType.STRING) +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/DurationEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/DurationEditor.kt new file mode 100644 index 0000000000..d5f8c02da9 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/DurationEditor.kt @@ -0,0 +1,35 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonPrimitive +import kotlinx.serialization.json.long +import java.time.Duration + +object DurationEditor : CustomEditor { + override val id: String = "duration" + + override fun accept(type: KSType): Boolean { + return type whenClassIs Duration::class + } + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonPrimitive(1000) + context(KSPLogger) override fun shape(type: KSType): DataBlueprint = PrimitiveBlueprint(PrimitiveType.INTEGER) + + context(KSPLogger) override fun validateDefault(type: KSType, default: JsonElement): Result { + val result = super.validateDefault(type, default) + if (result.isFailure) return result + val duration = Duration.ofMillis(default.jsonPrimitive.long) + if (duration.isNegative) return failure("The duration default value for %s must be positive") + return ok(Unit) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/FloatRangeEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/FloatRangeEditor.kt new file mode 100644 index 0000000000..8c8cde36db --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/FloatRangeEditor.kt @@ -0,0 +1,47 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object FloatRangeEditor : CustomEditor { + override val id: String = "floatRange" + + override fun accept(type: KSType): Boolean { + if (!type.whenClassIs(ClosedFloatingPointRange::class)) return false + + val typeArguments = type.arguments + if (typeArguments.size != 1) return false + + val typeArgument = typeArguments.first() + return typeArgument.type?.resolve()?.whenClassIs(Float::class) ?: false + } + + context(KSPLogger) + override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "start" to JsonPrimitive(0), + "end" to JsonPrimitive(0), + ) + ) + } + + context(KSPLogger) + override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "start" to PrimitiveBlueprint(PrimitiveType.INTEGER), + "end" to PrimitiveBlueprint(PrimitiveType.INTEGER) + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ItemEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ItemEditor.kt new file mode 100644 index 0000000000..027d83358c --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/ItemEditor.kt @@ -0,0 +1,57 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.* +import com.typewritermc.processors.fullName +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject + +object ItemEditor : CustomEditor { + override val id: String = "item" + + override fun accept(type: KSType): Boolean { + return type whenClassNameIs "com.typewritermc.engine.paper.utils.Item" + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + val klass = type.declaration as? KSClassDeclaration + ?: throw IllegalStateException("Expected Item to be a class, did you goof up gabber?") + + val properties = klass.getAllProperties() + .filter { it.hasBackingField } + .associate { prop -> + val name = prop.simpleName.asString() + val propertyType = prop.type.resolve() + val blueprint = + DataBlueprint.blueprint(propertyType) ?: throw CouldNotFindBlueprintException( + prop.fullName, + propertyType, + prop.location + ) + val default = blueprint.default() + name to default + + } + return JsonObject(properties) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return DataBlueprint.ObjectBlueprint.blueprint(type) ?: throw CouldNotFindBlueprintException( + type.fullName, + type, + type.declaration.location + ) + } + + override fun modifiers(type: KSType): List { + // TODO: Use the actual ContentEditorModifierComputer + return listOf( + DataModifier.Modifier( + "contentMode", + "com.typewritermc.engine.paper.content.modes.custom.HoldingItemContentMode" + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/MaterialEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/MaterialEditor.kt new file mode 100644 index 0000000000..e9064366f2 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/MaterialEditor.kt @@ -0,0 +1,21 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive + +object MaterialEditor : CustomEditor { + override val id: String = "material" + override fun accept(type: KSType): Boolean { + return type whenClassNameIs "org.bukkit.Material" + } + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonPrimitive("AIR") + context(KSPLogger) override fun shape(type: KSType): DataBlueprint = PrimitiveBlueprint(PrimitiveType.STRING) +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/OptionalEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/OptionalEditor.kt new file mode 100644 index 0000000000..28608e26fb --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/OptionalEditor.kt @@ -0,0 +1,46 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.* +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.fullName +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import java.util.* + +object OptionalEditor : CustomEditor { + override val id: String = "optional" + + override fun accept(type: KSType): Boolean { + return type whenClassIs Optional::class + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + val argumentType = type.arguments.firstOrNull()?.type?.resolve() + ?: throw IllegalStateException("Expected Optional to have a single argument") + val blueprint = DataBlueprint.blueprint(argumentType) + ?: throw IllegalStateException("Could not find blueprint for type ${argumentType.fullName}") + return JsonObject( + mapOf( + "enabled" to JsonPrimitive(false), + "value" to blueprint.default() + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + val argumentType = type.arguments.firstOrNull()?.type?.resolve() + ?: throw IllegalStateException("Expected Optional to have a single argument") + val blueprint = DataBlueprint.blueprint(argumentType) + ?: throw IllegalStateException("Could not find blueprint for type ${argumentType.fullName}") + return ObjectBlueprint( + mapOf( + "enabled" to PrimitiveBlueprint(PrimitiveType.BOOLEAN), + "value" to blueprint + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PositionEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PositionEditor.kt new file mode 100644 index 0000000000..2686003a01 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PositionEditor.kt @@ -0,0 +1,57 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.core.extension.annotations.ContentEditor +import com.typewritermc.core.utils.point.Position +import com.typewritermc.processors.entry.* +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.modifiers.ContentEditorModifierComputer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object PositionEditor : CustomEditor { + override val id: String = "position" + + override fun accept(type: KSType): Boolean { + return type whenClassIs Position::class + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "world" to JsonPrimitive(""), + "x" to JsonPrimitive(0.0), + "y" to JsonPrimitive(0.0), + "z" to JsonPrimitive(0.0), + "yaw" to JsonPrimitive(0.0), + "pitch" to JsonPrimitive(0.0), + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "world" to PrimitiveBlueprint(PrimitiveType.STRING), + "x" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "y" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "z" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "yaw" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "pitch" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + ) + ) + } + + override fun modifiers(type: KSType): List { + // TODO: Use the actual ContentEditorModifierComputer + return listOf( + DataModifier.Modifier( + "contentMode", + "com.typewritermc.engine.paper.content.modes.custom.PositionContentMode" + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PotionEffectTypeEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PotionEffectTypeEditor.kt new file mode 100644 index 0000000000..a6059b6265 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/PotionEffectTypeEditor.kt @@ -0,0 +1,22 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive + +object PotionEffectTypeEditor : CustomEditor { + override val id: String = "potionEffectType" + + override fun accept(type: KSType): Boolean { + return type.whenClassNameIs("org.bukkit.potion.PotionEffectType") + } + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonPrimitive("speed") + context(KSPLogger) override fun shape(type: KSType): DataBlueprint = PrimitiveBlueprint(PrimitiveType.STRING) +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/RefEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/RefEditor.kt new file mode 100644 index 0000000000..6a58062dc1 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/RefEditor.kt @@ -0,0 +1,53 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.Tags +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.* +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.fullName +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonNull + +object RefEditor : CustomEditor { + override val id: String = "ref" + + override fun accept(type: KSType): Boolean = type whenClassIs Ref::class + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonNull + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return PrimitiveBlueprint(PrimitiveType.STRING) + } + + context(KSPLogger) + override fun validateDefault(type: KSType, default: JsonElement): Result { + if (default is JsonNull) return ok(Unit) + return super.validateDefault(type, default) + } + + @OptIn(KspExperimental::class) + override fun modifiers(type: KSType): List { + val argument = type.arguments.firstOrNull()?.type?.resolve() + ?: throw IllegalArgumentException("Ref requires a single type argument") + val tags = + argument.declaration.getAnnotationsByType(Tags::class).firstOrNull()?.tags ?: throw NoTagsFoundException( + argument, + type + ) + if (tags.isEmpty()) throw NoTagsFoundException(argument, type) + val tag = tags.first() + + return listOf(DataModifier.Modifier("entry", tag)) + } +} + +class NoTagsFoundException(klass: KSType, origin: KSType) : Exception( + """|No tags found for ${klass.declaration.simpleName.asString()} + |${origin.fullName} tried to reference ${klass.fullName} but it does not have the @Tags annotation. + |To be able to reference ${klass.fullName}, it needs to have the @Tags annotation with at least one tag. +""".trimMargin() +) \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SkinEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SkinEditor.kt new file mode 100644 index 0000000000..1a712b6c79 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SkinEditor.kt @@ -0,0 +1,39 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object SkinEditor : CustomEditor { + override val id: String = "skin" + + override fun accept(type: KSType): Boolean { + return type whenClassNameIs "com.typewritermc.engine.paper.entry.entity.SkinProperty" + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "texture" to JsonPrimitive(""), + "signature" to JsonPrimitive(""), + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "texture" to PrimitiveBlueprint(PrimitiveType.STRING), + "signature" to PrimitiveBlueprint(PrimitiveType.STRING), + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundIdEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundIdEditor.kt new file mode 100644 index 0000000000..6b16ca74f4 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundIdEditor.kt @@ -0,0 +1,39 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object SoundIdEditor : CustomEditor { + override val id: String = "soundId" + + override fun accept(type: KSType): Boolean { + return type whenClassNameIs "com.typewritermc.engine.paper.utils.SoundId" + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "type" to JsonPrimitive("default"), + "value" to JsonPrimitive(""), + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "type" to PrimitiveBlueprint(PrimitiveType.STRING), + "value" to PrimitiveBlueprint(PrimitiveType.STRING), + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundSourceEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundSourceEditor.kt new file mode 100644 index 0000000000..de4ea93bb6 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/SoundSourceEditor.kt @@ -0,0 +1,59 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassNameIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object SoundSourceEditor : CustomEditor { + override val id: String = "soundSource" + + override fun accept(type: KSType): Boolean { + return type.whenClassNameIs("com.typewritermc.engine.paper.utils.SoundSource") + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "type" to JsonPrimitive("self"), + "entryId" to JsonPrimitive(""), + "location" to JsonObject( + mapOf( + "world" to JsonPrimitive(""), + "x" to JsonPrimitive(0.0), + "y" to JsonPrimitive(0.0), + "z" to JsonPrimitive(0.0), + "yaw" to JsonPrimitive(0.0), + "pitch" to JsonPrimitive(0.0), + ) + ) + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "type" to PrimitiveBlueprint(PrimitiveType.STRING), + "entryId" to PrimitiveBlueprint(PrimitiveType.STRING), + "location" to ObjectBlueprint( + mapOf( + "world" to PrimitiveBlueprint(PrimitiveType.STRING), + "x" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "y" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "z" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "yaw" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "pitch" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + ) + ) + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/VectorEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/VectorEditor.kt new file mode 100644 index 0000000000..607231dfd4 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/VectorEditor.kt @@ -0,0 +1,42 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.core.utils.point.Vector +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.ObjectBlueprint +import com.typewritermc.processors.entry.DataBlueprint.PrimitiveBlueprint +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive + +object VectorEditor : CustomEditor { + override val id: String = "vector" + + override fun accept(type: KSType): Boolean { + return type whenClassIs Vector::class + } + + context(KSPLogger) override fun default(type: KSType): JsonElement { + return JsonObject( + mapOf( + "x" to JsonPrimitive(0.0), + "y" to JsonPrimitive(0.0), + "z" to JsonPrimitive(0.0), + ) + ) + } + + context(KSPLogger) override fun shape(type: KSType): DataBlueprint { + return ObjectBlueprint( + mapOf( + "x" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "y" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + "z" to PrimitiveBlueprint(PrimitiveType.DOUBLE), + ) + ) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/WorldEditor.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/WorldEditor.kt new file mode 100644 index 0000000000..190076227f --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/editors/WorldEditor.kt @@ -0,0 +1,23 @@ +package com.typewritermc.processors.entry.editors + +import com.google.devtools.ksp.processing.KSPLogger +import com.google.devtools.ksp.symbol.KSType +import com.typewritermc.core.utils.point.World +import com.typewritermc.processors.entry.CustomEditor +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataBlueprint.* +import com.typewritermc.processors.entry.PrimitiveType +import com.typewritermc.processors.entry.whenClassIs +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive + +object WorldEditor : CustomEditor { + override val id: String = "world" + + override fun accept(type: KSType): Boolean { + return type whenClassIs World::class + } + + context(KSPLogger) override fun default(type: KSType): JsonElement = JsonPrimitive("") + context(KSPLogger) override fun shape(type: KSType): DataBlueprint = PrimitiveBlueprint(PrimitiveType.STRING) +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ColoredModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ColoredModifierComputer.kt new file mode 100644 index 0000000000..efb2ff89b4 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ColoredModifierComputer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Colored +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object ColoredModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Colored::class + + override fun compute(blueprint: DataBlueprint, annotation: Colored): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("Colored annotation can only be used on strings (including in lists or maps)!") + } + + if (blueprint.type != PrimitiveType.STRING) { + return failure("Colored annotation can only be used on strings (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("colored")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ContentEditorModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ContentEditorModifierComputer.kt new file mode 100644 index 0000000000..af44e9e595 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/ContentEditorModifierComputer.kt @@ -0,0 +1,25 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.ContentEditor +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.annotationClassValue +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.fullName +import kotlin.reflect.KClass + +object ContentEditorModifierComputer : DataModifierComputer { + override val annotationClass: KClass = ContentEditor::class + + override fun compute(blueprint: DataBlueprint, annotation: ContentEditor): Result { + innerCompute(blueprint, annotation)?.let { return ok(it) } + + val contentMode = annotation.annotationClassValue { capturer } + val className = contentMode.declaration.qualifiedName?.asString() + ?: return failure("ContentEditor ${contentMode.fullName} does not have a qualified name! It must be a non-local non-anonymous class.") + + return ok(DataModifier.Modifier("contentMode", className)) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/GeneratedModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/GeneratedModifierComputer.kt new file mode 100644 index 0000000000..0e1f05be1f --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/GeneratedModifierComputer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Generated +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object GeneratedModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Generated::class + + override fun compute(blueprint: DataBlueprint, annotation: Generated): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("Generated annotation can only be used on strings (including in lists or maps)!") + } + + if (blueprint.type != PrimitiveType.STRING) { + return failure("Generated annotation can only be used on strings (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("generated")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/HelpModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/HelpModifierComputer.kt new file mode 100644 index 0000000000..0eb92b025e --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/HelpModifierComputer.kt @@ -0,0 +1,18 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Help +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import kotlin.reflect.KClass + +object HelpModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Help::class + + override fun compute(blueprint: DataBlueprint, annotation: Help): Result { + innerCompute(blueprint, annotation)?.let { return ok(it) } + + return ok(DataModifier.Modifier("help", annotation.text)) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/IconModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/IconModifierComputer.kt new file mode 100644 index 0000000000..ddc7cb2b3a --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/IconModifierComputer.kt @@ -0,0 +1,15 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Icon +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.* +import kotlin.reflect.KClass + +object IconModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Icon::class + + override fun compute(blueprint: DataBlueprint, annotation: Icon): Result { + innerCompute(blueprint, annotation)?.let { return ok(it) } + return ok(DataModifier.Modifier("icon", annotation.icon)) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MaterialPropertiesModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MaterialPropertiesModifierComputer.kt new file mode 100644 index 0000000000..5650f495b4 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MaterialPropertiesModifierComputer.kt @@ -0,0 +1,28 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.MaterialProperties +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.* +import kotlin.reflect.KClass + +object MaterialPropertiesModifierComputer : DataModifierComputer { + override val annotationClass: KClass = MaterialProperties::class + + override fun compute(blueprint: DataBlueprint, annotation: MaterialProperties): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.CustomBlueprint) { + return failure("MaterialProperties annotation can only be used on custom fields") + } + if (blueprint.editor != "material") { + return failure("MaterialProperties annotation can only be used materials (not on ${blueprint.editor})") + } + + return ok(DataModifier.Modifier( + "material_properties", + annotation.properties.joinToString(";") { it.name.lowercase() } + )) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MultiLineModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MultiLineModifierComputer.kt new file mode 100644 index 0000000000..c3c984a1d3 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/MultiLineModifierComputer.kt @@ -0,0 +1,28 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.MultiLine +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object MultiLineModifierComputer : DataModifierComputer { + override val annotationClass: KClass = MultiLine::class + + override fun compute(blueprint: DataBlueprint, annotation: MultiLine): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("MultiLine annotation can only be used on strings") + } + if (blueprint.type != PrimitiveType.STRING) { + return failure("MultiLine annotation can only be used on strings") + } + + return ok(DataModifier.Modifier("multiline")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/NegativeModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/NegativeModifierComputer.kt new file mode 100644 index 0000000000..96ece384f7 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/NegativeModifierComputer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Negative +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object NegativeModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Negative::class + + override fun compute(blueprint: DataBlueprint, annotation: Negative): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("Negative annotation can only be used on numbers (including in lists or maps)!") + } + + if (blueprint.type != PrimitiveType.INTEGER && blueprint.type != PrimitiveType.DOUBLE) { + return failure("Negative annotation can only be used on numbers (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("negative")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/OnlyTagsModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/OnlyTagsModifierComputer.kt new file mode 100644 index 0000000000..83338b738e --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/OnlyTagsModifierComputer.kt @@ -0,0 +1,28 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.OnlyTags +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import kotlin.reflect.KClass + +object OnlyTagsModifierComputer : DataModifierComputer { + override val annotationClass: KClass = OnlyTags::class + + override fun compute(blueprint: DataBlueprint, annotation: OnlyTags): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.CustomBlueprint) { + return failure("OnlyTags annotation can only be used on Refs (including in lists or maps)!") + } + + if (blueprint.editor != "entryReference") { + return failure("OnlyTags annotation can only be used on Refs (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("only_tags", annotation.tags.joinToString(","))) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PageModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PageModifierComputer.kt new file mode 100644 index 0000000000..470b08419a --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PageModifierComputer.kt @@ -0,0 +1,28 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Page +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object PageModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Page::class + + override fun compute(blueprint: DataBlueprint, annotation: Page): Result { + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("Page annotation can only be used on primitive fields") + } + + if (blueprint.type != PrimitiveType.STRING) { + return failure("Page annotation can only be used on string fields") + } + + return ok(DataModifier.Modifier("page", annotation.type.id)) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PlaceholderModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PlaceholderModifierComputer.kt new file mode 100644 index 0000000000..4a9b7ac51a --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/PlaceholderModifierComputer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Placeholder +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object PlaceholderModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Placeholder::class + + override fun compute(blueprint: DataBlueprint, annotation: Placeholder): Result { + // If the field is wrapped in a list or other container we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("Placeholder annotation can only be used on strings (including in lists or maps)!") + } + + if (blueprint.type != PrimitiveType.STRING) { + return failure("Placeholder annotation can only be used on strings (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("placeholder")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/RegexModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/RegexModifierComputer.kt new file mode 100644 index 0000000000..d1a784de37 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/RegexModifierComputer.kt @@ -0,0 +1,29 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Regex +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import com.typewritermc.processors.entry.PrimitiveType +import kotlin.reflect.KClass + +object RegexModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Regex::class + + override fun compute(blueprint: DataBlueprint, annotation: Regex): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("Regex annotation can only be used on strings (including in lists or maps)!") + } + + if (blueprint.type != PrimitiveType.STRING) { + return failure("Regex annotation can only be used on strings (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("regex")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SegmentModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SegmentModifierComputer.kt new file mode 100644 index 0000000000..e0a561856b --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SegmentModifierComputer.kt @@ -0,0 +1,46 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.Segments +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.* +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlin.reflect.KClass + +object SegmentModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Segments::class + + override fun compute(blueprint: DataBlueprint, annotation: Segments): Result { + if (blueprint !is DataBlueprint.ListBlueprint) { + return failure("Segment annotation can only be used on lists") + } + + val type = blueprint.type + if (type !is DataBlueprint.ObjectBlueprint) { + return failure("Segment annotation can only be used on lists of objects") + } + + val startFrame = type.fields["startFrame"] + val endFrame = type.fields["endFrame"] + if (startFrame !is DataBlueprint.PrimitiveBlueprint || endFrame !is DataBlueprint.PrimitiveBlueprint) { + return failure("Segment annotation can only be used on lists of objects with startFrame and endFrame fields") + } + + if (startFrame.type != PrimitiveType.INTEGER || endFrame.type != PrimitiveType.INTEGER) { + return failure("Segment annotation can only be used on lists of objects with startFrame and endFrame fields of type int") + } + + val color = annotation.color + val icon = annotation.icon + + val data = JsonObject( + mapOf( + "color" to JsonPrimitive(color), + "icon" to JsonPrimitive(icon), + ) + ) + + return ok(DataModifier.InnerModifier(DataModifier.Modifier("segment", data))) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SizeModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SizeModifierComputer.kt new file mode 100644 index 0000000000..9741edeb2e --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SizeModifierComputer.kt @@ -0,0 +1,80 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.InnerMax +import com.typewritermc.core.extension.annotations.InnerMin +import com.typewritermc.core.extension.annotations.Max +import com.typewritermc.core.extension.annotations.Min +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import kotlin.reflect.KClass + +object MinModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Min::class + + override fun compute(blueprint: DataBlueprint, annotation: Min): Result { + return ok(DataModifier.Modifier("min", annotation.value)) + } +} + +object InnerMinModifierComputer : DataModifierComputer { + override val annotationClass: KClass = InnerMin::class + + override fun compute(blueprint: DataBlueprint, annotation: InnerMin): Result { + when (blueprint) { + is DataBlueprint.ListBlueprint, is DataBlueprint.ObjectBlueprint, is DataBlueprint.CustomBlueprint -> return ok( + DataModifier.InnerModifier( + DataModifier.Modifier( + "min", + annotation.annotation.value + ) + ) + ) + + is DataBlueprint.MapBlueprint -> return ok( + DataModifier.InnerMapModifier( + key = null, + value = DataModifier.Modifier("min", annotation.annotation.value) + ) + ) + + else -> return failure("InnerMin annotation can only be used on lists, maps or objects") + } + } +} + +object MaxModifierComputer : DataModifierComputer { + override val annotationClass: KClass = Max::class + + override fun compute(blueprint: DataBlueprint, annotation: Max): Result { + return ok(DataModifier.Modifier("max", annotation.value)) + } +} + +object InnerMaxModifierComputer : DataModifierComputer { + override val annotationClass: KClass = InnerMax::class + + override fun compute(blueprint: DataBlueprint, annotation: InnerMax): Result { + when (blueprint) { + is DataBlueprint.ListBlueprint, is DataBlueprint.ObjectBlueprint, is DataBlueprint.CustomBlueprint -> return ok( + DataModifier.InnerModifier( + DataModifier.Modifier( + "max", + annotation.annotation.value + ) + ) + ) + + is DataBlueprint.MapBlueprint -> return ok( + DataModifier.InnerMapModifier( + key = null, + value = DataModifier.Modifier("max", annotation.annotation.value) + ) + ) + + else -> return failure("InnerMax annotation can only be used on lists, maps or objects") + } + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SnakeCaseModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SnakeCaseModifierComputer.kt new file mode 100644 index 0000000000..2bb25da3b1 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/SnakeCaseModifierComputer.kt @@ -0,0 +1,25 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.SnakeCase +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.* +import kotlin.reflect.KClass + +object SnakeCaseModifierComputer : DataModifierComputer { + override val annotationClass: KClass = SnakeCase::class + + override fun compute(blueprint: DataBlueprint, annotation: SnakeCase): Result { + // If the field is wrapped in a list or other container we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.PrimitiveBlueprint) { + return failure("SnakeCase annotation can only be used on strings (including in lists or maps)!") + } + if (blueprint.type != PrimitiveType.STRING) { + return failure("SnakeCase annotation can only be used on strings (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("snake_case")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/WithRotationModifierComputer.kt b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/WithRotationModifierComputer.kt new file mode 100644 index 0000000000..236b7f5d35 --- /dev/null +++ b/module-plugin/extension-processor/src/main/kotlin/com/typewritermc/processors/entry/modifiers/WithRotationModifierComputer.kt @@ -0,0 +1,27 @@ +package com.typewritermc.processors.entry.modifiers + +import com.typewritermc.core.extension.annotations.WithRotation +import com.typewritermc.core.utils.failure +import com.typewritermc.core.utils.ok +import com.typewritermc.processors.entry.DataBlueprint +import com.typewritermc.processors.entry.DataModifier +import com.typewritermc.processors.entry.DataModifierComputer +import kotlin.reflect.KClass + +object WithRotationModifierComputer : DataModifierComputer { + override val annotationClass: KClass = WithRotation::class + + override fun compute(blueprint: DataBlueprint, annotation: WithRotation): Result { + // If the field is wrapped in a list or other container, we try if the inner type can be modified + innerCompute(blueprint, annotation)?.let { return ok(it) } + + if (blueprint !is DataBlueprint.CustomBlueprint) { + return failure("WithRotation annotation can only be used on positions or coordinates (including in lists or maps)!") + } + if (blueprint.editor != "position" && blueprint.editor != "coordinate") { + return failure("WithRotation annotation can only be used on positions or coordinates (including in lists or maps)!") + } + + return ok(DataModifier.Modifier("with_rotation")) + } +} \ No newline at end of file diff --git a/module-plugin/extension-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/module-plugin/extension-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 0000000000..3afcbb60e2 --- /dev/null +++ b/module-plugin/extension-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1 @@ +com.typewritermc.processors.ExtensionProcessorProvider \ No newline at end of file diff --git a/plugin/gradle/wrapper/gradle-wrapper.jar b/module-plugin/gradle/wrapper/gradle-wrapper.jar similarity index 79% rename from plugin/gradle/wrapper/gradle-wrapper.jar rename to module-plugin/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..249e5832f090a2944b7473328c07c9755baa3196 100644 GIT binary patch delta 10158 zcmaKSbyOWsmn~e}-QC?axCPf>!2<-jxI0|j{UX8L-QC?axDz};a7}ppGBe+Nv*x{5 zy?WI?=j^WT(_Md5*V*xNP>X9&wM>xUvNiMuKDK=Xg!N%oM>Yru2rh7#yD-sW0Ov#$ zCKBSOD3>TM%&1T5t&#FK@|@1f)Ze+EE6(7`}J(Ek4})CD@I+W;L{ zO>K;wokKMA)EC6C|D@nz%D2L3U=Nm(qc>e4GM3WsHGu-T?l^PV6m-T-(igun?PZ8U z{qbiLDMcGSF1`FiKhlsV@qPMRm~h9@z3DZmWp;Suh%5BdP6jqHn}$-gu`_xNg|j{PSJ0n$ zbE;Azwq8z6IBlgKIEKc4V?*##hGW#t*rh=f<;~RFWotXS$vr;Mqz>A99PMH3N5BMi zWLNRjc57*z`2)gBV0o4rcGM(u*EG8_H5(|kThAnp|}u2xz>>X6tN zv)$|P2Nr1D*fk4wvqf(7;NmdRV3eL{!>DO-B98(s*-4$g{)EnRYAw+DP-C`=k)B!* zHU7!ejcbavGCYuz9k@$aZQaU%#K%6`D}=N_m?~^)IcmQZun+K)fSIoS>Ws zwvZ%Rfmw>%c!kCd~Pmf$E%LCj2r>+FzKGDm+%u88|hHprot{*OIVpi`Vd^^aumtx2L}h} zPu$v~zdHaWPF<`LVQX4i7bk82h#RwRyORx*z3I}o&>>eBDCif%s7&*vF6kU%1` zf(bvILch^~>cQ{=Y#?nx(8C-Uuv7!2_YeCfo?zkP;FK zX+KdjKS;HQ+7 zj>MCBI=d$~9KDJ1I2sb_3=T6D+Mu9{O&vcTnDA(I#<=L8csjEqsOe=&`=QBc7~>u2 zfdcO44PUOST%PcN+8PzKFYoR0;KJ$-Nwu#MgSM{_!?r&%rVM}acp>53if|vpH)q=O z;6uAi__am8g$EjZ33?PmCrg@(M!V_@(^+#wAWNu&e3*pGlfhF2<3NobAC zlusz>wMV--3ytd@S047g)-J@eOD;DMnC~@zvS=Gnw3=LnRzkeV`LH4#JGPklE4!Q3 zq&;|yGR0FiuE-|&1p2g{MG!Z3)oO9Jf4@0h*3!+RHv=SiEf*oGQCSRQf=LqT5~sajcJ8XjE>E*@q$n z!4|Rz%Lv8TgI23JV6%)N&`Otk6&RBdS|lCe7+#yAfdyEWNTfFb&*S6-;Q}d`de!}*3vM(z71&3 z37B%@GWjeQ_$lr%`m-8B&Zl4Gv^X{+N{GCsQGr!LLU4SHmLt3{B*z-HP{73G8u>nK zHxNQ4eduv>lARQfULUtIlLx#7ea+O;w?LH}FF28c9pg#*M`pB~{jQmPB*gA;Hik#e zZpz&X#O}}r#O_#oSr4f`zN^wedt>ST791bAZ5(=g<Oj)m9X8J^>Th}fznPY0T zsD9ayM7Hrlb6?jHXL<{kdA*Q#UPCYce0p`fHxoZ7_P`cF-$1YY9Pi;0QFt{CCf%C# zuF60A_NTstTQeFR3)O*ThlWKk08}7Nshh}J-sGY=gzE!?(_ZI4ovF6oZ$)&Zt~WZi z_0@Bk!~R4+<&b6CjI{nGj+P{*+9}6;{RwZ7^?H)xjhiRi;?A|wb0UxjPr?L@$^v|0= z@6d3+eU|&re3+G*XgFS}tih3;>2-R1x>`2hmUb5+Z~eM4P|$ zAxvE$l@sIhf_#YLnF|Wcfp(Gh@@dJ-yh|FhKqsyQp_>7j1)w|~5OKETx2P$~`}5huK;{gw_~HXP6=RsG)FKSZ=VYkt+0z&D zr?`R3bqVV?Zmqj&PQ`G3b^PIrd{_K|Hhqt zAUS#|*WpEOeZ{@h*j6%wYsrL`oHNV=z*^}yT1NCTgk1-Gl(&+TqZhODTKb9|0$3;| z;{UUq7X9Oz`*gwbi|?&USWH?Fr;6=@Be4w=8zu>DLUsrwf+7A`)lpdGykP`^SA8{ok{KE3sM$N@l}kB2GDe7MEN? zWcQ2I0fJ1ZK%s-YKk?QbEBO6`C{bg$%le0FTgfmSan-Kih0A7)rGy|2gd)_gRH7qp z*bNlP0u|S^5<)kFcd&wQg*6QP5;y(3ZgI%vUgWk#`g!sMf`02>@xz{Ie9_-fXllyw zh>P%cK+-HkQ;D$Jh=ig(ASN^zJ7|q*#m;}2M*T#s0a^nF_>jI(L(|*}#|$O&B^t!W zv-^-vP)kuu+b%(o3j)B@do)n*Y0x%YNy`sYj*-z2ncYoggD6l z6{1LndTQUh+GCX;7rCrT z@=vy&^1zyl{#7vRPv;R^PZPaIks8okq)To8!Cks0&`Y^Xy5iOWC+MmCg0Jl?1ufXO zaK8Q5IO~J&E|<;MnF_oXLc=LU#m{6yeomA^Ood;)fEqGPeD|fJiz(`OHF_f*{oWJq z1_$NF&Mo7@GKae#f4AD|KIkGVi~ubOj1C>>WCpQq>MeDTR_2xL01^+K1+ zr$}J>d=fW{65hi2bz&zqRKs8zpDln z*7+Gtfz6rkgfj~#{MB=49FRP;ge*e0=x#czw5N{@T1{EAl;G&@tpS!+&2&Stf<%<+55R18u2%+}`?PZo8xg|Y9Xli(fSQyC7 z+O5{;ZyW$!eYR~gy>;l6cA+e`oXN6a6t(&kUkWus*Kf<m$W7L)w5uXYF)->OeWMSUVXi;N#sY zvz4c?GkBU{D;FaQ)9|HU7$?BX8DFH%hC11a@6s4lI}y{XrB~jd{w1x&6bD?gemdlV z-+ZnCcldFanu`P=S0S7XzwXO(7N9KV?AkgZzm|J&f{l-Dp<)|-S7?*@HBIfRxmo1% zcB4`;Al{w-OFD08g=Qochf9=gb56_FPc{C9N5UAjTcJ(`$>)wVhW=A<8i#!bmKD#6~wMBak^2(p56d2vs&O6s4>#NB0UVr24K z%cw|-Yv}g5`_zcEqrZBaRSoBm;BuXJM^+W$yUVS9?u(`87t)IokPgC_bQ3g_#@0Yg zywb?u{Di7zd3XQ$y!m^c`6~t-7@g-hwnTppbOXckS-^N?w1`kRMpC!mfMY?K#^Ldm zYL>771%d{+iqh4a&4RdLNt3_(^^*{U2!A>u^b{7e@}Azd_PiZ>d~(@(Q@EYElLAx3LgQ5(ZUf*I%EbGiBTG!g#=t zXbmPhWH`*B;aZI)$+PWX+W)z?3kTOi{2UY9*b9bpSU!GWcVu+)!^b4MJhf=U9c?jj z%V)EOF8X3qC5~+!Pmmmd@gXzbycd5Jdn!N#i^50a$4u}8^O}DG2$w-U|8QkR-WU1mk4pF z#_imS#~c2~Z{>!oE?wfYc+T+g=eJL`{bL6=Gf_lat2s=|RxgP!e#L|6XA8w{#(Po(xk1~rNQ4UiG``U`eKy7`ot;xv4 zdv54BHMXIq;#^B%W(b8xt%JRueW5PZsB2eW=s3k^Pe1C$-NN8~UA~)=Oy->22yJ%e zu=(XD^5s{MkmWB)AF_qCFf&SDH%ytqpt-jgs35XK8Ez5FUj?uD3++@2%*9+-65LGQ zvu1eopeQoFW98@kzU{+He9$Yj#`vaQkqu%?1wCoBd%G=)TROYl2trZa{AZ@#^LARR zdzg-?EUnt9dK2;W=zCcVj18RTj-%w^#pREbgpD0aL@_v-XV2&Cd@JB^(}GRBU}9gV z6sWmVZmFZ9qrBN%4b?seOcOdOZ+6cx8-#R(+LYKJu~Y%pF5#85aF9$MnP7r^Bu%D? zT{b-KBujiy>7_*9{8u0|mTJ(atnnnS%qBDM_Gx5>3V+2~Wt=EeT4cXOdud$+weM(>wdBg+cV$}6%(ccP;`!~CzW{0O2aLY z?rQtBB6`ZztPP@_&`kzDzxc==?a{PUPUbbX31Vy?_(;c+>3q*!df!K(LQYZNrZ>$A*8<4M%e8vj1`%(x9)d~);ym4p zoo518$>9Pe| zZaFGj);h?khh*kgUI-Xvj+Dr#r&~FhU=eQ--$ZcOY9;x%&3U(&)q}eJs=)K5kUgi5 zNaI-m&4?wlwFO^`5l-B?17w4RFk(IKy5fpS0K%txp0qOj$e=+1EUJbLd-u>TYNna~ z+m?gU0~xlcnP>J>%m_y_*7hVMj3d&)2xV8>F%J;6ncm)ILGzF2sPAV|uYk5!-F%jL(53^51BKr zc3g7+v^w<4WIhk7a#{N6Ku_u{F`eo;X+u!C(lIaiY#*V5!sMed39%-AgV*`(nI)Im zemHE^2foBMPyIP<*yuD21{6I?Co?_{pqp-*#N6sZRQAzEBV4HQheOyZT5UBd)>G85 zw^xHvCEP4AJk<{v2kQQ;g;C)rCY=X!c8rNpNJ4mHETN}t1rwSe7=s8u&LzW-+6AEB z)LX0o7`EqC94HM{4p}d2wOwj2EB|O;?&^FeG9ZrT%c!J&x`Z3D2!cm(UZbFBb`+h ztfhjq75yuSn2~|Pc)p$Ul6=)}7cfXtBsvc15f&(K{jnEsw5Gh0GM^O=JC+X-~@r1kI$=FH=yBzsO#PxR1xU9+T{KuPx7sMe~GX zSP>AT3%(Xs@Ez**e@GAn{-GvB^oa6}5^2s+Mg~Gw?#$u&ZP;u~mP|FXsVtr>3k9O?%v>`Ha-3QsOG<7KdXlqKrsN25R|K<<;- z8kFY!&J&Yrqx3ptevOHiqPxKo_wwAPD)$DWMz{0>{T5qM%>rMqGZ!dJdK(&tP1#89 zVcu}I1I-&3%nMyF62m%MDpl~p)PM(%YoR zD)=W)E7kjwzAr!?^P*`?=fMHd1q4yjLGTTRUidem^Ocjrfgk2Jp|6SabEVHKC3c>RX@tNx=&Z7gC z0ztZoZx+#o36xH8mv6;^e{vU;G{JW17kn(RO&0L%q^fpWSYSkr1Cb92@bV->VO5P z;=V{hS5wcROQfbah6ND{2a$zFnj>@yuOcw}X~E20g7)5=Z#(y)RC878{_rObmGQ;9 zUy>&`YT^2R@jqR1z9Fx&x)WBstIE#*UhAa>WrMm<10={@$UN@Cog+#pxq{W@l0DOf zJGs^Jv?t8HgIXk(;NFHXun$J{{p})cJ^BWn4BeQo6dMNp%JO@$9z{(}qqEHuZOUQP zZiwo70Oa@lMYL(W*R4(!oj`)9kRggJns-A|w+XL=P07>QBMTEbG^gPS)H zu^@MFTFZtsKGFHgj|hupbK({r>PX3_kc@|4Jdqr@gyyKrHw8Tu<#0&32Hh?S zsVm_kQ2K`4+=gjw1mVhdOz7dI7V!Iu8J1LgI+_rF`Wgx5-XwU~$h>b$%#$U3wWC-ea0P(At2SjPAm57kd;!W5k{do1}X681o}`!c*(w!kCjtGTh7`=!M)$9 zWjTns{<-WX+Xi;&d!lyV&1KT9dKL??8)fu2(?Ox<^?EAzt_(#5bp4wAfgIADYgLU` z;J7f8g%-tfmTI1ZHjgufKcAT4SO(vx?xSo4pdWh`3#Yk;DqPGQE0GD?!_CfXb(E8WoJt6*Yutnkvmb?7H9B zVICAYowwxK;VM4(#~|}~Ooyzm*1ddU_Yg%Ax*_FcZm^AzYc$<+9bv;Eucr(SSF}*JsjTfb*DY>qmmkt z;dRkB#~SylP~Jcmr&Bl9TxHf^DcGUelG%rA{&s)5*$|-ww}Kwx-lWnNeghVm@z zqi3@-oJnN%r2O4t9`5I5Zfc;^ROHmY6C9 z1VRRX*1+aBlbO_p>B+50f1p&%?_A*16R0n+l}HKWI$yIH3oq2`k4O?tEVd~a4~>iI zo{d}b8tr+$q<%%K%Ett*i|RAJEMnk9hU7LtL!lxOB45xO1g)ycDBd=NbpaE3j?Gw& z0M&xx13EkCgNHu%Z8rBLo93XH-zQUfF3{Iy>65-KSPniqIzF+?x$3>`L?oBOBeEsv zs_y7@7>IbS&w2Vju^#vBpPWQuUv=dDRGm(-MH|l+8T?vfgD;{nE_*-h?@D;GN>4hA z9{!G@ANfHZOxMq5kkoh4h*p3+zE7z$13ocDJR$XA*7uKtG5Cn_-ibn%2h{ z;J0m5aCjg(@_!G>i2FDAvcn5-Aby8b;J0u%u)!`PK#%0FS-C3(cq9J{V`DJEbbE|| zYpTDd+ulcjEd5`&v!?=hVgz&S0|C^We?2|>9|2T6?~nn^_CpLn&kuI|VG7_E{Ofu9 zAqe0Reuq5Zunlx@zyTqEL+ssT15X|Z0LUfZAr-i$1_SJ{j}BHmBm}s8{OgK3lm%4F zzC%jz!y!8WUJo2FLkU(mVh7-uzC+gcbkV^bM}&Y6=HTTca{!7ZSoB!)l|v<(3ly!jq&P5A2q(U5~h)))aj-`-6&aM~LBySnAy zA0{Z{FHiUb8rW|Yo%kQwi`Kh>EEE$0g7UxeeeVkcY%~87yCmSjYyxoqq(%Jib*lH; zz`t5y094U`k_o{-*U^dFH~+1I@GsgwqmGsQC9-Vr0X94TLhlV;Kt#`9h-N?oKHqpx zzVAOxltd%gzb_Qu{NHnE8vPp=G$#S)Y%&6drobF_#NeY%VLzeod delta 9041 zcmY*t@kVBCBP!g$Qih>$!M(|j-I?-C8+=cK0w!?cVWy9LXH zd%I}(h%K_>9Qvap&`U=={XcolW-VA%#t9ljo~WmY8+Eb|zcKX3eyx7qiuU|a)zU5cYm5{k5IAa3ibZf_B&=YT!-XyLap%QRdebT+PIcg$KjM3HqA3uZ5|yBj2vv8$L{#$>P=xi+J&zLILkooDarGpiupEiuy`9uy&>yEr95d)64m+~`y*NClGrY|5MLlv!)d5$QEtqW)BeBhrd)W5g1{S@J-t8_J1 zthp@?CJY}$LmSecnf3aicXde(pXfeCei4=~ZN=7VoeU|rEEIW^!UBtxGc6W$x6;0fjRs7Nn)*b9JW5*9uVAwi) zj&N7W;i<Qy80(5gsyEIEQm>_+4@4Ol)F?0{YzD(6V~e=zXmc2+R~P~< zuz5pju;(akH2+w5w!vnpoikD5_{L<6T`uCCi@_Uorr`L(8zh~x!yEK*!LN02Q1Iri z>v*dEX<(+_;6ZAOIzxm@PbfY4a>ws4D82&_{9UHCfll!x`6o8*i0ZB+B#Ziv%RgtG z*S}<4!&COp)*ZMmXzl0A8mWA$)fCEzk$Wex*YdB}_-v|k9>jKy^Y>3me;{{|Ab~AL zQC(naNU=JtU3aP6P>Fm-!_k1XbhdS0t~?uJ$ZvLbvow10>nh*%_Kh>7AD#IflU8SL zMRF1fmMX#v8m=MGGb7y5r!Qf~Y}vBW}fsG<{1CHX7Yz z=w*V9(vOs6eO>CDuhurDTf3DVVF^j~rqP*7S-$MLSW7Ab>8H-80ly;9Q0BWoNV zz8Wr2CdK!rW0`sMD&y{Ue{`mEkXm0%S2k;J^iMe|sV5xQbt$ojzfQE+6aM9LWH`t& z8B;Ig7S<1Dwq`3W*w59L(opjq)ll4E-c?MivCh!4>$0^*=DKI&T2&j?;Z82_iZV$H zKmK7tEs7;MI-Vo(9wc1b)kc(t(Yk? z#Hgo8PG_jlF1^|6ge%;(MG~6fuKDFFd&}>BlhBTh&mmuKsn>2buYS=<5BWw^`ncCb zrCRWR5`IwKC@URU8^aOJjSrhvO>s}O&RBD8&V=Fk2@~zYY?$qO&!9%s>YecVY0zhK zBxKGTTyJ(uF`p27CqwPU1y7*)r}y;{|0FUO)-8dKT^>=LUoU_6P^^utg|* zuj}LBA*gS?4EeEdy$bn#FGex)`#y|vg77NVEjTUn8%t z@l|7T({SM!y$PZy9lb2N;BaF}MfGM%rZk10aqvUF`CDaC)&Av|eED$x_;qSoAka*2 z2rR+OTZTAPBx`vQ{;Z{B4Ad}}qOBqg>P4xf%ta|}9kJ2$od>@gyC6Bf&DUE>sqqBT zYA>(sA=Scl2C_EF8)9d8xwdBSnH5uL=I4hch6KCHj-{99IywUD{HR`d(vk@Kvl)WD zXC(v{ZTsyLy{rio*6Wi6Lck%L(7T~Is-F_`2R}q z!H1ylg_)Mv&_|b1{tVl!t{;PDa!0v6^Zqs_`RdxI%@vR)n|`i`7O<>CIMzqI00y{;` zhoMyy>1}>?kAk~ND6}`qlUR=B+a&bvA)BWf%`@N)gt@@Ji2`p1GzRGC$r1<2KBO3N z++YMLD9c|bxC;za_UVJ*r6&Ea;_YC>-Ebe-H=VAgDmx+?Q=DxCE4=yQXrn z7(0X#oIjyfZUd}fv2$;4?8y|0!L^ep_rMz|1gU-hcgVYIlI~o>o$K&)$rwo(KJO~R zDcGKo-@im7C<&2$6+q-xtxlR`I4vL|wFd<`a|T}*Nt;(~Vwx&2QG_j$r0DktR+6I4W)gUx*cDVBwGe00aa803ZYiwy;d{1p)y0?*IT8ddPS`E~MiS z1d%Vm0Hb4LN2*f8FZ|6xRQev@ZK-?(oPs+mT*{%NqhGL_0dJ$?rAxA{2 z`r3MBv&)xblcd>@hArncJpL~C(_HTo&D&CS!_J5Giz$^2EfR_)xjgPg`Bq^u%1C*+ z7W*HGp|{B?dOM}|E)Cs$61y8>&-rHBw;A8 zgkWw}r$nT%t(1^GLeAVyj1l@)6UkHdM!%LJg|0%BO74M593&LlrksrgoO{iEz$}HK z4V>WXgk|7Ya!Vgm#WO^ZLtVjxwZ&k5wT6RteViH3ds{VO+2xMJZ`hToOz~_+hRfY{ z%M;ZDKRNTsK5#h6goUF(h#VXSB|7byWWle*d0$IHP+FA`y)Q^5W!|&N$ndaHexdTn z{vf?T$(9b&tI&O`^+IqpCheAFth;KY(kSl2su_9|Y1B{o9`mm)z^E`Bqw!n+JCRO) zGbIpJ@spvz=*Jki{wufWm|m`)XmDsxvbJR5dLF=kuf_C>dl}{nGO(g4I$8 zSSW#5$?vqUDZHe_%`Zm?Amd^>I4SkBvy+i}wiQYBxj0F1a$*%T+6}Yz?lX&iQ}zaU zI@%8cwVGtF3!Ke3De$dL5^j-$Bh3+By zrSR3c2a>XtaE#TB}^#hq@!vnZ1(An#bk_eKR{?;Z&0cgh4$cMNU2HL=m=YjMTI zT$BRltXs4T=im;Ao+$Bk3Dz(3!C;rTqelJ?RF)d~dP9>$_6dbz=_8#MQFMMX0S$waWxY#mtDn}1U{4PGeRH5?a>{>TU@1UlucMAmzrd@PCwr|il)m1fooO7Z{Vyr z6wn=2A5z(9g9-OU10X_ei50@~)$}w4u)b+mt)z-sz0X32m}NKTt4>!O{^4wA(|3A8 zkr(DxtMnl$Hol>~XNUE?h9;*pGG&kl*q_pb z&*$lH70zI=D^s)fU~A7cg4^tUF6*Oa+3W0=7FFB*bf$Kbqw1&amO50YeZM)SDScqy zTw$-M$NA<_We!@4!|-?V3CEPnfN4t}AeM9W$iSWYz8f;5H)V$pRjMhRV@Z&jDz#FF zXyWh7UiIc7=0U9L35=$G54RjAupR&4j`(O3i?qjOk6gb!WjNtl1Fj-VmltDTos-Bl z*OLfOleS~o3`?l!jTYIG!V7?c<;Xu(&#~xf-f(-jwow-0Hv7JZG>}YKvB=rRbdMyv zmao*-!L?)##-S#V^}oRm7^Db zT5C2RFY4>ov~?w!3l_H}t=#X=vY-*LQy(w>u%r`zQ`_RukSqIv@WyGXa-ppbk-X=g zyn?TH(`-m*in(w=Ny$%dHNSVxsL|_+X=+kM+v_w{ZC(okof9k1RP5qDvcA-d&u{5U z?)a9LXht1f6|Tdy5FgXo;sqR|CKxDKruU9RjK~P6xN+4;0eAc|^x%UO^&NM4!nK_! z6X14Zkk=5tqpl&d6FYuMmlLGQZep0UE3`fT>xzgH>C*hQ2VzCQlO`^kThU6q%3&K^ zf^kfQm|7SeU#c%f8e?A<9mALLJ-;)p_bv6$pp~49_o;>Y=GyUQ)*prjFbkU;z%HkOW_*a#j^0b@GF|`6c}7>=W{Ef!#dz5lpkN>@IH+(sx~QMEFe4 z1GeKK67;&P%ExtO>}^JxBeHii)ykX8W@aWhJO!H(w)DH4sPatQ$F-Phiqx_clj`9m zK;z7X6gD2)8kG^aTr|oY>vmgOPQ4`_W+xj2j!$YT9x(DH6pF~ zd_C#8c>Gfb)k2Ku4~t=Xb>T^8KW;2HPN#%}@@hC1lNf~Xk)~oj=w-Y11a@DtIyYk8 z9^|_RIAA(1qUSs3rowxr&OuRVFL8(zSqU_rGlqHpkeYT4z7DGdS0q4V-b!3fsv$Yb zPq4UP^3XFd(G%JAN|0y>?&sLzNir30K(lyzNYvCtE2gDyy-nthPlrXXU75fhoS7kA zg%GYyBEFQ(xgdjtv+>?>Q!G!8& z3+F>)4|N+F1a^T?XC8 zxRRx7-{DV%uUYt&*$z2uQTbZDbUn)PozID*(i^{JDjNq`v?;&OW^&~{ZPE_e+?RMk z!7O5CUKJSnGZvjTbLX2$zwYRZs_$f{T!hvVHuTg77|O;zBHlA|GIUu_bh4`Bl?7KE zYB~a`b?O;0SfD?0EZiPYpVf=P4=|zr(u_w}oP0S`YOZziX9cuwpll&%QMv4bBC_JdP#rT3>MliqySv0& zh)r=vw?no&;5T}QVTkHKY%t`%{#*#J;aw!wPs}?q2$(e0Y#cdBG1T09ypI@#-y24+fzhJem1NSZ$TCAjU2|ebYG&&6p(0f>wQoNqVa#6J^W!3$gIWEw7d<^k!U~O5v=8goq$jC`p8CS zrox#Jw3w`k&Ty7UVbm35nZ}FYT5`fN)TO6R`tEUFotxr^BTXZGt|n(Ymqmr^pCu^^w?uX!ONbm?q{y9FehdmcJuV8V%A-ma zgl=n9+op{wkj-}N;6t;(JA1A#VF3S9AFh6EXRa0~7qop~3^~t1>hc6rdS_4!+D?Xh z5y?j}*p@*-pmlTb#7C0x{E(E@%eepK_YycNkhrYH^0m)YR&gRuQi4ZqJNv6Rih0zQ zqjMuSng>Ps;?M0YVyh<;D3~;60;>exDe)Vq3x@GRf!$wgFY5w4=Jo=g*E{76%~jqr zxTtb_L4Cz_E4RTfm@0eXfr1%ho?zP(>dsRarS>!^uAh~bd0lEhe2x7AEZQmBc%rU; z&FUrs&mIt8DL`L4JpiFp3NNyk3N>iL6;Nohp*XbZZn%BDhF_y{&{X3UtX(7aAyG63P zELC;>2L`jnFS#vC->A(hZ!tGi7N7^YtW7-LB6!SVdEM&7N?g}r4rW2wLn{Ni*I~$Y z@#;KwJIl0^?eX{JWiHQxDvccnNKBhHW0h6`j=)OH1`)7)69B$XNT@)l1s25M+~o2_ zpa&X<_vHxN_oR|B#ir2p*VNB~o6Z1OE&~a+_|AxS)(@Dgznq(b(|K8BN_nQ7+>N`= zXOx_@AhcmmcRvp6eX#4z6sn=V0%KonKFVY@+m&)Rx!Z5U@WdyHMCF4_qzJNpzc9Fw z7Bdzx54(e7>wcEqHKqH-Paiut;~ZVJpS6_q>ub)zD#TQ4j*i(I8DvS$BfyX~A%<#} z*=g2$8s;YYjEHl`7cKw!a9PFRt8tVR zM&X|bs?B1#ycjl>AzgbdRkr-@NmBc^ys)aoT75F(yweV&Y-3hNNXj-valA&=)G{NL zX?smr5sQWi3n;GGPW{%vW)xw-#D0QY%zjXxYj?($b4JzpW0sWY!fkwC5bJMkhTp$J z6CNVLd=-Ktt7D<^-f|=wjNjf0l%@iu2dR+zdQ&9NLa(B_okKdRy^!Q!F$Ro=hF$-r z!3@ocUs^7?cvdTMPbn*8S-o!PsF;>FcBkBkg&ET`W`lp?j`Z}4>DF|}9407lK9y~^No&pT7J|rVQ9Dh>qg|%=gxxg=! z>WX$!;7s~gDPmPF<--(?CvEnvV*E1KdXpr>XVv!DN~PyISE7d+K_9+W^pnR6cX&?E ziLr{0`JIs@NcA|;8L|p!3H~9y8mga2Dsm4I?rBS7$3wcT!_l*$^8U3hKUri|_I3N2 zz$xY`)IWA7P*Y1BJtyBEh?8EEvs8Oyl^{(+`gi{9hwpcN#I%Z0j$^yBp?z<;Ny!G$ zra3J_^i0(~LiKuITs%v)qE+YrJr?~w+)`Rcte^O=nwmPg@&!Q7FGTtjpTdI6wH&ZV z)2}VZY6(MbP`tgoew++(pt$jVj- zvPK)pSJ)U(XfUqBqZNo|za#Xx+IVEb?HGQ^wUVH&wTdWgP(z#ijyvXjwk>tFBUn*2 zuj5ENQjT{2&T`k;q54*Z>O~djuUBNwc6l(BzY?Ed4SIt9QA&8+>qaRIck?WdD0rh@ zh`VTZPwSNNCcLH3J}(q zdEtu@HfxDTpEqWruG=86m;QVO{}E&q8qYWhmA>(FjW`V&rg!CEL1oZCZcAX@yX(2tg8`>m1psG0ZpO+Rnph@Bhjj!~|+S=@+U{*ukwGrBj{5xfIHHP7|} z^7@g2;d%FMO8f(MS&6c##mrX2i(5uiX1o(=Vw89IQcHw)n{ZTS@``xT$Af@CQTP#w zl3kn6+MJP+l(;K-rWgjpdBU|CB4>W%cObZBH^Am~EvRO%D>uU^HVRXi$1 zb?Pr~ZlopLfT5l%03SjI7>YiGZZs=n(A!c;N9%%aByY~5(-hS4z_i2wgKYsG%OhhxH#^5i%&9ESb(@# zV_f5${Gf=$BK)1VY=NX#f+M}6f`OWmpC*OU3&+P@n>$Xvco*Nm$c<=`S|lY6S}Ut- z80}ztIpkV>W%^Ox`enpk<25_i7`RPiDugxHfUDBD8$bp9XR15>a?r^#&!1Ne6n{MI z){H`!jwrx}8b-w@@E8H0v)l!5!W8En=u67v+`iNoz<_h4{V*qQK+@)JP^JqsKAedZ zNh4toE+I7;^}7kkj|hzNVFWkZ$N9rxPl9|_@2kbW*4}&o%(L`WpQCN2M?gz>cyWHk zulMwRxpdpx+~P(({@%UY20LwM7sA&1M|`bEoq)Id zyUHt>@vfu**UOL9wiW*C75cc&qBX37qLd`<;$gS+mvL^v3Z8i4p6(@Wv`N|U6Exn< zd`@WxqU^8u^Aw+uw#vuDEIByaD)vucU2{4xRseczf_TJXUwaUK+E_IoItXJq88${0 z=K5jGehPa2)CnH&Lcxv&1jQ=T8>*vgp1^%)c&C2TL69;vSN)Q)e#Hj7!oS0 zlrEmJ=w4N9pID5KEY5qz;?2Q}0|4ESEio&cLrp221LTt~j3KjUB`LU?tP=p;B=WSXo;C?8(pnF6@?-ZD0m3DYZ* z#SzaXh|)hmTC|zQOG>aEMw%4&2XU?prlk5(M3ay-YC^QLRMN+TIB*;TB=wL_atpeD zh-!sS%A`3 z=^?niQx+^za_wQd2hRR=hsR0uzUoyOcrY!z7W)G2|C-_gqc`wrG5qCuU!Z?g*GL^H z?j^<_-A6BC^Dp`p(i0!1&?U{YlF@!|W{E@h=qQ&5*|U~V8wS;m!RK(Q6aX~oH9ToE zZYKXZoRV~!?P1ADJ74J-PFk2A{e&gh2o)@yZOZuBi^0+Hkp`dX;cZs9CRM+##;P!*BlA%M48TuR zWUgfD1DLsLs+-4XC>o>wbv-B)!t*47ON5wgoMX%llnmXG%L8209Vi;yZ`+N2v2Ox+ zMe7JHunQE$ckHHhEYRA+e`A3=XO5L%fMau71`XL7v)b{f1rkTY+WWSIkH#sG=pLqe zA(xZIp>_=4$zKq0t_G7q9@L zZ5D-0{8o%7f>0szA#c;rjL;4Y%hl}wYrx1R`Viq|Pz}c-{{LJY070ym@E~mt*pTyG z79bfcWTGGEje;PLD;N-XHw=`wS^howfzb$%oP8n)lN$o$ZWjZx|6iSsi2piI_7s7z zX#b$@z6kIJ^9{-Y^~wJ!s0V^Td5V7#4&pyU#NHw#9)N&qbpNFDR1jqC00W}91OnnS z{$J@GBz%bka`xsz;rb_iJ|rgmpUVyEZ)Xi*SO5U&|NFkTHb3y@e@%{WrvE&Jp#Lw^ zcj13CbsW+V>i@rj@SEfFf0@yjS@nbPB0)6D`lA;e%61nh`-qhydO!uS7jXGQd%i7opEnOL;| zDn!3EUm(V796;f?fA+RDF<@%qKlo)`0VtL74`!~516_aogYP%QfG#<2kQ!pijthz2 zpaFX3|D$%C7!bL242U?-e@2QZ`q$~lgZbvgfLLyVfT1OC5<8@6lLi=A{stK#zJmWd zlx+(HbgX)l$RGwH|2rV@P3o@xCrxch0$*z1ASpy(n+d4d2XWd~2AYjQm`xZU3af8F p+x$Nxf1895@0bJirXkdpJh+N7@Nb7x007(DEB&^Lm}dWn{T~m64-^0Z diff --git a/plugin/gradle/wrapper/gradle-wrapper.properties b/module-plugin/gradle/wrapper/gradle-wrapper.properties similarity index 80% rename from plugin/gradle/wrapper/gradle-wrapper.properties rename to module-plugin/gradle/wrapper/gradle-wrapper.properties index 19cfad969b..3e4f5ac115 100644 --- a/plugin/gradle/wrapper/gradle-wrapper.properties +++ b/module-plugin/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Sat Aug 10 16:25:55 CEST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plugin/gradlew b/module-plugin/gradlew similarity index 100% rename from plugin/gradlew rename to module-plugin/gradlew diff --git a/plugin/gradlew.bat b/module-plugin/gradlew.bat similarity index 100% rename from plugin/gradlew.bat rename to module-plugin/gradlew.bat diff --git a/adapters/CitizensAdapter/settings.gradle.kts b/module-plugin/settings.gradle.kts similarity index 53% rename from adapters/CitizensAdapter/settings.gradle.kts rename to module-plugin/settings.gradle.kts index e78a7a1839..78f574b162 100644 --- a/adapters/CitizensAdapter/settings.gradle.kts +++ b/module-plugin/settings.gradle.kts @@ -1,9 +1,8 @@ -rootProject.name = "CitizensAdapter" - -includeBuild("../../plugin") +rootProject.name = "module-plugin" plugins { id("com.gradle.enterprise") version ("3.13.3") + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } gradleEnterprise { @@ -12,3 +11,6 @@ gradleEnterprise { termsOfServiceAgree = "yes" } } +include("extension-processor") +includeBuild("../engine") +include("api") diff --git a/module-plugin/src/main/kotlin/com/typewritermc/TypewriterModulePlugin.kt b/module-plugin/src/main/kotlin/com/typewritermc/TypewriterModulePlugin.kt new file mode 100644 index 0000000000..b0ff635c88 --- /dev/null +++ b/module-plugin/src/main/kotlin/com/typewritermc/TypewriterModulePlugin.kt @@ -0,0 +1,108 @@ +package com.typewritermc + +import com.google.devtools.ksp.gradle.KspExtension +import com.typewritermc.moduleplugin.TypewriterModuleConfiguration +import com.typewritermc.moduleplugin.validate +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import org.gradle.api.GradleException +import org.gradle.api.Plugin +import org.gradle.api.Project +import java.util.* + +class TypewriterModulePlugin : Plugin { + override fun apply(project: Project) { + project.pluginManager.apply("com.google.devtools.ksp") + + val extension = project.extensions.create("typewriter", TypewriterModuleConfiguration::class.java) + + project.checkExtension(extension) + + project.registerRepositories(extension) + project.registerKsp(extension) + } + + /** + * Checks if the extension is valid. + */ + private fun Project.checkExtension(extension: TypewriterModuleConfiguration) { + afterEvaluate { + try { + extension.validate() + } catch (e: Exception) { + throw GradleException("Invalid module configuration for $name", e) + } + } + } + + /** + * Registers repositories that are required for typewriter to work. + */ + private fun Project.registerRepositories(extension: TypewriterModuleConfiguration) = afterEvaluate { + // Add Maven Central repository + repositories.mavenCentral() + + extension.engine?.let { engine -> + // Add Typewriter repository + engine.channel.url?.let { url -> + repositories.maven { + it.setUrl(url) + } + } + // Add Typewriter dependency + dependencies.add("compileOnly", "com.typewritermc:engine-core:${engine.version}") + } + + + // Add PacketEvents repository + repositories.maven { + it.setUrl("https://repo.codemc.io/repository/maven-snapshots/") + } + // Add EntityLib repository + repositories.maven { + it.setUrl("https://maven.evokegames.gg/snapshots") + } + + if (extension.extension?.paper != null) { + extension.engine?.let { engine -> + // Add Typewriter Paper dependency + dependencies.add("compileOnly", "com.typewritermc:engine-paper:${engine.version}") + // Add Paper repository + repositories.maven { + it.setUrl("https://repo.papermc.io/repository/maven-public/") + } + // Add Geyser repository + repositories.maven { + it.setUrl("https://repo.opencollab.dev/maven-snapshots/") + } + } + } + } + + private fun Project.registerKsp(configuration: TypewriterModuleConfiguration) { + val pluginVersion = getPluginVersion() + dependencies.add("ksp", "com.typewritermc.module-plugin:extension-processor:$pluginVersion") + + afterEvaluate { + extensions.configure(KspExtension::class.java) { + it.arg( + "configuration", + Base64.getEncoder().encodeToString(Json.encodeToString(configuration).toByteArray()) + ) + it.arg("pluginVersion", pluginVersion) + it.arg("version", version.toString()) + } + } + } + + private fun getPluginVersion(): String { + val props = Properties().apply { + this@TypewriterModulePlugin::class.java.classLoader.getResourceAsStream("typewriter-module-plugin.properties") + ?.use { stream -> + load(stream) + } ?: throw IllegalStateException("Could not load properties") + } + val version = props.getProperty("version") + return version ?: "0.0.0" + } +} \ No newline at end of file diff --git a/plugin/settings.gradle.kts b/plugin/settings.gradle.kts deleted file mode 100644 index 4b94b7d580..0000000000 --- a/plugin/settings.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -rootProject.name = "typewriter" - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/plugin/src/main/kotlin/lirand/api/extensions/inventory/ItemExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/inventory/ItemExtensions.kt deleted file mode 100644 index 6ea9556141..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/inventory/ItemExtensions.kt +++ /dev/null @@ -1,72 +0,0 @@ -package lirand.api.extensions.inventory - -import lirand.api.extensions.server.server -import lirand.api.nbt.NbtData -import lirand.api.nbt.tagNbtData -import org.bukkit.Material -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.BookMeta -import org.bukkit.inventory.meta.ItemMeta -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract - -fun ItemStack(material: Material, amount: Int = 1, nbtData: NbtData): ItemStack { - return ItemStack(material, amount).apply { - this.tagNbtData = nbtData - } -} - - -fun ItemMeta(material: Material): T { - val meta = server.itemFactory.getItemMeta(material) - return meta as T -} - - -@JvmName("typedMeta") -@OptIn(ExperimentalContracts::class) -inline fun ItemStack.meta(builder: T.() -> Unit): ItemStack { - contract { - callsInPlace(builder, InvocationKind.EXACTLY_ONCE) - } - - itemMeta = ((itemMeta as T?) ?: ItemMeta(type)).apply(builder) - return this -} - -@OptIn(ExperimentalContracts::class) -inline fun ItemStack.meta(builder: ItemMeta.() -> Unit): ItemStack { - contract { - callsInPlace(builder, InvocationKind.EXACTLY_ONCE) - } - - return meta(builder) -} - -val BookMeta.content: String - get() = buildString { - for (it in pages) { - if (isNotEmpty()) - append('\n') - append(it) - } - } - - -val ItemStack?.isEmpty: Boolean get() = this == null || type == Material.AIR -val ItemStack?.isNotEmpty: Boolean get() = !isEmpty - -val Material.isPickaxe: Boolean get() = name.endsWith("_PICKAXE") -val Material.isSword: Boolean get() = name.endsWith("_SWORD") -val Material.isAxe: Boolean get() = name.endsWith("_AXE") -val Material.isSpade: Boolean get() = name.endsWith("_SPADE") -val Material.isHoe: Boolean get() = name.endsWith("_HOE") -val Material.isHelmet: Boolean get() = name.endsWith("_HELMET") -val Material.isChestplate: Boolean get() = name.endsWith("_CHESTPLATE") -val Material.isLeggings: Boolean get() = name.endsWith("_LEGGINGS") -val Material.isBoots: Boolean get() = name.endsWith("_BOOTS") -val Material.isOre: Boolean get() = name.endsWith("_ORE") -val Material.isIngot: Boolean get() = name.endsWith("_INGOT") -val Material.isDoor: Boolean get() = name.endsWith("_DOOR") -val Material.isMinecart: Boolean get() = name.endsWith("_MINECART") \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt deleted file mode 100644 index 63fac33858..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/math/MathExtensions.kt +++ /dev/null @@ -1,122 +0,0 @@ -package lirand.api.extensions.math - -import org.bukkit.Axis -import org.bukkit.Location -import org.bukkit.World -import org.bukkit.util.Vector - -/* - * LOCATION - */ - -operator fun Location.component1() = x -operator fun Location.component2() = y -operator fun Location.component3() = z -operator fun Location.component4() = yaw -operator fun Location.component5() = pitch - -fun Location(world: World?, x: Number, y: Number, z: Number) = Location(world, x.toDouble(), y.toDouble(), z.toDouble()) - -// extensions -fun Location.add(x: Number = 0.0, y: Number = 0.0, z: Number = 0.0) = add(x.toDouble(), y.toDouble(), z.toDouble()) -fun Location.subtract(x: Number = 0.0, y: Number = 0.0, z: Number = 0.0) = - subtract(x.toDouble(), y.toDouble(), z.toDouble()) - - -operator fun Location.get(axis: Axis): Double { - return when (axis) { - Axis.X -> x - Axis.Y -> y - Axis.Z -> z - } -} - -operator fun Location.set(axis: Axis, value: Number) { - when (axis) { - Axis.X -> x = value.toDouble() - Axis.Y -> y = value.toDouble() - Axis.Z -> z = value.toDouble() - } -} - - -val Location.blockLocation: Location get() = Location(world, blockX, blockY, blockZ) - -// operator functions -// immutable -operator fun Location.plus(vector: Vector) = clone().add(vector) -operator fun Location.minus(vector: Vector) = clone().subtract(vector) -operator fun Location.plus(location: Location) = clone().add(location) -operator fun Location.minus(location: Location) = clone().subtract(location) - -// mutable -operator fun Location.plusAssign(vector: Vector) { - add(vector) -} - -operator fun Location.minusAssign(vector: Vector) { - subtract(vector) -} - -operator fun Location.plusAssign(location: Location) { - add(location) -} - -operator fun Location.minusAssign(location: Location) { - subtract(location) -} - -/* - * VECTOR - */ - -operator fun Vector.component1() = x -operator fun Vector.component2() = y -operator fun Vector.component3() = z - -val Vector.isFinite: Boolean get() = x.isFinite() && y.isFinite() && z.isFinite() - -// fast construct -fun Vector(x: Number = 0.0, y: Number = 0.0, z: Number = 0.0) = Vector(x.toDouble(), y.toDouble(), z.toDouble()) - -// extensions -operator fun Vector.get(axis: Axis): Double { - return when (axis) { - Axis.X -> x - Axis.Y -> y - Axis.Z -> z - } -} - -operator fun Vector.set(axis: Axis, value: Number) { - when (axis) { - Axis.X -> x = value.toDouble() - Axis.Y -> y = value.toDouble() - Axis.Z -> z = value.toDouble() - } -} - - -// operator functions -// immutable -operator fun Vector.plus(vector: Vector) = clone().add(vector) -operator fun Vector.minus(vector: Vector) = clone().subtract(vector) -operator fun Vector.times(vector: Vector) = clone().multiply(vector) -operator fun Vector.times(number: Number) = clone().multiply(number.toDouble()) - -// mutable -operator fun Vector.plusAssign(vector: Vector) { - add(vector) -} - -operator fun Vector.minusAssign(vector: Vector) { - subtract(vector) -} - -operator fun Vector.timesAssign(vector: Vector) { - multiply(vector) -} - -operator fun Vector.timesAssign(number: Number) { - multiply(number.toDouble()) -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/other/ConfigurationExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/other/ConfigurationExtensions.kt deleted file mode 100644 index 26a421755e..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/other/ConfigurationExtensions.kt +++ /dev/null @@ -1,39 +0,0 @@ -package lirand.api.extensions.other - -import org.bukkit.configuration.ConfigurationSection - -fun ConfigurationSection.putAll(map: Map) { - for ((key, value) in map) { - if (value is Map<*, *>) { - set(key, null) - (getConfigurationSection(key) ?: createSection(key)).putAll(value as Map) - } - else { - set(key, value) - } - } -} - -/** - * @returns the count of absent values that was set, if returns 0, no values was set to the Configuration - */ -fun ConfigurationSection.putAllIfAbsent(map: Map): Int { - var missing = 0 - for ((key, value) in map) { - if (value is Map<*, *>) { - missing += (getConfigurationSection(key) ?: createSection(key)).putAllIfAbsent(value as Map) - } - else if (!contains(key)) { - missing++ - } - } - return missing -} - -fun ConfigurationSection.toMap(): Map { - return getValues(false).onEach { (key, value) -> - if (value is ConfigurationSection) { - set(key, value.toMap()) - } - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandController.kt b/plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandController.kt deleted file mode 100644 index 2e241a5409..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandController.kt +++ /dev/null @@ -1,32 +0,0 @@ -package lirand.api.extensions.server.commands - -import lirand.api.LirandAPI -import lirand.api.extensions.server.registerEvents -import org.bukkit.command.Command -import org.bukkit.event.EventHandler -import org.bukkit.event.Listener -import org.bukkit.event.server.PluginDisableEvent -import org.bukkit.plugin.Plugin - -internal fun provideCommandController(plugin: Plugin) = LirandAPI.instances[plugin]?.commandController - - -internal class CommandController(val plugin: Plugin) : Listener { - - val commands = mutableListOf() - - - fun initialize() { - plugin.registerEvents(this) - } - - - @EventHandler - fun onPluginDisableEvent(event: PluginDisableEvent) { - if (event.plugin != plugin) return - - commands.forEach { - it.unregister(plugin) - } - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandExtensions.kt deleted file mode 100644 index e4effc7044..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/server/commands/CommandExtensions.kt +++ /dev/null @@ -1,54 +0,0 @@ -package lirand.api.extensions.server.commands - -import lirand.api.extensions.server.server -import org.bukkit.command.Command -import org.bukkit.command.CommandSender -import org.bukkit.command.SimpleCommandMap -import org.bukkit.plugin.Plugin -import java.lang.reflect.Field - -private val serverCommands: SimpleCommandMap by lazy { - server::class.java.getDeclaredField("commandMap").apply { - isAccessible = true - }.get(server) as SimpleCommandMap -} - -private val knownCommandsField: Field by lazy { - SimpleCommandMap::class.java.getDeclaredField("knownCommands").apply { - isAccessible = true - } -} - -fun Command.register(plugin: Plugin) { - serverCommands.register(plugin.name, this) - - val commands = provideCommandController(plugin)?.commands ?: return - commands.add(this) -} - -fun Command.unregister(plugin: Plugin) { - try { - val knownCommands = knownCommandsField.get(serverCommands) as MutableMap - val toRemove = ArrayList() - for ((key, value) in knownCommands) { - if (value === this) { - toRemove.add(key) - } - } - for (name in toRemove) { - knownCommands.remove(name) - } - - provideCommandController(plugin)?.commands?.removeIf { it === this } - } catch (e: Exception) { - e.printStackTrace() - } -} - -/** - * Dispatches the command given by [commandLine]. - * - * @param commandLine the command without a leading / - */ -fun CommandSender.dispatchCommand(commandLine: String) = - server.dispatchCommand(this, commandLine) \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/world/BlockExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/world/BlockExtensions.kt deleted file mode 100644 index b61e0b5fbc..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/world/BlockExtensions.kt +++ /dev/null @@ -1,55 +0,0 @@ -package lirand.api.extensions.world - -import org.bukkit.Material -import org.bukkit.block.Block -import org.bukkit.block.BlockState -import org.bukkit.block.data.BlockData -import org.bukkit.entity.Player -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract - -operator fun Block.component1() = x -operator fun Block.component2() = y -operator fun Block.component3() = z - - -fun Block.equalsType(block: Block) = type == block.type -fun Block.equalsType(data: BlockData) = type == data.material && blockData == data -fun Block.equalsType(material: Material) = type == material - - -@JvmName("typedState") -@OptIn(ExperimentalContracts::class) -inline fun Block.state(builder: T.() -> Unit): Block { - contract { - callsInPlace(builder, InvocationKind.EXACTLY_ONCE) - } - - (state as T).apply(builder).update(true) - return this -} - -@OptIn(ExperimentalContracts::class) -inline fun Block.state(builder: BlockState.() -> Unit): Block { - contract { - callsInPlace(builder, InvocationKind.EXACTLY_ONCE) - } - - return state(builder) -} - - -fun Block.sendBlockChange( - blockData: BlockData, - players: List -) { - players.filter { it.world.name == world.name }.forEach { - it.sendBlockChange(location, blockData) - } -} - -fun Block.sendBlockChange( - material: Material, - players: List -) = sendBlockChange(material.createBlockData(), players) \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/world/EntityExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/world/EntityExtensions.kt deleted file mode 100644 index bc770d5989..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/world/EntityExtensions.kt +++ /dev/null @@ -1,23 +0,0 @@ -package lirand.api.extensions.world - -import org.bukkit.World -import org.bukkit.entity.Entity -import org.bukkit.entity.Firework -import org.bukkit.entity.Projectile -import org.bukkit.inventory.meta.FireworkMeta -import org.bukkit.projectiles.ProjectileSource -import org.bukkit.util.Vector - - -inline fun Firework.meta(crossinline block: FireworkMeta.() -> Unit) = apply { - fireworkMeta = fireworkMeta.apply(block) -} - -inline fun ProjectileSource.launchProjectile() = launchProjectile(T::class.java) -inline fun ProjectileSource.launchProjectile(vector: Vector) = - launchProjectile(T::class.java, vector) - - -inline fun World.getEntitiesByClass(): Collection { - return getEntitiesByClass(E::class.java) -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/world/LocationExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/world/LocationExtensions.kt deleted file mode 100644 index 336f52ea37..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/world/LocationExtensions.kt +++ /dev/null @@ -1,102 +0,0 @@ -package lirand.api.extensions.world - -import org.bukkit.BlockChangeDelegate -import org.bukkit.Effect -import org.bukkit.Location -import org.bukkit.Particle -import org.bukkit.Sound -import org.bukkit.SoundCategory -import org.bukkit.TreeType -import org.bukkit.block.data.BlockData -import org.bukkit.entity.AbstractArrow -import org.bukkit.entity.Entity -import org.bukkit.inventory.ItemStack -import org.bukkit.util.Vector - -fun Location.dropItem(item: ItemStack) = - world!!.dropItem(this, item) - -fun Location.dropItemNaturally(item: ItemStack) = - world!!.dropItemNaturally(this, item) - - -fun Location.spawnArrow(direction: Vector, speed: Float, spread: Float) = - world!!.spawnArrow(this, direction, speed, spread) - - -fun Location.generateTree(type: TreeType) = - world!!.generateTree(this, type) ?: false - -fun Location.generateTree(type: TreeType, delegate: BlockChangeDelegate) = - world!!.generateTree(this, type, delegate) ?: false - - -fun Location.strikeLightning() = - world!!.strikeLightning(this) - -fun Location.strikeLightningEffect() = - world!!.strikeLightningEffect(this) - -fun Location.getNearbyEntities(x: Double, y: Double, z: Double): Collection? = - world!!.getNearbyEntities(this, x, y, z) - - -fun Location.createExplosion(power: Float) = - world!!.createExplosion(this, power) ?: false - -fun Location.createExplosion(power: Float, setFire: Boolean) = - world!!.createExplosion(this, power, setFire) ?: false - - -inline fun Location.spawn(noinline builder: (E.() -> Unit)?) = - world!!.spawn(this, E::class.java, builder) - - -fun Location.spawnFallingBlock(blockData: BlockData) = - world!!.spawnFallingBlock(this, blockData) - -inline fun Location.spawnArrow(direction: Vector, speed: Float, spread: Float): A? = - world!!.spawnArrow(this, direction, speed, spread, A::class.java) - - -fun Location.playEffect(effect: Effect, data: Int) = - world!!.playEffect(this, effect, data) - -fun Location.playEffect(effect: Effect, data: Int, radius: Int) = - world!!.playEffect(this, effect, data, radius) - -fun Location.playEffect(effect: Effect, data: T) = - world!!.playEffect(this, effect, data) - -fun Location.playEffect(effect: Effect, data: T, radius: Int) = - world!!.playEffect(this, effect, data, radius) - - -/** - * Plays the sound at the location. It - * will be audible for everyone near it. - */ -fun Location.playSound( - sound: Sound, - category: SoundCategory = SoundCategory.MASTER, - volume: Float = 1f, - pitch: Float = 1f -) = world!!.playSound(this, sound, category, volume, pitch) - -/** - * Spawns the particle at the location. It - * will be visible for everyone near it. - */ -fun Location.spawnParticle( - particle: Particle, - amount: Int = 1, - offset: Vector = Vector(), - extra: Number = 1.0, - data: BlockData? = null, - force: Boolean = false -) = world!!.spawnParticle( - particle, this, amount, - offset.x, offset.y, offset.z, - extra.toDouble(), - data, force -) \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt b/plugin/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt deleted file mode 100644 index 928faf7182..0000000000 --- a/plugin/src/main/kotlin/lirand/api/extensions/world/PlayerExtensions.kt +++ /dev/null @@ -1,85 +0,0 @@ -package lirand.api.extensions.world - -import org.bukkit.Effect -import org.bukkit.Instrument -import org.bukkit.Location -import org.bukkit.Note -import org.bukkit.Particle -import org.bukkit.Sound -import org.bukkit.SoundCategory -import org.bukkit.block.data.BlockData -import org.bukkit.entity.Player -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.PlayerInventory -import org.bukkit.plugin.Plugin -import org.bukkit.util.Vector - -fun PlayerInventory.clearArmor() { - setArmorContents(arrayOfNulls(4)) -} - -fun PlayerInventory.clearAll() { - clear() - clearArmor() -} - -fun Player.playSound( - sound: Sound, - category: SoundCategory = SoundCategory.MASTER, - volume: Float = 1f, - pitch: Float = 1f -) = playSound(location, sound, category, volume, pitch) - -fun Player.playNote(instrument: Instrument, note: Note) { - playNote(location, instrument, note) -} - -fun Player.spawnParticle( - particle: Particle, - location: Location, - amount: Int = 1, - offset: Vector = Vector(), - extra: Number = 1.0, - data: BlockData? = null -) = spawnParticle( - particle, location, amount, - offset.x, offset.y, offset.z, - extra.toDouble(), data -) - -fun Player.playEffect(effect: Effect, data: T? = null) { - playEffect(location, effect, data) -} - - -/** - * Hides the player for all onlinePlayers. - */ -fun Player.disappear(plugin: Plugin) { - server.onlinePlayers - .filter { it != this } - .forEach { it.hidePlayer(plugin, this) } -} - -/** - * Shows the player for all onlinePlayers. - */ -fun Player.appear(plugin: Plugin) { - server.onlinePlayers - .filter { it != this } - .forEach { it.showPlayer(plugin, this) } -} - -/** - * Hides all online players from this player. - */ -fun Player.hideOnlinePlayers(plugin: Plugin) { - server.onlinePlayers.filter { it != this }.forEach { hidePlayer(plugin, it) } -} - -/** - * Shows all online players to this player. - */ -fun Player.showOnlinePlayers(plugin: Plugin) { - server.onlinePlayers.filter { it != this }.forEach { showPlayer(plugin, it) } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/NbtData.kt b/plugin/src/main/kotlin/lirand/api/nbt/NbtData.kt deleted file mode 100644 index d6e1f60bfd..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/NbtData.kt +++ /dev/null @@ -1,200 +0,0 @@ -package lirand.api.nbt - -inline fun nbtData(crossinline builder: NbtData.() -> Unit) = NbtData().apply(builder) - - -class NbtData internal constructor(nbtTagCompound: Any?) { - internal val nbtTagCompound: Any = nbtTagCompound ?: nbtCompoundConstructor.newInstance() - - @Suppress("UNCHECKED_CAST") - private val map: MutableMap = nbtCompoundMapField.get(this.nbtTagCompound) as MutableMap - - constructor() : this(null) - constructor(nbtString: String) : this(mojangParseMethod.invoke(null, nbtString)) - - - /** - * Gives access to change [NbtData] values of certain generic types. - */ - val tag = NbtDataAccessor(this) - - /** - * Returns a [Set] of all keys in this nbt. - */ - val keys: Set get() = map.keys - - - /** - * Gets the value - * at the given [key]. The returned [dataType] - * must be specified. - * The returned value is null, if it - * was not possible to find any value at - * the specified location, or if the type - * is not the one which was specified. - */ - operator fun get(key: String, dataType: NbtDataType): T? { - val value = map[key] ?: return null - - return dataType.decode(value) - } - - /** - * Gets the nbt value (NBTBase subtype) - * at the given [key]. - * The returned value is null, if it - * was not possible to find any value at - * the specified location. - */ - fun getNbtTag(key: String): Any? { - return map[key] - } - - /** - * Gets the value - * at the given [key]. The returned [dataType] - * must be specified. - * If it was not possible to find any value at - * the specified location, or if the type - * is not the one which was specified, - * the result of calling [defaultValue] was put into specified location. - */ - inline fun getOrSet(key: String, dataType: NbtDataType, defaultValue: () -> T): T { - return get(key, dataType) ?: defaultValue().also { - set(key, dataType, it) - } - } - - /** - * Gets the value - * at the given [key]. The returned [dataType] - * must be specified. - * The returned value is the result of calling [defaultValue], - * if it was not possible to find any value at - * the specified location, or if the type - * is not the one which was specified. - */ - inline fun getOrDefault(key: String, dataType: NbtDataType, defaultValue: () -> T): T { - return get(key, dataType) ?: defaultValue() - } - - /** - * Sets some [value] - * at the position of the given [key]. - * The [dataType] of the given [value] - * must be specified. - */ - operator fun set(key: String, dataType: NbtDataType, value: T) { - map[key] = dataType.encode(value) - } - - /** - * Sets some NBT [value] (NBTBase subtype) - * at the position of the given [key]. - */ - fun setNbtTag(key: String, value: Any) { - map[key] = value - } - - - /** - * Puts all values from [nbtData] - * to this [NbtData]. - */ - fun putAll(nbtData: NbtData) { - map.putAll(nbtData.map.toMap()) - } - - /** - * Removes the - * given [key] from the NBTTagCompound. - * Its value will be lost. - */ - fun remove(key: String) { - map.remove(key) - } - - /** - * @see remove - */ - operator fun minusAssign(key: String) = remove(key) - - /** - * Clears this [NbtData]. - */ - fun clear() { - map.clear() - } - - - /** - * Gets type id of the value under the provided [key]. - */ - fun getTypeId(key: String): Int? { - if (key !in this) return null - - return (nbtBaseGetTypeIdMethod.invoke(map[key]) as Byte).toInt() - } - - - /** - * Returns `true` if the nbt contains the specified [key]. - */ - operator fun contains(key: String): Boolean { - return map.containsKey(key) - } - - /** - * Returns `true` if the nbt contains the specified [key] of [type]. - */ - fun containsKeyOfType(key: String, type: NbtDataType<*>): Boolean { - return getTypeId(key) == type.typeId - } - - /** - * Returns `true` if the nbt contains the specified [key] of [typeId]. - */ - fun containsKeyOfType(key: String, typeId: Int): Boolean { - return getTypeId(key) == typeId - } - - - override fun toString(): String { - return nbtTagCompound.toString() - } - - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as NbtData - - if (nbtTagCompound != other.nbtTagCompound) return false - - return true - } - - override fun hashCode(): Int { - return nbtTagCompound.hashCode() - } -} - - -internal val nmsPackage = run { - "net.minecraft.nbt" -} - -internal val nbtCompoundClass = Class.forName("$nmsPackage.NBTTagCompound") - -private val mojangParseMethod = Class.forName("$nmsPackage.MojangsonParser").methods - .find { - it.returnType == nbtCompoundClass && it.parameterTypes.let { - it.size == 1 && it[0] == String::class.java - } - }!! -internal val nbtCompoundConstructor = nbtCompoundClass.getConstructor() - -private val nbtCompoundMapField = nbtCompoundClass.declaredFields - .find { it.type == MutableMap::class.java }!! - .apply { isAccessible = true } \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataAccessor.kt b/plugin/src/main/kotlin/lirand/api/nbt/NbtDataAccessor.kt deleted file mode 100644 index 41f81a8fe7..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataAccessor.kt +++ /dev/null @@ -1,88 +0,0 @@ -package lirand.api.nbt - -import kotlinx.serialization.SerializationException -import kotlinx.serialization.serializer -import lirand.api.nbt.serialization.NbtRootDecoder -import lirand.api.nbt.serialization.NbtRootEncoder - -/** - * Gives access to change [NbtData] values of certain generic types. - */ -class NbtDataAccessor(@PublishedApi internal val nbtData: NbtData) { - - - /** - * Gets the value at the given [key] - * or throws an [IllegalStateException] if it - * was not possible to find any value - * at the given [key], or if its type - * is not [T]. - */ - inline operator fun get(key: String): T { - return getOrNull(key) - ?: error("There is no value under the \"$key\" key or its type is not specified generic type") - } - - /** - * @see get - */ - inline operator fun invoke(key: String): T { - return get(key) - } - - /** - * Gets the value at the given [key]. - * The returned value is null if it - * was not possible to find any value - * at the given [key], or if its type - * is not [T]. - */ - inline fun getOrNull(key: String): T? { - val dataType = NbtDataType.getFor() ?: run { - val encoder = NbtRootDecoder(nbtData, key) - return try { - encoder.decodeSerializableValue(serializer()) - } catch (_: SerializationException) { - null - } - } - return nbtData[key, dataType] - } - - /** - * Gets the value at the given [key]. - * If it was not possible to find any value - * at the given [key], or if its type is not [T], - * the result of calling [defaultValue] was put into specified location. - */ - inline fun getOrSet(key: String, defaultValue: () -> T): T { - return getOrNull(key) ?: defaultValue().also { - set(key, it) - } - } - - /** - * Gets the value at the given [key]. - * The returned value is [defaultValue], if it - * was not possible to find any value - * at the given [key], or if the type - * is not [T]. - */ - inline fun getOrDefault(key: String, defaultValue: () -> T): T { - return getOrNull(key) ?: defaultValue() - } - - - /** - * Sets some [value] - * at the position of the given [key]. - */ - inline operator fun set(key: String, value: T) { - val dataType = NbtDataType.getFor() ?: run { - val encoder = NbtRootEncoder(nbtData, key) - encoder.encodeSerializableValue(serializer(), value) - return - } - nbtData[key, dataType] = value - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataLoader.kt b/plugin/src/main/kotlin/lirand/api/nbt/NbtDataLoader.kt deleted file mode 100644 index 26d8813a88..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataLoader.kt +++ /dev/null @@ -1,60 +0,0 @@ -package lirand.api.nbt - -import lirand.api.extensions.server.craftBukkitPackage -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.ItemMeta - -val ItemStack.nbtData: NbtData - get() { - val itemStack = asNMSCopyMethod.invoke(null, this) - - val nbtTagCompound = nbtCompoundConstructor.newInstance() - return NbtData(minecraftItemStackSaveMethod.invoke(itemStack, nbtTagCompound)) - } - - -var ItemStack.tagNbtData: NbtData - get() { - val itemStack = asNMSCopyMethod.invoke(null, this) - - return NbtData(minecraftItemStackTagField.get(itemStack)) - } - set(value) { - val nmsItemStack = (asNMSCopyMethod.invoke(null, this)).apply { - minecraftItemStackSetTagMethod.invoke(this, value.nbtTagCompound) - } - itemMeta = getItemMetaMethod.invoke(null, nmsItemStack) as ItemMeta - } - -private val craftItemStackClass = - Class.forName("$craftBukkitPackage.inventory.CraftItemStack") - -private val asNMSCopyMethod = - craftItemStackClass.getMethod("asNMSCopy", ItemStack::class.java) - -private val getItemMetaMethod = craftItemStackClass.methods - .find { method -> - method.name == "getItemMeta" && method.parameterTypes.let { - it.size == 1 && it[0] == asNMSCopyMethod.returnType - } - }!! - -private val minecraftItemStackClass = asNMSCopyMethod.returnType - -private val minecraftItemStackTagField = minecraftItemStackClass.declaredFields - .find { it.type == nbtCompoundClass }!! - .apply { isAccessible = true } - -private val minecraftItemStackSetTagMethod = minecraftItemStackClass.methods - .find { method -> - method.returnType == Void.TYPE && method.parameterTypes.let { - it.size == 1 && it[0] == nbtCompoundClass - } - }!! - -private val minecraftItemStackSaveMethod = minecraftItemStackClass.methods - .find { method -> - method.returnType == nbtCompoundClass && method.parameterTypes.let { - it.size == 1 && it[0] == nbtCompoundClass - } - }!! \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataSerializer.kt b/plugin/src/main/kotlin/lirand/api/nbt/NbtDataSerializer.kt deleted file mode 100644 index e9d10d302e..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataSerializer.kt +++ /dev/null @@ -1,67 +0,0 @@ -package lirand.api.nbt - -import lirand.api.extensions.inventory.Inventory -import lirand.api.extensions.inventory.ItemStack -import org.bukkit.Material -import org.bukkit.event.inventory.InventoryType -import org.bukkit.inventory.Inventory -import org.bukkit.inventory.InventoryHolder -import org.bukkit.inventory.ItemStack - -fun Inventory.getSerializableNbtData(title: String? = null): NbtData { - return nbtData { - tag["type"] = type.toString().lowercase() - - if (type == InventoryType.CHEST) - tag["size"] = size - - if (title != null) - tag["title"] = title - - tag["Items"] = mapIndexedNotNull { index, itemStack -> - itemStack?.let { - nbtData { - tag["Slot"] = index.toByte() - tag["ItemStack"] = itemStack.nbtData - } - } - } - } -} - - -fun NbtData.deserializeItemStack(): ItemStack { - return ItemStack( - Material.matchMaterial(tag["id"]) ?: error("Invalid material id"), - tag.getOrDefault("Count") { 1 }.toInt(), - tag.get("tag"), - ) -} - -fun NbtData.deserializeInventory( - owner: InventoryHolder? = null, - title: String? = null -): Inventory { - val type = InventoryType.valueOf(tag.get("type").uppercase()) - - val size = if (type == InventoryType.CHEST) tag.get("size") else -1 - - val resultTitle = title ?: tag.getOrNull("title") - - val resultInventory = if (type == InventoryType.CHEST) - Inventory(size, owner, resultTitle) - else - Inventory(type, owner, resultTitle) - - val itemStacksNbt = tag.get>("Items") - - return resultInventory.apply { - for (itemStackNbt in itemStacksNbt) { - setItem( - itemStackNbt.tag.getOrNull("Slot")?.toInt() ?: continue, - itemStackNbt.tag.getOrNull("ItemStack")?.deserializeItemStack() - ) - } - } -} - diff --git a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataType.kt b/plugin/src/main/kotlin/lirand/api/nbt/NbtDataType.kt deleted file mode 100644 index dc1d8fdbf7..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/NbtDataType.kt +++ /dev/null @@ -1,345 +0,0 @@ -package lirand.api.nbt - -import java.lang.reflect.Constructor -import java.lang.reflect.Method -import java.lang.reflect.Modifier -import kotlin.reflect.KClass -import kotlin.reflect.KType -import kotlin.reflect.KVariance -import kotlin.reflect.full.isSubtypeOf -import kotlin.reflect.typeOf - -sealed interface NbtDataType { - - val typeId: Int - - fun decode(nbt: Any): T? - - fun encode(data: T): Any - - - companion object { - /** - * Gets [NbtDataType] of the corresponding [T] type. - */ - @Suppress("UNCHECKED_CAST") - inline fun getFor(): NbtDataType? { - return getFor(typeOf()) as NbtDataType? - } - - /** - * Gets [NbtDataType] of the corresponding value. - */ - @Suppress("UNCHECKED_CAST") - fun getFor(value: T): NbtDataType? { - return when (value) { - is NbtData -> NbtCompoundType - is String -> NbtStringType - is Char -> NbtCharType - is Byte -> NbtByteType - is Boolean -> NbtBooleanType - is Short -> NbtShortType - is Int -> NbtIntType - is Long -> NbtLongType - is Float -> NbtFloatType - is Double -> NbtDoubleType - is ByteArray -> NbtByteArrayType - is IntArray -> NbtIntArrayType - is LongArray -> NbtLongArrayType - is Collection<*> -> { - if ((value as Collection).isNotEmpty()) - NbtListType(getFor(value.first()) ?: return null) - else - NbtListType(NbtByteType) - } - else -> null - } as NbtDataType? - } - - /** - * Gets [NbtDataType] of the corresponding [nbtTag]. - */ - @Suppress("UNCHECKED_CAST") - fun getForTag(nbtTag: Any): NbtDataType<*>? { - return when (getNbtTypeId(nbtTag)) { - 10 -> NbtCompoundType - 8 -> NbtStringType - 1 -> NbtByteType - 2 -> NbtShortType - 3 -> NbtIntType - 4 -> NbtLongType - 5 -> NbtFloatType - 6 -> NbtDoubleType - 7 -> NbtByteArrayType - 11 -> NbtIntArrayType - 12 -> NbtLongArrayType - 9 -> { - if ((nbtTag as List).isNotEmpty()) - NbtListType(getForTag(nbtTag.first()) ?: return null) - else - NbtListType(NbtByteType) - } - else -> null - } - } - - @PublishedApi - internal fun getFor(type: KType): NbtDataType<*>? { - return when (type.classifier) { - NbtData::class -> NbtCompoundType - String::class -> NbtStringType - Char::class -> NbtCharType - Byte::class -> NbtByteType - Boolean::class -> NbtBooleanType - Short::class -> NbtShortType - Int::class -> NbtIntType - Long::class -> NbtLongType - Float::class -> NbtFloatType - Double::class -> NbtDoubleType - ByteArray::class -> NbtByteArrayType - IntArray::class -> NbtIntArrayType - LongArray::class -> NbtLongArrayType - else -> { - if (!type.isSubtypeOf(typeOf>())) return null - - val innerType = type.arguments.firstOrNull() - ?.takeIf { it.variance != KVariance.IN } - ?.type - ?: return null - - NbtListType(getFor(innerType) ?: return null) - } - } - } - } -} - - -abstract class AbstractNbtDataType(override val typeId: Int) : NbtDataType { - final override fun decode(nbt: Any): T? { - return if (getNbtTypeId(nbt) == typeId) - decodeCorrectlyTyped(nbt) - else - null - } - - protected abstract fun decodeCorrectlyTyped(nbt: Any): T? - - override fun toString(): String { - return this::class.simpleName ?: "NbtDataType" - } -} - - -object NbtCompoundType : AbstractNbtDataType(10) { - override fun encode(data: NbtData): Any { - return data.nbtTagCompound - } - - override fun decodeCorrectlyTyped(nbt: Any): NbtData { - return NbtData(nbt) - } -} - -object NbtStringType : AbstractNbtDataType(8) { - override fun encode(data: String): Any { - return stringTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): String { - return (nbtStringAsStringMethod.invoke(nbt) as String).removeSurrounding("\"") - } -} - -object NbtCharType : AbstractNbtDataType(8) { - override fun encode(data: Char): Any { - return stringTagFactoryMethod.invoke(null, data.toString()) - } - - override fun decodeCorrectlyTyped(nbt: Any): Char? { - return (nbtStringAsStringMethod.invoke(nbt) as String).removeSurrounding("\"").singleOrNull() - } -} - -object NbtByteType : AbstractNbtDataType(1) { - override fun encode(data: Byte): Any { - return byteTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): Byte { - return nbtNumberAsByteMethod.invoke(nbt) as Byte - } -} - -object NbtBooleanType : AbstractNbtDataType(1) { - override fun encode(data: Boolean): Any { - return NbtByteType.encode(if (data) 1 else 0) - } - - override fun decodeCorrectlyTyped(nbt: Any): Boolean? { - val byte = NbtByteType.decode(nbt)?.takeIf { it in 0..1 } ?: return null - return byte > 0 - } -} - -object NbtShortType : AbstractNbtDataType(2) { - override fun encode(data: Short): Any { - return shortTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): Short { - return nbtNumberAsShortMethod.invoke(nbt) as Short - } -} - -object NbtIntType : AbstractNbtDataType(3) { - override fun encode(data: Int): Any { - return intTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): Int { - return nbtNumberAsIntMethod.invoke(nbt) as Int - } -} - -object NbtLongType : AbstractNbtDataType(4) { - override fun encode(data: Long): Any { - return longTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): Long { - return nbtNumberAsLongMethod.invoke(nbt) as Long - } -} - -object NbtFloatType : AbstractNbtDataType(5) { - override fun encode(data: Float): Any { - return floatTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): Float { - return nbtNumberAsFloatMethod.invoke(nbt) as Float - } -} - -object NbtDoubleType : AbstractNbtDataType(6) { - override fun encode(data: Double): Any { - return doubleTagFactoryMethod.invoke(null, data) - } - - override fun decodeCorrectlyTyped(nbt: Any): Double { - return nbtNumberAsDoubleMethod.invoke(nbt) as Double - } - -} - -object NbtByteArrayType : AbstractNbtDataType(7) { - override fun encode(data: ByteArray): Any { - return byteArrayTagConstructor.newInstance(data) - } - - override fun decodeCorrectlyTyped(nbt: Any): ByteArray { - return nbtByteArrayGetBytesMethod.invoke(nbt) as ByteArray - } -} - -object NbtIntArrayType : AbstractNbtDataType(11) { - override fun encode(data: IntArray): Any { - return intArrayTagConstructor.newInstance(data) - } - - override fun decodeCorrectlyTyped(nbt: Any): IntArray { - return nbtIntArrayGetIntsMethod.invoke(nbt) as IntArray - } -} - -object NbtLongArrayType : AbstractNbtDataType(12) { - override fun encode(data: LongArray): Any { - return longArrayTagConstructor.newInstance(data) - } - - override fun decodeCorrectlyTyped(nbt: Any): LongArray { - return nbtLongArrayGetLongsMethod.invoke(nbt) as LongArray - } -} - -@Suppress("UNCHECKED_CAST") -class NbtListType(val innerType: NbtDataType) : AbstractNbtDataType>(9) { - override fun encode(data: Collection): Any { - return (nbtListConstructor.newInstance() as MutableList).apply { - addAll(data.map { innerType.encode(it) }) - } - } - - override fun decodeCorrectlyTyped(nbt: Any): List { - val list = nbt as MutableList - - return list.map { innerType.decode(it)!! } - } - - override fun toString(): String { - return "NbtListType($innerType)" - } -} - - -private fun getNbtTypeId(nbtTag: Any): Int { - return (nbtBaseGetTypeIdMethod.invoke(nbtTag) as Byte).toInt() -} - -private val byteTagFactoryMethod = getTagFactoryMethod("NBTTagByte", Byte::class) -private val shortTagFactoryMethod = getTagFactoryMethod("NBTTagShort", Short::class) -private val intTagFactoryMethod = getTagFactoryMethod("NBTTagInt", Int::class) -private val longTagFactoryMethod = getTagFactoryMethod("NBTTagLong", Long::class) -private val floatTagFactoryMethod = getTagFactoryMethod("NBTTagFloat", Float::class) -private val doubleTagFactoryMethod = getTagFactoryMethod("NBTTagDouble", Double::class) -private val stringTagFactoryMethod = getTagFactoryMethod("NBTTagString", String::class) - -private fun getTagFactoryMethod(className: String, argumentType: KClass<*>): Method { - val clazz = Class.forName("${nmsPackage}.$className") - - return clazz.methods.find { - it.returnType == clazz && Modifier.isStatic(it.modifiers) - && it.parameterTypes.let { it.size == 1 && it[0] == argumentType.java } - }!! -} - - -private val nbtListConstructor = Class.forName("${nmsPackage}.NBTTagList").getConstructor() - -private val byteArrayTagConstructor = getTagConstructor("NBTTagByteArray", ByteArray::class) -private val intArrayTagConstructor = getTagConstructor("NBTTagIntArray", IntArray::class) -private val longArrayTagConstructor = getTagConstructor("NBTTagLongArray", LongArray::class) - -private fun getTagConstructor(className: String, dataArgumentClass: KClass<*>): Constructor<*> { - val clazz = Class.forName("${nmsPackage}.$className") - - return clazz.getConstructor(dataArgumentClass.java) -} - - - -private val nbtNumberClass = Class.forName("${nmsPackage}.NBTNumber") - -private val nbtNumberAsByteMethod = getDecodeMethod(nbtNumberClass, Byte::class) -private val nbtNumberAsDoubleMethod = getDecodeMethod(nbtNumberClass, Double::class) -private val nbtNumberAsFloatMethod = getDecodeMethod(nbtNumberClass, Float::class) -private val nbtNumberAsIntMethod = getDecodeMethod(nbtNumberClass, Int::class) -private val nbtNumberAsLongMethod = getDecodeMethod(nbtNumberClass, Long::class) -private val nbtNumberAsShortMethod = getDecodeMethod(nbtNumberClass, Short::class) -private val nbtByteArrayGetBytesMethod = getDecodeMethod("NBTTagByteArray", ByteArray::class) -private val nbtIntArrayGetIntsMethod = getDecodeMethod("NBTTagIntArray", IntArray::class) -private val nbtLongArrayGetLongsMethod = getDecodeMethod("NBTTagLongArray", LongArray::class) -private val nbtStringAsStringMethod = getDecodeMethod("NBTTagString", String::class) - -private fun getDecodeMethod(clazz: Class<*>, returnType: KClass<*>): Method { - return clazz.methods.find { it.returnType == returnType.java && it.parameterCount == 0 }!! -} - -private fun getDecodeMethod(className: String, returnType: KClass<*>): Method { - return getDecodeMethod(Class.forName("${nmsPackage}.$className"), returnType) -} - - -internal val nbtBaseGetTypeIdMethod = Class.forName("${nmsPackage}.NBTBase").methods - .find { it.returnType == Byte::class.java && it.parameterCount == 0 }!! \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataDecoder.kt b/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataDecoder.kt deleted file mode 100644 index e6f99cdf9c..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataDecoder.kt +++ /dev/null @@ -1,158 +0,0 @@ -package lirand.api.nbt.serialization - -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.SerializationException -import kotlinx.serialization.descriptors.PolymorphicKind -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.descriptors.StructureKind -import kotlinx.serialization.encoding.AbstractDecoder -import kotlinx.serialization.encoding.CompositeDecoder -import kotlinx.serialization.modules.SerializersModule -import lirand.api.nbt.* - -@OptIn(ExperimentalSerializationApi::class) -abstract class AbstractNbtDecoder(protected val nbt: Nbt) : AbstractDecoder() { - override val serializersModule: SerializersModule = nbt.serializersModule - - private var nextNullable: Any? = null - - - - @Suppress("UNCHECKED_CAST") - override fun decodeSerializableValue(deserializer: DeserializationStrategy): T { - val nbtDataType = getNbtDataType(deserializer.descriptor) - return if (nbtDataType != null && nbtDataType is NbtListType<*> && nbtDataType.innerType !is NbtCompoundType) - decodeValue() as T - else - super.decodeSerializableValue(deserializer) - } - - - override fun decodeValue(): Any { - val value = nextNullable ?: next() - nextNullable = null - - return NbtDataType.getForTag(value)?.decode(value) - ?: throw SerializationException("NbtDataType not found for current value") - } - - abstract fun next(): Any - - - @Suppress("UNCHECKED_CAST") - override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder { - return if (descriptor.kind !is StructureKind.LIST) { - NbtDataDecoder(decodeValue() as NbtData, nbt) - } - else { - NbtListDecoder(next() as List, nbt) - } - } - - - override fun decodeNotNullMark(): Boolean { - return (next() as? List<*>)?.let { - if (it.isEmpty()) { - false - } - else { - nextNullable = it[0] - true - } - } ?: true - } - - override fun decodeNull(): Nothing? { - nextNullable = null - return null - } -} - -class NbtRootDecoder( - private val nbtData: NbtData, - private val key: String? = null, - nbt: Nbt = Nbt -) : AbstractNbtDecoder(nbt) { - - override fun next(): Any { - return key?.let { nbtData.getNbtTag(it) } ?: nbtData.nbtTagCompound - } - - override fun decodeElementIndex(descriptor: SerialDescriptor): Int { - return 0 - } -} - - -@OptIn(ExperimentalSerializationApi::class) -class NbtDataDecoder( - val nbtData: NbtData, - nbt: Nbt = Nbt -) : AbstractNbtDecoder(nbt) { - private lateinit var currentElement: Any - private var currentIndex = 0 - - - override fun next(): Any { - return currentElement - } - - override fun decodeElementIndex(descriptor: SerialDescriptor): Int { - while (currentIndex < descriptor.elementsCount) { - val name = descriptor.getElementName(currentIndex++) - nbtData.getNbtTag(name)?.let { - currentElement = it - return currentIndex - 1 - } - } - return CompositeDecoder.DECODE_DONE - } - - override fun decodeCollectionSize(descriptor: SerialDescriptor): Int { - return nbtData.keys.size - } - - override fun endStructure(descriptor: SerialDescriptor) { - if (nbt.configuration.ignoreUnknownKeys || descriptor.kind is PolymorphicKind) return - - val names = (0 until descriptor.elementsCount).map { descriptor.getElementName(it) }.distinct() - for (key in nbtData.keys) { - if (key !in names) { - throw SerializationException("Unknown key: $key") - } - } - } -} - -@ExperimentalSerializationApi -class NbtListDecoder( - val list: List, - nbt: Nbt = Nbt -) : AbstractNbtDecoder(nbt) { - private val iterator = list.iterator() - private var currentIndex = 0 - - override fun next(): Any { - return iterator.next().also { - currentIndex++ - } - } - - override fun decodeElementIndex(descriptor: SerialDescriptor): Int { - return if (iterator.hasNext()) { - currentIndex + 1 - } - else { - CompositeDecoder.DECODE_DONE - } - } - - override fun decodeCollectionSize(descriptor: SerialDescriptor): Int { - return list.size - } - - override fun decodeSequentially(): Boolean { - return true - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataEncoder.kt b/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataEncoder.kt deleted file mode 100644 index 3adbfd030a..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtDataEncoder.kt +++ /dev/null @@ -1,155 +0,0 @@ -package lirand.api.nbt.serialization - -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.SerializationException -import kotlinx.serialization.SerializationStrategy -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.descriptors.StructureKind -import kotlinx.serialization.descriptors.elementDescriptors -import kotlinx.serialization.encoding.AbstractEncoder -import kotlinx.serialization.encoding.CompositeEncoder -import lirand.api.nbt.* -import java.util.* - -@OptIn(ExperimentalSerializationApi::class) -abstract class AbstractNbtEncoder(protected val nbt: Nbt) : AbstractEncoder() { - override val serializersModule = nbt.serializersModule - - protected var isNextNullable = false - - - @Suppress("UNCHECKED_CAST") - override fun encodeSerializableValue(serializer: SerializationStrategy, value: T) { - val nbtDataType = getNbtDataType(serializer.descriptor) - if (value != null && nbtDataType != null && nbtDataType is NbtListType<*> && nbtDataType.innerType !is NbtCompoundType) - encodeValue(value) - else - super.encodeSerializableValue(serializer, value) - } - - override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder { - return if (descriptor.kind !is StructureKind.LIST) { - NbtDataEncoder(NbtData(), this::consumeStructure, nbt) - } - else { - NbtListEncoder(this::consumeStructure, nbt) - } - } - - override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) { - encodeValue(enumDescriptor.getElementName(index)) - } - - override fun encodeNotNullMark() { - isNextNullable = true - } - - override fun shouldEncodeElementDefault(descriptor: SerialDescriptor, index: Int): Boolean { - return nbt.configuration.encodeDefaults - } - - - abstract fun consumeStructure(descriptor: SerialDescriptor, nbtData: NbtData) - - abstract fun consumeStructure(descriptor: SerialDescriptor, nbtList: List) -} - -class NbtRootEncoder( - val nbtData: NbtData = NbtData(), - val redirectKey: String? = null, - nbt: Nbt = Nbt -) : AbstractNbtEncoder(nbt) { - - override fun encodeValue(value: Any) { - check(redirectKey != null) { "redirectKey must be specified" } - - val dataType = NbtDataType.getFor(value) - require(dataType != null) { "Unknown data type of provided value" } - - nbtData[redirectKey, dataType] = value - } - - override fun consumeStructure(descriptor: SerialDescriptor, nbtData: NbtData) { - if (redirectKey == null) { - this.nbtData.clear() - this.nbtData.putAll(nbtData) - } - else { - this.nbtData[redirectKey, NbtCompoundType] = nbtData - } - } - - @Suppress("UNCHECKED_CAST") - override fun consumeStructure(descriptor: SerialDescriptor, nbtList: List) { - check(redirectKey != null) { "redirectKey must be specified" } - - nbtData[redirectKey, getNbtDataType(descriptor) as NbtDataType] = nbtList - } -} - - -@OptIn(ExperimentalSerializationApi::class) -class NbtDataEncoder( - val nbtData: NbtData, - private val consumer: (SerialDescriptor, NbtData) -> Unit, - nbt: Nbt = Nbt -) : AbstractNbtEncoder(nbt) { - private val keys = ArrayDeque() - - override fun encodeElement(descriptor: SerialDescriptor, index: Int): Boolean { - keys.push(descriptor.getElementName(index)) - return true - } - - override fun encodeValue(value: Any) { - NbtDataType.getFor(value)?.let { - if (isNextNullable) { - isNextNullable = false - nbtData[keys.pop(), NbtListType(it)] = listOf(value) - } - else - nbtData[keys.pop(), it] = value - } - } - - override fun encodeNull() { - nbtData[keys.pop(), NbtListType(NbtByteType)] = emptyList() - } - - override fun endStructure(descriptor: SerialDescriptor) { - consumer(descriptor, nbtData) - } - - override fun consumeStructure(descriptor: SerialDescriptor, nbtData: NbtData) { - this.nbtData[keys.pop(), NbtCompoundType] = nbtData - } - - @Suppress("UNCHECKED_CAST") - override fun consumeStructure(descriptor: SerialDescriptor, nbtList: List) { - this.nbtData[keys.pop(), getNbtDataType(descriptor) as NbtDataType] = nbtList - } -} - - -class NbtListEncoder( - private val consumer: (SerialDescriptor, List) -> Unit, - nbt: Nbt = Nbt -) : AbstractNbtEncoder(nbt) { - private val list = mutableListOf() - - override fun encodeValue(value: Any) { - list.add(value) - } - - override fun endStructure(descriptor: SerialDescriptor) { - consumer(descriptor, list) - } - - override fun consumeStructure(descriptor: SerialDescriptor, nbtData: NbtData) { - list.add(nbtData) - } - - override fun consumeStructure(descriptor: SerialDescriptor, nbtList: List) { - list.add(nbtList) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtSerialization.kt b/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtSerialization.kt deleted file mode 100644 index 891535ee64..0000000000 --- a/plugin/src/main/kotlin/lirand/api/nbt/serialization/NbtSerialization.kt +++ /dev/null @@ -1,140 +0,0 @@ -package lirand.api.nbt.serialization - -import kotlinx.serialization.* -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.descriptors.StructureKind -import kotlinx.serialization.descriptors.elementDescriptors -import kotlinx.serialization.modules.EmptySerializersModule -import kotlinx.serialization.modules.SerializersModule -import lirand.api.nbt.* - - -/** - * Represents [NbtData] serialization settings. - */ -sealed class Nbt( - val configuration: NbtConfiguration, - val serializersModule: SerializersModule -) { - - companion object Default : Nbt(NbtConfiguration(), EmptySerializersModule()) - - - inline fun encodeToNbtData(value: T, redirectKey: String? = null): NbtData { - return encodeToNbtData(serializer(), value, redirectKey) - } - - inline fun encodeToNbtData( - serializer: SerializationStrategy, - value: T, - redirectKey: String? = null - ): NbtData { - val encoder = NbtRootEncoder(NbtData(), redirectKey, this) - encoder.encodeSerializableValue(serializer, value) - return encoder.nbtData - } - - - inline fun decodeFromNbtData(nbtData: NbtData, key: String? = null): T { - return decodeFromNbtData(serializer(), nbtData, key) - } - - inline fun decodeFromNbtData( - deserializer: DeserializationStrategy, - nbtData: NbtData, - key: String? = null - ): T { - val decoder = NbtRootDecoder(nbtData, key, this) - return decoder.decodeSerializableValue(deserializer) - } -} - -/** - * Creates an instance of [Nbt] configured from the optionally given [Nbt] instance and adjusted with [builderAction]. - */ -fun Nbt(from: Nbt = Nbt.Default, builderAction: NbtBuilder.() -> Unit): Nbt { - val builder = NbtBuilder(from) - builder.builderAction() - val configuration = builder.build() - return NbtImpl(configuration, builder.serializersModule) -} - -private class NbtImpl( - configuration: NbtConfiguration, - serializersModule: SerializersModule -) : Nbt(configuration, serializersModule) - - - -/** - * Configuration of the current [Nbt] instance available through [Nbt.configuration] - * and configured with [NbtBuilder] constructor. - * - * Can be used for debug purposes and for custom Json-specific serializers - * via [NbtDataEncoder] and [NbtDataDecoder]. - * - * Standalone configuration object is meaningless and can nor be used outside of the - * [Nbt], neither new [Nbt] instance can be created from it. - * - * Detailed description of each property is available in [NbtBuilder] class. - */ -data class NbtConfiguration( - val encodeDefaults: Boolean = false, - val ignoreUnknownKeys: Boolean = false -) - -/** - * Builder of the [Nbt] instance provided by `Nbt { ... }` factory function. - */ -class NbtBuilder internal constructor(nbt: Nbt) { - /** - * Module with contextual and polymorphic serializers to be used in the resulting [Nbt] instance. - */ - var serializersModule: SerializersModule = nbt.serializersModule - - /** - * Specifies whether default values of Kotlin properties should be encoded. - * `false` by default. - */ - var encodeDefaults: Boolean = nbt.configuration.encodeDefaults - - /** - * Specifies whether encounters of unknown properties in the input JSON - * should be ignored instead of throwing [SerializationException]. - * `false` by default. - */ - var ignoreUnknownKeys: Boolean = nbt.configuration.ignoreUnknownKeys - - - fun build(): NbtConfiguration { - return NbtConfiguration(encodeDefaults, ignoreUnknownKeys) - } -} - - - - -@OptIn(ExperimentalSerializationApi::class) -internal fun getNbtDataType(descriptor: SerialDescriptor): NbtDataType<*>? { - return when (val kind = descriptor.kind) { - is StructureKind -> when (kind) { - is StructureKind.LIST -> { - NbtListType(getNbtDataType(descriptor.elementDescriptors.single()) as NbtDataType<*>) - } - else -> NbtCompoundType - } - is PrimitiveKind -> when (kind) { - is PrimitiveKind.STRING -> NbtStringType - is PrimitiveKind.CHAR -> NbtCharType - is PrimitiveKind.BYTE -> NbtByteType - is PrimitiveKind.BOOLEAN -> NbtBooleanType - is PrimitiveKind.SHORT -> NbtShortType - is PrimitiveKind.INT -> NbtIntType - is PrimitiveKind.LONG -> NbtLongType - is PrimitiveKind.FLOAT -> NbtFloatType - is PrimitiveKind.DOUBLE -> NbtDoubleType - } - else -> null - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/utilities/Reflection.kt b/plugin/src/main/kotlin/lirand/api/utilities/Reflection.kt deleted file mode 100644 index 36276bd1bb..0000000000 --- a/plugin/src/main/kotlin/lirand/api/utilities/Reflection.kt +++ /dev/null @@ -1,56 +0,0 @@ -package lirand.api.utilities - -import java.lang.reflect.Field -import java.lang.reflect.Method - - -val Class<*>.allFields: List - get() = buildList { - var currentClass: Class<*>? = this@allFields - while (currentClass != null) { - val declaredFields = currentClass.declaredFields - addAll(declaredFields) - currentClass = currentClass.superclass - } - } - -val Class<*>.allMethods: List - get() = buildList { - var currentClass: Class<*>? = this@allMethods - while (currentClass != null) { - val declaredMethods = currentClass.declaredMethods - addAll(declaredMethods) - currentClass = currentClass.superclass - } - } - -val Class<*>.superclasses: List> - get() = buildList { - var currentClass: Class<*>? = this@superclasses - while (true) { - val superClass = currentClass?.superclass ?: break - add(superClass) - currentClass = superClass - } - } - - -val Method.isOverridden: Boolean - get() { - val declaringClass: Class<*> = declaringClass - if (declaringClass == Any::class.java) { - return false - } - else try { - declaringClass.superclass.getMethod(name, *parameterTypes) - return true - } catch (_: NoSuchMethodException) { - declaringClass.interfaces.forEach { - try { - it.getMethod(name, *parameterTypes) - return true - } catch (_: NoSuchMethodException) {} - } - return false - } - } \ No newline at end of file diff --git a/plugin/src/main/kotlin/lirand/api/utilities/Scope.kt b/plugin/src/main/kotlin/lirand/api/utilities/Scope.kt deleted file mode 100644 index 03f6bbc0b9..0000000000 --- a/plugin/src/main/kotlin/lirand/api/utilities/Scope.kt +++ /dev/null @@ -1,32 +0,0 @@ -package lirand.api.utilities - -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract - -@OptIn(ExperimentalContracts::class) -inline fun Boolean.ifTrue(block: () -> Unit): Boolean { - contract { - callsInPlace(block, InvocationKind.AT_MOST_ONCE) - } - - if (this) block() - return this -} - -@OptIn(ExperimentalContracts::class) -inline fun Boolean.ifFalse(block: () -> Unit): Boolean { - contract { - callsInPlace(block, InvocationKind.AT_MOST_ONCE) - } - - if (!this) block() - return this -} - -fun T.applyIfNotNull(block: (T.() -> Unit)?): T { - if (block != null) - apply(block) - - return this -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterListeners.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterListeners.kt deleted file mode 100644 index 95c1051e40..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterListeners.kt +++ /dev/null @@ -1,83 +0,0 @@ -package me.gabber235.typewriter.adapters - -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.Entry -import org.bukkit.event.Event -import org.bukkit.event.EventPriority -import java.lang.reflect.* -import java.lang.reflect.Modifier -import kotlin.reflect.KClass - -data class AdapterListener( - val method: Method, - val entry: KClass, - val generators: List, - val priority: EventPriority, - val ignoreCancelled: Boolean, -) - -sealed interface ParameterGenerator { - fun isApplicable(parameter: Parameter): Boolean - fun generate(event: Event, adapterListener: AdapterListener): Any - - data object EventParameterGenerator : ParameterGenerator { - override fun isApplicable(parameter: Parameter): Boolean { - // It and all superclasses must be Event - return Event::class.java.isAssignableFrom(parameter.type) - } - - override fun generate(event: Event, adapterListener: AdapterListener): Any = event - } - - data object QueryParameterGenerator : ParameterGenerator { - override fun isApplicable(parameter: Parameter): Boolean { - // It can only be Query - return parameter.type.isAssignableFrom(Query::class.java) - } - - override fun generate(event: Event, adapterListener: AdapterListener): Any = Query(adapterListener.entry) - } - - companion object { - private val generators = listOf(EventParameterGenerator, QueryParameterGenerator) - - private fun getGenerator(parameter: Parameter): ParameterGenerator? { - return generators.firstOrNull { it.isApplicable(parameter) } - } - - /** - * Creates a list of ParameterGenerators for the given method. - * @throws IllegalArgumentException if the parameter is not applicable to any generator - */ - @Throws(IllegalArgumentException::class) - fun getGenerators(parameters: Array): List { - return parameters.map { parameter -> - getGenerator(parameter) - ?: throw IllegalArgumentException("There is no way to create a parameter for ${parameter.name} (${parameter.type}) in ${parameter.declaringExecutable}") - } - } - } -} - - -object AdapterListeners { - - private fun constructAdapterListener(method: Method): AdapterListener { - val annotation = method.getAnnotation(EntryListener::class.java) - val entry = annotation.entry - val parameters = method.parameters - val generators = ParameterGenerator.getGenerators(parameters) - return AdapterListener(method, entry, generators, annotation.priority, annotation.ignoreCancelled) - } - - fun constructAdapterListeners(classes: List>): List { - // Go through all classes and find methods with the @EntryListener annotation - // Then construct an AdapterListener for each of them - return classes.asSequence() - .flatMap { it.methods.asSequence() } - .filter { Modifier.isStatic(it.modifiers) } - .filter { it.isAnnotationPresent(EntryListener::class.java) } - .map(::constructAdapterListener) - .toList() - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterLoader.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterLoader.kt deleted file mode 100644 index 621da86610..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterLoader.kt +++ /dev/null @@ -1,388 +0,0 @@ -package me.gabber235.typewriter.adapters - -import com.google.gson.GsonBuilder -import com.google.gson.JsonArray -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.entry.EntryMigrations -import me.gabber235.typewriter.entry.EntryMigrator -import me.gabber235.typewriter.entry.dialogue.DialogueMessenger -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.RuntimeTypeAdapterFactory -import me.gabber235.typewriter.utils.digits -import me.gabber235.typewriter.utils.get -import me.gabber235.typewriter.utils.rightPad -import org.koin.core.component.KoinComponent -import java.io.File -import java.net.URLClassLoader -import java.util.jar.JarEntry -import java.util.jar.JarFile -import kotlin.reflect.KClass -import kotlin.reflect.full.cast -import kotlin.reflect.full.companionObject -import kotlin.reflect.full.isSubclassOf - -private val gson = - GsonBuilder().registerTypeAdapterFactory( - RuntimeTypeAdapterFactory.of(FieldInfo::class.java, "kind") - .registerSubtype(PrimitiveField::class.java, "primitive") - .registerSubtype(EnumField::class.java, "enum") - .registerSubtype(ListField::class.java, "list") - .registerSubtype(MapField::class.java, "map") - .registerSubtype(ObjectField::class.java, "object") - .registerSubtype(CustomField::class.java, "custom") - ).enableComplexMapKeySerialization() - .create() - - -interface AdapterLoader { - val adapters: List - val adaptersJson: JsonArray - val loader: URLClassLoader? - - fun loadAdapters() - fun initializeAdapters() - fun shutdown() - fun getEntryBlueprint(type: String): EntryBlueprint? - - fun getEntryMigrators(): List -} - -class AdapterLoaderImpl : AdapterLoader, KoinComponent { - override var adapters = listOf() - override var adaptersJson: JsonArray = JsonArray() - - override var loader: URLClassLoader? = null - private set - - override fun loadAdapters() { - val dir = plugin.dataFolder["adapters"] - if (!dir.exists()) { - dir.mkdirs() - } - - val jars = dir.listFiles()?.filter { it.extension == "jar" } ?: listOf() - - loader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), plugin.javaClass.classLoader) - - adapters = jars.mapNotNull { - logger.info("Loading adapter ${it.nameWithoutExtension}") - try { - loadAdapter(it) - } catch (e: ClassNotFoundException) { - logger.warning("Failed to load adapter ${it.nameWithoutExtension}. Error: ${e.message}. This is likely due to a missing dependency. Skipping...") - e.printStackTrace() - null - } catch (e: Exception) { - logger.warning("Failed to load adapter ${it.nameWithoutExtension}. Skipping...") - e.printStackTrace() - null - } - } - - val jsonArray = JsonArray() - - adapters.forEach { - jsonArray.add(gson.toJsonTree(it)) - } - - if (adapters.isEmpty()) { - logger.warning( - """ - | - |${"-".repeat(15)}{ No Adapters Loaded }${"-".repeat(15)} - | - |No adapters were loaded. - |You should always have at least the BasicAdapter loaded. - | - |${"-".repeat(50)} - """.trimMargin() - ) - } else { - val unsupportedMessage = if (adapters.any { it.flags.contains(AdapterFlag.Unsupported) }) { - "\nThere are unsupported adapters loaded. You won't get any support for these.\n" - } else { - "" - } - - val maxAdapterLength = adapters.maxOf { it.name.length } - val maxVersionLength = adapters.maxOf { it.version.length } - val maxDigits = adapters.maxOf { it.entries.size.digits } - logger.info( - """ - | - |${"-".repeat(15)}{ Loaded Adapters }${"-".repeat(15)} - | - |${adapters.joinToString("\n") { it.displayString(maxAdapterLength, maxVersionLength, maxDigits) }} - |$unsupportedMessage - |${"-".repeat(50)} - """.trimMargin() - ) - } - - adaptersJson = jsonArray - } - - override fun initializeAdapters() { - adapters.forEach { - try { - it.adapter.initialize() - } catch (e: Exception) { - logger.warning("Failed to initialize adapter ${it.name}. Error: ${e.message}") - e.printStackTrace() - } - } - } - - override fun shutdown() { - adapters.forEach { - try { - it.adapter.shutdown() - } catch (e: Exception) { - logger.warning("Failed to shutdown adapter ${it.name}. Error: ${e.message}") - e.printStackTrace() - } - } - } - - fun instantiateAdapter(adapterClass: Class<*>): TypewriterAdapter { - if (!TypewriterAdapter::class.java.isAssignableFrom(adapterClass)) { - throw IllegalArgumentException("Adapter class must be a subclass of TypewriteAdapter") - } - val objectInstance = adapterClass.kotlin.objectInstance - if (objectInstance != null) { - return TypewriterAdapter::class.cast(objectInstance) - } - return adapterClass.getConstructor().newInstance() as TypewriterAdapter - } - - private val ignorePrefixes = listOf("kotlin", "java", "META-INF", "org/bukkit", "org/intellij", "org/jetbrains") - - private fun loadAdapter(file: File): AdapterData { - val classes = loadClasses(file) - - val adapterClass: Class<*> = classes.firstOrNull { it.hasAnnotation(Adapter::class) } - ?: throw IllegalArgumentException("No adapter class found in ${file.name}") - - val adapterInstance = instantiateAdapter(adapterClass) - - val entryClasses = classes.filter { it.hasAnnotation(Entry::class) } - val messengerClasses = classes.filter { it.hasAnnotation(Messenger::class) } - - return constructAdapter(classes, adapterClass, adapterInstance, entryClasses, messengerClasses) - } - - private fun constructAdapter( - classes: List>, - adapterClass: Class<*>, - adapterInstance: TypewriterAdapter, - entryClasses: List>, - messengerClasses: List>, - ): AdapterData { - val adapterAnnotation = adapterClass.getAnnotation(Adapter::class.java) - - val flags = constructFlags(adapterClass) - - // Entries info - val blueprints = constructEntryBlueprints(adapterAnnotation, entryClasses) - - // Messengers info - val messengers = constructMessengers(messengerClasses) - - val adapterListeners = AdapterListeners.constructAdapterListeners(classes) - - val entryMigrators = EntryMigrations.constructEntryMigrators(classes) - - // Create the adapter data - return AdapterData( - adapterAnnotation?.name ?: "", - adapterAnnotation?.description ?: "", - adapterAnnotation?.version ?: "", - flags, - blueprints, - messengers, - adapterListeners, - entryMigrators, - adapterClass, - adapterInstance, - ) - } - - private fun constructFlags(adapterClass: Class<*>): List { - val flags = mutableListOf() - - if (adapterClass.hasAnnotation(Untested::class)) { - flags.add(AdapterFlag.Untested) - } - if (adapterClass.isAnnotationPresent(Deprecated::class.java)) { - flags.add(AdapterFlag.Deprecated) - } - if (adapterClass.hasAnnotation(Unsupported::class)) { - flags.add(AdapterFlag.Unsupported) - } - - return flags - } - - private fun constructEntryBlueprints(adapter: Adapter, entryClasses: List>) = - entryClasses.filter { me.gabber235.typewriter.entry.Entry::class.java.isAssignableFrom(it) } - .map { it as Class } - .map { entryClass -> - val entryAnnotation = entryClass.getAnnotation(Entry::class.java) - - EntryBlueprint( - entryAnnotation.name, - entryAnnotation.description, - adapter.name, - ObjectField.fromTypeToken(TypeToken.get(entryClass)), - entryAnnotation.color, - entryAnnotation.icon, - getTags(entryClass), - entryClass, - ) - } - - private fun constructMessengers(messengerClasses: List>) = - messengerClasses.map { messengerClass -> - val messengerAnnotation = messengerClass.getAnnotation(Messenger::class.java) - - val filter = findFilterForMessenger(messengerClass) - - MessengerData( - messengerClass as Class>, - messengerAnnotation.dialogue.java, - filter as Class, - messengerAnnotation.priority, - ) - } - - //TODO: Make compatible with java. - private fun findFilterForMessenger(messengerClass: Class<*>) = - if (messengerClass.kotlin.companionObject?.isSubclassOf(MessengerFilter::class) == true) { - messengerClass.kotlin.companionObject!!.java - } else { - EmptyMessengerFilter::class.java - } - - private fun loadClasses(file: File): List> { - val loader = this.loader ?: throw IllegalStateException("Loader is not initialized") - val jarFile = JarFile(file) - val entries = jarFile.entries() - - val classes = mutableListOf>() - while (entries.hasMoreElements()) { - val entry = entries.nextElement() - if (isClassFile(entry) && notIgnored(entry)) { - val className = entry.name.replace("/", ".").substring(0, entry.name.length - 6) - classes.add(loader.loadClass(className)) - } - } - - return classes - } - - private fun Class<*>.hasAnnotation(annotation: KClass): Boolean { - return isAnnotationPresent(annotation.java) - } - - private fun notIgnored(entry: JarEntry) = ignorePrefixes.none { entry.name.startsWith(it) } - - private fun isClassFile(entry: JarEntry) = entry.name.endsWith(".class") - - override fun getEntryBlueprint(type: String): EntryBlueprint? { - return adapters.asSequence().flatMap { it.entries }.firstOrNull { it.name == type } - } - - override fun getEntryMigrators(): List { - return adapters.asSequence().flatMap { it.entryMigrators }.toList() - } -} - -data class AdapterData( - val name: String, - val description: String, - val version: String, - val flags: List, - val entries: List, - @Transient - val messengers: List, - @Transient - val eventListeners: List, - @Transient - val entryMigrators: List, - @Transient - val clazz: Class<*>, - @Transient - val adapter: TypewriterAdapter -) { - /** - * Returns a string that can be used to display information about the adapter. - * It is nicely formatted to align the information between adapters. - */ - fun displayString(maxAdapterLength: Int, maxVersionLength: Int, maxDigits: Int): String { - var display = "${name}Adapter".rightPad(maxAdapterLength + "Adapter".length) - display += " (${version})".rightPad(maxVersionLength + 2) - display += padCount("πŸ“š", entries.size, maxDigits) - display += padCount("πŸ‘‚", eventListeners.size, maxDigits) - display += padCount("πŸ’¬", messengers.size, maxDigits) - display += padCount("🚚", entryMigrators.size, maxDigits) - - flags.filter { it.warning.isNotBlank() }.joinToString { it.warning }.let { - if (it.isNotBlank()) { - display += " ($it)" - } - } - - return display - } - - private fun padCount(prefix: String, count: Int, maxDigits: Int): String { - return " ${prefix}: ${" ".repeat((maxDigits - count.digits).coerceAtLeast(0))}$count" - } -} - -enum class AdapterFlag(val warning: String) { - /** - * The adapter is not tested and may not work. - */ - Untested("⚠\uFE0F UNTESTED"), - - /** - * The adapter is deprecated and should not be used. - */ - Deprecated("⚠\uFE0F DEPRECATED"), - - /** - * The adapter is not supported and should be migrated away from. - */ - Unsupported("⚠\uFE0F UNSUPPORTED"), -} - -// Annotation for marking a class as an adapter -@Target(AnnotationTarget.CLASS) -annotation class Adapter( - val name: String, - val description: String, - val version: String, -) - -@Target(AnnotationTarget.CLASS) -annotation class Entry( - val name: String, - val description: String, - val color: String, // Hex color - val icon: String, // Any https://icon-sets.iconify.design/ icon -) - -@Target(AnnotationTarget.CLASS) -annotation class Messenger( - val dialogue: KClass, - val priority: Int = 0, -) - -@Target(AnnotationTarget.CLASS) -annotation class Untested - -@Target(AnnotationTarget.CLASS) -annotation class Unsupported diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterMessenger.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterMessenger.kt deleted file mode 100644 index f88cc044a0..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/AdapterMessenger.kt +++ /dev/null @@ -1,22 +0,0 @@ -package me.gabber235.typewriter.adapters - -import me.gabber235.typewriter.entry.dialogue.DialogueMessenger -import me.gabber235.typewriter.entry.entries.DialogueEntry -import org.bukkit.entity.Player - -class MessengerData( - val messenger: Class>, - val dialogue: Class, - val filter: Class, - val priority: Int -) - -interface MessengerFilter { - fun filter(player: Player, entry: DialogueEntry): Boolean -} - -class EmptyMessengerFilter : MessengerFilter { - override fun filter(player: Player, entry: DialogueEntry): Boolean { - return true - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/CustomEditors.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/CustomEditors.kt deleted file mode 100644 index 5af5842204..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/CustomEditors.kt +++ /dev/null @@ -1,249 +0,0 @@ -package me.gabber235.typewriter.adapters - -import com.google.gson.* -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.adapters.editors.* -import me.gabber235.typewriter.adapters.modifiers.StaticModifierComputer -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entity.SkinProperty -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.utils.Color -import me.gabber235.typewriter.utils.CronExpression -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.SoundId -import me.gabber235.typewriter.utils.SoundSource -import me.gabber235.typewriter.utils.Vector -import org.bukkit.Location -import org.bukkit.Material -import org.bukkit.potion.PotionEffectType -import java.lang.reflect.Type -import java.time.Duration -import java.util.* -import kotlin.reflect.KClass -import kotlin.reflect.KFunction -import kotlin.reflect.full.extensionReceiverParameter -import kotlin.reflect.full.findAnnotation - -typealias GsonDeserializer = (JsonElement, Type, JsonDeserializationContext) -> T -typealias GsonSerializer = (T, Type, JsonSerializationContext) -> JsonElement - -typealias FieInfoGenerator = (TypeToken<*>) -> FieldInfo - -typealias DefaultGenerator = (TypeToken<*>) -> JsonElement -typealias FieldModifierGenerator = (TypeToken<*>, FieldInfo) -> FieldModifier? - -@Target(AnnotationTarget.FUNCTION) -annotation class CustomEditor(val klass: KClass<*>) - - -class ObjectEditor(val klass: KClass, val name: String) { - - /** - * If the custom editor is implemented inside the visual interface. We will use this to indicate it. - * - * Example: - * ```kotlin - * @CustomEditor(SomeClass::class) - * fun ObjectEditor.some() = reference { - * // ... - * } - * ``` - * In this case, the editor name that will be used is `some`. - */ - fun reference(editor: ObjectEditor.() -> Unit) = editor() - - /** - * The deserializer used to convert a JSON string into an instance of the class represented by this editor. - * NOTE: This field is used internally and should not be accessed directly. - */ - internal var deserializer: JsonDeserializer? = null - private set - - /** - * If the default deserialization is not enough, you can use this method to provide a custom deserializer for this editor. - * - * Example: - * ```kotlin - * @CustomEditor(SomeClass::class) - * fun ObjectEditor.some() = reference { - * deserializer = JsonDeserializer { element, type, context -> - * // ... - * } - * // ... - * } - * ``` - * - * @param deserializer The deserializer to use. - */ - fun jsonDeserialize(deserializer: GsonDeserializer) { - this.deserializer = - JsonDeserializer { json, typeOfT, context -> deserializer(json, typeOfT, context) } - } - - /** - * The serializer used to convert an instance of the class represented by this editor into a JSON string. - * NOTE: This field is used internally and should not be accessed directly. - */ - internal var serializer: JsonSerializer? = null - private set - - /** - * If the default serialization is not enough, you can use this method to provide a custom serializer for this editor. - * Example: - * ```kotlin - * @CustomEditor(SomeClass::class) - * fun ObjectEditor.some() = reference { - * serializer = JsonSerializer { element, type, context -> - * // ... - * } - * // ... - * } - */ - fun jsonSerialize(serializer: GsonSerializer) { - this.serializer = - JsonSerializer { src, typeOfSrc, context -> serializer(src, typeOfSrc, context) } - } - - - /** - * Save the field info generator for this editor. - * NOTE: This field is used internally and should not be accessed directly. - */ - private var fieldInfoGenerator: FieInfoGenerator? = null - - /** - * If a custom editor needs to have some information about the specific field it is editing, it can use this method to - * provide a function that will generate the information. - * - * Example: - * ```kotlin - * @CustomEditor(SomeClass::class) - * fun ObjectEditor.some() = reference { - * fieldInfo { klass -> - * // ... - * } - * // ... - * } - * ``` - * - * @param generator The function that will generate the information. - */ - fun fieldInfo(generator: FieInfoGenerator) { - this.fieldInfoGenerator = generator - } - - - /** - * Generates the field info for this editor. - * NOTE: This method is used internally and should not be accessed directly. - * @param token The type token of the class represented by this editor. - */ - internal fun generateFieldInfo(token: TypeToken<*>): FieldInfo? { - return fieldInfoGenerator?.invoke(token) - } - - /** - * Save the default generator for this editor. - * NOTE: This field is used internally and should not be accessed directly. - */ - private var defaultGenerator: DefaultGenerator? = null - - /** - * Custom editors need a default value to be able to create new instance of the class they are editing. - * - * Example: - * ```kotlin - * @CustomEditor(SomeClass::class) - * fun ObjectEditor.some() = reference { - * default { token -> - * // ... - * } - * // ... - * } - * ``` - * - * @param generator The function that will generate the information. - */ - fun default(generator: DefaultGenerator) { - this.defaultGenerator = generator - } - - /** - * Generates the default value for this editor. - * NOTE: This method is used internally and should not be accessed directly. - * @param token The type token of the class represented by this editor. - */ - internal fun generateDefault(token: TypeToken<*>): JsonElement { - return defaultGenerator?.invoke(token) ?: JsonNull.INSTANCE - } - - /** - * Save the modifiers for this editor. - * NOTE: This field is used internally and should not be accessed directly. - */ - private val modifiers = mutableListOf() - - /** - * Adds a modifier to this editor. - */ - operator fun FieldModifier?.unaryPlus() { - if (this == null) return - modifiers.add { _, _ -> this } - } - - infix fun StaticModifierComputer.with(annotation: A) { - modifiers.add { _, info -> - this.computeModifier(annotation, info).onFailure { - logger.warning("Failed to compute modifier for ${this.annotationClass::class.simpleName} with annotation $annotation: $it") - return@add null - }.getOrNull() - } - } - - fun modifier(supplier: FieldModifierGenerator) { - modifiers.add(supplier) - } - - /** - * Generates the modifiers for this editor. - * NOTE: This method is used internally and should not be accessed directly. - */ - internal fun generateModifiers(token: TypeToken<*>, info: FieldInfo): List { - return modifiers.mapNotNull { it(token, info) } - } -} - -internal val customEditors by lazy { - listOf( - ObjectEditor::material, - ObjectEditor>::optional, - ObjectEditor::location, - ObjectEditor::duration, - ObjectEditor::cron, - ObjectEditor::potionEffectType, - ObjectEditor::item, - ObjectEditor::soundId, - ObjectEditor::soundSource, - ObjectEditor>::entryReference, - ObjectEditor::skin, - ObjectEditor::vector, - ObjectEditor::color, - ObjectEditor>::floatRange, - ) - .mapNotNull(::objectEditorFromFunction) - .associateBy { it.klass } -} - -private fun objectEditorFromFunction(function: KFunction<*>): ObjectEditor<*>? { - val annotation = function.findAnnotation() ?: return null - val extension = function.extensionReceiverParameter ?: return null - if (extension.type.classifier != ObjectEditor::class) return null - val klass = annotation.klass - val name = function.name - return ObjectEditor(klass, name).apply { function.call(this) } -} - - -fun computeCustomEditor(token: TypeToken<*>): ObjectEditor<*>? { - return customEditors[token.rawType.kotlin] -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryAttributes.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryAttributes.kt deleted file mode 100644 index 6d1b4968d8..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryAttributes.kt +++ /dev/null @@ -1,36 +0,0 @@ -package me.gabber235.typewriter.adapters - -@Target(AnnotationTarget.CLASS) -annotation class Tags(vararg val tags: String) - - -fun getTags(clazz: Class<*>): List { - val clazzTags = clazz.getAnnotation(Tags::class.java)?.tags?.toList() ?: emptyList() - val superClassTags = clazz.superclass?.let { getTags(it) } ?: emptyList() - val interfaceTags = clazz.interfaces.flatMap { getTags(it) } - - val generatedTags = mutableListOf() - if (clazz.isAnnotationPresent(Deprecated::class.java)) { - generatedTags.add("deprecated") - } - - return (clazzTags + superClassTags + interfaceTags + generatedTags).distinct() -} - -object Colors { - const val RED = "#D32F2F" - const val GREEN = "#4CAF50" - const val MEDIUM_SEA_GREEN = "#3CB371" - const val PALATINATE_BLUE = "#3366CC" - const val BLUE = "#1E88E5" - const val MYRTLE_GREEN = "#297373" - const val YELLOW = "#FBB612" - const val PURPLE = "#5843e6" - const val MEDIUM_PURPLE = "#9370DB" - const val BLUE_VIOLET = "#8A2BE2" - const val ORANGE = "#F57C00" - const val DARK_ORANGE = "#FF8C00" - const val ORANGE_RED = "#FF4500" - const val PINK = "#eb4bb8" - const val CYAN = "#0abab5" -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryBlueprint.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryBlueprint.kt deleted file mode 100644 index 616ccb7ee1..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/EntryBlueprint.kt +++ /dev/null @@ -1,200 +0,0 @@ -package me.gabber235.typewriter.adapters - -import com.google.gson.* -import com.google.gson.annotations.SerializedName -import com.google.gson.reflect.TypeToken -import lirand.api.utilities.allFields -import me.gabber235.typewriter.entry.Entry -import java.lang.reflect.Modifier -import java.lang.reflect.ParameterizedType - -data class EntryBlueprint( - val name: String, - val description: String, - val adapter: String, - val fields: FieldInfo, - val color: String, // Hex color - val icon: String, // Font Awesome icon from [Icons] - val tags: List, - @Transient - val clazz: Class, -) - -sealed class FieldInfo { - val modifiers: MutableList = mutableListOf() - - companion object { - - fun fromTypeToken(token: TypeToken<*>): FieldInfo { - val customEditor = computeCustomEditor(token) - if (customEditor != null) { - return CustomField( - editor = customEditor.name, - fieldInfo = customEditor.generateFieldInfo(token), - default = customEditor.generateDefault(token), - ).apply { - customEditor.generateModifiers(token, this).forEach { it.appendModifier(this) } - } - } - - val primitive = PrimitiveFieldType.fromTokenType(token) - if (primitive != null) { - return PrimitiveField(primitive) - } - - - return when { - token.rawType.isEnum -> EnumField.fromTypeToken(token) - List::class.java.isAssignableFrom(token.rawType) -> { - val type = token.type - if (type is ParameterizedType) { - val typeArg = type.actualTypeArguments[0] - ListField(fromTypeToken(TypeToken.get(typeArg))) - } else { - throw IllegalArgumentException("Unknown type for list field: $type") - } - } - - Map::class.java.isAssignableFrom(token.rawType) -> { - val type = token.type - if (type is ParameterizedType) { - val typeArgs = type.actualTypeArguments - MapField(fromTypeToken(TypeToken.get(typeArgs[0])), fromTypeToken(TypeToken.get(typeArgs[1]))) - } else { - throw IllegalArgumentException("Unknown type for map field: $type") - } - } - - else -> ObjectField.fromTypeToken(token) - } - } - } - - abstract fun default(): JsonElement -} - -class PrimitiveField(val type: PrimitiveFieldType) : FieldInfo() { - override fun default(): JsonElement = type.default -} - - -enum class PrimitiveFieldType { - @SerializedName("boolean") - BOOLEAN, - - @SerializedName("double") - DOUBLE, - - @SerializedName("integer") - INTEGER, - - @SerializedName("string") - STRING, - ; - - val default: JsonElement - get() = when (this) { - BOOLEAN -> JsonPrimitive(false) - DOUBLE -> JsonPrimitive(0.0) - INTEGER -> JsonPrimitive(0) - STRING -> JsonPrimitive("") - } - - companion object { - fun fromTokenType(token: TypeToken<*>): PrimitiveFieldType? { - return when (token.rawType) { - Boolean::class.java -> BOOLEAN - Double::class.java -> DOUBLE - Double::class.javaObjectType -> DOUBLE - Float::class.java -> DOUBLE - Float::class.javaObjectType -> DOUBLE - Int::class.java -> INTEGER - Int::class.javaObjectType -> INTEGER - Long::class.java -> INTEGER - Long::class.javaObjectType -> INTEGER - String::class.java -> STRING - else -> null - } - } - } -} - -// If the field is an enum, the values will be the enum constants -class EnumField(private val values: List) : FieldInfo() { - companion object { - fun fromTypeToken(token: TypeToken<*>): EnumField { - /// If the enum fields have an @SerializedName annotation, use that as the value - /// Otherwise, use the enum constant name - - val values = token.rawType.enumConstants.filterIsInstance>().map { enumConstant -> - val field = enumConstant.javaClass.getField(enumConstant.name) - val annotation = field.getAnnotation(SerializedName::class.java) - annotation?.value ?: enumConstant.name - } - - return EnumField(values) - } - } - - override fun default(): JsonElement = JsonPrimitive(values.first()) -} - -// If the field is a list, this is the type of the list -class ListField(val type: FieldInfo) : FieldInfo() { - override fun default(): JsonElement = JsonArray() -} - -// If the field is a map, this is the type of the map -class MapField(val key: FieldInfo, val value: FieldInfo) : FieldInfo() { - override fun default(): JsonElement = JsonObject() -} - -// If the field is an object, this is the type of the object -class ObjectField(val fields: Map) : FieldInfo() { - override fun default(): JsonElement { - val obj = JsonObject() - fields.forEach { (name, field) -> - obj.add(name, field.default()) - } - return obj - } - - companion object { - fun fromTypeToken(token: TypeToken<*>): ObjectField { - val fields = mutableMapOf() - - token.rawType.allFields.filter { !Modifier.isStatic(it.modifiers) }.forEach { field -> - val name = - if (field.isAnnotationPresent(SerializedName::class.java)) { - field.getAnnotation(SerializedName::class.java).value - } else { - field.name - } - - val info = FieldInfo.fromTypeToken(TypeToken.get(field.genericType)) - - // If a field has a modifier for the ui. E.g. it is a trigger or fact or something else. - // We add a bit of extra information to the field. This is used by the UI to - // display the field differently. - computeFieldModifiers(field, info) - - fields[name] = info - } - - return ObjectField(fields) - } - - } -} - -// If a custom editor takes over a field, this is the type of the object. -// The custom editor will be responsible for displaying the field. -class CustomField( - val editor: String, - val fieldInfo: FieldInfo? = null, - val default: JsonElement = JsonNull.INSTANCE, -) : FieldInfo() { - override fun default(): JsonElement = default -} - - diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/FieldModifiers.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/FieldModifiers.kt deleted file mode 100644 index d718d7e07d..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/FieldModifiers.kt +++ /dev/null @@ -1,178 +0,0 @@ -package me.gabber235.typewriter.adapters - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.modifiers.* -import me.gabber235.typewriter.logger -import java.lang.reflect.Field - - -private val gson = com.google.gson.Gson() - -sealed interface FieldModifier { - - fun appendModifier(info: FieldInfo) - - interface DataModifier : FieldModifier { - fun modifierData(): JsonObject - override fun appendModifier(info: FieldInfo) { - val data = modifierData() - if (data.size() > 0) { - info.modifiers.add(data) - } - } - } - - - class StaticModifier(val name: String) : DataModifier { - override fun modifierData(): JsonObject { - return JsonObject().apply { - addProperty("name", name) - } - } - } - - class DynamicModifier(val name: String, val data: Any) : DataModifier { - override fun modifierData(): JsonObject { - return JsonObject().apply { - addProperty("name", name) - add("data", gson.toJsonTree(data)) - } - } - } - - class InnerListModifier(val modifier: FieldModifier) : FieldModifier { - override fun appendModifier(info: FieldInfo) { - if (info !is ListField) return - modifier.appendModifier(info.type) - } - } - - class InnerMapModifier(private val key: FieldModifier?, val value: FieldModifier?) : FieldModifier { - override fun appendModifier(info: FieldInfo) { - if (info !is MapField) return - key?.appendModifier(info.key) - value?.appendModifier(info.value) - } - } - - class MultiModifier(val modifiers: List) : FieldModifier { - constructor(vararg modifiers: FieldModifier) : this(modifiers.toList()) - - override fun appendModifier(info: FieldInfo) { - modifiers.forEach { it.appendModifier(info) } - } - } - - class InnerCustomModifier(val modifier: FieldModifier) : FieldModifier { - override fun appendModifier(info: FieldInfo) { - if (info !is CustomField) return - val customInfo = info.fieldInfo ?: return - modifier.appendModifier(customInfo) - } - } -} - -interface ModifierComputer { - fun compute(field: Field, info: FieldInfo): Result - - /** - * Checks if the given field is a list and tries to compute the modifier for the list's type. - * This can be called inside the [compute] method. - * - * @param field The field to check - * @param info The info of the field - */ - fun innerComputeForList(field: Field, info: FieldInfo): FieldModifier? { - if (info !is ListField) return null - val modifier = compute(field, info.type).getOrNull() ?: return null - return FieldModifier.InnerListModifier(modifier) - } - - /** - * Checks if the given field is a map and tries to compute the modifier for the map's key and value. - * This can be called inside the [compute] method. - * - * @param field The field to check - * @param info The info of the field - */ - fun innerComputeForMap(field: Field, info: FieldInfo): FieldModifier? { - if (info !is MapField) return null - val keyModifier = compute(field, info.key).onFailure { return null }.getOrNull() - val valueModifier = compute(field, info.value).onFailure { return null }.getOrNull() - - if (keyModifier == null && valueModifier == null) return null - return FieldModifier.InnerMapModifier(keyModifier, valueModifier) - } - - /** - * Checks if the given field is a custom field and tries to compute the modifier for the custom field's type. - * This can be called inside the [compute] method. - * - * @param field The field to check - * @param info The info of the field - */ - fun innerComputeForCustom(field: Field, info: FieldInfo): FieldModifier? { - if (info !is CustomField) return null - val customInfo = info.fieldInfo ?: return null - val modifier = compute(field, customInfo) - .getOrNull() - ?: return null - return FieldModifier.InnerCustomModifier(modifier) - } - - /** - * Checks if the given field is a list, map or custom field and tries to compute the modifier for the field's type. - * This can be called inside the [compute] method. - * - * @param field The field to check - * @param info The info of the field - */ - fun innerCompute(field: Field, info: FieldInfo): FieldModifier? { - return when (info) { - is ListField -> innerComputeForList(field, info) - is MapField -> innerComputeForMap(field, info) - is CustomField -> innerComputeForCustom(field, info) - else -> null - } - } -} - -private val computers: List by lazy { - listOf( - HelpModifierComputer, - SnakeCaseModifierComputer, - MultiLineModifierComputer, - OnlyTagsModifierComputer, - MaterialPropertiesModifierComputer, - WithRotationModifierComputer, - SegmentModifierComputer, - MinModifierComputer, - MaxModifierComputer, - PageModifierComputer, - GeneratedModifierComputer, - ContentEditorModifierComputer, - PlaceholderModifierComputer, - ColoredModifierComputer, - RegexModifierComputer, - IconModifierComputer, - NegativeModifierComputer, - ) -} - - -/** - * If a field has a modifier for the ui. E.g. it is a trigger or fact or something else. - * We add a bit of extra information to the field. This is used by the UI to - * display the field differently. - */ -fun computeFieldModifiers(field: Field, info: FieldInfo) { - computers.mapNotNull { computer -> - val result = computer.compute(field, info) - if (result.isSuccess) { - result.getOrNull() - } else { - logger.warning("Failed to compute modifier ${computer::class.simpleName} for field ${field.name} in ${field.declaringClass.simpleName}: ${result.exceptionOrNull()?.message}") - null - } - }.forEach { it.appendModifier(info) } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/TypewriterAdapter.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/TypewriterAdapter.kt deleted file mode 100644 index 10bc00cde9..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/TypewriterAdapter.kt +++ /dev/null @@ -1,7 +0,0 @@ -package me.gabber235.typewriter.adapters - -open class TypewriterAdapter { - open fun initialize() {} - - open fun shutdown() {} -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ColorEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ColorEditor.kt deleted file mode 100644 index bf1bc40dd4..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ColorEditor.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonPrimitive -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.utils.Color - -@CustomEditor(Color::class) -fun ObjectEditor.color() = reference { - default { - JsonPrimitive(0) - } - - jsonDeserialize { element, _, _ -> - Color(element.asInt) - } - - jsonSerialize { src, _, _ -> - JsonPrimitive(src.color) - } -} diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/CronEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/CronEditor.kt deleted file mode 100644 index f827eb65c6..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/CronEditor.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonPrimitive -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.utils.CronExpression - -@CustomEditor(CronExpression::class) -fun ObjectEditor.cron() = reference { - default { - JsonPrimitive(CronExpression.default().expression) - } - - jsonDeserialize { element, _, _ -> - CronExpression.createDynamic(element.asString) - } - - jsonSerialize { value, _, _ -> - JsonPrimitive(value.expression) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/DurationEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/DurationEditor.kt deleted file mode 100644 index 28f8e91aa1..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/DurationEditor.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonPrimitive -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import java.time.Duration - -@CustomEditor(Duration::class) -fun ObjectEditor.duration() = reference { - default { - JsonPrimitive(0) - } - - jsonDeserialize { element, _, _ -> - Duration.ofMillis(element.asLong) - } - - jsonSerialize { src, _, _ -> - JsonPrimitive(src.toMillis()) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/EntryReferenceEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/EntryReferenceEditor.kt deleted file mode 100644 index 149b881b62..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/EntryReferenceEditor.kt +++ /dev/null @@ -1,48 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.common.reflect.TypeToken -import com.google.gson.JsonPrimitive -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.entry.Entry -import me.gabber235.typewriter.entry.Ref -import java.lang.reflect.ParameterizedType -import kotlin.reflect.KClass - -@CustomEditor(Ref::class) -fun ObjectEditor>.entryReference() = reference { - default { - JsonPrimitive("") - } - - jsonDeserialize { element, type, _ -> - val subType = (type as ParameterizedType).actualTypeArguments[0] - val clazz = TypeToken.of(subType).rawType - val klass = clazz.kotlin - - if (element.isJsonNull) { - return@jsonDeserialize Ref("", klass as KClass) - } - val id = element.asString - - Ref(id, klass as KClass) - } - - jsonSerialize { src, _, _ -> - JsonPrimitive(src.id) - } - - modifier { token, _ -> - val subType = (token.type as ParameterizedType).actualTypeArguments[0] - val clazz = TypeToken.of(subType).rawType - val klass = clazz.kotlin - val tag = klass.annotations.find { it is Tags }?.let { (it as Tags).tags.firstOrNull() } - if (tag == null) { - throw IllegalArgumentException("Entry ${klass.simpleName} does not have a tag. It is needed for the StaticEntryIdentifier") - } - - FieldModifier.DynamicModifier("entry", tag) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/FloatRangeEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/FloatRangeEditor.kt deleted file mode 100644 index 069109862d..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/FloatRangeEditor.kt +++ /dev/null @@ -1,31 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor - -@CustomEditor(ClosedFloatingPointRange::class) -fun ObjectEditor>.floatRange() = reference { - default { - val obj = JsonObject() - obj.addProperty("start", 0f) - obj.addProperty("end", 0f) - - obj - } - - jsonDeserialize { element, _, _ -> - val obj = element.asJsonObject - val start = obj.get("start").asFloat - val end = obj.get("end").asFloat - start..end - } - - jsonSerialize { src, _, _ -> - val obj = JsonObject() - obj.addProperty("start", src.start) - obj.addProperty("end", src.endInclusive) - - obj - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ItemEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ItemEditor.kt deleted file mode 100644 index 99067ce489..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/ItemEditor.kt +++ /dev/null @@ -1,59 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.adapters.* -import me.gabber235.typewriter.adapters.modifiers.ContentEditor -import me.gabber235.typewriter.adapters.modifiers.ContentEditorModifierComputer -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.contentEditorCachedInventory -import me.gabber235.typewriter.content.modes.ImmediateFieldValueContentMode -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.toItem -import org.bukkit.entity.Player -import java.lang.reflect.Modifier - -@CustomEditor(Item::class) -fun ObjectEditor.item() = reference { - default { token -> - val obj = JsonObject() - - token.rawType.declaredFields.filter { !Modifier.isStatic(it.modifiers) }.forEach { field -> - val name = field.name - val info = FieldInfo.fromTypeToken(TypeToken.get(field.genericType)) - val default = info.default() - obj.add(name, default) - } - - obj - } - - fieldInfo { token -> - val fields = token.rawType.declaredFields.filter { !Modifier.isStatic(it.modifiers) }.associate { field -> - val name = field.name - // Check if the type is `Optional` - val type = if (field.type.name == "java.util.Optional") { - val type = field.genericType as java.lang.reflect.ParameterizedType - type.actualTypeArguments[0] - } else { - field.genericType - } - val info = FieldInfo.fromTypeToken(TypeToken.get(type)) - computeFieldModifiers(field, info) - name to info - } - - ObjectField(fields) - } - - ContentEditorModifierComputer with ContentEditor(HoldingItemContentMode::class) -} - -class HoldingItemContentMode(context: ContentContext, player: Player) : - ImmediateFieldValueContentMode(context, player) { - override fun value(): Item { - val slot = player.inventory.heldItemSlot - val item = player.contentEditorCachedInventory?.get(slot) ?: return Item() - return item.toItem() - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/LocationEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/LocationEditor.kt deleted file mode 100644 index 3c53e78159..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/LocationEditor.kt +++ /dev/null @@ -1,81 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import lirand.api.extensions.server.mainWorld -import lirand.api.extensions.server.server -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.adapters.modifiers.ContentEditor -import me.gabber235.typewriter.adapters.modifiers.ContentEditorModifierComputer -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.modes.ImmediateFieldValueContentMode -import me.gabber235.typewriter.utils.logErrorIfNull -import me.gabber235.typewriter.utils.round -import org.bukkit.Location -import org.bukkit.entity.Player - -@CustomEditor(Location::class) -fun ObjectEditor.location() = reference { - default { - val obj = JsonObject() - obj.addProperty("world", "") - obj.addProperty("x", 0.0) - obj.addProperty("y", 0.0) - obj.addProperty("z", 0.0) - obj.addProperty("yaw", 0.0) - obj.addProperty("pitch", 0.0) - - obj - } - - jsonDeserialize { element, _, _ -> - val obj = element.asJsonObject - val world = obj.getAsJsonPrimitive("world").asString - val x = obj.getAsJsonPrimitive("x").asDouble - val y = obj.getAsJsonPrimitive("y").asDouble - val z = obj.getAsJsonPrimitive("z").asDouble - val yaw = obj.getAsJsonPrimitive("yaw")?.asFloat ?: 0f - val pitch = obj.getAsJsonPrimitive("pitch")?.asFloat ?: 0f - - val bukkitWorld = - server.getWorld(world) ?: server.worlds.firstOrNull { it.name.equals(world, true) } - .logErrorIfNull( - "Could not find world '$world' for location, so picking default world. Possible worlds: ${ - server.worlds.joinToString( - ", " - ) { "'${it.name}'" } - }" - ) - ?: server.mainWorld - Location(bukkitWorld, x, y, z, yaw, pitch) - } - - jsonSerialize { src, _, _ -> - val obj = JsonObject() - obj.addProperty("world", src.world.name) - obj.addProperty("x", src.x) - obj.addProperty("y", src.y) - obj.addProperty("z", src.z) - obj.addProperty("yaw", src.yaw) - obj.addProperty("pitch", src.pitch) - - obj - } - - ContentEditorModifierComputer with ContentEditor(LocationContentMode::class) -} - -class LocationContentMode(context: ContentContext, player: Player) : - ImmediateFieldValueContentMode(context, player) { - override fun value(): Location { - val location = player.location - val world = location.world - val x = location.x.round(2) - val y = location.y.round(2) - val z = location.z.round(2) - val yaw = location.yaw.round(2) - val pitch = location.pitch.round(2) - - return Location(world, x, y, z, yaw, pitch) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/MaterialEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/MaterialEditor.kt deleted file mode 100644 index 2527f05cbb..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/MaterialEditor.kt +++ /dev/null @@ -1,13 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonPrimitive -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import org.bukkit.Material - -@CustomEditor(Material::class) -fun ObjectEditor.material() = reference { - default { - JsonPrimitive(Material.AIR.name) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/OptionalEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/OptionalEditor.kt deleted file mode 100644 index 4a0840942e..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/OptionalEditor.kt +++ /dev/null @@ -1,56 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonNull -import com.google.gson.JsonObject -import com.google.gson.reflect.TypeToken -import me.gabber235.typewriter.adapters.* -import java.lang.reflect.ParameterizedType -import java.util.* - - -@CustomEditor(Optional::class) -fun ObjectEditor>.optional() = reference { - default { - val obj = JsonObject() - - obj.addProperty("enabled", false) - - val default = generateFieldInfo(it)?.default() ?: JsonNull.INSTANCE - obj.add("value", default) - - obj - } - - jsonDeserialize { element, type, context -> - val obj = element.asJsonObject - val enabled = obj.get("enabled").asBoolean - if (!enabled) return@jsonDeserialize Optional.empty() - - val valueElement = obj.get("value") - - val value: Any? = context.deserialize(valueElement, (type as ParameterizedType).actualTypeArguments[0]) - Optional.ofNullable(value) - } - - jsonSerialize { src, _, context -> - val obj = JsonObject() - - obj.addProperty("enabled", src.isPresent) - - if (src.isPresent) { - val value = src.get() - val valueElement = context.serialize(value) - obj.add("value", valueElement) - } - - obj - } - - fieldInfo { - val type = it.type as ParameterizedType - val actualType = type.actualTypeArguments[0] - FieldInfo.fromTypeToken(TypeToken.get(actualType)) - } - - -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/PotionEffectTypeEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/PotionEffectTypeEditor.kt deleted file mode 100644 index f64a4b42c8..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/PotionEffectTypeEditor.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonPrimitive -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import org.bukkit.potion.PotionEffectType - -@CustomEditor(PotionEffectType::class) -fun ObjectEditor.potionEffectType() = reference { - default { - JsonPrimitive("speed") - } - - jsonDeserialize { element, _, _ -> - PotionEffectType.getByName(element.asString) ?: PotionEffectType.SPEED - } - - jsonSerialize { src, _, _ -> - JsonPrimitive(src.name) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SkinEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SkinEditor.kt deleted file mode 100644 index dc6b3b1b86..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SkinEditor.kt +++ /dev/null @@ -1,34 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.entry.entity.SkinProperty - -@CustomEditor(SkinProperty::class) -fun ObjectEditor.skin() = reference { - default { - val obj = JsonObject() - obj.addProperty("texture", "") - obj.addProperty("signature", "") - - obj - } - - jsonDeserialize { element, _, _ -> - val obj = element.asJsonObject - if (obj.has("texture") && obj.has("signature")) { - SkinProperty(obj.get("texture").asString, obj.get("signature").asString) - } else { - SkinProperty() - } - } - - jsonSerialize { src, _, _ -> - val obj = JsonObject() - obj.addProperty("texture", src.texture) - obj.addProperty("signature", src.signature) - - obj - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundIdEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundIdEditor.kt deleted file mode 100644 index 07c76382f8..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundIdEditor.kt +++ /dev/null @@ -1,50 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.utils.DefaultSoundId -import me.gabber235.typewriter.utils.EntrySoundId -import me.gabber235.typewriter.utils.SoundId - -@CustomEditor(SoundId::class) -fun ObjectEditor.soundId() = reference { - default { - val obj = JsonObject() - - obj.addProperty("type", "default") - obj.addProperty("value", "") - - obj - } - - jsonDeserialize { jsonElement, _, _ -> - val obj = jsonElement.asJsonObject - val type = obj.get("type").asString - val value = obj.get("value").asString - - when (type) { - "default" -> DefaultSoundId(value) - "entry" -> EntrySoundId(value) - else -> throw IllegalArgumentException("Invalid sound id type: $type") - } - } - - jsonSerialize { soundId, _, _ -> - val obj = JsonObject() - - when (soundId) { - is DefaultSoundId -> { - obj.addProperty("type", "default") - obj.addProperty("value", soundId.namespacedKey.toString()) - } - - is EntrySoundId -> { - obj.addProperty("type", "entry") - obj.addProperty("value", soundId.entryId) - } - } - - obj - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundSourceEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundSourceEditor.kt deleted file mode 100644 index 1a8f9a16c8..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/SoundSourceEditor.kt +++ /dev/null @@ -1,70 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.utils.EmitterSoundSource -import me.gabber235.typewriter.utils.LocationSoundSource -import me.gabber235.typewriter.utils.SelfSoundSource -import me.gabber235.typewriter.utils.SoundSource -import org.bukkit.Location - -@CustomEditor(SoundSource::class) -fun ObjectEditor.soundSource() = reference { - default { - JsonObject().apply { - addProperty("type", "self") - addProperty("entryId", "") - add("location", JsonObject().apply { - addProperty("world", "") - addProperty("x", 0.0) - addProperty("y", 0.0) - addProperty("z", 0.0) - addProperty("yaw", 0.0) - addProperty("pitch", 0.0) - }) - } - } - - jsonDeserialize { jsonElement, _, context -> - val obj = jsonElement.asJsonObject - val type = obj.get("type").asString - - when (type) { - "self" -> SelfSoundSource - "emitter" -> { - val value = obj.get("entryId").asString - EmitterSoundSource(value) - } - - "location" -> { - val location: Location = context.deserialize(obj.get("location"), Location::class.java) - LocationSoundSource(location) - } - - else -> throw IllegalArgumentException("Invalid sound source type: $type") - } - } - - jsonSerialize { soundSource, _, context -> - val obj = JsonObject() - - when (soundSource) { - is SelfSoundSource -> { - obj.addProperty("type", "self") - } - - is EmitterSoundSource -> { - obj.addProperty("type", "emitter") - obj.addProperty("entryId", soundSource.entryId) - } - - is LocationSoundSource -> { - obj.addProperty("type", "location") - obj.add("location", context.serialize(soundSource.location)) - } - } - - obj - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/VectorEditor.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/VectorEditor.kt deleted file mode 100644 index c7e63f2c9d..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/editors/VectorEditor.kt +++ /dev/null @@ -1,36 +0,0 @@ -package me.gabber235.typewriter.adapters.editors - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.CustomEditor -import me.gabber235.typewriter.adapters.ObjectEditor -import me.gabber235.typewriter.utils.Vector - -@CustomEditor(Vector::class) -fun ObjectEditor.vector() = reference { - default { - val obj = JsonObject() - obj.addProperty("x", 0.0) - obj.addProperty("y", 0.0) - obj.addProperty("z", 0.0) - - obj - } - - jsonDeserialize { element, _, _ -> - val obj = element.asJsonObject - val x = obj.getAsJsonPrimitive("x").asDouble - val y = obj.getAsJsonPrimitive("y").asDouble - val z = obj.getAsJsonPrimitive("z").asDouble - - Vector(x, y, z) - } - - jsonSerialize { src, _, _ -> - val obj = JsonObject() - obj.addProperty("x", src.x) - obj.addProperty("y", src.y) - obj.addProperty("z", src.z) - - obj - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ColoredModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ColoredModifierComputer.kt deleted file mode 100644 index ac308a6e8d..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ColoredModifierComputer.kt +++ /dev/null @@ -1,30 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class Colored - -object ColoredModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Colored::class.java - - override fun computeModifier(annotation: Colored, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("Colored annotation can only be used on strings (including in lists or maps)!") - } - - if (info.type != PrimitiveFieldType.STRING) { - return failure("Colored annotation can only be used on strings (including in lists or maps)!") - } - - return ok(FieldModifier.StaticModifier("colored")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ContentEditorModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ContentEditorModifierComputer.kt deleted file mode 100644 index 027bade190..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/ContentEditorModifierComputer.kt +++ /dev/null @@ -1,24 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok -import kotlin.reflect.KClass -import kotlin.reflect.jvm.jvmName - -@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY) -annotation class ContentEditor(val capturer: KClass) - -object ContentEditorModifierComputer : StaticModifierComputer { - override val annotationClass: Class = ContentEditor::class.java - - override fun computeModifier(annotation: ContentEditor, info: FieldInfo): Result { - val contentMode = annotation.capturer - val name = contentMode.qualifiedName - ?: return failure("ContentEditor ${contentMode.jvmName} does not have a qualified name! It must be a non-local non-anonymous class.") - - return ok(FieldModifier.DynamicModifier("contentMode", name)) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/GeneratedModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/GeneratedModifierComputer.kt deleted file mode 100644 index adbde8591c..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/GeneratedModifierComputer.kt +++ /dev/null @@ -1,30 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class Generated - -object GeneratedModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Generated::class.java - - override fun computeModifier(annotation: Generated, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("Generated annotation can only be used on strings (including in lists or maps)!") - } - - if (info.type != PrimitiveFieldType.STRING) { - return failure("Generated annotation can only be used on strings (including in lists or maps)!") - } - - return ok(FieldModifier.StaticModifier("generated")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/HelpModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/HelpModifierComputer.kt deleted file mode 100644 index 4f5488c1f3..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/HelpModifierComputer.kt +++ /dev/null @@ -1,17 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.FieldModifier.DynamicModifier -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class Help(val text: String) - -object HelpModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Help::class.java - - override fun computeModifier(annotation: Help, info: FieldInfo): Result { - return ok(DynamicModifier("help", annotation.text)) - } -} diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/Icon.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/Icon.kt deleted file mode 100644 index 22c0e221fd..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/Icon.kt +++ /dev/null @@ -1,16 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class Icon(val icon: String) - -object IconModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Icon::class.java - - override fun computeModifier(annotation: Icon, info: FieldInfo): Result { - return ok(FieldModifier.DynamicModifier("icon", annotation.icon)) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MaterialModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MaterialModifierComputer.kt deleted file mode 100644 index 586c2812ef..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MaterialModifierComputer.kt +++ /dev/null @@ -1,50 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.CustomField -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -enum class MaterialProperty { - ITEM, - BLOCK, - SOLID, - TRANSPARENT, - FLAMMABLE, - BURNABLE, - EDIBLE, - FUEL, - INTRACTABLE, - OCCLUDING, - RECORD, - TOOL, - WEAPON, - ARMOR, - ORE, -} - -@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY) -annotation class MaterialProperties(vararg val properties: MaterialProperty) - - -object MaterialPropertiesModifierComputer : StaticModifierComputer { - override val annotationClass: Class = MaterialProperties::class.java - - override fun computeModifier(annotation: MaterialProperties, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is CustomField) { - return failure("MaterialProperties annotation can only be used on custom fields") - } - if (info.editor != "material") { - return failure("MaterialProperties annotation can only be used materials (not on ${info.editor})") - } - - return ok(FieldModifier.DynamicModifier( - "material_properties", - annotation.properties.joinToString(";") { it.name.lowercase() } - )) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MultiLineModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MultiLineModifierComputer.kt deleted file mode 100644 index a9036bc941..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/MultiLineModifierComputer.kt +++ /dev/null @@ -1,30 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.FieldModifier.StaticModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY) -annotation class MultiLine - -object MultiLineModifierComputer : StaticModifierComputer { - override val annotationClass: Class = MultiLine::class.java - - override fun computeModifier(annotation: MultiLine, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("MultiLine annotation can only be used on strings") - } - if (info.type != PrimitiveFieldType.STRING) { - return failure("MultiLine annotation can only be used on strings") - } - - return ok(StaticModifier("multiline")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/NegativeModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/NegativeModifierComputer.kt deleted file mode 100644 index b9cd0c01ff..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/NegativeModifierComputer.kt +++ /dev/null @@ -1,30 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class Negative - -object NegativeModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Negative::class.java - - override fun computeModifier(annotation: Negative, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("Negative annotation can only be used on numbers (including in lists or maps)!") - } - - if (info.type != PrimitiveFieldType.INTEGER && info.type != PrimitiveFieldType.DOUBLE) { - return failure("Negative annotation can only be used on numbers (including in lists or maps)!") - } - - return ok(FieldModifier.StaticModifier("negative")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/OnlyTagsModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/OnlyTagsModifierComputer.kt deleted file mode 100644 index 68e8688003..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/OnlyTagsModifierComputer.kt +++ /dev/null @@ -1,29 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.CustomField -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class OnlyTags(vararg val tags: String) - -object OnlyTagsModifierComputer : StaticModifierComputer { - override val annotationClass: Class = OnlyTags::class.java - - override fun computeModifier(annotation: OnlyTags, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is CustomField) { - return failure("OnlyTags annotation can only be used on Refs (including in lists or maps)!") - } - - if (info.editor != "entryReference") { - return failure("OnlyTags annotation can only be used on Refs (including in lists or maps)!") - } - - return ok(FieldModifier.DynamicModifier("only_tags", annotation.tags.joinToString(","))) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PageModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PageModifierComputer.kt deleted file mode 100644 index fb2014ade0..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PageModifierComputer.kt +++ /dev/null @@ -1,30 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.entry.PageType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class Page(val type: PageType) - -object PageModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Page::class.java - - override fun computeModifier(annotation: Page, info: FieldInfo): Result { - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("Page annotation can only be used on primitive fields") - } - - if (info.type != PrimitiveFieldType.STRING) { - return failure("Page annotation can only be used on string fields") - } - - return ok(FieldModifier.DynamicModifier("page", annotation.type.id)) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PlaceholderModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PlaceholderModifierComputer.kt deleted file mode 100644 index 1375aa33de..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/PlaceholderModifierComputer.kt +++ /dev/null @@ -1,31 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class Placeholder - -object PlaceholderModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Placeholder::class.java - - override fun computeModifier(annotation: Placeholder, info: FieldInfo): Result { - // If the field is wrapped in a list or other container we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("Placeholder annotation can only be used on strings (including in lists or maps)!") - } - - if (info.type != PrimitiveFieldType.STRING) { - return failure("Placeholder annotation can only be used on strings (including in lists or maps)!") - } - - return ok(FieldModifier.StaticModifier("placeholder")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/RegexModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/RegexModifierComputer.kt deleted file mode 100644 index 01c566ac5c..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/RegexModifierComputer.kt +++ /dev/null @@ -1,29 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class Regex -object RegexModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Regex::class.java - - override fun computeModifier(annotation: Regex, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("Regex annotation can only be used on strings (including in lists or maps)!") - } - - if (info.type != PrimitiveFieldType.STRING) { - return failure("Regex annotation can only be used on strings (including in lists or maps)!") - } - - return ok(FieldModifier.StaticModifier("regex")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SegmentModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SegmentModifierComputer.kt deleted file mode 100644 index 0bd2afe562..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SegmentModifierComputer.kt +++ /dev/null @@ -1,45 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import com.google.gson.JsonObject -import me.gabber235.typewriter.adapters.* -import me.gabber235.typewriter.adapters.FieldModifier.DynamicModifier -import me.gabber235.typewriter.adapters.FieldModifier.InnerListModifier -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class Segments(val color: String = Colors.CYAN, val icon: String = "fa6-solid:star") - -object SegmentModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Segments::class.java - - override fun computeModifier(annotation: Segments, info: FieldInfo): Result { - if (info !is ListField) { - return failure("Segment annotation can only be used on lists") - } - val type = info.type - if (type !is ObjectField) { - return failure("Segment annotation can only be used on lists of objects") - } - val startFrame = type.fields["startFrame"] - val endFrame = type.fields["endFrame"] - if (startFrame !is PrimitiveField || endFrame !is PrimitiveField) { - return failure("Segment annotation can only be used on lists of objects with startFrame and endFrame fields") - } - - if (startFrame.type != PrimitiveFieldType.INTEGER || endFrame.type != PrimitiveFieldType.INTEGER) { - return failure("Segment annotation can only be used on lists of objects with startFrame and endFrame fields of type int") - } - - val color = annotation.color - val icon = annotation.icon - - val data = JsonObject().apply { - addProperty("color", color) - addProperty("icon", icon) - } - - return ok(InnerListModifier(DynamicModifier("segment", data))) - } -} - diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SizeModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SizeModifierComputer.kt deleted file mode 100644 index 7526bb29d9..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SizeModifierComputer.kt +++ /dev/null @@ -1,42 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class Min(val value: Int) - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class InnerMin(val annotation: Min) - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class Max(val value: Int) - -@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER) -annotation class InnerMax(val annotation: Max) - -object MinModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Min::class.java - - override val innerAnnotationFinders: List> = listOf( - InnerAnnotationFinder(InnerMin::class.java, InnerMin::annotation) - ) as List> - - - override fun computeModifier(annotation: Min, info: FieldInfo): Result { - return ok(FieldModifier.DynamicModifier("min", annotation.value)) - } -} - -object MaxModifierComputer : StaticModifierComputer { - override val annotationClass: Class = Max::class.java - - override val innerAnnotationFinders: List> = listOf( - InnerAnnotationFinder(InnerMax::class.java, InnerMax::annotation) - ) as List> - - override fun computeModifier(annotation: Max, info: FieldInfo): Result { - return ok(FieldModifier.DynamicModifier("max", annotation.value)) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SnakeCaseModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SnakeCaseModifierComputer.kt deleted file mode 100644 index 753fb799aa..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/SnakeCaseModifierComputer.kt +++ /dev/null @@ -1,31 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.adapters.FieldModifier.StaticModifier -import me.gabber235.typewriter.adapters.PrimitiveField -import me.gabber235.typewriter.adapters.PrimitiveFieldType -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class SnakeCase - -object SnakeCaseModifierComputer : StaticModifierComputer { - override val annotationClass: Class = SnakeCase::class.java - - override fun computeModifier(annotation: SnakeCase, info: FieldInfo): Result { - // If the field is wrapped in a list or other container we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is PrimitiveField) { - return failure("SnakeCase annotation can only be used on strings (including in lists or maps)!") - } - if (info.type != PrimitiveFieldType.STRING) { - return failure("SnakeCase annotation can only be used on strings (including in lists or maps)!") - } - - return ok(StaticModifier("snake_case")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/StaticModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/StaticModifierComputer.kt deleted file mode 100644 index 54f9fcd2e4..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/StaticModifierComputer.kt +++ /dev/null @@ -1,146 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.* -import me.gabber235.typewriter.utils.ok -import java.lang.reflect.Field -import kotlin.reflect.full.findAnnotations -import kotlin.reflect.full.findParameterByName -import kotlin.reflect.full.memberProperties -import kotlin.reflect.full.primaryConstructor - -enum class InnerModifierType { - LIST, - MAP, - OBJECT, -} - -data class InnerAnnotationFinder( - val parentAnnotationClass: Class, - val transformer: (ParentAnnotation) -> BaseAnnotation, - val types: List = listOf( - InnerModifierType.LIST, - InnerModifierType.MAP, - InnerModifierType.OBJECT - ), -) - -interface StaticModifierComputer : ModifierComputer { - val annotationClass: Class - val innerAnnotationFinders: List> get() = emptyList() - - fun computeModifier(annotation: A, info: FieldInfo): Result - - override fun compute(field: Field, info: FieldInfo): Result { - findAnnotation(field, annotationClass)?.let { annotation -> - return computeModifier(annotation, info) - } - - if (info !is ListField && info !is MapField && info !is ObjectField) { - return ok(null) - } - - innerAnnotationFinders.forEach { finder -> - val annotation = findAnnotation(field, finder.parentAnnotationClass) ?: return@forEach - val innerAnnotation = finder.transformer(annotation) - - if (info is ListField && finder.types.contains(InnerModifierType.LIST)) { - computeModifier(innerAnnotation, info.type).onSuccess { modifier -> - return ok(modifier?.let { FieldModifier.InnerListModifier(it) }) - } - .onFailure { return ok(null) } - } - if (info is MapField && finder.types.contains(InnerModifierType.MAP)) { - val keyModifier = computeModifier(innerAnnotation, info.key).onFailure { return ok(null) }.getOrNull() - val valueModifier = - computeModifier(innerAnnotation, info.value).onFailure { return ok(null) }.getOrNull() - - return ok(FieldModifier.InnerMapModifier(keyModifier, valueModifier)) - } - if (info is ObjectField && finder.types.contains(InnerModifierType.OBJECT)) { - computeModifier(innerAnnotation, info).onSuccess { modifier -> - return ok(modifier?.let { FieldModifier.InnerCustomModifier(it) }) - } - .onFailure { return ok(null) } - } - } - return ok(null) - } - - fun findAnnotation(field: Field, annotationClass: Class): T? { - val annotation = field.getAnnotation(annotationClass) - if (annotation != null) { - return annotation - } - - // If the annotation is not present on the field, check if it is present on primary constructor parameter - field.declaringClass.kotlin.primaryConstructor?.findParameterByName(field.name) - ?.findAnnotations(annotationClass.kotlin)?.firstOrNull()?.let { - return it - } - - // We try to find the interface property and see if it has the annotation - return field.declaringClass.interfaces.asSequence().mapNotNull { - it.kotlin.memberProperties.firstOrNull { prop -> prop.name == field.name } - }.firstOrNull()?.findAnnotations(annotationClass.kotlin)?.firstOrNull() - } - - /** - * Checks if the given field is a list and tries to compute the modifier for the list's type. - * This can be called inside the [compute] method. - * - * @param annotation the annotation that was found on the field - * @param info The info of the field - */ - fun innerComputeForList(annotation: A, info: FieldInfo): FieldModifier? { - if (info !is ListField) return null - val modifier = computeModifier(annotation, info.type).getOrNull() ?: return null - return FieldModifier.InnerListModifier(modifier) - } - - /** - * Checks if the given field is a map and tries to compute the modifier for the map's key and value. - * This can be called inside the [compute] method. - * - * @param annotation the annotation that was found on the field - * @param info The info of the field - */ - fun innerComputeForMap(annotation: A, info: FieldInfo): FieldModifier? { - if (info !is MapField) return null - val keyModifier = computeModifier(annotation, info.key).getOrNull() - val valueModifier = computeModifier(annotation, info.value).getOrNull() - - if (keyModifier == null && valueModifier == null) return null - return FieldModifier.InnerMapModifier(keyModifier, valueModifier) - } - - /** - * Checks if the given field is a custom field and tries to compute the modifier for the custom field's type. - * This can be called inside the [compute] method. - * - * @param annotation the annotation that was found on the field - * @param info The info of the field - */ - fun innerComputeForCustom(annotation: A, info: FieldInfo): FieldModifier? { - if (info !is CustomField) return null - val customInfo = info.fieldInfo ?: return null - val modifier = computeModifier(annotation, customInfo).getOrNull() ?: return null - return FieldModifier.InnerCustomModifier(modifier) - } - - /** - * Checks if the given field is a list, map or custom field and tries to compute the modifier for the field's type. - * This can be called inside the [compute] method. - * - * @param annotation the annotation that was found on the field - * @param info The info of the field - */ - fun innerCompute(annotation: A, info: FieldInfo): FieldModifier? { - return when (info) { - is ListField -> innerComputeForList(annotation, info) - is MapField -> innerComputeForMap(annotation, info) - is CustomField -> innerComputeForCustom(annotation, info) - else -> null - } - } - -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/WithRotationModifierComputer.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/WithRotationModifierComputer.kt deleted file mode 100644 index 1c23067335..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/adapters/modifiers/WithRotationModifierComputer.kt +++ /dev/null @@ -1,28 +0,0 @@ -package me.gabber235.typewriter.adapters.modifiers - -import me.gabber235.typewriter.adapters.CustomField -import me.gabber235.typewriter.adapters.FieldInfo -import me.gabber235.typewriter.adapters.FieldModifier -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok - -@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER) -annotation class WithRotation - -object WithRotationModifierComputer : StaticModifierComputer { - override val annotationClass: Class = WithRotation::class.java - - override fun computeModifier(annotation: WithRotation, info: FieldInfo): Result { - // If the field is wrapped in a list or other container, we try if the inner type can be modified - innerCompute(annotation, info)?.let { return ok(it) } - - if (info !is CustomField) { - return failure("WithRotation annotation can only be used on locations (including in lists or maps)!") - } - if (info.editor != "location") { - return failure("WithRotation annotation can only be used on locations (including in lists or maps)!") - } - - return ok(FieldModifier.StaticModifier("with_rotation")) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CachedInventoryComponent.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CachedInventoryComponent.kt deleted file mode 100644 index 4af446aab5..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/components/CachedInventoryComponent.kt +++ /dev/null @@ -1,24 +0,0 @@ -package me.gabber235.typewriter.content.components - -import me.gabber235.typewriter.content.ComponentContainer -import me.gabber235.typewriter.content.ContentComponent -import me.gabber235.typewriter.content.contentEditorCachedInventory -import org.bukkit.entity.Player - -fun ComponentContainer.cachedInventory() = +CachedInventoryComponent() - -class CachedInventoryComponent : ContentComponent, ItemsComponent { - private var cachedInventory: Map? = null - - override suspend fun initialize(player: Player) { - cachedInventory = player.contentEditorCachedInventory?.mapIndexedNotNull { index, item -> - item?.let { index to IntractableItem(it) {} } - }?.toMap() ?: emptyMap() - } - - override suspend fun tick(player: Player) {} - override suspend fun dispose(player: Player) {} - override fun items(player: Player): Map { - return cachedInventory ?: emptyMap() - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/ImmediateFieldValueContentMode.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/ImmediateFieldValueContentMode.kt deleted file mode 100644 index 4c0ba1e15e..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/content/modes/ImmediateFieldValueContentMode.kt +++ /dev/null @@ -1,44 +0,0 @@ -package me.gabber235.typewriter.content.modes - -import com.github.shynixn.mccoroutine.bukkit.launch -import kotlinx.coroutines.delay -import me.gabber235.typewriter.content.ContentContext -import me.gabber235.typewriter.content.ContentMode -import me.gabber235.typewriter.content.entryId -import me.gabber235.typewriter.content.fieldPath -import me.gabber235.typewriter.entry.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.SystemTrigger.CONTENT_END -import me.gabber235.typewriter.entry.fieldValue -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.failure -import me.gabber235.typewriter.utils.ok -import org.bukkit.entity.Player -import kotlin.time.Duration.Companion.milliseconds - -abstract class ImmediateFieldValueContentMode(context: ContentContext, player: Player) : - ContentMode(context, player) { - - override suspend fun setup(): Result { - val entryId = context.entryId - ?: return failure("No entryId found for ${this::class.simpleName}. This is a bug. Please report it.") - - val fieldPath = context.fieldPath - ?: return failure("No fieldPath found for ${this::class.simpleName}. This is a bug. Please report it.") - - // Needs to complete the initialisation so that we can properly get the value and end the content mode - plugin.launch { - delay(100.milliseconds) - val value = value() - - Ref(entryId, Entry::class).fieldValue(fieldPath, value) - CONTENT_END triggerFor player - } - - return ok(Unit) - } - - abstract fun value(): T - -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryDatabase.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryDatabase.kt deleted file mode 100644 index 582805705a..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryDatabase.kt +++ /dev/null @@ -1,261 +0,0 @@ -package me.gabber235.typewriter.entry - -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import com.google.gson.annotations.SerializedName -import com.google.gson.stream.JsonReader -import kotlinx.coroutines.runBlocking -import lirand.api.extensions.events.listen -import me.gabber235.typewriter.adapters.AdapterLoader -import me.gabber235.typewriter.adapters.customEditors -import me.gabber235.typewriter.entry.entries.CustomCommandEntry -import me.gabber235.typewriter.events.PublishedBookEvent -import me.gabber235.typewriter.events.TypewriterReloadEvent -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.* -import org.bukkit.entity.Player -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject -import org.koin.core.qualifier.named -import kotlin.reflect.KClass - -interface EntryDatabase { - val commandEvents: List - - fun initialize() - fun loadEntries() - - fun findEntries(klass: KClass, predicate: (E) -> Boolean): Sequence - - fun findEntriesFromPage(klass: KClass, pageId: String, filter: (E) -> Boolean): Sequence - - fun findEntry(klass: KClass, predicate: (E) -> Boolean): E? - - fun findEntryById(kClass: KClass, id: String): E? - - fun findPageById(id: String): Page? - fun getPageNames(type: PageType? = null): List - fun pageIdByEntryId(entryId: String): String? - - fun entryPriority(entry: Ref): Int - fun pagePriority(pageId: String): Int -} - -class EntryDatabaseImpl : EntryDatabase, KoinComponent { - private val entryListeners: EntryListeners by inject() - private val audienceManager: AudienceManager by inject() - private val gson: Gson by inject(named("entryParser")) - - private var pages: List = emptyList() - private var entries: List = emptyList() - - override var commandEvents = listOf() - - private var entryPriority = emptyMap, Int>() - - override fun initialize() { - plugin.listen { loadEntries() } - plugin.listen { loadEntries() } - } - - override fun loadEntries() { - val pages = readPages(gson) - - val newCommandEvents = pages.flatMap { it.entries.filterIsInstance() } - // CommandAPI crashes when we try to register commands not on the main thread - runBlocking { - ThreadType.SYNC.switchContext { - this@EntryDatabaseImpl.commandEvents = CustomCommandEntry.refreshAndRegisterAll(newCommandEvents) - } - } - - this.entries = pages.flatMap { it.entries } - this.entryPriority = pages.flatMap { page -> - page.entries.map { entry -> - if (entry !is PriorityEntry) return@map entry.ref() to page.priority - entry.ref() to entry.priorityOverride.orElse(page.priority) - } - }.toMap() - this.pages = pages - - - entryListeners.register() - audienceManager.register() - - logger.info("Loaded ${entries.size} entries from ${pages.size} pages.") - } - - private fun readPages(gson: Gson): List { - val dir = plugin.dataFolder["pages"] - if (!dir.exists()) { - dir.mkdirs() - } - - dir.migrateIfNecessary() - - return dir.pages().mapNotNull { file -> - val id = file.nameWithoutExtension - val dialogueReader = JsonReader(file.reader()) - dialogueReader.parsePage(id, gson).getOrNull() - } - } - - override fun findEntries(klass: KClass, predicate: (T) -> Boolean): Sequence { - return entries.asSequence().filterIsInstance(klass.java).filter(predicate) - } - - override fun findEntriesFromPage(klass: KClass, pageId: String, filter: (E) -> Boolean): Sequence { - return pages.firstOrNull { it.id == pageId }?.entries?.asSequence()?.filterIsInstance(klass.java) - ?.filter(filter) - ?: emptySequence() - } - - override fun findEntry(klass: KClass, predicate: (T) -> Boolean): T? { - return entries.asSequence().filterIsInstance(klass.java).firstOrNull(predicate) - } - - override fun findEntryById(kClass: KClass, id: String): T? = findEntry(kClass) { it.id == id } - - override fun findPageById(id: String): Page? = pages.firstOrNull { it.id == id } - - override fun getPageNames(type: PageType?): List { - return if (type == null) pages.map { it.id } - else pages.filter { it.type == type }.map { it.id } - } - - override fun pageIdByEntryId(entryId: String): String? { - return pages.firstOrNull { page -> page.entries.any { it.id == entryId } }?.id - } - - override fun entryPriority(entry: Ref): Int { - return entryPriority[entry] ?: 0 - } - - override fun pagePriority(pageId: String): Int { - return findPageById(pageId)?.priority ?: Int.MIN_VALUE - } -} - -fun JsonReader.parsePage(id: String, gson: Gson): Result { - return try { - var page = Page(id) - - beginObject() - while (hasNext()) { - when (nextName()) { - "entries" -> page = page.copy(entries = parseEntries(gson, id)) - "type" -> page = page.copy(type = PageType.fromId(nextString()) ?: PageType.SEQUENCE) - "priority" -> page = page.copy(priority = nextInt()) - else -> skipValue() - } - } - - endObject() - - Result.success(page) - } catch (e: Exception) { - logger.warning("Failed to parse page: ${e.message}") - Result.failure(e) - } -} - -private fun JsonReader.parseEntries(gson: Gson, pageId: String): List { - val entries = mutableListOf() - - beginArray() - while (hasNext()) { - val entry = parseEntry(gson, pageId) ?: continue - entries.add(entry) - } - endArray() - - return entries -} - -private fun JsonReader.parseEntry(gson: Gson, pageId: String): Entry? { - return try { - gson.fromJson(this, Entry::class.java) - } catch (e: NonExistentSubtypeException) { - val subtypeName = e.subtypeName - - logger.warning( - """ - |-------------------------------------------------------------------------- - |Failed to parse entry type '$subtypeName' on page '$pageId' is not a valid entry type. (skipping) - | - |This is either because an adapter is missing or due to having an outdated page entry. - | - |Please report this on the TypeWriter Discord! - |-------------------------------------------------------------------------- - """.trimMargin() - ) - null - } catch (e: Exception) { - logger.warning("Failed to parse entry: ${e.message} (${this})") - null - } -} - -data class Page( - val id: String = "", - val entries: List = emptyList(), - val type: PageType = PageType.SEQUENCE, - val priority: Int = 0 -) - -enum class PageType(val id: String) { - @SerializedName("sequence") - SEQUENCE("sequence"), - - @SerializedName("static") - STATIC("static"), - - @SerializedName("cinematic") - CINEMATIC("cinematic"), - - @SerializedName("manifest") - MANIFEST("manifest"), - ; - - companion object { - fun fromId(id: String) = entries.firstOrNull { it.id == id } - } -} - -infix fun Iterable.matches(player: Player): Boolean = all { - val entry = it.fact.get() - val fact = entry?.readForPlayersGroup(player) - it.isValid(fact) -} - -fun createEntryParserGson(adapterLoader: AdapterLoader): Gson { - val entryFactory = RuntimeTypeAdapterFactory.of(Entry::class.java) - - val entries = adapterLoader.adapters.flatMap { it.entries } - - entries.groupingBy { it.name }.eachCount().filter { it.value > 1 }.forEach { (name, count) -> - logger.warning("WARNING: Found $count entries with the name '$name'") - } - - entries.forEach { - entryFactory.registerSubtype(it.clazz, it.name) - } - - var builder = GsonBuilder() - .registerTypeAdapterFactory(entryFactory) - - customEditors.mapValues { it.value.deserializer }.filterValues { it != null }.forEach { - builder = builder.registerTypeAdapter(it.key.java, it.value) - } - customEditors.mapValues { it.value.serializer }.filterValues { it != null }.forEach { - builder = builder.registerTypeAdapter(it.key.java, it.value) - } - - return builder - .create() -} - -val Entry.priority: Int get() = ref().priority -val Ref.priority: Int - get() = org.koin.java.KoinJavaComponent.get(EntryDatabase::class.java).entryPriority(this) \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryListeners.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryListeners.kt deleted file mode 100644 index ffffdca37f..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryListeners.kt +++ /dev/null @@ -1,96 +0,0 @@ -package me.gabber235.typewriter.entry - -import lirand.api.extensions.events.listen -import lirand.api.extensions.events.unregister -import me.gabber235.typewriter.adapters.AdapterListener -import me.gabber235.typewriter.adapters.AdapterLoader -import me.gabber235.typewriter.entry.entries.EventEntry -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import org.bukkit.event.Event -import org.bukkit.event.EventPriority -import org.bukkit.event.Listener -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject -import java.lang.reflect.Method -import kotlin.reflect.KClass -import kotlin.reflect.full.isSubclassOf -import kotlin.reflect.full.isSuperclassOf - -/** - * Annotate a function to let Typewriter know that it should be called when a specific event occurs. - * - * When no entry of the specified class is registered, the bukkit listener will not be registered. - * - * The function must have at least one parameter, which is the event that occurred. - * Other parameters are optional and can be used to inject dependencies. - * Such as [Query]. - * - * Example: - * ```kotlin - * @EventListener(InteractEventEntry::class) - * fun onEntryCreated(event: PlayerInteractEvent, query: Query) { - * // ... - * } - * ``` - * - * IMPORTANT: The function must be static. - */ -@Target(AnnotationTarget.FUNCTION) -annotation class EntryListener( - val entry: KClass, - val priority: EventPriority = EventPriority.NORMAL, - val ignoreCancelled: Boolean = false -) - -/** - * Manages all the active entry listeners. - */ -class EntryListeners : KoinComponent { - private val adapterLoader: AdapterLoader by inject() - - private val listener = object : Listener {} - - - private fun onEvent(event: Event, adapterListener: AdapterListener) { - val parameters = adapterListener.generators.map { it.generate(event, adapterListener) } - try { - adapterListener.method.invoke(null, *parameters.toTypedArray()) - } catch (e: Exception) { - logger.severe("Failed to invoke entry listener ${adapterListener.method.name} for event ${event::class.simpleName}") - e.printStackTrace() - } - } - - /** - * Registers all the entry listeners. - */ - fun register() { - unregister() - - val entryListeners = adapterLoader.adapters.flatMap { it.eventListeners } - - val activeEventEntries = Query.find().map { it::class }.distinct() - - entryListeners.filter { - activeEventEntries.any { activeEventEntry -> it.entry.isSuperclassOf(activeEventEntry) } - }.forEach { - val eventClass = findEventFromMethod(it.method) ?: return@forEach - - listener.listen(plugin, eventClass, it.priority, it.ignoreCancelled) { event -> - onEvent(event, it) - } - } - } - - private fun findEventFromMethod(method: Method): KClass? { - return method.parameters.firstNotNullOfOrNull { it.type.kotlin.takeIf { type -> type.isSubclassOf(Event::class) } } as? KClass - } - - /** - * Unregisters all the entry listeners. - */ - fun unregister() { - listener.unregister() - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryMigration.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryMigration.kt deleted file mode 100644 index edd3a763f4..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/EntryMigration.kt +++ /dev/null @@ -1,220 +0,0 @@ -package me.gabber235.typewriter.entry - -import com.google.gson.Gson -import com.google.gson.JsonObject -import com.google.gson.JsonSyntaxException -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.AdapterLoader -import org.koin.core.qualifier.named -import org.koin.java.KoinJavaComponent.get -import java.lang.reflect.Method -import java.lang.reflect.Modifier -import kotlin.reflect.KClass -import kotlin.reflect.full.findAnnotations - -/** - * Annotate a function to let Typewriter know that it should be called when an entry needs to be migrated. - * - * The function must have the signature `(JsonObject, EntryMigratorContext) -> JsonObject`. - * - * Example: - * ```kotlin - * @EntryMigration(InventoryItemCountFact::class, "0.1.0") - * private fun migrate010(json: JsonObject, context: EntryMigratorContext): JsonObject { - * val data = JsonObject() - * data.copyAllBut(json, "test") - * - * val test = json.getAndParse>("test", context.gson).optional - * // ... - * return data - * } - * ``` - * - * IMPORTANT: The function must be static - * - * Additionally, you can annotate the function with [NeedsMigrationIfContainsAny], [NeedsMigrationIfContainsAll], - * or [NeedsMigrationIfNotParsable] to prevent the migration of entries that are already parsable by the current version - * of the entry. - */ -@Target(AnnotationTarget.FUNCTION) -annotation class EntryMigration(val klass: KClass, val version: String) - -class EntryMigratorContext(val gson: Gson) - -data class EntryMigrator( - val klass: KClass, - val version: SemanticVersion, - val needsMigration: NeedsMigration, - val migrator: (JsonObject, EntryMigratorContext) -> JsonObject, -) { - fun needsMigration(json: JsonObject, context: EntryMigratorContext): Boolean { - return needsMigration.needsMigration(this, json, context) - } -} - -fun JsonObject.copyAllBut(from: JsonObject, vararg properties: String) { - from.entrySet().filter { it.key !in properties }.forEach { (key, value) -> - this[key] = value.deepCopy() - } -} - -inline fun JsonObject.getAndParse(name: String, gson: Gson): T? { - val element = this[name] ?: return null - return gson.fromJson(element, object : com.google.gson.reflect.TypeToken() {}.type) -} - -object EntryMigrations { - fun finaMaximalMigrationVersion(): SemanticVersion? { - val migrators = get(AdapterLoader::class.java).getEntryMigrators() - return migrators.maxOfOrNull { it.version } - } - - fun findMinimalNeededMigrationVersion(currentVersion: SemanticVersion): SemanticVersion? { - val migrators = get(AdapterLoader::class.java).getEntryMigrators() - return migrators.map { it.version }.filter { it > currentVersion }.minOrNull() - } - - fun findEntryMigrators(targetVersion: SemanticVersion): List> { - val migrators = get(AdapterLoader::class.java).getEntryMigrators() - return migrators.filter { it.version == targetVersion }.map { entryName(it.klass) to it } - } - - private fun entryName(klass: KClass): String { - val entry = klass.findAnnotations(me.gabber235.typewriter.adapters.Entry::class).firstOrNull() - ?: throw IllegalStateException("Entry ${klass.simpleName} does not have an @Entry annotation.") - return entry.name - } - - fun JsonObject.migrateEntriesForPage(migrators: List>) { - val gson = get(Gson::class.java, named("entryParser")) - val entries = getAsJsonArray("entries") ?: return - val newEntries = entries.map { entry -> - val entryObject = entry.asJsonObject - val type = entryObject["type"]?.asString ?: return@map entry - val entryMigrators = migrators.filter { it.first == type }.map { it.second } - if (entryMigrators.isEmpty()) { - return@map entry - } - - val context = EntryMigratorContext(gson) - - entryMigrators.filter { it.needsMigration(entryObject, context) }.fold(entryObject) { acc, migrator -> - migrator.migrator(acc, context) - } - } - - this["entries"] = newEntries.json - } - - private fun constructEntryMigrator(method: Method): EntryMigrator { - val annotation = method.getAnnotation(EntryMigration::class.java) - - if (method.parameterCount != 2) { - throw EntryMigratorException(method, "has ${method.parameterCount} parameters.") - } - if (method.parameterTypes[0] != JsonObject::class.java) { - throw EntryMigratorException(method, "the first parameter is not JsonObject.") - } - if (method.parameterTypes[1] != EntryMigratorContext::class.java) { - throw EntryMigratorException(method, "the second parameter is not EntryMigratorContext.") - } - if (method.returnType != JsonObject::class.java) { - throw EntryMigratorException(method, "the return type is not JsonObject.") - } - val needsMigration = NeedsMigration.fromMethod(method) - - return EntryMigrator(annotation.klass, annotation.version.v, needsMigration) { json, context -> - method.isAccessible = true - method.invoke(null, json, context) as JsonObject - } - } - - fun constructEntryMigrators(classes: List>): List { - return classes.asSequence() - .flatMap { it.methods.asSequence() } - .filter { Modifier.isStatic(it.modifiers) } - .filter { it.isAnnotationPresent(EntryMigration::class.java) } - .map(::constructEntryMigrator) - .toList() - - } -} - -/** - * Indicates that an entry needs to be migrated if any of the specified properties contain any value. - * - * Use this to prevent the migration of entries that are already parsable by the current version of the entry. - * - * @param properties The list of properties to check for values. If any of these properties contain a value, - * the annotated function needs to be migrated. - */ -@Target(AnnotationTarget.FUNCTION) -annotation class NeedsMigrationIfContainsAny(val properties: Array) - -/** - * Indicates that an entry needs to be migrated if all the specified properties contain any value. - * - * Use this to prevent the migration of entries that are already parsable by the current version of the entry. - * - * @param properties The list of properties to check for values. If all of these properties contain a value, - */ -@Target(AnnotationTarget.FUNCTION) -annotation class NeedsMigrationIfContainsAll(val properties: Array) - -/** - * Indicates that an entry needs to be migrated if the object is not parsable by the current version of the entry. - * - * Use this to prevent the migration of entries that are already parsable by the current version of the entry. - */ -@Target(AnnotationTarget.FUNCTION) -annotation class NeedsMigrationIfNotParsable - -sealed interface NeedsMigration { - fun needsMigration(migrator: EntryMigrator, json: JsonObject, context: EntryMigratorContext): Boolean - - data object Always : NeedsMigration { - override fun needsMigration(migrator: EntryMigrator, json: JsonObject, context: EntryMigratorContext): Boolean = - true - } - - class ContainsAny(private val properties: Array) : NeedsMigration { - override fun needsMigration(migrator: EntryMigrator, json: JsonObject, context: EntryMigratorContext): Boolean { - return properties.any { json.has(it) } - } - } - - class ContainsAll(private val properties: Array) : NeedsMigration { - override fun needsMigration(migrator: EntryMigrator, json: JsonObject, context: EntryMigratorContext): Boolean { - return properties.all { json.has(it) } - } - } - - data object NotParsable : NeedsMigration { - override fun needsMigration(migrator: EntryMigrator, json: JsonObject, context: EntryMigratorContext): Boolean { - return try { - context.gson.fromJson(json, migrator.klass.java) - false - } catch (e: JsonSyntaxException) { - true - } - } - } - - companion object { - fun fromMethod(method: Method): NeedsMigration { - val any = method.getAnnotation(NeedsMigrationIfContainsAny::class.java) - val all = method.getAnnotation(NeedsMigrationIfContainsAll::class.java) - val notParsable = method.getAnnotation(NeedsMigrationIfNotParsable::class.java) - - return when { - any != null -> ContainsAny(any.properties) - all != null -> ContainsAll(all.properties) - notParsable != null -> NotParsable - else -> Always - } - } - } -} - -class EntryMigratorException(method: Method, comment: String) : - Exception("Entry migration method ${method.name} should have signature (JsonObject, EntryMigratorContext) -> JsonObject, but $comment.") diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/PageMigrator.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/PageMigrator.kt deleted file mode 100644 index 633233ecd9..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/PageMigrator.kt +++ /dev/null @@ -1,179 +0,0 @@ -package me.gabber235.typewriter.entry - -import com.google.gson.Gson -import com.google.gson.JsonElement -import com.google.gson.JsonObject -import com.google.gson.JsonPrimitive -import lirand.api.extensions.other.set -import me.gabber235.typewriter.entry.EntryMigrations.migrateEntriesForPage -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import me.gabber235.typewriter.utils.get -import java.io.File -import java.text.SimpleDateFormat -import java.util.* - - -data class PossibleMigration( - val file: File, - val version: SemanticVersion, -) - - -fun File.pages(): Array = listFiles { _, name -> name.endsWith(".json") } ?: emptyArray() - -fun File.migrateIfNecessary(run: Int = 0) { - val highestMigratorVersion = EntryMigrations.finaMaximalMigrationVersion() ?: return - val migratable = pages().mapNotNull { file -> - if (!file.exists()) { - return@mapNotNull null - } - - val content = file.readText() - val json = Gson().fromJson(content, JsonObject::class.java) - val pageVersion = json.getAsJsonPrimitive("version")?.asString ?: "0.0.0" - val semanticVersion = SemanticVersion.fromString(pageVersion) - - if (semanticVersion >= highestMigratorVersion) { - return@mapNotNull null - } - - return@mapNotNull PossibleMigration(file, semanticVersion) - } - - if (migratable.isEmpty()) { - return - } - - if (run == 0) { - logger.info( - """ - | - | -------------- MIGRATION -------------- - | Starting migration of ${migratable.size} files. - | - | This may take a while, please wait. - | - | If the migration fails, please report this to the developer. - | Your files will be backed up to the folder "plugins/Typewriter/backup". - | -------------- MIGRATION -------------- - """.trimMargin() - ) - - migratable.map { it.file }.backup() - } - - val lowestPageVersion = migratable.minBy { it.version }.version - val lowestMigratorVersion = EntryMigrations.findMinimalNeededMigrationVersion(lowestPageVersion) - ?: throw IllegalStateException("Could not find a migration for version $lowestPageVersion") - - val migrators = EntryMigrations.findEntryMigrators(lowestMigratorVersion) - - val migrating = migratable.filter { it.version == lowestPageVersion }.map { it.file } - - migrating.forEach { file -> - val content = file.readText() - val json = Gson().fromJson(content, JsonObject::class.java) - json.migrateEntriesForPage(migrators) - json["version"] = lowestMigratorVersion.toString().json - file.writeText(Gson().toJson(json)) - } - - - /// Recursively call this function until all files are migrated - migrateIfNecessary(run + 1) -} - -fun List.backup() { - if (isEmpty()) { - // Nothing to back up - return - } - val date = Date() - val dateFormat = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss") - - val backupFolder = plugin.dataFolder["backup/${dateFormat.format(date)}"] - backupFolder.mkdirs() - forEach { - val file = it - val backupFile = File(backupFolder, file.name) - file.copyTo(backupFile, overwrite = true) - } -} - -internal val String.json get() = JsonPrimitive(this) -internal val List.json get() = Gson().toJsonTree(this) - -internal val String.v get() = SemanticVersion.fromString(this) - -data class SemanticVersion( - val major: Int, - val minor: Int, - val patch: Int, - val type: VersionType = VersionType.RELEASE, - val buildNumber: Int = 0, -) : Comparable { - companion object { - fun fromString(version: String): SemanticVersion { - val versionParts = version.split("-") - val versionPart = versionParts[0] - val parts = versionPart.split(".") - if (parts.size != 3) { - throw IllegalArgumentException("Invalid version format: $version") - } - - val (major, minor, patch) = parts.map { it.toInt() } - - if (versionParts.size == 1) { - return SemanticVersion(major, minor, patch) - } - - val type = when (versionParts[1]) { - "dev" -> VersionType.DEVELOPMENT - else -> VersionType.RELEASE - } - - val buildNumber = if (versionParts.size == 3) { - versionParts[2].toInt() - } else { - 0 - } - - return SemanticVersion(major, minor, patch, type, buildNumber) - } - } - - override operator fun compareTo(other: SemanticVersion): Int { - if (major != other.major) { - return major - other.major - } - if (minor != other.minor) { - return minor - other.minor - } - if (patch != other.patch) { - return patch - other.patch - } - - if (type != other.type) { - return when (type) { - VersionType.RELEASE -> 1 - VersionType.DEVELOPMENT -> -1 - } - } - - return buildNumber - other.buildNumber - } - - override fun toString(): String { - if (type == VersionType.RELEASE) { - return "$major.$minor.$patch" - } - - return "$major.$minor.$patch-${type.suffix}-$buildNumber" - } -} - -enum class VersionType(val suffix: String) { - RELEASE(""), - DEVELOPMENT("dev"), -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityAttribute.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityAttribute.kt deleted file mode 100644 index 1720f7c8c6..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityAttribute.kt +++ /dev/null @@ -1,4 +0,0 @@ -package me.gabber235.typewriter.entry.entity - -interface EntityAttribute { -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityStorage.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityStorage.kt deleted file mode 100644 index 1d22d2d59f..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/EntityStorage.kt +++ /dev/null @@ -1,11 +0,0 @@ -package me.gabber235.typewriter.entry.entity - -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.EntityInstanceEntry -import java.util.* -import java.util.concurrent.ConcurrentHashMap - -class EntityStorage { - val location = ConcurrentHashMap, LocationProperty>() - -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/LocationProperty.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/LocationProperty.kt deleted file mode 100644 index 3a6023ec7c..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entity/LocationProperty.kt +++ /dev/null @@ -1,101 +0,0 @@ -package me.gabber235.typewriter.entry.entity - -import com.github.retrooper.packetevents.protocol.world.Location -import me.gabber235.typewriter.entry.entries.EntityProperty -import me.gabber235.typewriter.utils.Point -import java.util.* - -data class LocationProperty( - val world: UUID, - override val x: Double, - override val y: Double, - override val z: Double, - val yaw: Float, - val pitch: Float, -) : EntityProperty, Point { - constructor(location: org.bukkit.Location) : this( - location.world.uid, - location.x, - location.y, - location.z, - location.yaw, - location.pitch, - ) - - val bukkitWorld get() = org.bukkit.Bukkit.getWorld(world) - - fun toLocation(): org.bukkit.Location { - return org.bukkit.Location(org.bukkit.Bukkit.getWorld(world), x, y, z, yaw, pitch) - } - - fun toPacketLocation(): Location { - return Location(x, y, z, yaw, pitch) - } - - fun toVector(): org.bukkit.util.Vector { - return org.bukkit.util.Vector(x, y, z) - } - - fun distanceSqrt(other: LocationProperty): Double? { - if (world != other.world) return null - return toVector().distanceSquared(other.toVector()) - } - - fun distanceSqrt(other: org.bukkit.Location): Double? { - if (world != other.world.uid) return null - return toVector().distanceSquared(other.toVector()) - } - - // Returns the x, z centered location - fun mid(): LocationProperty { - return copy(x = x.toInt() + 0.5, y = y.toInt().toDouble(), z = z.toInt() + 0.5) - } - - override fun withX(x: Double): Point = copy(x = x) - - override fun withY(y: Double): Point = copy(y = y) - - override fun withZ(z: Double): Point = copy(z = z) - - override fun add(x: Double, y: Double, z: Double): LocationProperty { - return copy(x = this.x + x, y = this.y + y, z = this.z + z) - } - - override fun add(point: Point) = add(point.x, point.y, point.z) - - override fun add(value: Double) = add(value, value, value) - - override fun plus(point: Point) = add(point) - - override fun plus(value: Double) = add(value) - - override fun sub(x: Double, y: Double, z: Double) = copy(x = this.x - x, y = this.y - y, z = this.z - z) - - override fun sub(point: Point) = sub(point.x, point.y, point.z) - - override fun sub(value: Double) = sub(value, value, value) - - override fun minus(point: Point) = sub(point) - - override fun minus(value: Double) = sub(value) - - override fun mul(x: Double, y: Double, z: Double) = copy(x = this.x * x, y = this.y * y, z = this.z * z) - - override fun mul(point: Point) = mul(point.x, point.y, point.z) - - override fun mul(value: Double) = mul(value, value, value) - - override fun times(point: Point) = mul(point) - - override fun times(value: Double) = mul(value) - - override fun div(x: Double, y: Double, z: Double) = copy(x = this.x / x, y = this.y / y, z = this.z / z) - - override fun div(point: Point) = div(point.x, point.y, point.z) - - override fun div(value: Double) = div(value, value, value) -} - -fun org.bukkit.Location.toProperty(): LocationProperty { - return LocationProperty(this) -} diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/DialogueEntry.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/DialogueEntry.kt deleted file mode 100644 index 971d3ae571..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/entry/entries/DialogueEntry.kt +++ /dev/null @@ -1,16 +0,0 @@ -package me.gabber235.typewriter.entry.entries - -import me.gabber235.typewriter.adapters.Tags -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry - -@Tags("dialogue") -interface DialogueEntry : TriggerableEntry { - @Help("The speaker of the dialogue") - val speaker: Ref - - val speakerDisplayName: String - get() = speaker.get()?.displayName ?: "" -} - diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/events/TypewriterReloadEvent.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/events/TypewriterReloadEvent.kt deleted file mode 100644 index f899c00843..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/events/TypewriterReloadEvent.kt +++ /dev/null @@ -1,16 +0,0 @@ -package me.gabber235.typewriter.events - -import org.bukkit.event.Event -import org.bukkit.event.HandlerList - -class TypewriterReloadEvent : Event() { - override fun getHandlers(): HandlerList = HANDLER_LIST - - companion object { - @JvmStatic - val HANDLER_LIST = HandlerList() - - @JvmStatic - fun getHandlerList(): HandlerList = HANDLER_LIST - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/bstats/BStatsMetrics.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/bstats/BStatsMetrics.kt deleted file mode 100644 index dbf649dcb4..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/extensions/bstats/BStatsMetrics.kt +++ /dev/null @@ -1,31 +0,0 @@ -package me.gabber235.typewriter.extensions.bstats - -import me.gabber235.typewriter.adapters.AdapterLoader -import me.gabber235.typewriter.entry.Entry -import me.gabber235.typewriter.entry.Query -import me.gabber235.typewriter.plugin -import org.bstats.bukkit.Metrics -import org.bstats.charts.AdvancedPie -import org.bukkit.plugin.java.JavaPlugin -import org.koin.java.KoinJavaComponent.get -import kotlin.reflect.full.findAnnotation - -object BStatsMetrics { - private const val ID = 17839 - fun registerMetrics() { - val metrics = Metrics(plugin as JavaPlugin, ID) - - metrics.addCustomChart(AdvancedPie("adapters") { - val adapters = get(AdapterLoader::class.java) - adapters.adapters.associate { it.name to 1 }.toMap() - }) - - metrics.addCustomChart(AdvancedPie("entries") { - val entries = Query.find() - entries.groupBy { - it::class.findAnnotation()?.name ?: it::class.simpleName - ?: "Unknown" - }.mapValues { it.value.size }.toMap() - }) - } -} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ServerCommandMap.kt b/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ServerCommandMap.kt deleted file mode 100644 index 550bb31927..0000000000 --- a/plugin/src/main/kotlin/me/gabber235/typewriter/utils/ServerCommandMap.kt +++ /dev/null @@ -1,35 +0,0 @@ -package me.gabber235.typewriter.utils - -import dev.jorel.commandapi.CommandAPI -import dev.jorel.commandapi.CommandTree -import me.gabber235.typewriter.entry.EntryDatabase -import me.gabber235.typewriter.entry.entries.CustomCommandEntry -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.plugin -import org.koin.java.KoinJavaComponent.get - -fun CustomCommandEntry.Companion.refreshAndRegisterAll(newEntries: List): List { - val oldEntries = get(EntryDatabase::class.java).commandEvents - - if (oldEntries.isEmpty() && newEntries.isEmpty()) return emptyList() - - oldEntries.forEach { it.unregister() } - newEntries.forEach { it.register() } - - return newEntries -} - -fun CustomCommandEntry.register() { - if (command.isBlank()) { - logger.warning("Command for $name is blank. Skipping registration.") - return - } - CommandTree(command).apply { builder() }.register(plugin) - - logger.info("Registered command $command for $name (${id})") -} - -fun CustomCommandEntry.unregister() { - if (command.isBlank()) return - CommandAPI.unregister(command) -} \ No newline at end of file diff --git a/plugin/src/main/resources/plugin.yml b/plugin/src/main/resources/plugin.yml deleted file mode 100644 index 2d5a52c76f..0000000000 --- a/plugin/src/main/resources/plugin.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Typewriter -version: '${version}' -main: me.gabber235.typewriter.Typewriter -api-version: "1.21" -softdepend: - - PlaceholderAPI - - floodgate -depend: [ packetevents ] -authors: [ gabber235 ] -description: Minecraft's Real Quest Plugin -libraries: ${libraries} From 79979b47e4e645e1107221228e89e74278bcf1d9 Mon Sep 17 00:00:00 2001 From: Marten Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:25:03 +0200 Subject: [PATCH 04/32] [Docs] (hopefully) temporary build fixes --- .../02-extensions/07-api-changes/0.6.mdx | 2 +- documentation/docusaurus.config.js | 6 +- documentation/package-lock.json | 147 ++++++++++-------- .../plugins/code-snippets/codeSnippets.js | 71 ++++++--- .../plugins/code-snippets/snippets.json | 118 +++++--------- 5 files changed, 180 insertions(+), 164 deletions(-) diff --git a/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx b/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx index 966a86d1e3..4960a75743 100644 --- a/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx +++ b/documentation/docs/develop/02-extensions/07-api-changes/0.6.mdx @@ -5,6 +5,6 @@ title: 0.6.X API Changes # All API changes to 0.6.X As Typewriter changed from `Adapters` to `Extensions`, the API has changed significantly. -It is recommended to reread the [Getting Started](getting_started) guide to get a better understanding of how to create extensions. +It is recommended to reread the [Getting Started](../02-getting_started.mdx) guide to get a better understanding of how to create extensions. diff --git a/documentation/docusaurus.config.js b/documentation/docusaurus.config.js index 1ae08ce989..7948440af8 100644 --- a/documentation/docusaurus.config.js +++ b/documentation/docusaurus.config.js @@ -120,10 +120,10 @@ const config = { label: 'Documentation', }, { - type: 'docSidebar', - sidebarId: 'adapters', - position: 'left', + type: 'docsVersion', label: 'Extensions', + to: '/adapters', + position: 'left', }, { type: 'docSidebar', diff --git a/documentation/package-lock.json b/documentation/package-lock.json index 45341b336f..b522731ab2 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -177,9 +177,9 @@ } }, "node_modules/@algolia/client-common": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.2.3.tgz", - "integrity": "sha512-zqfcbgjYR72Y/rx/+/6g5Li/eV33yhRq5mkGbU06JYBzvGq6viy0gZl1ckCFhLLifKzXZ4yzUQTw/KG6FV+smg==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.2.5.tgz", + "integrity": "sha512-ITE85veJWwClnoNyv7Zydh9U0eKA82cDy8pLw+2hzL+zlzFIvV68ihGOEQ/kXt8N4v+R4MFzvsxnIpMruQzEug==", "license": "MIT", "peer": true, "engines": { @@ -208,15 +208,15 @@ } }, "node_modules/@algolia/client-search": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.2.3.tgz", - "integrity": "sha512-xXdCg8vpiwE8gqSyvjxq8V3qbFa+gHasY5epIz718IByWv3WKLLi/n4SMIfB/zRwXTLVWeGOH/UJSz5VCnAAqg==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.2.5.tgz", + "integrity": "sha512-OVDLzm5BEUbJmjfMm7b0Xx8vkK+NyEh7whPHuap2qy0x7RxQDLMXjiKsBbt1WNq+9nfX6+M/f2t0CJ8ENVuyYQ==", "license": "MIT", "peer": true, "dependencies": { - "@algolia/client-common": "5.2.3", - "@algolia/requester-browser-xhr": "5.2.3", - "@algolia/requester-node-http": "5.2.3" + "@algolia/client-common": "5.2.5", + "@algolia/requester-browser-xhr": "5.2.5", + "@algolia/requester-node-http": "5.2.5" }, "engines": { "node": ">= 14.0.0" @@ -302,13 +302,13 @@ } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.2.3.tgz", - "integrity": "sha512-lezcE4E7ax7JkDGDKA/xAnyAY9p9LZ4AxzsyL0pksqUpOvn4U0msP553M2yJRfsxxdGDp15noCnPuRsh7u8dMg==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.2.5.tgz", + "integrity": "sha512-Ri73PphNy1ceig94xJW9bPdN7uIYFAjpsABpp2Fsun4DmeZD5a4rMCNwwOXXsbC8h+lUzW34zpUf+h4Nk+eaqA==", "license": "MIT", "peer": true, "dependencies": { - "@algolia/client-common": "5.2.3" + "@algolia/client-common": "5.2.5" }, "engines": { "node": ">= 14.0.0" @@ -321,13 +321,13 @@ "license": "MIT" }, "node_modules/@algolia/requester-node-http": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.2.3.tgz", - "integrity": "sha512-xTxsRnJqxG1dylIkxmflrHO9LJfJKjSHqEF5yGdRrtnqIEvb2hiQPCHm2XwqxMa3NBcf6lmydGfJqhPLnRJwtw==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.2.5.tgz", + "integrity": "sha512-/tTdEuWcWHSe/mGMomWkuaFDoRcpfl/jvGISVTPRq3pJvM1FPAzxlh2MXge6C30aUS9bxh3V0aWwgKFCilzyMQ==", "license": "MIT", "peer": true, "dependencies": { - "@algolia/client-common": "5.2.3" + "@algolia/client-common": "5.2.5" }, "engines": { "node": ">= 14.0.0" @@ -4755,9 +4755,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", - "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.3.tgz", + "integrity": "sha512-njripolh85IA9SQGTAqbmnNZTdxv7X/4OYGPz8tgy5JDr8MP+uDBa921GpYEoDDnwm0Hmn5ZPeJgiiSTPoOzkQ==", "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -4803,9 +4803,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", - "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", + "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -5582,9 +5582,9 @@ "optional": true }, "node_modules/bare-fs": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.2.tgz", - "integrity": "sha512-Kcq/FG3lhspzGHK+Q0IMfImuFOmaW/jFofBAUJuuG7H67879JeaPUppUHhgLjJKenfxiO6Ix2AGSd47Pf7mRxg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.3.tgz", + "integrity": "sha512-7RYKL+vZVCyAsMLi5SPu7QGauGGT8avnP/HO571ndEuV4MYdGXvLhtW67FuLPeEI8EiIY7zbbRR9x7x7HU0kgw==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -5595,9 +5595,9 @@ } }, "node_modules/bare-os": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.1.tgz", - "integrity": "sha512-yQC/blMP/eUdULsF7hrcC9tUFXlUmAWRbSQndEln77nOIh/N4Loaqch/MA4hyoDKhw1Zd1Wj+uLV/bT6lC/4BQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.2.tgz", + "integrity": "sha512-HZoJwzC+rZ9lqEemTMiO0luOePoGYNBgsLLgegKR/cljiJvcDNhDZQkzC+NC5Oh0aHbdBNSOHpghwMuB5tqhjg==", "dev": true, "license": "Apache-2.0", "optional": true @@ -5614,13 +5614,14 @@ } }, "node_modules/bare-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.2.0.tgz", - "integrity": "sha512-+o9MG5bPRRBlkVSpfFlMag3n7wMaIZb4YZasU2+/96f+3HTQ4F9DKQeu3K/Sjz1W0umu6xvVq1ON0ipWdMlr3A==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.2.1.tgz", + "integrity": "sha512-YTB47kHwBW9zSG8LD77MIBAAQXjU2WjAkMHeeb7hUplVs6+IoM5I7uEVQNPMB7lj9r8I76UMdoMkGnCodHOLqg==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { + "b4a": "^1.6.6", "streamx": "^2.18.0" } }, @@ -8691,9 +8692,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", @@ -10614,9 +10615,9 @@ } }, "node_modules/launch-editor": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", - "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.2.tgz", + "integrity": "sha512-eF5slEUZXmi6WvFzI3dYcv+hA24/iKnROf24HztcURJpSz9RBmBgz5cNCVOeguouf1llrwy6Yctl4C4HM+xI8g==", "license": "MIT", "dependencies": { "picocolors": "^1.0.0", @@ -12422,9 +12423,9 @@ "license": "MIT" }, "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", "license": "MIT", "dependencies": { "@types/acorn": "^4.0.0", @@ -12434,6 +12435,7 @@ "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" @@ -12705,9 +12707,9 @@ "license": "MIT" }, "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz", + "integrity": "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==", "funding": [ { "type": "GitHub Sponsors", @@ -12722,6 +12724,7 @@ "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -12730,6 +12733,26 @@ "vfile-message": "^4.0.0" } }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", @@ -14301,9 +14324,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/picomatch": { @@ -14427,9 +14450,9 @@ } }, "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "funding": [ { "type": "opencollective", @@ -15669,9 +15692,9 @@ "license": "MIT" }, "node_modules/react-json-view-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz", - "integrity": "sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", "license": "MIT", "engines": { "node": ">=14" @@ -16467,9 +16490,9 @@ } }, "node_modules/search-insights": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.0.tgz", - "integrity": "sha512-AskayU3QNsXQzSL6v4LTYST7NNfs2HWyHHB+sdORP9chsytAhro5XRfToAMI/LAVYgNbzowVZTMfBRodgbUHKg==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.1.tgz", + "integrity": "sha512-HHFjYH/0AqXacETlIbe9EYc3UNlQYGNNTY0fZ/sWl6SweX+GDxq9NB5+RVoPLgEFuOtCz7M9dhYxqDnhbbF0eQ==", "license": "MIT", "peer": true }, @@ -17142,9 +17165,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.19.0.tgz", - "integrity": "sha512-5z6CNR4gtkPbwlxyEqoDGDmWIzoNJqCBt4Eac1ICP9YaIT08ct712cFj0u1rx4F8luAuL+3Qc+RFIdI4OX00kg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.0.tgz", + "integrity": "sha512-ZGd1LhDeGFucr1CUCTBOS58ZhEendd0ttpGT3usTvosS4ntIwKN9LJFp+OeCSprsCPL14BXVRZlHGRY1V9PVzQ==", "dev": true, "license": "MIT", "dependencies": { @@ -19075,9 +19098,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", "dev": true, "license": "ISC", "bin": { diff --git a/documentation/plugins/code-snippets/codeSnippets.js b/documentation/plugins/code-snippets/codeSnippets.js index 4d6f16e26d..11edeb8b21 100644 --- a/documentation/plugins/code-snippets/codeSnippets.js +++ b/documentation/plugins/code-snippets/codeSnippets.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); -const codeBockRegex = /\/\/<(?\/)?code-block:(?[a-zA-Z0-9_]*)>$/; +const codeBlockRegex = /\/\/<(?\/)?code-block:(?[a-zA-Z0-9_]*)>$/; module.exports = function() { const snippets = {}; @@ -10,26 +10,48 @@ module.exports = function() { const content = fs.readFileSync(filePath, 'utf8'); const lines = content.split('\n'); const blocks = {}; + const blockStartLines = {}; lines.forEach((line, index) => { - const match = line.match(codeBockRegex); + const match = line.match(codeBlockRegex); if (match) { const { closing, tag } = match.groups; if (closing) { const code = blocks[tag]; if (!code) { - throw new Error(`Code block not closed: ${tag} (${relativeFilePath}:${index + 1})`); + // Handle the case where a closing tag does not have an opening tag + snippets[tag] = { + file: relativeFilePath, + content: "Not found", // Temporary fix so the docs can be build... + startLine: "N/A", + endLine: index + 1 + }; + } else { + // Close the block and save the snippet + blocks[tag] = null; + snippets[tag] = { + file: relativeFilePath, + content: code.join('\n'), + startLine: blockStartLines[tag] + 1, + endLine: index + 1 + }; } - blocks[tag] = null; - snippets[tag] = { - file: relativeFilePath, - content: code.join('\n') - }; - return; + } else { + if (blocks[tag]) { + // Handle the case where an opening tag already exists + snippets[tag] = { + file: relativeFilePath, + content: "Not found", // Temporary fix so the docs can be build... + startLine: blockStartLines[tag] + 1, + endLine: index + 1 + }; + } + // Start a new block + blocks[tag] = []; + blockStartLines[tag] = index; } - - blocks[tag] = []; } else { + // Add lines to the current blocks for (const tag in blocks) { const code = blocks[tag]; if (!code) continue; @@ -41,11 +63,14 @@ module.exports = function() { // Handle any unclosed blocks for (const tag in blocks) { const code = blocks[tag]; - if (!code) continue; - snippets[tag] = { - file: relativeFilePath, - content: code.join('\n') - }; + if (code) { + snippets[tag] = { + file: relativeFilePath, + content: "Not found", // Temporary fix so the docs can be build... + startLine: blockStartLines[tag] + 1, + endLine: "N/A" + }; + } } } @@ -58,7 +83,13 @@ module.exports = function() { if (stat.isDirectory()) { traverseDirectory(filePath, baseDir); } else if (path.extname(filePath) === '.kt') { - processFile(filePath, relativeFilePath); + try { + processFile(filePath, relativeFilePath); + } catch (error) { + // Improve error handling by showing which file failed + console.error(`Error processing file: ${relativeFilePath}`); + throw error; + } } }); } @@ -67,13 +98,11 @@ module.exports = function() { const adaptersDir = path.resolve(__dirname, '../../../extensions/_DocsExtension'); traverseDirectory(adaptersDir, adaptersDir); - // console.log(`Exporting ${Object.keys(snippets).length} snippets: ${Object.keys(snippets)}`); - this.cacheable(false); const code = `${JSON.stringify(snippets, null, 2)}`; - fs.writeSync(fs.openSync(path.resolve(__dirname, 'snippets.json'), 'w'), code); + fs.writeFileSync(path.resolve(__dirname, 'snippets.json'), code); return `export default ${JSON.stringify(snippets, null, 2)}`; -}; +}; \ No newline at end of file diff --git a/documentation/plugins/code-snippets/snippets.json b/documentation/plugins/code-snippets/snippets.json index 09b958319a..4a27ba930a 100644 --- a/documentation/plugins/code-snippets/snippets.json +++ b/documentation/plugins/code-snippets/snippets.json @@ -1,98 +1,62 @@ { - "initializer": { - "file": "src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt", - "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Initializer\n\n@Initializer\nobject ExampleInitializer : Initializable {\n override fun initialize() {\n // Do something when the extension is initialized\n }\n\n override fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" - }, - "cinematic_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": "@Entry(\"example_cinematic\", \"An example cinematic entry\", Colors.BLUE, \"material-symbols:cinematic-blur\")\nclass ExampleCinematicEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n val segments: List = emptyList(),\n) : CinematicEntry {\n override fun create(player: Player): CinematicAction {\n return ExampleCinematicAction(player, this)\n }\n}" - }, - "cinematic_segment_with_min_max": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": " @Segments(Colors.BLUE, \"material-symbols:cinematic-blur\")\n @InnerMin(Min(10))\n @InnerMax(Max(20))\n val segments: List = emptyList()," - }, - "cinematic_create_actions": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": " // This will be used when the cinematic is normally displayed to the player.\n override fun create(player: Player): CinematicAction {\n return DefaultCinematicAction(player, this)\n }\n\n // This is used during content mode to display the cinematic to the player.\n // It may be null to not show it during simulation.\n override fun createSimulating(player: Player): CinematicAction? {\n return SimulatedCinematicAction(player, this)\n }\n\n // This is used during content mode to record the cinematic.\n // It may be null to not record it during simulation.\n override fun createRecording(player: Player): CinematicAction? {\n return RecordingCinematicAction(player, this)\n }" - }, - "cinematic_segment": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": "data class ExampleSegment(\n override val startFrame: Int = 0,\n override val endFrame: Int = 0,\n) : Segment" - }, - "cinematic_action": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": "class ExampleCinematicAction(\n val player: Player,\n val entry: ExampleCinematicEntry,\n) : CinematicAction {\n override suspend fun setup() {\n // Initialize variables, spawn entities, etc.\n }\n\n override suspend fun tick(frame: Int) {\n val segment = entry.segments activeSegmentAt frame\n // Can be null if no segment is active\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n\n // Execute tick logic for the segment\n }\n\n override suspend fun teardown() {\n // Remove entities, etc.\n }\n\n override fun canFinish(frame: Int): Boolean = entry.segments canFinishAt frame\n}" - }, - "cinematic_simple_action": { - "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": "class ExampleSimpleCinematicAction(\n val player: Player,\n entry: ExampleCinematicEntry,\n) : SimpleCinematicAction() {\n override val segments: List = entry.segments\n\n override suspend fun startSegment(segment: ExampleSegment) {\n super.startSegment(segment) // Keep this\n // Called when a segment starts\n }\n\n override suspend fun tickSegment(segment: ExampleSegment, frame: Int) {\n super.tickSegment(segment, frame) // Keep this\n // Called every tick while the segment is active\n // Will always be called after startSegment and never after stopSegment\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n }\n\n override suspend fun stopSegment(segment: ExampleSegment) {\n super.stopSegment(segment) // Keep this\n // Called when the segment ends\n // Will also be called if the cinematic is stopped early\n }\n}" - }, - "audience_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", - "content": "@Entry(\"example_audience\", \"An example audience entry.\", Colors.GREEN, \"material-symbols:chat-rounded\")\nclass ExampleAudienceEntry(\n override val id: String,\n override val name: String,\n) : AudienceEntry {\n override fun display(): AudienceDisplay {\n return ExampleAudienceDisplay()\n }\n}" - }, - "audience_display": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", - "content": "class ExampleAudienceDisplay : AudienceDisplay() {\n override fun initialize() {\n // This is called when the first player is added to the audience.\n super.initialize()\n // Do something when the audience is initialized\n }\n\n override fun onPlayerAdd(player: Player) {\n // Do something when a player gets added to the audience\n }\n\n override fun onPlayerRemove(player: Player) {\n // Do something when a player gets removed from the audience\n }\n\n override fun dispose() {\n super.dispose()\n // Do something when the audience is disposed\n // It will always call onPlayerRemove for all players.\n // So no player cleanup is needed here.\n }\n}" - }, - "tickable_audience_display": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", - "content": "// highlight-next-line\nclass TickableAudienceDisplay : AudienceDisplay(), TickableDisplay {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n override fun tick() {\n // Do something when the audience is ticked\n players.forEach { player ->\n // Do something with the player\n }\n\n // This is running asynchronously\n // If you need to do something on the main thread\n ThreadType.SYNC.launch {\n // Though this will run a tick later, to sync with the bukkit scheduler.\n }\n }\n // highlight-end\n}" - }, "audience_display_with_events": { - "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", - "content": "class AudienceDisplayWithEvents : AudienceDisplay() {\n override fun onPlayerAdd(player: Player) {}\n override fun onPlayerRemove(player: Player) {}\n\n // highlight-start\n @EventHandler\n fun onSomeEvent(event: SomeBukkitEvent) {\n // Do something when the event is triggered\n // This will trigger for all players, not just the ones in the audience.\n // So we need to check if the player is in the audience.\n if (event.player in this) {\n // Do something with the player\n }\n }\n // highlight-end\n}" - }, - "artifact_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", - "content": "@Entry(\"example_artifact\", \"An example artifact entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleArtifactEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val artifactId: String = \"\",\n) : ArtifactEntry" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\manifest\\ExampleAudienceEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 90 }, "artifact_access": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleArtifactEntry.kt", - "content": "suspend fun accessArtifactData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" - }, - "asset_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", - "content": "@Entry(\"example_asset\", \"An example asset entry.\", Colors.BLUE, \"material-symbols:home-storage-rounded\")\nclass ExampleAssetEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val path: String = \"\",\n) : AssetEntry" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleArtifactEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 26 }, "asset_access": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleAssetEntry.kt", - "content": "suspend fun accessAssetData(ref: Ref) {\n val assetManager = KoinJavaComponent.get(AssetManager::class.java)\n val entry = ref.get() ?: return\n val content: String? = assetManager.fetchAsset(entry)\n // Do something with the content\n}" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleAssetEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 26 }, "sound_id_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundIdEntry.kt", - "content": "@Entry(\"example_sound\", \"An example sound entry.\", Colors.BLUE, \"icon-park-solid:volume-up\")\nclass ExampleSoundIdEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val soundId: String = \"\",\n) : SoundIdEntry" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundIdEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 14 }, "sound_source_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSoundSourceEntry.kt", - "content": "@Entry(\"example_sound_source\", \"An example sound source entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSoundSourceEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n) : SoundSourceEntry {\n override fun getEmitter(): Sound.Emitter {\n // Return the emitter that should be used for the sound.\n // A bukkit entity can be used here.\n return Sound.Emitter.self()\n }\n}" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSoundSourceEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 20 }, "speaker_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleSpeakerEntry.kt", - "content": "@Entry(\"example_speaker\", \"An example speaker entry.\", Colors.BLUE, \"ic:round-spatial-audio-off\")\nclass ExampleSpeakerEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val displayName: String = \"\",\n override val sound: Sound = Sound.EMPTY,\n) : SpeakerEntry" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\static\\ExampleSpeakerEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 16 }, "action_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt", - "content": "@Entry(\"example_action\", \"An example action entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n) : ActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply all the modifiers.\n // Do something with the player\n }\n}" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleActionEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 26 }, "custom_triggering_action_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt", - "content": "@Entry(\n \"example_custom_triggering_action\",\n \"An example custom triggering entry.\",\n Colors.RED,\n \"material-symbols:touch-app-rounded\"\n)\nclass ExampleCustomTriggeringActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n @SerializedName(\"triggers\")\n override val customTriggers: List> = emptyList(),\n) : CustomTriggeringActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply the modifiers.\n // Do something with the player\n player.triggerCustomTriggers() // Can be called later to trigger the next entries.\n }\n}" - }, - "dialogue_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", - "content": "@Entry(\"example_dialogue\", \"An example dialogue entry.\", Colors.BLUE, \"material-symbols:chat-rounded\")\nclass ExampleDialogueEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n override val speaker: Ref = emptyRef(),\n @MultiLine\n @Placeholder\n @Colored\n @Help(\"The text to display to the player.\")\n val text: String = \"\",\n) : DialogueEntry" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleCustomTriggeringActionEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 34 }, "dialogue_messenger": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", - "content": "@Messenger(ExampleDialogueEntry::class)\nclass ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) :\n DialogueMessenger(player, entry) {\n\n companion object : MessengerFilter {\n override fun filter(player: Player, entry: DialogueEntry): Boolean = true\n }\n\n // Called every game tick (20 times per second).\n // The cycle is a parameter that is incremented every tick, starting at 0.\n override fun tick(playTime: Duration) {\n super.tick(playTime)\n if (state != MessengerState.RUNNING) return\n\n player.sendMessage(\"${entry.speakerDisplayName}: ${entry.text}\".parsePlaceholders(player).asMini())\n\n // When we want the dialogue to end, we can set the state to FINISHED.\n state = MessengerState.FINISHED\n }\n}" + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\entries\\trigger\\ExampleDialogueEntry.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 58 }, - "event_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", - "content": "@Entry(\"example_event\", \"An example event entry.\", Colors.YELLOW, \"material-symbols:bigtop-updates\")\nclass ExampleEventEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n) : EventEntry" - }, - "event_entry_listener": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", - "content": "// Must be scoped to be public\n@EntryListener(ExampleEventEntry::class)\nfun onEvent(event: SomeBukkitEvent, query: Query) {\n // Do something\n val entries = query.find() // Find all the entries of this type, for more information see the Query section\n // Do something with the entries, for example trigger them\n entries triggerAllFor event.player\n}" + "initializer": { + "file": "src\\main\\kotlin\\com\\typewritermc\\example\\ExampleInitializer.kt", + "content": "Not found", + "startLine": "N/A", + "endLine": 17 } } \ No newline at end of file From 881cc563e9619eb7374acd5c703fc816f848c7de Mon Sep 17 00:00:00 2001 From: Marten Mrfc <101009922+Marten-Mrfc@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:26:05 +0200 Subject: [PATCH 05/32] [Docs] Idk apple fix hopefully(Aargh) --- documentation/src/components/Player/index.tsx | 83 ++++++++++++------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/documentation/src/components/Player/index.tsx b/documentation/src/components/Player/index.tsx index 71b5def0e6..fd1af54b1b 100644 --- a/documentation/src/components/Player/index.tsx +++ b/documentation/src/components/Player/index.tsx @@ -1,7 +1,8 @@ -import React, { useState, useRef } from "react"; +import React, { useState, useRef, useEffect } from "react"; import ReactPlayer from "react-player"; import { Icon } from "@iconify/react"; -import fullscreen from "screenfull"; +import screenfull from "screenfull"; +import debounce from "lodash.debounce"; interface PlayerProps { url: string; @@ -10,19 +11,40 @@ interface PlayerProps { export default function Player({ url }: PlayerProps) { const [progress, setProgress] = useState(0); const [playing, setPlaying] = useState(true); + const [isFullscreen, setIsFullscreen] = useState(false); const playerRef = useRef(null); - const playerContainerRef = useRef(null); + const playerContainerRef = useRef(null); const togglePlayPause = () => { setPlaying((prev) => !prev); }; - const handleSeek = (e: React.ChangeEvent) => { + const handleSeek = debounce((e: React.ChangeEvent) => { const newProgress = parseFloat(e.target.value); setProgress(newProgress); playerRef.current?.seekTo(newProgress / 100, "fraction"); + }, 200); + + const handleFullscreenToggle = () => { + if (screenfull.isEnabled) { + screenfull.toggle(playerContainerRef.current); + } }; + useEffect(() => { + if (screenfull.isEnabled) { + screenfull.on("change", () => { + setIsFullscreen(screenfull.isFullscreen); + }); + + return () => { + screenfull.off("change", () => { + setIsFullscreen(screenfull.isFullscreen); + }); + }; + } + }, []); + return (