如果您在键盘图形用户界面中输入的代码是正确的,我正在尝试使用setBlock命令来放置我的键盘的活动(发出红石电源)版本。我将要向您展示的代码可以完美地在客户端(单人播放器)端运行,但不能在服务器端(多玩家端)运行。代码如下:
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;
} }
GuiKeypad代码:
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对象)切换它,它看起来像是放置了块,但是如果我更新了新块(右键单击它,在它旁边放置一个块,等等),它就消失了。因此,我猜我必须使用worldServerObj,但同样,每当我尝试使用它时,它都会抛出一个NullPointerException,即使我在打开图形用户界面之前就将其设置为服务器的World对象。
我在BlockKeypad类中创建了两个world对象,并向System.out.println()添加了一个item。
当我右键单击它时,它会在控制台(客户端)中打印以下内容:
net.minecraft.multiplayer.WorldClient()
null在服务器控制台中:
null
net.minecraft.multiplayer.WorldServer()有人知道哪里出问题了吗?我非常感谢任何人的帮助,因为这是唯一阻止我发布我的mod的多人兼容版本的东西。谢谢!
发布于 2013-09-26 00:12:30
简单地说,您已经将mod编码为只有一个玩家,这意味着只有当客户端代码和服务器代码在同一运行时环境中执行,并且可以轻松地来回传递对象引用和值时,它才能正确运行。客户端报告WorldServer对象为空的原因是,当连接到专用服务器时,它实际上无法访问任何WorldServer对象(在SSP中,客户端正在运行集成服务器,因此它确实可以访问它)。服务器无法访问WorldClient对象的原因也是如此。
基本上,您需要实现客户端/服务器数据包处理程序,以便客户端发送服务器所需的自定义数据,以确定播放器是否输入了正确的键盘输入并采取适当的操作。这是通过在玩家完成输入密钥代码并提交它时从客户端调度Packet250CustomPayload实例来完成的。Packet250CustomPayload由一个Object[]组成,它可以包含处理请求所需的任何对象类型。为了您的利益,我希望您使用Minecraft作为mod加载机制,因为这是使您的mod同时适用于SSP和SMP的最简单的方法。
这是一个关于在“我的世界”中处理数据包的教程的链接:http://www.minecraftforge.net/wiki/Packet_Handling
下面是指向Treecapitator源代码的另一个链接(这是我的代码,所以可以使用它来学习如何应用数据包处理概念):https://github.com/bspkrs/Treecapitator
此外,Treecapitator包处理代码使用了我所需的依赖关系mod中的一个类来帮助构造包(我不能发布第三个bspkrsCore,因为我没有名誉点):mygithubURL/bspkrsCore/blob/master/src/bspkrs/fml/util/ForgePacketHelper.java
其他提示:
~不检查世界对象是否属于特定的对象类型,而是使用world.isRemote()。当isRemote()为true时,您应该运行特定于客户端的代码;当为false时,您应该运行特定于服务器的代码。
~不要使用单独的线程来修改世界...相反,您应该注册一个新的tick处理程序,以避免并发修改异常。
https://stackoverflow.com/questions/18666908
复制相似问题