Skip to content

Commit

Permalink
Merge branch '1.20' into PC-1059
Browse files Browse the repository at this point in the history
# Conflicts:
#	platform/fabric/src/main/kotlin/br/com/gamemods/minecity/fabric/MineCityFabric.kt
  • Loading branch information
LoboMetalurgico committed Feb 6, 2024
2 parents c3a5f80 + bb1e62e commit f9d0379
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: Artifacts
path: build/libs/
path: platform/fabric/build/libs/
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package br.com.gamemods.minecity.core.helpers

import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf

/**
* Checks if an object **is** an instance of **ANY** of the classes given.
* @param types A list of [KClass] that will be checked.
*
* The following code examples are equivalent.
* ```kt
* obj is TypeA || obj is TypeB
* obj.isInstanceOfAny(TypeA::class, TypeB::class)
* ```
* @author alikindsys
*/
fun Any.isInstanceOfAny(vararg types: KClass<*>): Boolean {
// Short-circuiting on a list based on an OR operation.
for (cls in types) {
// ⊤ OR { ⊥,⊤ } = ⊤
// { ⊥,⊤ } OR ⊥ = { ⊥,⊤ }
if (this::class.isSubclassOf(cls)) return true
}
// ⊥ OR ⊥ = ⊥
return false
}

/**
* Checks if an object **is NOT** an instance of **ALL** the classes given.
* @param types A list of [KClass] that will be .
*
* The following code examples are equivalent.
* ```kt
* obj !is TypeA && obj !is TypeB
* obj.isInstanceOfNone(TypeA::class, TypeB::class)
* ```
* @author alikindsys
*/
fun Any.isInstanceOfNone(vararg types: KClass<*>): Boolean {
// !(P OR Q) = (!P AND !Q)
return !this.isInstanceOfAny(*types)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import br.com.gamemods.minecity.fabric.server.MineCityFabricServer
import br.com.gamemods.minecity.fabric.service.FabricNamedPlayerService
import br.com.gamemods.minecity.fabric.service.FabricWorldService
import br.com.gamemods.minecity.fabric.service.permission.FabricBuildClaimPermission
import br.com.gamemods.minecity.fabric.service.permission.FabricButtonClaimPermission
import br.com.gamemods.minecity.fabric.service.permission.FabricDoorClaimPermission
import br.com.gamemods.minecity.fabric.wrapper.FabricBlockPosWrapper
import br.com.gamemods.minecity.fabric.wrapper.FabricChunkPosWrapper
Expand Down Expand Up @@ -82,6 +83,7 @@ object MineCityFabric : ModInitializer, MineCityPlatform {
private fun registerPermissions() {
core.permission += FabricDoorClaimPermission()
core.permission += FabricBuildClaimPermission()
core.permission += FabricButtonClaimPermission()
}

@ServerSideOnly
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package br.com.gamemods.minecity.fabric.helpers

import br.com.gamemods.minecity.api.claim.Claim
import br.com.gamemods.minecity.api.id.ClaimPermissionId
import br.com.gamemods.minecity.api.serializer.UniqueId
import net.minecraft.util.ActionResult

/**
* Checks if a [UniqueId] has a given [ClaimPermissionId] inside a [Claim].
*
* *Note*: This is platform-dependent code since each loader treats [ActionResult]s differently.
* This code is **expected to work with Fabric API**'s event system.
* @param claim The claim being checked. Usually the one the player is located at.
* @param permissionId The [ClaimPermissionId] of the permission. E.g. [ClaimPermissionId.BUILD].
* @return An [ActionResult.PASS] if the player **has** the permission. An [ActionResult.FAIL] if the player **doesn't** have the permission.
* @see [ClaimPermissionId]
* @author alikindsys
*/
fun UniqueId.hasPermissionIn(claim: Claim, permissionId: ClaimPermissionId): ActionResult {
return if (claim.hasPermission(this, permissionId)) {
ActionResult.PASS
} else {
ActionResult.FAIL
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package br.com.gamemods.minecity.fabric.helpers

import net.minecraft.block.BlockState
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.world.World

/**
* Gets a [BlockState] from a [BlockHitResult] by accessing a [World]
*
* You *should* have a reference to a world on which this [BlockHitResult] was queried.
*
* **Trivial**: This is a mere convenience extension function.
* @param world The world being queried.
* @author alikindsys
*/
fun BlockHitResult.blockStateBy(world: World) : BlockState {
return world.getBlockState(this.blockPos)
}

/**
* Gets a [BlockEntity] from a [BlockHitResult] by accessing a [World]
*
* You *should* have a reference to a world on which this [BlockHitResult] was queried.
*
* **Trivial**: This is a mere convenience extension function.
* @param world The world being queried.
* @author alikindsys
*/
fun BlockHitResult.blockEntityBy(world: World) : BlockEntity? {
return world.getBlockEntity(this.blockPos)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package br.com.gamemods.minecity.fabric.service.permission

import br.com.gamemods.minecity.api.MineCity
import br.com.gamemods.minecity.api.annotation.internal.InternalMineCityApi
import br.com.gamemods.minecity.api.id.ClaimPermissionId
import br.com.gamemods.minecity.api.service.permission.ClaimPermission
import br.com.gamemods.minecity.core.helpers.isInstanceOfNone
import br.com.gamemods.minecity.fabric.helpers.blockStateBy
import br.com.gamemods.minecity.fabric.helpers.hasPermissionIn
import br.com.gamemods.minecity.fabric.service.claim.FabricClaimService.Companion.get
import net.fabricmc.fabric.api.event.player.UseBlockCallback
import net.kyori.adventure.text.Component
import net.minecraft.block.ButtonBlock
import net.minecraft.block.DaylightDetectorBlock
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.hit.HitResult
import net.minecraft.world.World

@InternalMineCityApi
class FabricButtonClaimPermission: ClaimPermission(
id = ClaimPermissionId.BUTTONS,
name = Component.text("Buttons"),
description = Component.text("Allows the player to trigger buttons, daylight sensors, switches and more.")
) {
override fun onRegister() {
UseBlockCallback.EVENT.register(OnUseBlock())
}

private inner class OnUseBlock() : UseBlockCallback {
override fun interact( player: PlayerEntity, world: World, hand: Hand, hitResult: BlockHitResult): ActionResult {
if (world.isClient) {
return ActionResult.PASS
}

if (hitResult.type != HitResult.Type.BLOCK) {
return ActionResult.PASS
}

val hitPos = hitResult.blockPos
val block = hitResult.blockStateBy(world).block

if (block.isInstanceOfNone(ButtonBlock::class, LeverBlock::class, DaylightDetectorBlock::class)) {
return ActionResult.PASS
}

val claim = MineCity.claims[world, hitPos] ?: return ActionResult.PASS

return player.uuid.hasPermissionIn(claim, permissionId = ClaimPermissionId.BUTTONS)
}
}
}



0 comments on commit f9d0379

Please sign in to comment.