18 déc. 2018, 11:10

Une nouvelle version pour Minecraft 1.15 est disponible ici !

Introduction

Je sais que beaucoup de personnes n’aiment pas utiliser les packets parce qu’ils les trouvent trop compliqués à coder. C’est pour cela que j’ai créé Packeta. Packeta c’est à la fois un outil de développement (plus exactement un annotation processor) qui va créer du code à votre place et une library pour pouvoir utiliser le code généré. Son but est de simplifier le plus possible la création de packets tout en minimisant les données transférées.

Principe

Le principe est simple :

  • Vous créez une classe qui contient les données que vous voulez transférer
  • Vous implémentez une ou les deux interfaces, IClientPacket pour un packet envoyé vers le client ou IServerPacket pour un packet envoyé au serveur
  • Vous ajoutez l’annotation magique @GeneratePacket
  • Packeta crée automatiquement pour vous la classe du packet contenant le constructeur et les méthodes d’envoi de données (fromBytes et toByte)

Bien entendu, il faut enregistrer ce packet sur un network. Pour cela encore plus simple :

  • Vous ajoutez l’annotation @GenerateNetwork sur votre classe principale
  • Packeta génère la classe de votre network qui enregistre tout seul les packets

Exemple

Voici un exemple qui montre quelques possibilités déjà implémentés dans Packeta :

Code de la class de données :

package fr.max2.packeta.test.network;
//imports
@GeneratePacket
public class ExampleData implements IServerPacket
{
	public int someNumber;
	public ItemStack aStack;
	public String[] aStringArray;
	public ArrayList<UUID> collectionOfIds;

	@Override
	public void onServerReceive(EntityPlayerMP sender)
	{
		sender.sendMessage(new TextComponentString("The number is " + this.someNumber));
	}
}

Code de la classe générée :

package fr.max2.packeta.test.network;
//imports
public class ExampleDataMessage extends ExampleData implements IServerMessage
{
	
	public ExampleDataMessage()
	{ }
	
	public ExampleDataMessage(ItemStack aStack, String[] aStringArray, ArrayList<UUID> collectionOfIds, int someNumber)
	{
		this.aStack = aStack;
		this.aStringArray = aStringArray;
		this.collectionOfIds = collectionOfIds;
		this.someNumber = someNumber;
	}

	@Override
	public void toBytes(ByteBuf buf)
	{
		ByteBufUtils.writeItemStack(buf, this.aStack);
		buf.writeInt(this.aStringArray.length);
		for (String aStringArrayElement : this.aStringArray)
		{
			ByteBufUtils.writeUTF8String(buf, aStringArrayElement);
		}
		buf.writeInt(this.collectionOfIds.size());
		for (UUID collectionOfIdsElement : this.collectionOfIds)
		{
			buf.writeLong(collectionOfIdsElement.getMostSignificantBits());
			buf.writeLong(collectionOfIdsElement.getLeastSignificantBits());
		}
		buf.writeInt(this.someNumber);
	}
	
	@Override
	public void fromBytes(ByteBuf buf)
	{
		this.aStack = ByteBufUtils.readItemStack(buf);
		int aStringArrayLength = buf.readInt();
		this.aStringArray = new String[aStringArrayLength];
		for (int aStringArrayIndex = 0; aStringArrayIndex < aStringArrayLength; aStringArrayIndex++)
		{
			this.aStringArray[aStringArrayIndex] = ByteBufUtils.readUTF8String(buf);
		}
		int collectionOfIdsLength = buf.readInt();
		this.collectionOfIds.clear();
		for (int collectionOfIdsIndex = 0; collectionOfIdsIndex < collectionOfIdsLength; collectionOfIdsIndex++)
		{
			this.collectionOfIds.add(new UUID(buf.readLong(), buf.readLong()));
		}
		this.someNumber = buf.readInt();
	}
	
}

Utilisation

Actuellement, le seul moyen d’utiliser Packeta, est de le compiler soit même à partir des sources disponibles sur mon github.
Pour l’ajouter à un projet, il faudra :

  • placer le fichier Packeta-x.y.z-dev.jar dans votre dossier libs/
  • paramétrer gradle pour utiliser Packeta : le plus simple pour cela est d’utiliser le plugin net.ltgt.apt :
plugins {
    id 'net.ltgt.apt' version '0.19'
}
  • vous pouvez aussi ajouter le plugin net.ltgt.apt-eclipse ou net.ltgt.apt-idea pour aussi configurer votre IDE automatiquement. (N’oubliez pas de relancer les commandes de gradle)

Possibilités d’amélioration futures :

  • ajouter la possibilité de faire passer un joueur ou une entité (en passant par son id / UUID)
  • ajouter la possibilité d’utiliser les annotations (@Nullable ou @NonNull par exemple) pour changer la manière dont les données sont enregistrées
  • supporter plus de versions (1.8.x à 1.12.x)
  • ajouter un système similaire pour l’enregistrement de données dans les NBT tags
  • ajouter la possibilité de synchroniser automatiquement des capabilities