optimization

This commit is contained in:
shsa 2015-01-30 17:09:36 +07:00
parent 999f0e6bb5
commit 1f4ab61026
11 changed files with 131 additions and 327 deletions

View file

@ -1,124 +0,0 @@
package Orebfuscator;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
public class AsyncPacketQueue<E> implements Iterable<E>, Collection<E>, Queue<E>
{
public Queue queue;
public EntityPlayerMP player;
public AsyncPacketQueue(EntityPlayerMP player, Queue queue)
{
this.player = player;
this.queue = queue;
}
@Override
public boolean add(E arg0) {
//Packet packet = (Packet) Fields.getValue(arg0, Fields.InboundHandlerTuplePacketListener.getPacketIndex());
//Log.msg("%s", packet.getClass().getName());
Log.msg("%s", arg0.getClass().getName());
return this.queue.add(arg0);
}
public void cleanup() {
this.player = null;
}
@Override
public E element() {
return (E) this.queue.element();
}
@Override
public boolean offer(E arg0) {
return this.queue.offer(arg0);
}
@Override
public E peek() {
return (E) this.queue.peek();
}
@Override
public E poll() {
return (E) this.queue.poll();
}
@Override
public E remove() {
return (E) this.queue.remove();
}
@Override
public boolean addAll(Collection<? extends E> arg0) {
Log.error("Queue.addAll");
return this.queue.addAll(arg0);
}
@Override
public void clear() {
this.queue.clear();
}
@Override
public boolean contains(Object arg0) {
return this.queue.contains(arg0);
}
@Override
public boolean containsAll(Collection<?> arg0) {
return this.queue.containsAll(arg0);
}
@Override
public boolean isEmpty() {
return this.queue.isEmpty();
}
@Override
public boolean remove(Object arg0) {
return this.queue.remove(arg0);
}
@Override
public boolean removeAll(Collection<?> arg0) {
return this.queue.removeAll(arg0);
}
@Override
public boolean retainAll(Collection<?> arg0) {
return this.queue.removeAll(arg0);
}
@Override
public int size() {
return this.queue.size();
}
@Override
public Object[] toArray() {
return this.queue.toArray();
}
@Override
public <T> T[] toArray(T[] arg0) {
return (T[]) this.queue.toArray(arg0);
}
@Override
public Iterator<E> iterator() {
return this.queue.iterator();
}
}

View file

@ -1,110 +0,0 @@
package Orebfuscator;
import io.netty.channel.Channel;
import java.lang.reflect.Field;
import java.util.HashSet;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.network.play.server.S23PacketBlockChange;
import net.minecraft.world.World;
public class BlockChange
{
public static Field fieldPositionX = null;
public static Field fieldPositionY = null;
public static Field fieldPositionZ = null;
public static HashSet<Integer> list = new HashSet();
public static int baseX;
public static int baseY;
public static int baseZ;
public static int updateRadius = 2;
public static int startPos;
public static void parse(World world, Channel channel, S23PacketBlockChange packet)
{
if (fieldPositionX == null)
{
fieldPositionX = Fields.getField(packet, "field_148887_a");
fieldPositionY = Fields.getField(packet, "field_148885_b");
fieldPositionZ = Fields.getField(packet, "field_148886_c");
}
int x = (Integer) Fields.getValue(packet, fieldPositionX);
int y = (Integer) Fields.getValue(packet, fieldPositionY);
int z = (Integer) Fields.getValue(packet, fieldPositionZ);
// èñïîëüçóåì áàçîâóþ òî÷êó, ÷òîáû â äàëüíåéøåì âûñ÷èòûâàòü ñìåùåíèÿ îáíîâëÿåìûõ áëîêîâ
// ñìåùåíèÿ áóäåì ñâîäèòü â îäèí int è õðàíèòü â HashSet
baseX = x - updateRadius;
baseY = y - updateRadius;
baseZ = z - updateRadius;
x = updateRadius;
y = updateRadius;
z = updateRadius;
startPos = (updateRadius << 16) | (updateRadius << 8) | updateRadius;
list.clear();
updateAjacentBlocks(world, updateRadius, updateRadius, updateRadius, updateRadius + 1);
for (int pos : list)
{
x = baseX + (pos >> 16 & 255);
y = baseY + (pos >> 8 & 255);
z = baseZ + (pos & 255);
world.markBlockForUpdate(x, y, z);
}
}
public static boolean isTransparent(World world, int x, int y, int z)
{
int pos = (x << 16) | (y << 8) | z;
if (pos == startPos)
return false;
Block block = world.getBlock(baseX + x, baseY + y, baseZ + z);
return Options.isBlockTransparent(Block.getIdFromBlock(block));
}
public static boolean needUpdate(World world, int x, int y, int z)
{
int pos = (x << 16) | (y << 8) | z;
if (pos == startPos)
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)
);
}
public static boolean updateAjacentBlocks(World world, int x, int y, int z, int step)
{
if (step == 0)
return false;
int pos = (x << 16) | (y << 8) | z;
if (list.contains(pos))
return false;
if (needUpdate(world, x, y, z))
list.add(pos);
step--;
updateAjacentBlocks(world, x - 1, y, z, step);
updateAjacentBlocks(world, x + 1, y, z, step);
updateAjacentBlocks(world, x, y - 1, z, step);
updateAjacentBlocks(world, x, y + 1, z, step);
updateAjacentBlocks(world, x, y, z - 1, step);
updateAjacentBlocks(world, x, y, z + 1, step);
return true;
}
}

