Jump to content

[1.7.10][Solved]GUI that chnges tile entity variables doesn't work


Recommended Posts

Posted

Hi.

I have a block called Password Lock that when you set up your code and receiver for it, when you type right code, receiver sends a redstone signel. For receiver, I have done this through metadata.

And the password lock through tile entity. But there isn's this problem. Problem is in it's gui. I opened it through

Minecraft.getMinecraft().displayGuiScreen(new PasswordLockScreen(world, x, y, z))

and it worked fine, but when I tried it in Lan(First player,(Me from first window, and opened LAN through this window) and second player playing through another window(All on one computer)

When first player opened it's GUI, it displayed to him, but when second player tried this, nothing happens to him, but it displayed to first player.

Then, I tried this using player.openGUI() <Through GUI Handler> and GUI opens, but when I typed right password and clicked UNLOCK, nothing happened.

I think it is because it has to be opened on server side, but GUI screen opens on client side and this block has no container because it has no slots.

And when you decide to delete my topic, please send me a reason.

In my code I currently use MainLib.openGui(new PasswordLockScreen(world, x, y, z)) that does Minecraft.getMinecraft().displayGuiScreen(new PasswordLockScreen(world, x, y, z));

This blocks also has a feature for changing password, that is PasswordChangeScreen.java

 

Here is my code.

 

 

Block:

package com.ec.blocks;

import com.ec.Main.MainRegistry;
import com.ec.Main.TabTMPI;
import com.ec.items.ItemWrench;
import com.ec.lib.MainLib;
import com.ec.lib.RefStrings;
import com.ec.screen.PasswordLockScreen;
import com.ec.tileentity.TileEntityPasswordLock;

import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

public class BlockPasswordLock extends Block{

public BlockPasswordLock()
{
	super(Material.anvil);
	this.setBlockName("blockPasswordLock");
	this.setBlockTextureName(RefStrings.MODID + ":PasswordLock");
	this.setBlockUnbreakable();
	this.setCreativeTab(TabTMPI.tab);
}

public static Block block;

public static void mainRegistry()
{
	block = new BlockPasswordLock();
	GameRegistry.registerBlock(block, block.getUnlocalizedName());
}

@Override
public TileEntity createTileEntity(World world, int metadata)
{
	return new TileEntityPasswordLock();
}

@Override
public boolean hasTileEntity(int metadata)
{
	return true;
}

@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entity, ItemStack item)
{
	TileEntityPasswordLock tile = (TileEntityPasswordLock) world.getTileEntity(x, y, z);
	tile.validPassword = "0000";
	tile.owner = entity.getCommandSenderName();
	tile.direction = MainLib.getEntityLookingDirection(entity);
}

@Override
public boolean onBlockActivated(World world, int bX, int bY, int bZ, EntityPlayer player, int metadata, float pX, float pY, float pZ)
{
	TileEntityPasswordLock tile = (TileEntityPasswordLock)world.getTileEntity(bX, bY, bZ);

	String playerName = new String(player.getCommandSenderName());

	ItemStack currentItemStack = player.getCurrentEquippedItem();
	Item wrench = ItemWrench.item;
	Item currentItem = null;

	boolean isOwner = playerName.equals(tile.owner);
	boolean hasWrench = false;

	if(currentItemStack != null)
	{
		currentItem = currentItemStack.getItem();
		hasWrench = currentItem.equals(wrench);
	}

	if(hasWrench)
	{
		if(hasWrench && isOwner)
		{
			world.removeTileEntity(bX, bY, bZ);

			float[] position = new float[3];
			position = MainLib.centerBlock(bX, bY, bZ);
			Item itemToDrop = Item.getItemFromBlock(world.getBlock(bX, bY, bZ));

			MainLib.spawnItemDrop(world, position[0], position[1], position[2], new ItemStack(itemToDrop));
			MainLib.destroyBlock(world, bX, bY, bZ);
		}
	}
	else
	{
		MainLib.openGui(world, new PasswordLockScreen(world, bX, bY, bZ));
	}

	return true;
}

public static IIcon[] iconSouth = new IIcon[6];
public static IIcon[] iconWest = new IIcon[6];
public static IIcon[] iconNorth = new IIcon[6];
public static IIcon[] iconEast = new IIcon[6];
public static IIcon[] invRenderIcon = new IIcon[6];

@Override
public void registerBlockIcons(IIconRegister reg)
{
	MainLib.createIcon(reg, iconNorth, "ComObs", "ComObs", "PasswordLock", "ComObs", "ComObs", "ComObs");
	MainLib.createIcon(reg, iconEast, "ComObs", "ComObs", "ComObs", "ComObs", "ComObs", "PasswordLock");
	MainLib.createIcon(reg, iconSouth, "ComObs", "ComObs", "ComObs", "PasswordLock", "ComObs", "ComObs");
	MainLib.createIcon(reg, iconWest, "ComObs", "ComObs", "ComObs", "ComObs", "PasswordLock", "ComObs");

	invRenderIcon[0] = reg.registerIcon(RefStrings.MODID + ":ComObs");
	invRenderIcon[1] = reg.registerIcon(RefStrings.MODID + ":ComObs");
	invRenderIcon[2] = reg.registerIcon(RefStrings.MODID + ":ComObs");
	invRenderIcon[3] = reg.registerIcon(this.textureName);
	invRenderIcon[4] = reg.registerIcon(RefStrings.MODID + ":ComObs");
	invRenderIcon[5] = reg.registerIcon(RefStrings.MODID + ":ComObs");

}

@Override
public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side)
{
	IIcon icon = null;

	TileEntityPasswordLock tile = (TileEntityPasswordLock)world.getTileEntity(x, y, z);

	switch(tile.direction)
	{
	case 0:
		icon = iconSouth[side];
		break;
	case 1:
		icon = iconWest[side];
		break;
	case 2:
		icon = iconNorth[side];
		break;
	case 3:
		icon = iconEast[side];
		break;
	}

	return icon;
}

