Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into patch/oop-api
Browse files Browse the repository at this point in the history
  • Loading branch information
MelonHell authored Jan 30, 2024
2 parents 5ad4b14 + 9d6752c commit 9853e10
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 39 deletions.
25 changes: 25 additions & 0 deletions demo/src/main/java/net/minestom/demo/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@
import net.minestom.server.ServerProcess;
import net.minestom.server.ServerSettings;
import net.minestom.server.command.CommandManager;
import net.minestom.server.entity.Player;
import net.minestom.server.event.server.ServerListPingEvent;
import net.minestom.server.extras.lan.OpenToLAN;
import net.minestom.server.extras.lan.OpenToLANConfig;
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.DeclareRecipesPacket;
import net.minestom.server.ping.ResponseData;
import net.minestom.server.recipe.RecipeCategory;
import net.minestom.server.recipe.ShapedRecipe;
import net.minestom.server.utils.identity.NamedAndIdentified;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;

import java.time.Duration;
import java.util.List;

public class Main {

Expand Down Expand Up @@ -64,6 +72,7 @@ public static void main(String[] args) {
commandManager.register(new TestCommand2());
commandManager.register(new ConfigCommand());
commandManager.register(new SidebarCommand(serverProcess));
commandManager.register(new SetEntityType());

commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage(Component.text("Unknown command", NamedTextColor.RED)));

Expand Down Expand Up @@ -105,6 +114,22 @@ public static void main(String[] args) {
//responseData.setPlayersHidden(true);
});

var ironBlockRecipe = new ShapedRecipe(
"minestom:test", 2, 2, "",
RecipeCategory.Crafting.MISC,
List.of(
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT))),
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT))),
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT))),
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT)))
), ItemStack.of(Material.IRON_BLOCK), true) {
@Override
public boolean shouldShow(@NotNull Player player) {
return true;
}
};
MinecraftServer.getRecipeManager().addRecipe(ironBlockRecipe);

new PlayerInit(serverProcess).init();

// VelocityProxy.enable("abcdef");
Expand Down
29 changes: 29 additions & 0 deletions demo/src/main/java/net/minestom/demo/commands/SetEntityType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.minestom.demo.commands;

import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentEntityType;
import net.minestom.server.entity.Player;
import org.jetbrains.annotations.NotNull;

