Compare commits

...

10 commits

Author SHA1 Message Date
Xamora 994ac12081
add download link in ReadMe 2024-09-15 15:49:59 +02:00
Xamora64 424e7c8c19 remove useless import, change folder name because strange crash building mod 2024-09-15 15:43:17 +02:00
Xamora64 ebf7842cab update mcmod.info 2024-09-15 14:47:07 +02:00
Xamora 3056c8f011
Update README.md 2024-09-15 14:42:54 +02:00
Xamora64 ce38da9f56 Readme update 2024-09-15 14:38:50 +02:00
Xamora64 1df8778984 Remove world instance and use directly data from the loaded chunk 2024-09-15 14:37:31 +02:00
shsa e3ac0f5e35 suppress warning 2015-02-03 23:05:49 +07:00
shsa 495c15d287 support BuildCraft servers 2015-02-03 20:42:37 +07:00
shsa 7238761ce1 added updateRadius 2015-01-31 17:03:29 +07:00
shsa ceb4c4aecf some optimizations
select blocks for update
2015-01-31 13:58:49 +07:00
16 changed files with 758 additions and 656 deletions

View file

@ -1,4 +1,7 @@
# orebfuscator
orebfuscator for mcpc+ 1.7.10
orebfuscator for mcpc+ 1.7.10<br>
Fix issue and remove random crash in chunk load
original idea https://github.com/Shevchik/Orebfuscator
download: https://github.com/Xamora64/orebfuscator/releases<br>
original fork: https://github.com/shsa/orebfuscator<br>
original idea: https://github.com/Shevchik/orebfuscator

View file

@ -1,209 +0,0 @@
package Orebfuscator;
import Orebfuscator.Options.WorldOptions;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
public class ChunkObfuscator
{
// èíôîðìàöèÿ î íàëè÷èè ñåêöèè. Ñåêöèè - ýòî áëîêè ðàçìåðîì 16õ16õ16, ñåêöèè ðàñïîëàãàþòñÿ äðóã íàä äðóãîì
// Chunk ñîñòîèò èç 16 ñåêöèé, ðàçìåð ÷àíêà 16x16x256
//public boolean[] listLSB = new boolean[16];
//public boolean[] listMSB = new boolean[16];
// offsetsLSB[] - ñîäåðæèò ñïèñîê ñåêöèé, ñ êîòîðûõ íà÷èíàþòñÿ áëîêè ðàçìåðîì 16x16x16 ñîäåðæàùèå ïåðâûå 8 áèò BlockID
// ðàçìåð ñåêöèè 16*16*16 = 4096 áàéò
public int[] offsetsLSB = new int[16];
// íà÷àëî NibbleArrays ñîäåðæàùèõ ExtendedBlockStorage.blockMetadataArray
// ðàçìåð ìàññèâà (16*16*16)/2 = 2048 (äåëèì ïîïàëàì, ò.ê. â îäíîì áàéòå ñîäåðæèòñÿ äâà çíà÷åíèÿ ïî 4 áèòà)
public int[] offsetsMetadata = new int[16];
// íà÷àëî NibbleArray ñîäåðæàùåãî ExtendedBlockStorage.blocklightArray
public int[] offsetsBlocklight = new int[16];
// NibbleArray ExtendedBlockStorage.blockMSBArray
public int[] offsetsMSB = new int[16];
public int startX;
public int startY;
// Ìàêñèìàëüíûé èíäåêñ+1 ñåêöèè
public int len;
public byte[] data;
public void obfuscate(World world, int chunkX, int chunkZ, int sectionLSB, int sectionMSB, byte[] data)
{
this.startX = chunkX << 4;
this.startY = chunkZ << 4;
this.data = data;
int countLSB = 0;
len = 0;
int l;
int pos = 0;
int i;
for (i = 0; i < 16; ++i)
{
l = sectionLSB >> i & 1;
if (l == 1)
{
offsetsLSB[i] = pos;
pos += 4096;
countLSB++;
len = i + 1;
}
else
{
offsetsLSB[i] = -1;
}
}
for (i = 0; i < len; i++)
{
if (offsetsLSB[i] > -1)
{
offsetsMetadata[i] = pos;
pos += 2048;
}
}
for (i = 0; i < len; i++)
{
if (offsetsLSB[i] > -1)
{
offsetsBlocklight[i] = pos;
pos += 2048;
}
}
if (!world.provider.hasNoSky)
{
// åñëè åñòü íåáî, òî â áóôåðå áóäåò ìàññèâ ExtendedBlockStorage.skylightArray
pos += countLSB * 2048;
}
for (i = 0; i < len; i++)
{
l = sectionMSB >> i & 1;
if (l == 1)
{
offsetsMSB[i] = pos;
pos += 2048;
}
else
{
offsetsMSB[i] = -1;
}
}
Options.worldOptions = Options.getWorldOptions(world.provider);
for (i = 0; i < len; i++)
{
if (offsetsLSB[i] > -1)
{
l = i << 4;
for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
for (int z = 0; z < 16; z++)
{
if (neetObfuscate(world, x, l | y, z))
{
setBlockID(x, l | y, z, Options.worldOptions.getRandomBlock());
}
}
}
}
}
}
}
/**
* Returns the block corresponding to the given coordinates inside a chunk.
*/
public int getBlockID(World world, int x, int y, int z)
{
int section = y >> 4;
if (this.offsetsLSB[section] > -1)
{
y = y & 15;
int id = this.data[this.offsetsLSB[section] + (y << 8 | z << 4 | x)] & 255;
if (this.offsetsMSB[section] > -1)
{
int l = y << 4 | z << 4 | x;
int i1 = l >> 1;
int j1 = l & 1;
id |= j1 == 0 ? this.data[this.offsetsMSB[section] + i1] & 15 : this.data[this.offsetsMSB[section] + i1] >> 4 & 15;
}
return id;
}
return 0;
}
public void setBlockID(int x, int y, int z, int blockID)
{
int section = y >> 4;
if (this.offsetsLSB[section] > -1)
{
y = y & 15;
this.data[this.offsetsLSB[section] + (y << 8 | z << 4 | x)] = (byte) (blockID & 255);
if (this.offsetsMSB[section] > -1)
{
int l = y << 4 | z << 4 | x;
int i1 = l >> 1;
int j1 = l & 1;
int pos = this.offsetsMSB[section] + i1;
if (j1 == 0)
{
this.data[pos] = (byte)(this.data[pos] & 240 | blockID & 15);
}
else
{
this.data[pos] = (byte)(this.data[pos] & 15 | (blockID & 15) << 4);
}
}
}
}
public boolean isTransparent(World world, int x, int y, int z)
{
if (y < 0 || y > 255)
return true;
if (x < 0 || x > 15 || z < 0 || z > 15)
{
return Options.isBlockTransparent(BlockHelper.getBlockID(world, this.startX | x, y, this.startY | z));
}
return Options.isBlockTransparent(getBlockID(world, x, y, z));
}
public boolean neetObfuscate(World world, int x, int y, int z)
{
if (y > Options.worldOptions.maxObfuscateHeight)
return false;
if (!Options.isObfuscated(getBlockID(world, x, y, z)))
{
return false;
}
return !(
isTransparent(world, x - 1, y, z) ||
isTransparent(world, x + 1, y, z) ||
isTransparent(world, x, y - 1, z) ||
isTransparent(world, x, y + 1, z) ||
isTransparent(world, x, y, z - 1) ||
isTransparent(world, x, y, z + 1)
);
}
}

