Ты специально сюда не приложил содержимое класса PickupPacket, чтобы народ не шокировать?
Я полез в репозиторий и офигел:
public class PickupPacket implements IMessage {
public int entityID;
public int playerID;
// ...
public static class Handler implements IMessageHandler<PickupPacket, IMessage> {
public IMessage onMessage(PickupPacket message, MessageContext ctx) {
MinecraftServer server = MinecraftServer.getServer();
if (server.getEntityWorld().getEntityByID(message.playerID) != null && server.getEntityWorld().getEntityByID(message.entityID) != null && server.getEntityWorld().getEntityByID(message.playerID) instanceof EntityPlayer) {
EntityPlayer thePlayer = (EntityPlayer)server.getEntityWorld().getEntityByID(message.playerID);
EntityItem theItem = (EntityItem)server.getEntityWorld().getEntityByID(message.entityID);
theItem.setDead();
thePlayer.worldObj.playSoundEffect(thePlayer.posX, thePlayer.posY, thePlayer.posZ, "random.pop", 1.0f, 1.0f);
thePlayer.inventory.addItemStackToInventory(theItem.getEntityItem());
thePlayer.inventoryContainer.detectAndSendChanges();
}
return null;
}
}
}
1. Нет проверки на расстояние до предмета. С каким-нибудь фрикамом можно потроллить игроков, у которых "исчезает" дроп с противника после их убийства в пвп
2. Читер может отправить пакет с любым
playerID
и заставить любого игрока подобрать любой выброшенный предмет, я правильно понял? Это даже ещё веселее предыдущего пункта.
Игрока, от которого пришёл пакет, можно получить с помощью
ctx.getServerHandler().playerEntity
3. Зачем вызывать
getEntityByID
5 раз, если можно всего один раз для предмета?
4. Проверка на null перед instanceof не нужна
5. Этот код сломает событие (оно просто не вызывается) поднятия предмета с земли, которое могут использовать твои или сторонние моды.
6. Ты убиваешь выброшенный предмет без проверки на невозможность его подобрать игроком (из-за заполненного инвентаря, например)
Результат метода
addItemStackToInventory
оберни в if-блок, в котором неплохо бы вызвать
FMLCommonHandler.instance().firePlayerItemPickupEvent(thePlayer, theItem)
,
inventoryContainer.detectAndSendChanges()
и уже потом
theItem.setDead()
Ещё забавный момент в
ItemRenderOnFloor#drawItems: у тебя уже есть переменная с инстансом Minecraft, но ты всё равно ещё 5 раз вызываешь Minecraft.getMinecraft(). Очень похоже на код, собранный из скопитыренных кусков.
Остальное решил не читать...