@Override
public IIcon getIcon(int side, int metadata)
{
	return invRenderIcon[side];
}

@Override
public boolean canProvidePower()
{
	return true;
}
}

 

Block's tile entity:

package com.ec.tileentity;

import com.ec.blocks.BlockRemoteReceiver;
import com.ec.lib.MainLib;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;

public class TileEntityPasswordLock extends TileEntity{

public String validPassword = "0000";
public int direction = 0;
public boolean active = false;
public String owner;
public int[] remoteLocation = new int[3];

@Override
public void readFromNBT(NBTTagCompound tag)
{
	super.readFromNBT(tag);
	this.validPassword = tag.getString("validPassword");
	this.direction = tag.getInteger("direction");
	this.active = tag.getBoolean("active");
	this.owner = tag.getString("owner");
	this.remoteLocation = tag.getIntArray("remoteLocation");
}

@Override
public void writeToNBT(NBTTagCompound tag)
{
	super.writeToNBT(tag);
	tag.setString("validPassword", validPassword);
	tag.setInteger("direction", direction);
	tag.setBoolean("active", active);
	tag.setString("owner", owner);
	tag.setIntArray("remoteLocation", remoteLocation);
}

@Override
public boolean canUpdate()
{
	return true;
}

@Override
public void updateEntity()
{
	if(this.active && this.remoteLocation != null && worldObj.getBlock(remoteLocation[0], remoteLocation[1], remoteLocation[2]).equals(BlockRemoteReceiver.block))
	{
		int x = remoteLocation[0];
		int y = remoteLocation[1];
		int z = remoteLocation[2];
		worldObj.setBlockMetadataWithNotify(x, y, z, 1, 1 + 2);
	}
	else
	{
		int x = remoteLocation[0];
		int y = remoteLocation[1];
		int z = remoteLocation[2];
		worldObj.setBlockMetadataWithNotify(x, y, z, 0, 1 + 2);
	}
}

public Packet getDescriptionPacket()
{
	NBTTagCompound tag = new NBTTagCompound();
	writeToNBT(tag);
	return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, tag);
}

public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet)
{
	readFromNBT(packet.func_148857_g());
}

}

 

Block's gui screen:

package com.ec.screen;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ChatLine;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.stream.ChatController;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderGameOverlayEvent.Chat;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

import com.ec.lib.MainLib;
import com.ec.lib.RefStrings;
import com.ec.tileentity.TileEntityPasswordLock;

public class PasswordLockScreen extends GuiScreen{
int screenWidth = 196;
int screenHeight = 169;

public static int id = 20;

public static World world;
public static int x;
public static int y;
public static int z;
private String enteredPassword = "";
private String validation = "";
private String owner = "";

public PasswordLockScreen(World world, int x, int y, int z)
{
	this.world = world;
	this.x = x;
	this.y = y;
	this.z = z;

	TileEntityPasswordLock tile = (TileEntityPasswordLock)world.getTileEntity(x, y, z);
	this.owner = tile.owner;
}

@Override
public void drawScreen(int x, int y, float tick)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	GL11.glColor4f(1, 1, 1, 1);
	drawDefaultBackground();
	mc.renderEngine.bindTexture(new ResourceLocation(RefStrings.MODID, "textures/gui/PasswordGui.png"));
	drawTexturedModalRect(screenX, screenY, 0, 0, screenWidth, screenHeight);
	fontRendererObj.drawString(enteredPassword, screenX + 36, screenY + 11, 0);
	fontRendererObj.drawString("Owner:", screenX + 115, screenY + 110, 0);
	fontRendererObj.drawString(owner, screenX + 115, screenY + 125, 0);
	fontRendererObj.drawString(validation, screenX + 110, screenY + 11, 0);

	super.drawScreen(x, y, tick);
}

