Pretty much all of security minus the gui.

and all the stuff I did that i forgot to comment.
This commit is contained in:
AlgorithmX2 2014-01-26 22:00:36 -06:00
parent bea039c7b5
commit 0f75db5e80
61 changed files with 2058 additions and 126 deletions

View file

@ -13,6 +13,7 @@ import net.minecraftforge.common.ForgeDirection;
import appeng.api.util.IOrientable;
import appeng.api.util.IOrientableBlock;
import appeng.client.render.ItemRenderer;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.AEBaseTile;
import appeng.util.Platform;
@ -110,6 +111,11 @@ public class AEBaseItemBlock extends ItemBlock
ori.setOrientation( forward, up );
}
if ( tile instanceof IGridProxyable )
{
((IGridProxyable) tile).getProxy().setOwner( player );
}
tile.onPlacement( stack, player, side );
}
else if ( blockType instanceof IOrientableBlock )

View file

@ -0,0 +1,48 @@
package appeng.block.misc;
import java.util.EnumSet;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import appeng.block.AEBaseBlock;
import appeng.client.render.BaseBlockRender;
import appeng.client.render.blocks.RendererSecurity;
import appeng.core.features.AEFeature;
import appeng.core.sync.GuiBridge;
import appeng.tile.misc.TileSecurity;
import appeng.util.Platform;
public class BlockSecurity extends AEBaseBlock
{
public BlockSecurity() {
super( BlockSecurity.class, Material.iron );
setfeature( EnumSet.of( AEFeature.Security ) );
setTileEntiy( TileSecurity.class );
}
@Override
protected Class<? extends BaseBlockRender> getRenderer()
{
return RendererSecurity.class;
}
@Override
public boolean onActivated(World w, int x, int y, int z, EntityPlayer p, int side, float hitX, float hitY, float hitZ)
{
if ( p.isSneaking() )
return false;
TileSecurity tg = getTileEntity( w, x, y, z );
if ( tg != null )
{
if ( Platform.isServer() )
Platform.openGUI( p, tg, ForgeDirection.getOrientation( side ), GuiBridge.GUI_SECURITY );
return true;
}
return false;
}
}

View file

@ -0,0 +1,212 @@
package appeng.client.gui.implementations;
import java.io.IOException;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerPriority;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.IPriorityHost;
import appeng.parts.misc.PartStorageBus;
import appeng.tile.storage.TileChest;
import appeng.tile.storage.TileDrive;
import cpw.mods.fml.common.network.PacketDispatcher;
public class GuiPriority extends AEBaseGui
{
GuiTextField priority;
GuiTabButton originalGuiBtn;
GuiButton plus1, plus10, plus100, plus1000;
GuiButton minus1, minus10, minus100, minus1000;
GuiBridge OriginalGui;
public GuiPriority(InventoryPlayer inventoryPlayer, IPriorityHost te) {
super( new ContainerPriority( inventoryPlayer, te ) );
}
@Override
public void initGui()
{
super.initGui();
buttonList.add( plus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 32, 22, 20, "+1" ) );
buttonList.add( plus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 32, 28, 20, "+10" ) );
buttonList.add( plus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 32, 32, 20, "+100" ) );
buttonList.add( plus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 32, 38, 20, "+1000" ) );
buttonList.add( minus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 69, 22, 20, "-1" ) );
buttonList.add( minus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 69, 28, 20, "-10" ) );
buttonList.add( minus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 69, 32, 20, "-100" ) );
buttonList.add( minus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 69, 38, 20, "-1000" ) );
ItemStack myIcon = null;
Object target = ((AEBaseContainer) inventorySlots).getTarget();
if ( target instanceof PartStorageBus )
{
myIcon = AEApi.instance().parts().partStorageBus.stack( 1 );
OriginalGui = GuiBridge.GUI_STORAGEBUS;
}
if ( target instanceof TileDrive )
{
myIcon = AEApi.instance().blocks().blockDrive.stack( 1 );
OriginalGui = GuiBridge.GUI_DRIVE;
}
if ( target instanceof TileChest )
{
myIcon = AEApi.instance().blocks().blockChest.stack( 1 );
OriginalGui = GuiBridge.GUI_CHEST;
}
if ( OriginalGui != null )
buttonList.add( originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), itemRenderer ) );
priority = new GuiTextField( this.fontRenderer, this.guiLeft + 62, this.guiTop + 57, 59, this.fontRenderer.FONT_HEIGHT );
priority.setEnableBackgroundDrawing( false );
priority.setMaxStringLength( 16 );
priority.setTextColor( 0xFFFFFF );
priority.setVisible( true );
priority.setFocused( true );
((ContainerPriority) inventorySlots).setTextField( priority );
}
@Override
protected void actionPerformed(GuiButton btn)
{
super.actionPerformed( btn );
if ( btn == originalGuiBtn )
{
try
{
PacketDispatcher.sendPacketToServer( (new PacketSwitchGuis( OriginalGui )).getPacket() );
}
catch (IOException e)
{
e.printStackTrace();
}
}
if ( btn == plus1 )
addQty( 1 );
if ( btn == plus10 )
addQty( 10 );
if ( btn == plus100 )
addQty( 100 );
if ( btn == plus1000 )
addQty( 1000 );
if ( btn == minus1 )
addQty( -1 );
if ( btn == minus10 )
addQty( -10 );
if ( btn == minus100 )
addQty( -100 );
if ( btn == minus1000 )
addQty( -1000 );
}
private void addQty(int i)
{
try
{
String Out = priority.getText();
boolean Fixed = false;
while (Out.startsWith( "0" ) && Out.length() > 1)
{
Out = Out.substring( 1 );
Fixed = true;
}
if ( Fixed )
priority.setText( Out );
if ( Out.length() == 0 )
Out = "0";
long result = Long.parseLong( Out );
result += i;
priority.setText( Out = Long.toString( result ) );
PacketDispatcher.sendPacketToServer( (new PacketValueConfig( "PriorityHost.Priority", Out )).getPacket() );
}
catch (IOException e)
{
e.printStackTrace();
}
}
@Override
protected void keyTyped(char character, int key)
{
if ( !this.checkHotbarKeys( key ) )
{
if ( (key == 211 || key == 205 || key == 203 || key == 14 || character == '-' || Character.isDigit( character ))
&& priority.textboxKeyTyped( character, key ) )
{
try
{
String Out = priority.getText();
boolean Fixed = false;
while (Out.startsWith( "0" ) && Out.length() > 1)
{
Out = Out.substring( 1 );
Fixed = true;
}
if ( Fixed )
priority.setText( Out );
if ( Out.length() == 0 )
Out = "0";
PacketDispatcher.sendPacketToServer( (new PacketValueConfig( "PriorityHost.Priority", Out )).getPacket() );
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
super.keyTyped( character, key );
}
}
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY)
{
bindTexture( "guis/priority.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, xSize, ySize );
priority.drawTextBox();
}
protected String getBackground()
{
return "guis/priority.png";
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY)
{
fontRenderer.drawString( GuiText.Priority.getLocal(), 8, 6, 4210752 );
}
}

View file

@ -0,0 +1,31 @@
package appeng.client.gui.implementations;
import net.minecraft.entity.player.InventoryPlayer;
import appeng.client.gui.AEBaseGui;
import appeng.container.implementations.ContainerSecurity;
import appeng.core.localization.GuiText;
import appeng.tile.misc.TileSecurity;
public class GuiSecurity extends AEBaseGui
{
public GuiSecurity(InventoryPlayer inventoryPlayer, TileSecurity te) {
super( new ContainerSecurity( inventoryPlayer, te ) );
this.ySize = 199;
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY)
{
bindTexture( "guis/security.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, xSize, ySize );
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY)
{
fontRenderer.drawString( GuiText.Security.getLocal(), 8, 6, 4210752 );
fontRenderer.drawString( GuiText.inventory.getLocal(), 8, ySize - 96 + 3, 4210752 );
}
}

View file

@ -0,0 +1,131 @@
package appeng.client.gui.widgets;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import appeng.client.texture.ExtraTextures;
public class GuiTabButton extends GuiButton implements ITooltip
{
RenderItem itemRenderer;
int myIcon = -1;
ItemStack myItem;
String Msg;
public void setVisibility(boolean vis)
{
drawButton = vis;
enabled = vis;
}
public GuiTabButton(int x, int y, int ico, String Msg, RenderItem ir) {
super( 0, 0, 16, "" );
xPosition = x;
yPosition = y;
width = 22;
height = 22;
myIcon = ico;
this.Msg = Msg;
this.itemRenderer = ir;
}
public GuiTabButton(int x, int y, ItemStack ico, String Msg, RenderItem ir) {
super( 0, 0, 16, "" );
xPosition = x;
yPosition = y;
width = 22;
height = 22;
myItem = ico;
this.Msg = Msg;
this.itemRenderer = ir;
}
@Override
public boolean isVisible()
{
return drawButton;
}
@Override
public void drawButton(Minecraft par1Minecraft, int par2, int par3)
{
if ( this.drawButton )
{
GL11.glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
par1Minecraft.renderEngine.bindTexture( ExtraTextures.GuiTexture( "guis/states.png" ) );
this.field_82253_i = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height;
int uv_y = (int) Math.floor( 13 / 16 );
int uv_x = 13 - uv_y * 16;
this.drawTexturedModalRect( this.xPosition, this.yPosition, uv_x * 16, uv_y * 16, 22, 22 );
if ( myIcon >= 0 )
{
uv_y = (int) Math.floor( myIcon / 16 );
uv_x = myIcon - uv_y * 16;
this.drawTexturedModalRect( this.xPosition + 3, this.yPosition + 3, uv_x * 16, uv_y * 16, 16, 16 );
}
this.mouseDragged( par1Minecraft, par2, par3 );
if ( myItem != null )
{
this.zLevel = 100.0F;
itemRenderer.zLevel = 100.0F;
GL11.glEnable( GL11.GL_LIGHTING );
GL11.glEnable( GL12.GL_RESCALE_NORMAL );
RenderHelper.enableGUIStandardItemLighting();
FontRenderer fontrenderer = par1Minecraft.fontRenderer;
itemRenderer.renderItemAndEffectIntoGUI( fontrenderer, par1Minecraft.renderEngine, myItem, this.xPosition + 3, this.yPosition + 3 );
GL11.glDisable( GL11.GL_LIGHTING );
itemRenderer.zLevel = 0.0F;
this.zLevel = 0.0F;
}
}
}
@Override
public String getMsg()
{
return Msg;
}
@Override
public int xPos()
{
return xPosition;
}
@Override
public int yPos()
{
return yPosition;
}
@Override
public int getWidth()
{
return 22;
}
@Override
public int getHeight()
{
return 22;
}
}

View file

@ -0,0 +1,66 @@
package appeng.client.render.blocks;
import java.util.EnumSet;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.ForgeDirection;
import appeng.block.AEBaseBlock;
import appeng.client.render.BaseBlockRender;
import appeng.client.texture.ExtraTextures;
import appeng.tile.misc.TileSecurity;
public class RendererSecurity extends BaseBlockRender
{
public RendererSecurity() {
super( false, 0 );
}
@Override
public void renderInventory(AEBaseBlock block, ItemStack is, RenderBlocks renderer)
{
renderer.overrideBlockTexture = ExtraTextures.getMissing();
this.renderInvBlock( EnumSet.of( ForgeDirection.SOUTH ), block, Tessellator.instance, 0x000000, renderer );
renderer.overrideBlockTexture = ExtraTextures.MEChest.getIcon();
this.renderInvBlock( EnumSet.of( ForgeDirection.UP ), block, Tessellator.instance, 0xffffff, renderer );
renderer.overrideBlockTexture = null;
super.renderInventory( block, is, renderer );
}
@Override
public boolean renderInWorld(AEBaseBlock imb, IBlockAccess world, int x, int y, int z, RenderBlocks renderer)
{
TileSecurity sp = imb.getTileEntity( world, x, y, z );
renderer.setRenderBounds( 0, 0, 0, 1, 1, 1 );
ForgeDirection up = sp.getUp();
preRenderInWorld( imb, world, x, y, z, renderer );
boolean result = renderer.renderStandardBlock( imb, x, y, z );
int b = world.getLightBrightnessForSkyBlocks( x + up.offsetX, y + up.offsetY, z + up.offsetZ, 0 );
if ( sp.isActive() )
{
b = 15 << 20 | 15 << 4;
}
Tessellator.instance.setBrightness( b );
Tessellator.instance.setColorOpaque_I( 0xffffff );
renderer.setRenderBounds( 0, 0, 0, 1, 1, 1 );
Icon ico = sp.isActive() ? ExtraTextures.BlockMESecurityOn.getIcon() : ExtraTextures.MEChest.getIcon();
renderFace( x, y, z, imb, ico, renderer, up );
renderer.overrideBlockTexture = null;
postRenderInWorld( renderer );
return result;
}
}

View file

@ -48,7 +48,9 @@ public enum ExtraTextures
BlockQuartzGlassB("BlockQuartzGlassB"), BlockQuartzGlassC("BlockQuartzGlassC"), BlockQuartzGlassD("BlockQuartzGlassD"),
BlockSpatialPylonE("BlockSpatialPylon_end"), BlockSpatialPylonE_dim("BlockSpatialPylon_end_dim"), BlockSpatialPylonE_red("BlockSpatialPylon_end_red");
BlockSpatialPylonE("BlockSpatialPylon_end"), BlockSpatialPylonE_dim("BlockSpatialPylon_end_dim"), BlockSpatialPylonE_red("BlockSpatialPylon_end_red"),
BlockMESecurityOn("BlockMESecurityOn");
final private String name;
public Icon icon;

View file

@ -14,9 +14,14 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.networking.IGridHost;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.security.PlayerSource;
import appeng.api.parts.IPart;
import appeng.api.storage.IMEInventoryHandler;
@ -43,6 +48,53 @@ public abstract class AEBaseContainer extends Container
BaseActionSource mySrc;
int ticksSinceCheck = 900;
public void verifyPermissions(SecurityPermissions security, boolean requirePower)
{
if ( Platform.isClient() )
return;
ticksSinceCheck++;
if ( ticksSinceCheck < 20 )
return;
ticksSinceCheck = 0;
IActionHost host = null;
if ( tileEntity instanceof IActionHost )
host = (IActionHost) tileEntity;
if ( part instanceof IActionHost )
host = (IActionHost) part;
if ( host == null )
invPlayer.player.closeScreen();// close!
else
{
IGridNode gn = host.getActionableNode();
if ( gn != null )
{
IGrid g = gn.getGrid();
if ( g != null )
{
if ( requirePower )
{
IEnergyGrid eg = g.getCache( IEnergyGrid.class );
if ( !eg.isNetworkPowered() )
{
invPlayer.player.closeScreen();
return;
}
}
ISecurityGrid sg = g.getCache( ISecurityGrid.class );
if ( !sg.hasPermission( invPlayer.player, security ) )
invPlayer.player.closeScreen();
}
}
}
}
public ContainerOpenContext openContext;
protected IMEInventoryHandler<IAEItemStack> cellInv;
@ -67,7 +119,7 @@ public abstract class AEBaseContainer extends Container
invPlayer = ip;
tileEntity = myTile;
part = myPart;
mySrc = new PlayerSource( ip.player, (IGridHost) (myTile instanceof IGridHost ? myTile : (myPart instanceof IGridHost ? myPart : null)) );
mySrc = new PlayerSource( ip.player, (IActionHost) (myTile instanceof IActionHost ? myTile : (myPart instanceof IActionHost ? myPart : null)) );
}
public boolean canDragIntoSlot(Slot s)

View file

@ -0,0 +1,13 @@
package appeng.container;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
public class ContainerOpenContext
{
public World w;
public int x, y, z;
public ForgeDirection side;
}

View file

@ -6,6 +6,7 @@ import net.minecraft.inventory.IInventory;
import appeng.api.config.FullnessMode;
import appeng.api.config.OperationMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.container.slot.SlotOutput;
import appeng.container.slot.SlotRestrictedInput;
@ -70,6 +71,8 @@ public class ContainerIOPort extends ContainerUpgradeable
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
if ( Platform.isServer() )
{
for (int i = 0; i < this.crafters.size(); ++i)

View file

@ -1,6 +1,7 @@
package appeng.container.implementations;
import net.minecraft.entity.player.InventoryPlayer;
import appeng.api.config.SecurityPermissions;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotNormal;
@ -30,4 +31,10 @@ public class ContainerInterface extends AEBaseContainer
bindPlayerInventory( ip, 0, 211 - /* height of playerinventory */82 );
}
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
super.detectAndSendChanges();
}
}

