├── .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 | ![img](https://cdn.nlark.com/yuque/0/2022/png/26025412/1662111393286-4c9dd5ef-6472-4baa-8b11-d6b0f66aee94.png) 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 | |![Version](https://img.shields.io/badge/dynamic/json?label=Version&query=%24.tag_name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLanscarlos%2FVulpecula%2Freleases%2Flatest) | ![Date](https://img.shields.io/badge/dynamic/json?label=Date&query=%24.created_at&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLanscarlos%2FVulpecula%2Freleases%2Flatest) | ![Author](https://img.shields.io/badge/dynamic/json?label=Author&query=%24.author.login&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLanscarlos%2FVulpecula%2Freleases%2Flatest) | ![Code-Size](https://img.shields.io/github/languages/code-size/lanscarlos/vulpecula) | 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> { 25 | return combineFuture( 26 | first.accept(frame), 27 | second.accept(frame), 28 | third.accept(frame) 29 | ).thenApply { 30 | Triple(it.t1, it.t2, it.t3) 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/property/BacikalProperty.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.property 2 | 3 | import kotlin.reflect.KClass 4 | 5 | /** 6 | * Vulpecula 7 | * top.lanscarlos.vulpecula.bacikal.property 8 | * 9 | * @author Lanscarlos 10 | * @since 2023-08-25 00:59 11 | */ 12 | annotation class BacikalProperty(val id: String, val bind: KClass<*>) 13 | -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/BacikalBlockBuilder.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.bacikal.quest 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-25 01:04 9 | */ 10 | interface BacikalBlockBuilder { 11 | 12 | /** 13 | * 主函数名 14 | * */ 15 | var name: String 16 | 17 | /** 18 | * 预设命名空间 19 | * */ 20 | val namespace: MutableList 21 | 22 | /** 23 | * 前置处理 24 | * */ 25 | val preprocessor: StringBuilder 26 | 27 | /** 28 | * 后置处理 29 | * */ 30 | val postprocessor: StringBuilder 31 | 32 | /** 33 | * 脚本内容 34 | * */ 35 | val content: StringBuilder 36 | 37 | /** 38 | * 构建源码 39 | * */ 40 | fun build(): String 41 | 42 | /** 43 | * 追加前置处理 44 | * */ 45 | fun appendPreprocessor(value: Any?) 46 | 47 | /** 48 | * 追加后置处理 49 | * */ 50 | fun appendPostprocessor(value: Any?) 51 | 52 | /** 53 | * 追加内容 54 | * */ 55 | fun appendContent(value: Any?) 56 | 57 | /** 58 | * 追加文本 59 | * */ 60 | fun appendLiteral(value: String) 61 | 62 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/BacikalQuest.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.bacikal.quest 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-20 22:02 9 | */ 10 | interface BacikalQuest : KetherQuest 11 | 12 | typealias KetherQuest = taboolib.library.kether.Quest -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/BacikalQuestCompiler.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | import top.lanscarlos.vulpecula.bacikal.Bacikal 4 | 5 | /** 6 | * Vulpecula 7 | * top.lanscarlos.vulpecula.bacikal.quest 8 | * 9 | * @author Lanscarlos 10 | * @since 2023-08-20 21:30 11 | */ 12 | interface BacikalQuestCompiler { 13 | 14 | fun compile(name: String, source: String, namespace: List = Bacikal.service.defaultCompileNamespace): BacikalQuest 15 | 16 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/BacikalQuestContext.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | import taboolib.common.platform.ProxyCommandSender 4 | import java.util.concurrent.CompletableFuture 5 | 6 | /** 7 | * Vulpecula 8 | * top.lanscarlos.vulpecula.bacikal.quest 9 | * 10 | * 任务上下文环境 11 | * 12 | * @author Lanscarlos 13 | * @since 2023-08-25 01:42 14 | */ 15 | interface BacikalQuestContext { 16 | 17 | /** 18 | * 任务 19 | * */ 20 | val quest: BacikalQuest 21 | 22 | /** 23 | * 入口主函数名 24 | * */ 25 | val entry: String 26 | 27 | /** 28 | * 脚本执行者 29 | * */ 30 | var sender: ProxyCommandSender? 31 | 32 | /** 33 | * 初始化变量 34 | * */ 35 | fun initVariables(variables: Map) 36 | 37 | /** 38 | * 获取变量 39 | * */ 40 | fun getVariable(key: String): T? 41 | 42 | /** 43 | * 设置变量 44 | * */ 45 | fun setVariable(key: String, value: Any?) 46 | 47 | /** 48 | * 设置变量 49 | * */ 50 | fun setVariables(vararg key: String, value: Any?) 51 | 52 | /** 53 | * 执行脚本 54 | * */ 55 | fun runActions(): CompletableFuture 56 | 57 | /** 58 | * 终止脚本 59 | * */ 60 | fun terminate() 61 | 62 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/BacikalQuestExecutor.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | import java.util.concurrent.CompletableFuture 4 | 5 | /** 6 | * Vulpecula 7 | * top.lanscarlos.vulpecula.bacikal.quest 8 | * 9 | * @author Lanscarlos 10 | * @since 2024-01-05 17:31 11 | */ 12 | interface BacikalQuestExecutor { 13 | 14 | /** 15 | * 创建脚本上下文环境 16 | * @param quest 脚本 17 | * @param entry 入口主函数名 18 | * */ 19 | fun createContext(quest: BacikalQuest, entry: String = "main"): BacikalQuestContext 20 | 21 | /** 22 | * 执行脚本 23 | * @param quest 脚本 24 | * @param entry 入口主函数名 25 | * */ 26 | fun execute(quest: BacikalQuest, entry: String = "main", func: BacikalQuestContext.() -> Unit): CompletableFuture 27 | 28 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/BacikalQuestTransfer.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.bacikal.quest 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-21 20:37 9 | */ 10 | interface BacikalQuestTransfer { 11 | 12 | fun transfer(source: StringBuilder) 13 | 14 | /** 15 | * 抽取所有字符并清空容器 16 | * */ 17 | fun StringBuilder.extract(): String { 18 | val result = toString() 19 | clear() 20 | return result 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/DefaultQuest.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.bacikal 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-20 22:32 9 | */ 10 | open class DefaultQuest(source: KetherQuest) : BacikalQuest, KetherQuest by source -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/FragmentReplacer.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.bacikal.quest 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-21 21:16 9 | */ 10 | class FragmentReplacer(val mapping: Map) : BacikalQuestTransfer { 11 | 12 | private val regex = mapping.keys.joinToString(separator = "|", prefix = "\\$\\{(", postfix = ")\\}").toRegex() 13 | 14 | override fun transfer(source: StringBuilder) { 15 | val result = regex.replace(source.extract()) { 16 | mapping[it.groupValues[1]] ?: it.value 17 | } 18 | source.append(result) 19 | } 20 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/KetherQuestCompiler.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | import taboolib.module.kether.KetherScriptLoader 4 | import taboolib.module.kether.ScriptService 5 | import taboolib.module.kether.printKetherErrorMessage 6 | import java.nio.charset.StandardCharsets 7 | 8 | /** 9 | * Vulpecula 10 | * top.lanscarlos.vulpecula.bacikal.quest 11 | * 12 | * @author Lanscarlos 13 | * @since 2023-08-20 23:20 14 | */ 15 | object KetherQuestCompiler : BacikalQuestCompiler { 16 | 17 | override fun compile(name: String, source: String, namespace: List): BacikalQuest { 18 | val quest = KetherScriptLoader().load( 19 | ScriptService, 20 | "bacikal_$name", 21 | source.toByteArray(StandardCharsets.UTF_8), 22 | listOf("vulpecula", *namespace.toTypedArray()) 23 | ) 24 | return DefaultQuest(quest) 25 | } 26 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/KetherQuestExecutor.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | import taboolib.library.kether.AbstractQuestContext.SimpleNamedFrame 4 | import taboolib.library.kether.AbstractQuestContext.SimpleVarTable 5 | import taboolib.library.kether.QuestContext 6 | import java.util.concurrent.CompletableFuture 7 | 8 | /** 9 | * Vulpecula 10 | * top.lanscarlos.vulpecula.bacikal.quest 11 | * 12 | * @author Lanscarlos 13 | * @since 2023-08-27 15:54 14 | */ 15 | object KetherQuestExecutor : BacikalQuestExecutor { 16 | 17 | override fun createContext(quest: BacikalQuest, entry: String): BacikalQuestContext { 18 | return KetherQuestContext(quest, entry) 19 | } 20 | 21 | override fun execute(quest: BacikalQuest, entry: String, func: BacikalQuestContext.() -> Unit): CompletableFuture { 22 | return createContext(quest, entry).also(func).runActions() 23 | } 24 | 25 | class KetherQuestContext(quest: BacikalQuest, entry: String) : AbstractQuestExecutor(quest, entry) { 26 | override fun createRootFrame(context: InnerContext): QuestContext.Frame { 27 | return SimpleNamedFrame(null, mutableListOf(), SimpleVarTable(null), entry, context) 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/kotlin/top/lanscarlos/vulpecula/bacikal/quest/UnicodeEscalator.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.bacikal.quest 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.bacikal.quest 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-21 21:27 9 | */ 10 | object UnicodeEscalator : BacikalQuestTransfer { 11 | 12 | val REGEX_UNICODE = "\\\\u([A-Za-z0-9]{4})".toRegex() 13 | 14 | override fun transfer(source: StringBuilder) { 15 | val result = REGEX_UNICODE.replace(source.extract()) { 16 | Integer.parseInt(it.groupValues[1], 16).toChar().toString() 17 | } 18 | source.append(result) 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /project/module-bacikal/src/main/resources/action-registry.yml: -------------------------------------------------------------------------------- 1 | 2 | # 请注意 3 | # 改动此文件后需要重启才能加载 4 | 5 | 6 | canvas: 7 | # 是否禁用语句 8 | disable: false 9 | # 是否为公有语句 10 | shared: true 11 | # 本地注册信息 [ 命名空间:语句名 ] 12 | local: 13 | - 'kether:v-canvas' 14 | - 'vulpecula:canvas' 15 | # 远程注册信息 [ 命名空间:语句名 ] 16 | remote: 17 | - 'kether:v-canvas' 18 | - 'vulpecula:canvas' 19 | 20 | ceil: 21 | shared: true 22 | local: 23 | - 'kether:v-ceil' 24 | - 'vulpecula:ceil' 25 | remote: 26 | - 'kether:v-ceil' 27 | - 'vulpecula:ceil' 28 | 29 | coerce: 30 | shared: true 31 | local: 32 | - 'kether:v-coerce' 33 | - 'vulpecula:coerce' 34 | remote: 35 | - 'kether:v-coerce' 36 | - 'vulpecula:coerce' 37 | 38 | item: 39 | shared: true 40 | switch: '@Item' 41 | local: 42 | - 'kether:v-item' 43 | - 'vulpecula:v-item' 44 | remote: 45 | - 'kether:v-item' 46 | - 'vulpecula:v-item' 47 | 48 | script: 49 | shared: true 50 | local: 51 | - 'kether:v-script' 52 | - 'vulpecula:v-script' 53 | remote: 54 | - 'kether:v-script' 55 | - 'vulpecula:v-script' -------------------------------------------------------------------------------- /project/module-bacikal/src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | 2 | 3 | # bacikal 配置 4 | bacikal: 5 | # 是否启用符号闭合检测 6 | analysis-symbol-closure: true 7 | 8 | # 编译器 9 | compiler: 'bacikal' 10 | # 执行器 11 | executor: 'kether' 12 | # 默认编译命名空间 13 | default-compile-namespace: 14 | - 'vulpecula' 15 | - 'kether' 16 | 17 | # 注释匹配规则 18 | comment-pattern: 19 | # 单行注释 20 | # 匹配 // 及其后所有字符直至换行 21 | single-line: '(? bindConfigSection(path: String, bind: String = "config.yml", transfer: Function): DynamicSection { 24 | val configFile = ConfigLoader.files[bind] ?: error("Config $bind not found.") 25 | return YamlDynamicConfig(configFile.file, configFile.configuration).read(path, transfer) 26 | } 27 | 28 | fun bindConfigSection(path: String, bind: File, transfer: Function): DynamicSection { 29 | return YamlDynamicConfig(bind, Configuration.loadFromFile(bind)).read(path, transfer) 30 | } 31 | -------------------------------------------------------------------------------- /project/module-config/src/main/kotlin/top/lanscarlos/vulpecula/config/DefaultDynamicSection.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.config 2 | 3 | import java.util.function.Function 4 | 5 | /** 6 | * Vulpecula 7 | * top.lanscarlos.vulpecula.config 8 | * 9 | * @author Lanscarlos 10 | * @since 2023-08-25 00:31 11 | */ 12 | class DefaultDynamicSection( 13 | override val config: DynamicConfig, 14 | override val path: String, 15 | val transfer: Function 16 | ) : DynamicSection { 17 | 18 | override val position: Int by lazy { 19 | config.indexOf(path) 20 | } 21 | 22 | var innerValue: T? = null 23 | 24 | var isInitialized = false 25 | 26 | @Suppress("UNCHECKED_CAST") 27 | override fun getValue(): T { 28 | if (!isInitialized) { 29 | innerValue = transfer.apply(config[path]) 30 | isInitialized = true 31 | } 32 | return innerValue as T 33 | } 34 | 35 | override fun update() { 36 | innerValue = transfer.apply(config[path]) 37 | isInitialized = true 38 | } 39 | } -------------------------------------------------------------------------------- /project/module-config/src/main/kotlin/top/lanscarlos/vulpecula/config/DynamicSection.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.config 2 | 3 | import kotlin.reflect.KProperty 4 | 5 | /** 6 | * Vulpecula 7 | * top.lanscarlos.vulpecula.config 8 | * 9 | * @author Lanscarlos 10 | * @since 2023-08-25 00:30 11 | */ 12 | interface DynamicSection { 13 | 14 | /** 15 | * 源配置 16 | * */ 17 | val config: DynamicConfig 18 | 19 | /** 20 | * 路径 21 | * */ 22 | val path: String 23 | 24 | /** 25 | * 所在文件的行号 26 | * */ 27 | val position: Int 28 | 29 | /** 30 | * 获取数据 31 | * */ 32 | fun getValue(): T 33 | 34 | /** 35 | * 更新数据 36 | * */ 37 | fun update() 38 | 39 | /** 40 | * 兼容代理属性 41 | * */ 42 | operator fun getValue(source: Any?, property: KProperty<*>): T { 43 | return getValue() 44 | } 45 | } -------------------------------------------------------------------------------- /project/module-volatile/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | taboolib { 3 | subproject = true 4 | } 5 | 6 | dependencies { 7 | compileOnly(project(":project:common")) 8 | 9 | compileOnly("ink.ptms.core:v12000:12000:mapped") 10 | compileOnly("ink.ptms:nms-all:1.0.0") 11 | } -------------------------------------------------------------------------------- /project/module-volatile/src/main/kotlin/top/lanscarlos/vulpecula/volatile/VolatileEntityMetadata.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.volatile 2 | 3 | import org.bukkit.entity.Entity 4 | import org.bukkit.entity.Player 5 | import taboolib.module.nms.MinecraftVersion 6 | import taboolib.module.nms.sendPacket 7 | 8 | /** 9 | * Vulpecula 10 | * top.lanscarlos.vulpecula.volatile 11 | * 12 | * @author Lanscarlos 13 | * @since 2023-08-10 11:32 14 | */ 15 | object VolatileEntityMetadata { 16 | 17 | private val minecraftVersion = MinecraftVersion.majorLegacy 18 | 19 | val HEALTH = volatile(17 to 9, 14 to 8, 10 to 7, 9 to 6) 20 | val POSE = volatile(14 to 6) 21 | 22 | fun updateHealth(viewer: Player, entity: Entity, health: Float) { 23 | viewer.sendPacket(VolatilePacket.createPacketPlayOutEntityMetadata(entity.entityId, HEALTH to health)) 24 | } 25 | 26 | fun updatePose(viewer: Player, entity: Player, pose: VolatilePose) { 27 | viewer.sendPacket(VolatilePacket.createPacketPlayOutEntityMetadata(entity.entityId, POSE to pose)) 28 | } 29 | 30 | private fun volatile(vararg meta: Pair): Int { 31 | return (meta.firstOrNull { minecraftVersion >= it.first - 8 }?.second ?: -1) 32 | } 33 | } -------------------------------------------------------------------------------- /project/module-volatile/src/main/kotlin/top/lanscarlos/vulpecula/volatile/VolatilePacket.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.volatile 2 | 3 | import taboolib.module.nms.nmsProxy 4 | 5 | /** 6 | * Vulpecula 7 | * top.lanscarlos.vulpecula.volatile 8 | * 9 | * @author Lanscarlos 10 | * @since 2023-08-10 11:04 11 | */ 12 | interface VolatilePacket { 13 | 14 | fun createPacketPlayOutEntityMetadata(entityId: Int, vararg metadata: Pair): Any 15 | 16 | companion object : VolatilePacket by nmsProxy("${VolatilePacket::class.java.`package`.name}.DefaultVolatilePacket") 17 | 18 | } -------------------------------------------------------------------------------- /project/module-volatile/src/main/kotlin/top/lanscarlos/vulpecula/volatile/VolatilePose.kt: -------------------------------------------------------------------------------- 1 | package top.lanscarlos.vulpecula.volatile 2 | 3 | /** 4 | * Vulpecula 5 | * top.lanscarlos.vulpecula.volatile 6 | * 7 | * @author Lanscarlos 8 | * @since 2023-08-11 17:31 9 | */ 10 | enum class VolatilePose { 11 | 12 | STANDING, 13 | 14 | FALL_FLYING, 15 | 16 | SLEEPING, 17 | 18 | SWIMMING, 19 | 20 | SPIN_ATTACK, 21 | 22 | CROUCHING, 23 | 24 | DYING, 25 | 26 | } -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name="Vulpecula" 2 | include("common-applicative") 3 | include("common-config") 4 | include("common-core") 5 | include("common-message") 6 | include("extension-action-item") 7 | include("module-bacikal") 8 | include("module-command") 9 | include("module-core") 10 | include("module-dispatcher") 11 | include("module-item") 12 | include("module-item-test") 13 | include("module-schedule") 14 | include("module-script") 15 | include("module-wireshark") 16 | include("platform-bukkit") 17 | include("plugin-mini") 18 | 19 | include("project:common") 20 | include("project:common-core") 21 | include("project:common-legacy") 22 | include("project:extension-anser") 23 | include("project:module-applicative") 24 | include("project:module-bacikal") 25 | include("project:module-config") 26 | include("project:module-volatile") 27 | --------------------------------------------------------------------------------