@Override
public void initGui()
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	buttonList.clear();
	GuiButton one;
	GuiButton two;
	GuiButton three;
	GuiButton four;
	GuiButton five;
	GuiButton six;
	GuiButton seven;
	GuiButton eight;
	GuiButton nine;
	GuiButton zero;
	GuiButton unlock;
	GuiButton lock;
	GuiButton erase;
	GuiButton changePassword;

	buttonList.add(one = new GuiButton(1, screenX + 25, screenY + 25, 10, 10, "1"));
	buttonList.add(two = new GuiButton(2, screenX + 45, screenY + 25, 10, 10, "2"));
	buttonList.add(three = new GuiButton(3, screenX + 65, screenY + 25, 10, 10, "3"));
	buttonList.add(four = new GuiButton(4, screenX + 25, screenY + 45, 10, 10, "4"));
	buttonList.add(five = new GuiButton(5, screenX + 45, screenY + 45, 10, 10, "5"));
	buttonList.add(six = new GuiButton(6, screenX + 65, screenY + 45, 10, 10, "6"));
	buttonList.add(seven = new GuiButton(7, screenX + 25, screenY + 65, 10, 10, "7"));
	buttonList.add(eight = new GuiButton(8, screenX + 45, screenY + 65, 10, 10, "8"));
	buttonList.add(nine = new GuiButton(9, screenX + 65, screenY + 65, 10, 10, "9"));
	buttonList.add(zero = new GuiButton(0, screenX + 45, screenY + 85, 10, 10, "0"));
	buttonList.add(unlock = new GuiButton(10, screenX + 35, screenY + 100, 15, 20, "Unlock"));
	buttonList.add(lock = new GuiButton(11, screenX + 65, screenY + 100, 15, 20, "Lock"));
	buttonList.add(erase = new GuiButton(12, screenX + 85, screenY + 45, 15, 20, "Clear"));
	buttonList.add(changePassword = new GuiButton(13, screenX + 125, screenY + 55, 35, 20, "Change password"));
	super.initGui();
}

@Override
public void actionPerformed(GuiButton button)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	TileEntityPasswordLock tileEntity = (TileEntityPasswordLock)world.getTileEntity(x, y, z);

	switch(button.id)
	{
	case 0:
		enteredPassword = enteredPassword + "0";
		break;
	case 1:
		enteredPassword = enteredPassword + "1";
		break;
	case 2:
		enteredPassword = enteredPassword + "2";
		break;
	case 3:
		enteredPassword = enteredPassword + "3";
		break;
	case 4:
		enteredPassword = enteredPassword + "4";
		break;
	case 5:
		enteredPassword = enteredPassword + "5";
		break;
	case 6:
		enteredPassword = enteredPassword + "6";
		break;
	case 7:
		enteredPassword = enteredPassword + "7";
		break;
	case 8:
		enteredPassword = enteredPassword + "8";
		break;
	case 9:
		enteredPassword = enteredPassword + "9";
		break;
	case 10:
		if(enteredPassword.equals(tileEntity.validPassword))
		{
			tileEntity.active = true;
			validation = "succesful";
		}
		else
		{
			validation = "wrong pass";
		}
		break;
	case 11:
		tileEntity.active = false;
		break;
	case 12:
		enteredPassword = "";
		validation = "";
		break;
	case 13:
		if(enteredPassword.equals(tileEntity.validPassword))
		{
			MainLib.openGui(world, new PasswordChangeScreen(world, x, y, z));
		}
		else
		{
			validation = "wrong pass";
		}
		break;
	default:
		break;
	}
}

@Override
public void keyTyped(char c, int key)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	switch(key)
	{
	case Keyboard.KEY_E:
		mc.displayGuiScreen(null);
            mc.setIngameFocus();
	}

	super.keyTyped(c, key);
}
}

 

GUI handler

package com.ec.handler;

import com.ec.container.ContainerTrialInventory;
import com.ec.screen.*;
import com.ec.tileentity.TileEntityTrialInventory;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.IGuiHandler;

public class GuiHandler implements IGuiHandler {

@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world,	int x, int y, int z)
{
	if(ID == ScreenTrialInventory.Gui_ID)
	{
		TileEntityTrialInventory trialInventory = (TileEntityTrialInventory)world.getTileEntity(x, y, z);
		return new ContainerTrialInventory(player.inventory, (TileEntityTrialInventory)trialInventory);
	}
	if(ID == PasswordLockScreen.id)
	{
		return null;
	}
	return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world,	int x, int y, int z)
{
	if(ID == ScreenTrialInventory.Gui_ID)
	{
		TileEntityTrialInventory trialInventory = (TileEntityTrialInventory)world.getTileEntity(x, y, z);
		return new ScreenTrialInventory(player.inventory, trialInventory);
	}
	else if(ID == PasswordLockScreen.id)
	{
		return new PasswordLockScreen(world, x, y, z);
	}
	return null;
}

}

 

PasswordChangeScreen

package com.ec.screen;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ChatLine;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.stream.ChatController;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderGameOverlayEvent.Chat;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

import com.ec.lib.MainLib;
import com.ec.lib.RefStrings;
import com.ec.tileentity.TileEntityPasswordLock;

public class PasswordChangeScreen extends GuiScreen{
int screenWidth = 196;
int screenHeight = 169;

String enteredPassword = "";

public static World world;
public static int x;
public static int y;
public static int z;

public PasswordChangeScreen(World world, int x, int y, int z)
{
	this.world = world;
	this.x = x;
	this.y = y;
	this.z = z;
}

@Override
public void drawScreen(int x, int y, float tick)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	GL11.glColor4f(1, 1, 1, 1);
	drawDefaultBackground();