View file

@ -1,52 +0,0 @@
package Orebfuscator;
import java.lang.reflect.Field;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
public class MapChunkBulkObfuscator
{
public static Field fieldChunkX;
public static Field fieldChunkZ;
// 1110011 - íàáîð áëîêîâ (ExtendedBlockStorage.blockLSBArray) ïî âûñîòå (1 - åñòü áëîê, 0 - íåò áëîêà)
public static Field fieldStatusLSB = null;
// 0001110 - íàáîð áëîêîâ (ExtendedBlockStorage.blockMSBArray) ïî âûñîòå (1 - åñòü áëîê, 0 - íåò áëîêà)
public static Field fieldStatusMSB;
// -- ìàññèâ äàííûõ
public static Field fieldData;
public static ChunkObfuscator info;
public static void obfuscate(World world, S26PacketMapChunkBulk packet)
{
if (fieldStatusLSB == null)
{
fieldChunkX = Fields.getField(packet, "field_149266_a");
fieldChunkZ = Fields.getField(packet, "field_149264_b");
fieldStatusLSB = Fields.getField(packet, "field_149265_c");
fieldStatusMSB = Fields.getField(packet, "field_149262_d");
fieldData = Fields.getField(packet, "field_149260_f");
info = new ChunkObfuscator();
}
int[] chunkX = (int[]) Fields.getValue(packet, fieldChunkX);
int[] chunkZ = (int[]) Fields.getValue(packet, fieldChunkZ);
int[] statusLSB = (int[]) Fields.getValue(packet, fieldStatusLSB);
int[] statusMSB = (int[]) Fields.getValue(packet, fieldStatusMSB);
byte[][] dataArray = (byte[][]) Fields.getValue(packet, fieldData);
for (int i = 0; i < statusLSB.length; i++)
{
info.obfuscate(world, chunkX[i], chunkZ[i], statusLSB[i], statusMSB[i], dataArray[i]);
}
}
}

View file