View file

@ -7,6 +7,7 @@ import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import appeng.api.config.FuzzyMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.container.slot.SlotFakeTypeOnly;
import appeng.container.slot.SlotRestrictedInput;
@ -80,6 +81,8 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
if ( Platform.isServer() )
{
for (int i = 0; i < this.crafters.size(); ++i)

View file

@ -0,0 +1,78 @@
package appeng.container.implementations;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.tileentity.TileEntity;
import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPart;
import appeng.container.AEBaseContainer;
import appeng.helpers.IPriorityHost;
import appeng.util.Platform;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ContainerPriority extends AEBaseContainer
{
IPriorityHost priHost;
@SideOnly(Side.CLIENT)
public GuiTextField textField;
@SideOnly(Side.CLIENT)
public void setTextField(GuiTextField level)
{
textField = level;
textField.setText( "" + PriorityValue );
}
public ContainerPriority(InventoryPlayer ip, IPriorityHost te) {
super( ip, (TileEntity) (te instanceof TileEntity ? te : null), (IPart) (te instanceof IPart ? te : null) );
priHost = te;
}
int PriorityValue = -1;
public void setPriority(int newValue, EntityPlayer player)
{
priHost.setPriority( newValue );
PriorityValue = newValue;
}
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
if ( Platform.isServer() )
{
for (int i = 0; i < this.crafters.size(); ++i)
{
ICrafting icrafting = (ICrafting) this.crafters.get( i );
if ( this.PriorityValue != priHost.getPriority() )
{
icrafting.sendProgressBarUpdate( this, 2, (int) priHost.getPriority() );
}
}
this.PriorityValue = (int) priHost.getPriority();
}
}
@Override
public void updateProgressBar(int idx, int value)
{
super.updateProgressBar( idx, value );
if ( idx == 2 )
{
PriorityValue = value;
if ( textField != null )
textField.setText( "" + PriorityValue );
}
}
}

View file

@ -0,0 +1,27 @@
package appeng.container.implementations;
import net.minecraft.entity.player.InventoryPlayer;
import appeng.api.config.SecurityPermissions;
import appeng.container.AEBaseContainer;
import appeng.tile.misc.TileSecurity;
public class ContainerSecurity extends AEBaseContainer
{
TileSecurity myte;
public ContainerSecurity(InventoryPlayer ip, TileSecurity te) {
super( ip, te, null );
myte = te;
bindPlayerInventory( ip, 0, 199 - /* height of playerinventory */82 );
}
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.SECURITY, true );
super.detectAndSendChanges();
}
}

View file