	mc.renderEngine.bindTexture(new ResourceLocation(RefStrings.MODID, "textures/gui/PasswordGui.png"));
	drawTexturedModalRect(screenX, screenY, 0, 0, screenWidth, screenHeight);
	fontRendererObj.drawString(enteredPassword, screenX + 36, screenY + 11, 0);
	this.drawTexturedModalRect(screenX + 110, screenY + 11, 145, 171, 68, 20);

	super.drawScreen(x, y, tick);
}

@Override
public void initGui()
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	buttonList.clear();
	GuiButton one;
	GuiButton two;
	GuiButton three;
	GuiButton four;
	GuiButton five;
	GuiButton six;
	GuiButton seven;
	GuiButton eight;
	GuiButton nine;
	GuiButton zero;
	GuiButton erase;
	GuiButton changePassword;
	GuiButton back;

	buttonList.add(one = new GuiButton(1, screenX + 25, screenY + 25, 10, 10, "1"));
	buttonList.add(two = new GuiButton(2, screenX + 45, screenY + 25, 10, 10, "2"));
	buttonList.add(three = new GuiButton(3, screenX + 65, screenY + 25, 10, 10, "3"));
	buttonList.add(four = new GuiButton(4, screenX + 25, screenY + 45, 10, 10, "4"));
	buttonList.add(five = new GuiButton(5, screenX + 45, screenY + 45, 10, 10, "5"));
	buttonList.add(six = new GuiButton(6, screenX + 65, screenY + 45, 10, 10, "6"));
	buttonList.add(seven = new GuiButton(7, screenX + 25, screenY + 65, 10, 10, "7"));
	buttonList.add(eight = new GuiButton(8, screenX + 45, screenY + 65, 10, 10, "8"));
	buttonList.add(nine = new GuiButton(9, screenX + 65, screenY + 65, 10, 10, "9"));
	buttonList.add(zero = new GuiButton(0, screenX + 45, screenY + 85, 10, 10, "0"));
	buttonList.add(erase = new GuiButton(10, screenX + 85, screenY + 45, 15, 20, "Clear"));
	buttonList.add(changePassword = new GuiButton(11, screenX + 125, screenY + 55, 20, 35, "Change password"));
	buttonList.add(back = new GuiButton(12, screenX + 125, screenY + 85, 20, 20, "Back"));
	super.initGui();
}

@Override
public void actionPerformed(GuiButton button)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	TileEntityPasswordLock tile = (TileEntityPasswordLock)world.getTileEntity(x, y, z);

	switch(button.id)
	{
	case 0:
		enteredPassword = enteredPassword + "0";
		break;
	case 1:
		enteredPassword = enteredPassword + "1";
		break;
	case 2:
		enteredPassword = enteredPassword + "2";
		break;
	case 3:
		enteredPassword = enteredPassword + "3";
		break;
	case 4:
		enteredPassword = enteredPassword + "4";
		break;
	case 5:
		enteredPassword = enteredPassword + "5";
		break;
	case 6:
		enteredPassword = enteredPassword + "6";
		break;
	case 7:
		enteredPassword = enteredPassword + "7";
		break;
	case 8:
		enteredPassword = enteredPassword + "8";
		break;
	case 9:
		enteredPassword = enteredPassword + "9";
		break;
	case 10:
		enteredPassword = "";
		break;
	case 11:
		if(enteredPassword.length() == 4)
		{
			tile.validPassword = enteredPassword;
			MainLib.openGui(world, new PasswordLockScreen(world, x, y, z));
		}
		break;
	case 12:
		MainLib.openGui(world ,new PasswordLockScreen(world, x, y, z));
		break;
	default:
		break;
	}
}

@Override
public void keyTyped(char c, int key)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	switch(key)
	{
	case Keyboard.KEY_E:
		mc.displayGuiScreen(null);
            mc.setIngameFocus();
	}

	super.keyTyped(c, key);
}
}

 

MainLib.java

package com.ec.lib;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.stats.Achievement;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;

