Minecraft 1.12.2模组开发(五十六) 网络(Networking)

news2025/2/27 4:57:09

我们本次在模组中实现客户端向服务器发送数据的功能。

key+network.gif
演示效果 演示效果 演示效果

1.新建packet包,包中新建PacketHandler类:

PacketHandler.java

package com.joy187.mcjoygun.packet;

import com.joy187.mcjoygun.Main;
import com.joy187.mcjoygun.utils.SerializableUtil;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetHandler;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.FMLEventChannel;
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;

public class PacketHandler {
//    public static final String[] CHANNELS = {"testmsg", "levelupclasses"};
//    public static FMLEventChannel initChannel,otherChannel;

    public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(Main.MODID);
    static int id = 0;

    public static void init() {
        PacketHandler handler = new PacketHandler();
        //注册该数据包类
        INSTANCE.registerMessage(MessageRangeAttackHandler.class, MessageRangeAttack.class, id++, Side.SERVER);

        MinecraftForge.EVENT_BUS.register(handler);
    }

}

在项目主类Main中的preInit类中添加PacketHandler的初始化函数:

Main.java

    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        PacketHandler.init();
        //RegistryHandler.preInitRegistries(event);
    }

2.packet包中新建一个MessageRangeAttack类:

MessageRangeAttack.java


package com.joy187.mcjoygun.packet;

import com.google.common.collect.Maps;

import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;

import java.util.Map;

public class MessageRangeAttack implements IMessage {

    public RangeAttackState mode;
    //定义几个可以枚举的攻击状态,之后会用到
    public enum RangeAttackState{UPKEY(1),
        BLISTERING(2),
        STORM(3);

        private final byte data;


        public static RangeAttackState getState(byte data){
            return stateMap.get(data);
        }
        private static final Map<Byte,RangeAttackState> stateMap = Maps.newHashMap();

        static {
            for (RangeAttackState value : values())
            {
                stateMap.put(value.data, value);
            }
        }

        RangeAttackState(int value){
            data = (byte)value;
        }

        public byte getData() {
            return data;
        }
    }

    public MessageRangeAttack(){};

    public MessageRangeAttack(RangeAttackState mode){
        this.mode = mode;
    }

    @Override
    public void fromBytes(ByteBuf buf) {
        this.mode = RangeAttackState.getState(buf.readByte());
    }

    @Override
    public void toBytes(ByteBuf buf) {
        buf.writeByte(this.mode.getData());
    }
}

同时新建一个MessageRangeAttackHandler类,作为上面那个类的管理器:

MessageRangeAttackHandler.java

package com.joy187.mcjoygun.packet;


import com.joy187.mcjoygun.items.ToolXuanFeng;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;


public class MessageRangeAttackHandler implements IMessageHandler<MessageRangeAttack,IMessage> {

    @Override
    public IMessage onMessage(MessageRangeAttack message, MessageContext ctx) {

        if(ctx.getServerHandler() == null) return null;
        EntityPlayerMP entityPlayer = ctx.getServerHandler().player;
        if(entityPlayer == null) return null;
        
        entityPlayer.getServerWorld().addScheduledTask(() -> {
            ItemStack stack = entityPlayer.getHeldItem(EnumHand.MAIN_HAND);
            //检查玩家手上是否拿着特定的武器,如果持有该武器就可以向服务器发送数据包
            if (!stack.isEmpty() && stack.getItem() instanceof ToolXuanFeng) {
                //输出yes
                System.out.println("yes");
                ((ToolXuanFeng) stack.getItem()).doRangeAttack(stack, entityPlayer, message.mode);
            }
        });

        return null;
    }
}

3.我们在KeyboardManager中给这个武器绑定两个键位事件:

KeyboardManager.java

@Mod.EventBusSubscriber
public class KeyboardManager {

    public static void init() {
        for (KeyBinding key:
             ClientProxy.KEY_BINDINGS) {
            ClientRegistry.registerKeyBinding(key);
        }
    }

    @SideOnly(Side.CLIENT)
    @SubscribeEvent
    public static void onKeyPressed(InputEvent.KeyInputEvent event) {
        
        //按键1按下就向服务器发送一个包,攻击状态为UPKEY
        if (ClientProxy.KEY1.isPressed()) {

            PacketHandler.INSTANCE.sendToServer(new MessageRangeAttack(MessageRangeAttack.RangeAttackState.UPKEY));
        }
        
        //按键2按下就向服务器发送一个包,攻击状态为STORM
        if(ClientProxy.KEY2.isPressed()){
            PacketHandler.INSTANCE.sendToServer(new MessageRangeAttack(MessageRangeAttack.RangeAttackState.STORM));
        }
    }
}

在项目主类中添加键位管理的初始化函数:

