Fixed ship movement exploit with custom scripts

Fixed NPE when breaking blocks
Refactored dimension checks
This commit is contained in:
LemADEC 2017-02-04 00:11:37 +01:00
parent 2b473ae3da
commit cc5bdfff8a
15 changed files with 108 additions and 71 deletions

View file

@ -1,7 +1,6 @@
package cr0s.warpdrive;
import cr0s.warpdrive.config.Dictionary;
import cr0s.warpdrive.config.WarpDriveConfig;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
@ -22,23 +21,19 @@ public class GravityManager {
private static final double SPACE_VOID_GRAVITY_RAW_SNEAK = 0.005D; // 0.001 = no mvt
public static double getGravityForEntity(Entity entity) {
// Is entity in space or hyper-space?
boolean inSpace = entity.worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID;
boolean inHyperspace = entity.worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
if (inSpace || inHyperspace) {
boolean insideGravField = isEntityInGraviField(entity);
if (WarpDrive.starMap.isLowGravity(entity.worldObj)) {
// Is entity in hyper-space?
boolean inHyperspace = WarpDrive.starMap.isInHyperspace(entity.worldObj);
if (insideGravField) {
if (inSpace) {
return SPACE_FIELD_ENTITY_GRAVITY;
} else {
if (isEntityInGraviField(entity)) {
if (inHyperspace) {
return HYPERSPACE_FIELD_ENTITY_GRAVITY;
} else {
return SPACE_FIELD_ENTITY_GRAVITY;
}
} else {
double jitter = (entity.worldObj.rand.nextDouble() - 0.5D) * 2.0D * HYPERSPACE_VOID_ENTITY_JITTER;
if (inSpace)
jitter = 0.0D;
double jitter = inHyperspace ? (entity.worldObj.rand.nextDouble() - 0.5D) * 2.0D * HYPERSPACE_VOID_ENTITY_JITTER : 0.0D;
if (entity instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) entity;
@ -65,8 +60,7 @@ public class GravityManager {
}
public static double getItemGravity(EntityItem entity) {
if ( entity.worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID
|| entity.worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
if (WarpDrive.starMap.isLowGravity(entity.worldObj)) {
if (isEntityInGraviField(entity)) {
return SPACE_FIELD_ITEM_GRAVITY;
} else {
@ -78,8 +72,7 @@ public class GravityManager {
}
public static double getItemGravity2(EntityItem entity) {
if ( entity.worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID
|| entity.worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
if (WarpDrive.starMap.isLowGravity(entity.worldObj)) {
if (isEntityInGraviField(entity)) {
return SPACE_FIELD_ITEM_GRAVITY2;
} else {

View file

@ -2,7 +2,6 @@ package cr0s.warpdrive.block;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MathHelper;
import net.minecraftforge.common.util.ForgeDirection;
import cpw.mods.fml.common.Optional;
import cr0s.warpdrive.WarpDrive;
@ -40,13 +39,13 @@ public class TileEntityAirGenerator extends TileEntityAbstractEnergy {
}
// Air generator works only in space & hyperspace
if (worldObj.provider.dimensionId != WarpDriveConfig.G_SPACE_DIMENSION_ID && worldObj.provider.dimensionId != WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
if (WarpDrive.starMap.hasAtmosphere(worldObj)) {
if (getBlockMetadata() != 0) {
worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 2); // set disabled texture
}
return;
}
cooldownTicks++;
if (cooldownTicks > WarpDriveConfig.AIRGEN_AIR_GENERATION_TICKS) {
if (isEnabled && energy_consume(WarpDriveConfig.AIRGEN_ENERGY_PER_NEWAIRBLOCK, true)) {

View file

@ -430,13 +430,11 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
if (distance <= 0) {
return 1.0D;
}
boolean isInSpace = (worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID);
boolean isInHyperSpace = (worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID);
double attenuation;
if (isInSpace || isInHyperSpace) {
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK;
} else {
if (WarpDrive.starMap.hasAtmosphere(worldObj)) {
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_AIR_BLOCK;
} else {
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK;
}
double transmittance = Math.exp(- attenuation * distance);
if (WarpDriveConfig.LOGGING_WEAPON) {

View file

@ -50,8 +50,6 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
private String beaconFrequency = "";
boolean ready = false; // Ready to operate (valid assembly)
private final int updateInterval_ticks = 20 * WarpDriveConfig.SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS;
private int updateTicks = updateInterval_ticks;
private int bootTicks = 20;
@ -569,13 +567,13 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] isInSpace(Context context, Arguments arguments) {
return new Boolean[] { worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID };
return new Boolean[] { WarpDrive.starMap.isInSpace(worldObj) };
}
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] isInHyperspace(Context context, Arguments arguments) {
return new Boolean[] { worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID };
return new Boolean[] { WarpDrive.starMap.isInHyperspace(worldObj) };
}
@Callback
@ -823,7 +821,7 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
return null;
}
return new Object[]{core.xCoord, core.yCoord, core.zCoord};
return new Object[] { core.xCoord, core.yCoord, core.zCoord };
case "energy":
if (core == null) {
@ -847,7 +845,7 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
case "getOrientation":
if (core != null) {
return new Object[]{core.dx, 0, core.dz};
return new Object[] { core.dx, 0, core.dz };
}
return null;
@ -855,17 +853,17 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced {
return shipName(arguments);
case "isInSpace":
return new Boolean[]{worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID};
return new Boolean[] { WarpDrive.starMap.isInSpace(worldObj) };
case "isInHyperspace":
return new Boolean[]{worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID};
return new Boolean[] { WarpDrive.starMap.isInHyperspace(worldObj) };
case "targetJumpgate":
return targetJumpgate(arguments);
case "isAttached": // isAttached
if (core != null) {
return new Object[]{core.controller != null};
return new Object[] { core.controller != null };
}
break;
case "movement":

View file

@ -32,7 +32,6 @@ import cr0s.warpdrive.block.TileEntityAbstractEnergy;
import cr0s.warpdrive.config.Dictionary;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Jumpgate;
import cr0s.warpdrive.data.StarMapRegistryItem;
import cr0s.warpdrive.data.VectorI;
import cr0s.warpdrive.event.JumpSequencer;
import cr0s.warpdrive.world.SpaceTeleporter;
@ -878,6 +877,22 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
if (currentMode != EnumShipCoreMode.HYPERSPACE) {
VectorI movement = controller.getMovement();
VectorI shipSize = new VectorI(controller.getFront() + 1 + controller.getBack(),
controller.getUp() + 1 + controller.getDown(),
controller.getRight() + 1 + controller.getLeft());
int maxDistance = WarpDriveConfig.SHIP_MAX_JUMP_DISTANCE;
if (WarpDrive.starMap.isInHyperspace(worldObj)) {
maxDistance *= 100;
}
if (Math.abs(movement.x) - shipSize.x > maxDistance) {
movement.x = (int) Math.signum(movement.x) * (shipSize.x + maxDistance);
}
if (Math.abs(movement.y) - shipSize.y > maxDistance) {
movement.y = (int) Math.signum(movement.y) * (shipSize.y + maxDistance);
}
if (Math.abs(movement.z) - shipSize.z > maxDistance) {
movement.z = (int) Math.signum(movement.z) * (shipSize.z + maxDistance);
}
moveX = dx * movement.x - dz * movement.z;
moveY = movement.y;
moveZ = dz * movement.x + dx * movement.z;
@ -903,13 +918,14 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
}
private void teleportPlayersToSpace() {
if (worldObj.provider.dimensionId != WarpDriveConfig.G_SPACE_DIMENSION_ID) {
if (!WarpDrive.starMap.isInSpace(worldObj)) {
AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBox(xCoord - 2, yCoord - 1, zCoord - 2, xCoord + 2, yCoord + 4, zCoord + 2);
List list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
WorldServer spaceWorld = MinecraftServer.getServer().worldServerForDimension(WarpDriveConfig.G_SPACE_DIMENSION_ID);
final int dimensionIdSpace = WarpDriveConfig.G_SPACE_DIMENSION_ID;
WorldServer spaceWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
if (spaceWorld == null) {
String msg = "Unable to load Space dimension " + WarpDriveConfig.G_SPACE_DIMENSION_ID + ", aborting teleportation.";
String msg = "Unable to load Space dimension " + dimensionIdSpace + ", aborting teleportation.";
messageToAllPlayersOnShip(msg);
return;
}
@ -936,8 +952,8 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
if (entity instanceof EntityPlayerMP) {
((EntityPlayerMP) entity).mcServer.getConfigurationManager().transferPlayerToDimension(((EntityPlayerMP) entity),
WarpDriveConfig.G_SPACE_DIMENSION_ID,
new SpaceTeleporter(DimensionManager.getWorld(WarpDriveConfig.G_SPACE_DIMENSION_ID), 0, x, 256, z));
dimensionIdSpace,
new SpaceTeleporter(DimensionManager.getWorld(dimensionIdSpace), 0, x, 256, z));
if (spaceWorld.isAirBlock(x, newY, z)) {
spaceWorld.setBlock(x, newY, z, Blocks.stone, 0, 2);

View file

@ -133,10 +133,10 @@ public class BlockAir extends Block {
}
int concentration = world.getBlockMetadata(x, y, z);
boolean isInSpaceWorld = world.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID || world.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
boolean hasAtmosphere = WarpDrive.starMap.hasAtmosphere(world);
// Remove air block to vacuum block
if (concentration <= 0 || !isInSpaceWorld) {
if (concentration <= 0 || hasAtmosphere) {
world.setBlock(x, y, z, Blocks.air, 0, 3); // replace our air block to vacuum block
} else {
// Try to spread the air
@ -392,11 +392,11 @@ public class BlockAir extends Block {
}
@Override
public void onBlockAdded(World par1World, int par2, int par3, int par4) {
if (par1World.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID || par1World.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
par1World.scheduleBlockUpdate(par2, par3, par4, this, tickRate(par1World));
public void onBlockAdded(World world, int x, int y, int z) {
if (!WarpDrive.starMap.hasAtmosphere(world)) {
world.scheduleBlockUpdate(x, y, z, this, tickRate(world));
} else {
par1World.setBlockToAir(par2, par3, par4);
world.setBlockToAir(x, y, z);
}
}
}

View file

@ -110,10 +110,10 @@ public class BlockGas extends Block {
}
@Override
public void onBlockAdded(World par1World, int par2, int par3, int par4) {
// Gas blocks allow only in space
if (par1World.provider.dimensionId != WarpDriveConfig.G_SPACE_DIMENSION_ID) {
par1World.setBlockToAir(par2, par3, par4);
public void onBlockAdded(World world, int x, int y, int z) {
// Gas blocks are only allowed in space
if (WarpDrive.starMap.hasAtmosphere(world)) {
world.setBlockToAir(x, y, z);
}
}
}

View file

@ -8,7 +8,6 @@ import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.config.structures.AbstractStructure;
import cr0s.warpdrive.config.structures.StructureManager;
import cr0s.warpdrive.world.JumpgateGenerator;
@ -64,7 +63,7 @@ public class CommandGenerate extends CommandBase {
String structure = params[0];
// Reject command, if player is not in space
if (world.provider.dimensionId != WarpDriveConfig.G_SPACE_DIMENSION_ID && (!"ship".equals(structure))) {
if (!WarpDrive.starMap.isInSpace(world) && (!"ship".equals(structure))) {
WarpDrive.addChatMessage(commandSender, "* generate: this structure is only allowed in space!");
return;
}

View file

@ -82,7 +82,7 @@ public class CommandSpace extends CommandBase {
for (EntityPlayerMP entityPlayerMP : entityPlayerMPs) {
// toggle between overworld and space if no dimension was provided
if (targetDimensionId == Integer.MAX_VALUE) {
if (entityPlayerMP.worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID) {
if (WarpDrive.starMap.isInSpace(entityPlayerMP.worldObj)) {
targetDimensionId = 0;
} else {
targetDimensionId = WarpDriveConfig.G_SPACE_DIMENSION_ID;

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkCoordIntPair;
@ -52,10 +53,10 @@ public class GlobalPosition {
}
public VectorI getSpaceCoordinates() {
if (dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID) {
if (WarpDrive.starMap.isInSpace(dimensionId)) {
return new VectorI(x, y + 256, z);
}
if (dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
if (WarpDrive.starMap.isInHyperspace(dimensionId)) {
return new VectorI(x, y + 512, z);
}
for (Planet planet : WarpDriveConfig.PLANETS) {

View file

@ -90,6 +90,9 @@ public class StarMapRegistry {
public void onBlockUpdated(World world, final int x, final int y, final int z, final Block block, final int metadata) {
CopyOnWriteArraySet<StarMapRegistryItem> setStarMapRegistryItems = registry.get(world.provider.dimensionId);
if (setStarMapRegistryItems == null) {
return;
}
for (StarMapRegistryItem registryItem : setStarMapRegistryItems) {
if (registryItem.contains(x, y, z)) {
TileEntity tileEntity = world.getTileEntity(registryItem.x, registryItem.y, registryItem.z);
@ -97,7 +100,7 @@ public class StarMapRegistry {
((IStarMapRegistryTileEntity) tileEntity).onBlockUpdatedInArea(new VectorI(x, y, z), block, metadata);
}
}
}
}
}
public ArrayList<StarMapRegistryItem> radarScan(TileEntity tileEntity, final int radius) {
@ -124,6 +127,34 @@ public class StarMapRegistry {
return res;
}
public boolean isInSpace(final int dimensionId) {
return dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID;
}
public boolean isInHyperspace(final int dimensionId) {
return dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
}
public boolean isInSpace(final World world) {
return isInSpace(world.provider.dimensionId);
}
public boolean isInHyperspace(final World world) {
return isInHyperspace(world.provider.dimensionId);
}
public boolean hasAtmosphere(final World world) {
return !isInSpace(world) && !isInHyperspace(world);
}
public boolean isPlanet(final World world) {
return !isInSpace(world) && !isInHyperspace(world);
}
public boolean isLowGravity(final World world) {
return isInSpace(world) || isInHyperspace(world);
}
public void printRegistry(final String trigger) {
WarpDrive.logger.info("Starmap registry (" + registry.size() + " entries after " + trigger + "):");

View file

@ -482,8 +482,8 @@ public class JumpSequencer extends AbstractSequencer {
StringBuilder reason = new StringBuilder();
boolean isInSpace = (sourceWorld.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID);
boolean isInHyperSpace = (sourceWorld.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID);
boolean isInSpace = WarpDrive.starMap.isInSpace(sourceWorld);
boolean isInHyperSpace = WarpDrive.starMap.isInHyperspace(sourceWorld);
boolean toSpace = (moveY > 0) && (ship.maxY + moveY > 255) && (!isInSpace) && (!isInHyperSpace);
boolean fromSpace = (moveY < 0) && (ship.minY + moveY < 0) && isInSpace;
@ -491,19 +491,21 @@ public class JumpSequencer extends AbstractSequencer {
if (isHyperspaceJump) {
if (isInHyperSpace) {
targetWorld = MinecraftServer.getServer().worldServerForDimension(WarpDriveConfig.G_SPACE_DIMENSION_ID);
final int dimensionIdSpace = WarpDriveConfig.G_SPACE_DIMENSION_ID;
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
if (targetWorld == null) {
LocalProfiler.stop();
String msg = "Unable to load Space dimension " + WarpDriveConfig.G_SPACE_DIMENSION_ID + ", aborting jump.";
String msg = "Unable to load Space dimension " + dimensionIdSpace + ", aborting jump.";
ship.messageToAllPlayersOnShip(msg);
disable(msg);
return;
}
} else if (isInSpace) {
targetWorld = MinecraftServer.getServer().worldServerForDimension(WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID);
final int dimensionIdHyperspace = WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdHyperspace);
if (targetWorld == null) {
LocalProfiler.stop();
String msg = "Unable to load Hyperspace dimension " + WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID + ", aborting jump.";
String msg = "Unable to load Hyperspace dimension " + dimensionIdHyperspace + ", aborting jump.";
ship.messageToAllPlayersOnShip(msg);
disable(msg);
return;
@ -530,10 +532,11 @@ public class JumpSequencer extends AbstractSequencer {
planetValid = true;
moveX = planet.spaceCenterX - planet.dimensionCenterX;
moveZ = planet.spaceCenterZ - planet.dimensionCenterZ;
targetWorld = MinecraftServer.getServer().worldServerForDimension(WarpDriveConfig.G_SPACE_DIMENSION_ID);
final int dimensionIdSpace = WarpDriveConfig.G_SPACE_DIMENSION_ID;
targetWorld = MinecraftServer.getServer().worldServerForDimension(dimensionIdSpace);
if (targetWorld == null) {
LocalProfiler.stop();
String msg = "Unable to load Space dimension " + WarpDriveConfig.G_SPACE_DIMENSION_ID + ", aborting jump.";
String msg = "Unable to load Space dimension " + dimensionIdSpace + ", aborting jump.";
ship.messageToAllPlayersOnShip(msg);
disable(msg);
return;
@ -612,9 +615,8 @@ public class JumpSequencer extends AbstractSequencer {
}
// Check mass constrains
if ( ((!isInSpace) && (!isInHyperSpace))
|| ( (targetWorld.provider.dimensionId != WarpDriveConfig.G_SPACE_DIMENSION_ID)
&& (targetWorld.provider.dimensionId != WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID)) ) {
if ( WarpDrive.starMap.isPlanet(sourceWorld)
|| WarpDrive.starMap.isPlanet(targetWorld) ) {
if (!ship.isUnlimited() && ship.actualMass > WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE) {
String msg = "Ship is too big for a planet (max is " + WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE + " blocks)";
ship.messageToAllPlayersOnShip(msg);

View file

@ -85,8 +85,7 @@ public class LivingHandler {
}
// If entity is in vacuum, check and start consuming air cells
if ( entity.worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID
|| entity.worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID) {
if (!WarpDrive.starMap.hasAtmosphere(entity.worldObj)) {
// find an air block
VectorI vAirBlock = null;
Block block;

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.render;
import java.util.Random;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Planet;
import net.minecraft.client.Minecraft;
@ -82,7 +83,7 @@ public class RenderSpaceSky extends IRenderHandler {
@Override
public void render(float partialTicks, WorldClient world, Minecraft mc) {
boolean isSpace = world.provider == null || world.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID;
boolean isSpace = world.provider == null || WarpDrive.starMap.isInSpace(world);
final Tessellator tessellator = Tessellator.instance;

View file

@ -22,7 +22,7 @@ public class SpaceWorldGenerator implements IWorldGenerator {
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
try {
if (world.provider.dimensionId != WarpDriveConfig.G_SPACE_DIMENSION_ID) {
if (!WarpDrive.starMap.isInSpace(world)) {
return;
}
int x = (chunkX * 16) + (5 - random.nextInt(10));