public class MainLib {

/**
 * Generates random particle location on the block.
 * @param int Coordinate
 * @param int maxToSpawn
 * @param int minToSpawn
 * @param Random random
 * @return Double particleLocation
 */
public static double generateParticleLocation(int coordinate, int max, int min, Random rnd)
    {
	double res = coordinate + rnd.nextFloat() * max * max - min;
	return res;
    }

/**
 * 
 * @param rawDirection - [int] enter the raw value to translate
 * @return String translatedDirection
 * 	 */
public static String getDirectionName(int rawDirection)
{
	String name = null;

	switch(rawDirection)
	{
	case 0:
		name = "South";
		break;
	case 1:
		name = "West";
		break;
	case 2:
		name = "North";
		break;
	case 3:
		name = "East";
		break;
	}
	return name;
}

/**
 * Gets the entity-is-looking-to position in South(0) East(1) North(2) and West(3)
 * @param EntityLivingBase entity
 * @return int direction
 */
public static int getEntityLookingDirection(EntityLivingBase entity)
{
	return MathHelper.floor_double((double) (entity.rotationYaw * 4.0F / 360) + 0.50) & 3;
}

/**
 * Creates whole icon for 6 sides.
 * The parameters 3,4,5,6,7,8 are Strings-names for textures without double-dot.
 */
public static void createIcon(IIconRegister reg, IIcon[] icon, String top, String bottom, String south, String north, String west, String east)
{
	icon[0] = reg.registerIcon(RefStrings.MODID + ":" + bottom);
    	icon[1] = reg.registerIcon(RefStrings.MODID + ":" + top);
    	icon[2] = reg.registerIcon(RefStrings.MODID + ":" + north);
    	icon[3] = reg.registerIcon(RefStrings.MODID + ":" + south);
    	icon[4] = reg.registerIcon(RefStrings.MODID + ":" + east);
    	icon[5] = reg.registerIcon(RefStrings.MODID + ":" + west);
}

/**
 * Sends a message to the "chat"
 * @param player
 * @param text
 */
public static void sendMessage(EntityPlayer player, Object text)
{
	World world = player.worldObj;
	String message = null;
	if(text instanceof String)
	{
		message = (String)text;
	}
	else if(text instanceof Integer)
	{
		message = "" + text;
	}
	else if(text instanceof Boolean)
	{
		message = "" + text;
	}
	else
	{
		message = "Unsupported format or unable to cast";
	}
	if(!world.isRemote)
	{
		player.addChatMessage(new ChatComponentText(message));
	}
}

/**
 * Returns center location of the block. Block must be full 1x1x1m cube. Args: int x, int y, int z. Used for spawning particles
 * @param  x
 * @param  y
 * @param  z
 * @return block's centre  ( double[x,y,z] )
 */
public static double[] centerBlockForParticles(int x, int y, int z)
{
	double[] res = new double[3];

	res[0] = x + 0.5D;
	res[1] = y - 0.5D;
	res[2] = z + 0.5D;

	return res;
}

/**
 * Returns center location of the block. Block must be full 1x1x1m cube. Args: int x, int y, int z
 * @param  x
 * @param  y
 * @param  z
 * @return block's centre  ( float[x,y,z] )
 */
public static float[] centerBlock(int x, int y, int z)
{
	float[] res = new float[3];

	res[0] = x + 0.5F;
	res[1] = y - 0.5F;
	res[2] = z + 0.5F;

	return res;
}

/**
 * Spawns an item at specified location.
 * @param world
 * @param xPos
 * @param yPos
 * @param zPos
 * @param itemStack
 */
public static void spawnItemDrop(World world, double xPos, double yPos, double zPos, ItemStack itemStack)
{
	if(!world.isRemote)
	{
		world.spawnEntityInWorld(new EntityItem(world, xPos, yPos, zPos, itemStack));
	}
}

/**
 * 
 * @param tile IInventory - TileEntity that implements IInventory
 * @param slotID int - An unique ID of slot
 * @param xPos int - X position of a slot in GUI
 * @param yPos int - Y position of a slot in GUI
 * @return Slot slot
 */
public static Slot createSlot(IInventory tile, int slotID, int xPos, int yPos)
{
	return new Slot(tile, slotID, xPos, yPos);
}

/**
 * Destroys block at given cordinates
 * @param world
 * @param x
 * @param y
 * @param z
 */
public static void destroyBlock(World world, int x, int y, int z)
{
	if(!world.isRemote)
	{
		world.setBlockToAir(x, y, z);
	}
}
/**
 * Converts potion to potion effect.
 * @param potion
 * @param duration
 * @return
 */
public static PotionEffect getPotionEffect(Potion potion, int duration)
{
	PotionEffect potionEffect = new PotionEffect(potion.id, duration);
	return potionEffect;
}
/**
 * Currently no use.
 * @param world
 * @param x
 * @param y
 * @param z
 * @param power
 */
public static void provideRedstonePower(World world, int x, int y, int z, int power)
{
	Block xPlus = world.getBlock(x + 1, y, z);
	Block xMinus = world.getBlock(x - 1, y, z);
	Block yPlus = world.getBlock(x, y + 1, z);
	Block yMinus = world.getBlock(x, y - 1, z);
	Block zPlus = world.getBlock(x, y, z + 1);
	Block zMinus = world.getBlock(x, y, z - 1);

	if(xPlus.equals(Blocks.redstone_wire))
	{
		world.setBlockMetadataWithNotify(x + 1, y, z, power, 1 + 2);
	}
	else if(xMinus.equals(Blocks.redstone_wire))
	{
		world.setBlockMetadataWithNotify(x - 1, y, z, power, 1 + 2);
	}
	else if(yPlus.equals(Blocks.redstone_wire))
	{
		world.setBlockMetadataWithNotify(x, y + 1, z, power, 1 + 2);
	}
	else if(yMinus.equals(Blocks.redstone_wire))
	{
		world.setBlockMetadataWithNotify(x, y - 1, z, power, 1 + 2);
	}
	else if(zPlus.equals(Blocks.redstone_wire))
	{
		world.setBlockMetadataWithNotify(x, y, z + 1, power, 1 + 2);
	}
	else if(zMinus.equals(Blocks.redstone_wire))
	{
		world.setBlockMetadataWithNotify(x, y, z - 1, power, 1 + 2);
	}
	else{}
}
/**
 * Registers and initializes an achievement.
 * @param unlocalizedName
 * @param x
 * @param y
 * @param displayedItem
 * @param requiredAchievement
 * @return
 */
public static Achievement createAchievement(String unlocalizedName, int x, int y, ItemStack displayedItem, Achievement requiredAchievement)
{
	Achievement achievement = new Achievement(unlocalizedName, unlocalizedName, x, y, displayedItem, requiredAchievement).registerStat();
	return achievement;
}

/**
 * Displayes classic Gui screen. NOT Gui Container.
 * @param world - type: World
 * @param gui - type: GuiScreen
 */
public static void openGui(World world , GuiScreen gui)
{
	if(!world.isRemote)
	{
		Minecraft.getMinecraft().displayGuiScreen(gui);
	}
}
}

 

