Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot resolve parser with generics when registering via geantyref. #453

Closed
solonovamax opened this issue Jun 23, 2023 · 0 comments · Fixed by #454
Closed

Cannot resolve parser with generics when registering via geantyref. #453

solonovamax opened this issue Jun 23, 2023 · 0 comments · Fixed by #454

Comments

@solonovamax
Copy link
Contributor

solonovamax commented Jun 23, 2023

See leangen/geantyref#17 for more info.

Currently, two TypeTokens which are equal, can have different hashCodes. This makes it so that HashMap does not behave as expected. This causes a problem with the parser registry, where if a parser is registered using TypeToken.get(TypeFactory.parameterizedClass(Set::class.java, ItemStackPredicateArgument::class.java)), then it cannot be properly resolved.

Stack trace:

java.lang.RuntimeException: Could not execute entrypoint stage 'main' due to errors, provided by 'altoclef'!
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.lambda$invoke0$0(EntrypointUtils.java:51)
	at net.fabricmc.loader.impl.util.ExceptionUtil.gatherExceptions(ExceptionUtil.java:33)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke0(EntrypointUtils.java:49)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke(EntrypointUtils.java:35)
	at net.fabricmc.loader.impl.game.minecraft.Hooks.startClient(Hooks.java:52)
	at net.minecraft.client.MinecraftClient.<init>(MinecraftClient.java:520)
	at net.minecraft.client.main.Main.main(Main.java:179)
	at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:462)
	at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
	at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
	at net.fabricmc.devlaunchinjector.Main.main(Main.java:86)
Caused by: java.lang.IllegalArgumentException: Parameter 'arg1' in method 'call' has parser 'java.util.Set<? extends net.minecraft.command.argument.ItemPredicateArgumentType$ItemStackPredicateArgument>' but no parser exists for that type
	at cloud.commandframework.annotations.AnnotationParser.lambda$buildArgument$7(AnnotationParser.java:720)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at cloud.commandframework.annotations.AnnotationParser.buildArgument(AnnotationParser.java:719)
	at cloud.commandframework.annotations.AnnotationParser.construct(AnnotationParser.java:570)
	at cloud.commandframework.annotations.AnnotationParser.parse(AnnotationParser.java:435)
	at gay.solonovamax.altoclef.AltoClef.initializeCommands(AltoClef.kt:398)
	at gay.solonovamax.altoclef.AltoClef.onInitialize(AltoClef.kt:229)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke0(EntrypointUtils.java:47)
	... 8 more

Code:

fun initializeCommands() {
    val itemStackPredicateType = object : TypeToken<ItemStackPredicateArgument>() {}
    val itemStackPredicateSetType = TypeToken.get(TypeFactory.parameterizedClass(Set::class.java, ItemStackPredicateArgument::class.java))

    manager.parserRegistry().registerParserSupplier(itemStackPredicateType) {
        FabricArgumentParsers.contextual(ItemPredicateArgumentType::itemPredicate)
    }
    manager.parserRegistry().registerParserSupplier(itemStackPredicateSetType) { parameters ->
        SetArgument.SetParser(parameters, itemStackPredicateType, manager)
    }
val manager = FabricClientCommandManager(
//        AsyncCommandCoordinator.builder<ClientCommand>()
//            .withAsynchronousParsing()
//            .withExecutor(scheduledThreadPool)
//            .build(),
        CommandExecutionCoordinator.simpleCoordinator(),
        ::ClientCommand,
        ClientCommand::source
    )

    MinecraftExceptionHandler<ClientCommand>()
        .withDefaultHandlers()
        .withDecorator { message: Component -> messagePrefix.append(message) }
        .apply(manager, AudienceProvider.nativeAudience<ClientCommand>())

    val annotationParser = AnnotationParser<ClientCommand>(manager) { SimpleCommandMeta.empty() }.apply {
        installCoroutineSupport()
    }

    annotationParser.parse(
        UtilCommands()
    )
}



data class ClientCommand(val source: FabricClientCommandSource) : ForwardingAudience.Single {
    private val audience: Audience = FabricClientAudiences.of().audience()

    override fun audience(): Audience = audience
}



@CommandMethod("altoclef")
class UtilCommands {
    @CommandMethod("deposit <items>")
    @CommandDescription("Deposit ALL of our items")
    fun deposit(
        command: ClientCommand,
        @Argument("items")
        items: Set<ItemPredicateArgumentType.ItemStackPredicateArgument>, // TODO: we need a custom parser for this (also probably a wrapper class)
    ) {
        val validItems = Registries.ITEM.filter { item ->
            items.any { it.test(item.defaultStack) }
        }
        val itemTarget = ItemTarget(validItems.toTypedArray())
        itemTarget.infinite()

        runUserTask(StoreInAnyContainerTask(false, itemTarget))
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants