diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index f6dbe24e..a1692354 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -10,11 +10,11 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up python 3 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: 3.x - name: Install mkdocs and mike diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86edd206..ad3b177c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,15 +11,16 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 17 - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 + distribution: 'temurin' - name: Build artifacts run: ./gradlew build - name: Upload build artifacts - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: build-artifacts path: build/libs \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1338d250..109814e8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,12 +9,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v1 + - name: Set up JDK 21 + uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 + distribution: 'temurin' - name: Build release run: ./gradlew build diff --git a/build.gradle.kts b/build.gradle.kts index ea43f3e0..69b018e1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -84,10 +84,12 @@ dependencies { // Config shadow(libs.konf.core) shadow(libs.konf.toml) + + detektPlugins(libs.detekt.formatting) } tasks { - val javaVersion = JavaVersion.VERSION_17 + val javaVersion = JavaVersion.VERSION_21 processResources { inputs.property("id", modId) diff --git a/detekt.yml b/detekt.yml index 1c47e569..7834e88d 100644 --- a/detekt.yml +++ b/detekt.yml @@ -70,7 +70,7 @@ complexity: threshold: 10 includeStaticDeclarations: false includePrivateDeclarations: false - ComplexMethod: + CyclomaticComplexMethod: active: false threshold: 15 ignoreSingleWhenExpression: false @@ -258,7 +258,6 @@ formatting: active: false autoCorrect: false indentSize: 4 - continuationIndentSize: 4 MaximumLineLength: active: true maxLineLength: 120 @@ -359,7 +358,6 @@ naming: parameterPattern: '[a-z][A-Za-z0-9]*' privateParameterPattern: '[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true EnumNaming: active: true excludes: ['**/test/**', '**/androidTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt'] @@ -381,13 +379,11 @@ naming: excludes: ['**/test/**', '**/androidTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt'] functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' excludeClassPattern: '$^' - ignoreOverridden: true FunctionParameterNaming: active: true excludes: ['**/test/**', '**/androidTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt'] parameterPattern: '[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true InvalidPackageDeclaration: # If you want to use this, set the root package and enable it active: false rootPackage: 'template' @@ -429,7 +425,6 @@ naming: variablePattern: '[a-z][A-Za-z0-9]*' privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true performance: active: true @@ -448,8 +443,6 @@ potential-bugs: active: true Deprecation: active: true - DuplicateCaseInWhenExpression: - active: true EqualsAlwaysReturnsTrueOrFalse: active: true EqualsWithHashCodeExist: @@ -474,16 +467,12 @@ potential-bugs: LateinitUsage: active: false excludes: ['**/test/**', '**/androidTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt'] - excludeAnnotatedProperties: [] + ignoreAnnotated: [] ignoreOnClassesPattern: '' MapGetWithNotNullAssertionOperator: active: true - MissingWhenCase: - active: true NullableToStringCall: active: true - RedundantElseInWhen: - active: true UnconditionalJumpStatementInLoop: active: true UnnecessaryNotNullOperator: @@ -503,13 +492,15 @@ potential-bugs: style: active: true + BracesOnWhenStatements: + active: true ClassOrdering: active: true CollapsibleIfStatements: active: true DataClassContainsFunctions: active: false - conversionFunctionPrefix: 'to' + conversionFunctionPrefix: ['to'] DataClassShouldBeImmutable: active: false EqualsNullCall: @@ -525,7 +516,7 @@ style: includeLineWrapping: false ForbiddenComment: active: false - values: ['TODO:', 'FIXME:', 'STOPSHIP:'] + comments: ['TODO:', 'FIXME:', 'STOPSHIP:'] allowedPatterns: '' ForbiddenImport: active: false @@ -534,9 +525,6 @@ style: ForbiddenMethodCall: active: false methods: [] - ForbiddenPublicDataClass: - active: false - ignorePackages: ['*.internal', '*.internal.*'] ForbiddenVoid: active: true ignoreOverridden: true @@ -544,8 +532,8 @@ style: FunctionOnlyReturningConstant: active: true ignoreOverridableFunction: true - excludedFunctions: 'describeContents' - excludeAnnotatedFunction: ['dagger.Provides'] + excludedFunctions: ['describeContents'] + ignoreAnnotated: ['dagger.Provides'] LibraryCodeMustSpecifyReturnType: active: true LibraryEntitiesShouldNotBePublic: @@ -566,7 +554,7 @@ style: ignoreNamedArgument: true ignoreEnums: true ignoreRanges: false - MandatoryBracesIfStatements: + BracesOnIfStatements: active: true MandatoryBracesLoops: active: true @@ -590,8 +578,6 @@ style: active: true OptionalUnit: active: false - OptionalWhenBraces: - active: true PreferToOverPairSyntax: active: true ProtectedMemberInFinalClass: @@ -603,7 +589,7 @@ style: ReturnCount: active: false max: 2 - excludedFunctions: 'equals' + excludedFunctions: ['equals'] excludeLabeled: false excludeReturnFromLambda: true excludeGuardClauses: false @@ -620,10 +606,10 @@ style: active: true UnderscoresInNumericLiterals: active: true - acceptableDecimalLength: 5 + acceptableLength: 5 UnnecessaryAbstractClass: active: true - excludeAnnotatedClasses: ['dagger.Module'] + ignoreAnnotated: ['dagger.Module'] UnnecessaryAnnotationUseSiteTarget: active: true UnnecessaryApply: @@ -638,6 +624,8 @@ style: active: true UnusedImports: active: true + UnusedParameter: + active: false UnusedPrivateClass: active: true UnusedPrivateMember: @@ -651,7 +639,7 @@ style: active: true UseDataClass: active: true - excludeAnnotatedClasses: [] + ignoreAnnotated: [] allowVars: false UseEmptyCounterpart: active: true diff --git a/docs/index.md b/docs/index.md index 43a168a1..bf8d2d17 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,5 +3,5 @@ ![Last commit](https://img.shields.io/github/last-commit/quiltservertools/ledger?color=7e56c2&style=for-the-badge) ![Contributors](https://img.shields.io/github/contributors/quiltservertools/ledger?color=7e56c2&style=for-the-badge) -Ledger is a server-side fabric logging mod for modern Minecraft 1.17 and 1.18. +Ledger is a server-side fabric logging mod for modern Minecraft 1.17+. Ledger has been written from scratch in Kotlin to solve the main issues of previous logging mods have encountered. diff --git a/gradle.properties b/gradle.properties index d7ea39e9..8da14fbb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ kotlin.code.style=official org.gradle.jvmargs=-Xmx2G # Mod Properties -modVersion = 1.3.1 +modVersion = 1.3.2 mavenGroup = com.github.quiltservertools modId = ledger modName = Ledger diff --git a/libs.versions.toml b/libs.versions.toml index 05bbe638..65b44868 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -1,17 +1,17 @@ [versions] -minecraft = "1.20.4" -yarn-mappings = "1.20.4+build.1" -fabric-loader = "0.15.10" +minecraft = "1.20.6" +yarn-mappings = "1.20.6+build.3" +fabric-loader = "0.15.11" -fabric-api = "0.91.3+1.20.4" +fabric-api = "0.99.0+1.20.6" # Kotlin -kotlin = "1.8.22" +kotlin = "1.9.23" # Also modrinth version in gradle.properties -fabric-kotlin = "1.9.4+kotlin.1.8.21" +fabric-kotlin = "1.10.19+kotlin.1.9.23" fabric-permissions = "0.3.1" -translations = "2.2.0+1.20.3-rc1" +translations = "2.3.0+1.20.5-rc2" exposed = "0.46.0" sqlite-jdbc = "3.44.1.0" @@ -20,6 +20,8 @@ konf = "1.1.2" wdmcf = "1.0.2" +detect = "1.23.6" + [libraries] minecraft = { module = "net.minecraft:minecraft", version.ref = "minecraft" } yarn-mappings = { module = "net.fabricmc:yarn", version.ref = "yarn-mappings" } @@ -39,12 +41,14 @@ sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite-jdbc" } konf-core = { module = "com.uchuhimo:konf-core", version.ref = "konf"} konf-toml = { module = "com.uchuhimo:konf-toml", version.ref = "konf"} +detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detect" } wdmcf = { module = "me.bymartrixx:wdmcf", version.ref = "wdmcf" } [plugins] kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.19.0" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detect" } loom = { id = "fabric-loom", version = "1.6.+" } git_hooks = { id = "com.github.jakemarsden.git-hooks", version = "0.0.2" } -shadow = { id = "com.github.johnrengelman.shadow", version = "7.1.2" } \ No newline at end of file +# https://github.com/johnrengelman/shadow/issues/894 +shadow = { id = "io.github.goooler.shadow", version = "8.1.7" } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/BucketDispenserBehaviorMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/BucketDispenserBehaviorMixin.java index 52c1e085..e12f6b37 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/BucketDispenserBehaviorMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/BucketDispenserBehaviorMixin.java @@ -15,18 +15,18 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(targets = "net/minecraft/block/dispenser/DispenserBehavior$9") +@Mixin(targets = "net/minecraft/block/dispenser/DispenserBehavior$16") public abstract class BucketDispenserBehaviorMixin extends ItemDispenserBehavior { @Inject( - method = "dispenseSilently(Lnet/minecraft/util/math/BlockPointer;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;", + method = "dispenseSilently", at = @At( value = "INVOKE", target = "Lnet/minecraft/block/FluidDrainable;tryDrainFluid(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/WorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/item/ItemStack;", shift = At.Shift.AFTER ) ) - private void logFluidPickup(BlockPointer pointer, ItemStack stack, CallbackInfoReturnable cir, @Local ItemStack itemStack, @Local BlockPos pos, @Local BlockState blockState) { + private void logFluidPickup(BlockPointer pointer, ItemStack stack, CallbackInfoReturnable cir, @Local(argsOnly = true) ItemStack itemStack, @Local BlockPos pos, @Local BlockState blockState) { var world = pointer.world(); if (!itemStack.isEmpty()) { if (blockState.isLiquid() || blockState.isOf(Blocks.POWDER_SNOW)) { diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/BucketItemMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/BucketItemMixin.java index 1c040356..c335a9c0 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/BucketItemMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/BucketItemMixin.java @@ -72,7 +72,7 @@ private void logWaterlog(PlayerEntity player, World world, BlockPos pos, BlockHi } } - @Inject(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;incrementStat(Lnet/minecraft/stat/Stat;)V")) + @Inject(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;incrementStat(Lnet/minecraft/stat/Stat;)V", ordinal = 0)) private void logFluidPickup(World world, PlayerEntity player, Hand hand, CallbackInfoReturnable> cir, @Local(ordinal = 0) BlockPos pos, @Local BlockState blockState) { if (blockState.getBlock() instanceof Waterloggable) { BlockChangeCallback.EVENT.invoker().changeBlock( diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/BedBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/BedBlockMixin.java index bc8ef93f..d1f56d25 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/BedBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/BedBlockMixin.java @@ -8,7 +8,6 @@ import net.minecraft.block.enums.BedPart; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -35,12 +34,12 @@ public void logBedBreak(World world, BlockPos pos, BlockState state, PlayerEntit } @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z")) - public void storeBlockEntity(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void storeBlockEntity(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { oldBlockEntity = world.getBlockEntity(pos); } @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z", shift = At.Shift.AFTER)) - public void logBedExplosion(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void logBedExplosion(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { BlockBreakCallback.EVENT.invoker().breakBlock(world, pos, state, oldBlockEntity, Sources.INTERACT, player); } } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CakeBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CakeBlockMixin.java index fff3b132..c78dc1f6 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CakeBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CakeBlockMixin.java @@ -5,9 +5,11 @@ import net.minecraft.block.BlockState; import net.minecraft.block.CakeBlock; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.state.property.IntProperty; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.ItemActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -56,11 +58,11 @@ private static void ledgerLogCakeEatAndRemove( player); } - @Inject(method = "onUse", at = @At(value = "INVOKE", + @Inject(method = "onUseWithItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z", shift = At.Shift.AFTER)) private void ledgerLogCakeAddCandle( - BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + ItemStack itemStack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable cir) { BlockChangeCallback.EVENT.invoker().changeBlock( player.getWorld(), pos, diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CampfireBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CampfireBlockMixin.java index 030114dd..09e62653 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CampfireBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/CampfireBlockMixin.java @@ -2,15 +2,17 @@ import com.github.quiltservertools.ledger.callbacks.BlockChangeCallback; import com.github.quiltservertools.ledger.utility.Sources; +import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.block.BlockState; import net.minecraft.block.CampfireBlock; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.ItemStack; import net.minecraft.state.property.BooleanProperty; -import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.ItemActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -22,7 +24,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(CampfireBlock.class) public abstract class CampfireBlockMixin { @@ -31,15 +32,15 @@ public abstract class CampfireBlockMixin { @Final public static BooleanProperty LIT; - @Inject(method = "onUse", at = @At(value = "INVOKE", - target = "Lnet/minecraft/entity/player/PlayerEntity;incrementStat(Lnet/minecraft/util/Identifier;)V"), - locals = LocalCapture.CAPTURE_FAILEXCEPTION) - public void logCampfireAddItem(BlockState blockState, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir, BlockEntity oldBlockEntity) { + @Inject(method = "onUseWithItem", at = @At(value = "INVOKE", + target = "Lnet/minecraft/entity/player/PlayerEntity;incrementStat(Lnet/minecraft/util/Identifier;)V") + ) + public void logCampfireAddItem(ItemStack itemStack, BlockState blockState, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable cir, @Local BlockEntity oldBlockEntity) { BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, blockState, world.getBlockState(pos), oldBlockEntity, world.getBlockEntity(pos), Sources.INSERT, player); } @Inject(method = "extinguish", at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/WorldAccess;emitGameEvent(Lnet/minecraft/entity/Entity;Lnet/minecraft/world/event/GameEvent;Lnet/minecraft/util/math/BlockPos;)V")) + target = "Lnet/minecraft/world/WorldAccess;emitGameEvent(Lnet/minecraft/entity/Entity;Lnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/util/math/BlockPos;)V")) private static void logCampfireExtinguish(Entity entity, WorldAccess worldAccess, BlockPos pos, BlockState blockState, CallbackInfo ci) { if (worldAccess instanceof World world) { if (entity instanceof PlayerEntity player) { diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/ComparatorBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/ComparatorBlockMixin.java index 1cf958da..698d8c07 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/ComparatorBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/ComparatorBlockMixin.java @@ -8,7 +8,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.property.EnumProperty; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -26,7 +25,7 @@ public abstract class ComparatorBlockMixin { public static EnumProperty MODE; @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logComparatorInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void logComparatorInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, state.cycle(MODE), state, world.getBlockEntity(pos), world.getBlockEntity(pos), Sources.INTERACT, player); } } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DaylightDetectorBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DaylightDetectorBlockMixin.java index fa99c756..a7b401be 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DaylightDetectorBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DaylightDetectorBlockMixin.java @@ -6,7 +6,6 @@ import net.minecraft.block.DaylightDetectorBlock; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -18,7 +17,7 @@ @Mixin(DaylightDetectorBlock.class) public abstract class DaylightDetectorBlockMixin { @ModifyArgs(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logDaylightDetectorToggling(Args args, BlockState oldState, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + public void logDaylightDetectorToggling(Args args, BlockState oldState, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { BlockState newState = args.get(1); BlockEntity blockEntity = world.getBlockEntity(pos); if (player == null) { diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DoorBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DoorBlockMixin.java index 46e5476e..72e07366 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DoorBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/DoorBlockMixin.java @@ -8,7 +8,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.property.BooleanProperty; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -27,7 +26,7 @@ public abstract class DoorBlockMixin { public static BooleanProperty OPEN; @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logDoorInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void logDoorInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, state.cycle(OPEN), state, null, null, Sources.INTERACT, player); } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FenceGateBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FenceGateBlockMixin.java index 8d995c7c..5fb7f3fd 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FenceGateBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FenceGateBlockMixin.java @@ -8,7 +8,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.property.BooleanProperty; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -27,7 +26,7 @@ public abstract class FenceGateBlockMixin { public static BooleanProperty OPEN; @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logFenceGateInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void logFenceGateInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, state.cycle(OPEN), state, null, null, Sources.INTERACT, player); } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FlowerPotBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FlowerPotBlockMixin.java index 65c76c6f..d706b44b 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FlowerPotBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/FlowerPotBlockMixin.java @@ -4,7 +4,6 @@ import net.minecraft.block.BlockState; import net.minecraft.block.FlowerPotBlock; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -16,7 +15,7 @@ @Mixin(FlowerPotBlock.class) public abstract class FlowerPotBlockMixin { @ModifyArgs(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logFlowerPotInteractions(Args args, BlockState oldState, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + public void logFlowerPotInteractions(Args args, BlockState oldState, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { BlockState state = args.get(1); BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, oldState, state, null, null, player); } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/JukeBoxBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/JukeBoxBlockMixin.java index be915393..8902569c 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/JukeBoxBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/JukeBoxBlockMixin.java @@ -7,7 +7,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.property.BooleanProperty; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -27,7 +26,7 @@ public abstract class JukeBoxBlockMixin { @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/JukeboxBlockEntity;dropRecord()V")) - private void ledgerLogDiscRemoved(BlockState blockState, World world, BlockPos pos, PlayerEntity player, Hand hand, + private void ledgerLogDiscRemoved(BlockState blockState, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { BlockChangeCallback.EVENT.invoker().changeBlock( world, diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/LeverBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/LeverBlockMixin.java index 7771772c..4f5b242a 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/LeverBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/LeverBlockMixin.java @@ -5,7 +5,6 @@ import net.minecraft.block.LeverBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -24,7 +23,7 @@ public abstract class LeverBlockMixin { private PlayerEntity activePlayer; @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/LeverBlock;togglePower(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;")) - public void storePlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void storePlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { activePlayer = player; } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/NoteBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/NoteBlockMixin.java index 3a86cadb..a88a80e3 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/NoteBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/NoteBlockMixin.java @@ -4,7 +4,6 @@ import net.minecraft.block.BlockState; import net.minecraft.block.NoteBlock; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -16,7 +15,7 @@ @Mixin(NoteBlock.class) public abstract class NoteBlockMixin { @ModifyArgs(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logNoteBlockChanges(Args args, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + public void logNoteBlockChanges(Args args, BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { BlockState newState = args.get(1); BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, state, newState, null, null, player); } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/RepeaterBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/RepeaterBlockMixin.java index 04a02363..82fe04d4 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/RepeaterBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/RepeaterBlockMixin.java @@ -7,7 +7,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.property.IntProperty; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -25,7 +24,7 @@ public abstract class RepeaterBlockMixin { public static IntProperty DELAY; @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public void logRepeaterInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { + public void logRepeaterInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable cir) { BlockChangeCallback.EVENT.invoker().changeBlock(world, pos, state, state.cycle(DELAY), null, null, Sources.INTERACT, player); } } diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/lectern/ScreenHandlerMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/lectern/ScreenHandlerMixin.java index e778eee9..3ce4580b 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/lectern/ScreenHandlerMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/lectern/ScreenHandlerMixin.java @@ -11,7 +11,7 @@ @Mixin(ScreenHandler.class) public class ScreenHandlerMixin { - @Inject(method = "onClosed", at = @At(value = "INVOKE")) + @Inject(method = "onClosed", at = @At(value = "HEAD")) public void onClosed(PlayerEntity player, CallbackInfo ci) { if (player.currentScreenHandler instanceof LecternScreenHandler) { PlayerLecternHook.getActiveHandlers().remove(player); diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/AbstractSignBlockMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/AbstractSignBlockMixin.java index c1a7ca6d..d18b6052 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/AbstractSignBlockMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/AbstractSignBlockMixin.java @@ -10,6 +10,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.SignChangingItem; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; @@ -36,7 +37,7 @@ public class AbstractSignBlockMixin { * @return Returns the result of calling {@code original} with this method's parameters. */ @WrapOperation( - method = "onUse", + method = "onUseWithItem", at = @At( value = "INVOKE", target = "Lnet/minecraft/item/SignChangingItem;useOnSign(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/SignBlockEntity;ZLnet/minecraft/entity/player/PlayerEntity;)Z" @@ -53,9 +54,10 @@ private boolean logSignItemInteraction( BlockState state = signBlockEntity.getCachedState(); BlockPos pos = signBlockEntity.getPos(); + DynamicRegistryManager registryManager = world.getRegistryManager(); // a bad hack to copy the old sign block entity for rollbacks - @Nullable BlockEntity oldSignEntity = BlockEntity.createFromNbt(pos, state, signBlockEntity.createNbtWithId()); + @Nullable BlockEntity oldSignEntity = BlockEntity.createFromNbt(pos, state, signBlockEntity.createNbtWithId(registryManager), registryManager); boolean result = original.call(instance, world, signBlockEntity, front, player); if (result && oldSignEntity != null) { diff --git a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/SignBlockEntityMixin.java b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/SignBlockEntityMixin.java index f83bc4f6..fd577ae1 100644 --- a/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/SignBlockEntityMixin.java +++ b/src/main/java/com/github/quiltservertools/ledger/mixin/blocks/sign/SignBlockEntityMixin.java @@ -3,19 +3,21 @@ import com.github.quiltservertools.ledger.callbacks.BlockChangeCallback; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import java.util.UUID; -import java.util.function.UnaryOperator; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.block.entity.SignText; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import java.util.UUID; +import java.util.function.UnaryOperator; + @Mixin(SignBlockEntity.class) public abstract class SignBlockEntityMixin { @@ -46,16 +48,17 @@ private boolean logSignTextChange( Operation original ) { + World world = instance.getWorld(); + DynamicRegistryManager registryManager = world.getRegistryManager(); BlockPos pos = instance.getPos(); BlockState state = instance.getCachedState(); // a bad hack to copy the old sign block entity for rollbacks - @Nullable BlockEntity oldSignEntity = BlockEntity.createFromNbt(pos, state, instance.createNbtWithId()); + @Nullable BlockEntity oldSignEntity = BlockEntity.createFromNbt(pos, state, instance.createNbtWithId(registryManager), registryManager); boolean result = original.call(instance, textChanger, front); if (result && oldSignEntity != null) { - World world = instance.getWorld(); assert world != null : "World cannot be null, this is already in the target method"; UUID editorID = instance.getEditor(); diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/Ledger.kt b/src/main/kotlin/com/github/quiltservertools/ledger/Ledger.kt index acd8ab2a..a7be1d12 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/Ledger.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/Ledger.kt @@ -1,6 +1,5 @@ package com.github.quiltservertools.ledger -import com.github.quiltservertools.ledger.config.config as realConfig import com.github.quiltservertools.ledger.actionutils.ActionSearchParams import com.github.quiltservertools.ledger.actionutils.Preview import com.github.quiltservertools.ledger.api.ExtensionManager @@ -16,6 +15,9 @@ import com.github.quiltservertools.ledger.listeners.registerEntityListeners import com.github.quiltservertools.ledger.listeners.registerPlayerListeners import com.github.quiltservertools.ledger.listeners.registerWorldEventListeners import com.github.quiltservertools.ledger.network.Networking +import com.github.quiltservertools.ledger.network.packet.action.ActionS2CPacket +import com.github.quiltservertools.ledger.network.packet.handshake.HandshakeS2CPacket +import com.github.quiltservertools.ledger.network.packet.response.ResponseS2CPacket import com.github.quiltservertools.ledger.registry.ActionRegistry import com.uchuhimo.konf.Config import kotlinx.coroutines.CoroutineScope @@ -28,6 +30,7 @@ import kotlinx.coroutines.withTimeout import net.fabricmc.api.DedicatedServerModInitializer import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry import net.fabricmc.loader.api.FabricLoader import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer @@ -54,6 +57,7 @@ object Ledger : DedicatedServerModInitializer, CoroutineScope { lateinit var config: Config lateinit var server: MinecraftServer val searchCache = ConcurrentHashMap() + @JvmField // Required for mixin access val previewCache = ConcurrentHashMap() @@ -76,6 +80,9 @@ object Ledger : DedicatedServerModInitializer, CoroutineScope { ServerLifecycleEvents.SERVER_STARTING.register(::serverStarting) ServerLifecycleEvents.SERVER_STOPPED.register(::serverStopped) CommandRegistrationCallback.EVENT.register { dispatcher, _, _ -> registerCommands(dispatcher) } + PayloadTypeRegistry.playS2C().register(ActionS2CPacket.ID, ActionS2CPacket.CODEC) + PayloadTypeRegistry.playS2C().register(HandshakeS2CPacket.ID, HandshakeS2CPacket.CODEC) + PayloadTypeRegistry.playS2C().register(ResponseS2CPacket.ID, ResponseS2CPacket.CODEC) } private fun serverStarting(server: MinecraftServer) { @@ -112,7 +119,8 @@ object Ledger : DedicatedServerModInitializer, CoroutineScope { Ledger.launch(Dispatchers.Default) { while (ActionQueueService.size > 0) { logInfo( - "Database is still busy. If you exit now data WILL be lost. Actions in queue: ${ActionQueueService.size}" + "Database is still busy. If you exit now data WILL be lost. " + + "Actions in queue: ${ActionQueueService.size}" ) delay(config[DatabaseSpec.queueCheckDelaySec].seconds) @@ -122,7 +130,9 @@ object Ledger : DedicatedServerModInitializer, CoroutineScope { logInfo("Successfully drained database queue") } } catch (e: TimeoutCancellationException) { - logWarn("Database drain timed out. ${ActionQueueService.size} actions still in queue. Data may be lost.") + logWarn( + "Database drain timed out. ${ActionQueueService.size} actions still in queue. Data may be lost." + ) } } } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/AbstractActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/AbstractActionType.kt index 7112a204..eda4002a 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/AbstractActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/AbstractActionType.kt @@ -6,8 +6,8 @@ import com.github.quiltservertools.ledger.utility.Sources import com.github.quiltservertools.ledger.utility.TextColorPallet import com.github.quiltservertools.ledger.utility.literal import com.mojang.authlib.GameProfile -import java.time.Instant import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.text.ClickEvent import net.minecraft.text.HoverEvent @@ -17,6 +17,7 @@ import net.minecraft.util.Identifier import net.minecraft.util.Util import net.minecraft.util.math.BlockPos import net.minecraft.world.World +import java.time.Instant import kotlin.time.ExperimentalTime abstract class AbstractActionType : ActionType { @@ -38,13 +39,13 @@ abstract class AbstractActionType : ActionType { override fun restore(server: MinecraftServer): Boolean = false @ExperimentalTime - override fun getMessage(): Text { + override fun getMessage(source: ServerCommandSource): Text { val message = Text.translatable( "text.ledger.action_message", getTimeMessage(), getSourceMessage(), getActionMessage(), - getObjectMessage(), + getObjectMessage(source), getLocationMessage() ) message.style = TextColorPallet.light @@ -81,7 +82,7 @@ abstract class AbstractActionType : ActionType { ) } - open fun getObjectMessage(): Text = Text.translatable( + open fun getObjectMessage(source: ServerCommandSource): Text = Text.translatable( Util.createTranslationKey( this.getTranslationType(), objectIdentifier diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ActionType.kt index 2445645c..b2720a6d 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ActionType.kt @@ -4,12 +4,13 @@ import com.github.quiltservertools.ledger.actionutils.Preview import com.github.quiltservertools.ledger.config.ActionsSpec import com.github.quiltservertools.ledger.config.config import com.mojang.authlib.GameProfile -import java.time.Instant import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.text.Text import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos +import java.time.Instant import kotlin.time.ExperimentalTime interface ActionType { @@ -33,7 +34,7 @@ interface ActionType { fun getTranslationType(): String @ExperimentalTime - fun getMessage(): Text + fun getMessage(source: ServerCommandSource): Text fun isBlacklisted() = config[ActionsSpec.typeBlacklist].contains(identifier) || config[ActionsSpec.objectBlacklist].contains(objectIdentifier) || diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockBreakActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockBreakActionType.kt index 4ee9e30a..e6a7052c 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockBreakActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockBreakActionType.kt @@ -2,6 +2,7 @@ package com.github.quiltservertools.ledger.actions import com.github.quiltservertools.ledger.utility.TextColorPallet import com.github.quiltservertools.ledger.utility.literal +import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.HoverEvent import net.minecraft.text.Text import net.minecraft.util.Util @@ -9,7 +10,7 @@ import net.minecraft.util.Util class BlockBreakActionType : BlockChangeActionType() { override val identifier = "block-break" - override fun getObjectMessage(): Text = Text.translatable( + override fun getObjectMessage(source: ServerCommandSource): Text = Text.translatable( Util.createTranslationKey( this.getTranslationType(), oldObjectIdentifier diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockChangeActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockChangeActionType.kt index c50a6459..33f44578 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockChangeActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockChangeActionType.kt @@ -12,6 +12,7 @@ import net.minecraft.nbt.StringNbtReader import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.text.HoverEvent import net.minecraft.text.Text @@ -24,8 +25,7 @@ open class BlockChangeActionType : AbstractActionType() { override fun rollback(server: MinecraftServer): Boolean { val world = server.getWorld(world) world?.setBlockState(pos, oldBlockState()) - - world?.getBlockEntity(pos)?.readNbt(StringNbtReader.parse(extraData)) + world?.getBlockEntity(pos)?.read(StringNbtReader.parse(extraData), server.registryManager) world?.chunkManager?.markForUpdate(pos) return true @@ -55,7 +55,7 @@ open class BlockChangeActionType : AbstractActionType() { override fun getTranslationType() = "block" - override fun getObjectMessage(): Text { + override fun getObjectMessage(source: ServerCommandSource): Text { val text = Text.literal("") text.append( Text.translatable( @@ -70,7 +70,8 @@ open class BlockChangeActionType : AbstractActionType() { oldObjectIdentifier.toString().literal() ) ) - }) + } + ) if (oldObjectIdentifier != objectIdentifier) { text.append(" → ".literal()) text.append( @@ -86,24 +87,31 @@ open class BlockChangeActionType : AbstractActionType() { objectIdentifier.toString().literal() ) ) - }) + } + ) } return text } - fun oldBlockState() = checkForBlockState(oldObjectIdentifier, oldObjectState?.let { + fun oldBlockState() = checkForBlockState( + oldObjectIdentifier, + oldObjectState?.let { NbtUtils.blockStateFromProperties( StringNbtReader.parse(it), oldObjectIdentifier ) - }) + } + ) - fun newBlockState() = checkForBlockState(objectIdentifier, objectState?.let { + fun newBlockState() = checkForBlockState( + objectIdentifier, + objectState?.let { NbtUtils.blockStateFromProperties( StringNbtReader.parse(it), objectIdentifier ) - }) + } + ) private fun checkForBlockState(identifier: Identifier, checkState: BlockState?): BlockState { val block = Registries.BLOCK.getOrEmpty(identifier) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockPlaceActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockPlaceActionType.kt index ca85bed5..c6c0c9d1 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockPlaceActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/BlockPlaceActionType.kt @@ -5,6 +5,7 @@ import com.github.quiltservertools.ledger.utility.getWorld import com.github.quiltservertools.ledger.utility.literal import net.minecraft.nbt.StringNbtReader import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.HoverEvent import net.minecraft.text.Text import net.minecraft.util.Util @@ -25,13 +26,13 @@ class BlockPlaceActionType : BlockChangeActionType() { val state = newBlockState() world?.setBlockState(pos, state) if (state.hasBlockEntity()) { - world?.getBlockEntity(pos)?.readNbt(StringNbtReader.parse(extraData)) + world?.getBlockEntity(pos)?.read(StringNbtReader.parse(extraData), server.registryManager) } return true } - override fun getObjectMessage(): Text = Text.translatable( + override fun getObjectMessage(source: ServerCommandSource): Text = Text.translatable( Util.createTranslationKey( this.getTranslationType(), objectIdentifier diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityChangeActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityChangeActionType.kt index b404fcf6..5deb2083 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityChangeActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityChangeActionType.kt @@ -1,6 +1,5 @@ package com.github.quiltservertools.ledger.actions -import com.github.quiltservertools.ledger.utility.NbtUtils import com.github.quiltservertools.ledger.utility.TextColorPallet import com.github.quiltservertools.ledger.utility.UUID import com.github.quiltservertools.ledger.utility.getWorld @@ -14,6 +13,7 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.StringNbtReader import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.HoverEvent import net.minecraft.text.Text import net.minecraft.util.Identifier @@ -31,7 +31,7 @@ class EntityChangeActionType : AbstractActionType() { } } - override fun getObjectMessage(): Text { + override fun getObjectMessage(source: ServerCommandSource): Text { val text = Text.literal("") text.append( Text.translatable( @@ -46,10 +46,11 @@ class EntityChangeActionType : AbstractActionType() { objectIdentifier.toString().literal() ) ) - }) + } + ) if (extraData != null && Identifier(extraData) != Identifier.tryParse("minecraft:air")) { - val stack = NbtUtils.itemFromProperties(null, Identifier(extraData)) + val stack = ItemStack(Registries.ITEM.get(Identifier(extraData))) text.append(Text.literal(" ").append(Text.translatable("text.ledger.action_message.with")).append(" ")) text.append( Text.translatable( @@ -64,7 +65,8 @@ class EntityChangeActionType : AbstractActionType() { HoverEvent.ItemStackContent(stack) ) ) - }) + } + ) } return text } @@ -89,7 +91,6 @@ class EntityChangeActionType : AbstractActionType() { return false } - override fun restore(server: MinecraftServer): Boolean { val world = server.getWorld(world) val newEntity = StringNbtReader.parse(objectState) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityKillActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityKillActionType.kt index 8ad25059..a0924f88 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityKillActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/EntityKillActionType.kt @@ -57,7 +57,7 @@ class EntityKillActionType : AbstractActionType() { entity.readNbt(StringNbtReader.parse(extraData)) entity.velocity = Vec3d.ZERO entity.fireTicks = 0 - if (entity is LivingEntity) { entity.health = entity.defaultMaxHealth.toFloat() } + if (entity is LivingEntity) entity.health = entity.defaultMaxHealth.toFloat() world?.spawnEntity(entity) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemChangeActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemChangeActionType.kt index 66a6789d..ca379df7 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemChangeActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemChangeActionType.kt @@ -19,6 +19,7 @@ import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.text.HoverEvent @@ -36,8 +37,14 @@ abstract class ItemChangeActionType : AbstractActionType() { } } - override fun getObjectMessage(): Text { - val stack = NbtUtils.itemFromProperties(extraData, objectIdentifier) + private fun getStack(server: MinecraftServer) = NbtUtils.itemFromProperties( + extraData, + objectIdentifier, + server.registryManager + ) + + override fun getObjectMessage(source: ServerCommandSource): Text { + val stack = getStack(source.server) return "${stack.count} ".literal().append( Text.translatable( @@ -63,17 +70,17 @@ abstract class ItemChangeActionType : AbstractActionType() { if (it) { val otherPos = getOtherChestSide(state, pos) if (otherPos != null) { - addPreview(preview, otherPos, insert) + addPreview(preview, player, otherPos, insert) } } } - addPreview(preview, pos, insert) + addPreview(preview, player, pos, insert) } - private fun addPreview(preview: Preview, pos: BlockPos, insert: Boolean) { + private fun addPreview(preview: Preview, player: ServerPlayerEntity, pos: BlockPos, insert: Boolean) { preview.modifiedItems.compute(pos) { _, list -> list ?: mutableListOf() - }?.add(Pair(NbtUtils.itemFromProperties(extraData, objectIdentifier), insert)) + }?.add(Pair(getStack(player.server), insert)) } private fun getInventory(world: ServerWorld): Inventory? { @@ -100,7 +107,7 @@ abstract class ItemChangeActionType : AbstractActionType() { val inventory = world?.let { getInventory(it) } if (world != null) { - val rollbackStack = NbtUtils.itemFromProperties(extraData, objectIdentifier) + val rollbackStack = getStack(server) if (inventory != null) { for (i in 0 until inventory.size()) { @@ -128,7 +135,7 @@ abstract class ItemChangeActionType : AbstractActionType() { val inventory = world?.let { getInventory(it) } if (world != null) { - val rollbackStack = NbtUtils.itemFromProperties(extraData, objectIdentifier) + val rollbackStack = getStack(server) if (inventory != null) { for (i in 0 until inventory.size()) { diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemDropActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemDropActionType.kt index 6af0b5e9..4c1882df 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemDropActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemDropActionType.kt @@ -13,6 +13,7 @@ import net.minecraft.item.BlockItem import net.minecraft.nbt.StringNbtReader import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.HoverEvent import net.minecraft.text.Text import net.minecraft.util.Util @@ -29,19 +30,27 @@ open class ItemDropActionType : AbstractActionType() { } } - override fun getObjectMessage(): Text { - val stack = NbtUtils.itemFromProperties(extraData, objectIdentifier) + private fun getStack(server: MinecraftServer) = NbtUtils.itemFromProperties( + extraData, + objectIdentifier, + server.registryManager + ) + + override fun getObjectMessage(source: ServerCommandSource): Text { + val stack = getStack(source.server) return "${stack.count} ".literal().append( Text.translatable( Util.createTranslationKey( - getTranslationType(), objectIdentifier + getTranslationType(), + objectIdentifier ) ) ).setStyle(TextColorPallet.secondaryVariant).styled { it.withHoverEvent( HoverEvent( - HoverEvent.Action.SHOW_ITEM, HoverEvent.ItemStackContent(stack) + HoverEvent.Action.SHOW_ITEM, + HoverEvent.ItemStackContent(stack) ) ) } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemPickUpActionType.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemPickUpActionType.kt index 29d6c811..69ddd238 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemPickUpActionType.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actions/ItemPickUpActionType.kt @@ -13,6 +13,7 @@ import net.minecraft.item.BlockItem import net.minecraft.nbt.StringNbtReader import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer +import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.HoverEvent import net.minecraft.text.Text import net.minecraft.util.Util @@ -29,19 +30,27 @@ open class ItemPickUpActionType : AbstractActionType() { } } - override fun getObjectMessage(): Text { - val stack = NbtUtils.itemFromProperties(extraData, objectIdentifier) + private fun getStack(server: MinecraftServer) = NbtUtils.itemFromProperties( + extraData, + objectIdentifier, + server.registryManager + ) + + override fun getObjectMessage(source: ServerCommandSource): Text { + val stack = getStack(source.server) return "${stack.count} ".literal().append( Text.translatable( Util.createTranslationKey( - getTranslationType(), objectIdentifier + getTranslationType(), + objectIdentifier ) ) ).setStyle(TextColorPallet.secondaryVariant).styled { it.withHoverEvent( HoverEvent( - HoverEvent.Action.SHOW_ITEM, HoverEvent.ItemStackContent(stack) + HoverEvent.Action.SHOW_ITEM, + HoverEvent.ItemStackContent(stack) ) ) } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionFactory.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionFactory.kt index 9b8f160d..212b8fbe 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionFactory.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionFactory.kt @@ -96,7 +96,7 @@ object ActionFactory { action.objectState = NbtUtils.blockStateToProperties(state)?.asString() action.oldObjectState = NbtUtils.blockStateToProperties(oldState)?.asString() action.sourceName = source - action.extraData = entity?.createNbt()?.asString() + action.extraData = entity?.createNbt(world.registryManager)?.asString() } fun itemInsertAction(world: World, stack: ItemStack, pos: BlockPos, source: String): ItemInsertActionType { @@ -193,7 +193,7 @@ object ActionFactory { action.world = world.registryKey.value action.objectIdentifier = Registries.ITEM.getId(stack.item) action.sourceName = source - action.extraData = NbtUtils.itemToProperties(stack)?.asString() + action.extraData = stack.encode(world.registryManager)?.asString() } fun entityKillAction(world: World, pos: BlockPos, entity: Entity, cause: DamageSource): EntityKillActionType { @@ -209,7 +209,9 @@ object ActionFactory { val source = Registries.ENTITY_TYPE.getId(killer.type).path setEntityData(action, pos, world, entity, source) } - else -> setEntityData(action, pos, world, entity, cause.name) + else -> { + setEntityData(action, pos, world, entity, cause.name) + } } return action diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionSearchParams.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionSearchParams.kt index 26c95e1f..7495ebfa 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionSearchParams.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/ActionSearchParams.kt @@ -29,7 +29,17 @@ data class ActionSearchParams( builder.worlds ) - fun isEmpty() = listOf(bounds, before, after, actions, objects, sourceNames, sourcePlayerIds, worlds, rolledBack).all { it == null } + fun isEmpty() = listOf( + bounds, + before, + after, + actions, + objects, + sourceNames, + sourcePlayerIds, + worlds, + rolledBack + ).all { it == null } companion object { inline fun build(block: Builder.() -> Unit) = Builder().apply(block).build() diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/Preview.kt b/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/Preview.kt index f60cfa55..8e8c36bd 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/Preview.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/actionutils/Preview.kt @@ -30,7 +30,6 @@ class Preview( // Preview items that should be modified in screen handlers (true = added, false = removed) val modifiedItems = mutableMapOf>>() - init { player.sendMessage( Text.translatable( diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/callbacks/BlockChangeCallback.kt b/src/main/kotlin/com/github/quiltservertools/ledger/callbacks/BlockChangeCallback.kt index a7fa85ee..ec6f815c 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/callbacks/BlockChangeCallback.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/callbacks/BlockChangeCallback.kt @@ -21,10 +21,26 @@ fun interface BlockChangeCallback { player: PlayerEntity? ) - fun changeBlock(world: World, pos: BlockPos, oldState: BlockState, newState: BlockState, oldBlockEntity: BlockEntity?, newBlockEntity: BlockEntity?, player: PlayerEntity) = + fun changeBlock( + world: World, + pos: BlockPos, + oldState: BlockState, + newState: BlockState, + oldBlockEntity: BlockEntity?, + newBlockEntity: BlockEntity?, + player: PlayerEntity + ) = changeBlock(world, pos, oldState, newState, oldBlockEntity, newBlockEntity, Sources.PLAYER, player) - fun changeBlock(world: World, pos: BlockPos, oldState: BlockState, newState: BlockState, oldBlockEntity: BlockEntity?, newBlockEntity: BlockEntity?, source: String) = + fun changeBlock( + world: World, + pos: BlockPos, + oldState: BlockState, + newState: BlockState, + oldBlockEntity: BlockEntity?, + newBlockEntity: BlockEntity?, + source: String + ) = changeBlock(world, pos, oldState, newState, oldBlockEntity, newBlockEntity, source, null) companion object { @@ -33,7 +49,16 @@ fun interface BlockChangeCallback { EventFactory.createArrayBacked(BlockChangeCallback::class.java) { listeners -> BlockChangeCallback { world, pos, oldState, newState, oldBlockEntity, newBlockEntity, source, player -> for (listener in listeners) { - listener.changeBlock(world, pos, oldState, newState, oldBlockEntity, newBlockEntity, source, player) + listener.changeBlock( + world, + pos, + oldState, + newState, + oldBlockEntity, + newBlockEntity, + source, + player + ) } } } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/parameters/ObjectParameter.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/parameters/ObjectParameter.kt index 66d203cc..a7772a33 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/parameters/ObjectParameter.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/parameters/ObjectParameter.kt @@ -27,13 +27,21 @@ class ObjectParameter : SimpleParameter>() { val tagId = IdentifierArgumentType.identifier().parse(stringReader) val blockTag = TagKey.of(RegistryKeys.BLOCK, tagId) - if (blockTag != null) return Registries.BLOCK.iterateEntries(blockTag).map { Registries.BLOCK.getId(it.value()) } + if (blockTag != null) { + return Registries.BLOCK.iterateEntries( + blockTag + ).map { Registries.BLOCK.getId(it.value()) } + } val itemTag = TagKey.of(RegistryKeys.ITEM, tagId) if (itemTag != null) Registries.ITEM.iterateEntries(itemTag).map { Registries.ITEM.getId(it.value()) } val entityTag = TagKey.of(RegistryKeys.ENTITY_TYPE, tagId) - if (entityTag != null) return Registries.ENTITY_TYPE.iterateEntries(entityTag).map { Registries.ENTITY_TYPE.getId(it.value()) } + if (entityTag != null) { + return Registries.ENTITY_TYPE.iterateEntries(entityTag).map { + Registries.ENTITY_TYPE.getId(it.value()) + } + } } return listOf(IdentifierArgumentType.identifier().parse(stringReader)) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PlayerCommand.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PlayerCommand.kt index c6b662a9..260580c5 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PlayerCommand.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PlayerCommand.kt @@ -18,15 +18,16 @@ object PlayerCommand : BuildableCommand { override fun build(): LiteralNode { return literal("player") .requires(Permissions.require("ledger.commands.player", CommandConsts.PERMISSION_LEVEL)) - .then(argument("player", GameProfileArgumentType.gameProfile()) + .then( + argument("player", GameProfileArgumentType.gameProfile()) .executes { return@executes lookupPlayer(GameProfileArgumentType.getProfileArgument(it, "player"), it.source) - }) + } + ) .build() } private fun lookupPlayer(profiles: MutableCollection, source: ServerCommandSource): Int { - Ledger.launch { val players = DatabaseManager.searchPlayers(profiles.toSet()) MessageUtils.sendPlayerMessage(source, players) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PreviewCommand.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PreviewCommand.kt index 180700c5..9e85b622 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PreviewCommand.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PreviewCommand.kt @@ -20,7 +20,8 @@ object PreviewCommand : BuildableCommand { override fun build(): LiteralNode { return CommandManager.literal("preview") .requires(Permissions.require("ledger.commands.preview", CommandConsts.PERMISSION_LEVEL)) - .then(CommandManager.literal("rollback") + .then( + CommandManager.literal("rollback") .then( SearchParamArgument.argument(CommandConsts.PARAMS) .executes { @@ -32,7 +33,8 @@ object PreviewCommand : BuildableCommand { } ) ) - .then(CommandManager.literal("restore") + .then( + CommandManager.literal("restore") .then( SearchParamArgument.argument(CommandConsts.PARAMS) .executes { diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PurgeCommand.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PurgeCommand.kt index 576d5c75..5e205f1d 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PurgeCommand.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/PurgeCommand.kt @@ -20,9 +20,11 @@ object PurgeCommand : BuildableCommand { override fun build(): LiteralNode { return literal("purge") .requires(Permissions.require("ledger.commands.purge", config[SearchSpec.purgePermissionLevel])) - .then(SearchParamArgument.argument(CommandConsts.PARAMS).executes { + .then( + SearchParamArgument.argument(CommandConsts.PARAMS).executes { runPurge(it, SearchParamArgument.get(it, CommandConsts.PARAMS)) - }) + } + ) .build() } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/SearchCommand.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/SearchCommand.kt index 8ff8b744..a3ecda8c 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/SearchCommand.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/SearchCommand.kt @@ -1,8 +1,5 @@ package com.github.quiltservertools.ledger.commands.subcommands -import kotlinx.coroutines.launch -import me.lucko.fabric.api.permissions.v0.Permissions -import net.minecraft.server.command.CommandManager.literal import com.github.quiltservertools.ledger.Ledger import com.github.quiltservertools.ledger.actionutils.ActionSearchParams import com.github.quiltservertools.ledger.commands.BuildableCommand @@ -13,6 +10,9 @@ import com.github.quiltservertools.ledger.utility.Context import com.github.quiltservertools.ledger.utility.LiteralNode import com.github.quiltservertools.ledger.utility.MessageUtils import com.github.quiltservertools.ledger.utility.TextColorPallet +import kotlinx.coroutines.launch +import me.lucko.fabric.api.permissions.v0.Permissions +import net.minecraft.server.command.CommandManager.literal import net.minecraft.text.Text object SearchCommand : BuildableCommand { diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/StatusCommand.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/StatusCommand.kt index e734471d..b3e9fad6 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/StatusCommand.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/StatusCommand.kt @@ -80,7 +80,8 @@ object StatusCommand : BuildableCommand { ) } ).setStyle(TextColorPallet.secondary) - }, false + }, + false ) source.sendFeedback( { @@ -97,7 +98,8 @@ object StatusCommand : BuildableCommand { ) } ).setStyle(TextColorPallet.secondary) - }, false + }, + false ) } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/TeleportCommand.kt b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/TeleportCommand.kt index ef3b2b26..4fc652b9 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/TeleportCommand.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/commands/subcommands/TeleportCommand.kt @@ -1,15 +1,15 @@ package com.github.quiltservertools.ledger.commands.subcommands +import com.github.quiltservertools.ledger.commands.BuildableCommand +import com.github.quiltservertools.ledger.commands.CommandConsts +import com.github.quiltservertools.ledger.utility.Context +import com.github.quiltservertools.ledger.utility.LiteralNode import me.lucko.fabric.api.permissions.v0.Permissions import net.minecraft.command.argument.DimensionArgumentType import net.minecraft.command.argument.PosArgument import net.minecraft.command.argument.Vec3ArgumentType import net.minecraft.server.command.CommandManager import net.minecraft.server.world.ServerWorld -import com.github.quiltservertools.ledger.commands.BuildableCommand -import com.github.quiltservertools.ledger.commands.CommandConsts -import com.github.quiltservertools.ledger.utility.Context -import com.github.quiltservertools.ledger.utility.LiteralNode object TeleportCommand : BuildableCommand { override fun build(): LiteralNode = diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/database/DatabaseManager.kt b/src/main/kotlin/com/github/quiltservertools/ledger/database/DatabaseManager.kt index 13cf4c7d..106abca7 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/database/DatabaseManager.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/database/DatabaseManager.kt @@ -528,7 +528,7 @@ object DatabaseManager { .toSet() // SQLite doesn't support update where so select by ID. Might not be as efficent actions.addAll(getActionsFromQuery(selectQuery)) - val updateQuery = Tables.Actions + Tables.Actions .update({ Tables.Actions.id inList actionIds and (Tables.Actions.rolledBack eq false) }) { it[rolledBack] = true } @@ -555,7 +555,7 @@ object DatabaseManager { val actionIds = selectQuery.map { it[Tables.Actions.id] }.toSet() actions.addAll(getActionsFromQuery(selectQuery)) - val updateQuery = Tables.Actions + Tables.Actions .update({ Tables.Actions.id inList actionIds and (Tables.Actions.rolledBack eq true) }) { it[rolledBack] = false } @@ -695,5 +695,4 @@ object DatabaseManager { return Tables.Player.wrapRows(query).toList().map { PlayerResult.fromRow(it) } } - } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/database/Tables.kt b/src/main/kotlin/com/github/quiltservertools/ledger/database/Tables.kt index 13a0b9d0..092ca735 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/database/Tables.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/database/Tables.kt @@ -72,7 +72,6 @@ object Tables { init { index("actions_by_location", false, x, y, z, world) } - } class Action(id: EntityID) : IntEntity(id) { diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/listeners/BlockEventListener.kt b/src/main/kotlin/com/github/quiltservertools/ledger/listeners/BlockEventListener.kt index 63c208db..2f52c8d6 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/listeners/BlockEventListener.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/listeners/BlockEventListener.kt @@ -15,7 +15,6 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.util.math.BlockPos import net.minecraft.world.World - fun registerBlockListeners() { BlockMeltCallback.EVENT.register(::onMelt) BlockPlaceCallback.EVENT.register(::onBlockPlace) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/listeners/EntityCallbackListener.kt b/src/main/kotlin/com/github/quiltservertools/ledger/listeners/EntityCallbackListener.kt index 3a13e7fd..3818d69d 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/listeners/EntityCallbackListener.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/listeners/EntityCallbackListener.kt @@ -11,7 +11,6 @@ import net.minecraft.nbt.NbtCompound import net.minecraft.util.math.BlockPos import net.minecraft.world.World - fun registerEntityListeners() { EntityKillCallback.EVENT.register(::onKill) EntityModifyCallback.EVENT.register(::onModify) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/listeners/PlayerEventListener.kt b/src/main/kotlin/com/github/quiltservertools/ledger/listeners/PlayerEventListener.kt index e37e8568..595ad5df 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/listeners/PlayerEventListener.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/listeners/PlayerEventListener.kt @@ -74,7 +74,6 @@ private fun onBlockAttack( return ActionResult.PASS } - private fun onJoin(networkHandler: ServerPlayNetworkHandler, packetSender: PacketSender, server: MinecraftServer) { Ledger.launch { DatabaseManager.logPlayer(networkHandler.player.uuid, networkHandler.player.nameForScoreboard) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/Networking.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/Networking.kt index cf722c50..b512b47e 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/Networking.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/Networking.kt @@ -2,20 +2,14 @@ package com.github.quiltservertools.ledger.network import com.github.quiltservertools.ledger.config.NetworkingSpec import com.github.quiltservertools.ledger.config.config -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import com.github.quiltservertools.ledger.network.packet.Receiver -import com.github.quiltservertools.ledger.network.packet.receiver.HandshakePacketReceiver -import com.github.quiltservertools.ledger.network.packet.receiver.InspectReceiver -import com.github.quiltservertools.ledger.network.packet.receiver.PurgeReceiver -import com.github.quiltservertools.ledger.network.packet.receiver.RollbackReceiver -import com.github.quiltservertools.ledger.network.packet.receiver.SearchReceiver -import net.fabricmc.fabric.api.networking.v1.PacketSender +import com.github.quiltservertools.ledger.network.packet.receiver.HandshakeC2SPacket +import com.github.quiltservertools.ledger.network.packet.receiver.InspectC2SPacket +import com.github.quiltservertools.ledger.network.packet.receiver.PurgeC2SPacket +import com.github.quiltservertools.ledger.network.packet.receiver.RollbackC2SPacket +import com.github.quiltservertools.ledger.network.packet.receiver.SearchC2SPacket +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.MinecraftServer -import net.minecraft.server.network.ServerPlayNetworkHandler import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.util.Identifier object Networking { // List of players who have a compatible client mod @@ -24,23 +18,20 @@ object Networking { init { if (config[NetworkingSpec.networking]) { - register(LedgerPacketTypes.INSPECT_POS.id, InspectReceiver()) - register(LedgerPacketTypes.SEARCH.id, SearchReceiver()) - register(LedgerPacketTypes.HANDSHAKE.id, HandshakePacketReceiver()) - register(LedgerPacketTypes.ROLLBACK.id, RollbackReceiver()) - register(LedgerPacketTypes.PURGE.id, PurgeReceiver()) - } - } + PayloadTypeRegistry.playC2S().register(InspectC2SPacket.ID, InspectC2SPacket.CODEC) + ServerPlayNetworking.registerGlobalReceiver(InspectC2SPacket.ID, InspectC2SPacket) + + PayloadTypeRegistry.playC2S().register(SearchC2SPacket.ID, SearchC2SPacket.CODEC) + ServerPlayNetworking.registerGlobalReceiver(SearchC2SPacket.ID, SearchC2SPacket) - private fun register(channel: Identifier, receiver: Receiver) { - ServerPlayNetworking.registerGlobalReceiver(channel) { - server: MinecraftServer, - player: ServerPlayerEntity, - handler: ServerPlayNetworkHandler, - buf: PacketByteBuf, - sender: PacketSender -> + PayloadTypeRegistry.playC2S().register(HandshakeC2SPacket.ID, HandshakeC2SPacket.CODEC) + ServerPlayNetworking.registerGlobalReceiver(HandshakeC2SPacket.ID, HandshakeC2SPacket) - receiver.receive(server, player, handler, buf, sender) + PayloadTypeRegistry.playC2S().register(RollbackC2SPacket.ID, RollbackC2SPacket.CODEC) + ServerPlayNetworking.registerGlobalReceiver(RollbackC2SPacket.ID, RollbackC2SPacket) + + PayloadTypeRegistry.playC2S().register(PurgeC2SPacket.ID, PurgeC2SPacket.CODEC) + ServerPlayNetworking.registerGlobalReceiver(PurgeC2SPacket.ID, PurgeC2SPacket) } } @@ -50,4 +41,3 @@ object Networking { fun ServerPlayerEntity.disableNetworking() = networkedPlayers.remove(this) } - diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/LedgerPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/LedgerPacket.kt deleted file mode 100644 index d358710d..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/LedgerPacket.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet - -import net.minecraft.network.PacketByteBuf -import net.minecraft.util.Identifier - -interface LedgerPacket { - val channel: Identifier - var buf: PacketByteBuf - fun populate(content: T) -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/action/ActionPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/action/ActionPacket.kt deleted file mode 100644 index ba46f739..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/action/ActionPacket.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.action - -import com.github.quiltservertools.ledger.actions.ActionType -import com.github.quiltservertools.ledger.network.packet.LedgerPacket -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs -import net.minecraft.network.PacketByteBuf -import net.minecraft.util.Identifier - -class ActionPacket: LedgerPacket { - override val channel: Identifier = LedgerPacketTypes.ACTION.id - override var buf: PacketByteBuf = PacketByteBufs.create() - - override fun populate(content: ActionType) { - // Position - buf.writeBlockPos(content.pos) - // Type - buf.writeString(content.identifier) - // Dimension - buf.writeIdentifier(content.world) - // Objects - buf.writeIdentifier(content.oldObjectIdentifier) - buf.writeIdentifier(content.objectIdentifier) - // Source - buf.writeString(content.sourceProfile?.name ?: "@" + content.sourceName) - // Epoch second of event, sent as a long - buf.writeLong(content.timestamp.epochSecond) - // Has been rolled back? - buf.writeBoolean(content.rolledBack) - // NBT - buf.writeString(content.extraData ?: "") - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/action/ActionS2CPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/action/ActionS2CPacket.kt new file mode 100644 index 00000000..05e16ccd --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/action/ActionS2CPacket.kt @@ -0,0 +1,39 @@ +package com.github.quiltservertools.ledger.network.packet.action + +import com.github.quiltservertools.ledger.actions.ActionType +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.network.packet.CustomPayload.Id + +data class ActionS2CPacket(val content: ActionType) : CustomPayload { + private fun write(buf: PacketByteBuf?) { + // Position + buf?.writeBlockPos(content.pos) + // Type + buf?.writeString(content.identifier) + // Dimension + buf?.writeIdentifier(content.world) + // Objects + buf?.writeIdentifier(content.oldObjectIdentifier) + buf?.writeIdentifier(content.objectIdentifier) + // Source + buf?.writeString(content.sourceProfile?.name ?: "@" + content.sourceName) + // Epoch second of event, sent as a long + buf?.writeLong(content.timestamp.epochSecond) + // Has been rolled back? + buf?.writeBoolean(content.rolledBack) + // NBT + buf?.writeString(content.extraData ?: "") + } + + override fun getId() = ID + + companion object { + val ID: Id = Id(LedgerPacketTypes.ACTION.id) + val CODEC: PacketCodec = CustomPayload.codecOf( + ActionS2CPacket::write + ) { _: PacketByteBuf? -> TODO() } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/HandshakePacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/HandshakePacket.kt deleted file mode 100644 index 9c0ebb46..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/HandshakePacket.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.handshake - -import com.github.quiltservertools.ledger.network.packet.LedgerPacket -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs -import net.minecraft.network.PacketByteBuf -import net.minecraft.util.Identifier - -class HandshakePacket: LedgerPacket { - override val channel: Identifier = LedgerPacketTypes.HANDSHAKE.id - override var buf: PacketByteBuf = PacketByteBufs.create() - override fun populate(content: HandshakeContent) { - // Ledger information - // Protocol Version - buf.writeInt(content.protocolVersion) - - // Ledger Version - buf.writeString(content.ledgerVersion) - - // We tell the client mod how many actions we are writing - buf.writeInt(content.actions.size) - - for (action in content.actions) { - buf.writeString(action) - } - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/HandshakeS2CPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/HandshakeS2CPacket.kt new file mode 100644 index 00000000..433023f2 --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/HandshakeS2CPacket.kt @@ -0,0 +1,33 @@ +package com.github.quiltservertools.ledger.network.packet.handshake + +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class HandshakeS2CPacket(val content: HandshakeContent) : CustomPayload { + fun write(buf: PacketByteBuf?) { + // Ledger information + // Protocol Version + buf?.writeInt(content.protocolVersion) + + // Ledger Version + buf?.writeString(content.ledgerVersion) + + // We tell the client mod how many actions we are writing + buf?.writeInt(content.actions.size) + + for (action in content.actions) { + buf?.writeString(action) + } + } + + override fun getId() = ID + + companion object { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.HANDSHAKE.id) + val CODEC: PacketCodec = CustomPayload.codecOf( + HandshakeS2CPacket::write + ) { _: PacketByteBuf? -> TODO() } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/ModInfo.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/ModInfo.kt index 8e0670e9..53f0c1c5 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/ModInfo.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/handshake/ModInfo.kt @@ -1,3 +1,3 @@ package com.github.quiltservertools.ledger.network.packet.handshake -data class ModInfo (val modid: String, val version: String, val protocolVersion: Int) +data class ModInfo(val modid: String, val version: String, val protocolVersion: Int) diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/HandshakeC2SPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/HandshakeC2SPacket.kt new file mode 100644 index 00000000..66acdbd6 --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/HandshakeC2SPacket.kt @@ -0,0 +1,87 @@ +package com.github.quiltservertools.ledger.network.packet.receiver + +import com.github.quiltservertools.ledger.Ledger +import com.github.quiltservertools.ledger.commands.CommandConsts +import com.github.quiltservertools.ledger.logInfo +import com.github.quiltservertools.ledger.network.Networking +import com.github.quiltservertools.ledger.network.Networking.enableNetworking +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import com.github.quiltservertools.ledger.network.packet.handshake.HandshakeContent +import com.github.quiltservertools.ledger.network.packet.handshake.ModInfo +import com.github.quiltservertools.ledger.registry.ActionRegistry +import me.lucko.fabric.api.permissions.v0.Permissions +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.nbt.NbtCompound +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.text.Text +import java.util.* + +data class HandshakeC2SPacket(val nbt: NbtCompound?) : CustomPayload { + + override fun getId() = ID + + companion object : ServerPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.HANDSHAKE.id) + val CODEC: PacketCodec = CustomPayload.codecOf({ _, _ -> TODO() }, { + HandshakeC2SPacket(it.readNbt()) + }) + + override fun receive(payload: HandshakeC2SPacket, context: ServerPlayNetworking.Context) { + val player = context.player() + if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL)) return + // This should be sent by the client whenever a player joins with a client mod + // We do some validation on the packet to make sure it's complete and intact + val info = readInfo(payload.nbt) + if (info.isPresent) { + val modid = info.get().modid + val modVersion = info.get().version + val ledgerVersion = FabricLoader.getInstance().getModContainer( + Ledger.MOD_ID + ).get().metadata.version.friendlyString + if (Networking.PROTOCOL_VERSION == info.get().protocolVersion) { + logInfo("${player.name.string} joined the server with a Ledger compatible client mod") + logInfo("Mod: $modid, Version: $modVersion") + + // Player has networking permissions so we send a response + val packet = com.github.quiltservertools.ledger.network.packet.handshake.HandshakeS2CPacket( + HandshakeContent( + Networking.PROTOCOL_VERSION, + ledgerVersion, + ActionRegistry.getTypes().toList() + ) + ) + ServerPlayNetworking.send(player, packet) + player.enableNetworking() + } else { + player.sendMessage( + Text.translatable( + "text.ledger.network.protocols_mismatched", + Networking.PROTOCOL_VERSION, + info.get().protocolVersion + ), + false + ) + logInfo( + "${player.name.string} joined the server with a Ledger compatible client mod, " + + "but has a mismatched protocol: Ledger protocol version: ${Networking.PROTOCOL_VERSION}" + + ", Client mod protocol version ${info.get().protocolVersion}" + ) + } + } else { + player.sendMessage(Text.translatable("text.ledger.network.no_mod_info"), false) + } + } + private fun readInfo(nbt: NbtCompound?): Optional { + if (nbt == null) { + return Optional.empty() + } + + return Optional.of( + ModInfo(nbt.getString("modid"), nbt.getString("version"), nbt.getInt("protocol_version")) + ) + } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/HandshakePacketReceiver.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/HandshakePacketReceiver.kt deleted file mode 100644 index a871258c..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/HandshakePacketReceiver.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.receiver - -import com.github.quiltservertools.ledger.Ledger -import com.github.quiltservertools.ledger.commands.CommandConsts -import com.github.quiltservertools.ledger.logInfo -import com.github.quiltservertools.ledger.network.Networking -import com.github.quiltservertools.ledger.network.Networking.enableNetworking -import com.github.quiltservertools.ledger.network.packet.Receiver -import com.github.quiltservertools.ledger.network.packet.handshake.HandshakeContent -import com.github.quiltservertools.ledger.network.packet.handshake.HandshakePacket -import com.github.quiltservertools.ledger.network.packet.handshake.ModInfo -import com.github.quiltservertools.ledger.registry.ActionRegistry -import me.lucko.fabric.api.permissions.v0.Permissions -import net.fabricmc.fabric.api.networking.v1.PacketSender -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking -import net.fabricmc.loader.api.FabricLoader -import net.minecraft.nbt.NbtCompound -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.MinecraftServer -import net.minecraft.server.network.ServerPlayNetworkHandler -import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.text.Text -import java.util.* - -class HandshakePacketReceiver : Receiver { - override fun receive( - server: MinecraftServer, - player: ServerPlayerEntity, - handler: ServerPlayNetworkHandler, - buf: PacketByteBuf, - sender: PacketSender - ) { - if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL)) return - // This should be sent by the client whenever a player joins with a client mod - val nbt = buf.readNbt() - // We do some validation on the packet to make sure it's complete and intact - val info = readInfo(nbt) - if (info.isPresent) { - val modid = info.get().modid - val modVersion = info.get().version - val ledgerVersion = FabricLoader.getInstance().getModContainer( - Ledger.MOD_ID).get().metadata.version.friendlyString - if (Networking.PROTOCOL_VERSION == info.get().protocolVersion) { - logInfo("${player.name.string} joined the server with a Ledger compatible client mod") - logInfo("Mod: $modid, Version: $modVersion") - - // Player has networking permissions so we send a response - val packet = HandshakePacket() - packet.populate(HandshakeContent(Networking.PROTOCOL_VERSION, ledgerVersion, ActionRegistry.getTypes().toList())) - ServerPlayNetworking.send(player, packet.channel, packet.buf) - player.enableNetworking() - } else { - player.sendMessage( - Text.translatable( - "text.ledger.network.protocols_mismatched", - Networking.PROTOCOL_VERSION, info.get().protocolVersion - ), false - ) - logInfo("${player.name.string} joined the server with a Ledger compatible client mod, " + - "but has a mismatched protocol: Ledger protocol version: ${Networking.PROTOCOL_VERSION}" + - ", Client mod protocol version ${info.get().protocolVersion}") - } - } else { - player.sendMessage(Text.translatable("text.ledger.network.no_mod_info"), false) - } - } - - private fun readInfo(nbt: NbtCompound?): Optional { - if (nbt == null) { - return Optional.empty() - } - - return Optional.of(ModInfo(nbt.getString("modid"), nbt.getString("version"), nbt.getInt("protocol_version"))) - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/InspectC2SPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/InspectC2SPacket.kt new file mode 100644 index 00000000..0c1c0c21 --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/InspectC2SPacket.kt @@ -0,0 +1,65 @@ +package com.github.quiltservertools.ledger.network.packet.receiver + +import com.github.quiltservertools.ledger.Ledger +import com.github.quiltservertools.ledger.commands.CommandConsts +import com.github.quiltservertools.ledger.database.DatabaseManager +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import com.github.quiltservertools.ledger.network.packet.action.ActionS2CPacket +import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes +import com.github.quiltservertools.ledger.network.packet.response.ResponseContent +import com.github.quiltservertools.ledger.network.packet.response.ResponseS2CPacket +import com.github.quiltservertools.ledger.utility.getInspectResults +import kotlinx.coroutines.launch +import me.lucko.fabric.api.permissions.v0.Permissions +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.math.BlockPos + +data class InspectC2SPacket(val pos: BlockPos, val pages: Int) : CustomPayload { + + override fun getId() = ID + + companion object : ServerPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.INSPECT_POS.id) + val CODEC: PacketCodec = CustomPayload.codecOf({ _, _ -> TODO() }, { + InspectC2SPacket(it.readBlockPos(), it.readInt()) + }) + + override fun receive(payload: InspectC2SPacket, context: ServerPlayNetworking.Context) { + val player = context.player() + val sender = context.responseSender() + if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || + !Permissions.check(player, "ledger.commands.inspect", CommandConsts.PERMISSION_LEVEL) + ) { + ResponseS2CPacket.sendResponse( + ResponseContent( + LedgerPacketTypes.INSPECT_POS.id, + ResponseCodes.NO_PERMISSION.code + ), + sender + ) + return + } + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.EXECUTING.code), + sender + ) + + Ledger.launch { + val results = player.getInspectResults(payload.pos) + for (i in 1..payload.pages) { + val page = DatabaseManager.searchActions(results.searchParams, i) + page.actions.forEach { action -> + sender.sendPacket(ActionS2CPacket(action)) + } + } + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.COMPLETED.code), + sender + ) + } + } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/InspectReceiver.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/InspectReceiver.kt deleted file mode 100644 index b4045503..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/InspectReceiver.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.receiver - -import com.github.quiltservertools.ledger.Ledger -import com.github.quiltservertools.ledger.commands.CommandConsts -import com.github.quiltservertools.ledger.database.DatabaseManager -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import com.github.quiltservertools.ledger.network.packet.Receiver -import com.github.quiltservertools.ledger.network.packet.action.ActionPacket -import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes -import com.github.quiltservertools.ledger.network.packet.response.ResponseContent -import com.github.quiltservertools.ledger.network.packet.response.ResponsePacket -import com.github.quiltservertools.ledger.utility.getInspectResults -import kotlinx.coroutines.launch -import me.lucko.fabric.api.permissions.v0.Permissions -import net.fabricmc.fabric.api.networking.v1.PacketSender -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.MinecraftServer -import net.minecraft.server.network.ServerPlayNetworkHandler -import net.minecraft.server.network.ServerPlayerEntity - -class InspectReceiver : Receiver { - override fun receive( - server: MinecraftServer, - player: ServerPlayerEntity, - handler: ServerPlayNetworkHandler, - buf: PacketByteBuf, - sender: PacketSender - ) { - if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || - !Permissions.check(player, "ledger.commands.inspect", CommandConsts.PERMISSION_LEVEL) - ) { - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.NO_PERMISSION.code), sender) - return - } - - val pos = buf.readBlockPos() - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.EXECUTING.code), sender) - - val pages = buf.readInt() - - Ledger.launch { - val results = player.getInspectResults(pos) - for (i in 1..pages) { - val page = DatabaseManager.searchActions(results.searchParams, i) - page.actions.forEach { action -> - val packet = ActionPacket() - packet.populate(action) - sender.sendPacket(packet.channel, packet.buf) - } - } - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.COMPLETED.code), sender) - } - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/PurgeC2SPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/PurgeC2SPacket.kt new file mode 100644 index 00000000..10e2e2c4 --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/PurgeC2SPacket.kt @@ -0,0 +1,65 @@ +package com.github.quiltservertools.ledger.network.packet.receiver + +import com.github.quiltservertools.ledger.Ledger +import com.github.quiltservertools.ledger.commands.CommandConsts +import com.github.quiltservertools.ledger.database.DatabaseManager +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import com.github.quiltservertools.ledger.network.packet.action.ActionS2CPacket +import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes +import com.github.quiltservertools.ledger.network.packet.response.ResponseContent +import com.github.quiltservertools.ledger.network.packet.response.ResponseS2CPacket +import com.github.quiltservertools.ledger.utility.getInspectResults +import kotlinx.coroutines.launch +import me.lucko.fabric.api.permissions.v0.Permissions +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.math.BlockPos + +data class PurgeC2SPacket(val pos: BlockPos, val pages: Int) : CustomPayload { + + override fun getId() = ID + + companion object : ServerPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.PURGE.id) + val CODEC: PacketCodec = CustomPayload.codecOf({ _, _ -> TODO() }, { + PurgeC2SPacket(it.readBlockPos(), it.readInt()) + }) + + override fun receive(payload: PurgeC2SPacket, context: ServerPlayNetworking.Context) { + val player = context.player() + val sender = context.responseSender() + if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || + !Permissions.check(player, "ledger.commands.inspect", CommandConsts.PERMISSION_LEVEL) + ) { + ResponseS2CPacket.sendResponse( + ResponseContent( + LedgerPacketTypes.INSPECT_POS.id, + ResponseCodes.NO_PERMISSION.code + ), + sender + ) + return + } + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.EXECUTING.code), + sender + ) + + Ledger.launch { + val results = player.getInspectResults(payload.pos) + for (i in 1..payload.pages) { + val page = DatabaseManager.searchActions(results.searchParams, i) + page.actions.forEach { action -> + sender.sendPacket(ActionS2CPacket(action)) + } + } + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.INSPECT_POS.id, ResponseCodes.COMPLETED.code), + sender + ) + } + } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/PurgeReceiver.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/PurgeReceiver.kt deleted file mode 100644 index ac264442..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/PurgeReceiver.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.receiver - -import com.github.quiltservertools.ledger.Ledger -import com.github.quiltservertools.ledger.commands.CommandConsts -import com.github.quiltservertools.ledger.commands.arguments.SearchParamArgument -import com.github.quiltservertools.ledger.database.DatabaseManager -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import com.github.quiltservertools.ledger.network.packet.Receiver -import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes -import com.github.quiltservertools.ledger.network.packet.response.ResponseContent -import com.github.quiltservertools.ledger.network.packet.response.ResponsePacket -import kotlinx.coroutines.launch -import me.lucko.fabric.api.permissions.v0.Permissions -import net.fabricmc.fabric.api.networking.v1.PacketSender -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.MinecraftServer -import net.minecraft.server.network.ServerPlayNetworkHandler -import net.minecraft.server.network.ServerPlayerEntity - -class PurgeReceiver : Receiver { - override fun receive( - server: MinecraftServer, - player: ServerPlayerEntity, - handler: ServerPlayNetworkHandler, - buf: PacketByteBuf, - sender: PacketSender - ) { - if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || - !Permissions.check(player, "ledger.commands.purge", CommandConsts.PERMISSION_LEVEL)) { - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.PURGE.id, ResponseCodes.NO_PERMISSION.code), sender) - return - } - - val params = SearchParamArgument.get(buf.readString(), player.commandSource) - - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.PURGE.id, ResponseCodes.EXECUTING.code), sender) - - Ledger.launch { - - DatabaseManager.purgeActions(params) - - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.PURGE.id, ResponseCodes.COMPLETED.code), sender) - } - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/RollbackC2SPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/RollbackC2SPacket.kt new file mode 100644 index 00000000..19e93a9a --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/RollbackC2SPacket.kt @@ -0,0 +1,58 @@ +package com.github.quiltservertools.ledger.network.packet.receiver + +import com.github.quiltservertools.ledger.Ledger +import com.github.quiltservertools.ledger.commands.CommandConsts +import com.github.quiltservertools.ledger.commands.arguments.SearchParamArgument +import com.github.quiltservertools.ledger.database.DatabaseManager +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes +import com.github.quiltservertools.ledger.network.packet.response.ResponseContent +import com.github.quiltservertools.ledger.network.packet.response.ResponseS2CPacket +import kotlinx.coroutines.launch +import me.lucko.fabric.api.permissions.v0.Permissions +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class RollbackC2SPacket(val input: String) : CustomPayload { + + override fun getId() = ID + + companion object : ServerPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.ROLLBACK.id) + val CODEC: PacketCodec = CustomPayload.codecOf({ _, _ -> TODO() }, { + RollbackC2SPacket(it.readString()) + }) + + override fun receive(payload: RollbackC2SPacket, context: ServerPlayNetworking.Context) { + val player = context.player() + val sender = context.responseSender() + if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || + !Permissions.check(player, "ledger.commands.purge", CommandConsts.PERMISSION_LEVEL) + ) { + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.PURGE.id, ResponseCodes.NO_PERMISSION.code), + sender + ) + return + } + + val params = SearchParamArgument.get(payload.input, player.commandSource) + + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.PURGE.id, ResponseCodes.EXECUTING.code), + sender + ) + + Ledger.launch { + DatabaseManager.purgeActions(params) + + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.PURGE.id, ResponseCodes.COMPLETED.code), + sender + ) + } + } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/RollbackReceiver.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/RollbackReceiver.kt deleted file mode 100644 index c158667c..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/RollbackReceiver.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.receiver - -import com.github.quiltservertools.ledger.Ledger -import com.github.quiltservertools.ledger.commands.CommandConsts -import com.github.quiltservertools.ledger.commands.arguments.SearchParamArgument -import com.github.quiltservertools.ledger.database.DatabaseManager -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import com.github.quiltservertools.ledger.network.packet.Receiver -import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes -import com.github.quiltservertools.ledger.network.packet.response.ResponseContent -import com.github.quiltservertools.ledger.network.packet.response.ResponsePacket -import com.github.quiltservertools.ledger.utility.MessageUtils -import com.github.quiltservertools.ledger.utility.launchMain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import me.lucko.fabric.api.permissions.v0.Permissions -import net.fabricmc.fabric.api.networking.v1.PacketSender -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.MinecraftServer -import net.minecraft.server.network.ServerPlayNetworkHandler -import net.minecraft.server.network.ServerPlayerEntity - -class RollbackReceiver : Receiver { - override fun receive( - server: MinecraftServer, - player: ServerPlayerEntity, - handler: ServerPlayNetworkHandler, - buf: PacketByteBuf, - sender: PacketSender - ) { - if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || - !Permissions.check(player, "ledger.commands.rollback", CommandConsts.PERMISSION_LEVEL) - ) { - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.ROLLBACK.id, ResponseCodes.NO_PERMISSION.code), sender) - return - } - - val source = player.commandSource - val restore = buf.readBoolean() - val args = buf.readString() - - val params = SearchParamArgument.get(args, source) - - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.ROLLBACK.id, ResponseCodes.EXECUTING.code), sender) - - Ledger.launch(Dispatchers.IO) { - MessageUtils.warnBusy(source) - if (restore) { - val actions = DatabaseManager.restoreActions(params) - - source.world.launchMain { - - for (action in actions) { - action.restore(source.server) - action.rolledBack = false - } - - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.ROLLBACK.id, ResponseCodes.COMPLETED.code), sender) - } - } else { - val actions = DatabaseManager.rollbackActions(params) - - source.world.launchMain { - - for (action in actions) { - action.rollback(source.server) - action.rolledBack = true - } - - ResponsePacket.sendResponse(ResponseContent(LedgerPacketTypes.ROLLBACK.id, ResponseCodes.COMPLETED.code), sender) - } - } - } - - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/SearchC2SPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/SearchC2SPacket.kt new file mode 100644 index 00000000..2102067a --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/SearchC2SPacket.kt @@ -0,0 +1,96 @@ +package com.github.quiltservertools.ledger.network.packet.receiver + +import com.github.quiltservertools.ledger.Ledger +import com.github.quiltservertools.ledger.commands.CommandConsts +import com.github.quiltservertools.ledger.commands.arguments.SearchParamArgument +import com.github.quiltservertools.ledger.database.DatabaseManager +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes +import com.github.quiltservertools.ledger.network.packet.response.ResponseContent +import com.github.quiltservertools.ledger.network.packet.response.ResponseS2CPacket +import com.github.quiltservertools.ledger.utility.MessageUtils +import com.github.quiltservertools.ledger.utility.launchMain +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import me.lucko.fabric.api.permissions.v0.Permissions +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class SearchC2SPacket(val restore: Boolean, val args: String) : CustomPayload { + + override fun getId() = ID + + companion object : ServerPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.SEARCH.id) + val CODEC: PacketCodec = CustomPayload.codecOf({ _, _ -> TODO() }, { + SearchC2SPacket(it.readBoolean(), it.readString()) + }) + + override fun receive(payload: SearchC2SPacket, context: ServerPlayNetworking.Context) { + val player = context.player() + val sender = context.responseSender() + if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || + !Permissions.check(player, "ledger.commands.rollback", CommandConsts.PERMISSION_LEVEL) + ) { + ResponseS2CPacket.sendResponse( + ResponseContent( + LedgerPacketTypes.ROLLBACK.id, + ResponseCodes.NO_PERMISSION.code + ), + sender + ) + return + } + + val source = player.commandSource + + val params = SearchParamArgument.get(payload.args, source) + + ResponseS2CPacket.sendResponse( + ResponseContent(LedgerPacketTypes.ROLLBACK.id, ResponseCodes.EXECUTING.code), + sender + ) + + Ledger.launch(Dispatchers.IO) { + MessageUtils.warnBusy(source) + if (payload.restore) { + val actions = DatabaseManager.restoreActions(params) + + source.world.launchMain { + for (action in actions) { + action.restore(source.server) + action.rolledBack = false + } + + ResponseS2CPacket.sendResponse( + ResponseContent( + LedgerPacketTypes.ROLLBACK.id, + ResponseCodes.COMPLETED.code + ), + sender + ) + } + } else { + val actions = DatabaseManager.rollbackActions(params) + + source.world.launchMain { + for (action in actions) { + action.rollback(source.server) + action.rolledBack = true + } + + ResponseS2CPacket.sendResponse( + ResponseContent( + LedgerPacketTypes.ROLLBACK.id, + ResponseCodes.COMPLETED.code + ), + sender + ) + } + } + } + } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/SearchReceiver.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/SearchReceiver.kt deleted file mode 100644 index 5cf41845..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/receiver/SearchReceiver.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.receiver - -import com.github.quiltservertools.ledger.Ledger -import com.github.quiltservertools.ledger.commands.CommandConsts -import com.github.quiltservertools.ledger.commands.arguments.SearchParamArgument -import com.github.quiltservertools.ledger.database.DatabaseManager -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import com.github.quiltservertools.ledger.network.packet.Receiver -import com.github.quiltservertools.ledger.network.packet.response.ResponseCodes -import com.github.quiltservertools.ledger.network.packet.response.ResponseContent -import com.github.quiltservertools.ledger.network.packet.response.ResponsePacket -import com.github.quiltservertools.ledger.utility.MessageUtils -import com.github.quiltservertools.ledger.utility.TextColorPallet -import kotlinx.coroutines.launch -import me.lucko.fabric.api.permissions.v0.Permissions -import net.fabricmc.fabric.api.networking.v1.PacketSender -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.MinecraftServer -import net.minecraft.server.network.ServerPlayNetworkHandler -import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.text.Text - -class SearchReceiver : Receiver { - override fun receive( - server: MinecraftServer, - player: ServerPlayerEntity, - handler: ServerPlayNetworkHandler, - buf: PacketByteBuf, - sender: PacketSender - ) { - if (!Permissions.check(player, "ledger.networking", CommandConsts.PERMISSION_LEVEL) || - !Permissions.check(player, "ledger.commands.search", CommandConsts.PERMISSION_LEVEL) - ) { - ResponsePacket.sendResponse( - ResponseContent(LedgerPacketTypes.SEARCH.id, ResponseCodes.NO_PERMISSION.code), - sender - ) - return - } - val source = player.commandSource - val input = buf.readString() - val params = SearchParamArgument.get(input, source) - - val pages = buf.readInt() - - if (params.isEmpty()) { - ResponsePacket.sendResponse( - ResponseContent(LedgerPacketTypes.SEARCH.id, ResponseCodes.ERROR.code), - sender - ) - return - } - - ResponsePacket.sendResponse( - ResponseContent(LedgerPacketTypes.SEARCH.id, ResponseCodes.EXECUTING.code), - sender - ) - - Ledger.launch { - Ledger.searchCache[source.name] = params - - MessageUtils.warnBusy(source) - val results = DatabaseManager.searchActions(params, 1) - - for (i in 1..pages) { - val page = DatabaseManager.searchActions(results.searchParams, i) - MessageUtils.sendSearchResults( - source, - page, - Text.translatable( - "text.ledger.header.search" - ).setStyle(TextColorPallet.primary) - ) - } - - ResponsePacket.sendResponse( - ResponseContent(LedgerPacketTypes.SEARCH.id, ResponseCodes.COMPLETED.code), - sender - ) - } - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/response/ResponsePacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/response/ResponsePacket.kt deleted file mode 100644 index a3b8fabf..00000000 --- a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/response/ResponsePacket.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.quiltservertools.ledger.network.packet.response - -import com.github.quiltservertools.ledger.network.packet.LedgerPacket -import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs -import net.fabricmc.fabric.api.networking.v1.PacketSender -import net.minecraft.network.PacketByteBuf -import net.minecraft.util.Identifier - -class ResponsePacket : LedgerPacket { - override var buf: PacketByteBuf = PacketByteBufs.create() - override val channel: Identifier = LedgerPacketTypes.RESPONSE.id - override fun populate(content: ResponseContent) { - // Packet type, rollback response would be `ledger.rollback` - buf.writeIdentifier(content.type) - // Response code - buf.writeInt(content.response) - } - - companion object { - fun sendResponse(content: ResponseContent, sender: PacketSender) { - val response = ResponsePacket() - response.populate(content) - sender.sendPacket(LedgerPacketTypes.RESPONSE.id, response.buf) - } - } -} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/response/ResponseS2CPacket.kt b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/response/ResponseS2CPacket.kt new file mode 100644 index 00000000..a890cc06 --- /dev/null +++ b/src/main/kotlin/com/github/quiltservertools/ledger/network/packet/response/ResponseS2CPacket.kt @@ -0,0 +1,29 @@ +package com.github.quiltservertools.ledger.network.packet.response + +import com.github.quiltservertools.ledger.network.packet.LedgerPacketTypes +import net.fabricmc.fabric.api.networking.v1.PacketSender +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class ResponseS2CPacket(val content: ResponseContent) : CustomPayload { + fun write(buf: PacketByteBuf?) { + // Packet type, rollback response would be `ledger.rollback` + buf?.writeIdentifier(content.type) + // Response code + buf?.writeInt(content.response) + } + + override fun getId() = ID + + companion object { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerPacketTypes.RESPONSE.id) + val CODEC: PacketCodec = CustomPayload.codecOf( + ResponseS2CPacket::write + ) { _: PacketByteBuf? -> TODO() } + + fun sendResponse(content: ResponseContent, sender: PacketSender) { + sender.sendPacket(ResponseS2CPacket(content)) + } + } +} diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/utility/InspectionManager.kt b/src/main/kotlin/com/github/quiltservertools/ledger/utility/InspectionManager.kt index 63c89c8f..b771d3d6 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/utility/InspectionManager.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/utility/InspectionManager.kt @@ -4,7 +4,6 @@ import com.github.quiltservertools.ledger.Ledger import com.github.quiltservertools.ledger.actionutils.ActionSearchParams import com.github.quiltservertools.ledger.actionutils.SearchResults import com.github.quiltservertools.ledger.database.DatabaseManager -import java.util.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import net.minecraft.block.BedBlock @@ -22,6 +21,7 @@ import net.minecraft.util.Formatting import net.minecraft.util.math.BlockBox import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction +import java.util.* private val inspectingUsers = HashSet() @@ -111,7 +111,9 @@ fun getOtherChestSide(state: BlockState, pos: BlockPos): BlockPos? { } else { pos.offset(facing.rotateClockwise(Direction.Axis.Y)) } - } else null + } else { + null + } } private fun getOtherDoorHalf(state: BlockState, pos: BlockPos): BlockPos { @@ -143,4 +145,3 @@ suspend fun PlayerEntity.getInspectResults(pos: BlockPos): SearchResults { MessageUtils.warnBusy(source) return DatabaseManager.searchActions(params, 1) } - diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/utility/MessageUtils.kt b/src/main/kotlin/com/github/quiltservertools/ledger/utility/MessageUtils.kt index 81823329..7dfc0413 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/utility/MessageUtils.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/utility/MessageUtils.kt @@ -5,7 +5,7 @@ import com.github.quiltservertools.ledger.actionutils.SearchResults import com.github.quiltservertools.ledger.config.SearchSpec import com.github.quiltservertools.ledger.database.DatabaseManager import com.github.quiltservertools.ledger.network.Networking.hasNetworking -import com.github.quiltservertools.ledger.network.packet.action.ActionPacket +import com.github.quiltservertools.ledger.network.packet.action.ActionS2CPacket import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.ClickEvent @@ -23,15 +23,12 @@ import kotlin.time.toKotlinDuration object MessageUtils { @OptIn(ExperimentalTime::class) suspend fun sendSearchResults(source: ServerCommandSource, results: SearchResults, header: Text) { - // If the player has a Ledger compatible client, we send results as action packets rather than as chat messages if (source.hasPlayer() && source.playerOrThrow.hasNetworking()) { for (n in results.page..results.pages) { val networkResults = DatabaseManager.searchActions(results.searchParams, n) networkResults.actions.forEach { - val packet = ActionPacket() - packet.populate(it) - ServerPlayNetworking.send(source.player, packet.channel, packet.buf) + ServerPlayNetworking.send(source.player, ActionS2CPacket(it)) } } return @@ -40,7 +37,7 @@ object MessageUtils { source.sendFeedback({ header }, false) results.actions.forEach { actionType -> - source.sendFeedback({ actionType.getMessage() }, false) + source.sendFeedback({ actionType.getMessage(source) }, false) } source.sendFeedback( diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/utility/NbtUtils.kt b/src/main/kotlin/com/github/quiltservertools/ledger/utility/NbtUtils.kt index 56743d53..47ec4548 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/utility/NbtUtils.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/utility/NbtUtils.kt @@ -1,14 +1,23 @@ package com.github.quiltservertools.ledger.utility -import net.fabricmc.fabric.api.util.NbtType +import com.mojang.serialization.Dynamic import net.minecraft.block.BlockState +import net.minecraft.datafixer.Schemas +import net.minecraft.datafixer.TypeReferences import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound +import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtHelper +import net.minecraft.nbt.NbtOps import net.minecraft.nbt.StringNbtReader import net.minecraft.registry.Registries +import net.minecraft.registry.RegistryWrapper import net.minecraft.util.Identifier +const val ITEM_NBT_DATA_VERSION = 3817 +const val ITEM_COMPONENTS_DATA_VERSION = 3825 + +const val COMPONENTS = "components" // ItemStack const val PROPERTIES = "Properties" // BlockState const val COUNT = "Count" // ItemStack const val TAG = "tag" // ItemStack @@ -18,7 +27,15 @@ object NbtUtils { fun blockStateToProperties(state: BlockState): NbtCompound? { val stateTag = NbtHelper.fromBlockState(state) if (state.block.defaultState == state) return null // Don't store default block state - return if (stateTag.contains(PROPERTIES, NbtType.COMPOUND)) stateTag.getCompound(PROPERTIES) else null + return if (stateTag.contains( + PROPERTIES, + NbtElement.COMPOUND_TYPE.toInt() + ) + ) { + stateTag.getCompound(PROPERTIES) + } else { + null + } } fun blockStateFromProperties(tag: NbtCompound, name: Identifier): BlockState { @@ -28,41 +45,30 @@ object NbtUtils { return NbtHelper.toBlockState(Registries.BLOCK.readOnlyWrapper, stateTag) } - fun itemToProperties(item: ItemStack): NbtCompound? { - val itemTag = NbtCompound() - - // Don't log the item count if there is only 1 item. The log itself indicates there must be at least 1 - if (item.count > 1) { - itemTag.putByte(COUNT, item.count.toByte()) - } - - if (item.nbt != null) { - itemTag.put(TAG, item.nbt) - } - return if (itemTag.isEmpty) null else itemTag - } - - fun itemFromProperties(tag: String?, name: Identifier): ItemStack { - val itemTag = NbtCompound() - - itemTag.putString("id", name.toString()) - if (tag == null) { - itemTag.putByte(COUNT, 1) - return ItemStack.fromNbt(itemTag) - } - - val tagNbt = StringNbtReader.parse(tag) - // Item was missing count tag. If it's been logged, it must have a single item - if (tagNbt.contains(COUNT)) { - itemTag.putByte(COUNT, tagNbt.getByte(COUNT)) + fun itemFromProperties(tag: String?, name: Identifier, registries: RegistryWrapper.WrapperLookup): ItemStack { + val extraDataTag = StringNbtReader.parse(tag ?: "{}") + var itemTag: NbtElement + if (extraDataTag.contains(COMPONENTS)) { + itemTag = extraDataTag } else { - itemTag.putByte(COUNT, 1) - } + itemTag = NbtCompound() + itemTag.putString("id", name.toString()) + if (extraDataTag.contains(COUNT)) { + itemTag.putByte(COUNT, extraDataTag.getByte(COUNT)) + } else { + itemTag.putByte(COUNT, 1) + } + + if (extraDataTag.contains(TAG)) { + itemTag.put(TAG, extraDataTag.getCompound(TAG)) - if (tagNbt.contains(TAG)) { - itemTag.put(TAG, tagNbt.getCompound(TAG)) + itemTag = Schemas.getFixer().update( + TypeReferences.ITEM_STACK, + Dynamic(NbtOps.INSTANCE, itemTag), ITEM_NBT_DATA_VERSION, ITEM_COMPONENTS_DATA_VERSION + ).cast(NbtOps.INSTANCE) + } } - return ItemStack.fromNbt(itemTag) + return ItemStack.fromNbt(registries, itemTag).get() } } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/utility/Negatable.kt b/src/main/kotlin/com/github/quiltservertools/ledger/utility/Negatable.kt index 8cb7d3af..73a9af6f 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/utility/Negatable.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/utility/Negatable.kt @@ -4,6 +4,7 @@ data class Negatable (val property: T, val allowed: Boolean) { companion object { @JvmStatic fun allow(value: U) = Negatable(value, true) + @JvmStatic fun deny(value: U) = Negatable(value, false) } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/utility/PlayerResult.kt b/src/main/kotlin/com/github/quiltservertools/ledger/utility/PlayerResult.kt index 882faa54..3b2dc235 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/utility/PlayerResult.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/utility/PlayerResult.kt @@ -17,6 +17,11 @@ data class PlayerResult(val uuid: UUID, val name: String, val firstJoin: Instant } companion object { - fun fromRow(row: Tables.Player): PlayerResult = PlayerResult(row.playerId, row.playerName, row.firstJoin, row.lastJoin) + fun fromRow(row: Tables.Player): PlayerResult = PlayerResult( + row.playerId, + row.playerName, + row.firstJoin, + row.lastJoin + ) } } diff --git a/src/main/kotlin/com/github/quiltservertools/ledger/utility/TextColorPallet.kt b/src/main/kotlin/com/github/quiltservertools/ledger/utility/TextColorPallet.kt index 7f823aae..3c4c0c8d 100644 --- a/src/main/kotlin/com/github/quiltservertools/ledger/utility/TextColorPallet.kt +++ b/src/main/kotlin/com/github/quiltservertools/ledger/utility/TextColorPallet.kt @@ -11,10 +11,14 @@ object TextColorPallet { val primary: Style get() = Style.EMPTY.withColor(TextColor.parse(config[ColorSpec.primary]).getOrNull()) - val primaryVariant: Style get() = Style.EMPTY.withColor(TextColor.parse(config[ColorSpec.primaryVariant]).getOrNull()) + val primaryVariant: Style get() = Style.EMPTY.withColor( + TextColor.parse(config[ColorSpec.primaryVariant]).getOrNull() + ) val secondary: Style get() = Style.EMPTY.withColor(TextColor.parse(config[ColorSpec.secondary]).getOrNull()) - val secondaryVariant: Style get() = Style.EMPTY.withColor(TextColor.parse(config[ColorSpec.secondaryVariant]).getOrNull()) + val secondaryVariant: Style get() = Style.EMPTY.withColor( + TextColor.parse(config[ColorSpec.secondaryVariant]).getOrNull() + ) val light: Style get() = Style.EMPTY.withColor(TextColor.parse(config[ColorSpec.light]).getOrNull()) } -fun DataResult.getOrNull(): TextColor? = this.get().left().orElse(null) +fun DataResult.getOrNull(): TextColor? = this.result().orElse(null) diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a1bf9687..567ca7d4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,7 +26,7 @@ "ledger.mixins.json" ], "depends": { - "fabricloader": ">=0.15.0", + "fabricloader": ">=0.15.10", "fabric": ">=${fabricApi}", "fabric-language-kotlin": ">=${fabricKotlin}", "minecraft": ">=${minecraft}" @@ -34,4 +34,4 @@ "breaks": { "cardboard": "*" } -} \ No newline at end of file +} diff --git a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/LedgerTest.kt b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/LedgerTest.kt index 8b4bd5e3..85bf2f5b 100644 --- a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/LedgerTest.kt +++ b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/LedgerTest.kt @@ -1,18 +1,20 @@ package com.github.quiltservertools.ledger.testmod +import com.github.quiltservertools.ledger.testmod.commands.packet.ActionS2CPacket +import com.github.quiltservertools.ledger.testmod.commands.packet.HandshakeC2SPacket +import com.github.quiltservertools.ledger.testmod.commands.packet.HandshakeS2CPacket +import com.github.quiltservertools.ledger.testmod.commands.packet.InspectC2SPacket +import com.github.quiltservertools.ledger.testmod.commands.packet.SearchC2SPacket import com.github.quiltservertools.ledger.testmod.commands.registerCommands import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs -import net.minecraft.nbt.NbtCompound +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger -import java.time.Instant object LedgerTest : ClientModInitializer { val HANDSHAKE = Identifier("ledger", "handshake") @@ -22,42 +24,15 @@ object LedgerTest : ClientModInitializer { val LOGGER: Logger = LogManager.getLogger("LedgerTestmod") override fun onInitializeClient() { - ClientPlayConnectionEvents.JOIN.register { handler, sender, client -> - // Create and send handshake packet - val tag = NbtCompound() - tag.putString("modid", "ledger-testmod") - tag.putString("version", "1.0.0") - tag.putInt("protocol_version", 1) - val buf = PacketByteBufs.create() - buf.writeNbt(tag) - sender.sendPacket(HANDSHAKE, buf) - } - - ClientPlayNetworking.registerGlobalReceiver(HANDSHAKE) { client, handler, buf, sender -> - val protocolVersion = buf.readInt() - val ledgerVersion = buf.readString() - val actionsLength = buf.readInt() - LOGGER.info("Protocol version: {}", protocolVersion) - LOGGER.info("Ledger version: {}", ledgerVersion) - LOGGER.info("Number of types registered: {}", actionsLength) - for (i in 0..actionsLength) { - LOGGER.info("Action type: {}", buf.readString()) - } - } + PayloadTypeRegistry.playC2S().register(HandshakeC2SPacket.ID, HandshakeC2SPacket.CODEC) + PayloadTypeRegistry.playC2S().register(SearchC2SPacket.ID, SearchC2SPacket.CODEC) + PayloadTypeRegistry.playC2S().register(InspectC2SPacket.ID, InspectC2SPacket.CODEC) - ClientPlayNetworking.registerGlobalReceiver(ACTION) { client, handler, buf, sender -> - val pos = buf.readBlockPos() - val id = buf.readString() - val world = buf.readIdentifier() - val oldObjectId = buf.readIdentifier() - val objectId = buf.readIdentifier() - val source = buf.readString() - val timestamp = Instant.ofEpochSecond(buf.readLong()) - val extraData = buf.readString() + PayloadTypeRegistry.playS2C().register(HandshakeS2CPacket.ID, HandshakeS2CPacket.CODEC) + PayloadTypeRegistry.playS2C().register(ActionS2CPacket.ID, ActionS2CPacket.CODEC) - LOGGER.info("pos={}, id={}, world={}, oldObjectId={}, objectId={}, source={}, timestamp={}, extraData={}", - pos, id, world, oldObjectId, objectId, source, timestamp, extraData) - } + ClientPlayNetworking.registerGlobalReceiver(HandshakeS2CPacket.ID, HandshakeS2CPacket) + ClientPlayNetworking.registerGlobalReceiver(ActionS2CPacket.ID, ActionS2CPacket) PlayerBlockBreakEvents.AFTER.register { world, player, pos, state, blockEntity -> inspectBlock(pos) @@ -69,14 +44,10 @@ object LedgerTest : ClientModInitializer { } fun inspectBlock(pos: BlockPos) { - val buf = PacketByteBufs.create() - buf.writeBlockPos(pos) - ClientPlayNetworking.send(INSPECT, buf) + ClientPlayNetworking.send(InspectC2SPacket(pos)) } fun sendSearchQuery(query: String) { - val buf = PacketByteBufs.create() - buf.writeString(query) - ClientPlayNetworking.send(SEARCH, buf) + ClientPlayNetworking.send(SearchC2SPacket(query)) } } diff --git a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/ActionS2CPacket.kt b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/ActionS2CPacket.kt new file mode 100644 index 00000000..d7c8f502 --- /dev/null +++ b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/ActionS2CPacket.kt @@ -0,0 +1,58 @@ +package com.github.quiltservertools.ledger.testmod.commands.packet + + +import com.github.quiltservertools.ledger.testmod.LedgerTest +import java.time.Instant +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Identifier +import net.minecraft.util.math.BlockPos + +data class ActionS2CPacket( + val pos: BlockPos, + val id: String, + val world: Identifier, + val oldObjectId: Identifier, + val objectId: Identifier, + val source: String, + val timestamp: Instant, + val extraData: String +) : + CustomPayload { + + override fun getId() = ID + + companion object : ClientPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerTest.ACTION) + val CODEC: PacketCodec = + CustomPayload.codecOf({ _, _ -> TODO() }, { + ActionS2CPacket( + it.readBlockPos(), + it.readString(), + it.readIdentifier(), + it.readIdentifier(), + it.readIdentifier(), + it.readString(), + Instant.ofEpochSecond(it.readLong()), + it.readString() + ) + }) + + override fun receive(payload: ActionS2CPacket, context: ClientPlayNetworking.Context?) { + LedgerTest.LOGGER.info( + "pos={}, id={}, world={}, oldObjectId={}, objectId={}, source={}, timestamp={}, extraData={}", + payload.pos, + payload.id, + payload.world, + payload.oldObjectId, + payload.objectId, + payload.source, + payload.timestamp, + payload.extraData + ) + } + } + +} diff --git a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/HandshakeC2SPacket.kt b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/HandshakeC2SPacket.kt new file mode 100644 index 00000000..ded3aa2f --- /dev/null +++ b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/HandshakeC2SPacket.kt @@ -0,0 +1,24 @@ +package com.github.quiltservertools.ledger.testmod.commands.packet + + +import com.github.quiltservertools.ledger.testmod.LedgerTest +import net.minecraft.nbt.NbtCompound +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class HandshakeC2SPacket(val nbt: NbtCompound?) : CustomPayload { + + override fun getId() = ID + + private fun write(buf: PacketByteBuf?) { + buf?.writeNbt(nbt) + } + + companion object { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerTest.HANDSHAKE) + val CODEC: PacketCodec = + CustomPayload.codecOf(HandshakeC2SPacket::write) { TODO() } + } + +} diff --git a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/HandshakeS2CPacket.kt b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/HandshakeS2CPacket.kt new file mode 100644 index 00000000..ca86fbd6 --- /dev/null +++ b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/HandshakeS2CPacket.kt @@ -0,0 +1,39 @@ +package com.github.quiltservertools.ledger.testmod.commands.packet + + +import com.github.quiltservertools.ledger.testmod.LedgerTest +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class HandshakeS2CPacket(val protocolVersion: Int, val ledgerVersion: String, val actionTypes: Collection) : + CustomPayload { + + override fun getId() = ID + + companion object : ClientPlayNetworking.PlayPayloadHandler { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerTest.HANDSHAKE) + val CODEC: PacketCodec = + CustomPayload.codecOf({ _, _ -> TODO() }, { + val protocolVersion = it.readInt() + val ledgerVersion = it.readString() + val actionsLength = it.readInt() + val actionTypes: MutableList = mutableListOf() + for (i in 0..actionsLength) { + actionTypes.add(it.readString()) + } + HandshakeS2CPacket(protocolVersion, ledgerVersion, actionTypes) + }) + + override fun receive(payload: HandshakeS2CPacket, context: ClientPlayNetworking.Context?) { + LedgerTest.LOGGER.info("Protocol version: {}", payload.protocolVersion) + LedgerTest.LOGGER.info("Ledger version: {}", payload.ledgerVersion) + LedgerTest.LOGGER.info("Number of types registered: {}", payload.actionTypes.size) + payload.actionTypes.forEach { + LedgerTest.LOGGER.info("Action type: {}", it) + } + } + } + +} diff --git a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/InspectC2SPacket.kt b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/InspectC2SPacket.kt new file mode 100644 index 00000000..b4af1461 --- /dev/null +++ b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/InspectC2SPacket.kt @@ -0,0 +1,24 @@ +package com.github.quiltservertools.ledger.testmod.commands.packet + + +import com.github.quiltservertools.ledger.testmod.LedgerTest +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.math.BlockPos + +data class InspectC2SPacket(val pos: BlockPos) : CustomPayload { + + override fun getId() = ID + + private fun write(buf: PacketByteBuf?) { + buf?.writeBlockPos(pos) + } + + companion object { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerTest.INSPECT) + val CODEC: PacketCodec = + CustomPayload.codecOf(InspectC2SPacket::write) { TODO() } + } + +} diff --git a/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/SearchC2SPacket.kt b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/SearchC2SPacket.kt new file mode 100644 index 00000000..db658aff --- /dev/null +++ b/src/testmod/kotlin/com/github/quiltservertools/ledger/testmod/commands/packet/SearchC2SPacket.kt @@ -0,0 +1,23 @@ +package com.github.quiltservertools.ledger.testmod.commands.packet + + +import com.github.quiltservertools.ledger.testmod.LedgerTest +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data class SearchC2SPacket(val query: String) : CustomPayload { + + override fun getId() = ID + + private fun write(buf: PacketByteBuf?) { + buf?.writeString(query) + } + + companion object { + val ID: CustomPayload.Id = CustomPayload.Id(LedgerTest.SEARCH) + val CODEC: PacketCodec = + CustomPayload.codecOf(SearchC2SPacket::write) { TODO() } + } + +}