If I forgot something, simply write a reply with notifying me. :)

 

 

 

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

What.. You should use this method: 'EntityPlayerMP#openGui',

  because it needs interaction between the Server World and the Client.

As you already set up your Gui Handler, what you need to do is just setting your container for the PasswordLockScreen.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

But what I write into container?

 

And, What is EntityPlayerMP?

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

You just need to follow some tutorials.. There are tons of tutorials about containers and guis for basic tileentity on Internet.

Just take one and follow that.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

I followed one tutorial, but I know Containers are used to create slots in Gui. And I don't need any slots in this gui. And when I make some slots I just made cheat machine, because I had problem with container with item duplication and administrators deleted these 3 topics about it. I posted it first time, they deleted it, I posted, they deleted it and the same at third time. I really don't know why they deleted the first topic about it.

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

And when I searched for tutorials, I found only one, but it was fo 1.6.4. Then, I followed it and then looked at cpw's ironchest code.

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

You don't need a container for this, you need to send a packet to the server to change the password in the TileEntity. TO open the gui, use [/code]EntityPlayer#openGui(parameters)[/code] on the client side (world.isRemote =

true

), and in your IGuiHandler, return the proper gui for the proper guiID, and return null for the container.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

Ok, but how can I send packet?

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

Well, thanks.

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

I have still problems with that.

I have seen You (diesieben07) wrote to one member: You can't simply change tile entity variables. It's used to prevent from hacks.

What did you mean at "hacks"?

If it is true, how could some modders made this?

And, I followed your tutorial and created this class.

There can be two errors: handler's method onMessage does not work or I wrong coded sender.

I used this for sending this packet.

MainRegistry.packets is SimpleNetworkWrapper as showed in your tutorial.

MainRegistry.packets.sendToServer(new PacketMessage("unlock", x, y, z));

 

Here is my code for this packet.

 

 

package com.ec.handler;

import com.ec.lib.MainLib;
import com.ec.tileentity.TileEntityPasswordLock;

import net.minecraft.inventory.Container;
import net.minecraft.world.World;
import io.netty.buffer.ByteBuf;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;

public class PacketMessage implements IMessage{
private String text;
private String password;
private int fromX;
private int fromY;
private int fromZ;

public PacketMessage(){}

public PacketMessage(String text, int x, int y, int z)
{
	this.text = text;
	this.fromX = x;
	this.fromY = y;
	this.fromZ = z;
	this.password = "not set";
}

public PacketMessage(String text, int x, int y, int z, String password)
{
	this.text = text;
	this.fromX = x;
	this.fromY = y;
	this.fromZ = z;
	this.password = password;
}

@Override
public void fromBytes(ByteBuf buf) {
	text = ByteBufUtils.readUTF8String(buf);
	String fromXString = ByteBufUtils.readUTF8String(buf);
	String fromYString = ByteBufUtils.readUTF8String(buf);
	String fromZString = ByteBufUtils.readUTF8String(buf);

	if(!password.equals("not set"))
	{
		password = ByteBufUtils.readUTF8String(buf);
	}

	fromX = Integer.parseInt(fromXString);
	fromY = Integer.parseInt(fromYString);
	fromZ = Integer.parseInt(fromZString);
}

@Override
public void toBytes(ByteBuf buf) {
	ByteBufUtils.writeUTF8String(buf, text);
	ByteBufUtils.writeUTF8String(buf, String.valueOf(fromX));
	ByteBufUtils.writeUTF8String(buf, String.valueOf(fromY));
	ByteBufUtils.writeUTF8String(buf, String.valueOf(fromZ));

	if(!password.equals("not set"))
	{
		ByteBufUtils.writeUTF8String(buf, password);
	}
}

public static class Handler implements IMessageHandler<PacketMessage, IMessage>
{
	@Override
	public IMessage onMessage(PacketMessage message, MessageContext ctx) {
		if(message.text.equals("unlock"))
		{
			World world = ctx.getServerHandler().playerEntity.getEntityWorld();
			TileEntityPasswordLock tileEntity = (TileEntityPasswordLock)world.getTileEntity(message.fromX, message.fromY, message.fromZ);
			tileEntity.active = true;
			MainLib.sendMessage(ctx.getServerHandler().playerEntity, "Unlocked: " + String.valueOf(tileEntity.active));
		}
		else if(message.text.equals("lock"))
		{
			World world = ctx.getServerHandler().playerEntity.worldObj;
			TileEntityPasswordLock tileEntity = (TileEntityPasswordLock)world.getTileEntity(message.fromX, message.fromY, message.fromZ);
			tileEntity.active = false;
		}
		else if(message.text.equals("changePassword"))
		{
			World world = ctx.getServerHandler().playerEntity.worldObj;
			TileEntityPasswordLock tileEntity = (TileEntityPasswordLock)world.getTileEntity(message.fromX, message.fromY, message.fromZ);

			if(!message.password.equals("not set"))
			{
				tileEntity.validPassword = message.password;

			}
		}
		else
		{
			MainLib.sendMessage(ctx.getServerHandler().playerEntity, "Not working");
		}
		return null;
	}
}

}

 

 

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

