mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-19 06:32:03 +01:00
Added the Notification API
This commit is contained in:
parent
7007c507c1
commit
593f2002a9
@ -3,6 +3,7 @@ package fr.themode.demo;
|
|||||||
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
||||||
import fr.themode.demo.generator.NoiseTestGenerator;
|
import fr.themode.demo.generator.NoiseTestGenerator;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.advancements.FrameType;
|
||||||
import net.minestom.server.benchmark.BenchmarkManager;
|
import net.minestom.server.benchmark.BenchmarkManager;
|
||||||
import net.minestom.server.benchmark.ThreadResult;
|
import net.minestom.server.benchmark.ThreadResult;
|
||||||
import net.minestom.server.chat.ChatColor;
|
import net.minestom.server.chat.ChatColor;
|
||||||
@ -11,10 +12,7 @@ import net.minestom.server.chat.ColoredText;
|
|||||||
import net.minestom.server.chat.RichMessage;
|
import net.minestom.server.chat.RichMessage;
|
||||||
import net.minestom.server.entity.*;
|
import net.minestom.server.entity.*;
|
||||||
import net.minestom.server.entity.damage.DamageType;
|
import net.minestom.server.entity.damage.DamageType;
|
||||||
import net.minestom.server.entity.fakeplayer.FakePlayer;
|
|
||||||
import net.minestom.server.entity.fakeplayer.FakePlayerController;
|
|
||||||
import net.minestom.server.event.entity.EntityAttackEvent;
|
import net.minestom.server.event.entity.EntityAttackEvent;
|
||||||
import net.minestom.server.event.entity.EntityDeathEvent;
|
|
||||||
import net.minestom.server.event.item.ItemDropEvent;
|
import net.minestom.server.event.item.ItemDropEvent;
|
||||||
import net.minestom.server.event.item.ItemUpdateStateEvent;
|
import net.minestom.server.event.item.ItemUpdateStateEvent;
|
||||||
import net.minestom.server.event.item.PickupItemEvent;
|
import net.minestom.server.event.item.PickupItemEvent;
|
||||||
@ -27,6 +25,7 @@ import net.minestom.server.inventory.Inventory;
|
|||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.item.metadata.MapMeta;
|
||||||
import net.minestom.server.network.ConnectionManager;
|
import net.minestom.server.network.ConnectionManager;
|
||||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||||
import net.minestom.server.ping.ResponseDataConsumer;
|
import net.minestom.server.ping.ResponseDataConsumer;
|
||||||
@ -46,7 +45,7 @@ public class PlayerInit {
|
|||||||
private static volatile Inventory inventory;
|
private static volatile Inventory inventory;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
//StorageFolder storageFolder = MinecraftServer.getStorageManager().getFolder("instance_data");
|
//StorageFolder storageFolder = MinecraftServer.getStorageManager().getFolder("instance_data", new StorageOption().setCompression(true));
|
||||||
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
|
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
|
||||||
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
|
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
|
||||||
//instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder);
|
//instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder);
|
||||||
@ -160,7 +159,7 @@ public class PlayerInit {
|
|||||||
zombie.setAttribute(Attribute.MOVEMENT_SPEED, 0.25f);
|
zombie.setAttribute(Attribute.MOVEMENT_SPEED, 0.25f);
|
||||||
zombie.setInstance(player.getInstance());*/
|
zombie.setInstance(player.getInstance());*/
|
||||||
|
|
||||||
FakePlayer.initPlayer(UUID.randomUUID(), "test", fakePlayer -> {
|
/*FakePlayer.initPlayer(UUID.randomUUID(), "test", fakePlayer -> {
|
||||||
//fakePlayer.setInstance(player.getInstance());
|
//fakePlayer.setInstance(player.getInstance());
|
||||||
fakePlayer.teleport(player.getPosition());
|
fakePlayer.teleport(player.getPosition());
|
||||||
fakePlayer.setSkin(PlayerSkin.fromUsername("TheMode911"));
|
fakePlayer.setSkin(PlayerSkin.fromUsername("TheMode911"));
|
||||||
@ -172,7 +171,7 @@ public class PlayerInit {
|
|||||||
fakePlayer.setArrowCount(25);
|
fakePlayer.setArrowCount(25);
|
||||||
FakePlayerController controller = fakePlayer.getController();
|
FakePlayerController controller = fakePlayer.getController();
|
||||||
controller.sendChatMessage("I am a bot!");
|
controller.sendChatMessage("I am a bot!");
|
||||||
});
|
});*/
|
||||||
//Hologram hologram = new Hologram(player.getInstance(), player.getPosition(), "Hey guy");
|
//Hologram hologram = new Hologram(player.getInstance(), player.getPosition(), "Hey guy");
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -245,7 +244,7 @@ public class PlayerInit {
|
|||||||
displayData.title = ColoredText.of("Hello");
|
displayData.title = ColoredText.of("Hello");
|
||||||
displayData.description = ColoredText.of("Hello");
|
displayData.description = ColoredText.of("Hello");
|
||||||
displayData.icon = new ItemStack(Material.DIRT, (byte) 1);
|
displayData.icon = new ItemStack(Material.DIRT, (byte) 1);
|
||||||
displayData.frameType = AdvancementsPacket.FrameType.TASK;
|
displayData.frameType = FrameType.TASK;
|
||||||
displayData.flags = 0x1;
|
displayData.flags = 0x1;
|
||||||
displayData.backgroundTexture = "minecraft:textures/block/red_wool.png";
|
displayData.backgroundTexture = "minecraft:textures/block/red_wool.png";
|
||||||
|
|
||||||
@ -270,7 +269,7 @@ public class PlayerInit {
|
|||||||
displayData.title = ColoredText.of("Hello World");
|
displayData.title = ColoredText.of("Hello World");
|
||||||
displayData.description = ColoredText.of("Hello World");
|
displayData.description = ColoredText.of("Hello World");
|
||||||
displayData.icon = new ItemStack(Material.DIAMOND, (byte) 1);
|
displayData.icon = new ItemStack(Material.DIAMOND, (byte) 1);
|
||||||
displayData.frameType = AdvancementsPacket.FrameType.GOAL;
|
displayData.frameType = FrameType.GOAL;
|
||||||
displayData.flags = 0x2;
|
displayData.flags = 0x2;
|
||||||
|
|
||||||
secondAdvancement.displayData = displayData;
|
secondAdvancement.displayData = displayData;
|
||||||
@ -299,35 +298,13 @@ public class PlayerInit {
|
|||||||
player.getInventory().setItemStack(i, new ItemStack(Material.STONE, (byte) 127));
|
player.getInventory().setItemStack(i, new ItemStack(Material.STONE, (byte) 127));
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/*ItemStack map = new ItemStack(Material.FILLED_MAP, (byte) 1);
|
|
||||||
MapMeta mapMeta = (MapMeta) map.getItemMeta();
|
|
||||||
mapMeta.setMapId(1);
|
|
||||||
player.getInventory().setItemStack(0, map);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Map test
|
ItemStack map = new ItemStack(Material.FILLED_MAP, (byte) 1);
|
||||||
MapDataPacket mapDataPacket = new MapDataPacket();
|
MapMeta mapMeta = (MapMeta) map.getItemMeta();
|
||||||
mapDataPacket.mapId = 1;
|
mapMeta.setMapId(1);
|
||||||
mapDataPacket.scale = 1;
|
//player.getInventory().setItemStack(0, map);
|
||||||
mapDataPacket.trackingPosition = false;
|
|
||||||
mapDataPacket.locked = false;
|
|
||||||
mapDataPacket.icons = null;
|
|
||||||
mapDataPacket.columns = (byte) 127;
|
|
||||||
mapDataPacket.rows = (byte) 127;
|
|
||||||
mapDataPacket.x = 0;
|
|
||||||
mapDataPacket.z = 0;
|
|
||||||
|
|
||||||
final byte[] data = new byte[127 * 127];
|
}
|
||||||
for (int i = 0; i < data.length; i++) {
|
|
||||||
final byte color = (byte) (i % 2 == 0 ? 5 : 10);
|
|
||||||
data[i] = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapDataPacket.data = data;
|
|
||||||
|
|
||||||
player.getPlayerConnection().sendPacket(mapDataPacket);
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);
|
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);
|
||||||
@ -347,12 +324,19 @@ public class PlayerInit {
|
|||||||
|
|
||||||
//player.getInventory().addItemStack(new ItemStack(Material.STONE, (byte) 100));
|
//player.getInventory().addItemStack(new ItemStack(Material.STONE, (byte) 100));
|
||||||
|
|
||||||
|
{
|
||||||
|
/*EntityItemFrame entityItemFrame = new EntityItemFrame(new Position(-5, 36, 9, 0, 180), EntityItemFrame.ItemFrameOrientation.DOWN);
|
||||||
|
entityItemFrame.setNoGravity(true);
|
||||||
|
entityItemFrame.setInstance(player.getInstance());
|
||||||
|
entityItemFrame.setItemStack(item);*/
|
||||||
|
}
|
||||||
|
|
||||||
Instance instance = player.getInstance();
|
Instance instance = player.getInstance();
|
||||||
WorldBorder worldBorder = instance.getWorldBorder();
|
WorldBorder worldBorder = instance.getWorldBorder();
|
||||||
worldBorder.setDiameter(30);
|
worldBorder.setDiameter(30);
|
||||||
|
|
||||||
RichMessage richMessage = RichMessage.of(ColoredText.of(ChatColor.RED + "test item"));
|
RichMessage richMessage = RichMessage.of(ColoredText.of(ChatColor.RED + "test item"));
|
||||||
richMessage.setHoverEvent(ChatHoverEvent.showItem(new ItemStack(Material.DIAMOND, (byte) 1)));
|
richMessage.setHoverEvent(ChatHoverEvent.showEntity(player));
|
||||||
richMessage.setInsertion("Test Insert");
|
richMessage.setInsertion("Test Insert");
|
||||||
System.out.println(richMessage.toString());
|
System.out.println(richMessage.toString());
|
||||||
player.sendMessage(richMessage);
|
player.sendMessage(richMessage);
|
||||||
@ -386,6 +370,10 @@ public class PlayerInit {
|
|||||||
event.setRespawnPosition(new Position(0f, 41f, 0f));
|
event.setRespawnPosition(new Position(0f, 41f, 0f));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
player.addEventCallback(PlayerCommandEvent.class, event -> {
|
||||||
|
System.out.println("COMMAND EVENT");
|
||||||
|
});
|
||||||
|
|
||||||
player.addEventCallback(PlayerUseItemEvent.class, useEvent -> {
|
player.addEventCallback(PlayerUseItemEvent.class, useEvent -> {
|
||||||
player.sendMessage("Using item in air: " + useEvent.getItemStack().getMaterial());
|
player.sendMessage("Using item in air: " + useEvent.getItemStack().getMaterial());
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
package fr.themode.demo.commands;
|
package fr.themode.demo.commands;
|
||||||
|
|
||||||
import fr.themode.demo.entity.ChickenCreature;
|
import net.minestom.server.advancements.FrameType;
|
||||||
import net.minestom.server.advancements.notifications.AdvancementNotification;
|
import net.minestom.server.advancements.notifications.Notification;
|
||||||
import net.minestom.server.advancements.notifications.AdvancementNotificationManager;
|
import net.minestom.server.advancements.notifications.NotificationCenter;
|
||||||
import net.minestom.server.chat.ChatColor;
|
import net.minestom.server.chat.ChatColor;
|
||||||
import net.minestom.server.chat.ColoredText;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.command.CommandProcessor;
|
import net.minestom.server.command.CommandProcessor;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.Instance;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
|
||||||
import net.minestom.server.utils.Position;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class SimpleCommand implements CommandProcessor {
|
public class SimpleCommand implements CommandProcessor {
|
||||||
@Override
|
@Override
|
||||||
@ -58,19 +56,19 @@ public class SimpleCommand implements CommandProcessor {
|
|||||||
System.gc();
|
System.gc();
|
||||||
player.sendMessage("Garbage collector called");*/
|
player.sendMessage("Garbage collector called");*/
|
||||||
|
|
||||||
Instance instance = player.getInstance();
|
/*Instance instance = player.getInstance();
|
||||||
|
|
||||||
ChickenCreature chickenCreature = new ChickenCreature(new Position(-10, 43, -10));
|
ChickenCreature chickenCreature = new ChickenCreature(new Position(-10, 43, -10));
|
||||||
chickenCreature.setInstance(instance);
|
chickenCreature.setInstance(instance);
|
||||||
|
|
||||||
chickenCreature.setPathTo(player.getPosition());
|
chickenCreature.setPathTo(player.getPosition());*/
|
||||||
|
|
||||||
|
final Notification notification = new Notification(ColoredText.of(ChatColor.BRIGHT_GREEN + "Welcome to Minestom!"),
|
||||||
|
FrameType.TASK, Material.APPLE);
|
||||||
|
|
||||||
|
NotificationCenter.send(notification, Arrays.asList(player));
|
||||||
|
NotificationCenter.send(notification, Arrays.asList(player));
|
||||||
|
|
||||||
new AdvancementNotificationManager().sendAdvancementNotification(
|
|
||||||
new AdvancementNotification(
|
|
||||||
ColoredText.of(ChatColor.BRIGHT_GREEN + "Welcome to Minestom!"),
|
|
||||||
new ItemStack(Material.ACACIA_BOAT, (byte) 1), AdvancementsPacket.FrameType.GOAL)
|
|
||||||
, player
|
|
||||||
);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package net.minestom.server.advancements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the frame around the Advancement.
|
||||||
|
* Also describes the type of advancement it is for "toast" notifications.
|
||||||
|
*/
|
||||||
|
public enum FrameType {
|
||||||
|
/**
|
||||||
|
* A simple rounded square as the frame.
|
||||||
|
*/
|
||||||
|
TASK,
|
||||||
|
/**
|
||||||
|
* A spike in all 8 directions as the frame.
|
||||||
|
*/
|
||||||
|
CHALLENGE,
|
||||||
|
/**
|
||||||
|
* A square with a outward rounded edge on the top and bottom as the frame.
|
||||||
|
*/
|
||||||
|
GOAL
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
package net.minestom.server.advancements.notifications;
|
|
||||||
|
|
||||||
import net.minestom.server.chat.ColoredText;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Lukas Mansour (Articdive)
|
|
||||||
*/
|
|
||||||
public class AdvancementNotification {
|
|
||||||
private final ColoredText title;
|
|
||||||
private final ItemStack icon;
|
|
||||||
private final AdvancementsPacket.FrameType frameType;
|
|
||||||
|
|
||||||
public AdvancementNotification(@NotNull ColoredText title, @NotNull ItemStack icon, @NotNull AdvancementsPacket.FrameType frameType) {
|
|
||||||
this.title = title;
|
|
||||||
this.icon = icon;
|
|
||||||
this.frameType = frameType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ColoredText getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ItemStack getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public AdvancementsPacket.FrameType getFrameType() {
|
|
||||||
return frameType;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
package net.minestom.server.advancements.notifications;
|
|
||||||
|
|
||||||
import net.minestom.server.chat.ColoredText;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Lukas Mansour
|
|
||||||
*/
|
|
||||||
public class AdvancementNotificationManager {
|
|
||||||
public AdvancementNotificationManager() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendAdvancementNotification(AdvancementNotification advancementNotification, Player player) {
|
|
||||||
// Sending
|
|
||||||
{
|
|
||||||
// For An advancement to be shown, it must have all of it's criteria achieved (progress 100%)
|
|
||||||
// Create a Criteria that we can set to 100% achieved.
|
|
||||||
// Criteria
|
|
||||||
|
|
||||||
AdvancementsPacket.Criteria criteria = new AdvancementsPacket.Criteria();
|
|
||||||
{
|
|
||||||
AdvancementsPacket.CriterionProgress progress = new AdvancementsPacket.CriterionProgress();
|
|
||||||
progress.achieved = true;
|
|
||||||
progress.dateOfAchieving = new Date(System.currentTimeMillis()).getTime();
|
|
||||||
criteria.criterionProgress = progress;
|
|
||||||
criteria.criterionIdentifier = "minestom:some_criteria";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now create an AdvancementsPacket that we can send:
|
|
||||||
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
|
||||||
advancementsPacket.resetAdvancements = false;
|
|
||||||
|
|
||||||
AdvancementsPacket.AdvancementMapping mapping = new AdvancementsPacket.AdvancementMapping();
|
|
||||||
{
|
|
||||||
// Get the advancement
|
|
||||||
AdvancementsPacket.Advancement advancement = new AdvancementsPacket.Advancement();
|
|
||||||
// Setup display data for the advancement
|
|
||||||
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
|
|
||||||
{
|
|
||||||
displayData.title = advancementNotification.getTitle();
|
|
||||||
// Description is required, but never shown/seen so, small Easter egg.
|
|
||||||
displayData.description = ColoredText.of("Articdive was here. #Minestom");
|
|
||||||
displayData.icon = advancementNotification.getIcon();
|
|
||||||
displayData.frameType = advancementNotification.getFrameType();
|
|
||||||
displayData.flags = 0x6;
|
|
||||||
// No background texture required as we are using 0x6
|
|
||||||
displayData.x = 0.0F;
|
|
||||||
displayData.y = 0.0F;
|
|
||||||
}
|
|
||||||
advancement.displayData = displayData;
|
|
||||||
// Add the criteria to the advancement
|
|
||||||
advancement.criterions = new String[]{criteria.criterionIdentifier};
|
|
||||||
// Add the requirement of the criteria to the advancement
|
|
||||||
AdvancementsPacket.Requirement requirement = new AdvancementsPacket.Requirement();
|
|
||||||
{
|
|
||||||
requirement.requirements = new String[]{criteria.criterionIdentifier};
|
|
||||||
}
|
|
||||||
advancement.requirements = new AdvancementsPacket.Requirement[]{requirement};
|
|
||||||
|
|
||||||
mapping.key = "minestom:advancement_login";
|
|
||||||
mapping.value = advancement;
|
|
||||||
}
|
|
||||||
// Add the mapping to the main packet
|
|
||||||
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{mapping};
|
|
||||||
|
|
||||||
|
|
||||||
// We have no identifiers to remove.
|
|
||||||
advancementsPacket.identifiersToRemove = new String[]{};
|
|
||||||
|
|
||||||
// Now we need to set the player's progress for the criteria.
|
|
||||||
AdvancementsPacket.ProgressMapping progressMapping = new AdvancementsPacket.ProgressMapping();
|
|
||||||
{
|
|
||||||
AdvancementsPacket.AdvancementProgress advancementProgress = new AdvancementsPacket.AdvancementProgress();
|
|
||||||
advancementProgress.criteria = new AdvancementsPacket.Criteria[]{criteria};
|
|
||||||
|
|
||||||
progressMapping.key = "minestom:advancement_login";
|
|
||||||
progressMapping.value = advancementProgress;
|
|
||||||
}
|
|
||||||
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{progressMapping};
|
|
||||||
|
|
||||||
// Now let's send the the tasty toast.
|
|
||||||
player.getPlayerConnection().sendPacket(advancementsPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we should send a packet telling the player to remove that advancement
|
|
||||||
// Removing
|
|
||||||
{
|
|
||||||
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
|
||||||
advancementsPacket.resetAdvancements = false;
|
|
||||||
advancementsPacket.identifiersToRemove = new String[]{"minestom:advancement_login"};
|
|
||||||
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{};
|
|
||||||
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
|
||||||
player.getPlayerConnection().sendPacket(advancementsPacket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,59 @@
|
|||||||
|
package net.minestom.server.advancements.notifications;
|
||||||
|
|
||||||
|
import net.minestom.server.advancements.FrameType;
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent a message which can be send using the {@link NotificationCenter}
|
||||||
|
*/
|
||||||
|
public class Notification {
|
||||||
|
|
||||||
|
private final ColoredText title;
|
||||||
|
private final FrameType frameType;
|
||||||
|
private final ItemStack icon;
|
||||||
|
|
||||||
|
public Notification(@NotNull ColoredText title, @NotNull FrameType frameType, @NotNull ItemStack icon) {
|
||||||
|
this.title = title;
|
||||||
|
this.frameType = frameType;
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Notification(@NotNull ColoredText title, @NotNull FrameType frameType, @NotNull Material icon) {
|
||||||
|
this.title = title;
|
||||||
|
this.frameType = frameType;
|
||||||
|
this.icon = new ItemStack(icon, (byte) 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the notification
|
||||||
|
*
|
||||||
|
* @return the notification title
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public ColoredText getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the frame type of the notification
|
||||||
|
*
|
||||||
|
* @return the notification frame type
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public FrameType getFrameType() {
|
||||||
|
return frameType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon of the notification
|
||||||
|
*
|
||||||
|
* @return the notification icon
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
protected ItemStack getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
package net.minestom.server.advancements.notifications;
|
||||||
|
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to send one or multiples {@link Notification}
|
||||||
|
*/
|
||||||
|
public class NotificationCenter {
|
||||||
|
|
||||||
|
private static final String IDENTIFIER = "minestom:notification";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can't create an instance
|
||||||
|
*/
|
||||||
|
private NotificationCenter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send(Notification notification, Player player) {
|
||||||
|
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
|
|
||||||
|
playerConnection.sendPacket(getCreatePacket(notification));
|
||||||
|
|
||||||
|
playerConnection.sendPacket(getRemovePacket());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send(Notification notification, Collection<Player> players) {
|
||||||
|
// Can't use PacketWriterUtils before we need the packets to come in the correct order
|
||||||
|
players.forEach(player -> {
|
||||||
|
send(notification, player);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the packet responsive for showing the Toast to players
|
||||||
|
*
|
||||||
|
* @param notification the notification
|
||||||
|
* @return the packet to show the Toast
|
||||||
|
*/
|
||||||
|
private static AdvancementsPacket getCreatePacket(Notification notification) {
|
||||||
|
// For An advancement to be shown, it must have all of it's criteria achieved (progress 100%)
|
||||||
|
// Create a Criteria that we can set to 100% achieved.
|
||||||
|
// Criteria
|
||||||
|
|
||||||
|
AdvancementsPacket.Criteria criteria = new AdvancementsPacket.Criteria();
|
||||||
|
{
|
||||||
|
AdvancementsPacket.CriterionProgress progress = new AdvancementsPacket.CriterionProgress();
|
||||||
|
progress.achieved = true;
|
||||||
|
progress.dateOfAchieving = new Date(System.currentTimeMillis()).getTime();
|
||||||
|
criteria.criterionProgress = progress;
|
||||||
|
criteria.criterionIdentifier = "minestom:some_criteria";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create an AdvancementsPacket that we can send:
|
||||||
|
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||||
|
advancementsPacket.resetAdvancements = false;
|
||||||
|
|
||||||
|
AdvancementsPacket.AdvancementMapping mapping = new AdvancementsPacket.AdvancementMapping();
|
||||||
|
{
|
||||||
|
// Get the advancement
|
||||||
|
AdvancementsPacket.Advancement advancement = new AdvancementsPacket.Advancement();
|
||||||
|
// Setup display data for the advancement
|
||||||
|
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
|
||||||
|
{
|
||||||
|
displayData.title = notification.getTitle();
|
||||||
|
// Description is required, but never shown/seen so, small Easter egg.
|
||||||
|
displayData.description = ColoredText.of("Articdive was here. #Minestom");
|
||||||
|
displayData.icon = notification.getIcon();
|
||||||
|
displayData.frameType = notification.getFrameType();
|
||||||
|
displayData.flags = 0x6;
|
||||||
|
// No background texture required as we are using 0x6
|
||||||
|
displayData.x = 0.0F;
|
||||||
|
displayData.y = 0.0F;
|
||||||
|
}
|
||||||
|
advancement.displayData = displayData;
|
||||||
|
// Add the criteria to the advancement
|
||||||
|
advancement.criterions = new String[]{criteria.criterionIdentifier};
|
||||||
|
// Add the requirement of the criteria to the advancement
|
||||||
|
AdvancementsPacket.Requirement requirement = new AdvancementsPacket.Requirement();
|
||||||
|
{
|
||||||
|
requirement.requirements = new String[]{criteria.criterionIdentifier};
|
||||||
|
}
|
||||||
|
advancement.requirements = new AdvancementsPacket.Requirement[]{requirement};
|
||||||
|
|
||||||
|
mapping.key = IDENTIFIER;
|
||||||
|
mapping.value = advancement;
|
||||||
|
}
|
||||||
|
// Add the mapping to the main packet
|
||||||
|
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{mapping};
|
||||||
|
|
||||||
|
|
||||||
|
// We have no identifiers to remove.
|
||||||
|
advancementsPacket.identifiersToRemove = new String[]{};
|
||||||
|
|
||||||
|
// Now we need to set the player's progress for the criteria.
|
||||||
|
AdvancementsPacket.ProgressMapping progressMapping = new AdvancementsPacket.ProgressMapping();
|
||||||
|
{
|
||||||
|
AdvancementsPacket.AdvancementProgress advancementProgress = new AdvancementsPacket.AdvancementProgress();
|
||||||
|
advancementProgress.criteria = new AdvancementsPacket.Criteria[]{criteria};
|
||||||
|
|
||||||
|
progressMapping.key = IDENTIFIER;
|
||||||
|
progressMapping.value = advancementProgress;
|
||||||
|
}
|
||||||
|
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{progressMapping};
|
||||||
|
|
||||||
|
return advancementsPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the packet responsive for removing the advancement identifier
|
||||||
|
*
|
||||||
|
* @return the packet to remove the identifier
|
||||||
|
*/
|
||||||
|
private static AdvancementsPacket getRemovePacket() {
|
||||||
|
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||||
|
advancementsPacket.resetAdvancements = false;
|
||||||
|
advancementsPacket.identifiersToRemove = new String[]{IDENTIFIER};
|
||||||
|
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{};
|
||||||
|
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
||||||
|
|
||||||
|
return advancementsPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
|
import net.minestom.server.advancements.FrameType;
|
||||||
import net.minestom.server.chat.ColoredText;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
@ -34,25 +35,6 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
return ServerPacketIdentifier.ADVANCEMENTS;
|
return ServerPacketIdentifier.ADVANCEMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the frame around the Advancement.
|
|
||||||
* Also describes the type of advancement it is for "toast" notifications.
|
|
||||||
*/
|
|
||||||
public enum FrameType {
|
|
||||||
/**
|
|
||||||
* A simple rounded square as the frame.
|
|
||||||
*/
|
|
||||||
TASK,
|
|
||||||
/**
|
|
||||||
* A spike in all 8 directions as the frame.
|
|
||||||
*/
|
|
||||||
CHALLENGE,
|
|
||||||
/**
|
|
||||||
* A square with a outward rounded edge on the top and bottom as the frame.
|
|
||||||
*/
|
|
||||||
GOAL
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AdvancementMapping maps the namespaced ID to the Advancement.
|
* AdvancementMapping maps the namespaced ID to the Advancement.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user