gpt4 book ai didi

java - Minecraft 模组 - 如何在服务器端使用 setBlock?

转载 作者:行者123 更新时间:2023-12-01 14:09:16 27 4
gpt4 key购买 nike

如果您在键盘 GUI 中输入的代码正确,我将尝试使用 setBlock 命令来放置我的键盘的 Activity (发出红石电源)版本。我将向您展示的代码在客户端(单人游戏)端可以完美运行,但在服务器(多人游戏)端则不能。代码如下:

BlockKeypad“onBlockActivated”代码:

public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9){
this.playerObj = par5EntityPlayer;
this.lastKeypadX = par2;
this.lastKeypadY = par3;
this.lastKeypadZ = par4;

if(par1World instanceof WorldServer){
this.worldServerObj = par1World;
TileEntityKeypad TEK = (TileEntityKeypad) par1World.getBlockTileEntity(par2, par3, par4);
System.out.println(TEK.getKeypadCode() + " | Code from TileEntity");

this.openCode = TEK.getKeypadCode();
if(TEK.getKeypadCode() == 0){
par5EntityPlayer.openGui(mod_SecurityCraft.instance, 1, par1World, par2, par3, par4);
}else{
par5EntityPlayer.openGui(mod_SecurityCraft.instance, 0, par1World, par2, par3, par4);
}

return true;
}else{
this.worldObj = par1World;
//Rest of client code here


return true;
}

}

Gui键盘代码:

private void checkCode(String par1String) {
int code = 0;
try{
code = Integer.parseInt(par1String);
}catch(Exception e){
e.printStackTrace();
}

System.out.println(BlockKeypad.openCode + " | GUI");
if(code == BlockKeypad.openCode){
new ScheduleUpdate(3, BlockKeypad.worldServerObj, BlockKeypad.lastKeypadX,BlockKeypad.lastKeypadY, BlockKeypad.lastKeypadZ, BlockKeypad.openCode, this.keypadInventory);
BlockKeypad.playerObj.closeScreen();
}

}

ScheduleUpdate 类:

public class ScheduleUpdate{
Timer timer;
private int xCoord;
private int yCoord;
private int zCoord;
private int metadata;
private int passcode;
private TileEntityKeypad TEK;
public ScheduleUpdate(int seconds, World par2World, int par3, int par4, int par5, int par6, TileEntityKeypad keypadInventory){
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000); //TODO 60
xCoord = par3;
yCoord = par4;
zCoord = par5;
passcode = par6;
TEK = keypadInventory;
//BlockKeypad.shouldCheckMeta = false;

metadata = par2World.getBlockMetadata(par3, par4 , par5);
System.out.println(metadata + " | metadata");
par2World.setBlock(par3, par4, par5, mod_SecurityCraft.KeypadActive.blockID, metadata, 3);
par2World.notifyBlocksOfNeighborChange(par3, par4 , par5, mod_SecurityCraft.KeypadActive.blockID);

}
class RemindTask extends TimerTask{

public void run(){
BlockKeypad.worldObj.setBlock(xCoord, yCoord, zCoord, mod_SecurityCraft.Keypad.blockID, metadata, 3);
BlockKeypad.worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, mod_SecurityCraft.Keypad.blockID);

((TileEntityKeypad) BlockKeypad.worldObj.getBlockTileEntity(xCoord, yCoord, zCoord)).setKeypadCode(passcode);


timer.cancel();
}
}

}

如果我使用我现在拥有的这段代码,出于某种原因,当我创建一个新的 ScheduleUpdate 对象(在 GuiKeypad 代码中)时,它会在 BlockKeypad.worldServerObj 上给我一个 NullPointerException 。如果我用 BlockKeypad.worldObj (我的客户端 World 对象)切换它,它看起来像是放置了该 block ,但如果我更新新 block (右键单击它,在它旁边放置一个 block 等),它就会消失。所以我猜我必须使用 worldServerObj,但同样,每当我尝试使用它时,它都会抛出 NullPointerException,即使我在 GUI 打开之前设置为服务器的 World 对象。

我为 System.out.println() 创建了一个项目,这是我在 BlockKeypad 类中创建的两个世界对象。

当我右键单击它时,它会在控制台(客户端)中打印:

net.minecraft.multiplayer.WorldClient()
null

在服务器控制台中:

null
net.minecraft.multiplayer.WorldServer()

有人知道这是怎么回事吗?我将非常感谢任何帮助,因为这是唯一阻止我发布多人游戏兼容版本的 mod 的原因。谢谢!

最佳答案

简单的回答是,您已将 mod 编码为仅单人游戏,这意味着只有客户端代码和服务器代码在同一运行时环境中执行并且可以轻松传递对象引用和值来回。您的客户端报告 WorldServer 对象为 null 的原因是,当连接到专用服务器时,它实际上无法访问任何 WorldServer 对象(在 SSP 中,客户端正在运行集成服务器,因此它可以访问它) 。这同样适用于服务器无法访问 WorldClient 对象的原因。

基本上,您需要为客户端实现客户端/服务器数据包处理程序,以发送服务器所需的自定义数据,以确定玩家是否输入了正确的键盘条目并采取适当的操作。这是通过当玩家完成输入键码并提交时从客户端分派(dispatch) Packet250CustomPayload 实例来完成的。 Packet250CustomPayload 由一个 Object[] 组成,其中可以包含处理请求所需的任何对象类型。为了您的利益,我希望您使用 Minecraft Forge 作为 mod 加载机制,因为这是让您的 mod 同时适用于 SSP 和 SMP 的最简单方法。

以下是 Minecraft 中数据包处理教程的链接:http://www.minecraftforge.net/wiki/Packet_Handling

这是 Treecapitator 源代码的另一个链接(这是我的代码,因此请随意使用它来学习如何应用数据包处理概念):https://github.com/bspkrs/Treecapitator

此外,Treecapitator 数据包处理代码使用我所需的依赖项 mod bspkrsCore 中的一个类,该类有助于构建数据包(我无法发布第三个 URL,因为我没有信誉点):[mygithubURL]/bspkrsCore/blob/master/src/bspkrs/fml/util/ForgePacketHelper.java

其他提示:
~ 使用 world.isRemote() 代替检查 World 对象是否属于特定对象类型。当 isRemote() 为 true 时,您应该运行特定于客户端的代码,当 isRemote() 为 false 时,您应该运行特定于服务器的代码。
~ 不要使用单独的线程来修改世界...您应该注册一个新的刻度处理程序以避免并发修改异常。

关于java - Minecraft 模组 - 如何在服务器端使用 setBlock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18666908/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com