提供: Minecraft Modding Wiki
移動先: 案内検索
(FML仕様のパケットシステムに変更。)
 
(3人の利用者による、間の5版が非表示)
1行目: 1行目:
 
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}}
 
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}}
 
 
==パケットについて==
 
==パケットについて==
 
<p>1.7.2でパケット関連のシステムが大幅に変更され、nettyと呼ばれるオープンプロジェクトのシステムを利用したHandshake方式になりました。<br>
 
<p>1.7.2でパケット関連のシステムが大幅に変更され、nettyと呼ばれるオープンプロジェクトのシステムを利用したHandshake方式になりました。<br>
19行目: 18行目:
  
 
     //このMOD用のSimpleNetworkWrapperを生成。チャンネルの文字列は固有であれば何でも良い。MODIDの利用を推奨。
 
     //このMOD用のSimpleNetworkWrapperを生成。チャンネルの文字列は固有であれば何でも良い。MODIDの利用を推奨。
 +
    //チャンネル名は20文字以内の文字数制限があるので注意。
 
     public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("SamplePacketMod");
 
     public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("SamplePacketMod");
  
24行目: 24行目:
 
     public static void init() {
 
     public static void init() {
  
         /*IMesssageHandlerクラスとMessageクラスの登録。今回同じクラスにしているが、別々でもよい。
+
         /*IMesssageHandlerクラスとMessageクラスの登録。
 
         *第三引数:MessageクラスのMOD内での登録ID。256個登録できる
 
         *第三引数:MessageクラスのMOD内での登録ID。256個登録できる
 
         *第四引数:送り先指定。クライアントかサーバーか、Side.CLIENT Side.SERVER*/
 
         *第四引数:送り先指定。クライアントかサーバーか、Side.CLIENT Side.SERVER*/
         INSTANCE.registerMessage(MessageSample.class, MessageSample.class, 0, Side.SERVER);
+
         INSTANCE.registerMessage(MessageSampleHandler.class, MessageSample.class, 0, Side.SERVER);
 
     }
 
     }
 
}</source>
 
}</source>
35行目: 35行目:
 
package mods.samplepacketmod;
 
package mods.samplepacketmod;
  
import cpw.mods.fml.client.FMLClientHandler;
 
import cpw.mods.fml.common.FMLCommonHandler;
 
 
import cpw.mods.fml.common.network.simpleimpl.IMessage;
 
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
 
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
 
 
import io.netty.buffer.ByteBuf;
 
import io.netty.buffer.ByteBuf;
  
public class MessageSample implements IMessage, IMessageHandler<MessageSample, IMessage> {
+
public class MessageSample implements IMessage {
  
     private byte data;
+
     public byte data;
  
 
     public MessageSample(){}
 
     public MessageSample(){}
61行目: 57行目:
 
         buf.writeByte(this.data);
 
         buf.writeByte(this.data);
 
     }
 
     }
 +
}
 +
</source>
 +
 +
 +
===MessageSampleHandler===
 +
<source lang = "java">
 +
package mods.samplepacketmod;
 +
 +
import cpw.mods.fml.common.network.simpleimpl.IMessage;
 +
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
 +
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
 +
import io.netty.buffer.ByteBuf;
 +
 +
public class MessageSampleHandler implements IMessageHandler<MessageSample, IMessage> {
  
 
     @Override//IMessageHandlerのメソッド
 
     @Override//IMessageHandlerのメソッド
     public IMessage onMessage(MessageKeyPressed message, MessageContext ctx) {
+
     public IMessage onMessage(MessageSample message, MessageContext ctx) {
         //クライアントへ送った際に、Worldインスタンスはこのように取れる。
+
         //クライアントへ送った際に、EntityPlayerインスタンスはこのように取れる。
         //FMLClientHandler.instance().getClient().theWorld
+
         //EntityPlayer player = SamplePacketMod.proxy.getEntityPlayerInstance();
 
         //サーバーへ送った際に、EntityPlayerインスタンス(EntityPlayerMPインスタンス)はこのように取れる。
 
         //サーバーへ送った際に、EntityPlayerインスタンス(EntityPlayerMPインスタンス)はこのように取れる。
 
         //EntityPlayer entityPlayer = ctx.getServerHandler().playerEntity;
 
         //EntityPlayer entityPlayer = ctx.getServerHandler().playerEntity;
73行目: 83行目:
 
}
 
}
 
</source>
 
</source>
 +
 +
===CommonProxy(クライアントにMessageを飛ばした際にEntityPlayerを必要とする場合)===
 +
<source lang = "java">
 +
package mods.samplepacketmod;
 +
 +
import net.minecraft.entity.player.EntityPlayer;
 +
public class CommonProxy {
 +
    public EntityPlayer getEntityPlayerInstance() {return null;}
 +
}
 +
</source>
 +
 +
===ClientProxy(クライアントにMessageを飛ばした際にEntityPlayerを必要とする場合)===
 +
<source lang = "java">
 +
package mods.samplepacketmod;
 +
 +
import net.minecraft.client.Minecraft;
 +
import net.minecraft.entity.player.EntityPlayer;
 +
 +
public class ClientProxy extends CommonProxy {
 +
    @Override
 +
    public EntityPlayer getEntityPlayerInstance() {
 +
        return Minecraft.getMinecraft().thePlayer;
 +
    }
 +
}
 +
</source>
 +
 
===@Modクラス内の記述===
 
===@Modクラス内の記述===
 
<source lang = "java">
 
<source lang = "java">
84行目: 120行目:
 
@Mod.Instance("SamplePacketMod")
 
@Mod.Instance("SamplePacketMod")
 
public static SamplePacketMod instance;
 
public static SamplePacketMod instance;
 +
    @SidedProxy(clientSide = "mods.samplepacketmod.ClientProxy", serverSide = "mods.samplepacketmod.CommonProxy")
 +
    public static CommonProxy proxy;
 
@Mod.EventHandler
 
@Mod.EventHandler
 
public void preInit(FMLPreInitializationEvent event)
 
public void preInit(FMLPreInitializationEvent event)
91行目: 129行目:
 
}
 
}
 