@ -1,239 +0,0 @@
package Orebfuscator;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.WorldProviderEnd;
import net.minecraft.world.WorldProviderHell;
import net.minecraft.world.WorldProviderSurface;
import net.minecraftforge.common.config.Configuration;
public class Options
{
public static class WorldOptions
{
public static int maxObfuscateHeight = 128;
public int[] randomBlocks;
private int randomBlock = 0;
public int getRandomBlock()
{
randomBlock++;
if (randomBlock >= randomBlocks.length)
randomBlock = 0;
return randomBlocks[randomBlock];
}
}
private static HashMap<String, WorldOptions> worlds = new HashMap<String, WorldOptions>();
public static WorldOptions getWorldOptions(WorldProvider provider)
{
String name = provider.getClass().getSimpleName();
WorldOptions options = worlds.get(name);
if (options == null)
{
Configuration config = new Configuration(configFile, false);
options = new WorldOptions();
options.maxObfuscateHeight = clamp(config.get(name, "maxObfuscateHeight", options.maxObfuscateHeight).getInt(), 0, 256);
if (provider instanceof WorldProviderSurface)
{
options.randomBlocks = config.get(name, "randomBlocks", new int[] {
getID(Blocks.gold_ore),
getID(Blocks.iron_ore),
getID(Blocks.coal_ore),
getID(Blocks.lapis_ore),
getID(Blocks.diamond_ore),
getID(Blocks.redstone_ore),
getID(Blocks.emerald_ore),
getID(Blocks.mossy_cobblestone),
}).getIntList();
if (options.randomBlocks.length == 0)
options.randomBlocks = new int[] {getID(Blocks.stone)};
}
if (provider instanceof WorldProviderHell)
{
options.randomBlocks = config.get(name, "randomBlocks", new int[] {
getID(Blocks.glowstone),
getID(Blocks.netherrack),
getID(Blocks.nether_brick),
getID(Blocks.nether_brick_fence),
getID(Blocks.nether_brick_stairs),
getID(Blocks.nether_wart),
getID(Blocks.quartz_ore),
}).getIntList();
if (options.randomBlocks.length == 0)
options.randomBlocks = new int[] {getID(Blocks.nether_brick)};
}
else
if (provider instanceof WorldProviderEnd)
{
options.randomBlocks = config.get(name, "randomBlocks", new int[] {
getID(Blocks.end_stone),
}).getIntList();
if (options.randomBlocks.length == 0)
options.randomBlocks = new int[] {getID(Blocks.end_stone)};
}
else
{
options.randomBlocks = config.get(name, "randomBlocks", new int[] {
getID(Blocks.stone),
getID(Blocks.gold_ore),
getID(Blocks.iron_ore),
getID(Blocks.coal_ore),
getID(Blocks.lapis_ore),
getID(Blocks.diamond_ore),
getID(Blocks.redstone_ore),
getID(Blocks.emerald_ore),
getID(Blocks.netherrack),
getID(Blocks.nether_brick),
getID(Blocks.quartz_ore),
getID(Blocks.end_portal_frame),
getID(Blocks.end_portal),
getID(Blocks.end_stone),
getID(Blocks.mob_spawner),
}).getIntList();
if (options.randomBlocks.length == 0)
options.randomBlocks = new int[] {getID(Blocks.stone)};
}
if (options.randomBlocks.length == 0)
options.randomBlocks = new int[] {getID(Blocks.stone)};
config.save();
}
return options;
}
public static WorldOptions worldOptions;
private static boolean[] obfuscateBlocks = new boolean[4096];
public static int[] randomBlocks;
public static boolean[] transparentBlocks = new boolean[4096];
public static File configFile;
public static void load(File modDir)
{
configFile = new File(modDir, Orebfuscator.MODID + ".cfg");
Configuration config = new Configuration(configFile, false);
int[] list = config.get("Options", "obfuscateBlocks", new int[] {
getID(Blocks.stone),
getID(Blocks.dirt),
getID(Blocks.gold_ore),
getID(Blocks.iron_ore),
getID(Blocks.coal_ore),
getID(Blocks.lapis_ore),
getID(Blocks.diamond_ore),
getID(Blocks.redstone_ore),
getID(Blocks.emerald_ore),
getID(Blocks.netherrack),
getID(Blocks.nether_brick),
getID(Blocks.quartz_ore),
getID(Blocks.end_stone),
}).getIntList();
if (list.length == 0)
{
for (int i = 0; i < obfuscateBlocks.length; i++)
{
obfuscateBlocks[i] = true;
}
}
else
{
updateList(obfuscateBlocks, list);
}
list = config.get("Options", "transparentBlocks", new int[] {}).getIntList();
updateList(transparentBlocks, list);
config.save();
}
private static void updateList(boolean[] blocks, int[] list)
{
for (int i = 0; i < blocks.length; i++)
{
blocks[i] = false;
}
for (int i = 0; i < list.length; i++)
{
if (list[i] >= 0 || list[i] < blocks.length)
blocks[list[i]] = true;
}
}
private static int getID(Block block)
{
return Block.getIdFromBlock(block);
}
private static int clamp(int value, int min, int max) {
if (value < min) {
value = min;
}
if (value > max) {
value = max;
}
return value;
}
public static boolean isObfuscated(int id) {
return obfuscateBlocks[id];
}
public static boolean isObfuscated(Block block) {
return obfuscateBlocks[Block.getIdFromBlock(block)];
}
private static boolean[] _transparentBlocks = new boolean[4096];
private static boolean TransparentCached = false;
public static boolean isBlockTransparent(int id)
{
if (id < 0)
return true;
if (!TransparentCached)
{
// Generate TransparentBlocks by reading them from Minecraft
for (int i = 0; i < _transparentBlocks.length; i++) {
if (transparentBlocks[i])
{
_transparentBlocks[i] = true;
}
else
{
Block block = Block.getBlockById(i);
if (block == null)
{
_transparentBlocks[i] = true;
}
else
{
_transparentBlocks[i] = !block.isNormalCube();
}
}
}
TransparentCached = true;
}
return _transparentBlocks[id];
}
public static boolean isTransparent(Block block)
{
return isBlockTransparent(Block.getIdFromBlock(block));
}
}

