Skip to content

Commit

Permalink
Merge pull request #220 from KevinDaGame/Feat/fabric-implementation
Browse files Browse the repository at this point in the history
VoxelSniper: The journey through the Fabric of time. Part three: The ability to snipe a single block (and more)
  • Loading branch information
KevinDaGame authored Oct 30, 2023
2 parents 02471f3 + 1a9addf commit a379c29
Show file tree
Hide file tree
Showing 23 changed files with 966 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ output/
test.sh
/bin/
/VoxelSniperSpigot/run/
/VoxelSniperFabric/run/
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public enum Environment {
SPIGOT,
FORGE,
FABRIC,
}
4 changes: 2 additions & 2 deletions VoxelSniperFabric/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
version = findProperty("voxelsniper.version")
group = "com.github.kevdadev"

description='VoxelSniperFabric'
description = 'VoxelSniperFabric'

ext {
platform = "fabric-alpha-" + getProperty("voxelsniper.fabric.minecraft_version")
Expand Down Expand Up @@ -68,7 +68,7 @@ java {

jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
rename { "${it}_${project.archivesBaseName}" }
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.github.kevdadev.voxelsniperfabric

import com.github.kevdadev.voxelsniperfabric.voxelsniperfabric.FabricPlayer
import com.github.kevindagame.command.VoxelCommand
import com.github.kevindagame.util.Messages
import com.github.kevindagame.voxelsniper.entity.player.IPlayer
import com.mojang.brigadier.Command
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.suggestion.SuggestionProvider
import com.mojang.brigadier.suggestion.Suggestions
import com.mojang.brigadier.suggestion.SuggestionsBuilder
import net.minecraft.server.command.ServerCommandSource
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.function.Predicate

class FabricCommandHandler(private val voxelCommand: VoxelCommand) :
Predicate<ServerCommandSource>,
SuggestionProvider<ServerCommandSource>,
Command<ServerCommandSource> {
override fun test(commandSource: ServerCommandSource): Boolean {
if (commandSource.isExecutedByPlayer) {
val p = commandSource.player ?: return false
val player: IPlayer = VoxelSniperFabric.instance.getPlayer(p)
return player.hasPermission(voxelCommand.permission)
}
return false
}

override fun getSuggestions(
context: CommandContext<ServerCommandSource>?,
builder: SuggestionsBuilder?
): CompletableFuture<Suggestions> {
val inputString = context!!.input
val input = inputString.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
this.voxelCommand.setActiveIdentifier(context.rootNode.name) // This is the root command.

this.voxelCommand.setActiveAlias(input[0]) // This is the alias that was executed.

if (context.source.isExecutedByPlayer) {
val p = VoxelSniperFabric.instance.getPlayer(context.source.player!!)
val args: Array<String> = getArguments(inputString)
val lastArg = args[args.size - 1]
// create string with all arguments, except the last one
val argString = inputString.substring(input[0].length + 1, inputString.length - lastArg.length)
val completions: List<String> = voxelCommand.doSuggestion(p, args)
completions.stream().filter(Predicate<String> { s: String ->
startsWithIgnoreCase(
lastArg,
s
)
}).forEach { s: String -> builder!!.suggest(argString + s) }
}

return builder!!.buildFuture()
}

private fun getArguments(inputString: String): Array<String> {
val input = inputString.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
return if (inputString.endsWith(" ")) {
val args = Arrays.copyOfRange(input, 1, input.size + 1)
args[args.size - 1] = ""
args
} else {
Arrays.copyOfRange(input, 1, input.size)
}
}

private fun startsWithIgnoreCase(prefix: String, s: String): Boolean {
return s.lowercase().startsWith(prefix.lowercase())
}

override fun run(context: CommandContext<ServerCommandSource>?): Int {
val inputString = context!!.input
val input = inputString.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
voxelCommand.activeIdentifier = context.nodes[0].node.name // This is the root command.

voxelCommand.activeAlias = input[0] // This is the alias that was executed.


if (context.source.isExecutedByPlayer) {
val p: IPlayer = VoxelSniperFabric.instance.getPlayer(context.source.player!!)
val args = getArguments(inputString)
voxelCommand.execute(p, args)
} else {
context.source.sendError(FabricPlayer.toNative(Messages.ONLY_PLAYERS_CAN_EXECUTE_COMMANDS.asComponent()))
}
return 0 // TODO figure out what we should return

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.github.kevdadev.voxelsniperfabric

import com.github.kevindagame.command.VoxelCommand
import com.github.kevindagame.command.VoxelCommandManager
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.arguments.StringArgumentType
import com.mojang.brigadier.builder.LiteralArgumentBuilder.literal
import com.mojang.brigadier.builder.RequiredArgumentBuilder.argument
import net.minecraft.server.command.ServerCommandSource

class FabricCommandManager : VoxelCommandManager() {
override fun registerCommand(command: VoxelCommand?) {
val identifiers: MutableList<String> = ArrayList(command!!.otherIdentifiers)
identifiers.add(command.identifier)
val handler = FabricCommandHandler(command)

for (id in identifiers) {
// TODO aliases?
argumentsMap[id] = command.registerTabCompletion()
dispatcher.register(
literal<ServerCommandSource?>(id).requires(handler).then(
argument<ServerCommandSource, String>("args", StringArgumentType.greedyString())
.suggests(handler).executes(handler)
)
)
}
}

companion object {
private lateinit var dispatcher: CommandDispatcher<ServerCommandSource>
fun initialize(dispatcher: CommandDispatcher<ServerCommandSource>) {
this.dispatcher = dispatcher
instance = FabricCommandManager()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.github.kevdadev.voxelsniperfabric

import com.github.kevdadev.voxelsniperfabric.voxelsniperfabric.FabricPlayer
import com.github.kevindagame.voxelsniper.entity.player.IPlayer
import net.fabricmc.fabric.api.networking.v1.PacketSender
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayNetworkHandler
import net.minecraft.server.network.ServerPlayerEntity
import java.util.*

object FabricPlayerManager : ServerPlayConnectionEvents.Join, ServerPlayConnectionEvents.Disconnect {

private val players: MutableMap<String, IPlayer> = mutableMapOf()
override fun onPlayReady(handler: ServerPlayNetworkHandler?, sender: PacketSender?, server: MinecraftServer?) {
val player = FabricPlayer(handler!!.player)
players[handler.player.uuid.toString()] = player
}

override fun onPlayDisconnect(handler: ServerPlayNetworkHandler?, server: MinecraftServer?) {
players.remove(handler!!.player.uuid.toString())
}

fun getPlayer(uuid: UUID): IPlayer? {
return players[uuid.toString()]
}

fun getPlayer(player: ServerPlayerEntity): IPlayer {
return players[player.uuid.toString()]!!
}

fun getPlayerByName(name: String): IPlayer? {
return players.values.firstOrNull { it.getName() == name }
}

fun getPlayers(): List<IPlayer> {
return players.values.toList()
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.github.kevdadev.voxelsniperfabric

import com.github.kevindagame.VoxelSniper
import com.github.kevindagame.snipe.Sniper
import com.github.kevindagame.voxelsniper.material.VoxelMaterial
import net.fabricmc.fabric.api.event.player.UseItemCallback
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.util.Hand
import net.minecraft.util.TypedActionResult
import net.minecraft.world.World
import java.util.*

class FabricVoxelSniperListener : UseItemCallback {
private val cooldown: MutableList<UUID> = mutableListOf()
override fun interact(player: PlayerEntity, world: World, hand: Hand): TypedActionResult<ItemStack> {
if (hand != Hand.MAIN_HAND) return TypedActionResult.fail(player.getStackInHand(hand))
val voxelPlayer = VoxelSniper.voxelsniper.getPlayer(player.uuid)!!
//check permission

if (cooldown.contains(player.uuid)) return TypedActionResult.fail(player.getStackInHand(hand))

try {
val sniper: Sniper = voxelPlayer.getSniper()
val action: Sniper.Action = getAction()
if (sniper.isEnabled && sniper.snipe(
action,
getItemStack(player, hand),
null,//TODO
null, //TODO
)
) {
// event.setCanceled(true) TODO
cooldown.add(player.uuid)
Thread {
try {
Thread.sleep(500)
} catch (e: InterruptedException) {
e.printStackTrace()
}
cooldown.remove(player.uuid)
}.start()
}
} catch (e: Exception) {
e.printStackTrace()
}

return TypedActionResult.pass(player.getStackInHand(hand))
}

private fun getItemStack(player: PlayerEntity, hand: Hand): VoxelMaterial? {
return VoxelSniper.voxelsniper.getMaterial("minecraft", "arrow")
}

private fun getAction(): Sniper.Action {
return Sniper.Action.RIGHT_CLICK_AIR
}


}

This file was deleted.

Loading

0 comments on commit a379c29

Please sign in to comment.