I have seen You (diesieben07) wrote to one member: You can't simply change tile entity variables. It's used to prevent from hacks.

 

Sorry for that.

 

And what method can I use as replacement for ByteBufUtils.readUTF8String(buf)?

And I added System.out.println(something) to onMessage and it does nothing.

 

And when I said "sender" I meant  MainRegistry.packets.sendToServer(new PacketMessage("unlock", x, y, z))

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

Registering packet and SimpleNetworkWrapper(Main mod class)

public static SimpleNetworkWrapper packets = NetworkRegistry.INSTANCE.newSimpleChannel("MyChannel");
@EventHandler
public static void preLoad(FMLPreInitializationEvent PreEvent)
{
	packets.registerMessage(PacketMessage.Handler.class, PacketMessage.class, 0, Side.SERVER);
}

 

*Don't think I have only packet in my mod. I have some other things in my mod.

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

Yes and No, I am not sure, if it was sent.

Here is code where it sends packet.

Currently, I didn't modify lines with mc.displayGuiScreen or MainLib.openGui.

I change them when we solve this problem.

 

 

 

package com.ec.screen;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ChatLine;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.stream.ChatController;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderGameOverlayEvent.Chat;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

import com.ec.Main.MainRegistry;
import com.ec.handler.PacketMessage;
import com.ec.lib.MainLib;
import com.ec.lib.RefStrings;
import com.ec.tileentity.TileEntityPasswordLock;

import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;

public class PasswordLockScreen extends GuiScreen{
int screenWidth = 196;
int screenHeight = 169;

public static int id = 20;

public static World world;
public static int x;
public static int y;
public static int z;
private String enteredPassword = "";
private String validation = "";
private String owner = "";

public PasswordLockScreen(World world, int x, int y, int z)
{
	this.world = world;
	this.x = x;
	this.y = y;
	this.z = z;

	TileEntityPasswordLock tile = (TileEntityPasswordLock)world.getTileEntity(x, y, z);
	this.owner = tile.owner;
}

@Override
public void drawScreen(int x, int y, float tick)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	GL11.glColor4f(1, 1, 1, 1);
	drawDefaultBackground();
	mc.renderEngine.bindTexture(new ResourceLocation(RefStrings.MODID, "textures/gui/PasswordGui.png"));
	drawTexturedModalRect(screenX, screenY, 0, 0, screenWidth, screenHeight);
	fontRendererObj.drawString(enteredPassword, screenX + 36, screenY + 11, 0);
	fontRendererObj.drawString("Owner:", screenX + 115, screenY + 110, 0);
	fontRendererObj.drawString(owner, screenX + 115, screenY + 125, 0);
	fontRendererObj.drawString(validation, screenX + 110, screenY + 11, 0);

	super.drawScreen(x, y, tick);
}

@Override
public void initGui()
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	buttonList.clear();
	GuiButton one;
	GuiButton two;
	GuiButton three;
	GuiButton four;
	GuiButton five;
	GuiButton six;
	GuiButton seven;
	GuiButton eight;
	GuiButton nine;
	GuiButton zero;
	GuiButton unlock;
	GuiButton lock;
	GuiButton erase;
	GuiButton changePassword;

	buttonList.add(one = new GuiButton(1, screenX + 25, screenY + 25, 10, 10, "1"));
	buttonList.add(two = new GuiButton(2, screenX + 45, screenY + 25, 10, 10, "2"));
	buttonList.add(three = new GuiButton(3, screenX + 65, screenY + 25, 10, 10, "3"));
	buttonList.add(four = new GuiButton(4, screenX + 25, screenY + 45, 10, 10, "4"));
	buttonList.add(five = new GuiButton(5, screenX + 45, screenY + 45, 10, 10, "5"));
	buttonList.add(six = new GuiButton(6, screenX + 65, screenY + 45, 10, 10, "6"));
	buttonList.add(seven = new GuiButton(7, screenX + 25, screenY + 65, 10, 10, "7"));
	buttonList.add(eight = new GuiButton(8, screenX + 45, screenY + 65, 10, 10, "8"));
	buttonList.add(nine = new GuiButton(9, screenX + 65, screenY + 65, 10, 10, "9"));
	buttonList.add(zero = new GuiButton(0, screenX + 45, screenY + 85, 10, 10, "0"));
	buttonList.add(unlock = new GuiButton(10, screenX + 35, screenY + 100, 15, 20, "Unlock"));
	buttonList.add(lock = new GuiButton(11, screenX + 65, screenY + 100, 15, 20, "Lock"));
	buttonList.add(erase = new GuiButton(12, screenX + 85, screenY + 45, 15, 20, "Clear"));
	buttonList.add(changePassword = new GuiButton(13, screenX + 125, screenY + 55, 35, 20, "Change password"));
	super.initGui();
}