</source>
 
</source>
 +
 
===パケットを送る際の記述===
 
===パケットを送る際の記述===
 
<source lang = "java">
 
<source lang = "java">

2017年2月25日 (土) 14:50時点における最新版

この記事は"Minecraft Forge Universal 10.12.1.1090~"を前提MODとしています。

パケットについて[編集]

1.7.2でパケット関連のシステムが大幅に変更され、nettyと呼ばれるオープンプロジェクトのシステムを利用したHandshake方式になりました。
以前ここで解説したパケットシステムはメモリリークを誘発するので、こちらの方法が推奨されています。

ソースコード[編集]

PacketHander[編集]

package mods.samplepacketmod;

import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.Side;


public class PacketHandler {

    //このMOD用のSimpleNetworkWrapperを生成。チャンネルの文字列は固有であれば何でも良い。MODIDの利用を推奨。
    //チャンネル名は20文字以内の文字数制限があるので注意。
    public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("SamplePacketMod");


    public static void init() {

        /*IMesssageHandlerクラスとMessageクラスの登録。
        *第三引数:MessageクラスのMOD内での登録ID。256個登録できる
        *第四引数:送り先指定。クライアントかサーバーか、Side.CLIENT Side.SERVER*/
        INSTANCE.registerMessage(MessageSampleHandler.class, MessageSample.class, 0, Side.SERVER);
    }
}

MessageSample[編集]

package mods.samplepacketmod;

import cpw.mods.fml.common.network.simpleimpl.IMessage;
import io.netty.buffer.ByteBuf;

public class MessageSample implements IMessage {

    public byte data;

    public MessageSample(){}

    public MessageSample(byte par1) {
        this.data= par1;
    }

    @Override//IMessageのメソッド。ByteBufからデータを読み取る。
    public void fromBytes(ByteBuf buf) {
        this.data= buf.readByte();
    }

    @Override//IMessageのメソッド。ByteBufにデータを書き込む。
    public void toBytes(ByteBuf buf) {
        buf.writeByte(this.data);
    }
}


MessageSampleHandler[編集]

package mods.samplepacketmod;

import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;

public class MessageSampleHandler implements IMessageHandler<MessageSample, IMessage> {

    @Override//IMessageHandlerのメソッド
    public IMessage onMessage(MessageSample message, MessageContext ctx) {
        //クライアントへ送った際に、EntityPlayerインスタンスはこのように取れる。
        //EntityPlayer player = SamplePacketMod.proxy.getEntityPlayerInstance();
        //サーバーへ送った際に、EntityPlayerインスタンス(EntityPlayerMPインスタンス)はこのように取れる。
        //EntityPlayer entityPlayer = ctx.getServerHandler().playerEntity;
        //Do something.
        return null;//本来は返答用IMessageインスタンスを返すのだが、旧来のパケットの使い方をするなら必要ない。
    }
}

CommonProxy(クライアントにMessageを飛ばした際にEntityPlayerを必要とする場合)[編集]

package mods.samplepacketmod;

import net.minecraft.entity.player.EntityPlayer;
public class CommonProxy {
    public EntityPlayer getEntityPlayerInstance() {return null;}
}

ClientProxy(クライアントにMessageを飛ばした際にEntityPlayerを必要とする場合)[編集]

package mods.samplepacketmod;

import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;

public class ClientProxy extends CommonProxy {
    @Override
    public EntityPlayer getEntityPlayerInstance() {
        return Minecraft.getMinecraft().thePlayer;
    }
}

@Modクラス内の記述[編集]

package mods.samplepacketmod;

import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;

@Mod(modid="SamplePacketMod", name="SamplePacketMod", version="1.0.0",dependencies="required-after:Forge@[10.12.1.1090,)")
public class SamplePacketMod {
	@Mod.Instance("SamplePacketMod")
	public static SamplePacketMod instance;
    @SidedProxy(clientSide = "mods.samplepacketmod.ClientProxy", serverSide = "mods.samplepacketmod.CommonProxy")
    public static CommonProxy proxy;
	@Mod.EventHandler
	public void preInit(FMLPreInitializationEvent event)
	{
        PacketHandler.init();
	}
}

パケットを送る際の記述[編集]

PacketHandler.INSTANCE.sendToServer(new MessageSample(data));

解説[編集]

Nettyを利用していることには変わりないので、パケット(Message)の書き方が1.6とは大分違ったものとなっている。
ソース内に必要なコメントは載せているので、パケットの流れを解説する。

PacketHandler.INSTANCE.sendToServer

IMessageのtoBytesメソッド

サーバーorクライアントへ

IMessageのfromBytesメソッド

IMessageHandlerのonMessageメソッド
IMessageクラスに引数を指定したコンストラクタを用意する必要はないが、例のように、用意したほうが利便性は高い。