public class SetEntityType extends Command {
private final ArgumentEntityType entityTypeArg = ArgumentType.EntityType("type");

public SetEntityType() {
super("setentitytype");

addSyntax(this::execute, entityTypeArg);
}

private void execute(@NotNull CommandSender sender, @NotNull CommandContext context) {
if (!(sender instanceof Player player)) {
return;
}

var entityType = context.get(entityTypeArg);
player.switchEntityType(entityType);
player.sendMessage("set entity type to " + entityType);
}
}
2 changes: 1 addition & 1 deletion src/main/java/net/minestom/server/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ protected void updatePose() {
setPose(Pose.FALL_FLYING);
} else if (entityMeta.isSwimming()) {
setPose(Pose.SWIMMING);
} else if (this instanceof LivingEntity && ((LivingEntityMeta) entityMeta).isInRiptideSpinAttack()) {
} else if (entityMeta instanceof LivingEntityMeta livingMeta && livingMeta.isInRiptideSpinAttack()) {
setPose(Pose.SPIN_ATTACK);
} else if (entityMeta.isSneaking()) {
setPose(Pose.SNEAKING);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/minestom/server/entity/Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ public static Entry<float[]> Quaternion(float @NotNull[] value) {
public static final byte TYPE_VECTOR3 = 26;
public static final byte TYPE_QUATERNION = 27;

// Impl Note: Adding an entry here requires that a default value entry is added in MetadataImpl.EMPTY_VALUES

private static final VarHandle NOTIFIED_CHANGES;

static {
Expand Down
17 changes: 13 additions & 4 deletions src/main/java/net/minestom/server/entity/MetadataImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.metadata.animal.FrogMeta;
import net.minestom.server.entity.metadata.animal.SnifferMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.Direction;
Expand All @@ -10,10 +14,6 @@
import org.jetbrains.annotations.UnknownNullability;
import org.jglrxavpok.hephaistos.nbt.NBTEnd;

import static net.minestom.server.entity.Metadata.Boolean;
import static net.minestom.server.entity.Metadata.Byte;
import static net.minestom.server.entity.Metadata.Float;
import static net.minestom.server.entity.Metadata.String;
import static net.minestom.server.entity.Metadata.*;
import static net.minestom.server.network.NetworkBuffer.VAR_INT;

Expand All @@ -23,6 +23,7 @@ final class MetadataImpl {
static {
EMPTY_VALUES.set(TYPE_BYTE, Byte((byte) 0));
EMPTY_VALUES.set(TYPE_VARINT, VarInt(0));
EMPTY_VALUES.set(TYPE_LONG, Long(0L));
EMPTY_VALUES.set(TYPE_FLOAT, Float(0f));
EMPTY_VALUES.set(TYPE_STRING, String(""));
EMPTY_VALUES.set(TYPE_CHAT, Chat(Component.empty()));
Expand All @@ -34,12 +35,20 @@ final class MetadataImpl {
EMPTY_VALUES.set(TYPE_OPTPOSITION, OptPosition(null));
EMPTY_VALUES.set(TYPE_DIRECTION, Direction(Direction.DOWN));
EMPTY_VALUES.set(TYPE_OPTUUID, OptUUID(null));
EMPTY_VALUES.set(TYPE_BLOCKSTATE, BlockState(Block.AIR.id()));
EMPTY_VALUES.set(TYPE_OPTBLOCKSTATE, OptBlockState(null));
EMPTY_VALUES.set(TYPE_NBT, NBT(NBTEnd.INSTANCE));
//EMPTY_VALUES.set(TYPE_PARTICLE -> throw new UnsupportedOperationException();
EMPTY_VALUES.set(TYPE_VILLAGERDATA, VillagerData(0, 0, 0));
EMPTY_VALUES.set(TYPE_OPTVARINT, OptVarInt(null));
EMPTY_VALUES.set(TYPE_POSE, Pose(Entity.Pose.STANDING));
EMPTY_VALUES.set(TYPE_CAT_VARIANT, CatVariant(CatMeta.Variant.TABBY));
EMPTY_VALUES.set(TYPE_FROG_VARIANT, FrogVariant(FrogMeta.Variant.TEMPERATE));
// OptGlobalPos
// PaintingVariant
EMPTY_VALUES.set(TYPE_SNIFFER_STATE, SnifferState(SnifferMeta.State.IDLING));
EMPTY_VALUES.set(TYPE_VECTOR3, Vector3(Vec.ZERO));
EMPTY_VALUES.set(TYPE_QUATERNION, Quaternion(new float[]{0, 0, 0, 0}));
EMPTY_VALUES.trim();
}

Expand Down
25 changes: 19 additions & 6 deletions src/main/java/net/minestom/server/entity/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import net.minestom.server.effects.Effects;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.fakeplayer.FakePlayer;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.vehicle.PlayerVehicleInformation;
import net.minestom.server.event.inventory.InventoryOpenEvent;
Expand Down Expand Up @@ -823,14 +824,14 @@ protected void updatePose() {
Pose newPose;

// Figure out their expected state
var meta = Objects.requireNonNull(getLivingEntityMeta());
var meta = getEntityMeta();
if (meta.isFlyingWithElytra()) {
newPose = Pose.FALL_FLYING;
} else if (false) { // When should they be sleeping? We don't have any in-bed state...
newPose = Pose.SLEEPING;
} else if (meta.isSwimming()) {
newPose = Pose.SWIMMING;
} else if (meta.isInRiptideSpinAttack()) {
} else if (meta instanceof LivingEntityMeta livingMeta && livingMeta.isInRiptideSpinAttack()) {
newPose = Pose.SPIN_ATTACK;
} else if (isSneaking() && !isFlying()) {
newPose = Pose.SNEAKING;
Expand Down Expand Up @@ -1017,27 +1018,39 @@ public void setHealth(float health) {
sendPacket(new UpdateHealthPacket(health, food, foodSaturation));
}

@Override
public @NotNull PlayerMeta getEntityMeta() {
/**
* Gets the entity meta for the player.
*
* <p>Note that this method will throw an exception if the player's entity type has
* been changed with {@link #switchEntityType(EntityType)}. It is wise to check
* {@link #getEntityType()} first.</p>
*/
public @NotNull PlayerMeta getPlayerMeta() {
return (PlayerMeta) super.getEntityMeta();
}

/**
* Gets the player additional hearts.
*
* <p>Note that this function is uncallable if the player has their entity type switched
* with {@link #switchEntityType(EntityType)}.</p>
*
* @return the player additional hearts
*/
public float getAdditionalHearts() {
return getEntityMeta().getAdditionalHearts();
return getPlayerMeta().getAdditionalHearts();
}

/**
* Changes the amount of additional hearts shown.
*
* <p>Note that this function is uncallable if the player has their entity type switched
* with {@link #switchEntityType(EntityType)}.</p>
*
* @param additionalHearts the count of additional hearts
*/
public void setAdditionalHearts(float additionalHearts) {
getEntityMeta().setAdditionalHearts(additionalHearts);
getPlayerMeta().setAdditionalHearts(additionalHearts);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.item.ItemUpdateStateEvent;
import net.minestom.server.event.player.PlayerCancelDiggingEvent;
import net.minestom.server.event.player.PlayerFinishDiggingEvent;
Expand Down Expand Up @@ -144,8 +146,8 @@ private static void dropSingle(Player player) {
}

private static void updateItemState(Player player) {
PlayerMeta meta = player.getEntityMeta();
if (!meta.isHandActive()) return;
LivingEntityMeta meta = player.getLivingEntityMeta();
if (meta == null || !meta.isHandActive()) return;
Player.Hand hand = meta.getActiveHand();

player.refreshEating(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,12 @@ public static void loginEncryptionResponseListener(@NotNull ClientEncryptionResp
final HttpClient client = HttpClient.newHttpClient();
final HttpRequest request = HttpRequest.newBuilder(URI.create(url)).GET().build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).whenComplete((response, throwable) -> {
if (throwable != null) {
connection.getServerProcess().getExceptionHandler().handleException(throwable);
final boolean ok = throwable == null && response.statusCode() == 200 && response.body() != null && !response.body().isEmpty();

if (!ok) {
if (throwable != null) {
connection.getServerProcess().getExceptionHandler().handleException(throwable);
}
if (socketConnection.getPlayer() != null) {
socketConnection.getPlayer().kick(Component.text("Failed to contact Mojang's Session Servers (Are they down?)"));
} else {
Expand All @@ -133,15 +137,6 @@ public static void loginEncryptionResponseListener(@NotNull ClientEncryptionResp
}
try {
final JsonObject gameProfile = GSON.fromJson(response.body(), JsonObject.class);
if (gameProfile == null) {
// Invalid response
if (socketConnection.getPlayer() != null) {
socketConnection.getPlayer().kick(Component.text("Failed to get data from Mojang's Session Servers (Are they down?)"));
} else {
socketConnection.disconnect();
}
return;
}
socketConnection.setEncryptionKey(getSecretKey(mojangAuth, packet.sharedSecret()));
UUID profileUUID = java.util.UUID.fromString(gameProfile.get("id").getAsString()
.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,16 @@ public void write(@NotNull NetworkBuffer writer) {
}
}

public record DeclaredShapedCraftingRecipe(@NotNull String recipeId, int width, int height,
public record DeclaredShapedCraftingRecipe(@NotNull String recipeId,
@NotNull String group, @NotNull RecipeCategory.Crafting category,
@NotNull List<Ingredient> ingredients,
int width, int height, @NotNull List<Ingredient> ingredients,
@NotNull ItemStack result, boolean showNotification) implements DeclaredRecipe {
public DeclaredShapedCraftingRecipe {
ingredients = List.copyOf(ingredients);
}

private DeclaredShapedCraftingRecipe(DeclaredShapedCraftingRecipe packet) {
this(packet.recipeId, packet.width, packet.height, packet.group, packet.category, packet.ingredients, packet.result, packet.showNotification);
this(packet.recipeId, packet.group, packet.category, packet.width, packet.height, packet.ingredients, packet.result, packet.showNotification);
}

public DeclaredShapedCraftingRecipe(@NotNull NetworkBuffer reader) {
Expand All @@ -108,25 +108,25 @@ public DeclaredShapedCraftingRecipe(@NotNull NetworkBuffer reader) {
private static DeclaredShapedCraftingRecipe read(@NotNull NetworkBuffer reader) {

String recipeId = reader.read(STRING);
int width = reader.read(VAR_INT);
int height = reader.read(VAR_INT);
String group = reader.read(STRING);
RecipeCategory.Crafting category = reader.readEnum(RecipeCategory.Crafting.class);
int width = reader.read(VAR_INT);
int height = reader.read(VAR_INT);
List<Ingredient> ingredients = new ArrayList<>();
for (int slot = 0; slot < width * height; slot++) {
ingredients.add(new Ingredient(reader));
}
ItemStack result = reader.read(ITEM);
boolean showNotification = reader.read(BOOLEAN);
return new DeclaredShapedCraftingRecipe(recipeId, width, height, group, category, ingredients, result, showNotification);
return new DeclaredShapedCraftingRecipe(recipeId, group, category, width, height, ingredients, result, showNotification);
}

@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(VAR_INT, width);
writer.write(VAR_INT, height);
writer.write(STRING, group);
writer.writeEnum(RecipeCategory.Crafting.class, category);
writer.write(VAR_INT, width);
writer.write(VAR_INT, height);
for (Ingredient ingredient : ingredients) {
ingredient.write(writer);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/minestom/server/recipe/RecipeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ private void refreshRecipesPacket() {
recipesCache.add(
new DeclareRecipesPacket.DeclaredShapedCraftingRecipe(
shapedRecipe.getRecipeId(),
shapedRecipe.getWidth(),
shapedRecipe.getHeight(),
shapedRecipe.getGroup(),
shapedRecipe.getCategory(),
shapedRecipe.getWidth(),
shapedRecipe.getHeight(),
shapedRecipe.getIngredients(),
shapedRecipe.getResult(),
shapedRecipe.getShowNotification()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@
import net.minestom.server.network.packet.client.handshake.ClientHandshakePacket;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.common.DisconnectPacket;
import net.minestom.server.network.packet.server.status.ResponsePacket;
import net.minestom.server.network.packet.server.login.LoginDisconnectPacket;
import net.minestom.server.network.packet.server.login.LoginSuccessPacket;
import net.minestom.server.network.packet.server.login.SetCompressionPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.packet.server.play.DeclareRecipesPacket.Ingredient;
import net.minestom.server.network.packet.server.status.PongPacket;
import net.minestom.server.network.packet.server.status.ResponsePacket;
import net.minestom.server.recipe.RecipeCategory;
import net.minestom.server.utils.crypto.KeyUtils;
import org.apache.commons.net.util.Base64;
import org.jglrxavpok.hephaistos.nbt.NBT;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -92,10 +90,10 @@ public static void setupServer() {
),
new DeclareRecipesPacket.DeclaredShapedCraftingRecipe(
"minecraft:torch",
1,
2,
"",
RecipeCategory.Crafting.MISC,
1,
2,
List.of(new Ingredient(List.of(ItemStack.of(Material.COAL))),
new Ingredient(List.of(ItemStack.of(Material.STICK)))),
ItemStack.of(Material.TORCH),
Expand Down

0 comments on commit 9853e10

Please sign in to comment.