当前位置: 首页 > 知识库问答 >
问题:

Minecraft Modding-如何在服务器端使用setBlock?

端木明贤
2023-03-14

我试图使用setBlock命令来放置我的小键盘的活动(给出红石电源)版本,如果你在小键盘GUI中键入的代码是正确的。我将要向您展示的代码在客户端(单人游戏)端工作得很好,但在服务器(多人游戏)端却不行。代码如下:

BlockKeypad“在BlockActivated上”

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;
}           

}

GuikePad代码:

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();
            }
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();
    }
}
net.minecraft.multiplayer.WorldClient()
null

在服务器控制台中:

null
net.minecraft.multiplayer.WorldServer()

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

共有1个答案

薄涵衍
2023-03-14

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

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

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

此外,Treecapitator数据包处理代码使用了我所需的依赖项mod bspkrsCore中的一个类来帮助构造数据包(因为我没有信誉点,所以不能发布第三个URL):[mygithubURL]/bspkrsCore/blob/master/src/bspkrs/fml/util/forgePacketHelper.java

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

 类似资料:
  • 问题内容: 收到以下错误: TypeError:Object.values不是函数。 从这个对计算器的问题-我看是不是在所有的浏览器都支持。 但是我在服务器端的Node.js中使用该功能-如何在Node.js中使用它看起来如此直观? 问题答案: 是ES2017中的新功能。这是非常出血的边缘。从7.0版开始,Node.js完全支持它。 6.8.1支持它,但是它被认为是不稳定的并且被锁定在标志后面。

  • 我正在使用收集器跟踪java服务中的跨度,这一服务是http和grpc。收集器终结点是localhost:55680。此java服务跟踪成功。 现在,我想使用这个收集器基于gRPC跟踪我的go服务。 在我的go服务中,我复制以下文件:interceptor。去grpctrace。从repo opentelemetry转到contrib,这里https://github.com/open-telem

  • 问题内容: 我想要一个PHP脚本,它允许您ping IP地址和端口号()。我找到了类似的脚本,但是它仅适用于网站,而不适用于。 我想要一个游戏服务器。 这个想法是我可以输入IP地址和端口号,然后得到ping响应。 问题答案: 我认为这个问题的答案几乎可以概括您的问题。 如果您要查找给定主机是否将在端口80上接受TCP连接,则可以执行以下操作: 对于TCP以外的任何其他东西,都会更加困难(尽管由于您

  • 我将创建一个身份验证服务器,它本身与一组不同的Oauth2.0服务器交互。Netty似乎是在这里实现网络部分的一个很好的候选者。但在开始之前,我需要澄清一些关于netty的细节,因为我是新手。例行程序如下: > < li> 服务器接受来自客户端的HTTPS连接。 然后,不关闭第一个连接,它通过HTTPS与远程OAuth2.0服务器建立另一个连接并获取数据 毕竟,服务器将结果发送回客户端,客户端应该

  • 在开发阶段,在页面中嵌入一个 Less.js 将Less在线编译成CSS样式,确实很方便。但是,在线编译会产生加载延迟,即便在浏览器中有不足一秒的加载延迟,也会降低性能。如果Javascrip执行错误,还会引起美观问题。因此,在生产环境中,并不推荐这种方式,而是推荐在服务器端使用Less。 在服务器端使用Less,需要借助于 Less 的编译器,由它将 Less 源文件编译成最终的 CSS 文件。

  • 问题内容: 使用以下选项启动Java应用程序时: Java使用临时端口,这对于避免冲突非常有用。 是否可以从应用程序内部以编程方式获取实际端口(或连接URL)? 问题答案: 这将打印如下网址