@ -1,6 +1,7 @@
package appeng.container.implementations;
import net.minecraft.entity.player.InventoryPlayer;
import appeng.api.config.SecurityPermissions;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotOutput;
import appeng.container.slot.SlotRestrictedInput;
@ -22,4 +23,12 @@ public class ContainerSpatialIOPort extends AEBaseContainer
bindPlayerInventory( ip, 0, 199 - /* height of playerinventory */82 );
}
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
super.detectAndSendChanges();
}
}

View file

@ -5,6 +5,7 @@ import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import appeng.api.config.AccessRestriction;
import appeng.api.config.FuzzyMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.container.slot.OptionalSlotFakeTypeOnly;
@ -80,6 +81,8 @@ public class ContainerStorageBus extends ContainerUpgradeable
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
if ( Platform.isServer() )
{
for (int i = 0; i < this.crafters.size(); ++i)

View file

@ -8,6 +8,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import appeng.api.config.FuzzyMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
@ -159,6 +160,8 @@ public class ContainerUpgradeable extends AEBaseContainer implements IOptionalSl
@Override
public void detectAndSendChanges()
{
verifyPermissions( SecurityPermissions.BUILD, false );
if ( Platform.isServer() )
{
for (int i = 0; i < this.crafters.size(); ++i)

View file

@ -6,6 +6,7 @@ import appeng.api.definitions.Blocks;
import appeng.api.definitions.Items;
import appeng.api.definitions.Materials;
import appeng.api.definitions.Parts;
import appeng.api.exceptions.FailedConnection;
import appeng.api.features.IRegistryContainer;
import appeng.api.networking.IGridBlock;
import appeng.api.networking.IGridConnection;
@ -89,7 +90,7 @@ public class Api implements IAppEngApi
}
@Override
public IGridConnection createGridConnection(IGridNode a, IGridNode b)
public IGridConnection createGridConnection(IGridNode a, IGridNode b) throws FailedConnection
{
return new GridConnection( a, b, ForgeDirection.UNKNOWN );
}

View file

@ -21,6 +21,7 @@ import appeng.api.definitions.Parts;
import appeng.api.implementations.tiles.ITileStorageMonitorable;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.pathing.IPathingGrid;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.spatial.ISpatialCache;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
@ -40,6 +41,7 @@ import appeng.block.misc.BlockInterface;
import appeng.block.misc.BlockNetworkEmitter;
import appeng.block.misc.BlockQuartzCrystalizer;
import appeng.block.misc.BlockQuartzTorch;
import appeng.block.misc.BlockSecurity;
import appeng.block.misc.BlockTinyTNT;
import appeng.block.misc.BlockVibrationChamber;
import appeng.block.networking.BlockCableBus;
@ -111,6 +113,7 @@ import appeng.me.cache.EnergyGridCache;
import appeng.me.cache.GridStorageCache;
import appeng.me.cache.P2PCache;
import appeng.me.cache.PathGridCache;
import appeng.me.cache.SecurityCache;
import appeng.me.cache.SpatialPylonCache;
import appeng.me.cache.TickManagerCache;
import appeng.me.storage.AEExternalHandler;
@ -256,6 +259,8 @@ public class Registration
blocks.blockEnergyCellDense = addFeature( BlockDenseEnergyCell.class );
blocks.blockEnergyCellCreative = addFeature( BlockCreativeEnergyCell.class );
blocks.blockSecurity = addFeature( BlockSecurity.class );
items.itemEncodedAsemblerPattern = addFeature( ItemEncodedPattern.class );
items.itemCellCreative = addFeature( ItemCreativeStorageCell.class );
@ -410,6 +415,7 @@ public class Registration
AEApi.instance().registries().gridCache().registerGridCache( IStorageGrid.class, GridStorageCache.class );
AEApi.instance().registries().gridCache().registerGridCache( P2PCache.class, P2PCache.class );
AEApi.instance().registries().gridCache().registerGridCache( ISpatialCache.class, SpatialPylonCache.class );
AEApi.instance().registries().gridCache().registerGridCache( ISecurityGrid.class, SecurityCache.class );
AEApi.instance().registries().externalStorage().addExternalStorageInterface( new AEExternalHandler() );

View file

@ -2,10 +2,13 @@ package appeng.core;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import net.minecraftforge.common.ConfigCategory;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.Property;
import appeng.api.util.WorldCoord;
import appeng.me.GridStorage;
import appeng.me.GridStorageSearch;
@ -17,16 +20,19 @@ public class WorldSettings extends Configuration
private static WorldSettings instance;
long lastGridStorage = 0;
int lastPlayer = 0;
public WorldSettings(File f) {
super( f );
try
{
lastGridStorage = Long.parseLong( get( "Counters", "lastGridStorage", 0 ).getString() );
lastPlayer = get( "Counters", "lastPlayer", 0 ).getInt();
}
catch (NumberFormatException err)
{
lastGridStorage = 0;
lastPlayer = 0;
}
}
@ -141,4 +147,38 @@ public class WorldSettings extends Configuration
return r;
}
private long nextPlayer()
{
long r = lastPlayer++;
get( "Counters", "lastPlayer", lastPlayer ).set( lastPlayer );
return r;
}
public String getUsername(int id)
{
ConfigCategory playerList = this.getCategory( "players" );
for (Entry<String, Property> fish : playerList.entrySet())
{
if ( fish.getValue().isIntValue() && fish.getValue().getInt() == id )
return fish.getKey();
}
return null;
}
public int getPlayerID(String username)
{
ConfigCategory playerList = this.getCategory( "players" );
if ( playerList == null )
return -1;
Property prop = playerList.get( username );
if ( prop != null && prop.isIntValue() )
return prop.getInt();
else
{
playerList.put( username, prop = new Property( username, "" + nextPlayer(), Property.Type.INTEGER ) );
save();
return prop.getInt();
}
}
}

View file

@ -40,7 +40,7 @@ public enum AEFeature
DenseEnergyCells("HigherCapacity"), DenseCables("HigherCapacity"),
P2PTunnelME("P2PTunnels"), P2PTunnelItems("P2PTunnels"), P2PTunnelRedstone("P2PTunnels"), P2PTunnelEU("P2PTunnels"), P2PTunnelMJ("P2PTunnels"), P2PTunnelLiquids(
"P2PTunnels"),
"P2PTunnels"), Security("Security"),
MassCannonBlockDamage("BlockFeatures"), TinyTNTBlockDamage("BlockFeatures"), Facades("Facades"),

View file

@ -0,0 +1,28 @@
package appeng.core.features.registries;
import net.minecraft.entity.player.EntityPlayer;
import appeng.api.features.IPlayerRegistry;
import appeng.core.WorldSettings;
public class PlayerRegistry implements IPlayerRegistry
{
@Override
public int getID(String username)
{
return WorldSettings.getInstance().getPlayerID( username );
}
@Override
public int getID(EntityPlayer player)
{
return WorldSettings.getInstance().getPlayerID( player.username );
}
@Override
public String getUsername(int id)
{
return WorldSettings.getInstance().getUsername( id );
}
}

View file

@ -4,6 +4,7 @@ import appeng.api.features.IGrinderRegistry;
import appeng.api.features.ILocateableRegistry;
import appeng.api.features.IMatterCannonAmmoRegistry;
import appeng.api.features.IP2PTunnelRegistry;
import appeng.api.features.IPlayerRegistry;
import appeng.api.features.IRegistryContainer;
import appeng.api.features.ISpecialComparisonRegistry;
import appeng.api.features.IWirelessTermRegistery;
@ -25,6 +26,7 @@ public class RegistryContainer implements IRegistryContainer
private P2PTunnelRegistry P2PRegistry = new P2PTunnelRegistry();
private MovableTileRegistry MoveableReg = new MovableTileRegistry();
private MatterCannonAmmoRegistry matterCannonReg = new MatterCannonAmmoRegistry();
private PlayerRegistry playerreg = new PlayerRegistry();
@Override
public IWirelessTermRegistery wireless()
@ -86,4 +88,10 @@ public class RegistryContainer implements IRegistryContainer
return matterCannonReg;
}
@Override
public IPlayerRegistry players()
{
return playerreg;
}
}

View file

@ -0,0 +1,58 @@
package appeng.core.sync.packets;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.network.INetworkManager;
import net.minecraft.tileentity.TileEntity;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerOpenContext;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.GuiBridge;
import appeng.util.Platform;
public class PacketSwitchGuis extends AppEngPacket
{
final GuiBridge newGui;
// automatic.
public PacketSwitchGuis(DataInputStream stream) throws IOException {
newGui = GuiBridge.values()[stream.readInt()];
}
@Override
public void serverPacketData(INetworkManager manager, AppEngPacket packet, EntityPlayer player)
{
Container c = player.openContainer;
if ( c instanceof AEBaseContainer )
{
AEBaseContainer bc = (AEBaseContainer) c;
ContainerOpenContext context = bc.openContext;
if ( context != null )
{
TileEntity te = context.w.getBlockTileEntity( context.x, context.y, context.z );
Platform.openGUI( player, te, context.side, newGui );
}
}
}
// api
public PacketSwitchGuis(GuiBridge newGui) throws IOException {
this.newGui = newGui;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream( bytes );
data.writeInt( getPacketID() );
data.writeInt( newGui.ordinal() );
isChunkDataPacket = false;
configureWrite( bytes.toByteArray() );
}
}

View file

