Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
- cloud-sponge7: integration for [Sponge API](https://spongepowered.org) v7
- cloud-bungee: integration for Bungeecord API
- cloud-cloudburst: integration for cloudburst
- cloud-waterdog: integration for [WaterdogPE](https://waterdog.dev) API
- cloud-minecraft-extras: optional extras using [adventure](https://github.com/KyoriPowered/adventure) API
- cloud-minecraft-bom: [bill of materials](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies) for cloud-minecraft dependencies
11 changes: 11 additions & 0 deletions cloud-waterdog/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
plugins {
id("conventions.base")
id("conventions.publishing")
}

dependencies {
api(libs.cloud.core)
compileOnly(libs.waterdog) {
isTransitive = false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package org.incendo.cloud.waterdog;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.caption.Caption;

/**
* WaterdogPE specific {@link Caption caption keys}
*
* @since 2.0.0
*/
public final class WaterdogCaptionKeys {

private static final Collection<Caption> RECOGNIZED_CAPTIONS = new LinkedList<>();

/**
* Variables: {@code <input>}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_PLAYER = of("argument.parse.failure.player");

/**
* Variables: {@code <input>}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_SERVER = of("argument.parse.failure.server");

private WaterdogCaptionKeys() {
}

private static @NonNull Caption of(final @NonNull String key) {
final Caption caption = Caption.of(key);
RECOGNIZED_CAPTIONS.add(caption);
return caption;
}

/**
* Returns an immutable collection containing all standard caption keys.
*
* @return immutable collection of keys
*/
public static @NonNull Collection<@NonNull Caption> waterdogCaptionKeys() {
return Collections.unmodifiableCollection(RECOGNIZED_CAPTIONS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package org.incendo.cloud.waterdog;

import dev.waterdog.waterdogpe.command.Command;
import dev.waterdog.waterdogpe.command.CommandSender;
import dev.waterdog.waterdogpe.command.CommandSettings;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.incendo.cloud.component.CommandComponent;

final class WaterdogCommand<C> extends Command {

private final WaterdogCommandManager<C> manager;
private final CommandComponent<C> command;

WaterdogCommand(
final org.incendo.cloud.@NonNull Command<C> cloudCommand,
final @NonNull CommandComponent<C> command,
final @NonNull WaterdogCommandManager<C> manager
) {
super(
command.name(),
CommandSettings.builder()
.setAliases(command.alternativeAliases().toArray(new String[0]))
.setDescription(cloudCommand.commandDescription().description().textDescription())
.build()
);
this.command = command;
this.manager = manager;
}

@Override
public boolean onExecute(final CommandSender sender, final @Nullable String alias, final String[] args) {
/* Join input */
final StringBuilder builder = new StringBuilder(this.command.name());
for (final String arg : args) {
builder.append(" ").append(arg);
}
final C cloudSender = this.manager.senderMapper().map(sender);
this.manager.commandExecutor().executeCommand(cloudSender, builder.toString());
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package org.incendo.cloud.waterdog;

import dev.waterdog.waterdogpe.command.CommandSender;
import dev.waterdog.waterdogpe.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.SenderMapper;
import org.incendo.cloud.SenderMapperHolder;
import org.incendo.cloud.caption.CaptionProvider;
import org.incendo.cloud.execution.ExecutionCoordinator;
import org.incendo.cloud.waterdog.parser.PlayerParser;
import org.incendo.cloud.waterdog.parser.ServerParser;

/**
* Command manager for the WaterdogPE platform
*
* @param <C> Command sender type
* @since 2.0.0
*/
public class WaterdogCommandManager<C> extends CommandManager<C> implements SenderMapperHolder<CommandSender, C> {

/**
* Default caption for {@link WaterdogCaptionKeys#ARGUMENT_PARSE_FAILURE_PLAYER}
*/
public static final String ARGUMENT_PARSE_FAILURE_PLAYER = "'<input>' is not a valid player";

/**
* Default caption for {@link WaterdogCaptionKeys#ARGUMENT_PARSE_FAILURE_SERVER}
*/
public static final String ARGUMENT_PARSE_FAILURE_SERVER = "'<input>' is not a valid server";

/**
* WaterdogPE color code used to highlight error messages sent to command senders.
*/
private static final String RED_COLOR_CODE = "§c";

private final Plugin owningPlugin;
private final SenderMapper<CommandSender, C> senderMapper;

/**
* Construct a new WaterdogPE command manager
*
* @param owningPlugin Plugin that is constructing the manager
* @param commandExecutionCoordinator Coordinator provider
* @param senderMapper Function that maps {@link CommandSender} to the command sender type
*/
@SuppressWarnings("this-escape")
public WaterdogCommandManager(
final @NonNull Plugin owningPlugin,
final @NonNull ExecutionCoordinator<C> commandExecutionCoordinator,
final @NonNull SenderMapper<CommandSender, C> senderMapper
) {
super(commandExecutionCoordinator, new WaterdogPluginRegistrationHandler<>());
((WaterdogPluginRegistrationHandler<C>) this.commandRegistrationHandler()).initialize(this);
this.owningPlugin = owningPlugin;
this.senderMapper = senderMapper;

/* Register WaterdogPE Preprocessor */
this.registerCommandPreProcessor(new WaterdogCommandPreprocessor<>(this));

/* Register WaterdogPE Parsers */
this.parserRegistry()
.registerParser(PlayerParser.playerParser())
.registerParser(ServerParser.serverParser());

/* Register default captions */
this.captionRegistry()
.registerProvider(CaptionProvider.<C>constantProvider()
.putCaption(WaterdogCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER, ARGUMENT_PARSE_FAILURE_PLAYER)
.putCaption(WaterdogCaptionKeys.ARGUMENT_PARSE_FAILURE_SERVER, ARGUMENT_PARSE_FAILURE_SERVER)
.build());

this.registerDefaultExceptionHandlers();
}

@Override
public final boolean hasPermission(
final @NonNull C sender,
final @NonNull String permission
) {
if (permission.isEmpty()) {
return true;
}
return this.senderMapper.reverse(sender).hasPermission(permission);
}

/**
* Returns the owning plugin.
*
* @return owning plugin
*/
public @NonNull Plugin owningPlugin() {
return this.owningPlugin;
}

private void registerDefaultExceptionHandlers() {
this.registerDefaultExceptionHandlers(
triplet -> {
final CommandSender commandSender = this.senderMapper.reverse(triplet.first().sender());
final String message = triplet.first().formatCaption(triplet.second(), triplet.third());
commandSender.sendMessage(RED_COLOR_CODE + message);
},
pair -> this.owningPlugin.getLogger().error(pair.first(), pair.second())
);
}

@Override
public final @NonNull SenderMapper<CommandSender, C> senderMapper() {
return this.senderMapper;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package org.incendo.cloud.waterdog;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.execution.preprocessor.CommandPreprocessingContext;
import org.incendo.cloud.execution.preprocessor.CommandPreprocessor;

/**
* Command preprocessor which decorates incoming {@link org.incendo.cloud.context.CommandContext}
* with WaterdogPE specific objects
*
* @param <C> Command sender type
* @since 2.0.0
*/
final class WaterdogCommandPreprocessor<C> implements CommandPreprocessor<C> {

private final WaterdogCommandManager<C> mgr;

/**
* The WaterdogPE Command Preprocessor for storing WaterdogPE-specific contexts in the command contexts
*
* @param mgr The WaterdogCommandManager
*/
WaterdogCommandPreprocessor(final @NonNull WaterdogCommandManager<C> mgr) {
this.mgr = mgr;
}

@Override
public void accept(final @NonNull CommandPreprocessingContext<C> context) {
context.commandContext().store(WaterdogContextKeys.PROXY_SERVER_KEY, this.mgr.owningPlugin().getProxy());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package org.incendo.cloud.waterdog;

import dev.waterdog.waterdogpe.ProxyServer;
import io.leangen.geantyref.TypeToken;
import org.incendo.cloud.key.CloudKey;

/**
* WaterdogPE related {@link org.incendo.cloud.context.CommandContext} keys
*
* @since 2.0.0
*/
public final class WaterdogContextKeys {

/**
* The {@link ProxyServer} instance is stored in the {@link org.incendo.cloud.context.CommandContext}
* in {@link WaterdogCommandPreprocessor}
*/
public static final CloudKey<ProxyServer> PROXY_SERVER_KEY = CloudKey.of(
"ProxyServer",
TypeToken.get(ProxyServer.class)
);

private WaterdogContextKeys() {
}
}
Loading