View file

@ -1,113 +0,0 @@
package Orebfuscator;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import net.minecraft.block.Block;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.util.ReportedException;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
public class PlayerHandler
{
public Map<EntityPlayer, BlockBreakInfo> list = new HashMap<EntityPlayer, BlockBreakInfo>();
public static class BlockBreakInfo
{
public boolean[][][] isTransparent = new boolean[5][5][5];
public int x;
public int y;
public int z;
public void updateBlocksTransparent(World world, int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
for (short i = -1; i < 2; i++)
{
for (short j = -1; j < 2; j++)
{
for (short k = -1; k < 2; k++)
{
this.isTransparent[2 + i][2 + j][2 + k] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x + i, y + j, z + k));
}
}
}
this.isTransparent[0][2][2] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x - 2, y, z));
this.isTransparent[4][2][2] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x + 2, y, z));
this.isTransparent[2][0][2] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x, y - 2, z));
this.isTransparent[2][4][2] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x, y + 2, z));
this.isTransparent[2][2][0] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x, y, z - 2));
this.isTransparent[2][2][4] = Options.isBlockTransparent(BlockHelper.getBlockID(world, x, y, z + 2));
this.isTransparent[2][2][2] = false;
}
public boolean isTransparent(final World world, final int x, final int y, final int z)
{
return this.isTransparent[2 + x - this.x][2 + y - this.y][2 + z - this.z];
}
public void updateBlock(World world, int x, int y, int z)
{
if (Options.isObfuscated(BlockHelper.getBlockID(world, x, y, z)))
{
if (isTransparent(world, x - 1, y, z) || isTransparent(world, x + 1, y, z) ||
isTransparent(world, x, y - 1, z) || isTransparent(world, x, y + 1, z) ||
isTransparent(world, x, y, z - 1) || isTransparent(world, x, y, z + 1))
return;
world.markBlockForUpdate(x, y, z);
}
}
}
public void update(EntityPlayer player, int x, int y, int z)
{
BlockBreakInfo info = list.get(player);
if (info == null)
{
info = new BlockBreakInfo();
list.put(player, info);
}
if (info.x != x || info.y != y || info.z != z)
{
info.updateBlocksTransparent(player.worldObj, x, y, z);
info.updateBlock(player.worldObj, x-1, y, z);
info.updateBlock(player.worldObj, x+1, y, z);
info.updateBlock(player.worldObj, x, y-1, z);
info.updateBlock(player.worldObj, x, y+1, z);
info.updateBlock(player.worldObj, x, y, z-1);
info.updateBlock(player.worldObj, x, y, z+1);
}
}
@SubscribeEvent
public void onBreakSpeed(PlayerEvent.BreakSpeed event)
{
update(event.entityPlayer, event.x, event.y, event.z);
}
@SubscribeEvent
public void onBlockBreak(BlockEvent.BreakEvent event)
{
update(event.getPlayer(), event.x, event.y, event.z);
}
}

View file

@ -1,6 +1,5 @@
package Orebfuscator;
package orebfuscator;
import net.minecraft.block.Block;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;

View file