View file

@ -0,0 +1,53 @@
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;
public class BlockHelper
{
private static int getBlockExtId(final ExtendedBlockStorage extendedblockstorage, final int x, final int y, final int z)
{
if (extendedblockstorage != null)
{
int l = extendedblockstorage.getBlockLSBArray()[y << 8 | z << 4 | x] & 255;
if (extendedblockstorage.getBlockMSBArray() != null)
{
l |= extendedblockstorage.getBlockMSBArray().get(x, y, z) << 8;
}
return l;
}
return 0;
}
public static int getBlockID(final Chunk chunk, final int x, final int y, final int z)
{
ExtendedBlockStorage[] storageArrays = chunk.getBlockStorageArray();
if (y >> 4 < storageArrays.length)
{
return getBlockExtId(storageArrays[y >> 4], x, y & 15, z);
}
return 0;
}
public static int getBlockID(final World world, final int x, final int y, final int z)
{
if (x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000 && y >= 0 && y < 256)
{
Chunk chunk = null;
try
{
chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4);
return getBlockID(chunk, x & 15, y, z & 15);
}
catch (Throwable throwable)
{
}
}
return 0;
}
}

View file

@ -1,6 +0,0 @@
package Orebfuscator;
public class BlockUpdate
{
}

View file

@ -1,12 +1,11 @@
package Orebfuscator;
import Orebfuscator.Options.WorldOptions;
import net.minecraft.block.Block;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
public class ChunkInfo
public class ChunkObfuscator
{
// èíôîðìàöèÿ î íàëè÷èè ñåêöèè. Ñåêöèè - ýòî áëîêè ðàçìåðîì 16õ16õ16, ñåêöèè ðàñïîëàãàþòñÿ äðóã íàä äðóãîì
// Chunk ñîñòîèò èç 16 ñåêöèé, ðàçìåð ÷àíêà 16x16x256
@ -34,7 +33,7 @@ public class ChunkInfo
public int len;
public byte[] data;
public void parse(World world, int chunkX, int chunkZ, int sectionLSB, int sectionMSB, 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;
@ -182,15 +181,9 @@ public class ChunkInfo
if (x < 0 || x > 15 || z < 0 || z > 15)
{
//if (Options.engineMode == 2)
{
Block block = world.getBlock(this.startX | x, y, this.startY | z);
return Options.isBlockTransparent(Block.getIdFromBlock(block));
}
//return true;
return Options.isBlockTransparent(BlockHelper.getBlockID(world, this.startX | x, y, this.startY | z));
}
return Options.isBlockTransparent(getBlockID(world, x, y, z));
}

View file

@ -6,7 +6,7 @@ import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
public class MapChunkBulk
public class MapChunkBulkObfuscator
{
public static Field fieldChunkX;
public static Field fieldChunkZ;
@ -21,9 +21,9 @@ public class MapChunkBulk
// -- ìàññèâ äàííûõ
public static Field fieldData;
public static ChunkInfo info;
public static ChunkObfuscator info;
public static void parse(World world, S26PacketMapChunkBulk packet)
public static void obfuscate(World world, S26PacketMapChunkBulk packet)
{
if (fieldStatusLSB == null)
{
@ -34,7 +34,7 @@ public class MapChunkBulk
fieldStatusMSB = Fields.getField(packet, "field_149262_d");
fieldData = Fields.getField(packet, "field_149260_f");
info = new ChunkInfo();
info = new ChunkObfuscator();
}
@ -46,7 +46,7 @@ public class MapChunkBulk
for (int i = 0; i < statusLSB.length; i++)
{
info.parse(world, chunkX[i], chunkZ[i], statusLSB[i], statusMSB[i], dataArray[i]);
info.obfuscate(world, chunkX[i], chunkZ[i], statusLSB[i], statusMSB[i], dataArray[i]);
}
}
}

View file

@ -55,9 +55,6 @@ public class Options
getID(Blocks.diamond_ore),
getID(Blocks.redstone_ore),
getID(Blocks.emerald_ore),
getID(Blocks.end_portal_frame),
getID(Blocks.end_portal),
getID(Blocks.mob_spawner),
getID(Blocks.mossy_cobblestone),
}).getIntList();
if (options.randomBlocks.length == 0)
@ -73,7 +70,6 @@ public class Options
getID(Blocks.nether_brick_stairs),
getID(Blocks.nether_wart),
getID(Blocks.quartz_ore),
getID(Blocks.mob_spawner),
}).getIntList();
if (options.randomBlocks.length == 0)
options.randomBlocks = new int[] {getID(Blocks.nether_brick)};
@ -82,8 +78,6 @@ public class Options
if (provider instanceof WorldProviderEnd)
{
options.randomBlocks = config.get(name, "randomBlocks", new int[] {
getID(Blocks.end_portal_frame),
getID(Blocks.end_portal),
getID(Blocks.end_stone),
}).getIntList();
if (options.randomBlocks.length == 0)
@ -122,8 +116,6 @@ public class Options
public static WorldOptions worldOptions;
public static int engineMode = 2;
private static boolean[] obfuscateBlocks = new boolean[4096];
public static int[] randomBlocks;
@ -137,10 +129,6 @@ public class Options
configFile = new File(modDir, Orebfuscator.MODID + ".cfg");
Configuration config = new Configuration(configFile, false);
//engineMode = clamp(config.get("Options", "engineMode", engineMode).getInt(), 1, 2);
//BlockChange.updateRadius = clamp(config.get("Options", "updateRadius", BlockChange.updateRadius).getInt(), 1, 5);
int[] list = config.get("Options", "obfuscateBlocks", new int[] {
getID(Blocks.stone),
getID(Blocks.dirt),
@ -243,4 +231,9 @@ public class Options
}
return _transparentBlocks[id];
}
public static boolean isTransparent(Block block)
{
return isBlockTransparent(Block.getIdFromBlock(block));
}
}