@ -1,9 +1,9 @@
package appeng.helpers;
import net.minecraft.tileentity.TileEntity;
import appeng.api.networking.IGridHost;
import appeng.api.networking.security.IActionHost;
public interface IInterfaceHost extends IGridHost
public interface IInterfaceHost extends IActionHost
{
DualityInterface getInterfaceDuality();

View file

@ -0,0 +1,16 @@
package appeng.helpers;
public interface IPriorityHost
{
/**
* get current priority.
*/
int getPriority();
/**
* set new priority
*/
void setPriority(int newValue);
}

View file

@ -20,7 +20,6 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import appeng.api.AEApi;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartItem;
import appeng.api.parts.PartItemStack;
@ -93,7 +92,7 @@ public class PartPlacement
{
is.add( sp.part.getItemStack( PartItemStack.Wrench ) );
sp.part.getDrops( is, true );
host.removePart( sp.side );
host.removePart( sp.side, false );
}
if ( sp.facade != null )
@ -305,13 +304,9 @@ public class PartPlacement
if ( !world.isRemote )
{
ForgeDirection mySide = host.addPart( held, side );
ForgeDirection mySide = host.addPart( held, side, player );
if ( mySide != null )
{
IPart newlyPlacedPart = host.getPart( mySide );
if ( newlyPlacedPart != null )
newlyPlacedPart.onPlacement( player, held, side );
StepSound ss = AEApi.instance().blocks().blockMultiPart.block().stepSound;
world.playSoundEffect( 0.5 + x, 0.5 + y, 0.5 + z, ss.getPlaceSound(), (ss.getVolume() + 1.0F) / 2.0F, ss.getPitch() * 0.8F );

View file

@ -0,0 +1,24 @@
package appeng.items.contents;
import net.minecraft.item.ItemStack;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
public class CellConfig extends AppEngInternalInventory
{
final ItemStack is;
public CellConfig(ItemStack is) {
super( null, 63 );
this.is = is;
readFromNBT( Platform.openNbtData( is ), "list" );
}
@Override
public void onInventoryChanged()
{
writeToNBT( Platform.openNbtData( is ), "list" );
}
}

View file

@ -0,0 +1,24 @@
package appeng.items.contents;
import net.minecraft.item.ItemStack;
import appeng.parts.automation.UpgradeInventory;
import appeng.util.Platform;
public class CellUpgrades extends UpgradeInventory
{
final ItemStack is;
public CellUpgrades(ItemStack is, int upgrades) {
super( is.getItem(), null, upgrades );
this.is = is;
readFromNBT( Platform.openNbtData( is ), "upgrades" );
}
@Override
public void onInventoryChanged()
{
writeToNBT( Platform.openNbtData( is ), "upgrades" );
}
}

View file

@ -0,0 +1,117 @@
package appeng.items.contents;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import appeng.api.implementations.guiobjects.INetworkTool;
import appeng.api.implementations.items.IUpgradeModule;
import appeng.api.networking.IGridHost;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
public class NetworkToolViewer implements INetworkTool
{
final AppEngInternalInventory inv;
final ItemStack is;
final IGridHost gh;
public NetworkToolViewer(ItemStack is, IGridHost gHost) {
this.is = is;
gh = gHost;
inv = new AppEngInternalInventory( null, 9 );
inv.readFromNBT( Platform.openNbtData( is ), "inv" );
}
@Override
public int getSizeInventory()
{
return inv.getSizeInventory();
}
@Override
public ItemStack getStackInSlot(int i)
{
return inv.getStackInSlot( i );
}
@Override
public ItemStack decrStackSize(int i, int j)
{
return inv.decrStackSize( i, j );
}
@Override
public ItemStack getStackInSlotOnClosing(int i)
{
return inv.getStackInSlotOnClosing( i );
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
inv.setInventorySlotContents( i, itemstack );
}
@Override
public String getInvName()
{
return inv.getInvName();
}
@Override
public boolean isInvNameLocalized()
{
return inv.isInvNameLocalized();
}
@Override
public int getInventoryStackLimit()
{
return inv.getInventoryStackLimit();
}
@Override
public void onInventoryChanged()
{
inv.onInventoryChanged();
inv.writeToNBT( Platform.openNbtData( is ), "inv" );
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return inv.isUseableByPlayer( entityplayer );
}
@Override
public void openChest()
{
inv.openChest();
}
@Override
public void closeChest()
{
inv.closeChest();
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return inv.isItemValidForSlot( i, itemstack ) && itemstack.getItem() instanceof IUpgradeModule
&& ((IUpgradeModule) itemstack.getItem()).getType( itemstack ) != null;
}
@Override
public ItemStack getItemStack()
{
return is;
}
@Override
public IGridHost getGridHost()
{
return gh;
}
}

View file

@ -0,0 +1,54 @@
package appeng.items.contents;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.MEMonitorHandler;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.me.storage.CellInventory;
public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell
{
private ItemStack target;
private IAEItemPowerStorage ips;
public PortableCellViewer(ItemStack is) {
super( CellInventory.getCell( is ) );
ips = (IAEItemPowerStorage) is.getItem();
target = is;
}
public ItemStack getItemStack()
{
return target;
}
@Override
public double extractAEPower(double amt, Actionable mode, PowerMultiplier usePowerMultiplier)
{
amt = usePowerMultiplier.multiply( amt );
if ( mode == Actionable.SIMULATE )
return usePowerMultiplier.divide( Math.min( amt, ips.getAECurrentPower( getItemStack() ) ) );
return usePowerMultiplier.divide( ips.extractAEPower( getItemStack(), amt ) );
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
return this;
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
return null;
}
}

View file

@ -4,6 +4,7 @@ import java.util.Arrays;
import java.util.EnumSet;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.exceptions.FailedConnection;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridConnection;
import appeng.api.networking.IGridNode;
@ -11,6 +12,7 @@ import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.pathing.IPathingGrid;
import appeng.api.util.IReadOnlyCollection;
import appeng.me.pathfinding.IPathItem;
import appeng.util.Platform;
import appeng.util.ReadOnlyCollection;
public class GridConnection implements IGridConnection, IPathItem
@ -26,13 +28,16 @@ public class GridConnection implements IGridConnection, IPathItem
public int channelData = 0;
public GridConnection(IGridNode aNode, IGridNode bNode, ForgeDirection fromAtoB) {
public GridConnection(IGridNode aNode, IGridNode bNode, ForgeDirection fromAtoB) throws FailedConnection {
GridNode a = (GridNode) aNode;
GridNode b = (GridNode) bNode;
if ( Platform.securityCheck( a, b ) )
throw new FailedConnection();
if ( a == null || b == null )
throw new GridException( "Connection Forged Between null entnties." );
throw new GridException( "Connection Forged Between null enties." );
if ( a.hasConnection( b ) || b.hasConnection( a ) )
throw new GridException( "Connection already exists." );

View file

@ -3,11 +3,13 @@ package appeng.me;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.exceptions.FailedConnection;
import appeng.api.networking.GridFlags;
import appeng.api.networking.GridNotification;
import appeng.api.networking.IGrid;
@ -24,7 +26,9 @@ import appeng.api.networking.pathing.IPathingGrid;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IReadOnlyCollection;
import appeng.core.AELog;
import appeng.core.WorldSettings;
import appeng.helpers.TickHandler;
import appeng.me.pathfinding.IPathItem;
import appeng.util.ReadOnlyCollection;
@ -54,6 +58,16 @@ public class GridNode implements IGridNode, IPathItem
private int maxChannels = 8;
private int channelData = 0;
public long lastSecurityKey = -1;
public int playerID = -1;
@Override
public void setPlayerID(int playerID)
{
if ( playerID >= 0 )
this.playerID = playerID;
}
public int usedChannels()
{
return channelData >> 8;
@ -72,7 +86,13 @@ public class GridNode implements IGridNode, IPathItem
public void loadFromNBT(String name, NBTTagCompound nodeData)
{
if ( myGrid == null )
setGridStorage( WorldSettings.getInstance().getGridStorage( nodeData.getLong( name ) ) );
{
NBTTagCompound node = nodeData.getCompoundTag( name );
playerID = node.getInteger( "p" );
lastSecurityKey = node.getLong( "k" );
AELog.info( "Player: " + playerID );
setGridStorage( WorldSettings.getInstance().getGridStorage( node.getLong( "g" ) ) );
}
else
throw new RuntimeException( "Loading data after part of a grid, this is invalid." );
}
@ -81,7 +101,15 @@ public class GridNode implements IGridNode, IPathItem
public void saveToNBT(String name, NBTTagCompound nodeData)
{
if ( myStorage != null )
nodeData.setLong( name, myStorage.getID() );
{
NBTTagCompound node = new NBTTagCompound();
node.setInteger( "p", playerID );
node.setLong( "k", lastSecurityKey );
node.setLong( "g", myStorage.getID() );
nodeData.setCompoundTag( name, node );
}
else
nodeData.removeTag( name );
}
@ -211,6 +239,8 @@ public class GridNode implements IGridNode, IPathItem
if ( !gridProxy.isWorldAccessable() )
return;
EnumSet<ForgeDirection> newSecurityConnections = EnumSet.noneOf( ForgeDirection.class );
DimensionalCoord dc = gridProxy.getLocation();
for (ForgeDirection f : ForgeDirection.VALID_DIRECTIONS)
{
@ -250,12 +280,67 @@ public class GridNode implements IGridNode, IPathItem
}
else if ( isValidConnection )
{
// construct a new connection between these two nodes.
new GridConnection( node, this, f.getOpposite() );
if ( node.lastSecurityKey != -1 )
newSecurityConnections.add( f );
else
{
// construct a new connection between these two nodes.
try
{
new GridConnection( node, this, f.getOpposite() );
}
catch (FailedConnection e)
{
TickHandler.instance.addCallable( new Callable() {
@Override
public Object call() throws Exception
{
getMachine().securityBreak();
return null;
}
} );
return;
}
}
}
}
}
for (ForgeDirection f : newSecurityConnections)
{
IGridHost te = findGridHost( dc.getWorld(), dc.x + f.offsetX, dc.y + f.offsetY, dc.z + f.offsetZ );
if ( te != null )
{
GridNode node = (GridNode) te.getGridNode( f.getOpposite() );
if ( node == null )
continue;
// construct a new connection between these two nodes.
try
{
new GridConnection( node, this, f.getOpposite() );
}
catch (FailedConnection e)
{
TickHandler.instance.addCallable( new Callable() {
@Override
public Object call() throws Exception
{
getMachine().securityBreak();
return null;
}
} );
return;
}
}
}
}
private IGridHost findGridHost(World world, int x, int y, int z)
@ -491,4 +576,10 @@ public class GridNode implements IGridNode, IPathItem
return getGridBlock().getFlags().contains( flag );
}
@Override
public int getPlayerID()
{
return playerID;
}
}

View file

@ -10,6 +10,7 @@ import appeng.api.networking.IGridStorage;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.storage.IStackWatcher;
import appeng.api.networking.storage.IStackWatcherHost;
@ -68,12 +69,12 @@ public class GridStorageCache implements IStorageGrid
for (IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( StorageChannel.ITEMS ))
{
postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList<IAEItemStack>() ), new MachineSource( machine ) );
postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList<IAEItemStack>() ), new MachineSource( cc ) );
}
for (IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( StorageChannel.FLUIDS ))
{
postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList<IAEFluidStack>() ), new MachineSource( machine ) );
postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList<IAEFluidStack>() ), new MachineSource( cc ) );
}
}
@ -100,12 +101,12 @@ public class GridStorageCache implements IStorageGrid
for (IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( StorageChannel.ITEMS ))
{
postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList<IAEItemStack>() ), new MachineSource( machine ) );
postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList<IAEItemStack>() ), new MachineSource( cc ) );
}
for (IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( StorageChannel.FLUIDS ))
{
postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList<IAEFluidStack>() ), new MachineSource( machine ) );
postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList<IAEFluidStack>() ), new MachineSource( cc ) );
}
}
@ -120,10 +121,12 @@ public class GridStorageCache implements IStorageGrid
private void buildNetworkStorage(StorageChannel chan)
{
SecurityCache security = myGrid.getCache( ISecurityGrid.class );
switch (chan)
{
case FLUIDS:
myFluidNetwork = new NetworkInventoryHandler<IAEFluidStack>( StorageChannel.FLUIDS );
myFluidNetwork = new NetworkInventoryHandler<IAEFluidStack>( StorageChannel.FLUIDS, security );
for (ICellContainer cc : cellContainers)
{
for (IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( chan ))
@ -131,7 +134,7 @@ public class GridStorageCache implements IStorageGrid
}
break;
case ITEMS:
myItemNetwork = new NetworkInventoryHandler<IAEItemStack>( StorageChannel.ITEMS );
myItemNetwork = new NetworkInventoryHandler<IAEItemStack>( StorageChannel.ITEMS, security );
for (ICellContainer cc : cellContainers)
{
for (IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( chan ))

153
me/cache/SecurityCache.java vendored Normal file
View file

@ -0,0 +1,153 @@
package appeng.me.cache;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridCache;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridStorage;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkSecurityChange;
import appeng.api.networking.security.ISecurityGrid;
import appeng.core.WorldSettings;
import appeng.me.GridNode;
import appeng.tile.misc.TileSecurity;
public class SecurityCache implements IGridCache, ISecurityGrid
{
private List<TileSecurity> securityProvider = new ArrayList();
private HashMap<Integer, EnumSet<SecurityPermissions>> playerPerms = new HashMap<Integer, EnumSet<SecurityPermissions>>();
public SecurityCache(IGrid g) {
myGrid = g;
}
private long securityKey = -1;
public final IGrid myGrid;
@MENetworkEventSubscribe
public void updatePermissions(MENetworkSecurityChange ev)
{
playerPerms.clear();
if ( securityProvider.isEmpty() )
return;
securityProvider.get( 0 ).readPermissions( playerPerms );
}
public long getSecurityKey()
{
return securityKey;
}
@Override
public boolean isAvailable()
{
return securityProvider.size() == 1 && securityProvider.get( 0 ).isSecurityEnabled();
}
@Override
public boolean hasPermission(EntityPlayer player, SecurityPermissions perm)
{
return hasPermission( WorldSettings.getInstance().getPlayerID( player.username ), perm );
}
@Override
public boolean hasPermission(int playerID, SecurityPermissions perm)
{
if ( isAvailable() )
{
EnumSet<SecurityPermissions> perms = playerPerms.get( playerID );
if ( perms == null )
{
if ( playerID == -1 ) // no default?
return false;
else
return hasPermission( -1, perm );
}
return perms.contains( perm );
}
return true;
}
private void updateSecurityKey()
{
long lastCode = securityKey;
if ( securityProvider.size() == 1 )
securityKey = securityProvider.get( 0 ).securityKey;
else
securityKey = -1;
if ( lastCode != securityKey )
{
myGrid.postEvent( new MENetworkSecurityChange() );
for (IGridNode n : myGrid.getNodes())
((GridNode) n).lastSecurityKey = securityKey;
}
}
@Override
public void removeNode(IGrid grid, IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof TileSecurity )
{
securityProvider.remove( (TileSecurity) machine );
updateSecurityKey();
}
}
@Override
public void addNode(IGrid grid, IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof TileSecurity )
{
securityProvider.add( (TileSecurity) machine );
updateSecurityKey();
}
else
((GridNode) gridNode).lastSecurityKey = securityKey;
}
@Override
public void onUpdateTick(IGrid grid)
{
}
@Override
public void onSplit(IGridStorage destinationStorage)
{
}
@Override
public void onJoin(IGridStorage sourceStorage)
{
}
@Override
public void populateGridStorage(IGridStorage destinationStorage)
{
}
@Override
public int getOwner()
{
if ( isAvailable() )
return securityProvider.get( 0 ).getOwner();
return -1;
}
}

View file

@ -10,6 +10,7 @@ import net.minecraftforge.event.world.WorldEvent;
import appeng.api.AEApi;
import appeng.api.events.LocatableEventAnnounce;
import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
import appeng.api.exceptions.FailedConnection;
import appeng.api.features.ILocatable;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
@ -135,7 +136,14 @@ public class QuantumCluster implements ILocatable, IAECluster
return;
}
sideA.connection = sideB.connection = new ConnectionWrapper( AEApi.instance().createGridConnection( sideA.getNode(), sideB.getNode() ) );
try
{
sideA.connection = sideB.connection = new ConnectionWrapper( AEApi.instance().createGridConnection( sideA.getNode(), sideB.getNode() ) );
}
catch (FailedConnection e)
{
// :(
}
}
else
shutdown = true;

