├── .github
└── workflows
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle.kts
├── common-applicative
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── common
│ │ └── applicative
│ │ ├── AbstractApplicative.kt
│ │ ├── Applicative.kt
│ │ ├── ApplicativeRegistry.kt
│ │ ├── ApplicativeUtil.kt
│ │ ├── Applicatives.kt
│ │ ├── BooleanApplicative.kt
│ │ ├── ColorApplicative.kt
│ │ ├── DoubleApplicative.kt
│ │ ├── EntityApplicative.kt
│ │ ├── FloatApplicative.kt
│ │ ├── IntApplicative.kt
│ │ ├── InvalidValueException.kt
│ │ ├── InventoryApplicative.kt
│ │ ├── ItemStackApplicative.kt
│ │ ├── ListApplicative.kt
│ │ ├── LocationApplicative.kt
│ │ ├── LongApplicative.kt
│ │ ├── MapApplicative.kt
│ │ ├── PlayerApplicative.kt
│ │ ├── StringApplicative.kt
│ │ ├── UnsupportedTypeException.kt
│ │ └── VectorApplicative.kt
│ └── resources
│ └── lang
│ └── zh_CN.yml
├── common-config
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── common
│ │ └── config
│ │ ├── ConfigService.kt
│ │ ├── ConfigServiceCallback.kt
│ │ ├── ConfigUtil.kt
│ │ ├── Configs.kt
│ │ ├── DelegateConfigNode.kt
│ │ ├── ExceptionalLiveData.kt
│ │ ├── InvalidFieldException.kt
│ │ ├── LiveData.kt
│ │ ├── LiveDataConversion.kt
│ │ └── LiveDataTransformer.kt
│ └── resources
│ └── lang
│ └── zh_CN.yml
├── common-core
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ ├── NmsHandler.kt
│ │ ├── Vulpecula.kt
│ │ ├── VulpeculaAPI.kt
│ │ ├── command
│ │ └── VulpeculaCommandRegistry.kt
│ │ ├── metrics
│ │ └── VulpeculaMetrics.kt
│ │ └── utils
│ │ └── TimingUtil.kt
│ └── resources
│ └── config.yml
├── common-message
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── common
│ │ └── message
│ │ ├── MessageIO.kt
│ │ └── MessageService.kt
│ └── resources
│ └── lang
│ └── zh_CN.yml
├── extension-action-item
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── top
│ └── lanscarlos
│ └── vulpecula
│ └── action
│ └── item
│ └── ActionItemBuild.kt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── module-bacikal
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── module
│ │ └── bacikal
│ │ ├── BacikalCommand.kt
│ │ ├── BacikalRegistry.kt
│ │ ├── BacikalService.kt
│ │ ├── annotation
│ │ ├── Additional.kt
│ │ ├── BacikalParser.kt
│ │ ├── Expected.kt
│ │ └── Optional.kt
│ │ ├── exception
│ │ ├── BacikalCompileException.kt
│ │ ├── BacikalException.kt
│ │ ├── BacikalRuntimeException.kt
│ │ └── BacikalTimeoutException.kt
│ │ ├── parser
│ │ ├── BacikalAction.kt
│ │ ├── BacikalActionParser.kt
│ │ ├── BacikalActionResolver.kt
│ │ ├── BacikalComplexActionParser.kt
│ │ ├── BacikalFrame.kt
│ │ ├── BacikalReader.kt
│ │ ├── DefaultFrame.kt
│ │ └── DefaultReader.kt
│ │ └── quest
│ │ ├── BacikalQuestCompiler.kt
│ │ ├── BacikalQuestExecutor.kt
│ │ ├── BacikalQuestLoader.kt
│ │ ├── CffuDependency.kt
│ │ └── KetherQuestExecutor.kt
│ └── resources
│ ├── bacikal-registry.yml
│ └── lang
│ └── zh_CN.yml
├── module-command
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── module
│ │ └── command
│ │ ├── BooleanSuggester.kt
│ │ ├── CommandService.kt
│ │ ├── CustomCommand.kt
│ │ ├── DoubleRestrictor.kt
│ │ ├── DynamicNode.kt
│ │ ├── IntRestrictor.kt
│ │ ├── ListSuggester.kt
│ │ ├── LiteralNode.kt
│ │ ├── MainNode.kt
│ │ ├── MaterialSuggester.kt
│ │ ├── Node.kt
│ │ ├── OfflinePlayerSuggester.kt
│ │ ├── PlayerSuggester.kt
│ │ ├── ReloadCommand.kt
│ │ ├── Restrictor.kt
│ │ ├── ScriptExecutor.kt
│ │ ├── Suggester.kt
│ │ └── WorldSuggester.kt
│ └── resources
│ ├── command
│ └── example.yml
│ └── lang
│ └── zh_CN.yml
├── module-core
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── top
│ └── lanscarlos
│ └── vulpecula
│ └── module
│ └── core
│ └── command
│ └── ReloadCommand.kt
├── module-dispatcher
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── dispatcher
│ │ ├── AbstractDispatcher.kt
│ │ ├── Context.kt
│ │ ├── DefaultTrigger.kt
│ │ ├── Dispatcher.kt
│ │ ├── Listener.kt
│ │ ├── Trigger.kt
│ │ ├── condition
│ │ ├── Condition.kt
│ │ ├── Conditions.kt
│ │ └── PlayerCondition.kt
│ │ └── rule
│ │ ├── AbstractRule.kt
│ │ ├── GenericEventRule.kt
│ │ ├── PlayerMoveEventRule.kt
│ │ ├── Rule.kt
│ │ └── Rules.kt
│ └── resources
│ └── dispatcher
│ ├── def.yml
│ └── example
│ └── PlayerMoveDispatcher.yml
├── module-item-test
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── top
│ └── lanscarlos
│ └── vulpecula
│ └── module
│ └── item
│ ├── CustomEnchantment.kt
│ ├── DefaultEntityInLevelCallback.kt
│ ├── DefaultVolatileAPI.kt
│ ├── EnchantmentAPI.kt
│ ├── EquipmentSource.kt
│ ├── InventorySource.kt
│ ├── ItemEntityHandler.kt
│ ├── ItemHolder.kt
│ ├── ItemNameEditor.kt
│ ├── ItemSource.kt
│ ├── ItemStackSource.kt
│ ├── ItemStream.kt
│ └── VolatileAPI.kt
├── module-item
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── top
│ └── lanscarlos
│ └── vulpecula
│ └── module
│ └── item
│ ├── DefaultItemStream.kt
│ ├── EquipmentSource.kt
│ ├── InventorySource.kt
│ ├── ItemCommand.kt
│ ├── ItemSource.kt
│ ├── ItemStackSource.kt
│ └── ItemStream.kt
├── module-schedule
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── module
│ │ └── schedule
│ │ ├── AbstractSchedule.kt
│ │ ├── CronSchedule.kt
│ │ ├── PeriodicSchedule.kt
│ │ ├── Schedule.kt
│ │ ├── ScheduleCommand.kt
│ │ ├── ScheduleService.kt
│ │ ├── ScheduleTask.kt
│ │ ├── SenderSelector.kt
│ │ ├── TaskState.kt
│ │ └── selector
│ │ ├── AreaSelector.kt
│ │ ├── ConsoleSelector.kt
│ │ ├── OnlinePlayerSelector.kt
│ │ ├── PlayerSelector.kt
│ │ ├── RangeSelector.kt
│ │ ├── SelfSelector.kt
│ │ └── WorldSelector.kt
│ └── resources
│ ├── lang
│ └── zh_CN.yml
│ └── schedule
│ ├── cron.yml
│ └── periodic.yml
├── module-script
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── module
│ │ └── script
│ │ ├── AbstractScript.kt
│ │ ├── CompiledScript.kt
│ │ ├── DefaultScriptTask.kt
│ │ ├── NativeScript.kt
│ │ ├── ProxyScript.kt
│ │ ├── Script.kt
│ │ ├── ScriptCommand.kt
│ │ ├── ScriptService.kt
│ │ ├── ScriptTask.kt
│ │ └── exception
│ │ └── ScriptNotFoundException.kt
│ └── resources
│ ├── lang
│ └── zh_CN.yml
│ └── script
│ └── example.yml
├── module-wireshark
├── build.gradle.kts
└── src
│ └── main
│ ├── kotlin
│ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── wireshark
│ │ ├── ClientboundLevelChunkWithLightPacketMapper.kt
│ │ ├── ComplexPacketFilter.kt
│ │ ├── DefaultPacketMatcher.kt
│ │ ├── DefaultPacketTracker.kt
│ │ ├── NamedPacketFilter.kt
│ │ ├── PacketCache.kt
│ │ ├── PacketDispatcher.kt
│ │ ├── PacketFilter.kt
│ │ ├── PacketMatcher.kt
│ │ ├── PacketMatcherBuilder.kt
│ │ ├── PacketTracker.kt
│ │ ├── Session.kt
│ │ └── Wireshark.kt
│ └── resources
│ └── config
│ └── wireshark.conf
├── platform-bukkit
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── top
│ └── lanscarlos
│ └── vulpecula
│ └── platform
│ └── bukkit
│ └── VulpeculaPlugin.kt
├── plugin-mini
└── build.gradle.kts
├── project
├── common-core
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ ├── kotlin
│ │ └── top
│ │ │ └── lanscarlos
│ │ │ └── vulpecula
│ │ │ └── core
│ │ │ ├── ClassAliases.kt
│ │ │ ├── modularity
│ │ │ ├── DefaultCommand.kt
│ │ │ ├── DefaultCommandComponent.kt
│ │ │ ├── DefaultDispatcher.kt
│ │ │ ├── DefaultModule.kt
│ │ │ ├── DispatcherPipeline.kt
│ │ │ ├── ModularCommand.kt
│ │ │ ├── ModularComponent.kt
│ │ │ ├── ModularDispatcher.kt
│ │ │ ├── ModularSchedule.kt
│ │ │ ├── ModularScript.kt
│ │ │ ├── Module.kt
│ │ │ └── pipeline
│ │ │ │ ├── AbstractPipeline.kt
│ │ │ │ ├── InteractPipeline.kt
│ │ │ │ ├── MovePipeline.kt
│ │ │ │ └── PlayerPipeline.kt
│ │ │ └── utils
│ │ │ └── MessageUtil.kt
│ │ └── resources
│ │ ├── class-aliases.yml
│ │ ├── config.yml
│ │ ├── lang
│ │ └── zh_CN.yml
│ │ └── modules
│ │ └── #def
│ │ └── module.yml
├── common-legacy
│ ├── build.gradle.kts
│ ├── libs
│ │ ├── AbolethCoreAPI-1.0.0.jar
│ │ └── AdyeshachAPI-2.0.0-snapshot-30.jar
│ └── src
│ │ └── main
│ │ ├── kotlin
│ │ └── top
│ │ │ └── lanscarlos
│ │ │ └── vulpecula
│ │ │ └── legacy
│ │ │ ├── Vulpecula.kt
│ │ │ ├── VulpeculaContext.kt
│ │ │ ├── api
│ │ │ ├── VulpeculaAPI.kt
│ │ │ ├── chemdah
│ │ │ │ ├── DataMatch.kt
│ │ │ │ ├── Flags.kt
│ │ │ │ ├── InferItem.kt
│ │ │ │ └── Utils.kt
│ │ │ └── event
│ │ │ │ └── InferItemHookEvent.kt
│ │ │ ├── bacikal
│ │ │ ├── Applicative.kt
│ │ │ ├── Bacikal.kt
│ │ │ ├── BacikalGenericProperty.kt
│ │ │ ├── BacikalParser.kt
│ │ │ ├── BacikalProperty.kt
│ │ │ ├── BacikalReader.kt
│ │ │ ├── BacikalRegistry.kt
│ │ │ ├── BacikalScriptLoader.kt
│ │ │ ├── BacikalUtil.kt
│ │ │ ├── BacikalWorkspace.kt
│ │ │ ├── LiveData.kt
│ │ │ ├── LiveDataProxy.kt
│ │ │ ├── RegistryMetadata.kt
│ │ │ ├── action
│ │ │ │ ├── ActionBlock.kt
│ │ │ │ ├── ActionIfElse.kt
│ │ │ │ ├── ActionInput.kt
│ │ │ │ ├── ActionMemory.kt
│ │ │ │ ├── ActionRegex.kt
│ │ │ │ ├── ActionSound.kt
│ │ │ │ ├── ActionTellRaw.kt
│ │ │ │ ├── ActionTryCatch.kt
│ │ │ │ ├── canvas
│ │ │ │ │ ├── ActionBrush.kt
│ │ │ │ │ ├── ActionCanvas.kt
│ │ │ │ │ ├── ActionDraw.kt
│ │ │ │ │ ├── ActionDuration.kt
│ │ │ │ │ ├── ActionViewers.kt
│ │ │ │ │ ├── CanvasBrush.kt
│ │ │ │ │ ├── CanvasQuest.kt
│ │ │ │ │ ├── CanvasScriptContext.kt
│ │ │ │ │ ├── fx
│ │ │ │ │ │ ├── ActionFx.kt
│ │ │ │ │ │ ├── ConstantFx.kt
│ │ │ │ │ │ ├── DecimalFx.kt
│ │ │ │ │ │ ├── EntityDirectionFx.kt
│ │ │ │ │ │ ├── EntityPitchFx.kt
│ │ │ │ │ │ ├── EntityYawFx.kt
│ │ │ │ │ │ ├── Fx.kt
│ │ │ │ │ │ ├── FxLiveData.kt
│ │ │ │ │ │ ├── LinearFx.kt
│ │ │ │ │ │ ├── NumberFx.kt
│ │ │ │ │ │ ├── RandomFx.kt
│ │ │ │ │ │ ├── SimpleVectorFx.kt
│ │ │ │ │ │ ├── SineFx.kt
│ │ │ │ │ │ └── VectorFx.kt
│ │ │ │ │ └── pattern
│ │ │ │ │ │ ├── ActionPattern.kt
│ │ │ │ │ │ ├── ActionPatternSelect.kt
│ │ │ │ │ │ ├── BezierCurvePattern.kt
│ │ │ │ │ │ ├── CanvasPattern.kt
│ │ │ │ │ │ ├── CirclePattern.kt
│ │ │ │ │ │ ├── LinePattern.kt
│ │ │ │ │ │ ├── LissajousCurvePattern.kt
│ │ │ │ │ │ ├── PatternTransformation.kt
│ │ │ │ │ │ ├── PentagramPattern.kt
│ │ │ │ │ │ ├── PolygonPattern.kt
│ │ │ │ │ │ ├── RotationTransformer.kt
│ │ │ │ │ │ ├── ScalingTransformer.kt
│ │ │ │ │ │ ├── SquarePattern.kt
│ │ │ │ │ │ ├── StarPattern.kt
│ │ │ │ │ │ ├── Transformer.kt
│ │ │ │ │ │ ├── TranslationTransformer.kt
│ │ │ │ │ │ └── TrianglePattern.kt
│ │ │ │ ├── entity
│ │ │ │ │ ├── ActionEntity.kt
│ │ │ │ │ ├── ActionEntityDamage.kt
│ │ │ │ │ ├── ActionEntityPotion.kt
│ │ │ │ │ └── ActionEntityTeleport.kt
│ │ │ │ ├── event
│ │ │ │ │ ├── ActionEvent.kt
│ │ │ │ │ ├── ActionEventCancel.kt
│ │ │ │ │ ├── ActionEventCancelled.kt
│ │ │ │ │ ├── ActionEventName.kt
│ │ │ │ │ └── ActionEventWait.kt
│ │ │ │ ├── illusion
│ │ │ │ │ ├── ActionIllusion.kt
│ │ │ │ │ ├── ActionIllusionHealth.kt
│ │ │ │ │ ├── ActionIllusionHologram.kt
│ │ │ │ │ └── ActionIllusionSwitch.kt
│ │ │ │ ├── internal
│ │ │ │ │ ├── ActionFunction.kt
│ │ │ │ │ ├── ActionUnicode.kt
│ │ │ │ │ ├── ActionVulpecula.kt
│ │ │ │ │ ├── ActionVulpeculaDispatcher.kt
│ │ │ │ │ ├── ActionVulpeculaSchedule.kt
│ │ │ │ │ └── ActionVulpeculaScript.kt
│ │ │ │ ├── inventory
│ │ │ │ │ ├── ActionInventory.kt
│ │ │ │ │ ├── ActionInventoryCheck.kt
│ │ │ │ │ ├── ActionInventoryCount.kt
│ │ │ │ │ ├── ActionInventoryFind.kt
│ │ │ │ │ ├── ActionInventorySwitch.kt
│ │ │ │ │ └── ActionInventoryTake.kt
│ │ │ │ ├── item
│ │ │ │ │ ├── ActionItem.kt
│ │ │ │ │ ├── ActionItemAmount.kt
│ │ │ │ │ ├── ActionItemBuild.kt
│ │ │ │ │ ├── ActionItemColor.kt
│ │ │ │ │ ├── ActionItemConsume.kt
│ │ │ │ │ ├── ActionItemDestroy.kt
│ │ │ │ │ ├── ActionItemDrop.kt
│ │ │ │ │ ├── ActionItemDurability.kt
│ │ │ │ │ ├── ActionItemEnchantment.kt
│ │ │ │ │ ├── ActionItemFlag.kt
│ │ │ │ │ ├── ActionItemGive.kt
│ │ │ │ │ ├── ActionItemLore.kt
│ │ │ │ │ ├── ActionItemMatch.kt
│ │ │ │ │ ├── ActionItemModify.kt
│ │ │ │ │ ├── ActionItemPotion.kt
│ │ │ │ │ ├── ActionItemTag.kt
│ │ │ │ │ └── ActionItemUnbreakable.kt
│ │ │ │ ├── location
│ │ │ │ │ ├── ActionLocation.kt
│ │ │ │ │ ├── ActionLocationAdd.kt
│ │ │ │ │ ├── ActionLocationBuild.kt
│ │ │ │ │ ├── ActionLocationClone.kt
│ │ │ │ │ ├── ActionLocationDistance.kt
│ │ │ │ │ ├── ActionLocationDistanceSquared.kt
│ │ │ │ │ ├── ActionLocationDivide.kt
│ │ │ │ │ ├── ActionLocationModify.kt
│ │ │ │ │ ├── ActionLocationMultiply.kt
│ │ │ │ │ └── ActionLocationSubtract.kt
│ │ │ │ ├── math
│ │ │ │ │ ├── ActionCoerce.kt
│ │ │ │ │ └── ActionMaths.kt
│ │ │ │ ├── target
│ │ │ │ │ ├── ActionTarget.kt
│ │ │ │ │ ├── ActionTargetForeach.kt
│ │ │ │ │ ├── filter
│ │ │ │ │ │ ├── ActionTargetFilterForeach.kt
│ │ │ │ │ │ ├── ActionTargetFilterInstance.kt
│ │ │ │ │ │ └── ActionTargetFilterType.kt
│ │ │ │ │ └── selector
│ │ │ │ │ │ ├── ActionTargetSelectInRadius.kt
│ │ │ │ │ │ ├── ActionTargetSelectInRing.kt
│ │ │ │ │ │ ├── ActionTargetSelectNearest.kt
│ │ │ │ │ │ ├── ActionTargetSelectPlayer.kt
│ │ │ │ │ │ ├── ActionTargetSelectSelf.kt
│ │ │ │ │ │ ├── ActionTargetSelectServer.kt
│ │ │ │ │ │ └── ActionTargetSelectWorld.kt
│ │ │ │ └── vector
│ │ │ │ │ ├── ActionVector.kt
│ │ │ │ │ ├── ActionVectorAdd.kt
│ │ │ │ │ ├── ActionVectorAngle.kt
│ │ │ │ │ ├── ActionVectorBuild.kt
│ │ │ │ │ ├── ActionVectorClone.kt
│ │ │ │ │ ├── ActionVectorCross.kt
│ │ │ │ │ ├── ActionVectorDistance.kt
│ │ │ │ │ ├── ActionVectorDistanceSquared.kt
│ │ │ │ │ ├── ActionVectorDivide.kt
│ │ │ │ │ ├── ActionVectorDot.kt
│ │ │ │ │ ├── ActionVectorLength.kt
│ │ │ │ │ ├── ActionVectorLengthSquared.kt
│ │ │ │ │ ├── ActionVectorMidpoint.kt
│ │ │ │ │ ├── ActionVectorModify.kt
│ │ │ │ │ ├── ActionVectorMultiply.kt
│ │ │ │ │ ├── ActionVectorNormalize.kt
│ │ │ │ │ ├── ActionVectorRandom.kt
│ │ │ │ │ ├── ActionVectorRotateAxis.kt
│ │ │ │ │ ├── ActionVectorRotateAxisNonUnit.kt
│ │ │ │ │ ├── ActionVectorRotateEuler.kt
│ │ │ │ │ ├── ActionVectorRotateX.kt
│ │ │ │ │ ├── ActionVectorRotateY.kt
│ │ │ │ │ ├── ActionVectorRotateZ.kt
│ │ │ │ │ └── ActionVectorSubtract.kt
│ │ │ ├── property
│ │ │ │ ├── BlockProperty.kt
│ │ │ │ ├── ItemStackProperty.kt
│ │ │ │ ├── LocationBukkitProperty.kt
│ │ │ │ ├── LocationTabooProperty.kt
│ │ │ │ ├── OfflinePlayerProperty.kt
│ │ │ │ ├── VectorBukkitProperty.kt
│ │ │ │ ├── VectorTabooProperty.kt
│ │ │ │ ├── WorldProperty.kt
│ │ │ │ ├── entity
│ │ │ │ │ ├── EntityProperty.kt
│ │ │ │ │ ├── LivingEntityProperty.kt
│ │ │ │ │ └── PlayerProperty.kt
│ │ │ │ └── event
│ │ │ │ │ ├── AsyncPlayerChatEventProperty.kt
│ │ │ │ │ ├── EntityDamageEventProperty.kt
│ │ │ │ │ ├── EntityDeathEventProperty.kt
│ │ │ │ │ ├── EntityShootBowEventProperty.kt
│ │ │ │ │ ├── EventProperty.kt
│ │ │ │ │ ├── PacketReceiveEventProperty.kt
│ │ │ │ │ ├── PacketSendEventProperty.kt
│ │ │ │ │ ├── PlayerCommandEventProperty.kt
│ │ │ │ │ ├── PlayerInteractEventProperty.kt
│ │ │ │ │ ├── PlayerItemHeldEventProperty.kt
│ │ │ │ │ ├── PlayerJoinEventProperty.kt
│ │ │ │ │ ├── PlayerKickEventProperty.kt
│ │ │ │ │ ├── PlayerMoveEventProperty.kt
│ │ │ │ │ ├── PlayerQuitEventProperty.kt
│ │ │ │ │ └── PlayerRespawnEventProperty.kt
│ │ │ └── script
│ │ │ │ ├── BacikalScript.kt
│ │ │ │ ├── BacikalScriptBuilder.kt
│ │ │ │ ├── CommentEraser.kt
│ │ │ │ ├── FragmentReplacer.kt
│ │ │ │ ├── ScriptTransfer.kt
│ │ │ │ └── UnicodeEscalator.kt
│ │ │ ├── command
│ │ │ ├── CommandDispatcher.kt
│ │ │ ├── CommandSchedule.kt
│ │ │ ├── CommandScript.kt
│ │ │ ├── CommandUtilTiming.kt
│ │ │ └── CommandVulpecula.kt
│ │ │ ├── config
│ │ │ ├── DynamicConfig.kt
│ │ │ ├── DynamicConfigNode.kt
│ │ │ ├── DynamicConfigNodeBinding.kt
│ │ │ └── DynamicConfigNodeTransfer.kt
│ │ │ ├── internal
│ │ │ ├── ClassInjector.kt
│ │ │ ├── CommandComponentBuilder.kt
│ │ │ ├── CustomCommand.kt
│ │ │ ├── EventDispatcher.kt
│ │ │ ├── EventHandler.kt
│ │ │ ├── EventListener.kt
│ │ │ ├── EventMapper.kt
│ │ │ ├── ExternalScript.kt
│ │ │ ├── ScheduleTask.kt
│ │ │ └── ScriptWorkspace.kt
│ │ │ ├── modularity
│ │ │ └── Module.kt
│ │ │ └── utils
│ │ │ ├── CoerceUtil.kt
│ │ │ ├── ConfigUtil.kt
│ │ │ ├── Debug.kt
│ │ │ ├── FileUtil.kt
│ │ │ ├── FutureUtil.kt
│ │ │ ├── KetherUtil.kt
│ │ │ ├── LegacyUtil.kt
│ │ │ ├── MessageUtil.kt
│ │ │ ├── ScriptUtil.kt
│ │ │ └── TimingUtil.kt
│ │ └── resources
│ │ ├── actions
│ │ ├── action-registry.yml
│ │ ├── property-registry.yml
│ │ └── unicode
│ │ │ ├── #blank.yml
│ │ │ └── #def.yml
│ │ ├── commands
│ │ └── #def.yml
│ │ ├── config.yml
│ │ ├── dispatchers
│ │ └── #def.yml
│ │ ├── handlers
│ │ └── #def.yml
│ │ ├── lang
│ │ └── zh_CN.yml
│ │ ├── listen-mapping.yml
│ │ ├── schedules
│ │ └── #def.yml
│ │ └── scripts
│ │ └── #def.yml
├── common
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ ├── Vulpecula.kt
│ │ ├── VulpeculaAPI.kt
│ │ ├── command
│ │ ├── ReloadCommand.kt
│ │ └── VulpeculaCommand.kt
│ │ ├── metrics
│ │ └── VulpeculaMetrics.kt
│ │ └── utils
│ │ └── TimingUtil.kt
├── extension-anser
│ └── build.gradle.kts
├── module-applicative
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── applicative
│ │ ├── AbstractApplicative.kt
│ │ ├── Applicative.kt
│ │ ├── ApplicativeRegistry.kt
│ │ ├── ApplicativeUtil.kt
│ │ ├── BooleanApplicative.kt
│ │ ├── ColorApplicative.kt
│ │ ├── DefaultLiveData.kt
│ │ ├── DoubleApplicative.kt
│ │ ├── EntityApplicative.kt
│ │ ├── FloatApplicative.kt
│ │ ├── IntApplicative.kt
│ │ ├── InventoryApplicative.kt
│ │ ├── ItemStackApplicative.kt
│ │ ├── ListApplicative.kt
│ │ ├── LiveData.kt
│ │ ├── LiveDataUtil.kt
│ │ ├── LocationApplicative.kt
│ │ ├── LongApplicative.kt
│ │ ├── PlayerApplicative.kt
│ │ └── VectorApplicative.kt
├── module-bacikal
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── lanscarlos
│ │ │ └── vulpecula
│ │ │ └── bacikal
│ │ │ └── Maturation.java
│ │ ├── kotlin
│ │ └── top
│ │ │ └── lanscarlos
│ │ │ └── vulpecula
│ │ │ └── bacikal
│ │ │ ├── Bacikal.kt
│ │ │ ├── BacikalError.kt
│ │ │ ├── BacikalRegistry.kt
│ │ │ ├── BacikalScript.kt
│ │ │ ├── BacikalService.kt
│ │ │ ├── BacikalTest.kt
│ │ │ ├── BacikalUtil.kt
│ │ │ ├── BacikalWorkspace.kt
│ │ │ ├── DefaultBacikalService.kt
│ │ │ ├── DefaultScript.kt
│ │ │ ├── DefaultWorkspace.kt
│ │ │ ├── FutureUtil.kt
│ │ │ ├── command
│ │ │ ├── EvalCommand.kt
│ │ │ ├── TestCommand.kt
│ │ │ └── TimingCommand.kt
│ │ │ ├── debugger
│ │ │ └── BacikalDebugger.kt
│ │ │ ├── parser
│ │ │ ├── AbstractSeed.kt
│ │ │ ├── AdditionalSeed.kt
│ │ │ ├── BacikalActionParser.kt
│ │ │ ├── BacikalComplexActionParser.kt
│ │ │ ├── BacikalContext.kt
│ │ │ ├── BacikalFrame.kt
│ │ │ ├── BacikalFruit.kt
│ │ │ ├── BacikalParser.kt
│ │ │ ├── BacikalParserBody.kt
│ │ │ ├── BacikalReader.kt
│ │ │ ├── BacikalSeed.kt
│ │ │ ├── DefaultContext.kt
│ │ │ ├── DefaultFrame.kt
│ │ │ ├── DefaultReader.kt
│ │ │ ├── DefaultSeed.kt
│ │ │ ├── ExpectedSeed.kt
│ │ │ ├── NullableSeed.kt
│ │ │ ├── OptionalSeed.kt
│ │ │ ├── PairSeed.kt
│ │ │ └── TripleSeed.kt
│ │ │ ├── property
│ │ │ ├── BacikalGenericProperty.kt
│ │ │ └── BacikalProperty.kt
│ │ │ └── quest
│ │ │ ├── AbstractQuestExecutor.kt
│ │ │ ├── AnalysisQuestCompiler.kt
│ │ │ ├── BacikalBlockBuilder.kt
│ │ │ ├── BacikalQuest.kt
│ │ │ ├── BacikalQuestBuilder.kt
│ │ │ ├── BacikalQuestCompiler.kt
│ │ │ ├── BacikalQuestContext.kt
│ │ │ ├── BacikalQuestExecutor.kt
│ │ │ ├── BacikalQuestTransfer.kt
│ │ │ ├── CommentEraser.kt
│ │ │ ├── CoroutinesQuestExecutor.kt
│ │ │ ├── DefaultBlockBuilder.kt
│ │ │ ├── DefaultQuest.kt
│ │ │ ├── DefaultQuestBuilder.kt
│ │ │ ├── FixedQuestCompiler.kt
│ │ │ ├── FragmentReplacer.kt
│ │ │ ├── KetherQuestCompiler.kt
│ │ │ ├── KetherQuestExecutor.kt
│ │ │ └── UnicodeEscalator.kt
│ │ └── resources
│ │ ├── action-registry.yml
│ │ ├── config.yml
│ │ ├── kether$bacikal.yml
│ │ └── property-registry.yml
├── module-config
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── top
│ │ └── lanscarlos
│ │ └── vulpecula
│ │ └── config
│ │ ├── AbstractDynamicConfig.kt
│ │ ├── ConfigUtil.kt
│ │ ├── DefaultDynamicSection.kt
│ │ ├── DynamicConfig.kt
│ │ ├── DynamicSection.kt
│ │ └── YamlDynamicConfig.kt
└── module-volatile
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── kotlin
│ └── top
│ └── lanscarlos
│ └── vulpecula
│ └── volatile
│ ├── DefaultVolatileMetadata.kt
│ ├── DefaultVolatilePacket.kt
│ ├── VolatileEntityMetadata.kt
│ ├── VolatileMetadata.kt
│ ├── VolatilePacket.kt
│ └── VolatilePose.kt
└── settings.gradle.kts
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Project Build
2 | on: [ push ]
3 | jobs:
4 | build:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - name: checkout repository
8 | uses: actions/checkout@v4
9 | - name: cache gradle packages
10 | uses: actions/cache@v4
11 | with:
12 | key: ${{ runner.os }}-build-${{ env.cache-name }}
13 | path: |
14 | ~/.gradle/caches
15 | ~/.gradle/wrapper
16 | ~/.gradle/gradle.properties
17 | - name: validate gradle wrapper
18 | uses: gradle/actions/wrapper-validation@v4
19 | - name: setup jdk 16
20 | uses: actions/setup-java@v4
21 | with:
22 | distribution: adopt
23 | java-version: 16
24 | - name: make gradle wrapper executable
25 | run: chmod +x ./gradlew
26 | - name: build
27 | run: ./gradlew build
28 | - name: capture build artifacts
29 | uses: actions/upload-artifact@v4
30 | with:
31 | name: Artifacts
32 | path: build/libs/
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Workflow Release
2 | on:
3 | release:
4 | types: [ published ]
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: checkout repository
10 | uses: actions/checkout@v4
11 | - name: validate gradle wrapper
12 | uses: gradle/wrapper-validation-action@v4
13 | - name: setup jdk 16.0
14 | uses: actions/setup-java@v4
15 | with:
16 | distribution: adopt
17 | java-version: 16
18 | - name: make gradle wrapper executable
19 | run: chmod +x ./gradlew
20 | - name: build
21 | run: ./gradlew publish
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | .idea
3 | build
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Lanscarlos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## Vulpecula
4 |
5 | Vulpecula 是基于 [TabooLib 6.0](https://github.com/TabooLib/taboolib) 开发的一款 Kether 拓展插件,旨在为 Kether 提供更多元化的功能。
6 |
7 | - 更多的拓展语句、拓展属性
8 | - 简化部分原生语句或增强其功能
9 | - 支持事件处理
10 | - 支持自定义定时任务
11 | - 支持自定义脚本
12 | - 支持自定义命令
13 |
14 |
15 |
16 | | 构建版本 | 发行时间 | 发行者 | 大小 |
17 | | --- | --- | --- | --- |
18 | | |  |  |  |
19 |
20 |
21 |
22 | ### 相关链接
23 |
24 | [Vulpecula 文档](https://www.yuque.com/lanscarlos/vulpecula-doc)
25 |
26 | [Kether 烹饪食用指南](https://www.yuque.com/sacredcraft/kether)
27 |
28 | [枫溪大佬的 Aboleth 插件](https://xv5zac7cto.feishu.cn/docx/doxcnP4k0XN7IK7pcugdodQlJLh)
29 |
--------------------------------------------------------------------------------
/common-applicative/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-message"))
8 | compileOnly("ink.ptms.core:v12004:12004:mapped")
9 | }
--------------------------------------------------------------------------------
/common-applicative/src/main/kotlin/top/lanscarlos/vulpecula/common/applicative/EntityApplicative.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.applicative
2 |
3 | import org.bukkit.Bukkit
4 | import org.bukkit.OfflinePlayer
5 | import org.bukkit.entity.Entity
6 | import taboolib.common.platform.ProxyPlayer
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.common.applicative
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-08-21 15:10
14 | */
15 | object EntityApplicative : AbstractApplicative(Entity::class.java) {
16 |
17 | override fun convertOrThrow(instance: Any): Entity {
18 | return when (instance) {
19 | is Entity -> instance
20 | is OfflinePlayer -> instance.player!!
21 | is ProxyPlayer -> instance.cast()
22 | is String -> Bukkit.getPlayerExact(instance) ?: throw InvalidValueException(instance, Entity::class.java)
23 | else -> throw UnsupportedTypeException(instance::class.java, Entity::class.java)
24 | }
25 | }
26 |
27 | override fun readProperty(instance: Entity, key: String): Any? {
28 | errorGetPropertyNotSupported(instance, key)
29 | }
30 |
31 | override fun writeProperty(instance: Entity, key: String, value: Any?) {
32 | errorBySetPropertyNotSupported(instance, key)
33 | }
34 | }
--------------------------------------------------------------------------------
/common-applicative/src/main/kotlin/top/lanscarlos/vulpecula/common/applicative/InvalidValueException.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.applicative
2 |
3 | import top.lanscarlos.vulpecula.common.message.MessageService
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.common.applicative
8 | *
9 | * @author Lanscarlos
10 | * @since 2025/5/29 11:54
11 | */
12 | class InvalidValueException(val value: String, val target: Class<*>) : RuntimeException() {
13 |
14 | override val message: String = MessageService.asLang("common-applicative-exception-invalid-value", value, target.name)
15 |
16 | }
--------------------------------------------------------------------------------
/common-applicative/src/main/kotlin/top/lanscarlos/vulpecula/common/applicative/UnsupportedTypeException.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.applicative
2 |
3 | import top.lanscarlos.vulpecula.common.message.MessageService
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.common.applicative
8 | *
9 | * @author Lanscarlos
10 | * @since 2025/5/29 10:50
11 | */
12 | class UnsupportedTypeException(val source: Class<*>, val target: Class<*>) : RuntimeException() {
13 |
14 | override val message: String = MessageService.asLang("common-applicative-exception-unsupported-type", source.name, target.name)
15 |
16 | }
--------------------------------------------------------------------------------
/common-applicative/src/main/resources/lang/zh_CN.yml:
--------------------------------------------------------------------------------
1 |
2 | # Applicative 模块
3 | common-applicative-exception-invalid-value: '无法将 &e{0}&7 转换为 &e{1}&7.'
4 | common-applicative-exception-unsupported-type: '无法将 &e{0}&7 转换为 &e{1}&7.'
5 |
6 |
--------------------------------------------------------------------------------
/common-config/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-message"))
9 |
10 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1")
11 | testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1")
12 | }
13 |
14 | tasks.test {
15 | useJUnitPlatform()
16 | }
--------------------------------------------------------------------------------
/common-config/src/main/kotlin/top/lanscarlos/vulpecula/common/config/ConfigServiceCallback.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.config
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import java.io.File
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.common.config
9 | *
10 | * 文件监听
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/4/25 14:06
14 | */
15 | interface ConfigServiceCallback {
16 |
17 | fun onFileDeleted(sender: ProxyCommandSender, id: String, file: File)
18 |
19 | fun onFileCreated(sender: ProxyCommandSender, id: String, file: File)
20 |
21 | fun onFileModified(sender: ProxyCommandSender, id: String, file: File)
22 |
23 | /**
24 | * 当路径不存在时调用
25 | * */
26 | fun onLoadInit(sender: ProxyCommandSender, directory: File)
27 |
28 | fun onLoadStarted(sender: ProxyCommandSender) {}
29 |
30 | fun onLoadCompleted(sender: ProxyCommandSender, time: Double)
31 |
32 | fun onLoadFailed(sender: ProxyCommandSender, id: String, file: File, e: Throwable)
33 |
34 | }
--------------------------------------------------------------------------------
/common-config/src/main/kotlin/top/lanscarlos/vulpecula/common/config/ConfigUtil.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.config
2 |
3 | import taboolib.library.configuration.ConfigurationSection
4 | import taboolib.module.configuration.ConfigLoader
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.common.config
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-03-11 16:53
12 | */
13 |
14 | /**
15 | * 从 ConfigurationSection 读取指定字段数据
16 | * */
17 | fun ConfigurationSection.read(vararg keys: String): LiveData {
18 | return DelegateConfigNode(this, keys)
19 | }
20 |
21 | /**
22 | * 绑定 TabooLib 配置文件中的指定键值
23 | *
24 | * @param path 键
25 | * @param bind 文件名
26 | * */
27 | fun bindConfig(path: String, bind: String = "config.yml"): LiveData {
28 | val configFile = ConfigLoader.files[bind] ?: error("Config $bind not found.")
29 | return configFile.configuration.read(path)
30 | }
--------------------------------------------------------------------------------
/common-config/src/main/kotlin/top/lanscarlos/vulpecula/common/config/ExceptionalLiveData.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.config
2 |
3 | import java.util.function.Function
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.common.config
8 | *
9 | * @author Lanscarlos
10 | * @since 2025/5/28 11:05
11 | */
12 | class ExceptionalLiveData(private val source: LiveData, private val exceptionally: Function) : LiveData {
13 |
14 | override val id: String
15 | get() = source.id
16 |
17 | override val isInitialized
18 | get() = source.isInitialized
19 |
20 | override fun getValue(): T {
21 | return try {
22 | source.getValue()
23 | } catch (e: InvalidFieldException) {
24 | exceptionally.apply(e.cause as Exception)
25 | } catch (e: Exception) {
26 | exceptionally.apply(e)
27 | }
28 | }
29 |
30 | override fun update() {
31 | source.update()
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/common-config/src/main/kotlin/top/lanscarlos/vulpecula/common/config/InvalidFieldException.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.config
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.common.config
6 | *
7 | * @author Lanscarlos
8 | * @since 2025/5/29 9:36
9 | */
10 | class InvalidFieldException(val field: String, override val cause: Throwable) : RuntimeException()
--------------------------------------------------------------------------------
/common-config/src/main/kotlin/top/lanscarlos/vulpecula/common/config/LiveData.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.config
2 |
3 | import kotlin.reflect.KProperty
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.common.config
8 | *
9 | * @author Lanscarlos
10 | * @since 2025-03-10 18:58
11 | */
12 | interface LiveData {
13 |
14 | /**
15 | * 键名
16 | * */
17 | val id: String
18 |
19 | /**
20 | * 是否已初始化
21 | * */
22 | val isInitialized: Boolean
23 |
24 | /**
25 | * 获取值
26 | * */
27 | fun getValue(): T
28 |
29 | /**
30 | * 更新值
31 | * */
32 | fun update()
33 |
34 | /**
35 | * 兼容代理属性
36 | * */
37 | operator fun getValue(parent: Any?, property: KProperty<*>): T {
38 | return getValue()
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/common-config/src/main/kotlin/top/lanscarlos/vulpecula/common/config/LiveDataTransformer.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.common.config
2 |
3 | import java.util.function.Function
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.common.config
8 | *
9 | * @author Lanscarlos
10 | * @since 2025-03-10 19:12
11 | */
12 | class LiveDataTransformer(val source: LiveData, val transfer: Function) : LiveData {
13 |
14 | override val id: String
15 | get() = source.id
16 |
17 | /**
18 | * 缓存值
19 | * */
20 | private var value: R? = null
21 |
22 | /**
23 | * 是否已初始化
24 | * */
25 | override val isInitialized
26 | get() = source.isInitialized
27 |
28 | @Suppress("UNCHECKED_CAST")
29 | override fun getValue(): R {
30 | if (!isInitialized) {
31 | // 初始化
32 | try {
33 | value = transfer.apply(source.getValue())
34 | } catch (e: InvalidFieldException) {
35 | throw e
36 | } catch (e: Exception) {
37 | throw InvalidFieldException(id, e)
38 | }
39 | }
40 | return value as R
41 | }
42 |
43 | override fun update() {
44 | this.source.update()
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/common-config/src/main/resources/lang/zh_CN.yml:
--------------------------------------------------------------------------------
1 |
2 | # 主配置
3 |
4 | common-config-main-load-succeeded: '主配置加载成功 &8({0} ms)'
5 | common-config-main-load-failed: |-
6 | 主配置加载失败!
7 | &e[ERROR: config#load]: {0}
--------------------------------------------------------------------------------
/common-core/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly("ink.ptms.core:v12004:12004:mapped")
8 | compileOnly("ink.ptms.core:v12004:12004:universal")
9 | }
--------------------------------------------------------------------------------
/common-core/src/main/kotlin/top/lanscarlos/vulpecula/VulpeculaAPI.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-08-21 21:38
9 | */
10 | interface VulpeculaAPI {
11 | }
--------------------------------------------------------------------------------
/common-core/src/main/kotlin/top/lanscarlos/vulpecula/utils/TimingUtil.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.utils
2 |
3 | import taboolib.common5.Coerce
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.utils
8 | *
9 | * @author Lanscarlos
10 | * @since 2024-05-15 10:06
11 | */
12 |
13 | /**
14 | * 开始计时
15 | * */
16 | fun timing(): Long {
17 | return System.nanoTime()
18 | }
19 |
20 | /**
21 | * 结束计时
22 | *
23 | * @return 毫秒数
24 | * */
25 | fun timing(start: Long): Double {
26 | return Coerce.format((System.nanoTime() - start).div(1000000.0))
27 | }
--------------------------------------------------------------------------------
/common-core/src/main/resources/config.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/common-core/src/main/resources/config.yml
--------------------------------------------------------------------------------
/common-message/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1")
8 | testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1")
9 | }
10 |
11 | tasks.test {
12 | useJUnitPlatform()
13 | }
--------------------------------------------------------------------------------
/common-message/src/main/resources/lang/zh_CN.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Message 消息模组
4 | common-message-info: '&8[&3Vul&bpecula&8] &a良好 &8|&7 {0}'
5 | common-message-warning: '&8[&3Vul&bpecula&8] &e警告 &8|&7 {0}'
6 | common-message-error: '&8[&3Vul&bpecula&8] &c错误 &8|&7 {0}'
7 | common-message-debug: '&8[&3Vul&bpecula&8] &7调试 &8|&7 {0}'
--------------------------------------------------------------------------------
/extension-action-item/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | version = "1.0.0"
3 |
4 | taboolib {
5 | subproject = false
6 |
7 | description {
8 | name("Vulpecula-Extension-Action-Item")
9 | desc("Please put this extension in directory `./plugins/Vulpecula/extension/` of your server.")
10 | contributors {
11 | this.contributors.clear()
12 | name("Lanscarlos")
13 | }
14 | dependencies {
15 | this.dependencies.clear()
16 | name("DISABLE")
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compileOnly(project(":module-bacikal"))
23 | compileOnly("ink.ptms.core:v12004:12004:mapped")
24 | }
25 |
26 | tasks {
27 | jar {
28 | archiveBaseName.set(project.name.replace("module", "extension"))
29 | archiveClassifier.set("")
30 | destinationDirectory.set(file("${rootDir}/build/libs"))
31 | }
32 | }
--------------------------------------------------------------------------------
/extension-action-item/src/main/kotlin/top/lanscarlos/vulpecula/action/item/ActionItemBuild.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.action.item
2 |
3 | import org.bukkit.inventory.ItemStack
4 | import taboolib.library.xseries.XMaterial
5 | import taboolib.platform.util.buildItem
6 | import top.lanscarlos.vulpecula.module.bacikal.annotation.Additional
7 | import top.lanscarlos.vulpecula.module.bacikal.annotation.BacikalParser
8 | import top.lanscarlos.vulpecula.module.bacikal.parser.BacikalActionResolver
9 |
10 | /**
11 | * Vulpecula
12 | * top.lanscarlos.vulpecula.action.item
13 | *
14 | * @author Lanscarlos
15 | * @since 2024-11-20 20:39
16 | */
17 | @BacikalParser
18 | object ActionItemBuild : BacikalActionResolver {
19 |
20 | override val id: String = "build"
21 |
22 | override val bind: String = "item"
23 |
24 | fun resolve(
25 | type: String,
26 | @Additional(["name"]) name: String? = "wcnm"
27 | ): ItemStack {
28 | val material = XMaterial.matchXMaterial(type).orElseThrow { IllegalArgumentException("ActionItemBuild#resolve >> Unknown material: $type") }
29 | return buildItem(material) {
30 | if (name != null) {
31 | this.name = name
32 | }
33 | colored()
34 | }
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | group=top.lanscarlos.vulpecula
2 | version=3.0.0
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.9-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
--------------------------------------------------------------------------------
/module-bacikal/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-message"))
9 | compileOnly("ink.ptms.core:v12004:12004:mapped")
10 | compileOnly("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.0")
11 |
12 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
13 | testImplementation("org.junit.jupiter:junit-jupiter")
14 | }
15 |
16 | tasks.test {
17 | useJUnitPlatform()
18 | }
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/annotation/Additional.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.annotation
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.bacikal.annotation
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-11-20 11:07
9 | */
10 | annotation class Additional(val prefix: Array)
11 |
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/annotation/BacikalParser.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.annotation
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.bacikal.annotation
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-11-20 17:40
9 | */
10 | annotation class BacikalParser
11 |
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/annotation/Expected.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.annotation
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.bacikal.annotation
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-11-20 11:06
9 | */
10 | annotation class Expected(val prefix: Array)
11 |
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/annotation/Optional.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.annotation
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.bacikal.annotation
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-11-20 11:07
9 | */
10 | annotation class Optional(val prefix: Array)
11 |
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/exception/BacikalException.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.exception
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.bacikal.exception
6 | *
7 | * @author Lanscarlos
8 | * @since 2025-05-03 13:19
9 | */
10 | abstract class BacikalException(override val cause: Throwable) : RuntimeException(cause)
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/exception/BacikalTimeoutException.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.exception
2 |
3 | import taboolib.library.kether.Quest
4 | import taboolib.module.kether.printKetherErrorMessage
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.bacikal.exception
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-05-02 20:04
12 | */
13 | class BacikalTimeoutException(
14 | cause: Throwable,
15 | quest: Quest,
16 | properties: Map,
17 | timeout: Long
18 | ) : BacikalRuntimeException(cause, quest, properties) {
19 |
20 | override val message: String = "Timeout ${timeout}ms"
21 |
22 | override fun getLocalizedMessage(): String {
23 | return message
24 | }
25 |
26 | override fun printKetherMessage(detailError: Boolean) {
27 | this.printKetherErrorMessage(detailError)
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/parser/BacikalAction.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.parser
2 |
3 | import java.util.concurrent.CompletableFuture
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.module.bacikal.parser
8 | *
9 | * @author Lanscarlos
10 | * @since 2024-11-20 14:03
11 | */
12 | interface BacikalAction {
13 |
14 | fun execute(frame: BacikalFrame): CompletableFuture
15 |
16 | }
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/parser/BacikalActionResolver.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.parser
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.bacikal.parser
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-11-20 10:41
9 | */
10 | interface BacikalActionResolver {
11 |
12 | /**
13 | * 语句 ID
14 | */
15 | val id: String
16 |
17 | /**
18 | * 绑定主体, 若为空则不绑定
19 | */
20 | val bind: String?
21 |
22 | }
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/parser/BacikalComplexActionParser.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.parser
2 |
3 | import taboolib.library.kether.QuestAction
4 | import taboolib.library.kether.QuestActionParser
5 | import taboolib.library.kether.QuestReader
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.bacikal.parser
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-05-13 17:02
13 | */
14 | class BacikalComplexActionParser(val name: String) : QuestActionParser {
15 |
16 | val actions = linkedMapOf()
17 |
18 | fun registerAction(id: String, parser: BacikalActionParser) {
19 | actions[id] = parser
20 | }
21 |
22 | override fun resolve(reader: QuestReader): QuestAction {
23 | reader.mark()
24 | val next = reader.nextToken()
25 | val parser = actions[next] ?: actions["@DEFAULT"] ?: error("Unknown action '$next' at $name")
26 | return parser.resolve(reader)
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/parser/BacikalReader.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.parser
2 |
3 | import taboolib.library.kether.ParsedAction
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.module.bacikal.parser
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-20 21:30
11 | */
12 | interface BacikalReader {
13 |
14 | val index: Int
15 |
16 | /**
17 | * 读取一个标记
18 | * */
19 | fun readToken(): String
20 |
21 | fun readAction(): ParsedAction<*>
22 |
23 | fun readActionList(): List>
24 |
25 | /**
26 | * 查看下一个标记,但不改变位置
27 | * */
28 | fun peekToken(): String
29 |
30 | /**
31 | * 读取下一个标记并判断是否符合预期,若不符合预期则抛出异常
32 | * */
33 | fun expectToken(vararg expect: String)
34 |
35 | /**
36 | * 读取一个标记并判断是否符合预期
37 | * 若不符合预期则重置位置
38 | * */
39 | fun hasToken(vararg expect: String): Boolean
40 |
41 | /**
42 | * 标记位置
43 | * */
44 | fun mark(): Int
45 |
46 | /**
47 | * 回滚到标记位置
48 | * */
49 | fun rollback(offset: Int = 1)
50 |
51 | }
--------------------------------------------------------------------------------
/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/module/bacikal/quest/CffuDependency.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.bacikal.quest
2 |
3 | import taboolib.common.env.RuntimeDependency
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.module.bacikal.quest
8 | *
9 | * @author Lanscarlos
10 | * @since 2025-05-18 11:17
11 | */
12 | @RuntimeDependency(
13 | value = "!io.foldright:cffu:1.1.3",
14 | test = "!io.foldright.cffu.CompletableFutureUtils",
15 | relocate = [ "!io.foldright.cffu.", "!io.foldright.cffu113." ],
16 | )
17 | object CffuDependency
--------------------------------------------------------------------------------
/module-bacikal/src/main/resources/bacikal-registry.yml:
--------------------------------------------------------------------------------
1 |
2 | # Bacikal.Registry.Config
3 |
4 | actions:
5 | item:
6 | local: [ 'vulpecula:item' ]
7 | remote: [ 'vulpecula:item' ]
8 |
--------------------------------------------------------------------------------
/module-bacikal/src/main/resources/lang/zh_CN.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Bacikal
4 | module-bacikal-service-compile-failure-reason: '异常原因: &e{0}'
5 | module-bacikal-service-compile-failure-detail-header: '异常位置:'
6 | module-bacikal-service-compile-failure-detail-item: '&7 {0} &8|&7 {1}'
7 | module-bacikal-service-execute-failure-action: '异常语句: &e{0}'
8 | module-bacikal-service-execute-failure-reason: '异常原因: &e{0}'
9 | module-bacikal-service-execute-failure-detail-header: '异常位置:'
10 | module-bacikal-service-execute-failure-detail-item: '&7 {0} &8|&7 {1}'
11 |
--------------------------------------------------------------------------------
/module-command/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-config"))
9 | compileOnly(project(":common-message"))
10 | compileOnly(project(":module-bacikal"))
11 | compileOnly(project(":module-script"))
12 | compileOnly("ink.ptms.core:v12004:12004:mapped")
13 |
14 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
15 | testImplementation("org.junit.jupiter:junit-jupiter")
16 | }
17 |
18 | tasks.test {
19 | useJUnitPlatform()
20 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/BooleanSuggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.command
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/29 14:03
12 | */
13 | object BooleanSuggester : Suggester {
14 |
15 | override fun suggest(sender: ProxyCommandSender, context: CommandContext): List {
16 | return listOf("true", "false")
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/DoubleRestrictor.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.command
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/29 14:26
12 | */
13 | object DoubleRestrictor : Restrictor {
14 |
15 | override fun restrict(sender: ProxyCommandSender, context: CommandContext, argument: String): Boolean {
16 | return argument.toDoubleOrNull() != null
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/IntRestrictor.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.command
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/29 14:22
12 | */
13 | object IntRestrictor : Restrictor {
14 |
15 | override fun restrict(sender: ProxyCommandSender, context: CommandContext, argument: String): Boolean {
16 | return argument.toIntOrNull() != null
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/ListSuggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.command
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/5/6 11:47
12 | */
13 | class ListSuggester(list: List<*>) : Suggester {
14 |
15 | val list = list.map { it.toString() }
16 |
17 | override fun suggest(sender: ProxyCommandSender, context: CommandContext): List {
18 | return list
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/MainNode.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.component.CommandBase
5 | import taboolib.expansion.createHelper
6 | import taboolib.library.configuration.ConfigurationSection
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.command
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/4/29 17:03
14 | */
15 | class MainNode(section: ConfigurationSection) : Node("main", null, section) {
16 |
17 | override fun build(): CommandBase {
18 | val component = CommandBase()
19 | if (executor == null) {
20 | // 默认创建命令提示
21 | component.createHelper()
22 | } else {
23 | component.execute(bind = ProxyCommandSender::class.java, function = ::execute)
24 | }
25 | for (child in children) {
26 | component.children += child.build()
27 | }
28 | return component
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/MaterialSuggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 | import taboolib.library.xseries.XMaterial
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.command
10 | *
11 | * @author Lanscarlos
12 | * @since 2025/4/29 15:06
13 | */
14 | object MaterialSuggester : Suggester {
15 |
16 | override fun suggest(sender: ProxyCommandSender, context: CommandContext): List {
17 | return XMaterial.entries.map { it.name }
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/OfflinePlayerSuggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import org.bukkit.Bukkit
4 | import org.bukkit.OfflinePlayer
5 | import taboolib.common.platform.ProxyCommandSender
6 | import taboolib.common.platform.command.CommandContext
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.command
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/4/29 14:18
14 | */
15 | object OfflinePlayerSuggester : Suggester {
16 |
17 | override fun suggest(sender: ProxyCommandSender, context: CommandContext): List {
18 | return Bukkit.getOfflinePlayers().mapNotNull { it.name }
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/PlayerSuggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import org.bukkit.Bukkit
4 | import org.bukkit.entity.Player
5 | import taboolib.common.platform.ProxyCommandSender
6 | import taboolib.common.platform.command.CommandContext
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.command
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/4/29 13:26
14 | */
15 | object PlayerSuggester : Suggester {
16 |
17 | override fun suggest(sender: ProxyCommandSender, context: CommandContext): List {
18 | return Bukkit.getOnlinePlayers().map { it.name }
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/ReloadCommand.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandBody
5 | import taboolib.common.platform.command.subCommand
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.command
10 | *
11 | * @author Lanscarlos
12 | * @since 2025/5/6 11:23
13 | */
14 | object ReloadCommand {
15 |
16 | @CommandBody
17 | val command = subCommand {
18 | literal("reload") {
19 | execute { sender, _, _ ->
20 | CommandService.reload(sender)
21 | }
22 | }
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/Restrictor.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.command
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/29 13:51
12 | */
13 | interface Restrictor {
14 |
15 | fun restrict(sender: ProxyCommandSender, context: CommandContext, argument: String): Boolean
16 |
17 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/Suggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandContext
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.command
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/29 13:25
12 | */
13 | interface Suggester {
14 |
15 | fun suggest(sender: ProxyCommandSender, context: CommandContext): List
16 |
17 | }
--------------------------------------------------------------------------------
/module-command/src/main/kotlin/top/lanscarlos/vulpecula/module/command/WorldSuggester.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.command
2 |
3 | import org.bukkit.Bukkit
4 | import org.bukkit.World
5 | import taboolib.common.platform.ProxyCommandSender
6 | import taboolib.common.platform.command.CommandContext
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.command
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/4/29 14:01
14 | */
15 | object WorldSuggester : Suggester {
16 |
17 | override fun suggest(sender: ProxyCommandSender, context: CommandContext): List {
18 | return Bukkit.getWorlds().map { it.name }
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/module-command/src/main/resources/command/example.yml:
--------------------------------------------------------------------------------
1 |
2 | name: 'exam'
3 |
4 | main:
5 | execute: |-
6 | print "Hello, World!"
7 |
8 | components:
9 | script:
10 | parent: 'main'
11 |
12 | run:
13 | parent: 'script'
14 | parameters:
15 | - name: 'scriptId'
16 | execute: |-
17 | tell hi!
18 | tell &scriptId
19 |
--------------------------------------------------------------------------------
/module-core/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-config"))
9 | compileOnly("ink.ptms.core:v12004:12004:mapped")
10 | }
--------------------------------------------------------------------------------
/module-core/src/main/kotlin/top/lanscarlos/vulpecula/module/core/command/ReloadCommand.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.core.command
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.command.CommandBody
5 | import taboolib.common.platform.command.subCommand
6 | import taboolib.common.platform.command.suggest
7 | import top.lanscarlos.vulpecula.common.config.Configs
8 |
9 | /**
10 | * Vulpecula
11 | * top.lanscarlos.vulpecula.module.core.command
12 | *
13 | * @author Lanscarlos
14 | * @since 2025/4/30 14:14
15 | */
16 | object ReloadCommand {
17 |
18 | @CommandBody
19 | val reload = subCommand {
20 | execute { sender, _, _ ->
21 | Configs.load(sender)
22 | }
23 |
24 | dynamic("service") {
25 | suggest { Configs.services.map { it.id } }
26 | execute { sender, _, serviceId ->
27 | Configs.services.first { it.id == serviceId }.load(sender)
28 | }
29 | }
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/module-dispatcher/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-config"))
9 | compileOnly(project(":module-script"))
10 | compileOnly("ink.ptms.core:v12004:12004:mapped")
11 |
12 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
13 | testImplementation("org.junit.jupiter:junit-jupiter")
14 | }
15 |
16 | tasks.test {
17 | useJUnitPlatform()
18 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/Context.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher
2 |
3 | import org.bukkit.entity.Player
4 | import org.bukkit.event.Event
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.dispatcher
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-03-12 17:47
12 | */
13 | class Context(private val event: Event, var player: Player?) {
14 |
15 | @Suppress("UNCHECKED_CAST")
16 | fun event(): T {
17 | return event as T
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/Dispatcher.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher
2 |
3 | import org.bukkit.event.Event
4 | import taboolib.common.platform.event.EventPriority
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.dispatcher
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-02-04 17:19
12 | */
13 | interface Dispatcher {
14 |
15 | val id: String
16 |
17 | val clazz: Class
18 |
19 | val priority: EventPriority
20 |
21 | val weight: Int
22 |
23 | fun accept(event: Event)
24 |
25 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/Trigger.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher
2 |
3 | import org.bukkit.event.Event
4 | import taboolib.common.platform.event.EventPriority
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.dispatcher
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-03-13 17:13
12 | */
13 | interface Trigger {
14 |
15 | val clazz: Class
16 |
17 | val priority: EventPriority
18 |
19 | val weight: Int
20 |
21 | fun accept(event: Event)
22 |
23 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/condition/Condition.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher.condition
2 |
3 | import top.lanscarlos.vulpecula.dispatcher.Context
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.dispatcher.condition
8 | *
9 | * @author Lanscarlos
10 | * @since 2025-03-10 13:46
11 | */
12 | interface Condition {
13 |
14 | /**
15 | * 检查输入是否符合条件
16 | * */
17 | fun check(context: Context): Boolean
18 |
19 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/condition/Conditions.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher.condition
2 |
3 | import org.bukkit.event.Event
4 | import taboolib.library.configuration.ConfigurationSection
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.dispatcher.condition
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-03-12 18:35
12 | */
13 | object Conditions {
14 |
15 | fun create(clazz: Class, config: ConfigurationSection): Condition {
16 | TODO("Not yet implemented")
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/rule/GenericEventRule.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher.rule
2 |
3 | import org.bukkit.event.Event
4 | import taboolib.library.configuration.ConfigurationSection
5 | import top.lanscarlos.vulpecula.dispatcher.Context
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.dispatcher.rule
10 | *
11 | * @author Lanscarlos
12 | * @since 2025-03-12 17:21
13 | */
14 | class GenericEventRule(clazz: Class, config: ConfigurationSection) : AbstractRule(clazz, config) {
15 | override fun matches(context: Context): Boolean {
16 | TODO("Not yet implemented")
17 | }
18 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/rule/PlayerMoveEventRule.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher.rule
2 |
3 | import org.bukkit.event.Event
4 | import org.bukkit.event.player.PlayerMoveEvent
5 | import taboolib.library.configuration.ConfigurationSection
6 | import top.lanscarlos.vulpecula.dispatcher.Context
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.dispatcher.rule
11 | *
12 | * @author Lanscarlos
13 | * @since 2025-03-12 17:18
14 | */
15 | class PlayerMoveEventRule(clazz: Class, config: ConfigurationSection) : AbstractRule(clazz, config) {
16 | override fun matches(context: Context): Boolean {
17 | TODO("Not yet implemented")
18 | }
19 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/rule/Rule.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher.rule
2 |
3 | import org.bukkit.event.Event
4 | import top.lanscarlos.vulpecula.dispatcher.Context
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.dispatcher.rule
9 | *
10 | * @author Lanscarlos
11 | * @since 2025-03-12 09:03
12 | */
13 | interface Rule {
14 |
15 | /**
16 | * 解析玩家
17 | * */
18 | fun parsePlayer(context: Context)
19 |
20 | /**
21 | * 匹配事件
22 | * */
23 | fun matches(context: Context): Boolean
24 |
25 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/kotlin/top/lanscarlos/vulpecula/dispatcher/rule/Rules.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.dispatcher.rule
2 |
3 | import org.bukkit.event.Event
4 | import org.bukkit.event.player.PlayerMoveEvent
5 | import taboolib.library.configuration.ConfigurationSection
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.dispatcher.rule
10 | *
11 | * @author Lanscarlos
12 | * @since 2025-03-12 16:34
13 | */
14 | object Rules {
15 |
16 | val registry: HashMap, Class>> = hashMapOf()
17 |
18 | init {
19 | registry[PlayerMoveEvent::class.java] = PlayerMoveEventRule::class.java
20 | }
21 |
22 | @Suppress("UNCHECKED_CAST")
23 | fun create(event: Class, config: ConfigurationSection): Rule {
24 | val clazz = registry[event] ?: return GenericEventRule(event, config)
25 | val constructor = clazz.getDeclaredConstructor(Class::class.java, ConfigurationSection::class.java)
26 | return constructor.newInstance(event, config) as Rule
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/module-dispatcher/src/main/resources/dispatcher/def.yml:
--------------------------------------------------------------------------------
1 |
2 | # 事件监听器可以用来监听游戏内的各种事件, 并触发对应的脚本, 修改事件的行为.
3 |
4 | # 监听器 ID
5 | id: "default-listener"
6 |
7 | # 监听对象
8 | # 这里选取玩家交互事件为例
9 | event: "org.bukkit.event.player.PlayerInteractEvent"
10 |
11 | # 事件优先级 [可选]
12 | # 可用值: LOWEST, LOW, NORMAL, HIGH, HIGHEST, MONITOR
13 | # 优先级越高, 事件监听器越早被调用
14 | # 默认为 NORMAL
15 | priority: "NORMAL"
16 |
17 | # 是否忽略已取消的事件 [可选]
18 | # 如果处理事件时, 事件已经被取消, 那么会忽略该事件
19 | # 默认为 false
20 | ignore-cancelled: false
21 |
22 | hand: ""
23 |
24 | # 事件过滤器配置
25 | # 设置的过滤选项需要全部满足才会触发脚本
26 | filter: []
27 |
--------------------------------------------------------------------------------
/module-dispatcher/src/main/resources/dispatcher/example/PlayerMoveDispatcher.yml:
--------------------------------------------------------------------------------
1 | # 监听事件
2 | listen-event: 'org.bukkit.event.player.PlayerMoveEvent'
3 | # 监听优先级
4 | listen-priority: 'normal'
5 | # 是否监听已取消的事件
6 | listen-cancelled: false
7 |
8 | # 规则
9 | rule:
10 | # 触发优先级
11 | trigger-priority: 1
12 | # 是否需要玩家
13 | require-player: true
14 | # 是否监听视角的变化
15 | listen-view-change: true
16 | # 最小监听距离
17 | min-distance: 0.01
18 |
19 | # 过滤器
20 | filter:
21 | # 条件检查
22 | condition-check:
23 | # 条件
24 | condition:
25 | - '...'
26 | # 条件类型
27 | condition-type: '...'
28 | # 条件检查类型
29 | check-type: '...'
30 |
31 | # 脚本
32 | script:
33 | # 脚本超时
34 | timeout: 5s
35 | on-error: ...
36 | # 是否异步执行脚本
37 | async: false
38 | # 是否阻塞并等待脚本运行完毕 (谨慎操作)
39 | blocking: true
40 | # 预设变量
41 | variables:
42 | display: 'wcnm'
43 | # 编译命名空间
44 | namespace: [...]
45 | # 前置处理, 会在外部脚本执行前执行
46 | preprocess: ...
47 | # 后置处理, 会在外部脚本执行后执行
48 | postprocess: ...
49 | # 链接的外部脚本
50 | link: [...]
--------------------------------------------------------------------------------
/module-item-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-config"))
8 | compileOnly("ink.ptms.core:v12004:12004:mapped")
9 | // compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
10 |
11 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
12 | testImplementation("org.junit.jupiter:junit-jupiter")
13 | }
14 |
15 | tasks.test {
16 | useJUnitPlatform()
17 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/CustomEnchantment.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import top.lanscarlos.vulpecula.common.config.ConfigSource
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.item
8 | *
9 | * 基于 NBT 的自定义附魔拓展
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-12-16 00:50
13 | */
14 | class CustomEnchantment(val id: String, val config: ConfigSource) {
15 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/DefaultEntityInLevelCallback.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import net.minecraft.world.entity.Entity
4 | import net.minecraft.world.level.entity.EntityInLevelCallback
5 | import org.bukkit.entity.Item
6 | import taboolib.common.platform.function.info
7 | import taboolib.common.platform.function.warning
8 |
9 | /**
10 | * Vulpecula
11 | * top.lanscarlos.vulpecula.item
12 | *
13 | * @author Lanscarlos
14 | * @since 2024-11-28 17:40
15 | */
16 | class DefaultEntityInLevelCallback(private val source: EntityInLevelCallback, val entity: Item) : EntityInLevelCallback {
17 |
18 | init {
19 | info("DefaultEntityInLevelCallback >> proxy created.")
20 | }
21 |
22 | fun a() {
23 | source.onMove()
24 | }
25 |
26 | fun a(reason: Entity.RemovalReason?) {
27 | source.onRemove(reason)
28 | info("DefaultEntityInLevelCallback >> gaga onRemove by ${reason?.name}")
29 | }
30 |
31 | override fun onMove() {
32 | warning("DefaultEntityInLevelCallback >> onMove")
33 | }
34 |
35 | override fun onRemove(p0: Entity.RemovalReason?) {
36 | warning("DefaultEntityInLevelCallback >> onRemove")
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/DefaultVolatileAPI.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import net.minecraft.world.level.entity.EntityInLevelCallback
4 | import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity
5 | import org.bukkit.entity.Item
6 | import taboolib.common.platform.function.submit
7 | import taboolib.library.reflex.Reflex.Companion.getProperty
8 | import taboolib.module.nms.nmsProxy
9 |
10 | /**
11 | * Vulpecula
12 | * top.lanscarlos.vulpecula.item
13 | *
14 | * @author Lanscarlos
15 | * @since 2024-11-28 16:59
16 | */
17 | class DefaultVolatileAPI : VolatileAPI {
18 |
19 | override fun registerItemDespawnHandler(entity: Item) {
20 | val handle = (entity as CraftEntity).handle
21 | val levelCallback = handle.getProperty("levelCallback", findToParent = true, remap = true)!!
22 | val proxy = nmsProxy("top.lanscarlos.vulpecula.module.item.DefaultEntityInLevelCallback", levelCallback, entity)
23 | submit {
24 | // 使用 submit 覆写才能生效
25 | handle.setLevelCallback(proxy)
26 | }
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/EnchantmentAPI.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.item
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-12-16 00:49
9 | */
10 | object EnchantmentAPI {
11 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/EquipmentSource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.Material
4 | import org.bukkit.entity.LivingEntity
5 | import org.bukkit.inventory.ItemStack
6 | import taboolib.type.BukkitEquipment
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.item
11 | *
12 | * @author Lanscarlos
13 | * @since 2024-12-14 16:05
14 | */
15 | class EquipmentSource(val entity: LivingEntity, val slot: BukkitEquipment) : ItemSource {
16 |
17 | override fun get(): ItemStack {
18 | return slot.getItem(entity) ?: ItemStack(Material.AIR)
19 | }
20 |
21 | override fun set(item: ItemStack) {
22 | slot.setItem(entity, item)
23 | }
24 |
25 | override fun remove() {
26 | set(ItemStack(Material.AIR))
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/InventorySource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.Material
4 | import org.bukkit.inventory.Inventory
5 | import org.bukkit.inventory.ItemStack
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.item
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-12-14 15:58
13 | */
14 | class InventorySource(val inventory: Inventory, val slot: Int) : ItemSource {
15 |
16 | override fun get(): ItemStack {
17 | return inventory.getItem(slot) ?: ItemStack(Material.AIR)
18 | }
19 |
20 | override fun set(item: ItemStack) {
21 | inventory.setItem(slot, item)
22 | }
23 |
24 | override fun remove() {
25 | set(ItemStack(Material.AIR))
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemEntityHandler.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | //import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent
4 | //import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent
5 | import org.bukkit.entity.Item
6 | import org.bukkit.event.entity.EntitySpawnEvent
7 | import taboolib.common.platform.event.SubscribeEvent
8 | import taboolib.common.platform.function.info
9 |
10 | /**
11 | * Vulpecula
12 | * top.lanscarlos.vulpecula.item
13 | *
14 | * @author Lanscarlos
15 | * @since 2024-11-28 16:58
16 | */
17 | object ItemEntityHandler {
18 |
19 | // @SubscribeEvent
20 | // fun e(e: EntitySpawnEvent) {
21 | // info("EntitySpawnEvent >> ${e.entity.type.name}")
22 | // val item = e.entity as? Item ?: return
23 | // VolatileAPI.registerItemDespawnHandler(item)
24 | // }
25 |
26 | // @SubscribeEvent
27 | // fun e(e: PlayerArmorChangeEvent) {
28 | // info("PlayerArmorChangeEvent >> ${e.player.name}; slot=${e.slotType.name}; old=${e.oldItem}; new=${e.newItem}")
29 | // }
30 |
31 | // @SubscribeEvent
32 | // fun e(e: EntityRemoveFromWorldEvent) {
33 | // info("EntityRemoveFromWorldEvent >> ${e.entity.type.name}; slot=${e.world.name}")
34 | // }
35 |
36 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemNameEditor.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.item
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-12-14 16:32
9 | */
10 | object ItemNameEditor {
11 |
12 | fun append(source: ItemSource, name: String) {
13 | val item = source.get() ?: return
14 | source.set(item)
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemSource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.inventory.ItemStack
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.item
8 | *
9 | * 物品源
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-12-14 15:58
13 | */
14 | interface ItemSource {
15 |
16 | fun get(): ItemStack
17 |
18 | fun set(item: ItemStack)
19 |
20 | fun remove()
21 |
22 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemStackSource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.inventory.ItemStack
4 | import taboolib.common.platform.function.warning
5 | import taboolib.module.nms.MinecraftVersion
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.item
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-12-14 15:58
13 | */
14 | class ItemStackSource(val item: ItemStack) : ItemSource {
15 |
16 | override fun get(): ItemStack {
17 | return item
18 | }
19 |
20 | override fun set(item: ItemStack) {
21 | this.item.type = item.type
22 | this.item.amount = item.amount
23 | this.item.durability = item.durability
24 | this.item.itemMeta = item.itemMeta
25 | }
26 |
27 | override fun remove() {
28 | if (MinecraftVersion.major < MinecraftVersion.V1_12) {
29 | // 1.12 以下的版本可能存在问题
30 | warning("ItemStackSource#remove >> You are using a version lower than 1.12. Removing items may cause problems.")
31 | }
32 | item.amount = 0
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/module-item-test/src/main/kotlin/top/lanscarlos/vulpecula/module/item/VolatileAPI.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.entity.Item
4 | import taboolib.module.nms.nmsProxy
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.item
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-11-28 16:59
12 | */
13 | interface VolatileAPI {
14 |
15 | fun registerItemDespawnHandler(entity: Item)
16 |
17 | companion object : VolatileAPI by nmsProxy("top.lanscarlos.vulpecula.module.item.DefaultVolatileAPI")
18 |
19 | }
--------------------------------------------------------------------------------
/module-item/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-config"))
8 | compileOnly("ink.ptms.core:v12004:12004:mapped")
9 |
10 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
11 | testImplementation("org.junit.jupiter:junit-jupiter")
12 | }
13 |
14 | tasks.test {
15 | useJUnitPlatform()
16 | }
--------------------------------------------------------------------------------
/module-item/src/main/kotlin/top/lanscarlos/vulpecula/module/item/EquipmentSource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.Material
4 | import org.bukkit.entity.LivingEntity
5 | import org.bukkit.inventory.ItemStack
6 | import taboolib.type.BukkitEquipment
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.item
11 | *
12 | * @author Lanscarlos
13 | * @since 2024-12-14 16:05
14 | */
15 | class EquipmentSource(val entity: LivingEntity, val slot: BukkitEquipment) : ItemSource {
16 |
17 | override fun get(): ItemStack {
18 | return slot.getItem(entity) ?: ItemStack(Material.AIR)
19 | }
20 |
21 | override fun set(item: ItemStack) {
22 | slot.setItem(entity, item)
23 | }
24 |
25 | override fun remove() {
26 | set(ItemStack(Material.AIR))
27 | }
28 |
29 | override fun toStream(): ItemStream {
30 | return DefaultItemStream(this)
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/module-item/src/main/kotlin/top/lanscarlos/vulpecula/module/item/InventorySource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.Material
4 | import org.bukkit.inventory.Inventory
5 | import org.bukkit.inventory.ItemStack
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.item
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-12-14 15:58
13 | */
14 | class InventorySource(val inventory: Inventory, val slot: Int) : ItemSource {
15 |
16 | override fun get(): ItemStack {
17 | return inventory.getItem(slot) ?: ItemStack(Material.AIR)
18 | }
19 |
20 | override fun set(item: ItemStack) {
21 | inventory.setItem(slot, item)
22 | }
23 |
24 | override fun remove() {
25 | set(ItemStack(Material.AIR))
26 | }
27 |
28 | override fun toStream(): ItemStream {
29 | return DefaultItemStream(this)
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/module-item/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemCommand.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import taboolib.common.platform.command.CommandBody
4 | import taboolib.common.platform.command.component.CommandComponent
5 | import taboolib.common.platform.command.subCommand
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.item
10 | *
11 | * @author Lanscarlos
12 | * @since 2025-01-12 14:13
13 | */
14 | object ItemCommand {
15 |
16 | @CommandBody
17 | val item = subCommand {
18 | literal("switch", literal = switch)
19 | }
20 |
21 | val switch: CommandComponent.() -> Unit = {
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/module-item/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemSource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.inventory.ItemStack
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.module.item
8 | *
9 | * @author Lanscarlos
10 | * @since 2025-01-13 13:18
11 | */
12 | interface ItemSource {
13 |
14 | fun get(): ItemStack
15 |
16 | fun set(item: ItemStack)
17 |
18 | fun remove()
19 |
20 | fun toStream(): ItemStream
21 |
22 | }
--------------------------------------------------------------------------------
/module-item/src/main/kotlin/top/lanscarlos/vulpecula/module/item/ItemStackSource.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.item
2 |
3 | import org.bukkit.inventory.ItemStack
4 | import taboolib.common.platform.function.warning
5 | import taboolib.module.nms.MinecraftVersion
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.item
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-12-14 15:58
13 | */
14 | class ItemStackSource(val item: ItemStack) : ItemSource {
15 |
16 | override fun get(): ItemStack {
17 | return item
18 | }
19 |
20 | @Suppress("DEPRECATION")
21 | override fun set(item: ItemStack) {
22 | this.item.type = item.type
23 | this.item.amount = item.amount
24 | this.item.durability = item.durability
25 | this.item.itemMeta = item.itemMeta
26 | }
27 |
28 | override fun remove() {
29 | if (MinecraftVersion.major < MinecraftVersion.V1_12) {
30 | // 1.12 以下的版本可能存在问题
31 | warning("ItemStackSource#remove >> You are using a version lower than 1.12. Removing items may cause problems.")
32 | }
33 | item.amount = 0
34 | }
35 |
36 | override fun toStream(): ItemStream {
37 | return DefaultItemStream(this)
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/module-schedule/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-config"))
9 | compileOnly(project(":common-message"))
10 | compileOnly(project(":module-bacikal"))
11 | compileOnly(project(":module-script"))
12 | compileOnly("ink.ptms.core:v12004:12004:mapped")
13 |
14 | compileOnly("com.ucasoft.kcron:kcron-common:0.23.0")
15 |
16 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
17 | testImplementation("org.junit.jupiter:junit-jupiter")
18 | }
19 |
20 | tasks.test {
21 | useJUnitPlatform()
22 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/ScheduleTask.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.schedule
6 | *
7 | * @author Lanscarlos
8 | * @since 2025-05-11 09:42
9 | */
10 | interface ScheduleTask {
11 |
12 | val id: String
13 |
14 | val pid: String
15 |
16 | val state: TaskState
17 |
18 | val activationTime: Long
19 |
20 | val expirationTime: Long
21 |
22 | val counter: Int
23 |
24 | val isOutOfDuration: Boolean
25 |
26 | val isOutOfMaxRuns: Boolean
27 |
28 | /**
29 | * 开始
30 | * */
31 | fun start()
32 |
33 | /**
34 | * 暂停
35 | * */
36 | fun pause()
37 |
38 | /**
39 | * 恢复
40 | * */
41 | fun resume()
42 |
43 | /**
44 | * 终止
45 | * */
46 | fun stop()
47 |
48 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/TaskState.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.module.schedule
6 | *
7 | * @author Lanscarlos
8 | * @since 2025/5/12 15:18
9 | */
10 | enum class TaskState(val isRunning: Boolean) {
11 |
12 | WAITING(true), // 等待运行
13 | RUNNING(true), // 正在运行
14 | PAUSED(false), // 已暂停
15 | TERMINATED(false); // 已终止
16 |
17 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/selector/ConsoleSelector.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule.selector
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.function.console
5 | import top.lanscarlos.vulpecula.module.schedule.SenderSelector
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.schedule.selector
10 | *
11 | * @author Lanscarlos
12 | * @since 2025/5/22 11:39
13 | */
14 | object ConsoleSelector : SenderSelector {
15 | override fun select(sender: ProxyCommandSender?): List {
16 | return listOf(console())
17 | }
18 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/selector/OnlinePlayerSelector.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule.selector
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.function.onlinePlayers
5 | import top.lanscarlos.vulpecula.module.schedule.SenderSelector
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.schedule.selector
10 | *
11 | * @author Lanscarlos
12 | * @since 2025/5/22 11:40
13 | */
14 | object OnlinePlayerSelector : SenderSelector {
15 | override fun select(sender: ProxyCommandSender?): List {
16 | return onlinePlayers()
17 | }
18 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/selector/PlayerSelector.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule.selector
2 |
3 | import org.bukkit.Bukkit
4 | import taboolib.common.platform.ProxyCommandSender
5 | import taboolib.common.platform.function.adaptPlayer
6 | import top.lanscarlos.vulpecula.module.schedule.SenderSelector
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.schedule.selector
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/5/22 11:30
14 | */
15 | class PlayerSelector(val name: String) : SenderSelector {
16 | override fun select(sender: ProxyCommandSender?): List {
17 | return Bukkit.getPlayerExact(name)?.let(::adaptPlayer)?.let(::listOf)
18 | ?: error("无法选取脚本执行者, 玩家 $name 不在线.")
19 | }
20 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/selector/RangeSelector.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule.selector
2 |
3 | import org.bukkit.Location
4 | import org.bukkit.World
5 | import taboolib.common.platform.ProxyCommandSender
6 | import taboolib.common.platform.function.adaptPlayer
7 | import taboolib.platform.util.toBukkitLocation
8 | import top.lanscarlos.vulpecula.common.applicative.LocationApplicative
9 | import top.lanscarlos.vulpecula.module.schedule.SenderSelector
10 | import kotlin.math.pow
11 |
12 | /**
13 | * Vulpecula
14 | * top.lanscarlos.vulpecula.module.schedule.selector
15 | *
16 | * @author Lanscarlos
17 | * @since 2025/5/22 11:45
18 | */
19 | class RangeSelector(location: String, range: String) : SenderSelector {
20 |
21 | val center: Location = LocationApplicative.convertOrThrow(location).toBukkitLocation()
22 |
23 | val range = range.toDouble().pow(2)
24 |
25 | val world: World = center.world ?: error("坐标不合法.")
26 |
27 | override fun select(sender: ProxyCommandSender?): List {
28 | return world.players.filter { it.location.distanceSquared(center) <= range }.map(::adaptPlayer)
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/selector/SelfSelector.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule.selector
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.function.console
5 | import top.lanscarlos.vulpecula.module.schedule.SenderSelector
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.module.schedule.selector
10 | *
11 | * @author Lanscarlos
12 | * @since 2025/5/22 11:25
13 | */
14 | object SelfSelector : SenderSelector {
15 | override fun select(sender: ProxyCommandSender?): List {
16 | return sender?.let(::listOf) ?: listOf(console())
17 | }
18 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/kotlin/top/lanscarlos/vulpecula/module/schedule/selector/WorldSelector.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.schedule.selector
2 |
3 | import org.bukkit.Bukkit
4 | import taboolib.common.platform.ProxyCommandSender
5 | import taboolib.common.platform.function.adaptPlayer
6 | import top.lanscarlos.vulpecula.module.schedule.SenderSelector
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.schedule.selector
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/5/22 11:40
14 | */
15 | class WorldSelector(val name: String) : SenderSelector {
16 |
17 | override fun select(sender: ProxyCommandSender?): List {
18 | val world = Bukkit.getWorld(name)
19 | ?: error("无法解析世界 $name")
20 | return world.players.map(::adaptPlayer)
21 | }
22 | }
--------------------------------------------------------------------------------
/module-schedule/src/main/resources/schedule/cron.yml:
--------------------------------------------------------------------------------
1 |
2 | # 日程类型
3 | type: 'cron'
4 |
5 | # 秒的定义
6 | # 填入 * 表示每秒都执行
7 | # 填入 a-b 表示范围内的每个秒都执行一次
8 | # 填入 a/b:从第 a 秒开始每隔 b 秒执行一次
9 | # 填入 a,b,c:指定具体的秒执行
10 | seconds: '5 at 2'
11 |
12 | # 分的定义, 参考 seconds 字段
13 | minutes: '*'
14 |
15 | # 时的定义, 参考 seconds 字段
16 | hours: '*'
17 |
18 | # 日的定义, 这里表示的是一个月内的日期
19 | days: '*'
20 |
21 | # 月的定义
22 | months: '*'
23 |
24 | # 年的定义, 通常不会设计到这么大的跨度
25 | years: '*'
26 |
27 | # CRON 表达式, 此字段与 年月日时分秒 字段冲突
28 | # cron: '* * * * * ? *'
29 |
30 | # [选填] 最大运转时间
31 | # 格式参考 period 字段
32 | max-duration: '5h'
33 |
34 | # [选填] 最大循环次数, 默认为 -1
35 | # 设置为 -1 则无视循环次数
36 | max-replication: 10
37 |
38 | # [选填] 自启动, 默认为 false
39 | # 是否在服务器启动后自动激活日程
40 | auto-start: true
41 |
42 | # [选填] 原型模式
43 | # 启用后允许该日程多次执行
44 | prototype: false
45 |
46 | # [选填] 脚本执行者, 默认为 @console
47 | sender: '@console'
48 |
49 | # 执行模块
50 | # 支持调用脚本 script@<脚本ID>, 例如:script@example
51 | # 支持激活日程 schedule@<日程ID>, 例如:schedule@example
52 | execute: |-
53 | tell hi!
54 |
--------------------------------------------------------------------------------
/module-schedule/src/main/resources/schedule/periodic.yml:
--------------------------------------------------------------------------------
1 |
2 | # 日程类型
3 | type: 'periodic'
4 |
5 | # 循环间隔
6 | # 支持的单位:
7 | # 游戏刻 tick, t
8 | # 秒 second, s
9 | # 分 minute, min, m
10 | # 时 hour, h
11 | period: '5s'
12 |
13 | # [选填] 延迟激活
14 | # 格式参考 period 字段
15 | delay: '5s'
16 |
17 | # [选填] 最大运转时间
18 | # 格式参考 period 字段
19 | max-duration: '5m'
20 |
21 | # [选填] 最大循环次数, 默认为 -1
22 | # 设置为 -1 则无视循环次数
23 | max-replication: 10
24 |
25 | # [选填] 自启动, 默认为 false
26 | # 是否在服务器启动后自动激活日程
27 | auto-start: true
28 |
29 | # [选填] 原型模式
30 | # 启用后允许该日程多次执行
31 | prototype: false
32 |
33 | # [选填] 脚本执行者, 默认为 @console
34 | sender: '@console'
35 |
36 | # 执行模块
37 | # 支持调用脚本 script@<脚本ID>, 例如:script@example
38 | # 支持激活日程 schedule@<日程ID>, 例如:schedule@example
39 | execute: |-
40 | tell join [ "Hello, counter >> " &count ]
41 |
--------------------------------------------------------------------------------
/module-script/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":common-applicative"))
8 | compileOnly(project(":common-config"))
9 | compileOnly(project(":common-message"))
10 | compileOnly(project(":module-bacikal"))
11 | compileOnly("ink.ptms.core:v12004:12004:mapped")
12 |
13 | compileOnly("io.foldright:cffu:1.1.3")
14 |
15 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
16 | testImplementation("org.junit.jupiter:junit-jupiter")
17 | }
18 |
19 | tasks.test {
20 | useJUnitPlatform()
21 | }
--------------------------------------------------------------------------------
/module-script/src/main/kotlin/top/lanscarlos/vulpecula/module/script/AbstractScript.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.script
2 |
3 | import taboolib.library.kether.Quest
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.module.script
8 | *
9 | * @author Lanscarlos
10 | * @since 2025/5/20 13:55
11 | */
12 | abstract class AbstractScript : Script {
13 |
14 | abstract val quest: Quest
15 |
16 | }
--------------------------------------------------------------------------------
/module-script/src/main/kotlin/top/lanscarlos/vulpecula/module/script/DefaultScriptTask.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.script
2 |
3 | import taboolib.module.kether.ScriptContext
4 | import java.util.concurrent.CompletableFuture
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.script
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/27 14:10
12 | */
13 | class DefaultScriptTask(
14 | override val pid: Long,
15 | override val script: Script,
16 | val context: ScriptContext,
17 | override var future: CompletableFuture,
18 | override val startTime: Long
19 | ) : ScriptTask {
20 |
21 | override val isDone: Boolean
22 | get() = future.isDone
23 |
24 | override fun terminate() {
25 | context.terminate()
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/module-script/src/main/kotlin/top/lanscarlos/vulpecula/module/script/ProxyScript.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.script
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import top.lanscarlos.vulpecula.module.bacikal.exception.BacikalRuntimeException
5 | import java.util.function.Consumer
6 | import java.util.function.Function
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.script
11 | *
12 | * @author Lanscarlos
13 | * @since 2025-05-10 23:16
14 | */
15 | class ProxyScript(override val id: String) : Script {
16 |
17 | override fun run(
18 | sender: ProxyCommandSender?,
19 | args: List,
20 | variables: Map,
21 | onSuccess: Consumer,
22 | onFailure: Function
23 | ): ScriptTask {
24 | val script = ScriptService.get(id)
25 | return script.run(sender, args, variables, onSuccess, onFailure)
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/module-script/src/main/kotlin/top/lanscarlos/vulpecula/module/script/Script.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.script
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import top.lanscarlos.vulpecula.module.bacikal.exception.BacikalRuntimeException
5 | import java.util.function.Consumer
6 | import java.util.function.Function
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.module.script
11 | *
12 | * @author Lanscarlos
13 | * @since 2025-03-19 16:48
14 | */
15 | interface Script {
16 |
17 | val id: String
18 |
19 | fun run(
20 | sender: ProxyCommandSender?,
21 | args: List,
22 | variables: Map,
23 | onSuccess: Consumer,
24 | onFailure: Function
25 | ): ScriptTask
26 |
27 | }
--------------------------------------------------------------------------------
/module-script/src/main/kotlin/top/lanscarlos/vulpecula/module/script/ScriptTask.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.script
2 |
3 | import taboolib.module.kether.ScriptContext
4 | import java.util.concurrent.CompletableFuture
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.module.script
9 | *
10 | * 代表一个正在运行中的脚本任务
11 | *
12 | * @author Lanscarlos
13 | * @since 2025/4/27 14:02
14 | */
15 | interface ScriptTask {
16 |
17 | val pid: Long
18 |
19 | val script: Script
20 |
21 | val future: CompletableFuture
22 |
23 | val startTime: Long
24 |
25 | val isDone: Boolean
26 |
27 | fun terminate()
28 |
29 | }
--------------------------------------------------------------------------------
/module-script/src/main/kotlin/top/lanscarlos/vulpecula/module/script/exception/ScriptNotFoundException.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.module.script.exception
2 |
3 | import top.lanscarlos.vulpecula.common.message.MessageService
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.module.script.exception
8 | *
9 | * @author Lanscarlos
10 | * @since 2025/5/6 14:20
11 | */
12 | class ScriptNotFoundException(scriptId: String) : RuntimeException() {
13 |
14 | override val message: String = MessageService.asLang("module-script-exception-script-not-found", scriptId)
15 |
16 | }
--------------------------------------------------------------------------------
/module-script/src/main/resources/lang/zh_CN.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 脚本模块
4 | module-script-service-load-success: '成功加载 &a{0}&7 个脚本 &8({0}ms)'
5 | module-script-service-load-failure: '脚本 &c{0}&7 加载失败!'
6 | module-script-command-run: '正在运行脚本 &a{0}&7. 执行者 &a{1}&7, 参数 &a{2}&7'
7 | module-script-command-run-success: '脚本 &a{0}&7 运行成功. 运行结果: &a{1}&7'
8 | module-script-command-run-failure: '脚本 &c{0}&7 运行异常.'
9 | module-script-command-stop: '终止脚本 &a{0}&7.'
10 | module-script-command-task-stop: '终止脚本任务 &a{0}&7.'
11 | module-script-command-task-list-header: '当前正在运行的脚本任务:'
12 | module-script-command-task-list-item: '&7 - PID: &a{0}&7; 脚本: &a{1}&7; 开始时间: &a{2}'
13 | module-script-command-task-list-footer: ''
14 |
15 | module-script-exception-script-not-found: '脚本 &c{0}&7 不存在.'
16 |
17 |
--------------------------------------------------------------------------------
/module-script/src/main/resources/script/example.yml:
--------------------------------------------------------------------------------
1 | # 预设编译命名空间
2 | namespace: [ 'chemdah' ]
3 |
4 | # 参数列表
5 | parameters: []
6 |
7 | # 返回值转换
8 | return-conversion: 'location'
9 |
10 | # 简单变量预设
11 | variables:
12 | display: 'wcnm'
13 |
14 | # 入口主函数
15 | main: |-
16 | print "你好, 欢迎使用 Vulpecula 脚本!"
17 |
18 | # 其他函数
19 | functions:
20 | func-name: |-
21 | xxx
22 |
23 | timeout: 500ms
24 | on-timeout: |-
25 | print "脚本 $name 运行超时!"
26 |
27 | exception:
28 | - catch: 'NullPointerException'
29 | handle: |-
30 | print "脚本 $name 运行时出现 NullPointerException 异常"
31 |
32 | # 碎片替换
33 | fragments:
34 | name: 'example'
35 |
--------------------------------------------------------------------------------
/module-wireshark/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly("ink.ptms.core:v12001:12001:mapped")
8 |
9 | testImplementation(platform("org.junit:junit-bom:5.9.1"))
10 | testImplementation("org.junit.jupiter:junit-jupiter")
11 | }
12 |
13 | tasks.test {
14 | useJUnitPlatform()
15 | }
16 |
17 | gradle.buildFinished {
18 | buildDir.deleteRecursively()
19 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/DefaultPacketMatcher.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import taboolib.module.nms.Packet
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.wireshark
8 | *
9 | * @author Lanscarlos
10 | * @since 2024-11-12 21:53
11 | */
12 | class DefaultPacketMatcher() : PacketMatcher {
13 |
14 | override fun matches(packet: Packet): Boolean {
15 | TODO("Not yet implemented")
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/DefaultPacketTracker.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import taboolib.module.nms.PacketReceiveEvent
4 | import taboolib.module.nms.PacketSendEvent
5 | import java.util.LinkedList
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.wireshark
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-11-12 19:15
13 | */
14 | class DefaultPacketTracker : PacketTracker {
15 |
16 | val cache = LinkedList()
17 |
18 | override fun track(event: PacketReceiveEvent) {
19 | cache += PacketCache(event.packet, event.player)
20 | }
21 |
22 | override fun track(event: PacketSendEvent) {
23 | cache += PacketCache(event.packet, event.player)
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/PacketCache.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import org.bukkit.entity.Player
4 | import taboolib.module.nms.Packet
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.wireshark
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-11-12 21:00
12 | */
13 | data class PacketCache(
14 | val packet: Packet,
15 | val player: Player,
16 | val time: Long = System.currentTimeMillis()
17 | )
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/PacketDispatcher.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import taboolib.common.platform.event.SubscribeEvent
4 | import taboolib.module.nms.PacketReceiveEvent
5 | import taboolib.module.nms.PacketSendEvent
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.wireshark
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-11-12 15:59
13 | */
14 | object PacketDispatcher {
15 |
16 | @SubscribeEvent
17 | fun onPacketReceive(e: PacketReceiveEvent) {
18 | for (session in Session.registry.values) {
19 | session.onPacketReceive(e)
20 | }
21 | }
22 |
23 | @SubscribeEvent
24 | fun onPacketSend(e: PacketSendEvent) {
25 | for (session in Session.registry.values) {
26 | session.onPacketSend(e)
27 | }
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/PacketFilter.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import taboolib.module.nms.PacketReceiveEvent
4 | import taboolib.module.nms.PacketSendEvent
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.wireshark
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-11-12 17:52
12 | */
13 | interface PacketFilter {
14 |
15 | /**
16 | * 过滤数据包
17 | *
18 | * @param event 数据包事件
19 | * @return 是否过滤
20 | */
21 | fun filter(event: PacketReceiveEvent): Boolean
22 |
23 | /**
24 | * 过滤数据包
25 | *
26 | * @param event 数据包事件
27 | * @return 是否过滤
28 | */
29 | fun filter(event: PacketSendEvent): Boolean
30 |
31 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/PacketMatcher.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import taboolib.module.nms.Packet
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.wireshark
8 | *
9 | * @author Lanscarlos
10 | * @since 2024-11-12 21:48
11 | */
12 | interface PacketMatcher {
13 |
14 | fun matches(packet: Packet): Boolean
15 |
16 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/PacketMatcherBuilder.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.wireshark
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-11-12 21:49
9 | */
10 | class PacketMatcherBuilder {
11 |
12 | // fun build(): PacketMatcher {
13 | // return object : PacketMatcher {}
14 | // }
15 |
16 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/kotlin/top/lanscarlos/vulpecula/wireshark/PacketTracker.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.wireshark
2 |
3 | import taboolib.module.nms.PacketReceiveEvent
4 | import taboolib.module.nms.PacketSendEvent
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.wireshark
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-11-12 19:14
12 | */
13 | interface PacketTracker {
14 |
15 | fun track(event: PacketReceiveEvent)
16 |
17 | fun track(event: PacketSendEvent)
18 |
19 | }
--------------------------------------------------------------------------------
/module-wireshark/src/main/resources/config/wireshark.conf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/module-wireshark/src/main/resources/config/wireshark.conf
--------------------------------------------------------------------------------
/platform-bukkit/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
--------------------------------------------------------------------------------
/platform-bukkit/src/main/kotlin/top/lanscarlos/vulpecula/platform/bukkit/VulpeculaPlugin.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.platform.bukkit
2 |
3 | import taboolib.common.platform.Plugin
4 | import taboolib.common.platform.function.info
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.platform.bukkit
9 | *
10 | * @author Lanscarlos
11 | * @since 2025/4/27 17:15
12 | */
13 | object VulpeculaPlugin : Plugin() {
14 |
15 | override fun onEnable() {
16 | info("Successfully running Vulpecula!")
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/project/common-core/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":project:common"))
8 | compileOnly(project(":project:module-applicative"))
9 | compileOnly(project(":project:module-bacikal"))
10 | compileOnly(project(":project:module-config"))
11 |
12 | compileOnly("ink.ptms.core:v12001:12001:mapped")
13 | compileOnly("ink.ptms.core:v12001:12001:universal")
14 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/DispatcherPipeline.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity
2 |
3 | import org.bukkit.event.Event
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.modularity
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-12-28 00:40
11 | */
12 | interface DispatcherPipeline {
13 |
14 | /**
15 | * 过滤事件
16 | * */
17 | fun filter(event: T): Boolean
18 |
19 | /**
20 | * 前置处理
21 | * */
22 | fun preprocess(event: T)
23 |
24 | /**
25 | * 预设内置变量
26 | * */
27 | fun variables(event: T): Map
28 |
29 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/ModularCommand.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity
2 |
3 | import taboolib.common.platform.command.PermissionDefault
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.modularity
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-09-02 10:50
11 | */
12 | interface ModularCommand : ModularComponent {
13 |
14 | /**
15 | * 命令名称
16 | * */
17 | val name: String
18 |
19 | /**
20 | * 命令别名
21 | * */
22 | val aliases: List
23 |
24 | /**
25 | * 命令描述
26 | * */
27 | val description: String
28 |
29 | /**
30 | * 命令用法
31 | * */
32 | val usage: String
33 |
34 | /**
35 | * 命令权限
36 | * */
37 | val permission: String
38 |
39 | /**
40 | * 命令权限消息
41 | * */
42 | val permissionMessage: String
43 |
44 | /**
45 | * 命令权限默认值
46 | * */
47 | val permissionDefault: PermissionDefault
48 |
49 | /**
50 | * 是否使用新解析器
51 | * */
52 | val useParser: Boolean
53 |
54 | /**
55 | * 注册命令
56 | * */
57 | fun register()
58 |
59 | /**
60 | * 注销命令
61 | * */
62 | fun unregister()
63 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/ModularComponent.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity
2 |
3 | import java.io.File
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.modularity
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-30 23:01
11 | */
12 | interface ModularComponent {
13 |
14 | /**
15 | * 组件 ID
16 | * */
17 | val id: String
18 |
19 | /**
20 | * 所在文件
21 | * */
22 | val file: File
23 |
24 | /**
25 | * 所属模块
26 | * */
27 | val module: Module
28 |
29 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/ModularSchedule.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.modularity
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-09-02 10:38
9 | */
10 | interface ModularSchedule : ModularComponent {
11 |
12 | /**
13 | * 任务周期
14 | * */
15 | val period: Long
16 |
17 | /**
18 | * 延迟时间
19 | * */
20 | val delay: Long
21 |
22 | /**
23 | * 起始时间
24 | * */
25 | val startTime: Long
26 |
27 | /**
28 | * 结束时间
29 | * */
30 | val endTime: Long
31 |
32 | /**
33 | * 是否自动启动
34 | * 即在服务器进入 ACTIVE 状态时自动启动
35 | * */
36 | val autostart: Boolean
37 |
38 | /**
39 | * 是否在异步线程运行
40 | * */
41 | val isAsync: Boolean
42 |
43 | /**
44 | * 是否正在运行
45 | * */
46 | val isRunning: Boolean
47 |
48 | /**
49 | * 启动任务
50 | * */
51 | fun start()
52 |
53 | /**
54 | * 停止任务
55 | * */
56 | fun stop()
57 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/ModularScript.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.modularity
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-09-02 10:54
9 | */
10 | interface ModularScript : ModularComponent {
11 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/Module.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity
2 |
3 | import top.lanscarlos.vulpecula.bacikal.BacikalWorkspace
4 | import java.io.File
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.modularity
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-08-29 16:46
12 | */
13 | interface Module {
14 |
15 | val id: String
16 |
17 | val directory: File
18 |
19 | val dispatchers: Map
20 |
21 | val workspace: BacikalWorkspace
22 |
23 | /**
24 | * 启用模块
25 | * */
26 | fun enable()
27 |
28 | /**
29 | * 禁用模块
30 | * */
31 | fun disable()
32 |
33 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/pipeline/MovePipeline.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity.pipeline
2 |
3 | import org.bukkit.event.player.PlayerMoveEvent
4 | import top.lanscarlos.vulpecula.config.DynamicConfig
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.core.modularity.pipeline
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-01-03 00:23
12 | */
13 | class MovePipeline(config: DynamicConfig) : AbstractPipeline(config) {
14 |
15 | /**
16 | * 是否忽略视角变动
17 | * */
18 | val ignoreView by config.readBoolean("ignore-view", true)
19 |
20 | override fun filter(event: PlayerMoveEvent): Boolean {
21 | if (ignoreView) {
22 | if (event.from.world != event.to?.world) {
23 | // 忽略跨世界移动
24 | return true
25 | }
26 | val to = event.to ?: return true
27 | return event.from.distanceSquared(to) > 1e-3
28 | }
29 | return true
30 | }
31 |
32 | override fun preprocess(event: PlayerMoveEvent) {
33 | }
34 |
35 | override fun variables(event: PlayerMoveEvent): Map {
36 | return mapOf(
37 | "from" to event.from,
38 | "to" to event.to
39 | )
40 | }
41 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/modularity/pipeline/PlayerPipeline.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.modularity.pipeline
2 |
3 | import org.bukkit.event.player.PlayerEvent
4 | import top.lanscarlos.vulpecula.config.DynamicConfig
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.core.modularity.pipeline
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-01-03 00:33
12 | */
13 | class PlayerPipeline(config: DynamicConfig) : AbstractPipeline(config) {
14 | override fun filter(event: PlayerEvent): Boolean {
15 | return true
16 | }
17 |
18 | override fun preprocess(event: PlayerEvent) {
19 | }
20 |
21 | override fun variables(event: PlayerEvent): Map {
22 | return mapOf(VARIABLE_PLAYER to event.player)
23 | }
24 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/kotlin/top/lanscarlos/vulpecula/core/utils/MessageUtil.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.core.utils
2 |
3 | import taboolib.common.platform.ProxyCommandSender
4 | import taboolib.common.platform.ProxyPlayer
5 | import taboolib.common.platform.function.console
6 | import taboolib.module.lang.sendLang
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.core.utils
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-08-27 13:59
14 | */
15 |
16 | fun ProxyCommandSender.infoLang(node: String, vararg args: String) {
17 | if (this is ProxyPlayer) {
18 | this.sendLang(node, *args)
19 | }
20 | console().sendLang(node, *args)
21 | }
--------------------------------------------------------------------------------
/project/common-core/src/main/resources/class-aliases.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/project/common-core/src/main/resources/class-aliases.yml
--------------------------------------------------------------------------------
/project/common-core/src/main/resources/config.yml:
--------------------------------------------------------------------------------
1 |
2 | # 命令 Vulpecula Timing 测试次数
3 | command-timing-repeat: 10000
--------------------------------------------------------------------------------
/project/common-core/src/main/resources/lang/zh_CN.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 主配置
4 |
5 | Config-Load-Succeeded: '&8[&3Vul&bpecula&8] &a良好 &8|&7 加载 Config.yml 完毕! &8({0} ms)'
6 | Config-Load-Failed: |-
7 | &8[&3Vul&bpecula&8] &c错误 &8|&7 Config.yml 加载失败!
8 | &e[ERROR: Config@Load]: {0}
--------------------------------------------------------------------------------
/project/common-core/src/main/resources/modules/#def/module.yml:
--------------------------------------------------------------------------------
1 |
2 | # 模块配置文件
3 |
4 | automatic-reload:
5 | dispatcher: true
6 | handler: true
--------------------------------------------------------------------------------
/project/common-legacy/libs/AbolethCoreAPI-1.0.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/project/common-legacy/libs/AbolethCoreAPI-1.0.0.jar
--------------------------------------------------------------------------------
/project/common-legacy/libs/AdyeshachAPI-2.0.0-snapshot-30.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/project/common-legacy/libs/AdyeshachAPI-2.0.0-snapshot-30.jar
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/api/VulpeculaAPI.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.api
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.api
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-02-09 18:19
9 | */
10 | object VulpeculaAPI {
11 |
12 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/api/chemdah/Utils.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.api.chemdah
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.api.chemdah
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-01-23 00:24
9 | */
10 | fun String.startsWithAny(vararg prefix: String): Boolean {
11 | return prefix.any { startsWith(it) }
12 | }
13 |
14 | fun String.substringAfterAny(vararg morePrefix: String): String {
15 | return substringAfter(morePrefix.firstOrNull { startsWithAny(it) } ?: return this)
16 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/api/event/InferItemHookEvent.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.api.event
2 |
3 | import taboolib.platform.type.BukkitProxyEvent
4 | import top.lanscarlos.vulpecula.legacy.api.chemdah.InferItem
5 |
6 | /**
7 | * Chemdah
8 | * ink.ptms.chemdah.api.event.InferItemHookEvent
9 | *
10 | * @author sky
11 | * @since 2021/4/17 2:41 下午
12 | */
13 | class InferItemHookEvent(val id: String, var itemClass: Class) : BukkitProxyEvent() {
14 |
15 | override val allowCancelled: Boolean
16 | get() = false
17 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/Bacikal.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal
2 |
3 | import taboolib.library.kether.QuestAction
4 | import taboolib.module.kether.ScriptFrame
5 | import taboolib.module.kether.printKetherErrorMessage
6 | import java.util.concurrent.CompletableFuture
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.bacikal
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-02-27 15:32
14 | */
15 | class Bacikal {
16 |
17 | class Action(val func: (ScriptFrame) -> CompletableFuture) {
18 | fun run(frame: ScriptFrame): CompletableFuture {
19 | return func(frame).exceptionally {
20 | it.printKetherErrorMessage()
21 | null
22 | }
23 | }
24 | }
25 |
26 | class Parser(val action: Action) {
27 |
28 | constructor(func: (ScriptFrame) -> CompletableFuture) : this(Action(func))
29 |
30 | fun resolve(): QuestAction {
31 | return object : QuestAction() {
32 | override fun process(frame: ScriptFrame): CompletableFuture {
33 | return action.run(frame)
34 | }
35 | }
36 | }
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/BacikalParser.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-19 22:02
9 | */
10 | annotation class BacikalParser(
11 | val id: String,
12 | val aliases: Array,
13 | val namespace: String = "vulpecula",
14 | val shared: Boolean = true
15 | )
16 |
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/BacikalProperty.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal
2 |
3 | import kotlin.reflect.KClass
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-19 22:12
11 | */
12 | annotation class BacikalProperty(
13 | val id: String,
14 | val bind: KClass<*>,
15 | val shared: Boolean = true
16 | )
17 |
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/BacikalWorkspace.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal
6 | *
7 | * Todo()
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-02-26 13:32
11 | */
12 | object BacikalWorkspace {
13 |
14 | // private val coroutineScope by lazy { CoroutineScope(Dispatchers.Default) }
15 | //
16 | // fun launch(block: suspend CoroutineScope.() -> Unit) {
17 | // coroutineScope.launch(block = block)
18 | // }
19 |
20 | // fun shutdown() {
21 | // coroutineScope.cancel()
22 | // }
23 |
24 | // fun runActions() {
25 | //
26 | // }
27 |
28 | // @KetherParser(["output"])
29 | // fun parser() = scriptParser {
30 | // val next = it.nextParsedAction()
31 | // actionTake {
32 | // val future = CompletableFuture()
33 | // info("before")
34 | // launch {
35 | // info("inner")
36 | // val result = run(next).join()
37 | // info("result -> $result")
38 | // future.complete(result)
39 | // }
40 | // info("after")
41 | // future
42 | // }
43 | // }
44 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/LiveDataProxy.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal
2 |
3 | import taboolib.module.kether.ScriptFrame
4 | import java.util.concurrent.CompletableFuture
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-02-27 13:45
12 | */
13 | class LiveDataProxy(
14 | vararg val prefix: String,
15 | val source: LiveData,
16 | val def: T
17 | ) : LiveData(source.func) {
18 |
19 | fun accept(prefix: String, reader: BacikalReader) {
20 | if (prefix !in this.prefix) return
21 | source.accept(reader)
22 | }
23 |
24 | override fun accept(reader: BacikalReader): LiveData = source
25 |
26 | override fun accept(frame: ScriptFrame): CompletableFuture {
27 | return if (source.isAccepted()) {
28 | source.accept(frame)
29 | } else {
30 | CompletableFuture.completedFuture(def)
31 | }
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/RegistryMetadata.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal
2 |
3 | import taboolib.library.kether.QuestActionParser
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-26 14:06
11 | */
12 | class RegistryMetadata(
13 | val id: String,
14 | val parser: QuestActionParser,
15 | val aliases: Array,
16 | val namespace: Array,
17 | val shared: Boolean,
18 | val injectDefaultNamespace: Boolean
19 | )
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/fx/ConstantFx.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.fx
2 |
3 | import top.lanscarlos.vulpecula.legacy.bacikal.Bacikal
4 | import top.lanscarlos.vulpecula.legacy.bacikal.BacikalReader
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.canvas.fx
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-06-29 11:45
12 | */
13 | class ConstantFx(val value: Double) : DecimalFx() {
14 |
15 | override fun calculate(): Double {
16 | return value
17 | }
18 |
19 | override fun calculate(input: Double): Double {
20 | return value
21 | }
22 |
23 | override fun copy(): ConstantFx {
24 | return ConstantFx(value)
25 | }
26 |
27 | companion object : ActionFx.Resolver {
28 |
29 | override val name = arrayOf("constant", "c")
30 |
31 | override fun resolve(reader: BacikalReader): Bacikal.Parser> {
32 | return reader.run {
33 | combine(
34 | double(display = "fx constant")
35 | ) { value ->
36 | ConstantFx(value)
37 | }
38 | }
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/fx/DecimalFx.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.fx
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.canvas.fx
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-06-30 00:07
9 | */
10 | abstract class DecimalFx : NumberFx()
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/fx/Fx.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.fx
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.canvas.fx
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-06-29 11:36
9 | */
10 | interface Fx {
11 |
12 | /**
13 | * 根据自增计算输出值
14 | * */
15 | fun calculate(): R
16 |
17 | /**
18 | * 根据输入值计算输出值
19 | * */
20 | fun calculate(input: T): R
21 |
22 | fun copy(): Fx
23 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/fx/NumberFx.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.fx
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.canvas.fx
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-06-30 00:06
9 | */
10 | abstract class NumberFx : Number(), Fx {
11 |
12 | override fun toByte(): Byte {
13 | return calculate().toByte()
14 | }
15 |
16 | override fun toChar(): Char {
17 | return calculate().toChar()
18 | }
19 |
20 | override fun toShort(): Short {
21 | return calculate().toShort()
22 | }
23 |
24 | override fun toInt(): Int {
25 | return calculate().toInt()
26 | }
27 |
28 | override fun toLong(): Long {
29 | return calculate().toLong()
30 | }
31 |
32 | override fun toFloat(): Float {
33 | return calculate().toFloat()
34 | }
35 |
36 | override fun toDouble(): Double {
37 | return calculate().toDouble()
38 | }
39 |
40 | override fun toString(): String {
41 | return calculate().toString()
42 | }
43 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/fx/SimpleVectorFx.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.fx
2 |
3 | import taboolib.common.util.Vector
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.canvas.fx
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-06-30 11:28
11 | */
12 | class SimpleVectorFx(
13 | val x: Number?,
14 | val y: Number?,
15 | val z: Number?
16 | ) : VectorFx() {
17 |
18 | constructor(vector: Vector): this(vector.x, vector.y, vector.z)
19 |
20 | override fun calculate(): Vector {
21 | return Vector(x?.toDouble() ?: 0.0, y?.toDouble() ?: 0.0, z?.toDouble() ?: 0.0)
22 | }
23 |
24 | override fun calculate(input: Unit): Vector {
25 | return calculate()
26 | }
27 |
28 | override fun copy(): SimpleVectorFx {
29 | return SimpleVectorFx(x, y, z)
30 | }
31 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/fx/VectorFx.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.fx
2 |
3 | import taboolib.common.util.Vector
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.canvas.fx
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-06-30 01:35
11 | */
12 | abstract class VectorFx : Fx
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/ActionPatternSelect.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.ActionCanvas
4 | import top.lanscarlos.vulpecula.legacy.utils.getVariable
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-06-29 14:19
12 | */
13 | object ActionPatternSelect : ActionPattern.PatternResolver {
14 |
15 | override val name: Array = arrayOf("select", "sel")
16 |
17 | override fun resolve(reader: ActionPattern.Reader): ActionPattern.Handler {
18 | return reader.handle {
19 | combine(
20 | int(display = "pattern index")
21 | ) { index ->
22 | val patterns = this.getVariable>(ActionCanvas.VARIABLE_PATTERNS) ?: error("No patterns selected.")
23 | patterns.getOrNull(index - 1) ?: error("Illegal pattern index \"$index\" at pattern action.")
24 | }
25 | }
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/CanvasPattern.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import taboolib.common.util.Location
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
8 | *
9 | * @author Lanscarlos
10 | * @since 2022-11-10 10:32
11 | */
12 | interface CanvasPattern {
13 |
14 | /**
15 | * 获取图案的下一个点坐标
16 | *
17 | * @param origin 原点,当内置原点时,优先使用内置原点
18 | * @return 点坐标
19 | * */
20 | fun point(origin: Location): Location
21 |
22 | /**
23 | * 获取图案的所有点坐标
24 | *
25 | * @param origin 原点,当内置原点时,优先使用内置原点
26 | * @return 坐标集合
27 | * */
28 | fun shape(origin: Location): Collection
29 |
30 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/LinePattern.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import kotlin.math.cos
4 | import kotlin.math.sin
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-07-07 13:33
12 | */
13 | object LinePattern : ActionPattern.PatternResolver {
14 |
15 | override val name = arrayOf("line")
16 |
17 | override fun resolve(reader: ActionPattern.Reader): ActionPattern.Handler {
18 | return reader.handle {
19 | combine(
20 | argument("step", "s", then = double(), def = 0.1),
21 | argument("init", "i", then = double(), def = 0.0),
22 | argument("loop", then = bool(), def = false)
23 | ) { step, init, loop ->
24 | val points = intArrayOf(0, 180).map {
25 | val radians = Math.toRadians(it + init)
26 | cos(radians) to sin(radians)
27 | }
28 |
29 | PolygonPattern(points, step, loop)
30 | }
31 | }
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/PentagramPattern.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import kotlin.math.cos
4 | import kotlin.math.sin
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
9 | *
10 | * 五角星
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-07-10 23:36
14 | */
15 | object PentagramPattern : ActionPattern.PatternResolver {
16 |
17 | override val name = arrayOf("pentagram")
18 |
19 | override fun resolve(reader: ActionPattern.Reader): ActionPattern.Handler {
20 | return reader.handle {
21 | combine(
22 | argument("step", "s", then = double(0.1), def = 0.1),
23 | argument("init", "i", then = double(0.0), def = 0.0)
24 | ) { step, init ->
25 | val points = intArrayOf(0, 216, 72, 288, 144).map {
26 | val radians = Math.toRadians(it + init)
27 | cos(radians) to sin(radians)
28 | }
29 |
30 | PolygonPattern(points, step, true)
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/SquarePattern.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import kotlin.math.cos
4 | import kotlin.math.sin
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
9 | *
10 | * 正方形
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-07-10 23:35
14 | */
15 | object SquarePattern : ActionPattern.PatternResolver {
16 |
17 | override val name = arrayOf("square")
18 |
19 | override fun resolve(reader: ActionPattern.Reader): ActionPattern.Handler {
20 | return reader.handle {
21 | combine(
22 | argument("step", "s", then = double(0.1), def = 0.1),
23 | argument("init", "i", then = double(0.0), def = 0.0)
24 | ) { step, init ->
25 | val points = intArrayOf(45, 135, 225, 315).map {
26 | val radians = Math.toRadians(init + it)
27 | cos(radians) to sin(radians)
28 | }
29 |
30 | PolygonPattern(points, step, true)
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/Transformer.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import taboolib.common.util.Location
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-06-29 11:29
11 | */
12 | interface Transformer {
13 |
14 | /**
15 | * 变换
16 | * @param origin 原点
17 | * @param target 目标点
18 | * */
19 | fun transform(origin: Location, target: Location): Location
20 |
21 | /**
22 | * 变换
23 | * */
24 | fun transform(origin: Location, target: Collection): Collection
25 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/canvas/pattern/TrianglePattern.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.canvas.pattern
2 |
3 | import kotlin.math.cos
4 | import kotlin.math.sin
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.canvas.pattern
9 | *
10 | * 三角形
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-07-08 23:46
14 | */
15 | object TrianglePattern : ActionPattern.PatternResolver {
16 |
17 | override val name = arrayOf("triangle")
18 |
19 | override fun resolve(reader: ActionPattern.Reader): ActionPattern.Handler {
20 | return reader.handle {
21 | combine(
22 | argument("step", "s", then = double(0.1), def = 0.1),
23 | argument("init", "i", then = double(0.0), def = 0.0)
24 | ) { step, init ->
25 | val points = intArrayOf(0, 120, 240).map {
26 | val radians = Math.toRadians(it + init)
27 | cos(radians) to sin(radians)
28 | }
29 |
30 | PolygonPattern(points, step, true)
31 | }
32 | }
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/event/ActionEventCancel.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.event
2 |
3 | import org.bukkit.event.Cancellable
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.event
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-23 16:13
11 | */
12 | object ActionEventCancel : ActionEvent.Resolver {
13 |
14 | override val name: Array = arrayOf("cancel")
15 |
16 | /**
17 | * event cancel
18 | * */
19 | override fun resolve(reader: ActionEvent.Reader): ActionEvent.Handler {
20 | return reader.transfer {
21 | combine(
22 | source(),
23 | optional("to", then = bool(), def = true)
24 | ) { event, cancelled ->
25 | (event as? Cancellable)?.isCancelled = cancelled
26 | event
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/event/ActionEventCancelled.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.event
2 |
3 | import org.bukkit.event.Cancellable
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.event
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-23 16:13
11 | */
12 | object ActionEventCancelled : ActionEvent.Resolver {
13 |
14 | override val name: Array = arrayOf("cancelled")
15 |
16 | /**
17 | * event cancelled
18 | * */
19 | override fun resolve(reader: ActionEvent.Reader): ActionEvent.Handler {
20 | return reader.handle {
21 | combine(
22 | source()
23 | ) { event ->
24 | (event as? Cancellable)?.isCancelled ?: false
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/event/ActionEventName.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.event
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.event
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-23 16:13
9 | */
10 | object ActionEventName : ActionEvent.Resolver {
11 |
12 | override val name: Array = arrayOf("name")
13 |
14 | /**
15 | * event name
16 | * */
17 | override fun resolve(reader: ActionEvent.Reader): ActionEvent.Handler {
18 | return reader.handle {
19 | combine(
20 | source()
21 | ) { event ->
22 | event.eventName
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/illusion/ActionIllusionHealth.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.illusion
2 |
3 | import top.lanscarlos.vulpecula.legacy.bacikal.Bacikal
4 | import top.lanscarlos.vulpecula.volatile.VolatileEntityMetadata
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.illusion
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-08-09 23:15
12 | */
13 | object ActionIllusionHealth : ActionIllusion.Resolver {
14 |
15 | override val name = arrayOf("health")
16 |
17 | override fun resolve(reader: ActionIllusion.Reader): Bacikal.Parser {
18 | return reader.run {
19 | combine(
20 | source(),
21 | expect("to", then = double()),
22 | argument("duration", then = int()), // 幻觉持续时间
23 | argument("period", then = long()) // 幻觉刷新间隔
24 | ) { target, health, duration, period ->
25 | target.forEach { VolatileEntityMetadata.updateHealth(it, it, health.toFloat()) }
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/internal/ActionVulpecula.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.internal
2 |
3 | import top.lanscarlos.vulpecula.legacy.bacikal.BacikalParser
4 | import top.lanscarlos.vulpecula.legacy.bacikal.bacikal
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.internal
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-03-25 00:29
12 | */
13 | object ActionVulpecula {
14 |
15 | @BacikalParser(
16 | id = "vulpecula",
17 | aliases = ["vulpecula", "vul"]
18 | )
19 | fun parser() = bacikal {
20 | when (val next = this.nextToken()) {
21 | "dispatcher" -> ActionVulpeculaDispatcher.resolve(this)
22 | "schedule" -> ActionVulpeculaSchedule.resolve(this)
23 | "script" -> ActionVulpeculaScript.resolve(this)
24 | else -> error("Unknown sub action \"$next\" at vulpecula action.")
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/inventory/ActionInventoryCheck.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.inventory
2 |
3 | import top.lanscarlos.vulpecula.legacy.api.chemdah.InferItem.Companion.toInferItem
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.inventory
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-26 14:40
11 | */
12 | object ActionInventoryCheck : ActionInventory.Resolver {
13 |
14 | override val name: Array = arrayOf("check")
15 |
16 | override fun resolve(reader: ActionInventory.Reader): ActionInventory.Handler {
17 | return reader.handle {
18 | combine(
19 | source(),
20 | text("pattern"),
21 | argument("amount", "amt", then = int(display = "amount"), def = 1)
22 | ) { inventory, pattern, amount ->
23 | pattern.toInferItem().check(inventory, amount)
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/inventory/ActionInventoryCount.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.inventory
2 |
3 | import top.lanscarlos.vulpecula.legacy.api.chemdah.InferItem.Companion.toInferItem
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.inventory
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-26 14:40
11 | */
12 | object ActionInventoryCount : ActionInventory.Resolver {
13 |
14 | override val name: Array = arrayOf("count")
15 |
16 | override fun resolve(reader: ActionInventory.Reader): ActionInventory.Handler {
17 | return reader.handle {
18 | combine(
19 | source(),
20 | text("pattern"),
21 | ) { inventory, pattern ->
22 | pattern.toInferItem().count(inventory)
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/inventory/ActionInventoryFind.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.inventory
2 |
3 | import top.lanscarlos.vulpecula.legacy.api.chemdah.InferItem.Companion.toInferItem
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.inventory
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-04-12 09:13
11 | */
12 | object ActionInventoryFind : ActionInventory.Resolver {
13 |
14 | override val name: Array = arrayOf("find")
15 |
16 | override fun resolve(reader: ActionInventory.Reader): ActionInventory.Handler {
17 | return reader.handle {
18 | combine(
19 | source(),
20 | text("pattern"),
21 | ) { inventory, pattern ->
22 | val infer = pattern.toInferItem()
23 | for ((index, item) in inventory.withIndex()) {
24 | if (infer.match(item)) return@combine index
25 | }
26 | return@combine -1
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/inventory/ActionInventoryTake.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.inventory
2 |
3 | import top.lanscarlos.vulpecula.legacy.api.chemdah.InferItem.Companion.toInferItem
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.inventory
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-26 14:40
11 | */
12 | object ActionInventoryTake : ActionInventory.Resolver {
13 |
14 | override val name: Array = arrayOf("take")
15 |
16 | override fun resolve(reader: ActionInventory.Reader): ActionInventory.Handler {
17 | return reader.handle {
18 | combine(
19 | source(),
20 | text("pattern"),
21 | argument("amount", "amt", then = int(display = "amount"), def = 1)
22 | ) { inventory, pattern, amount ->
23 | val infer = pattern.toInferItem()
24 | if (!infer.check(inventory, amount)) {
25 | return@combine false
26 | }
27 | infer.take(inventory, amount)
28 | updateInventory()
29 | return@combine true
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/item/ActionItemConsume.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.item
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.item
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-24 16:16
9 | */
10 | object ActionItemConsume : ActionItem.Resolver {
11 |
12 | override val name: Array = arrayOf("consume")
13 |
14 | override fun resolve(reader: ActionItem.Reader): ActionItem.Handler {
15 | return reader.transfer {
16 | combine(
17 | source(),
18 | optional("with", "to", then = int(display = "amount"), def = 1)
19 | ) { item, amount ->
20 | item.amount = (item.amount - amount).coerceIn(0, item.type.maxStackSize)
21 | item
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/item/ActionItemDestroy.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.item
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.item
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-24 16:23
9 | */
10 | object ActionItemDestroy : ActionItem.Resolver {
11 |
12 | override val name: Array = arrayOf("destroy")
13 |
14 | override fun resolve(reader: ActionItem.Reader): ActionItem.Handler {
15 | return reader.transfer {
16 | combine(
17 | source()
18 | ) { item ->
19 | item.also { it.amount = 0 }
20 | }
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/item/ActionItemDrop.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.item
2 |
3 | import taboolib.platform.util.toBukkitLocation
4 | import top.lanscarlos.vulpecula.legacy.utils.playerOrNull
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.item
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-03-24 16:25
12 | */
13 | object ActionItemDrop : ActionItem.Resolver {
14 |
15 | override val name: Array = arrayOf("drop")
16 |
17 | override fun resolve(reader: ActionItem.Reader): ActionItem.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | optional("at", "to", then = location(display = "drop location"))
22 | ) { item, location ->
23 |
24 | val loc = location?.toBukkitLocation() ?: this.playerOrNull()?.location?.toBukkitLocation()
25 | ?: error("No drop location selected.")
26 |
27 | loc.world?.dropItem(loc, item)
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/item/ActionItemGive.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.item
2 |
3 | import taboolib.platform.util.giveItem
4 | import top.lanscarlos.vulpecula.legacy.utils.playerOrNull
5 | import top.lanscarlos.vulpecula.legacy.utils.toBukkit
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.bacikal.action.item
10 | *
11 | * @author Lanscarlos
12 | * @since 2023-03-27 23:11
13 | */
14 | object ActionItemGive : ActionItem.Resolver {
15 |
16 | override val name: Array = arrayOf("give")
17 |
18 | override fun resolve(reader: ActionItem.Reader): ActionItem.Handler {
19 | return reader.transfer {
20 | combine(
21 | source(),
22 | optional("to", then = player()),
23 | optional("with", "repeat", then = int(), def = 1)
24 | ) { item, player, repeat ->
25 | val target = player ?: this.playerOrNull()?.toBukkit() ?: error("No player selected.")
26 | target.giveItem(item, repeat)
27 | item
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/item/ActionItemMatch.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.item
2 |
3 | import top.lanscarlos.vulpecula.legacy.api.chemdah.InferItem.Companion.toInferItem
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.item
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-04-04 22:45
11 | */
12 | object ActionItemMatch : ActionItem.Resolver {
13 |
14 | override val name: Array = arrayOf("match")
15 |
16 | /**
17 | * item match &item by &pattern
18 | * */
19 | override fun resolve(reader: ActionItem.Reader): ActionItem.Handler {
20 | return reader.handle {
21 | combine(
22 | source(),
23 | text(display = "pattern")
24 | ) { item, pattern ->
25 | pattern.toInferItem().match(item)
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/location/ActionLocationBuild.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.location
2 |
3 | import taboolib.common.util.Location
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.location
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-20 21:25
11 | */
12 | object ActionLocationBuild : ActionLocation.Resolver {
13 |
14 | override val name: Array = arrayOf("build", "create")
15 |
16 | /**
17 | * loc build &world &x &y &z
18 | * loc build &world &x &y &z and &yaw &pitch
19 | * */
20 | override fun resolve(reader: ActionLocation.Reader): ActionLocation.Handler {
21 | return reader.transfer {
22 | combine(
23 | text(),
24 | double(),
25 | double(),
26 | double(),
27 | optional("and", then = float().union(float()))
28 | ) { world, x, y, z, addition ->
29 | Location(world, x, y, z, addition?.first ?: 0f, addition?.second ?: 0f)
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/location/ActionLocationClone.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.location
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.location
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-20 21:22
9 | */
10 | object ActionLocationClone : ActionLocation.Resolver {
11 |
12 | override val name: Array = arrayOf("clone")
13 |
14 | override fun resolve(reader: ActionLocation.Reader): ActionLocation.Handler {
15 | return reader.transfer {
16 | combine(
17 | source(),
18 | ) { location ->
19 | location.clone()
20 | }
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/location/ActionLocationDistance.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.location
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.location
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-21 15:06
9 | */
10 | object ActionLocationDistance : ActionLocation.Resolver {
11 |
12 | override val name: Array = arrayOf("distance", "dist")
13 |
14 | /**
15 | * loc distance &loc with/to &target
16 | * loc distance &loc with/to x,y,z
17 | * */
18 | override fun resolve(reader: ActionLocation.Reader): ActionLocation.Handler {
19 | return reader.handle {
20 | combine(
21 | reader.source(),
22 | trim("with", "to", then = location(display = "location target"))
23 | ) { location, target ->
24 | location.distance(target)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/location/ActionLocationDistanceSquared.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.location
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.location
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-21 15:10
9 | */
10 | object ActionLocationDistanceSquared : ActionLocation.Resolver {
11 |
12 | override val name: Array = arrayOf("distance2", "dist2")
13 |
14 | /**
15 | * loc distance &loc with/to &target
16 | * loc distance &loc with/to x,y,z
17 | * */
18 | override fun resolve(reader: ActionLocation.Reader): ActionLocation.Handler {
19 | return reader.handle {
20 | combine(
21 | reader.source(),
22 | trim("with", "to", then = location(display = "location target"))
23 | ) { location, target ->
24 | location.distanceSquared(target)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/target/selector/ActionTargetSelectPlayer.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.target.selector
2 |
3 | import org.bukkit.Bukkit
4 | import top.lanscarlos.vulpecula.legacy.bacikal.action.target.ActionTarget
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.target.selector
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-03-22 21:46
12 | */
13 | object ActionTargetSelectPlayer : ActionTarget.Resolver {
14 |
15 | override val name: Array = arrayOf("Player")
16 |
17 | override fun resolve(reader: ActionTarget.Reader): ActionTarget.Handler {
18 | return reader.transfer {
19 | combine(
20 | source(),
21 | text(display = "player name")
22 | ) { target, name ->
23 | val offline = Bukkit.getOfflinePlayers().firstOrNull { it.name == name }
24 | if (offline != null) {
25 | target += offline.player ?: offline
26 | }
27 | target
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/target/selector/ActionTargetSelectSelf.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.target.selector
2 |
3 | import taboolib.module.kether.script
4 | import taboolib.platform.type.BukkitPlayer
5 | import top.lanscarlos.vulpecula.legacy.bacikal.action.target.ActionTarget
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.bacikal.action.target.selector
10 | *
11 | * @author Lanscarlos
12 | * @since 2023-03-22 21:41
13 | */
14 | object ActionTargetSelectSelf : ActionTarget.Resolver {
15 |
16 | override val name: Array = arrayOf("Self")
17 |
18 | override fun resolve(reader: ActionTarget.Reader): ActionTarget.Handler {
19 | return reader.transfer {
20 | combine(
21 | source()
22 | ) { target ->
23 |
24 | // 加入自身
25 | when (val it = this.script().sender) {
26 | is BukkitPlayer -> target += it.player
27 | else -> {
28 | if (it != null) target += it
29 | }
30 | }
31 |
32 | target
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/target/selector/ActionTargetSelectServer.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.target.selector
2 |
3 | import org.bukkit.Bukkit
4 | import top.lanscarlos.vulpecula.legacy.bacikal.action.target.ActionTarget
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.action.target.selector
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-03-23 09:08
12 | */
13 | object ActionTargetSelectServer : ActionTarget.Resolver {
14 |
15 | override val name: Array = arrayOf("PlayerOnServer", "PlayersOnServer", "Server")
16 |
17 | override fun resolve(reader: ActionTarget.Reader): ActionTarget.Handler {
18 | return reader.transfer {
19 | combine(
20 | source()
21 | ) { target ->
22 | target.add(Bukkit.getOnlinePlayers())
23 | target
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorAngle.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 14:58
9 | */
10 | object ActionVectorAngle : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("angle")
13 |
14 | /**
15 | * vec angle &vec with/by &target
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | trim("with", "by", then = vector(display = "vector target"))
22 | ) { vector, target ->
23 | vector.angle(target)
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorBuild.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | import taboolib.common.util.Vector
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.vector
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-22 14:52
11 | */
12 | object ActionVectorBuild : ActionVector.Resolver {
13 |
14 | override val name: Array = arrayOf("build", "create")
15 |
16 | /**
17 | * vec build &x &y &z
18 | * */
19 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
20 | return reader.transfer {
21 | combine(
22 | double(),
23 | double(),
24 | double()
25 | ) { x, y, z ->
26 | Vector(x, y, z)
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorClone.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:01
9 | */
10 | object ActionVectorClone : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("clone")
13 |
14 | /**
15 | * vec clone &vec
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source()
21 | ) { vector ->
22 | vector.clone()
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorDistance.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:21
9 | */
10 | object ActionVectorDistance : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("distance", "dist")
13 |
14 | /**
15 | * vec distance &vec with/by &target
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | trim("with", "by", then = vector(display = "vector target"))
22 | ) { vector, target ->
23 | vector.distance(target)
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorDistanceSquared.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:23
9 | */
10 | object ActionVectorDistanceSquared : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("distance2", "dist2")
13 |
14 | /**
15 | * vec distance2 &vec with/by &target
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | trim("with", "by", then = vector(display = "vector target"))
22 | ) { vector, target ->
23 | vector.distanceSquared(target)
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorDot.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:24
9 | */
10 | object ActionVectorDot : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("dot")
13 |
14 | /**
15 | * vec dot &vec with/by &target
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | trim("with", "by", then = vector(display = "vector target"))
22 | ) { vector, target ->
23 | vector.dot(target)
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorLength.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:26
9 | */
10 | object ActionVectorLength : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("length", "size")
13 |
14 | /**
15 | * vec length &vec
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | ) { vector ->
22 | vector.length()
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorLengthSquared.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:26
9 | */
10 | object ActionVectorLengthSquared : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("length2", "size2")
13 |
14 | /**
15 | * vec length2 &vec
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.handle {
19 | combine(
20 | source(),
21 | ) { vector ->
22 | vector.lengthSquared()
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorNormalize.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:48
9 | */
10 | object ActionVectorNormalize : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("normalize", "normal")
13 |
14 | /**
15 | * vec normal &vec
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source()
21 | ) { vector ->
22 | vector.normalize()
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRandom.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | import taboolib.common.util.Vector
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.vector
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-22 15:50
11 | */
12 | object ActionVectorRandom : ActionVector.Resolver {
13 |
14 | override val name: Array = arrayOf("random")
15 |
16 | /**
17 | * vec random
18 | * */
19 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
20 | return reader.transfer {
21 | discrete {
22 | Vector.getRandom()
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRotateAxis.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:54
9 | */
10 | object ActionVectorRotateAxis : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("rotate-axis", "rotate-a")
13 |
14 | /**
15 | * vec rotate-axis &vec with/by &angle
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source(),
21 | trim("with", "by", then = vector(display = "vector axis")),
22 | double(0.0)
23 | ) { vector, axis, angle ->
24 | if (angle == 0.0) return@combine vector
25 | vector.rotateAroundAxis(axis, angle)
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRotateAxisNonUnit.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:54
9 | */
10 | object ActionVectorRotateAxisNonUnit : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("rotate-axis-non-unit", "rotate-a-n")
13 |
14 | /**
15 | * vec rotate-axis-non-unit &vec with/by &angle
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source(),
21 | trim("with", "by", then = vector(display = "vector axis")),
22 | double(0.0)
23 | ) { vector, axis, angle ->
24 | if (angle == 0.0) return@combine vector
25 | vector.rotateAroundNonUnitAxis(axis, angle)
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRotateEuler.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | import taboolib.module.effect.utils.VectorUtils
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.action.vector
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-03-22 15:54
11 | */
12 | object ActionVectorRotateEuler : ActionVector.Resolver {
13 |
14 | override val name: Array = arrayOf("rotate-euler", "rotate-e")
15 |
16 | /**
17 | * vec rotate-euler &vec with/by &yaw &pitch
18 | * */
19 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
20 | return reader.transfer {
21 | combine(
22 | source(),
23 | trim("with", "by", then = float(0f)),
24 | float(0f)
25 | ) { vector, yaw, pitch ->
26 | if (yaw == 0f && pitch == 0f) return@combine vector
27 | VectorUtils.rotateVector(vector, yaw, pitch)
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRotateX.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:54
9 | */
10 | object ActionVectorRotateX : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("rotate-x")
13 |
14 | /**
15 | * vec rotate-x &vec with/by &angle
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source(),
21 | trim("with", "by", then = double(0.0))
22 | ) { vector, angle ->
23 | if (angle == 0.0) return@combine vector
24 | vector.rotateAroundX(angle)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRotateY.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:54
9 | */
10 | object ActionVectorRotateY : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("rotate-y")
13 |
14 | /**
15 | * vec rotate-y &vec with/by &angle
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source(),
21 | trim("with", "by", then = double(0.0))
22 | ) { vector, angle ->
23 | if (angle == 0.0) return@combine vector
24 | vector.rotateAroundY(angle)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/action/vector/ActionVectorRotateZ.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.action.vector
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.action.vector
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-03-22 15:54
9 | */
10 | object ActionVectorRotateZ : ActionVector.Resolver {
11 |
12 | override val name: Array = arrayOf("rotate-z")
13 |
14 | /**
15 | * vec rotate-z &vec with/by &angle
16 | * */
17 | override fun resolve(reader: ActionVector.Reader): ActionVector.Handler {
18 | return reader.transfer {
19 | combine(
20 | source(),
21 | trim("with", "by", then = double(0.0))
22 | ) { vector, angle ->
23 | if (angle == 0.0) return@combine vector
24 | vector.rotateAroundZ(angle)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/property/WorldProperty.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.property
2 |
3 | import org.bukkit.World
4 | import taboolib.common.OpenResult
5 | import top.lanscarlos.vulpecula.legacy.bacikal.BacikalProperty
6 | import top.lanscarlos.vulpecula.legacy.bacikal.BacikalGenericProperty
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.bacikal.property
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-03-22 14:03
14 | */
15 | @BacikalProperty(
16 | id = "world",
17 | bind = World::class
18 | )
19 | class WorldProperty : BacikalGenericProperty("world") {
20 | override fun readProperty(instance: World, key: String): OpenResult {
21 | val property: Any? = when (key) {
22 | "name" -> instance.name
23 | else -> return OpenResult.failed()
24 | }
25 | return OpenResult.successful(property)
26 | }
27 |
28 | override fun writeProperty(instance: World, key: String, value: Any?): OpenResult {
29 | return OpenResult.failed()
30 | }
31 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/script/FragmentReplacer.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.script
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.script
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-05-09 12:38
9 | */
10 | class FragmentReplacer : ScriptTransfer {
11 |
12 | /**
13 | * 碎片
14 | * */
15 | val fragments = mutableMapOf()
16 |
17 | /**
18 | * 是否启用全局碎片替换
19 | * */
20 | var enableGlobalFragmentReplace = true
21 |
22 | /**
23 | * 替换碎片
24 | * */
25 | override fun transfer(source: StringBuilder) {}
26 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/script/ScriptTransfer.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.script
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.script
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-05-09 12:45
9 | */
10 | interface ScriptTransfer {
11 |
12 | /**
13 | * 转换脚本
14 | * */
15 | fun transfer(source: StringBuilder)
16 |
17 | /**
18 | * 抽取所有字符并清空容器
19 | * */
20 | fun StringBuilder.extract(): String {
21 | val result = toString()
22 | clear()
23 | return result
24 | }
25 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/bacikal/script/UnicodeEscalator.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.bacikal.script
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.script
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-05-09 12:41
9 | */
10 | class UnicodeEscalator : ScriptTransfer {
11 |
12 | /**
13 | * Unicode 转义
14 | * */
15 | override fun transfer(source: StringBuilder) {
16 | val regex = "\\\\u([A-Za-z0-9]{4})".toRegex()
17 | val result = regex.replace(source.extract()) {
18 | Integer.parseInt(it.groupValues[1], 16).toChar().toString()
19 | }
20 | source.append(result)
21 | }
22 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/config/DynamicConfigNode.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.config
2 |
3 | import kotlin.reflect.KProperty
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.config
8 | *
9 | * @author Lanscarlos
10 | * @since 2022-12-15 18:22
11 | */
12 | interface DynamicConfigNode {
13 | operator fun getValue(any: Any?, property: KProperty<*>): R
14 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/config/DynamicConfigNodeBinding.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.config
2 |
3 | import taboolib.library.configuration.ConfigurationSection
4 | import taboolib.module.configuration.ConfigLoader
5 | import kotlin.reflect.KProperty
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.config
10 | *
11 | * @author Lanscarlos
12 | * @since 2022-12-15 22:05
13 | */
14 | @Suppress("UNCHECKED_CAST")
15 | class DynamicConfigNodeBinding(
16 | val path: String,
17 | bind: String,
18 | private val transfer: ConfigurationSection.(Any?) -> R
19 | ) : DynamicConfigNode, Runnable {
20 |
21 | var isInitialized = false
22 | var value: R? = null
23 |
24 | val config by lazy {
25 | ConfigLoader.files[bind]?.configuration?.also {
26 | it.onReload(this)
27 | } ?: error("config \"$bind\" not defined.")
28 | }
29 |
30 | override fun run() {
31 | value = transfer(config, config[path])
32 | }
33 |
34 | override fun getValue(any: Any?, property: KProperty<*>): R {
35 | if (!isInitialized) {
36 | value = transfer(config, config[path])
37 | isInitialized = true
38 | }
39 | return value as R
40 | }
41 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/modularity/Module.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.modularity
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.modularity
6 | *
7 | * 模块化
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-08 14:45
11 | */
12 | interface Module {
13 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/utils/MessageUtil.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.utils
2 |
3 | import org.bukkit.command.CommandSender
4 | import org.bukkit.entity.Player
5 | import taboolib.common.platform.function.adaptCommandSender
6 | import taboolib.common.platform.function.console
7 | import taboolib.module.lang.sendLang
8 |
9 | /**
10 | * Vulpecula
11 | * top.lanscarlos.vulpecula.utils
12 | *
13 | * @author Lanscarlos
14 | * @since 2023-02-06 18:05
15 | */
16 |
17 | /**
18 | * 同步控制台发送信息
19 | * 若发送者是玩家,则同时向控制台发送
20 | * */
21 | fun CommandSender.sendSyncLang(node: String, vararg args: Any) {
22 | adaptCommandSender(this).sendLang(node, *args)
23 | if (this is Player) console().sendLang(node, *args)
24 | }
25 |
26 | /**
27 | * 发送静默消息
28 | * 仅发送于控制台
29 | * */
30 | fun CommandSender.sendSyncLang(silent: Boolean, node: String, vararg args: Any) {
31 | if (silent) {
32 | console().sendLang(node, *args)
33 | } else {
34 | sendSyncLang(node, *args)
35 | }
36 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/kotlin/top/lanscarlos/vulpecula/legacy/utils/TimingUtil.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.legacy.utils
2 |
3 | import taboolib.common5.Coerce
4 |
5 | fun timing(): Long {
6 | return System.nanoTime()
7 | }
8 |
9 | fun timing(start: Long): Double {
10 | return Coerce.format((System.nanoTime() - start).div(1000000.0))
11 | }
--------------------------------------------------------------------------------
/project/common-legacy/src/main/resources/actions/property-registry.yml:
--------------------------------------------------------------------------------
1 |
2 | # 请注意
3 | # 改动此文件后需要重启才能加载
4 |
5 | entity-generic:
6 | # 是否为公有属性
7 | shared: true
8 |
9 | event-generic:
10 | shared: true
11 |
12 | location-generic:
13 | shared: true
--------------------------------------------------------------------------------
/project/common-legacy/src/main/resources/actions/unicode/#blank.yml:
--------------------------------------------------------------------------------
1 |
2 | # 负空格
3 |
4 | '-1': '-1'
5 | '-2': '-2'
6 | '-3': '-3'
7 | '-4': '-4'
8 | '-5': '-5'
9 | '-6': '-6'
10 | '-7': '-7'
11 | '-8': '-8'
12 | '-16': '-16'
13 | '-32': '-32'
14 | '-64': '-64'
15 | '-128': '-128'
16 |
17 | # 正空格
18 |
19 | '+1': '+1'
20 | '+2': '+2'
21 | '+3': '+3'
22 | '+4': '+4'
23 | '+5': '+5'
24 | '+6': '+6'
25 | '+7': '+7'
26 | '+8': '+8'
27 | '+16': '+16'
28 | '+32': '+32'
29 | '+64': '+64'
30 | '+128': '+128'
--------------------------------------------------------------------------------
/project/common-legacy/src/main/resources/actions/unicode/#def.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | cloud: '\u2601'
4 | star: '\u2605'
--------------------------------------------------------------------------------
/project/common-legacy/src/main/resources/config.yml:
--------------------------------------------------------------------------------
1 |
2 | # 配置文件的自动重置设置
3 | # 部分模块的自动加载可能会存在小概率失灵情况
4 | # 用户可根据实际情况自行选择启用与否
5 | # 修改此节点可能需要重新启动服务器才能完全生效
6 | automatic-reload:
7 | custom-command: false
8 | dispatcher: false
9 | handler: false
10 | listen-mapping: false
11 | schedule: false
12 | script-source: false
13 | script-compiled: false
14 |
15 | action-unicode: false
16 |
17 | script-setting:
18 | # 注释匹配规则
19 | comment-pattern:
20 | # 单行注释
21 | # 匹配 // 及其后所有字符直至换行
22 | single-line: '(? 事件全类名
4 |
5 |
6 | # 实体受伤事件
7 | entity-damage: 'org.bukkit.event.entity.EntityDamageEvent'
8 |
9 | # 实体受其他实体攻击事件
10 | entity-damage-by-entity: 'org.bukkit.event.entity.EntityDamageByEventEvent'
11 |
12 | # 实体死亡事件
13 | entity-death: 'org.bukkit.event.entity.EntityDeathEvent'
14 |
15 | # 玩家执行命令事件
16 | player-command: 'org.bukkit.event.player.PlayerCommandPreprocessEvent'
17 |
18 | # 玩家交互事件
19 | player-interact: 'org.bukkit.event.player.PlayerInteractEvent'
20 |
21 | # 玩家破坏方块事件
22 | player-break: 'org.bukkit.event.block.BlockBreakEvent'
23 |
24 | # 实体射箭事件
25 | entity-shoot: 'org.bukkit.event.entity.EntityShootBowEvent'
--------------------------------------------------------------------------------
/project/common-legacy/src/main/resources/schedules/#def.yml:
--------------------------------------------------------------------------------
1 |
2 | # 示例日程计划
3 | daily-message:
4 | disable: true
5 | start: '2022-12-15 13:40:00'
6 | end: '2022-12-15 22:55:00'
7 | period: '1h30m10s'
8 | execute: |-
9 | print running...
--------------------------------------------------------------------------------
/project/common-legacy/src/main/resources/scripts/#def.yml:
--------------------------------------------------------------------------------
1 | # 编译构建设置
2 | build-setting:
3 | # 指定编译结果的文件路径
4 | # 默认情况下以 .compile/ 为根路径
5 | # 若路径以 / 开头,则默认以服务器所在路径为根路径
6 | # target-path: './output'
7 |
8 | # 编译时,若目标文件存在是否将其覆盖
9 | # 默认为 true
10 | target-override: true
11 |
12 | # 当文件发生变化时是否自动编译
13 | # 默认为 true
14 | auto-compile: true
15 |
16 | # 是否转义 unicode
17 | # 默认为 false
18 | escape-unicode: true
19 |
20 | # 导入命名空间
21 | namespace:
22 | - chemdah
23 |
24 | # 主语句
25 | main: |-
26 | pring "Running Example Script."
27 | print func color-tips with [ "&d新年快乐!" ]
28 | print "今天翻的是书,${next}"
29 | print &example-tips
30 |
31 | # 前置变量
32 | variables:
33 | example-tips: |-
34 | color "&f[温馨小贴士&f] $tips"
35 |
36 | # 条件
37 | # 当条件满足时,执行 main 里面的语句
38 | # 否则执行 deny 里面的语句
39 | condition: |-
40 | check 5 > 3
41 |
42 | deny: |-
43 | print "条件不通过,5 怎么可能大于 3 呢?"
44 |
45 | # 异常处理
46 | # 当 main 内的语句运行时发生异常则执行下面的语句
47 | exception: |-
48 | print "检测到报错,是什么问题?"
49 |
50 | # 自定义函数
51 | functions:
52 | color-tips:
53 | # 定义参数名
54 | args: [ 'input' ]
55 | # 函数体
56 | content: |-
57 | color &input
58 |
59 | # 自定义片段
60 | # 可使用 $id 或 ${id} 来替换脚本内的片段
61 | # 注意,请勿在片段内使用 $id 或 ${id} 套娃
62 | fragments:
63 | next: '明天数的是钱!'
64 | tips: '丈母娘喜欢有学历的女婿'
--------------------------------------------------------------------------------
/project/common/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly("ink.ptms.core:v12004:12004:mapped")
8 | compileOnly("ink.ptms.core:v12004:12004:universal")
9 | }
--------------------------------------------------------------------------------
/project/common/src/main/kotlin/top/lanscarlos/vulpecula/VulpeculaAPI.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-08-21 21:38
9 | */
10 | interface VulpeculaAPI {
11 | }
--------------------------------------------------------------------------------
/project/common/src/main/kotlin/top/lanscarlos/vulpecula/utils/TimingUtil.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.utils
2 |
3 | import taboolib.common5.Coerce
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.utils
8 | *
9 | * @author Lanscarlos
10 | * @since 2024-05-15 10:06
11 | */
12 |
13 | /**
14 | * 开始计时
15 | * */
16 | fun timing(): Long {
17 | return System.nanoTime()
18 | }
19 |
20 | /**
21 | * 结束计时
22 | *
23 | * @return 毫秒数
24 | * */
25 | fun timing(start: Long): Double {
26 | return Coerce.format((System.nanoTime() - start).div(1000000.0))
27 | }
--------------------------------------------------------------------------------
/project/extension-anser/build.gradle.kts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lanscarlos/Vulpecula/5b0607820ade0d6399a7d43efcd8003e9babda7b/project/extension-anser/build.gradle.kts
--------------------------------------------------------------------------------
/project/module-applicative/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly("ink.ptms.core:v12004:12004:mapped")
8 | }
--------------------------------------------------------------------------------
/project/module-applicative/src/main/kotlin/top/lanscarlos/vulpecula/applicative/Applicative.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.applicative
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.applicative
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-08-21 13:55
9 | */
10 | interface Applicative {
11 |
12 | /**
13 | * 转换为目标类型
14 | * */
15 | fun apply(instance: Any): T?
16 |
17 | /**
18 | * 转换为目标类型, 如果转换失败则返回默认值
19 | *
20 | * @param def 默认值
21 | * */
22 | fun apply(instance: Any, def: T): T
23 |
24 | /**
25 | * 接收实例并转换为对应的 LiveData
26 | * */
27 | fun accept(instance: Any): LiveData
28 |
29 | /**
30 | * 获取属性
31 | *
32 | * @param key 属性名, 递归获取属性使用 . 分隔
33 | * @param strict 严格模式, 递归过程遇到中间属性为空或不存在时抛出异常
34 | * @throws IllegalStateException 如果属性不存在或者严格模式下遇到中间属性为空或不存在
35 | * */
36 | fun getProperty(instance: T, key: String, strict: Boolean = false): Any?
37 |
38 | /**
39 | * 设置属性
40 | *
41 | * @param key 属性名, 递归获取属性使用 . 分隔
42 | * @param value 属性值
43 | * @param strict 严格模式, 递归过程遇到中间属性为空或不存在时抛出异常
44 | * @throws IllegalStateException 如果属性不存在或者严格模式下遇到中间属性为空或不存在
45 | * */
46 | fun setProperty(instance: T, key: String, value: Any?, strict: Boolean = false)
47 |
48 | }
--------------------------------------------------------------------------------
/project/module-applicative/src/main/kotlin/top/lanscarlos/vulpecula/applicative/DefaultLiveData.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.applicative
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.applicative
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-05-15 17:25
9 | */
10 | class DefaultLiveData(val source: Any, val applicative: Applicative) : LiveData {
11 |
12 | /**
13 | * 缓存值
14 | * */
15 | private var value: T? = null
16 |
17 | /**
18 | * 是否已初始化
19 | * */
20 | private var isInitialized = false
21 |
22 | override fun getValue(): T? {
23 | if (!isInitialized) {
24 | value = applicative.apply(source)
25 | }
26 | return value
27 | }
28 |
29 | override fun getValue(def: T): T {
30 | if (!isInitialized) {
31 | value = applicative.apply(source, def)
32 | }
33 | return value ?: def
34 | }
35 |
36 | override fun get(key: String): Any? {
37 | val instance = getValue() ?: return null
38 | return applicative.getProperty(instance, key)
39 | }
40 |
41 | override fun set(key: String, value: Any?) {
42 | val instance = getValue() ?: return
43 | applicative.setProperty(instance, key, value)
44 | }
45 | }
--------------------------------------------------------------------------------
/project/module-applicative/src/main/kotlin/top/lanscarlos/vulpecula/applicative/EntityApplicative.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.applicative
2 |
3 | import org.bukkit.Bukkit
4 | import org.bukkit.OfflinePlayer
5 | import org.bukkit.entity.Entity
6 | import taboolib.common.platform.ProxyPlayer
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.applicative
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-08-21 15:10
14 | */
15 | object EntityApplicative : AbstractApplicative() {
16 |
17 | override fun transfer(instance: Any, def: Entity?): Entity? {
18 | return when (instance) {
19 | is Entity -> instance
20 | is OfflinePlayer -> instance.player
21 | is ProxyPlayer -> instance.castSafely()
22 | is String -> Bukkit.getPlayerExact(instance)
23 | else -> def
24 | }
25 | }
26 |
27 | override fun readProperty(instance: Entity, key: String): Any? {
28 | failedByGetPropertyNotSupported(instance, key)
29 | }
30 |
31 | override fun writeProperty(instance: Entity, key: String, value: Any?) {
32 | failedBySetPropertyNotSupported(instance, key)
33 | }
34 | }
--------------------------------------------------------------------------------
/project/module-applicative/src/main/kotlin/top/lanscarlos/vulpecula/applicative/LiveData.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.applicative
2 |
3 | import kotlin.reflect.KProperty
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.applicative
8 | *
9 | * @author Lanscarlos
10 | * @since 2024-05-15 17:30
11 | */
12 | interface LiveData {
13 |
14 | /**
15 | * 取值
16 | * */
17 | fun getValue(): T?
18 |
19 | /**
20 | * 取值,如果为 null,返回默认值
21 | * @param def 默认值
22 | * */
23 | fun getValue(def: T): T
24 |
25 | /**
26 | * 兼容代理属性
27 | * */
28 | operator fun getValue(parent: Any?, property: KProperty<*>): T? {
29 | return getValue()
30 | }
31 |
32 | /**
33 | * 读取属性
34 | *
35 | * @param key 属性名, 递归获取属性使用 . 分隔
36 | * @throws IllegalStateException 如果属性不存在
37 | * */
38 | operator fun get(key: String): Any?
39 |
40 | /**
41 | * 设置属性
42 | * */
43 | operator fun set(key: String, value: Any?)
44 |
45 | }
--------------------------------------------------------------------------------
/project/module-bacikal/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | taboolib {
3 | subproject = true
4 | }
5 |
6 | dependencies {
7 | compileOnly(project(":project:common"))
8 | compileOnly(project(":project:module-applicative"))
9 | compileOnly(project(":project:module-config"))
10 |
11 | compileOnly("ink.ptms.core:v12004:12004:mapped")
12 | compileOnly("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") // 协程
13 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/BacikalError.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal
2 |
3 | import taboolib.library.kether.LocalizedException
4 | import java.util.*
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal
9 | *
10 | * @author Lanscarlos
11 | * @since 2024-03-23 13:22
12 | */
13 | enum class BacikalError {
14 |
15 | SYMBOL_NOT_OPENED, // 符号未打开
16 | SYMBOL_NOT_CLOSED, // 符号未闭合
17 | UNKNOWN_ACTION; // 未知语句
18 |
19 | fun create(vararg args: Any?): LocalizedException {
20 | return LocalizedException.of("bacikal-error." + name.lowercase(Locale.getDefault()).replace("_", "-"), *args)
21 | }
22 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/BacikalScript.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal
2 |
3 | import top.lanscarlos.vulpecula.bacikal.quest.BacikalQuest
4 | import java.io.File
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-09-03 21:35
12 | */
13 | interface BacikalScript : BacikalQuest {
14 |
15 | /**
16 | * 脚本文件
17 | * */
18 | val file: File
19 |
20 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/BacikalService.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal
2 |
3 | import top.lanscarlos.vulpecula.bacikal.quest.*
4 | import java.util.concurrent.CompletableFuture
5 | import java.util.function.Consumer
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.bacikal
10 | *
11 | * @author Lanscarlos
12 | * @since 2023-08-20 21:30
13 | */
14 | interface BacikalService {
15 |
16 | /**
17 | * 默认编译命名空间
18 | * */
19 | val defaultCompileNamespace: List
20 |
21 | val questCompiler: BacikalQuestCompiler
22 |
23 | val questExecutor: BacikalQuestExecutor
24 |
25 | fun buildQuest(name: String, func: Consumer): BacikalQuest
26 |
27 | fun executeQuest(quest: BacikalQuest): CompletableFuture<*>
28 |
29 | fun terminateQuest(quest: BacikalQuest)
30 |
31 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/BacikalTest.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal
2 |
3 | import taboolib.common.LifeCycle
4 | import taboolib.common.platform.Awake
5 | import taboolib.common.platform.function.getDataFolder
6 | import taboolib.common.platform.function.info
7 | import java.io.File
8 |
9 | /**
10 | * Vulpecula
11 | * top.lanscarlos.vulpecula.bacikal
12 | *
13 | * @author Lanscarlos
14 | * @since 2024-05-14 02:29
15 | */
16 | object BacikalTest {
17 |
18 | @Awake(LifeCycle.ENABLE)
19 | fun onTest() {
20 | info("BacikalTest onTest...")
21 | BacikalRegistry.registerAction(File(getDataFolder(), "item-3.0.0.jar"))
22 | info("BacikalTest onTest... x2")
23 |
24 |
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/DefaultScript.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal
2 |
3 | import top.lanscarlos.vulpecula.bacikal.quest.DefaultQuest
4 | import top.lanscarlos.vulpecula.bacikal.quest.KetherQuest
5 | import java.io.File
6 | import java.nio.charset.StandardCharsets
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.bacikal
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-09-03 21:36
14 | */
15 | class DefaultScript(name: String, override val file: File) : BacikalScript, DefaultQuest(
16 | Bacikal.service.questCompiler.compile(name, file.readText(StandardCharsets.UTF_8))
17 | )
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/debugger/BacikalDebugger.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.debugger
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.debugger
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-12-27 13:28
9 | */
10 | class BacikalDebugger {
11 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/AbstractSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import taboolib.library.kether.ParsedAction
4 | import java.util.concurrent.CompletableFuture
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.seed
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-08-21 15:15
12 | */
13 | abstract class AbstractSeed : BacikalSeed {
14 |
15 | private lateinit var action: ParsedAction<*>
16 |
17 | override val isAccepted: Boolean
18 | get() = ::action.isInitialized
19 |
20 | override fun accept(reader: BacikalReader) {
21 | action = reader.readAction()
22 | }
23 |
24 | override fun accept(frame: BacikalFrame): CompletableFuture {
25 | return frame.runAction(action).thenApply {
26 | resolve(frame, it)
27 | }
28 | }
29 |
30 | abstract fun resolve(frame: BacikalFrame, value: Any?): T
31 |
32 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/AdditionalSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import java.util.concurrent.CompletableFuture
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.seed
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-21 17:59
11 | */
12 | class AdditionalSeed(val seed: BacikalSeed, val prefix: Array) : BacikalSeed {
13 |
14 | override val isAccepted: Boolean
15 | get() = seed.isAccepted
16 |
17 | /**
18 | * @return 若前缀匹配则返回 true
19 | * */
20 | fun accept(prefix: String, reader: BacikalReader): Boolean {
21 | if (isAccepted) {
22 | return false
23 | }
24 | if (prefix in this.prefix) {
25 | seed.accept(reader)
26 | return true
27 | }
28 | return false
29 | }
30 |
31 | override fun accept(reader: BacikalReader) {
32 | }
33 |
34 | override fun accept(frame: BacikalFrame): CompletableFuture {
35 | return if (seed.isAccepted) {
36 | seed.accept(frame)
37 | } else {
38 | CompletableFuture.completedFuture(null)
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/BacikalComplexActionParser.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import taboolib.library.kether.QuestAction
4 | import taboolib.library.kether.QuestActionParser
5 | import taboolib.library.kether.QuestReader
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.bacikal.parser
10 | *
11 | * @author Lanscarlos
12 | * @since 2024-05-13 17:02
13 | */
14 | abstract class BacikalComplexActionParser(val name: String) : QuestActionParser {
15 |
16 | val actions: Map = linkedMapOf()
17 |
18 | fun registerAction(id: String, parser: BacikalActionParser) {
19 | (actions as LinkedHashMap)[id] = parser
20 | }
21 |
22 | override fun resolve(reader: QuestReader): QuestAction {
23 | reader.mark()
24 | val next = reader.nextToken()
25 | val parser = actions[next] ?: actions["@DEFAULT"] ?: error("Unknown action '$next' at $name")
26 | return parser.resolve(reader)
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/BacikalFruit.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import taboolib.library.kether.QuestAction
4 | import taboolib.module.kether.ScriptFrame
5 | import java.util.concurrent.CompletableFuture
6 | import java.util.function.Function
7 |
8 | /**
9 | * Vulpecula
10 | * top.lanscarlos.vulpecula.bacikal.parser
11 | *
12 | * @author Lanscarlos
13 | * @since 2023-08-21 10:15
14 | */
15 | class BacikalFruit(private val func: Function>) : QuestAction() {
16 | override fun process(frame: ScriptFrame): CompletableFuture {
17 | return func.apply(DefaultFrame(frame))
18 | }
19 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/BacikalParser.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.parser
6 | *
7 | * @author Lanscarlos
8 | * @since 2023-08-25 00:59
9 | */
10 | annotation class BacikalParser(val id: String)
11 |
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/BacikalParserBody.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | /**
4 | * Vulpecula
5 | * top.lanscarlos.vulpecula.bacikal.parser
6 | *
7 | * @author Lanscarlos
8 | * @since 2024-05-14 23:39
9 | */
10 | annotation class BacikalParserBody(val id: String, val bind: String)
11 |
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/BacikalReader.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import taboolib.library.kether.ParsedAction
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-20 21:30
11 | */
12 | interface BacikalReader {
13 |
14 | val index: Int
15 |
16 | /**
17 | * 读取一个标记
18 | * */
19 | fun readToken(): String
20 |
21 | fun readAction(): ParsedAction<*>
22 |
23 | fun readActionList(): List>
24 |
25 | /**
26 | * 查看下一个标记,但不改变位置
27 | * */
28 | fun peekToken(): String
29 |
30 | /**
31 | * 读取下一个标记并判断是否符合预期,若不符合预期则抛出异常
32 | * */
33 | fun expectToken(vararg expect: String)
34 |
35 | /**
36 | * 读取一个标记并判断是否符合预期
37 | * 若不符合预期则重置位置
38 | * */
39 | fun hasToken(vararg expect: String): Boolean
40 |
41 | /**
42 | * 标记位置
43 | * */
44 | fun mark(): Int
45 |
46 | /**
47 | * 回滚到标记位置
48 | * */
49 | fun rollback(offset: Int = 1)
50 |
51 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/BacikalSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import java.util.concurrent.CompletableFuture
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.seed
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-21 10:14
11 | */
12 | interface BacikalSeed {
13 |
14 | /**
15 | * 是否已接收 BacikalReader 并完成解析
16 | * */
17 | val isAccepted: Boolean
18 |
19 | /**
20 | * 从 BacikalReader 中解析数据
21 | *
22 | * @return 若未接受则返回 null
23 | * */
24 | fun accept(reader: BacikalReader)
25 |
26 | fun accept(frame: BacikalFrame): CompletableFuture
27 |
28 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/DefaultSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import taboolib.library.kether.ParsedAction
4 | import java.util.concurrent.CompletableFuture
5 | import java.util.function.BiFunction
6 |
7 | /**
8 | * Vulpecula
9 | * top.lanscarlos.vulpecula.bacikal.seed
10 | *
11 | * @author Lanscarlos
12 | * @since 2023-08-21 15:15
13 | */
14 | class DefaultSeed(val transfer: BiFunction) : BacikalSeed {
15 |
16 | private lateinit var action: ParsedAction<*>
17 |
18 | override val isAccepted: Boolean
19 | get() = ::action.isInitialized
20 |
21 | override fun accept(reader: BacikalReader) {
22 | action = reader.readAction()
23 | }
24 |
25 | override fun accept(frame: BacikalFrame): CompletableFuture {
26 | return frame.runAction(action).thenApply {
27 | transfer.apply(frame, it)
28 | }
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/ExpectedSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import java.util.concurrent.CompletableFuture
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.seed
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-21 17:39
11 | */
12 | class ExpectedSeed(val seed: BacikalSeed, val expect: Array) : BacikalSeed {
13 |
14 | override val isAccepted: Boolean
15 | get() = seed.isAccepted
16 |
17 | override fun accept(reader: BacikalReader) {
18 | reader.expectToken(*expect)
19 | seed.accept(reader)
20 | }
21 |
22 | override fun accept(frame: BacikalFrame): CompletableFuture {
23 | return seed.accept(frame)
24 | }
25 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/NullableSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import java.util.concurrent.CompletableFuture
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.seed
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-21 18:03
11 | */
12 | class NullableSeed(val seed: BacikalSeed) : BacikalSeed {
13 |
14 | override val isAccepted: Boolean
15 | get() = seed.isAccepted
16 |
17 | override fun accept(reader: BacikalReader) {
18 | seed.accept(reader)
19 | }
20 |
21 | override fun accept(frame: BacikalFrame): CompletableFuture {
22 | return seed.accept(frame).thenApply { it }
23 | }
24 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/OptionalSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import java.util.concurrent.CompletableFuture
4 |
5 | /**
6 | * Vulpecula
7 | * top.lanscarlos.vulpecula.bacikal.seed
8 | *
9 | * @author Lanscarlos
10 | * @since 2023-08-21 17:43
11 | */
12 | class OptionalSeed(val seed: BacikalSeed, val expect: Array) : BacikalSeed {
13 |
14 | override val isAccepted: Boolean
15 | get() = seed.isAccepted
16 |
17 | override fun accept(reader: BacikalReader) {
18 | if (reader.hasToken(*expect)) {
19 | seed.accept(reader)
20 | }
21 | }
22 |
23 | override fun accept(frame: BacikalFrame): CompletableFuture {
24 | return if (isAccepted) {
25 | seed.accept(frame)
26 | } else {
27 | CompletableFuture.completedFuture(null)
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/PairSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import top.lanscarlos.vulpecula.bacikal.combineFuture
4 | import java.util.concurrent.CompletableFuture
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.seed
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-08-21 20:00
12 | */
13 | class PairSeed(val first: BacikalSeed, val second: BacikalSeed) : BacikalSeed> {
14 |
15 | override val isAccepted: Boolean
16 | get() = first.isAccepted && second.isAccepted
17 |
18 | override fun accept(reader: BacikalReader) {
19 | first.accept(reader)
20 | second.accept(reader)
21 | }
22 |
23 | override fun accept(frame: BacikalFrame): CompletableFuture> {
24 | return combineFuture(
25 | first.accept(frame),
26 | second.accept(frame)
27 | ).thenApply {
28 | it.t1 to it.t2
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/parser/TripleSeed.kt:
--------------------------------------------------------------------------------
1 | package top.lanscarlos.vulpecula.bacikal.parser
2 |
3 | import top.lanscarlos.vulpecula.bacikal.combineFuture
4 | import java.util.concurrent.CompletableFuture
5 |
6 | /**
7 | * Vulpecula
8 | * top.lanscarlos.vulpecula.bacikal.parser
9 | *
10 | * @author Lanscarlos
11 | * @since 2023-12-27 15:22
12 | */
13 | class TripleSeed(val first: BacikalSeed, val second: BacikalSeed, val third: BacikalSeed) : BacikalSeed> {
14 |
15 | override val isAccepted: Boolean
16 | get() = first.isAccepted && second.isAccepted && third.isAccepted
17 |
18 | override fun accept(reader: BacikalReader) {
19 | first.accept(reader)
20 | second.accept(reader)
21 | third.accept(reader)
22 | }
23 |
24 | override fun accept(frame: BacikalFrame): CompletableFuture