Skip to content

Commit

Permalink
impl sending messages and sounds.
Browse files Browse the repository at this point in the history
  • Loading branch information
fhnaumann committed Jan 30, 2024
1 parent 11908aa commit 833122e
Show file tree
Hide file tree
Showing 17 changed files with 198 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@

public class ChallengeManager {

private @NotNull Challenges plugin;

private @NotNull List<Rule> rules;
private @NotNull List<Goal> goals;

private GameState gameState;


public ChallengeManager() {

public ChallengeManager(@NotNull Challenges plugin) {
this.plugin = plugin;
}

public void start() {
Expand All @@ -32,6 +33,7 @@ public void start() {
throw new RuntimeException("No goals specified!");
}
gameState = GameState.RUNNING;

Challenges.getPlugin(Challenges.class).getLogger().info("starting");
}

Expand Down
28 changes: 5 additions & 23 deletions plugin/src/main/java/wand555/github/io/challenges/Challenges.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,14 @@ public void onEnable() {
* #8846f2 Only [Challenges]
* #c9526c Only [Punishment]
* #ffc54d Only [Rules]
* #3abeaa Only [Goals]
*
* #fceaff default text
* #64baaa highlight in text
*/
if(!getDataFolder().exists()) {
boolean created = getDataFolder().mkdir();
}



// Plugin startup logic
getCommand("test").setExecutor(this);
getCommand("load").setExecutor(this);

Expansion.Builder builder = Expansion.builder("challenges");
builder.globalPlaceholder("player", (argumentQueue, context) -> {
String playerName = argumentQueue.popOr("argument missing").value();
return Tag.selfClosingInserting(Component.text(playerName));
});
builder.audiencePlaceholder("player2", (audience, queue, ctx) -> {
return Tag.selfClosingInserting(Component.text(((Player) audience).getName()));
});

Expansion expansion = builder.build();
if(!expansion.registered()) {
expansion.register();
}

}

@Override
Expand All @@ -80,12 +60,14 @@ public void onDisable() {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(command.getName().equalsIgnoreCase("load")) {

File file = new File(getDataFolder(), "data.json");
if(!file.exists()) {

}
try {
ChallengeManager challengeManager = FileManager.readFromFile(file, this);
challengeManager.start();
} catch (LoadValidationException e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -119,10 +101,10 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
sender.sendMessage("ABC");
try {

ChallengeManager challengeManager = new ChallengeManager();
ChallengeManager challengeManager = new ChallengeManager(this);

JsonNode schemaRoot = new ObjectMapper().readTree(Challenges.class.getResource("/test-output-schema.json"));
MobGoal mobGoal = new MobGoal(new Context(this, new ResourceBundleContext(bundle, null), schemaRoot, challengeManager), new HashMap<>(Map.of(EntityType.PIG, new Collect(2))));
MobGoal mobGoal = new MobGoal(new Context(this, new ResourceBundleContext(bundle, null, null), schemaRoot, challengeManager), new HashMap<>(Map.of(EntityType.PIG, new Collect(2))));
Player player = (Player) sender;
mobGoal.openCollectedInv(player);
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,30 @@
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import wand555.github.io.challenges.utils.ResourceBundleHelper;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.logging.Level;

public class ComponentInterpolator {

public static Component interpolate(@NotNull Challenges plugin, @NotNull ResourceBundle bundle, @NotNull String key) {
return interpolate(plugin, bundle, key, Map.of());
}
@NotNull
public static Component interpolate(@NotNull Challenges plugin, @NotNull ResourceBundle bundle, @NotNull String key, @NotNull Map<String, Component> placeholders) {
Objects.requireNonNull(bundle);

Check failure on line 23 in plugin/src/main/java/wand555/github/io/challenges/ComponentInterpolator.java

View workflow job for this annotation

GitHub Actions / Maven Tests

wand555.github.io.goals.MobGoalTest ► testMobKillTracked

Failed test found in: plugin/target/surefire-reports/TEST-wand555.github.io.goals.MobGoalTest.xml Error: java.lang.NullPointerException
Raw output
java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:209)
	at wand555.github.io.challenges.ComponentInterpolator.interpolate(ComponentInterpolator.java:23)
	at wand555.github.io.challenges.goals.MobGoal.newEntityKilled(MobGoal.java:105)
	at wand555.github.io.challenges.goals.MobGoal.onMobDeath(MobGoal.java:83)
	at wand555.github.io.challenges.goals.MobGoal.onMobDeath(MobGoal.java:79)
	at wand555.github.io.goals.MobGoalTest.testMobKillTracked(MobGoalTest.java:79)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Objects.requireNonNull(key);
Objects.requireNonNull(placeholders);

String rawText = getFromBundle(plugin, bundle, key);
String rawText = ResourceBundleHelper.getFromBundle(plugin, bundle, key);

String prefixColor = getFromBundle(plugin, bundle, "chat.color.prefix");
String defaultColor = getFromBundle(plugin, bundle, "chat.color.default");
String highlightColor = getFromBundle(plugin, bundle, "chat.color.highlight");
String prefixColor = ResourceBundleHelper.getFromBundle(plugin, bundle, "chat.color.prefix");
String defaultColor = ResourceBundleHelper.getFromBundle(plugin, bundle, "chat.color.default");
String highlightColor = ResourceBundleHelper.getFromBundle(plugin, bundle, "chat.color.highlight");

TagResolver.Single[] mappedPlaceholders = mapPlaceHolders(placeholders, highlightColor);

Expand All @@ -41,7 +47,7 @@ private static Component getBaseName(@NotNull Challenges plugin, @NotNull Resour
return Component.empty();
}
String baseName = split[0];
String baseDisplayName = getFromBundle(plugin, bundle, String.format("%s.name", baseName));
String baseDisplayName = ResourceBundleHelper.getFromBundle(plugin, bundle, String.format("%s.name", baseName));
return Component.text(String.format("[%s]: ", baseDisplayName), TextColor.fromHexString(prefixColor));
}

Expand All @@ -54,20 +60,23 @@ private static TagResolver.Single[] mapPlaceHolders(@NotNull Map<String, Compone
.toArray(TagResolver.Single[]::new);
}

private static String getFromBundle(@NotNull Challenges plugin, ResourceBundle bundle, String key) {
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
// log to ingame
String msg = String.format("Key '%s' is not found in resource bundle '%s'.", key, bundle.getBaseBundleName());
plugin.getServer().getLogger().warning(msg);
plugin.getServer().getLogger().log(Level.WARNING, msg, e);
} catch (ClassCastException e) {
// log to ingame
String msg = String.format("Key '%s' is not a valid string in resource bundle '%s'.", key, bundle.getBaseBundleName());
plugin.getServer().getLogger().warning(msg);
plugin.getServer().getLogger().log(Level.WARNING, msg, e);

public static <E extends Enum<E>> Component translate(E enumToTranslate) {
String prefix = null;
if(enumToTranslate instanceof Material material) {
if(material.isBlock()) {
prefix = "block";
}
else if (material.isItem()) {
prefix = "item";
}
}
else if(enumToTranslate instanceof EntityType) {
prefix = "entity";
}
if(prefix == null) {
throw new RuntimeException(String.format("Failed to map enum %s to translatable component!", enumToTranslate));
}
return "";
return Component.translatable(String.format("%s.minecraft.%s", prefix, enumToTranslate.toString().toLowerCase()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public Builder withRuleResourceBundle(ResourceBundle ruleResourceBundle) {
return this;
}

public Builder withGoalResourceBundle(ResourceBundle goalResourceBundle) {
resourceBundleContextBuilder.withGoalResourceBundle(goalResourceBundle);
return this;
}

public Builder withPunishmentResourceBundle(ResourceBundle punishmentResourceBundle) {
resourceBundleContextBuilder.withPunishmentResourceBundle(punishmentResourceBundle);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ public static ChallengeManager readFromFile(File file, Challenges plugin) throws
Context context = new Context.Builder()
.withPlugin(plugin)
.withRuleResourceBundle(ResourceBundle.getBundle("rules", Locale.US, UTF8ResourceBundleControl.get()))
.withGoalResourceBundle(ResourceBundle.getBundle("goals", Locale.US, UTF8ResourceBundleControl.get()))
.withPunishmentResourceBundle(ResourceBundle.getBundle("punishments", Locale.US, UTF8ResourceBundleControl.get()))
.withSchemaRoot(schemaRoot)
.withChallengeManager(new ChallengeManager())
.withChallengeManager(new ChallengeManager(plugin))
.build();

ModelMapper.map2ModelClasses(context, testOutputSchema);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import java.util.ResourceBundle;

public record ResourceBundleContext(ResourceBundle ruleResourceBundle, ResourceBundle punishmentResourceBundle) {
public record ResourceBundleContext(ResourceBundle ruleResourceBundle, ResourceBundle goalResourceBundle, ResourceBundle punishmentResourceBundle) {

public static final class Builder {
private ResourceBundle ruleResourceBundle, punishmentResourceBundle;
private ResourceBundle ruleResourceBundle, goalResourceBundle, punishmentResourceBundle;

public Builder() {}

Expand All @@ -16,13 +16,18 @@ public Builder withRuleResourceBundle(ResourceBundle ruleResourceBundle) {
return this;
}

public Builder withGoalResourceBundle(ResourceBundle goalResourceBundle) {
this.goalResourceBundle = goalResourceBundle;
return this;
}

public Builder withPunishmentResourceBundle(ResourceBundle punishmentResourceBundle) {
this.punishmentResourceBundle = punishmentResourceBundle;
return this;
}

public ResourceBundleContext build() {
return new ResourceBundleContext(ruleResourceBundle, punishmentResourceBundle);
return new ResourceBundleContext(ruleResourceBundle, goalResourceBundle, punishmentResourceBundle);
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package wand555.github.io.challenges.exceptions;

public class MissingSoundException extends Exception {
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package wand555.github.io.challenges.goals;

import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import wand555.github.io.challenges.Challenges;
import wand555.github.io.challenges.ComponentInterpolator;
import wand555.github.io.challenges.Context;
import wand555.github.io.challenges.Storable;
import wand555.github.io.challenges.generated.CollectableEntryConfig;
import wand555.github.io.challenges.generated.GoalsConfig;
import wand555.github.io.challenges.generated.MobGoalConfig;
import wand555.github.io.challenges.inventory.CollectedInventory;
import wand555.github.io.challenges.inventory.CollectedItemStack;
import wand555.github.io.challenges.utils.ActionHelper;

import java.util.Map;
import java.util.logging.Level;
Expand All @@ -31,10 +34,6 @@ public MobGoal(Context context, boolean complete, Map<EntityType, Collect> toKil
super(context, complete);
this.toKill = toKill;
this.collectedInventory = new CollectedInventory(context.plugin());
for(int i=0; i<100; i++) {
collectedInventory.addCollectedItemStack(new CollectedItemStack(Material.STONE, i+"", i));
}

context.plugin().getServer().getPluginManager().registerEvents(this, context.plugin());
}

Expand All @@ -49,7 +48,18 @@ public Map<EntityType, Collect> getToKill() {
@Override
public void onComplete() {
setComplete(true);
// TODO: display messages

Component toSend = ComponentInterpolator.interpolate(
context.plugin(),
context.resourceBundleContext().goalResourceBundle(),
"mobgoal.all.reached.message"
);
ActionHelper.sendAndPlaySound(
context.plugin(),
toSend,
context.resourceBundleContext().goalResourceBundle(),
"mobgoal.all.reached.sound"
);

notifyManager();
}
Expand All @@ -74,10 +84,44 @@ public void onMobDeath(EntityDeathEvent event) {
}

private void newEntityKilled(Player killer, EntityType killed) {
getToKill().computeIfPresent(killed, (entityType, collect) -> {
Collect updatedCollect = getToKill().computeIfPresent(killed, (entityType, collect) -> {
collect.setCurrentAmount(collect.getCurrentAmount()+1);
return collect;
});
Component toSend = null;
String soundInBundleKey = null;
if(updatedCollect.isComplete()) {
toSend = ComponentInterpolator.interpolate(
context.plugin(),
context.resourceBundleContext().goalResourceBundle(),
"mobgoal.single.reached.message",
Map.of(
"entity", ComponentInterpolator.translate(killed)
)
);
soundInBundleKey = "mobgoal.single.reached.sound";
}
else {
toSend = ComponentInterpolator.interpolate(
context.plugin(),
context.resourceBundleContext().goalResourceBundle(),
"mobgoal.single.step.message",
Map.of(
"player", Component.text(killer.getName()),
"entity", ComponentInterpolator.translate(killed),
"amount", Component.text(updatedCollect.getCurrentAmount()),
"total_amount", Component.text(updatedCollect.getAmountNeeded())
)
);
soundInBundleKey = "mobgoal.single.step.sound";
}
ActionHelper.sendAndPlaySound(
context.plugin(),
toSend,
context.resourceBundleContext().goalResourceBundle(),
soundInBundleKey
);

if(determineComplete()) {
onComplete();
}
Expand All @@ -89,6 +133,6 @@ private boolean determineComplete() {

@Override
public void addToGeneratedConfig(GoalsConfig config) {

config.setMobGoal(toGeneratedJSONClass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package wand555.github.io.challenges.utils;

import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
import wand555.github.io.challenges.Challenges;
import wand555.github.io.challenges.exceptions.MissingSoundException;

import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.bukkit.Sound;

import javax.validation.constraints.NotNull;

public class ActionHelper {

private static final Map<String, Sound> ALL_SOUNDS = Stream.of(Sound.values())
.collect(Collectors.toMap(
sound -> sound.getKey().getKey(),
Function.identity()
));

public static void sendAndPlaySound(@NotNull Challenges plugin, @NotNull Component componentToSend, @NotNull ResourceBundle resourceBundle, @NotNull String keyInBundle) {
String soundToPlayKey = ResourceBundleHelper.getFromBundle(plugin, resourceBundle, keyInBundle);

plugin.getServer().broadcast(componentToSend);
try {
Sound soundToPlay = str2Sound(soundToPlayKey);
plugin.getServer().getOnlinePlayers().forEach(onlinePlayer -> {
onlinePlayer.playSound(onlinePlayer.getLocation(), soundToPlay, 1f,1f);
});
} catch (MissingSoundException e) {
plugin.getLogger().warning("missing sound");
}
}

private static Sound str2Sound(String soundKey) throws MissingSoundException {
Sound sound = ALL_SOUNDS.get(soundKey);
if(sound == null) {
throw new MissingSoundException();
}
return sound;
}
}
Loading

0 comments on commit 833122e

Please sign in to comment.