Main.java

    @EventHandler
    public void init(FMLInitializationEvent event)
    {
        MinecraftForge.EVENT_BUS.register(this);
        FMLCommonHandler.instance().bus().register(this);
        //添加键位管理的注册函数
        if (!proxy.isServer())
        {
            KeyboardManager.init();
        }
    }

4.准备一个武器类ToolXuanFeng,对范围攻击状态进行定义:

ToolXuanFeng.java

package com.joy187.mcjoygun.items;

import com.joy187.mcjoygun.Main;
import com.joy187.mcjoygun.init.ItemInit;
import com.joy187.mcjoygun.packet.MessageRangeAttack;
import com.joy187.mcjoygun.packet.PacketHandler;
import com.joy187.mcjoygun.utils.IhasModel;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemAxe;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.SoundCategory;
import net.minecraft.world.World;

import java.util.EnumSet;

public class ToolXuanFeng extends ItemAxe implements IhasModel {
    public ToolXuanFeng(String name, CreativeTabs tab, ToolMaterial material) {
        super(material,34.0F,-3.3F);
        setUnlocalizedName(name);
        setRegistryName(name);
        setCreativeTab(tab);

        ItemInit.ITEMS.add(this);
    }

    //该武器的范围攻击函数
    public void doRangeAttack(ItemStack item, EntityLivingBase entity, MessageRangeAttack.RangeAttackState mode) {
        //函数被调用时输出okokok
        System.out.println("okokok");
        switch(mode) {
            //当攻击状态为UPKEY时,就释放大爆炸
            case UPKEY: {
                entity.world.createExplosion(entity, entity.posX, entity.posY, entity.posZ, (float) (4.0D + entity.getRNG().nextDouble() * 1.5D * 1), true);
                break;
            }
            //当攻击状态为STORM时,就产生雷鸣
            case STORM:{
                entity.world.addWeatherEffect(new EntityLightningBolt(entity.world, entity.posX, entity.posY, entity.posZ, true));
                //entity.world.setLastLightningBolt(2);
                break;
            }
        }

    }

    @Override
    public void registerModels() {
        Main.proxy.registerItemRenderer(this, 0, "inventory");
    }
}

在ItemInit中注册该武器:

ItemInit.java

    public static final ItemAxe FENBAOCHUI = new ToolXuanFeng("xuanfengaxe", Main.ITEM_TAB, MATERIAL_XUANFENG);

5.保存代码 -> 进行调试。

你可以在控制台查看数据包是否发送:在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/412878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Huggingface微调BART的代码示例:WMT16数据集训练新的标记进行翻译

BART模型是用来预训练seq-to-seq模型的降噪自动编码器&#xff08;autoencoder&#xff09;。它是一个序列到序列的模型&#xff0c;具有对损坏文本的双向编码器和一个从左到右的自回归解码器&#xff0c;所以它可以完美的执行翻译任务。 如果你想在翻译任务上测试一个新的体系…

Java Stream API 操作完全攻略:让你的代码更加出色 (四)

前言 Java Stream 是一种强大的数据处理工具&#xff0c;可以帮助开发人员快速高效地处理和转换数据流。使用 Stream 操作可以大大简化代码&#xff0c;使其更具可读性和可维护性&#xff0c;从而提高开发效率。本文将为您介绍 Java Stream 操作的所有方面&#xff0c;包括 ran…

交友项目【通用设置】三个功能实现

目录 1&#xff1a;交友项目【通用设置】 1.1&#xff1a;查询通用设置 1.1.1&#xff1a;接口地址 1.1.2&#xff1a;流程分析 1.1.3&#xff1a;代码实现 1.2&#xff1a;设置陌生人问题 1.2.1&#xff1a;接口地址 1.2.2&#xff1a;流程分析 1.2.3&#xff1a;代码…

Python 小型项目大全 51~55

五十一、九十九瓶的变体 原文&#xff1a;http://inventwithpython.com/bigbookpython/project51.html 在歌曲“九十九瓶”的这个版本中&#xff0c;该程序通过删除一个字母、交换一个字母的大小写、调换两个字母或重叠一个字母&#xff0c;在每个小节中引入了一些小的不完美。…

4月,我从外包公司离职了

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

python学习

1.安装 Download Python | Python.org 安装时&#xff0c;点击添加路径。 1.1 python的解释器 我们把代码写进.py结尾的文件里&#xff0c;然后 python 路径文件名就可以运行它了。 2.字面量 例如print("我们"),"我们",就是字符串字面量&#xff0c;…

简化你的代码,提高生产力:这10个Lambda表达式必须掌握