View file

@ -2,6 +2,7 @@ package appeng.me.helpers;
import java.util.EnumSet;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
@ -20,6 +21,7 @@ import appeng.api.networking.ticking.ITickManager;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IOrientable;
import appeng.core.WorldSettings;
import appeng.helpers.TickHandler;
import appeng.me.GridAccessException;
import appeng.me.cache.P2PCache;
@ -47,6 +49,8 @@ public class AENetworkProxy implements IGridBlock
final private String nbtName; // name
NBTTagCompound data = null; // input
private EntityPlayer owner;
@Override
public ItemStack getMachineRepresentation()
{
@ -75,6 +79,11 @@ public class AENetworkProxy implements IGridBlock
node.loadFromNBT( nbtName, data );
data = null;
}
else if ( node != null && owner != null )
{
node.setPlayerID( WorldSettings.getInstance().getPlayerID( owner.username ) );
owner = null;
}
}
@Override
@ -312,4 +321,9 @@ public class AENetworkProxy implements IGridBlock
gp.gridChanged();
}
public void setOwner(EntityPlayer player)
{
owner = player;
}
}

View file

@ -6,6 +6,8 @@ import appeng.api.util.DimensionalCoord;
public interface IGridProxyable extends IGridHost
{
AENetworkProxy getProxy();
DimensionalCoord getLocation();
void gridChanged();

View file

@ -9,11 +9,18 @@ import java.util.TreeMap;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.security.PlayerSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.cache.SecurityCache;
public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
@ -29,11 +36,14 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
};
final StorageChannel myChannel;
final SecurityCache security;
// final TreeMultimap<Integer, IMEInventoryHandler<T>> prorityInventory;
final TreeMap<Integer, List<IMEInventoryHandler<T>>> prorityInventory;
public NetworkInventoryHandler(StorageChannel chan) {
public NetworkInventoryHandler(StorageChannel chan, SecurityCache security) {
myChannel = chan;
this.security = security;
prorityInventory = new TreeMap( prioritySorter ); // TreeMultimap.create( prioritySorter, hashSorter );
}
@ -86,12 +96,50 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
}
private boolean testPermission(BaseActionSource src, SecurityPermissions inject)
{
if ( src.isPlayer() )
{
if ( !security.hasPermission( ((PlayerSource) src).player, SecurityPermissions.INJECT ) )
return true;
}
else if ( src.isMachine() )
{
if ( security.isAvailable() )
{
IGridNode n = ((MachineSource) src).via.getActionableNode();
if ( n == null )
return true;
IGrid gn = n.getGrid();
if ( gn != security.myGrid )
{
int playerID = -1;
ISecurityGrid sg = gn.getCache( ISecurityGrid.class );
playerID = sg.getOwner();
if ( !security.hasPermission( playerID, SecurityPermissions.INJECT ) )
return true;
}
}
}
return false;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
{
if ( diveList( this ) )
return input;
if ( testPermission( src, SecurityPermissions.INJECT ) )
{
surface( this );
return input;
}
Iterator<List<IMEInventoryHandler<T>>> i = prorityInventory.values().iterator();// asMap().entrySet().iterator();
while (i.hasNext())
@ -127,6 +175,12 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
if ( diveList( this ) )
return null;
if ( testPermission( src, SecurityPermissions.EXTRACT ) )
{
surface( this );
return null;
}
Iterator<List<IMEInventoryHandler<T>>> i = prorityInventory.descendingMap().values().iterator();// prorityInventory.asMap().descendingMap().entrySet().iterator();
T output = request.copy();

View file

@ -3,6 +3,7 @@ package appeng.parts;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
@ -20,8 +21,8 @@ import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollsionHelper;
import appeng.api.parts.IPartHost;
@ -34,8 +35,9 @@ import appeng.api.util.IConfigManager;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.parts.networking.PartCable;
import appeng.util.Platform;
public class AEBasePart implements IPart, IGridProxyable, IGridHost, IUpgradeableHost
public class AEBasePart implements IPart, IGridProxyable, IActionHost, IUpgradeableHost
{
protected AENetworkProxy proxy;
@ -277,7 +279,7 @@ public class AEBasePart implements IPart, IGridProxyable, IGridHost, IUpgradeabl
@Override
public void onPlacement(EntityPlayer player, ItemStack held, ForgeDirection side)
{
proxy.setOwner( player );
}
@Override
@ -286,4 +288,29 @@ public class AEBasePart implements IPart, IGridProxyable, IGridHost, IUpgradeabl
return tile;
}
@Override
public void securityBreak()
{
if ( is.stackSize > 0 )
{
List<ItemStack> items = new ArrayList();
items.add( is.copy() );
host.removePart( side, false );
Platform.spawnDrops( tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, items );
is.stackSize = 0;
}
}
@Override
public AENetworkProxy getProxy()
{
return proxy;
}
@Override
public IGridNode getActionableNode()
{
return proxy.getNode();
}
}

View file

@ -23,6 +23,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import powercrystals.minefactoryreloaded.api.rednet.RedNetConnectionType;
import appeng.api.AEApi;
import appeng.api.exceptions.FailedConnection;
import appeng.api.implementations.parts.IPartCable;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
@ -76,7 +77,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
}
@Override
public void removePart(ForgeDirection side)
public void removePart(ForgeDirection side, boolean supressUpdate)
{
if ( side == ForgeDirection.UNKNOWN )
{
@ -91,9 +92,12 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
sides[side.ordinal()] = null;
}
updateConnections();
markForUpdate();
PartChanged();
if ( !supressUpdate )
{
updateConnections();
markForUpdate();
PartChanged();
}
}
/**
@ -154,7 +158,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
}
@Override
public ForgeDirection addPart(ItemStack is, ForgeDirection side)
public ForgeDirection addPart(ItemStack is, ForgeDirection side, EntityPlayer player)
{
if ( canAddPart( is, side ) )
{
@ -182,6 +186,9 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
center = (IPartCable) bp;
bp.setPartHostInfo( ForgeDirection.UNKNOWN, this, tcb.getTile() );
if ( player != null )
bp.onPlacement( player, is, side );
if ( inWorld )
bp.addToWorld();
@ -195,7 +202,20 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
{
IGridNode sn = sbp.getGridNode();
if ( sn != null && cn != null )
new GridConnection( (IGridNode) cn, (IGridNode) sn, ForgeDirection.UNKNOWN );
{
try
{
new GridConnection( (IGridNode) cn, (IGridNode) sn, ForgeDirection.UNKNOWN );
}
catch (FailedConnection e)
{
// ekk!
bp.removeFromWorld();
center = null;
return null;
}
}
}
}
}
@ -214,6 +234,9 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
sides[side.ordinal()] = bp;
bp.setPartHostInfo( side, this, this.getTile() );
if ( player != null )
bp.onPlacement( player, is, side );
if ( inWorld )
bp.addToWorld();
@ -224,7 +247,18 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
if ( cn != null && sn != null )
{
new GridConnection( (IGridNode) cn, (IGridNode) sn, ForgeDirection.UNKNOWN );
try
{
new GridConnection( (IGridNode) cn, (IGridNode) sn, ForgeDirection.UNKNOWN );
}
catch (FailedConnection e)
{
// ekk!
bp.removeFromWorld();
sides[side.ordinal()] = null;
return null;
}
}
}
@ -270,7 +304,14 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
IGridNode cn = center.getGridNode();
if ( cn != null )
{
AEApi.instance().createGridConnection( cn, sn );
try
{
AEApi.instance().createGridConnection( cn, sn );
}
catch (FailedConnection e)
{
// ekk
}
}
}
@ -645,8 +686,8 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
p.readFromStream( data );
else
{
removePart( side );
side = addPart( new ItemStack( Item.itemsList[itemID], 1, dmgValue ), side );
removePart( side, false );
side = addPart( new ItemStack( Item.itemsList[itemID], 1, dmgValue ), side, null );
if ( side != null )
{
p = getPart( side );
@ -657,7 +698,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
}
}
else
removePart( side );
removePart( side, false );
}
return fc.readFromStream( data );
@ -722,8 +763,8 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
p.readFromNBT( extra );
else
{
removePart( side );
side = addPart( iss, side );
removePart( side, false );
side = addPart( iss, side, null );
if ( side != null )
{
p = getPart( side );
@ -734,7 +775,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
}
}
else
removePart( side );
removePart( side, false );
}
}
@ -985,4 +1026,15 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
// never called
}
@Override
public void securityBreak()
{
for (ForgeDirection d : ForgeDirection.values())
{
IPart p = getPart( d );
if ( p != null && p instanceof IGridHost )
((IGridHost) p).securityBreak();
}
}
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
@ -13,7 +14,9 @@ import net.minecraftforge.common.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.FuzzyMode;
import appeng.api.config.IncludeExclude;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.security.BaseActionSource;
@ -32,25 +35,35 @@ import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReciever;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.client.texture.CableBusTextures;
import appeng.core.sync.GuiBridge;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.me.storage.MEInventoryHandler;
import appeng.me.storage.MEMonitorIInventory;
import appeng.parts.automation.PartUpgradeable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.item.ItemList;
import appeng.util.prioitylist.FuzzyPriorityList;
import appeng.util.prioitylist.PrecisePriorityList;
import buildcraft.api.transport.IPipeConnection;
import buildcraft.api.transport.IPipeTile.PipeType;
import cpw.mods.fml.common.Optional.Interface;
import cpw.mods.fml.common.Optional.Method;
@Interface(modid = "BuildCraft|Transport", iface = "buildcraft.api.transport.IPipeConnection")
public class PartStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IMEMonitorHandlerReciever<IAEItemStack>, IPipeConnection
public class PartStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IMEMonitorHandlerReciever<IAEItemStack>, IPipeConnection,
IPriorityHost
{
int priority = 0;
BaseActionSource mySrc;
AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 );
public PartStorageBus(ItemStack is) {
super( PartStorageBus.class, is );
getConfigManager().registerSetting( Settings.ACCESS, AccessRestriction.READ_WRITE );
@ -91,11 +104,22 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
@Override
public void onNeighborChanged()
public IInventory getInventoryByName(String name)
{
if ( name.equals( "config" ) )
return Config;
return super.getInventoryByName( name );
}
private void resetCache(boolean fullReset)
{
cached = false;
if ( fullReset )
handlerHash = 0;
try
{
// force grid to update handlers...
proxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
}
catch (GridAccessException e)
@ -104,6 +128,36 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
}
@Override
public void onNeighborChanged()
{
resetCache( false );
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack)
{
super.onChangeInventory( inv, slot, mc, removedStack, newStack );
if ( inv == Config )
resetCache( true );
}
@Override
public void updateSetting(Enum settingName, Enum newValue)
{
resetCache( true );
host.markForSave();
}
@Override
public void setPriority(int newValue)
{
priority = newValue;
host.markForSave();
resetCache( true );
}
private MEInventoryHandler getHandler()
{
if ( cached )
@ -140,6 +194,25 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
handler = new MEInventoryHandler( inv );
handler.myAccess = (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS );
handler.myWhitelist = getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST;
handler.myPriority = priority;
IItemList priorityList = new ItemList();
int slotsToUse = 18 + getInstalledUpgrades( Upgrades.CAPACITY ) * 9;
for (int x = 0; x < Config.getSizeInventory() && x < slotsToUse; x++)
{
IAEItemStack is = Config.getAEStackInSlot( x );
if ( is != null )
priorityList.add( is );
}
if ( getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
handler.myPartitionList = new FuzzyPriorityList( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) );
else
handler.myPartitionList = new PrecisePriorityList( priorityList );
if ( inv instanceof IMEMonitor )
((IMEMonitor) inv).addListener( this, handler );
}
@ -242,16 +315,18 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
@Override
public void writeToNBT(NBTTagCompound extra)
public void writeToNBT(NBTTagCompound data)
{
super.writeToNBT( extra );
extra.setInteger( "priority", priority );
super.writeToNBT( data );
Config.writeToNBT( data, "config" );
data.setInteger( "priority", priority );
}
public void readFromNBT(NBTTagCompound extra)
public void readFromNBT(NBTTagCompound data)
{
super.readFromNBT( extra );
priority = extra.getInteger( "priority" );
super.readFromNBT( data );
Config.readFromNBT( data, "config" );
priority = data.getInteger( "priority" );
};
@Override

View file

@ -1,8 +1,11 @@
package appeng.parts.misc;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
@ -11,6 +14,7 @@ import net.minecraftforge.common.ForgeDirection;
import org.lwjgl.opengl.GL11;
import appeng.api.AEApi;
import appeng.api.exceptions.FailedConnection;
import appeng.api.networking.IGridConnection;
import appeng.api.networking.IGridNode;
import appeng.api.parts.IPartCollsionHelper;
@ -20,6 +24,7 @@ import appeng.api.util.AECableType;
import appeng.client.texture.CableBusTextures;
import appeng.me.helpers.AENetworkProxy;
import appeng.parts.PartBasicState;
import appeng.util.Platform;
public class PartToggleBus extends PartBasicState
{
@ -31,6 +36,13 @@ public class PartToggleBus extends PartBasicState
boolean hasRedstone = false;
@Override
public void onPlacement(EntityPlayer player, ItemStack held, ForgeDirection side)
{
super.onPlacement( player, held, side );
outerProxy.setOwner( player );
}
@Override
protected int populateFlags(int cf)
{
@ -96,7 +108,14 @@ public class PartToggleBus extends PartBasicState
{
if ( intention )
{
connection = AEApi.instance().createGridConnection( proxy.getNode(), outerProxy.getNode() );
try
{
connection = AEApi.instance().createGridConnection( proxy.getNode(), outerProxy.getNode() );
}
catch (FailedConnection e)
{
// :(
}
}
else
{
@ -195,4 +214,17 @@ public class PartToggleBus extends PartBasicState
{
return 5;
}
@Override
public void securityBreak()
{
if ( is.stackSize > 0 )
{
List<ItemStack> items = new ArrayList();
items.add( is.copy() );
host.removePart( side, false );
Platform.spawnDrops( tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, items );
is.stackSize = 0;
}
}
}

View file

@ -4,6 +4,7 @@ import java.util.EnumSet;
import java.util.Set;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
@ -36,6 +37,13 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider
proxy.setFlags( GridFlags.CANNOT_CARRY );
}
@Override
public void onPlacement(EntityPlayer player, ItemStack held, ForgeDirection side)
{
super.onPlacement( player, held, side );
outerProxy.setOwner( player );
}
@Override
public void setPartHostInfo(ForgeDirection side, IPartHost host, TileEntity tile)
{

View file

@ -8,6 +8,7 @@ import net.minecraft.util.Icon;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.config.PowerUnits;
import appeng.api.config.TunnelType;
import appeng.api.networking.IGridNode;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
@ -27,6 +28,11 @@ public class PartP2PBCPower extends PartP2PTunnel<PartP2PBCPower> implements IPo
PowerHandler pp;
public TunnelType getTunnelType()
{
return TunnelType.BC_POWER;
}
public PartP2PBCPower(ItemStack is) {
super( is );
pp = new PowerHandler( this, Type.MACHINE );

View file

@ -8,6 +8,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.config.TunnelType;
import appeng.me.GridAccessException;
import appeng.me.cache.helpers.TunnelCollection;
import appeng.util.Platform;
@ -17,6 +18,11 @@ import cpw.mods.fml.relauncher.SideOnly;
public class PartP2PIC2Power extends PartP2PTunnel<PartP2PIC2Power> implements ic2.api.energy.tile.IEnergySink, ic2.api.energy.tile.IEnergySource
{
public TunnelType getTunnelType()
{
return TunnelType.IC2_POWER;
}
public PartP2PIC2Power(ItemStack is) {
super( is );
}

View file

@ -12,6 +12,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.util.Icon;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.config.TunnelType;
import appeng.core.AppEng;
import appeng.integration.abstraction.IBC;
import appeng.integration.abstraction.ITE;
@ -31,6 +32,11 @@ import cpw.mods.fml.relauncher.SideOnly;
public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IPipeConnection, IInventory, ISidedInventory
{
public TunnelType getTunnelType()
{
return TunnelType.ITEM;
}
public PartP2PItems(ItemStack is) {
super( is );
}

View file

@ -14,6 +14,7 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import appeng.api.config.TunnelType;
import appeng.me.GridAccessException;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ -21,6 +22,11 @@ import cpw.mods.fml.relauncher.SideOnly;
public class PartP2PLiquids extends PartP2PTunnel<PartP2PLiquids> implements IFluidHandler
{
public TunnelType getTunnelType()
{
return TunnelType.FLUID;
}
public PartP2PLiquids(ItemStack is) {
super( is );
}

View file

@ -6,6 +6,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
import appeng.api.config.TunnelType;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
@ -17,6 +18,11 @@ import cpw.mods.fml.relauncher.SideOnly;
public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
{
public TunnelType getTunnelType()
{
return TunnelType.REDSTONE;
}
public PartP2PRedstone(ItemStack is) {
super( is );
}

View file

@ -65,8 +65,8 @@ public class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
ItemStack newType = ItemStack.loadItemStackFromNBT( data );
long freq = data.getLong( "freq" );
getHost().removePart( side );
ForgeDirection dir = getHost().addPart( newType, side );
getHost().removePart( side, true );
ForgeDirection dir = getHost().addPart( newType, side, player );
IPart newBus = getHost().getPart( dir );
if ( newBus instanceof PartP2PTunnel )
@ -125,8 +125,8 @@ public class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
boolean oldOutput = output;
long myFreq = freq;
getHost().removePart( side );
ForgeDirection dir = getHost().addPart( newType, side );
getHost().removePart( side, false );
ForgeDirection dir = getHost().addPart( newType, side, player );
IPart newBus = getHost().getPart( dir );
if ( newBus instanceof PartP2PTunnel )
@ -152,6 +152,11 @@ public class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
return false;
}
public TunnelType getTunnelType()
{
return null;
}
@Override
public boolean onShiftActivate(EntityPlayer player, Vec3 pos)
{

View file

@ -4,11 +4,14 @@ import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.TunnelType;
import appeng.api.exceptions.FailedConnection;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.ticking.IGridTickable;
@ -16,7 +19,6 @@ import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPartHost;
import appeng.api.util.AECableType;
import appeng.core.AELog;
import appeng.helpers.TickHandler;
import appeng.me.GridAccessException;
import appeng.me.cache.helpers.Connections;
@ -26,6 +28,11 @@ import appeng.me.helpers.AENetworkProxy;
public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements IGridTickable
{
public TunnelType getTunnelType()
{
return TunnelType.ME;
}
AENetworkProxy outerProxy = new AENetworkProxy( this, "outer", null, true );
public Connections connection = new Connections( this );
@ -143,6 +150,13 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
return TickRateModulation.IDLE;
}
@Override
public void onPlacement(EntityPlayer player, ItemStack held, ForgeDirection side)
{
super.onPlacement( player, held, side );
outerProxy.setOwner( player );
}
public void updateConnections(Connections connections)
{
if ( connections.destroy )
@ -159,7 +173,6 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
while (i.hasNext())
{
TunnelConnection cw = i.next();
AELog.info( "Old!" );
try
{
if ( cw.tunnel.proxy.getGrid() != proxy.getGrid() )
@ -175,7 +188,7 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
}
catch (GridAccessException e)
{
e.printStackTrace();
// e.printStackTrace();
}
}
@ -192,8 +205,16 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
for (PartP2PTunnelME me : newSides)
{
connections.connections.put( me.getGridNode(),
new TunnelConnection( me, AEApi.instance().createGridConnection( outerProxy.getNode(), me.outerProxy.getNode() ) ) );
try
{
connections.connections.put( me.getGridNode(),
new TunnelConnection( me, AEApi.instance().createGridConnection( outerProxy.getNode(), me.outerProxy.getNode() ) ) );
}
catch (FailedConnection e)
{
e.printStackTrace();
// :(
}
}
}
catch (GridAccessException e)

View file

@ -1,14 +0,0 @@
package appeng.server;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
public class Security
{
public static boolean hasPermissions(TileEntity myTile, EntityPlayer player, AccessType blockAccess)
{
return true;
}
}

View file

@ -335,4 +335,9 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile
return null;
}
public void securityBreak()
{
worldObj.destroyBlock( xCoord, yCoord, zCoord, true );
dropItems = false;
}
}

View file

@ -1,17 +1,51 @@
package appeng.tile.grid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.AEBaseInvTile;
import appeng.tile.events.AETileEventHandler;
import appeng.tile.events.TileEventType;
public abstract class AENetworkInvTile extends AEBaseInvTile implements IGridHost, IGridProxyable
public abstract class AENetworkInvTile extends AEBaseInvTile implements IActionHost, IGridProxyable
{
class AENetworkInvTileHandler extends AETileEventHandler
{
public AENetworkInvTileHandler() {
super( TileEventType.WORLD_NBT );
}
@Override
public void readFromNBT(NBTTagCompound data)
{
gridProxy.readFromNBT( data );
}
@Override
public void writeToNBT(NBTTagCompound data)
{
gridProxy.writeToNBT( data );
}
};
public AENetworkInvTile() {
addNewHandler( new AENetworkInvTileHandler() );
}
protected AENetworkProxy gridProxy = new AENetworkProxy( this, "proxy", getItemFromTile( this ), true );
@Override
public AENetworkProxy getProxy()
{
return gridProxy;
}
@Override
public IGridNode getGridNode(ForgeDirection dir)
{
@ -51,4 +85,10 @@ public abstract class AENetworkInvTile extends AEBaseInvTile implements IGridHos
{
}
@Override
public IGridNode getActionableNode()
{
return gridProxy.getNode();
}
}

View file

@ -1,19 +1,53 @@
package appeng.tile.grid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.events.AETileEventHandler;
import appeng.tile.events.TileEventType;
import appeng.tile.powersink.AEBasePoweredTile;
public abstract class AENetworkPowerTile extends AEBasePoweredTile implements IGridHost, IGridProxyable
public abstract class AENetworkPowerTile extends AEBasePoweredTile implements IActionHost, IGridProxyable
{
class AENetworkPowerTileHandler extends AETileEventHandler
{
public AENetworkPowerTileHandler() {
super( TileEventType.WORLD_NBT );
}
@Override
public void readFromNBT(NBTTagCompound data)
{
gridProxy.readFromNBT( data );
}
@Override
public void writeToNBT(NBTTagCompound data)
{
gridProxy.writeToNBT( data );
}
};
public AENetworkPowerTile() {
addNewHandler( new AENetworkPowerTileHandler() );
}
protected AENetworkProxy gridProxy = new AENetworkProxy( this, "proxy", getItemFromTile( this ), true );
@Override
public AENetworkProxy getProxy()
{
return gridProxy;
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
@ -65,4 +99,10 @@ public abstract class AENetworkPowerTile extends AEBasePoweredTile implements IG
{
}
@Override
public IGridNode getActionableNode()
{
return gridProxy.getNode();
}
}

View file

@ -1,17 +1,45 @@
package appeng.tile.grid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.AEBaseTile;
import appeng.tile.events.AETileEventHandler;
import appeng.tile.events.TileEventType;
public class AENetworkTile extends AEBaseTile implements IGridHost, IGridProxyable
public class AENetworkTile extends AEBaseTile implements IActionHost, IGridProxyable
{
class AENetworkTileHandler extends AETileEventHandler
{
public AENetworkTileHandler() {
super( TileEventType.WORLD_NBT );
}
@Override
public void readFromNBT(NBTTagCompound data)
{
gridProxy.readFromNBT( data );
}
@Override
public void writeToNBT(NBTTagCompound data)
{
gridProxy.writeToNBT( data );
}
};
public AENetworkTile() {
addNewHandler( new AENetworkTileHandler() );
}
final protected AENetworkProxy gridProxy = createProxy();
protected AENetworkProxy createProxy()
@ -70,4 +98,16 @@ public class AENetworkTile extends AEBaseTile implements IGridHost, IGridProxyab
{
}
@Override
public AENetworkProxy getProxy()
{
return gridProxy;
}
@Override
public IGridNode getActionableNode()
{
return gridProxy.getNode();
}
}

View file

@ -22,7 +22,6 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.me.GridAccessException;
import appeng.server.AccessType;
import appeng.server.Security;
import appeng.tile.events.AETileEventHandler;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkPowerTile;
@ -226,7 +225,7 @@ public class TileCharger extends AENetworkPowerTile implements ICrankable
public void activate(EntityPlayer player)
{
if ( !Security.hasPermissions( this, player, AccessType.BLOCK_ACCESS ) )
if ( !Platform.hasPermissions( this, player, AccessType.BLOCK_ACCESS ) )
return;
ItemStack myItem = getStackInSlot( 0 );

147
tile/misc/TileSecurity.java Normal file
View file

@ -0,0 +1,147 @@
package appeng.tile.misc;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.EnumSet;
import java.util.HashMap;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.tile.events.AETileEventHandler;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.util.Platform;
public class TileSecurity extends AENetworkTile
{
private static int diffrence = 0;
private boolean isActive = false;
public long securityKey;
@Override
public void onReady()
{
super.onReady();
if ( Platform.isServer() )
isActive = true;
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
isActive = false;
}
@Override
public void invalidate()
{
super.invalidate();
isActive = false;
}
class SecurityHandler extends AETileEventHandler
{
public SecurityHandler() {
super( TileEventType.WORLD_NBT, TileEventType.NETWORK );
}
@Override
public boolean readFromStream(DataInputStream data) throws IOException
{
boolean wasActive = isActive;
isActive = data.readBoolean();
return wasActive != isActive;
}
@Override
public void writeToStream(DataOutputStream data) throws IOException
{
data.writeBoolean( gridProxy.isActive() );
}
@Override
public void writeToNBT(NBTTagCompound data)
{
data.setLong( "securityKey", securityKey );
}
@Override
public void readFromNBT(NBTTagCompound data)
{
securityKey = data.getLong( "securityKey" );
}
};
public void readPermissions(HashMap<Integer, EnumSet<SecurityPermissions>> playerPerms)
{
playerPerms.put( gridProxy.getNode().getPlayerID(), EnumSet.allOf( SecurityPermissions.class ) );
}
@MENetworkEventSubscribe
public void bootUpdate(MENetworkChannelsChanged changed)
{
markForUpdate();
}
@MENetworkEventSubscribe
public void powerUpdate(MENetworkPowerStatusChange changed)
{
markForUpdate();
}
public boolean isSecurityEnabled()
{
return isActive && gridProxy.isActive();
}
public void updateNodeCount(int nodes)
{
gridProxy.setIdlePowerUsage( 2.0 + ((double) nodes / 0.033) );
}
public TileSecurity() {
addNewHandler( new SecurityHandler() );
gridProxy.setFlags( GridFlags.REQURE_CHANNEL );
gridProxy.setIdlePowerUsage( 2.0 );
diffrence++;
securityKey = System.currentTimeMillis() * 10 + diffrence;
if ( diffrence > 10 )
diffrence = 0;
}
public int getOwner()
{
return gridProxy.getNode().getPlayerID();
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
public boolean isActive()
{
return isActive;
}
}

View file

@ -8,6 +8,7 @@ import java.util.EnumSet;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
@ -143,15 +144,15 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl
}
@Override
public ForgeDirection addPart(ItemStack is, ForgeDirection side)
public ForgeDirection addPart(ItemStack is, ForgeDirection side, EntityPlayer player)
{
return cb.addPart( is, side );
return cb.addPart( is, side, player );
}
@Override
public void removePart(ForgeDirection side)
public void removePart(ForgeDirection side, boolean supressUpdate)
{
cb.removePart( side );
cb.removePart( side, supressUpdate );
}
@Override

View file

@ -50,11 +50,15 @@ import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.SecurityPermissions;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.api.implementations.items.IAEWrench;
import appeng.api.implementations.tiles.ITileStorageMonitorable;
import appeng.api.networking.IGrid;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitorHandlerReciever;
@ -68,8 +72,8 @@ import appeng.api.util.AEItemDefinition;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.me.GridNode;
import appeng.server.AccessType;
import appeng.server.Security;
import appeng.util.item.AEItemStack;
import appeng.util.item.AESharedNBT;
import appeng.util.item.ItemList;
@ -274,19 +278,26 @@ public class Platform
return FMLCommonHandler.instance().getEffectiveSide().isServer();
}
public static boolean hasPermissions(TileEntity myTile, EntityPlayer player, AccessType blockAccess)
{
return true;
}
public static void openGUI(EntityPlayer p, TileEntity tile, ForgeDirection side, GuiBridge type)
{
if ( isClient() )
return;
if ( tile == null )
if ( type.isItem() || hasPermissions( tile, p, AccessType.BLOCK_ACCESS ) )
{
p.openGui( AppEng.instance, type.ordinal() << 3, p.getEntityWorld(), (int) p.posX, (int) p.posY, (int) p.posZ );
}
else
{
if ( type.isItem() || Security.hasPermissions( tile, p, AccessType.BLOCK_ACCESS ) )
if ( tile == null )
{
p.openGui( AppEng.instance, type.ordinal() << 3, p.getEntityWorld(), (int) p.posX, (int) p.posY, (int) p.posZ );
}
else
{
p.openGui( AppEng.instance, type.ordinal() << 3 | (side.ordinal()), tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord );
}
}
}
@ -1407,4 +1418,52 @@ public class Platform
return hash;
}
public static boolean securityCheck(GridNode a, GridNode b)
{
if ( a.lastSecurityKey == -1 && b.lastSecurityKey == -1 )
return false;
else if ( a.lastSecurityKey == b.lastSecurityKey )
return false;
boolean a_isSecure = isPowered( a.getGrid() ) && a.lastSecurityKey != -1;
boolean b_isSecure = isPowered( b.getGrid() ) && b.lastSecurityKey != -1;
// can't do that son...
if ( a_isSecure && b_isSecure )
return true;
if ( !a_isSecure && b_isSecure )
return checkPlayerPermissions( b.getGrid(), a.playerID );
if ( a_isSecure && !b_isSecure )
return checkPlayerPermissions( a.getGrid(), b.playerID );
return false;
}
private static boolean isPowered(IGrid grid)
{
if ( grid == null )
return false;
IEnergyGrid eg = (IEnergyGrid) grid.getCache( IEnergyGrid.class );
return eg.isNetworkPowered();
}
private static boolean checkPlayerPermissions(IGrid grid, int playerID)
{
if ( grid == null )
return false;
ISecurityGrid gs = (ISecurityGrid) grid.getCache( ISecurityGrid.class );
if ( gs == null )
return false;
if ( !gs.isAvailable() )
return false;
return !gs.hasPermission( playerID, SecurityPermissions.BUILD );
}
}

View file

@ -1,30 +0,0 @@
package appeng.util.math;
import org.lwjgl.util.vector.Quaternion;
import org.lwjgl.util.vector.Vector3f;
public class Helper
{
public static final Helper instance = new Helper();
public Quaternion getRotation(Vector3f vForward, Vector3f vUp)
{
Vector3f vRight = new Vector3f();
Vector3f.cross( vUp, vForward, vRight );
/*
* vRight.x vRight.y, vRight.z, vUp.x, vUp.y, vUp.z, vForward.x,
* vForward.y, vForward.z
*/
Quaternion qrot = new Quaternion();
qrot.w = (float) Math.sqrt( 1.0f + vRight.x + vUp.y + vForward.z ) / 2.0f;
double dfWScale = qrot.w * 4.0;
qrot.x = (float) ((vForward.y - vUp.z) / dfWScale);
qrot.y = (float) ((vRight.z - vForward.x) / dfWScale);
qrot.z = (float) ((vUp.x - vRight.y) / dfWScale);
return qrot;
}
}