@Override
public void actionPerformed(GuiButton button)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	TileEntityPasswordLock tileEntity = (TileEntityPasswordLock)world.getTileEntity(x, y, z);

	switch(button.id)
	{
	case 0:
		enteredPassword = enteredPassword + "0";
		break;
	case 1:
		enteredPassword = enteredPassword + "1";
		break;
	case 2:
		enteredPassword = enteredPassword + "2";
		break;
	case 3:
		enteredPassword = enteredPassword + "3";
		break;
	case 4:
		enteredPassword = enteredPassword + "4";
		break;
	case 5:
		enteredPassword = enteredPassword + "5";
		break;
	case 6:
		enteredPassword = enteredPassword + "6";
		break;
	case 7:
		enteredPassword = enteredPassword + "7";
		break;
	case 8:
		enteredPassword = enteredPassword + "8";
		break;
	case 9:
		enteredPassword = enteredPassword + "9";
		break;
	case 10:
		if(enteredPassword.equals(tileEntity.validPassword))
		{
			tileEntity.active = true;
			validation = "succesful";
		}
		else
		{
			validation = "wrong pass";
		}
		break;
	case 11:
		MainRegistry.packets.sendToServer(new PacketMessage("unlock", x, y, z));
		break;
	case 12:
		enteredPassword = "";
		validation = "";
		break;
	case 13:
		if(enteredPassword.equals(tileEntity.validPassword))
		{
			MainLib.openGui(world, new PasswordChangeScreen(world, x, y, z));
		}
		else
		{
			validation = "wrong pass";
		}
		break;
	default:
		break;
	}
}

@Override
public void keyTyped(char c, int key)
{
	int screenX = (width - screenWidth) / 2;
	int screenY = (height - screenHeight) / 2;

	switch(key)
	{
	case Keyboard.KEY_E:
		mc.displayGuiScreen(null);
            mc.setIngameFocus();
	}

	super.keyTyped(c, key);
}
}

 

 

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

Ohhh, sorry, it was working, but I pressed wrong button in the GUI.

And when I pressed right button and closed GUI, it disconnected me from my single-player world and writes on screen: A fatal error occured, exited this connection.

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Posted

Ok, I found the error. The error was in my PacketMessage.java where in both fromBytes and ToBytes I checked if the password is required using this: if(!password.equals("not set")) and when it was null, it throwed me exception. :-)

I repaired it with adding boolean isPasswordRequired and in second constructor(first must be default) setted this variable to false and in third constructor(only for changing password) setted it to true.

Sorry, if you find mistaches in my posts.

I am not EN.

And when I post anything on Modder support, it means, I can't help myself and I need your help. And when you decide to delete my topic, just PM me with the reason, please.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • When I first heard about Bitcoin back in 2018, I was skeptical. The idea of a decentralized, digital currency seemed too good to be true. But I was intrigued as I learned more about the technology behind it and its potential. I started small, investing just a few hundred dollars, dipping my toes into the cryptocurrency waters. At first, it was exhilarating to watch the value of my investment grow exponentially. I felt like I was part of the future, an early adopter of this revolutionary new asset. But that euphoria was short-lived. One day, I logged into my digital wallet only to find it empty - my Bitcoin had vanished without a trace. It turned out that the online exchange I had trusted had been hacked, and my funds were stolen. I was devastated, both financially and emotionally. All the potential I had seen in Bitcoin was tainted by the harsh reality that with decentralization came a lack of regulation and oversight. My hard-earned money was gone, lost to the ether of the digital world. This experience taught me a painful lesson about the price of trust in the uncharted territory of cryptocurrency. While the technology holds incredible promise, the risks can be catastrophic if you don't approach it with extreme caution. My Bitcoin investment gamble had failed, and I was left to pick up the pieces, wiser but poorer for having placed my faith in the wrong hands. My sincere appreciation goes to MUYERN TRUST HACKER. You are my hero in recovering my lost funds. Send a direct m a i l ( muyerntrusted ( @ ) mail-me ( . )c o m ) or message on whats app : + 1 ( 4-4-0 ) ( 3 -3 -5 ) ( 0-2-0-5 )
    • You could try posting a log (if there is no log at all, it may be the launcher you are using, the FAQ may have info on how to enable the log) as described in the FAQ, however this will probably need to be reported to/remedied by the mod author.
    • So me and a couple of friends are playing with a shitpost mod pack and one of the mods in the pack is corail tombstone and for some reason there is a problem with it, where on death to fire the player will get kicked out of the server and the tombstone will not spawn basically deleting an entire inventory, it doesn't matter what type of fire it is, whether it's from vanilla fire/lava, or from modded fire like ice&fire/lycanites and it's common enough to where everyone on the server has experienced at least once or twice and it doesn't give any crash log. a solution to this would be much appreciated thank you!
    • It is 1.12.2 - I have no idea if there is a 1.12 pack
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.