View file

@ -23,7 +23,7 @@ import cpw.mods.fml.relauncher.ReflectionHelper;
public class Orebfuscator
{
public static final String MODID = "Orebfuscator";
public static final String VERSION = "0.1";
public static final String VERSION = "0.2";
@EventHandler
public void init(FMLInitializationEvent event)
@ -50,13 +50,4 @@ public class Orebfuscator
{
PlayerInjector.cleanupPlayer((EntityPlayerMP) event.player);
}
@SubscribeEvent
public void onClientConnect(FMLNetworkEvent.ServerConnectionFromClientEvent event)
{
/*
NetHandlerPlayServer handler = (NetHandlerPlayServer)event.handler;
PlayerInjector.hookPlayer(handler.playerEntity, handler.netManager);
*/
}
}

View file

@ -2,10 +2,17 @@ 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;
@ -16,15 +23,57 @@ public class PlayerHandler
public static class BlockBreakInfo
{
public boolean[][][] isTransparent = new boolean[5][5][5];
public int x;
public int y;
public int z;
}
public void updateBlock(World world, int x, int y, int z)
{
if (Options.isObfuscated(world.getBlock(x, y, z)))
world.markBlockForUpdate(x, y, 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)
@ -38,18 +87,15 @@ public class PlayerHandler
if (info.x != x || info.y != y || info.z != z)
{
info.x = x;
info.y = y;
info.z = z;
info.updateBlocksTransparent(player.worldObj, x, y, z);
updateBlock(player.worldObj, x-1, y, z);
updateBlock(player.worldObj, x+1, y, z);
updateBlock(player.worldObj, x, y-1, z);
updateBlock(player.worldObj, x, y+1, z);
updateBlock(player.worldObj, x, y, z-1);
updateBlock(player.worldObj, x, y, z+1);
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);
}
//Log.msg("updated: %d, %d, %d", x, y, z);
}
@SubscribeEvent

