Skip to content

Commit

Permalink
Service abstraction upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
BomBardyGamer committed Aug 15, 2023
1 parent 1aa2d5e commit c4192fa
Show file tree
Hide file tree
Showing 27 changed files with 491 additions and 581 deletions.
16 changes: 11 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ dependencies {
implementation("ch.qos.logback:logback-classic:1.4.8")

// APIs
api("dev.emortal.api:module-system:16353c8")
api("dev.emortal.api:module-system:e69aa43")
api("dev.emortal.api:agones-sdk:1.0.7")
api("dev.emortal.api:common-proto-sdk:da7a48c")
api("dev.emortal.api:live-config-parser:a9fc46f")
api("dev.emortal.api:kurushimi-sdk:82c14c3")
api("dev.emortal.api:common-proto-sdk:4135280")
api("dev.emortal.api:live-config-parser:89c56a9")

api("io.kubernetes:client-java:18.0.0")

Expand All @@ -42,10 +41,17 @@ dependencies {

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(20))
}
}

tasks.compileJava {
options.compilerArgs.addAll(listOf(
"--release", "20",
"--enable-preview"
))
}

publishing {
repositories {
maven {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dev.emortal.api.modules.Module;
import dev.emortal.api.modules.ModuleData;
import dev.emortal.api.modules.ModuleEnvironment;
import dev.emortal.api.modules.env.ModuleEnvironment;
import net.minestom.server.MinecraftServer;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import dev.emortal.api.message.messagehandler.ChatMessageCreatedMessage;
import dev.emortal.api.model.messagehandler.ChatMessage;
import dev.emortal.api.modules.ModuleData;
import dev.emortal.api.modules.ModuleEnvironment;
import dev.emortal.api.modules.env.ModuleEnvironment;
import dev.emortal.api.utils.kafka.FriendlyKafkaProducer;
import dev.emortal.minestom.core.module.MinestomModule;
import dev.emortal.minestom.core.module.messaging.MessagingModule;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package dev.emortal.minestom.core.module.core;

import dev.emortal.api.modules.ModuleData;
import dev.emortal.api.modules.ModuleEnvironment;
import dev.emortal.api.modules.env.ModuleEnvironment;
import dev.emortal.api.service.badges.BadgeService;
import dev.emortal.api.utils.GrpcStubCollection;
import dev.emortal.api.utils.resolvers.PlayerResolver;
import dev.emortal.minestom.core.module.MinestomModule;
import dev.emortal.minestom.core.module.core.badge.BadgeCommand;
import dev.emortal.minestom.core.module.core.performance.PerformanceCommand;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ModuleData(name = "core", required = false)
public final class CoreModule extends MinestomModule {
private static final Logger LOGGER = LoggerFactory.getLogger(CoreModule.class);

public CoreModule(@NotNull ModuleEnvironment environment) {
super(environment);
Expand All @@ -26,9 +32,15 @@ public boolean onLoad() {
return new PlayerResolver.CachedMcPlayer(player.getUuid(), player.getUsername(), player.isOnline());
});

var commandManager = MinecraftServer.getCommandManager();
CommandManager commandManager = MinecraftServer.getCommandManager();
commandManager.register(new PerformanceCommand(this.eventNode));
commandManager.register(new BadgeCommand());

BadgeService badgeService = GrpcStubCollection.getBadgeManagerService().orElse(null);
if (badgeService != null) {
commandManager.register(new BadgeCommand(badgeService));
} else {
LOGGER.warn("Badge service unavailable. Badges will not work.");
}

return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package dev.emortal.minestom.core.module.core.badge;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.rpc.Status;
import dev.emortal.api.grpc.badge.BadgeManagerGrpc;
import dev.emortal.api.grpc.badge.BadgeManagerProto;
import dev.emortal.api.grpc.mcplayer.McPlayerProto;
import dev.emortal.api.model.mcplayer.McPlayer;
import dev.emortal.api.utils.GrpcStubCollection;
import dev.emortal.minestom.core.utils.command.ExtraConditions;
import dev.emortal.api.service.badges.AddBadgeToPlayerResult;
import dev.emortal.api.service.badges.BadgeService;
import dev.emortal.api.service.badges.RemoveBadgeFromPlayerResult;
import dev.emortal.api.service.mcplayer.McPlayerService;
import dev.emortal.minestom.core.utils.command.argument.ArgumentBadge;
import dev.emortal.minestom.core.utils.command.argument.ArgumentMcPlayer;
import io.grpc.protobuf.StatusProto;
import io.grpc.StatusRuntimeException;
import net.kyori.adventure.text.Component;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
Expand All @@ -22,123 +18,69 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import java.util.UUID;
import java.util.function.Supplier;

public final class BadgeAdminSubcommand extends Command {
final class BadgeAdminSubcommand extends Command {
private static final Logger LOGGER = LoggerFactory.getLogger(BadgeAdminSubcommand.class);

private final BadgeManagerGrpc.BadgeManagerFutureStub badgeManager;
private final BadgeService badgeService;

public BadgeAdminSubcommand(@NotNull BadgeManagerGrpc.BadgeManagerFutureStub badgeManager) {
BadgeAdminSubcommand(@NotNull BadgeService badgeService, @NotNull McPlayerService mcPlayerService) {
super("admin");
this.badgeManager = badgeManager;
this.badgeService = badgeService;

this.setCondition(ExtraConditions.hasPermission("command.badge.admin"));
this.setCondition((sender, $) -> sender.hasPermission("command.badge.admin"));

var addArgument = new ArgumentLiteral("add");
var removeArgument = new ArgumentLiteral("remove");
var playerArgument = ArgumentMcPlayer.create("player",
GrpcStubCollection.getPlayerService().orElse(null),
McPlayerProto.SearchPlayersByUsernameRequest.FilterMethod.NONE
);
var badgeArgument = ArgumentBadge.create(badgeManager, "badge", false);
var playerArgument = ArgumentMcPlayer.create("player", mcPlayerService, McPlayerProto.SearchPlayersByUsernameRequest.FilterMethod.NONE);
var badgeArgument = ArgumentBadge.create(badgeService, "badge", false);

this.addSyntax(this::executeAddBadgeToPlayer, addArgument, playerArgument, badgeArgument);
this.addSyntax(this::executeRemoveBadgeFromPlayer, removeArgument, playerArgument, badgeArgument);
}

private void executeAddBadgeToPlayer(CommandSender sender, CommandContext context) {
CompletableFuture<McPlayer> playerFuture = context.get("player");
private void executeAddBadgeToPlayer(@NotNull CommandSender sender, @NotNull CommandContext context) {
McPlayer player = getPlayer(context);
String badgeId = context.get("badge");

playerFuture.thenAccept(mcPlayer -> {
var request = BadgeManagerProto.AddBadgeToPlayerRequest.newBuilder()
.setBadgeId(badgeId)
.setPlayerId(mcPlayer.getId())
.build();

Futures.addCallback(this.badgeManager.addBadgeToPlayer(request), new AddBadgeToPlayerCallback(sender), ForkJoinPool.commonPool());
});
}

private record AddBadgeToPlayerCallback(@NotNull CommandSender sender) implements FutureCallback<BadgeManagerProto.AddBadgeToPlayerResponse> {

@Override
public void onSuccess(@NotNull BadgeManagerProto.AddBadgeToPlayerResponse result) {
this.sender.sendMessage(Component.text("Added badge to player"));
AddBadgeToPlayerResult result;
try {
result = this.badgeService.addBadgeToPlayer(UUID.fromString(player.getId()), badgeId);
} catch (StatusRuntimeException exception) {
LOGGER.error("Failed to add badge to player", exception);
sender.sendMessage(Component.text("Failed to add badge to player"));
return;
}

@Override
public void onFailure(@NotNull Throwable throwable) {
Status status = StatusProto.fromThrowable(throwable);
if (status == null || status.getDetailsCount() == 0) {
LOGGER.error("Failed to add badge to player", throwable);
return;
}

final BadgeManagerProto.AddBadgeToPlayerErrorResponse response;
try {
response = status.getDetails(0).unpack(BadgeManagerProto.AddBadgeToPlayerErrorResponse.class);
} catch (InvalidProtocolBufferException exception) {
LOGGER.error("Failed to add badge to player", exception);
return;
}

switch (response.getReason()) {
case PLAYER_ALREADY_HAS_BADGE -> this.sender.sendMessage(Component.text("Player already has that badge"));
default -> {
LOGGER.error("Failed to add badge to player", throwable);
this.sender.sendMessage(Component.text("Failed to add badge to player"));
}
}
switch (result) {
case SUCCESS -> sender.sendMessage(Component.text("Added badge to player"));
case PLAYER_ALREADY_HAS_BADGE -> sender.sendMessage(Component.text("Player already has that badge"));
}
}

private void executeRemoveBadgeFromPlayer(CommandSender sender, CommandContext context) {
CompletableFuture<McPlayer> playerFuture = context.get("player");
private void executeRemoveBadgeFromPlayer(@NotNull CommandSender sender, @NotNull CommandContext context) {
McPlayer player = getPlayer(context);
String badgeId = context.get("badge");

playerFuture.thenAccept(mcPlayer -> {
var request = BadgeManagerProto.RemoveBadgeFromPlayerRequest.newBuilder()
.setBadgeId(badgeId)
.setPlayerId(mcPlayer.getId())
.build();

Futures.addCallback(this.badgeManager.removeBadgeFromPlayer(request), new RemoveBadgeFromPlayerCallback(sender), ForkJoinPool.commonPool());
});
}

private record RemoveBadgeFromPlayerCallback(@NotNull CommandSender sender) implements FutureCallback<BadgeManagerProto.RemoveBadgeFromPlayerResponse> {

@Override
public void onSuccess(@NotNull BadgeManagerProto.RemoveBadgeFromPlayerResponse result) {
this.sender.sendMessage(Component.text("Removed badge from player"));
RemoveBadgeFromPlayerResult result;
try {
result = this.badgeService.removeBadgeFromPlayer(UUID.fromString(player.getId()), badgeId);
} catch (StatusRuntimeException exception) {
LOGGER.error("Failed to remove badge from player", exception);
sender.sendMessage(Component.text("Failed to remove badge from player"));
return;
}

@Override
public void onFailure(@NotNull Throwable throwable) {
Status status = StatusProto.fromThrowable(throwable);
if (status == null || status.getDetailsCount() == 0) {
LOGGER.error("Failed to remove badge from player", throwable);
return;
}

final BadgeManagerProto.RemoveBadgeFromPlayerErrorResponse response;
try {
response = status.getDetails(0).unpack(BadgeManagerProto.RemoveBadgeFromPlayerErrorResponse.class);
} catch (InvalidProtocolBufferException exception) {
LOGGER.error("Failed to remove badge from player", exception);
return;
}

switch (response.getReason()) {
case PLAYER_DOESNT_HAVE_BADGE -> this.sender.sendMessage(Component.text("Player doesn't have that badge"));
default -> {
LOGGER.error("Failed to remove badge from player", throwable);
this.sender.sendMessage(Component.text("Failed to remove badge from player"));
}
}
switch (result) {
case SUCCESS -> sender.sendMessage(Component.text("Removed badge from player"));
case PLAYER_DOESNT_HAVE_BADGE -> sender.sendMessage(Component.text("Player doesn't have that badge"));
}
}

private static @NotNull McPlayer getPlayer(@NotNull CommandContext context) {
Supplier<McPlayer> supplier = context.get("player");
return supplier.get();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package dev.emortal.minestom.core.module.core.badge;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.rpc.Status;
import dev.emortal.api.grpc.badge.BadgeManagerGrpc;
import dev.emortal.api.grpc.badge.BadgeManagerProto;
import dev.emortal.api.service.badges.BadgeService;
import dev.emortal.api.service.badges.SetActiveBadgeResult;
import dev.emortal.api.service.mcplayer.McPlayerService;
import dev.emortal.api.utils.GrpcStubCollection;
import dev.emortal.minestom.core.utils.command.argument.ArgumentBadge;
import io.grpc.protobuf.StatusProto;
import io.grpc.StatusRuntimeException;
import net.kyori.adventure.text.Component;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
Expand All @@ -20,69 +17,46 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ForkJoinPool;

public final class BadgeCommand extends Command {
private static final Logger LOGGER = LoggerFactory.getLogger(BadgeCommand.class);

private final BadgeManagerGrpc.BadgeManagerFutureStub badgeManager = GrpcStubCollection.getBadgeManagerService().orElse(null);
private final BadgeService badgeService;

public BadgeCommand() {
public BadgeCommand(@NotNull BadgeService badgeService) {
super("badge");
this.badgeService = badgeService;

this.setCondition(Conditions::playerOnly);
this.setDefaultExecutor((sender, context) -> new BadgeGui((Player) sender));
this.setDefaultExecutor((sender, context) -> new BadgeGui((Player) sender, badgeService));

var setArgument = new ArgumentLiteral("set");
var badgeArgument = ArgumentBadge.create(this.badgeManager, "badge", true);

var badgeArgument = ArgumentBadge.create(this.badgeService, "badge", true);
this.addConditionalSyntax(Conditions::playerOnly, this::executeSetCurrentBadge, setArgument, badgeArgument);
this.addSubcommand(new BadgeAdminSubcommand(this.badgeManager));

McPlayerService mcPlayerService = GrpcStubCollection.getPlayerService().orElse(null);
if (mcPlayerService != null) {
this.addSubcommand(new BadgeAdminSubcommand(this.badgeService, mcPlayerService));
} else {
LOGGER.warn("MC player service unavailable. Badge admin command will not be registered.");
}
}

private void executeSetCurrentBadge(CommandSender sender, CommandContext context) {
String badgeId = context.get("badge");
Player player = (Player) sender;

var request = BadgeManagerProto.SetActivePlayerBadgeRequest.newBuilder()
.setBadgeId(badgeId)
.setPlayerId(player.getUuid().toString())
.build();

Futures.addCallback(this.badgeManager.setActivePlayerBadge(request), new SetCurrentBadgeCallback(sender, badgeId), ForkJoinPool.commonPool());
}

private record SetCurrentBadgeCallback(@NotNull CommandSender sender,
@NotNull String badgeId) implements FutureCallback<BadgeManagerProto.SetActivePlayerBadgeResponse> {

@Override
public void onSuccess(@NotNull BadgeManagerProto.SetActivePlayerBadgeResponse result) {
this.sender.sendMessage(Component.text("Set your badge to " + this.badgeId));
SetActiveBadgeResult result;
try {
result = this.badgeService.setActiveBadge(player.getUuid(), badgeId);
} catch (StatusRuntimeException exception) {
LOGGER.error("Failed to set badge", exception);
sender.sendMessage(Component.text("Failed to set badge"));
return;
}

@Override
public void onFailure(@NotNull Throwable throwable) {
Status status = StatusProto.fromThrowable(throwable);
if (status == null || status.getDetailsCount() == 0) {
LOGGER.error("Failed to set badge", throwable);
return;
}

final BadgeManagerProto.SetActivePlayerBadgeErrorResponse response;
try {
response = status.getDetails(0).unpack(BadgeManagerProto.SetActivePlayerBadgeErrorResponse.class);
} catch (InvalidProtocolBufferException exception) {
LOGGER.error("Failed to set badge", throwable);
return;
}

switch (response.getReason()) {
case PLAYER_DOESNT_HAVE_BADGE -> this.sender.sendMessage(Component.text("You don't have that badge"));
default -> {
LOGGER.error("Failed to set badge", throwable);
this.sender.sendMessage(Component.text("Failed to set badge"));
}
}
switch (result) {
case SUCCESS -> sender.sendMessage(Component.text("Set your badge to " + badgeId));
case PLAYER_DOESNT_HAVE_BADGE -> sender.sendMessage(Component.text("You don't have that badge"));
}
}
}
Loading

0 comments on commit c4192fa

Please sign in to comment.