@ -0,0 +1,210 @@
package orebfuscator;
import net.minecraft.block.Block;
import net.minecraft.world.World;
public class ChunkObfuscator
{
// ?????????? ? ??????? ??????. ?????? - ??? ????? ???????? 16?16?16, ?????? ????????????? ???? ??? ??????
// Chunk ??????? ?? 16 ??????, ?????? ????? 16x16x256
//public boolean[] listLSB = new boolean[16];
//public boolean[] listMSB = new boolean[16];
// offsetsLSB[] - ???????? ?????? ??????, ? ??????? ?????????? ????? ???????? 16x16x16 ?????????? ?????? 8 ??? BlockID
// ?????? ?????? 16*16*16 = 4096 ????
public int[] offsetsLSB = new int[16];
// ?????? NibbleArrays ?????????? ExtendedBlockStorage.blockMetadataArray
// ?????? ??????? (16*16*16)/2 = 2048 (????? ???????, ?.?. ? ????? ????? ?????????? ??? ???????? ?? 4 ????)
public int[] offsetsMetadata = new int[16];
// ?????? NibbleArray ??????????? ExtendedBlockStorage.blocklightArray
public int[] offsetsBlocklight = new int[16];
// NibbleArray ExtendedBlockStorage.blockMSBArray
public int[] offsetsMSB = new int[16];
public int startX;
public int startZ;
// ???????????? ??????+1 ??????
public int len;
public byte[] data;
public int obfuscate(World world, int chunkX, int chunkZ, boolean hasSky, int sectionLSB, int sectionMSB, byte[] data, int pos)
{
this.startX = chunkX << 4;
this.startZ = chunkZ << 4;
this.data = data;
int countLSB = 0;
len = 0;
int l;
int i;
for (i = 0; i < 16; ++i)
{
l = sectionLSB >> i & 1;
if (l == 1)
{
offsetsLSB[i] = pos;
pos += 4096;
countLSB++;
len = i + 1;
}
else
{
offsetsLSB[i] = -1;
}
}
for (i = 0; i < len; i++)
{
if (offsetsLSB[i] > -1)
{
offsetsMetadata[i] = pos;
pos += 2048;
}
}
for (i = 0; i < len; i++)
{
if (offsetsLSB[i] > -1)
{
offsetsBlocklight[i] = pos;
pos += 2048;
}
}
//if (!world.provider.hasNoSky)
if (hasSky)
{
// ???? ???? ????, ?? ? ?????? ????? ?????? ExtendedBlockStorage.skylightArray
pos += countLSB * 2048;
}
for (i = 0; i < len; i++)
{
l = sectionMSB >> i & 1;
if (l == 1)
{
offsetsMSB[i] = pos;
pos += 2048;
}
else
{
offsetsMSB[i] = -1;
}
}
// biome info
pos += 256;
for (i = 0; i < len; i++)
{
if (offsetsLSB[i] > -1)
{
l = i << 4;
for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
for (int z = 0; z < 16; z++)
{
if (neetObfuscate(x, l | y, z))
{
setBlockID(x, l | y, z, Options.worldOptions.getRandomID());
}
}
}
}
}
}
return pos;
}
/**
* Returns the block corresponding to the given coordinates inside a chunk.
*/
public int getBlockID(int x, int y, int z) {
int sectionIndex = y >> 4; // Index de la section
if (sectionIndex >= offsetsLSB.length || offsetsLSB[sectionIndex] == -1) {
return 0;
}
int yLocal = y & 15;
int xLocal = x & 15;
int zLocal = z & 15;
int blockIndex = (yLocal << 8) | (zLocal << 4) | xLocal;
int lsbIndex = offsetsLSB[sectionIndex] + blockIndex;
int lsb = data[lsbIndex] & 0xFF;
int msb = 0;
if (offsetsMSB[sectionIndex] > -1) {
int msbByteIndex = offsetsMSB[sectionIndex] + (blockIndex >> 1);
int msbByte = data[msbByteIndex] & 0xFF;
if ((blockIndex & 1) == 0) {
msb = msbByte & 0x0F;
} else {
msb = (msbByte >> 4) & 0x0F;
}
}
return (msb << 8) | lsb;
}
public void setBlockID(int x, int y, int z, int blockID)
{
int section = y >> 4;
if (this.offsetsLSB[section] > -1)
{
y = y & 15;
this.data[this.offsetsLSB[section] + (y << 8 | z << 4 | x)] = (byte) (blockID & 255);
if (this.offsetsMSB[section] > -1)
{
int l = y << 4 | z << 4 | x;
int i1 = l >> 1;
int j1 = l & 1;
int pos = this.offsetsMSB[section] + i1;
if (j1 == 0)
{
this.data[pos] = (byte)(this.data[pos] & 240 | blockID & 15);
}
else
{
this.data[pos] = (byte)(this.data[pos] & 15 | (blockID & 15) << 4);
}
}
}
}
public boolean isTransparent(int x, int y, int z) {
if (x < 0 || x > 15 || y < 0 || y > 255 || z < 0 || z > 15) {
return true;
}
int blockID = getBlockID(x, y, z);
return Options.isTransparent(Block.getBlockById(blockID));
}
public boolean neetObfuscate(int x, int y, int z) {
if (y > Options.worldOptions.maxObfuscateHeight)
return false;
int blockID = getBlockID(x, y, z);
if (!Options.isObfuscated(blockID)) {
return false;
}
return !(
isTransparent(x - 1, y, z) ||
isTransparent(x + 1, y, z) ||
isTransparent(x, y - 1, z) ||
isTransparent(x, y + 1, z) ||
isTransparent(x, y, z - 1) ||
isTransparent(x, y, z + 1)
);
}
}

View file