前言 Lambda表达式是一种在现代编程语言中越来越常见的特性&#xff0c;可以简化代码、提高生产力。这篇文章将介绍10个必须掌握的Lambda表达式&#xff0c;这些表达式涵盖了在实际编程中经常用到的常见场景&#xff0c;例如列表操作、函数组合、条件筛选等。通过学习这些Lambd…

JUC源码系列-CountDownLatch源码研读

前言 CountDownLatch是一个很有用的工具&#xff0c;latch是门闩的意思&#xff0c;该工具是为了解决某些操作只能在一组操作全部执行完成后才能执行的情景。例如&#xff0c;小组早上开会&#xff0c;只有等所有人到齐了才能开&#xff1b;再如&#xff0c;游乐园里的过山车&…

运行时内存数据区之堆(二)

Minor GC、Major GC、与Full GC JVM在进行GC时&#xff0c;并非每次都对上面三个内存&#xff08;新生代、老年代&#xff1a;方法区&#xff09;区域一起回收的&#xff0c;大部分时候回收的都是指新生代。 针对HotSpot VM的实现&#xff0c;它里面的GC按照回收区域又分为两…

浅谈 如果做微服务了 这个模块怎么去划分?

如果做微服务了 这个模块怎么去划分&#xff1f; 还是高内聚 低耦合的一个思想吧 &#xff0c;单一职责的设计原则&#xff0c;也是一个封装的思想吧&#xff0c; 业务维度&#xff1a; ​ 按照业务的关联程度来决定&#xff0c;关联比较密切的业务适合拆分为一个微服务&…

C++语法(14)---- 模板进阶

C语法&#xff08;13&#xff09;---- 模拟实现priority_queue_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/130069707?spm1001.2014.3001.5501 目录 1.非类型模板参数 2.模板的特化 1.函数模板(仿函数) 2.类模板 1.全特化 2.半特化、偏…

INFINONE XC164单片机逆向记录(6)C语言学习

本人所写的博客都为开发之中遇到问题记录的随笔,主要是给自己积累些问题。免日后无印象,如有不当之处敬请指正(欢迎进扣群 24849632 探讨问题); 写在专栏前面https://blog.csdn.net/Junping1982/article/details/129955766 INFINONE XC164单片机逆向记录(1)资料准备

FusionCharts Suite XT v3.20.0 Crack

FusionCharts Suite XT v3.20.0 改进了仪表的径向条形图和调整大小功能。2023 年 4 月 11 日 - 9:37新版本特征 添加了一个新方法“_changeXAxisCoordinates”&#xff0c;它允许用户将 x 轴更改为在图例或数据交互时自动居中对齐。更新了 Angular 集成以支持 Angular 版本 14 …

【无功优化】基于多目标差分进化算法的含DG配电网无功优化模型【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

SAM - 分割一切图像【AI大模型】

如果你认为 AI 领域已经通过 ChatGPT、GPT4 和 Stable Diffusion 快速发展&#xff0c;那么请系好安全带&#xff0c;为 AI 的下一个突破性创新做好准备。 推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 Meta 的 FAIR 实验室刚刚发布了 Segment Anything Model (SAM)&am…

电脑软件:推荐一款Windows剪贴板增强软件——ClipX

目录 ClipX能做什么&#xff1f; 软件优点 软件不足之处 今天要介绍的剪切板神器——ClipX&#xff0c;拥有它可以作为弥补Windows 自带的剪贴板的短板的增强型工具软件。 ClipX能做什么&#xff1f; 1. 扩充剪贴板数量&#xff0c;数量可以自己设置 ClipX支持4到1024个剪…

Flutter(三)--可滚动布局

之前介绍了布局和容器&#xff0c;它们都用于摆放一个或多个子组件&#xff0c;而实际应用中&#xff0c;受限于手机、Pad、电脑的屏幕大小&#xff0c;一个布局不可能摆放无限个组件&#xff0c;我们往往采取滚动的方式&#xff0c;来使得一部分组件展示在屏幕上&#xff0c;一…

L2-041 插松枝PTA

人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送器&#xff0c;每次推送一…

piwigo安装及初步使用

一 摘要 本文主要介绍piwigo 安装及初步使用&#xff0c;nginx \php\mysql 等使用 docker 安装 二 环境信息 2.1 操作系统 CentOS Linux release 7.9.2009 (Core)2.2 piwigo piwigo-13.6.0.zip三 安装 3.1安装资源下载 piwigo 请到官网下载https://piwigo.org 安装步骤也…

【STL九】关联容器——map容器、multimap容器

【STL九】关联容器——map容器、multimap容器一、map简介二、头文件三、模板类四、map的内部结构五、成员函数1、迭代器2、元素访问3、容量4、修改操作~~5、操作~~5、查找6、查看操作六、demo1、查找find2、查找lower_bound、upper_bound3、insert、emplace() 和 emplace_hint(…