View file

@ -14,21 +14,8 @@ import net.minecraft.network.Packet;
public class PlayerInjector {
@SuppressWarnings("unchecked")
public static void hookPlayer(EntityPlayerMP player)
{
/*
NetworkManager nm = player.playerNetServerHandler.netManager;
Queue queue = (Queue)Fields.getValue(nm, Fields.NetworkManager.getReceivedPacketsQueueIndex());
queue = new AsyncPacketQueue(player, queue);
Fields.setValue(nm, Fields.NetworkManager.getReceivedPacketsQueueIndex(), queue);
*/
/*
Queue queue = (Queue)Fields.getValue(nm, Fields.NetworkManager.getOutboundPacketsQueueIndex());
queue = new AsyncPacketQueue(player, queue);
Fields.setValue(nm, Fields.NetworkManager.getOutboundPacketsQueueIndex(), queue);
*/
NetworkManager nm = player.playerNetServerHandler.netManager;
Channel channel = (Channel)Fields.getValue(nm, Fields.NetworkManager.getChannelIndex());
channel = new ProxyChannel(channel, player);
@ -37,13 +24,5 @@ public class PlayerInjector {
public static void cleanupPlayer(EntityPlayerMP player)
{
/*
NetworkManager nm = player.playerNetServerHandler.netManager;
((AsyncPacketQueue)Fields.getValue(nm, Fields.NetworkManager.getReceivedPacketsQueueIndex())).cleanup();
*/
/*
NetworkManager nm = player.playerNetServerHandler.netManager;
((AsyncPacketQueue)Fields.getValue(nm, Fields.NetworkManager.getOutboundPacketsQueueIndex())).cleanup();
*/
}
}

View file

@ -33,20 +33,9 @@ public class ProxyChannel implements Channel
if (msg instanceof S26PacketMapChunkBulk)
{
S26PacketMapChunkBulk packet = (S26PacketMapChunkBulk)msg;
MapChunkBulk.parse(player.worldObj, packet);
MapChunkBulkObfuscator.obfuscate(player.worldObj, packet);
return;
}
/*
if (msg instanceof S23PacketBlockChange)
{
S23PacketBlockChange packet = (S23PacketBlockChange)msg;
BlockChange.parse(player.worldObj, channel, packet);
return;
}
*/
//String className = msg.getClass().getSimpleName();
//if (className.indexOf("Entity") == -1)
//Log.msg("%s", msg.getClass().getName());
}
@Override
@ -126,7 +115,7 @@ public class ProxyChannel implements Channel
@Override
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
this.updateMsg(msg);
//this.updateMsg(msg);
return this.channel.writeAndFlush(msg, promise);
}