@ -1,4 +1,4 @@
package Orebfuscator;
package orebfuscator;
import java.lang.reflect.Field;
@ -72,6 +72,19 @@ public class Fields
}
}
public static void setValue(Object instance, Field field, Object value)
{
try
{
field.setAccessible(true);
field.set(instance, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static class NetworkManager
{
public static String getOutboundPacketsQueueName()

View file

@ -1,14 +1,8 @@
package Orebfuscator;
import java.util.Locale;
package orebfuscator;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import cpw.mods.fml.common.TracingPrintStream;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
public class Log
{

View file

@ -0,0 +1,76 @@
package orebfuscator;
import java.lang.reflect.Field;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import net.minecraft.world.World;
public class MapChunkBulkObfuscator
{
public static Field fieldChunkX;
public static Field fieldChunkZ;
public static Field fieldHasSky;
// 1110011 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ExtendedBlockStorage.blockLSBArray) <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (1 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0 - <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
public static Field fieldStatusLSB = null;
// 0001110 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ExtendedBlockStorage.blockMSBArray) <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (1 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0 - <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
public static Field fieldStatusMSB;
// -- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public static Field fieldData;
public static Field field_149268_i;
public static ChunkObfuscator info;
public static S26PacketMapChunkBulk obfuscate(World world, S26PacketMapChunkBulk packet)
{
if (fieldStatusLSB == null)
{
fieldChunkX = Fields.getField(packet, "field_149266_a");
fieldChunkZ = Fields.getField(packet, "field_149264_b");
fieldHasSky = Fields.getField(packet, "field_149267_h");
fieldStatusLSB = Fields.getField(packet, "field_149265_c");
fieldStatusMSB = Fields.getField(packet, "field_149262_d");
fieldData = Fields.getField(packet, "field_149260_f");
field_149268_i = Fields.getField(packet, "field_149268_i");
byte[] data = (byte[]) Fields.getValue(packet, field_149268_i);
Options.isBuildCraft = data.length > 0; // Forge keep this array empty
info = new ChunkObfuscator();
}
int[] chunkX = (int[]) Fields.getValue(packet, fieldChunkX);
int[] chunkZ = (int[]) Fields.getValue(packet, fieldChunkZ);
boolean hasSky = (Boolean) Fields.getValue(packet, fieldHasSky);
int[] statusLSB = (int[]) Fields.getValue(packet, fieldStatusLSB);
int[] statusMSB = (int[]) Fields.getValue(packet, fieldStatusMSB);
Options.worldOptions = Options.getWorldOptions(world);
if (Options.isBuildCraft)
{
byte[] data = (byte[]) Fields.getValue(packet, field_149268_i);
int pos = 0;
for (int i = 0; i < statusLSB.length; i++)
{
pos = info.obfuscate(world, chunkX[i], chunkZ[i], hasSky, statusLSB[i], statusMSB[i], data, pos);
}
}
else
{
byte[][] dataArray = (byte[][]) Fields.getValue(packet, fieldData);
for (int i = 0; i < statusLSB.length; i++)
{
info.obfuscate(world, chunkX[i], chunkZ[i], hasSky, statusLSB[i], statusMSB[i], dataArray[i], 0);
}
}
return packet;
}
}

View file

@ -0,0 +1,352 @@
package orebfuscator;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderEnd;
import net.minecraft.world.WorldProviderHell;
import net.minecraft.world.WorldProviderSurface;
import net.minecraftforge.common.config.Configuration;
public class Options
{
public static class WorldOptions
{
public World worldObj;
public String name;
public WorldOptions(World world)
{
this.worldObj = world;
this.name = getWorldName(world);
}
public int maxObfuscateHeight = 128;
private int[] rndBlocks;
private int[] rndBlocksInterval;
private int[] rndBlocksCount;
private int rndBlockIndex = 0;
public int getRandomID()
{
while (true)
{
rndBlockIndex++;
if (rndBlockIndex >= rndBlocks.length)
rndBlockIndex = 0;
if (rndBlocksCount[rndBlockIndex] >= rndBlocksInterval[rndBlockIndex])
{
rndBlocksCount[rndBlockIndex] = 1;
return rndBlocks[rndBlockIndex];
}
else
{
rndBlocksCount[rndBlockIndex]++;
}
}
}
public void load(final Configuration config, final String[] blockList)
{
this.maxObfuscateHeight = config.getInt("maxObfuscateHeight", name, this.maxObfuscateHeight, 0, 256, "Max obfuscate height");
String[] list = config.getStringList("randomBlocks", this.name, blockList, "[blockID]:[interval]");
int count = validateBlockList(list);
if (count == 0)
{
if (list.length == 0)
Log.error("%s.randomBlocks.length == 0", this.name);
else
Log.error("%s.randomBlocks has errors", this.name);
list = blockList;
count = list.length;
}
rndBlocks = new int[count];
rndBlocksInterval = new int[count];
rndBlocksCount = new int[count];
int i = 0;
for (String value : list)
{
String[] values = value.split(":");
try
{
int v0 = Integer.valueOf(values[0]);
int v1 = Integer.valueOf(values[1]);
if (v0 >= 0 && v0 < 4096 && v1 > 0)
{
rndBlocks[i] = v0;
rndBlocksCount[i] = 1;
rndBlocksInterval[i] = v1;
i++;
}
}
catch (Exception e) { }
}
}
private int validateBlockList(String[] list)
{
int count = 0;
for (int i = 0; i < list.length; i++)
{
String[] values = list[i].split(":");
try
{
int v0 = Integer.valueOf(values[0]);
int v1 = Integer.valueOf(values[1]);
if (v0 >= 0 && v0 < 4096 && v1 > 0)
count++;
}
catch(Exception e)
{
}
}
return count;
}
}
public static String getWorldName(World world)
{
return world.provider.getClass().getSimpleName();
}
private static HashMap<String, WorldOptions> worlds = new HashMap<String, WorldOptions>();
public static WorldOptions getWorldOptions(World world)
{
String name = getWorldName(world);
WorldOptions options = worlds.get(name);
if (options == null)
{
Configuration config = new Configuration(configFile, false);
options = new WorldOptions(world);
if (world.provider instanceof WorldProviderSurface)
{
options.load(config, new String[] {
getID(Blocks.air, 1),
getID(Blocks.gold_ore, 16),
getID(Blocks.iron_ore, 16),
getID(Blocks.coal_ore, 16),
getID(Blocks.lapis_ore, 16),
getID(Blocks.diamond_ore, 16),
getID(Blocks.redstone_ore, 16),
getID(Blocks.emerald_ore, 16),
getID(Blocks.mossy_cobblestone, 16),
getID(Blocks.mob_spawner, 1000),
});
}
if (world.provider instanceof WorldProviderHell)
{
options.load(config, new String[] {
getID(Blocks.air, 1),
getID(Blocks.glowstone, 16),
getID(Blocks.netherrack, 16),
getID(Blocks.nether_brick, 16),
getID(Blocks.nether_brick_fence, 16),
getID(Blocks.nether_brick_stairs, 16),
getID(Blocks.nether_wart, 16),
getID(Blocks.quartz_ore, 16),
getID(Blocks.mob_spawner, 1000),
});
}
else
if (world.provider instanceof WorldProviderEnd)
{
options.load(config, new String[] {
getID(Blocks.air, 1),
getID(Blocks.end_stone, 16),
});
}
else
{
options.load(config, new String[] {
getID(Blocks.air, 1),
getID(Blocks.gold_ore, 16),
getID(Blocks.iron_ore, 16),
getID(Blocks.coal_ore, 16),
getID(Blocks.lapis_ore, 16),
getID(Blocks.diamond_ore, 16),
getID(Blocks.redstone_ore, 16),
getID(Blocks.emerald_ore, 16),
getID(Blocks.mossy_cobblestone, 16),
getID(Blocks.mob_spawner, 1000),
});
}
config.save();
}
return options;
}
public static WorldOptions worldOptions;
private static boolean[] obfuscateBlocks = new boolean[4096];
public static boolean[] transparentBlocks = new boolean[4096];
public static boolean isBuildCraft = false;
public static class Offset
{
public int x;
public int y;
public int z;
}
public static ArrayList<Offset> updateOffsets = new ArrayList<Offset>();
public static File configFile;
public static void load(File modDir)
{
configFile = new File(modDir, Orebfuscator.MODID + ".cfg");
Configuration config = new Configuration(configFile, false);
/*
ClassLoader loader = (ClassLoader)Thread.currentThread().getContextClassLoader();
try
{
loader.loadClass("org.bukkit.craftbukkit.CraftWorld");
isBuildCraft = true;
}
catch (Exception e)
{
isBuildCraft = false;
}
isBuildCraft = config.getBoolean("isBuildCraft", "Options", isBuildCraft, "BuildCraft and Forge have different algorithms update chunks");
*/
int updateRadius = config.getInt("updateRadius", "Options", 2, 1, 5, "How much blocks update after block break");
for (int x = -updateRadius; x <= updateRadius; x++)
{
for (int y = -updateRadius; y <= updateRadius; y++)
{
for (int z = -updateRadius; z <= updateRadius; z++)
{
if (x == 0 && y == 0 && z == 0)
continue;
if ((x*x + y*y + z*z) <= updateRadius*2)
{
Offset offset = new Offset();
offset.x = x;
offset.y = y;
offset.z = z;
updateOffsets.add(offset);
}
}
}
}
int[] list = config.get("Options", "obfuscateBlocks", new int[] {
getID(Blocks.stone),
getID(Blocks.dirt),
getID(Blocks.gold_ore),
getID(Blocks.iron_ore),
getID(Blocks.coal_ore),
getID(Blocks.lapis_ore),
getID(Blocks.diamond_ore),
getID(Blocks.redstone_ore),
getID(Blocks.emerald_ore),
getID(Blocks.netherrack),
getID(Blocks.nether_brick),
getID(Blocks.quartz_ore),
getID(Blocks.end_stone),
}).getIntList();
if (list.length == 0)
{
for (int i = 0; i < obfuscateBlocks.length; i++)
{
obfuscateBlocks[i] = true;
}
}
else
{
updateList(obfuscateBlocks, list);
}
list = config.get("Options", "transparentBlocks", new int[] {}).getIntList();
updateList(transparentBlocks, list);
config.save();
}
private static void updateList(boolean[] blocks, int[] list)
{
for (int i = 0; i < blocks.length; i++)
{
blocks[i] = false;
}
for (int i = 0; i < list.length; i++)
{
if (list[i] >= 0 || list[i] < blocks.length)
blocks[list[i]] = true;
}
}
private static int getID(Block block)
{
return Block.getIdFromBlock(block);
}
private static String getID(Block block, int interval)
{
return String.format("%d:%d", Block.getIdFromBlock(block), interval);
}
public static boolean isObfuscated(int id) {
return obfuscateBlocks[id];
}
public static boolean isObfuscated(Block block) {
return obfuscateBlocks[Block.getIdFromBlock(block)];
}
private static boolean[] _transparentBlocks = new boolean[4096];
private static boolean TransparentCached = false;
public static boolean isBlockTransparent(int id)
{
if (id < 0)
return true;
if (!TransparentCached)
{
// Generate TransparentBlocks by reading them from Minecraft
for (int i = 0; i < _transparentBlocks.length; i++) {
if (transparentBlocks[i])
{
_transparentBlocks[i] = true;
}
else
{
Block block = Block.getBlockById(i);
if (block == null)
{
_transparentBlocks[i] = true;
}
else
{
_transparentBlocks[i] = !block.isNormalCube();
}
}
}
TransparentCached = true;
}
return _transparentBlocks[id];
}
public static boolean isTransparent(Block block)
{
return isBlockTransparent(Block.getIdFromBlock(block));
}
}

View file

@ -1,13 +1,7 @@
package Orebfuscator;
package orebfuscator;
import java.io.File;
import java.util.HashSet;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
@ -15,15 +9,12 @@ import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import cpw.mods.fml.common.network.FMLNetworkEvent;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.ReflectionHelper;
@Mod(modid = Orebfuscator.MODID, version = Orebfuscator.VERSION, acceptableRemoteVersions = "*")
public class Orebfuscator
{
public static final String MODID = "Orebfuscator";
public static final String VERSION = "0.2";
public static final String MODID = "orebfuscator";
public static final String VERSION = "0.5";
@EventHandler
public void init(FMLInitializationEvent event)
@ -35,7 +26,7 @@ public class Orebfuscator
{
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(new PlayerHandler());
Options.load(event.getModConfigurationDirectory());
}

View file

@ -0,0 +1,84 @@
package orebfuscator;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
public class PlayerHandler
{
public Map<EntityPlayer, BlockBreakInfo> list = new HashMap<EntityPlayer, BlockBreakInfo>();
public static class BlockBreakInfo
{
public int x;
public int y;
public int z;
public void update(final int x, final int y, final int z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
public boolean isTransparent(final World world, final int x, final int y, final int z)
{
return Options.isBlockTransparent(BlockHelper.getBlockID(world, x, y, z));
}
public void updateBlock(final World world, final int x, final int y, final int z)
{
if (isTransparent(world, x, y, z))
return;
if (Options.isObfuscated(BlockHelper.getBlockID(world, x, y, z)))
{
if (isTransparent(world, x - 1, y, z) || isTransparent(world, x + 1, y, z) ||
isTransparent(world, x, y - 1, z) || isTransparent(world, x, y + 1, z) ||
isTransparent(world, x, y, z - 1) || isTransparent(world, x, y, z + 1))
return;
world.markBlockForUpdate(x, y, z);
}
}
public void update(EntityPlayer player, int x, int y, int z)
{
BlockBreakInfo info = list.get(player);
if (info == null)
{
info = new BlockBreakInfo();
list.put(player, info);
}
if (info.x != x || info.y != y || info.z != z)
{
info.update(x, y, z);
for (int i = 0; i < Options.updateOffsets.size(); i++)
{
Options.Offset offset = Options.updateOffsets.get(i);
updateBlock(player.worldObj, x + offset.x, y + offset.y, z + offset.z);
}
}
}
@SubscribeEvent
public void onBreakSpeed(PlayerEvent.BreakSpeed event)
{
update(event.entityPlayer, event.x, event.y, event.z);
}
@SubscribeEvent
public void onBlockBreak(BlockEvent.BreakEvent event)
{
update(event.getPlayer(), event.x, event.y, event.z);
}
}

View file

@ -1,16 +1,9 @@
package Orebfuscator;
package orebfuscator;
import io.netty.channel.Channel;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Queue;
import cpw.mods.fml.relauncher.ReflectionHelper;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
public class PlayerInjector {

View file

@ -1,9 +1,8 @@
package Orebfuscator;
package orebfuscator;
import java.net.SocketAddress;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.play.server.S23PacketBlockChange;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
@ -28,14 +27,14 @@ public class ProxyChannel implements Channel
this.player = player;
}
public void updateMsg(Object msg)
public Object updateMsg(Object msg)
{
if (msg instanceof S26PacketMapChunkBulk)
{
S26PacketMapChunkBulk packet = (S26PacketMapChunkBulk)msg;
MapChunkBulkObfuscator.obfuscate(player.worldObj, packet);
return;
return MapChunkBulkObfuscator.obfuscate(player.worldObj, packet);
}
return msg;
}
@Override
@ -68,6 +67,7 @@ public class ProxyChannel implements Channel
return this.channel.close();
}
@SuppressWarnings( "deprecation" )
@Override
public ChannelFuture deregister() {
return this.channel.deregister();
@ -121,7 +121,7 @@ public class ProxyChannel implements Channel
@Override
public ChannelFuture writeAndFlush(Object msg) {
this.updateMsg(msg);
msg = this.updateMsg(msg);
return this.channel.writeAndFlush(msg);
}

View file

@ -1,14 +1,14 @@
[
{
"modid": "Orebfuscator",
"name": "Example Mod",
"modid": "orebfuscator",
"name": "",
"description": "",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "",
"updateUrl": "",
"authorList": ["ExampleDude"],
"credits": "The Forge and FML guys, for making this example",
"authorList": ["shsa", "xamora"],
"credits": "Shsa https://github.com/shsa",
"logoFile": "",
"screenshots": [],
"dependencies": []