[1.7.10] Pickup on key / Подбор на кнопку

[1.7.10] Pickup on key / Подбор на кнопку 0.0.1

Нет прав для скачивания
167
10
69
Fr0Le добавил(а) новый ресурс:

[1.7.10] Pickup on key / Подбор на кнопку - Создание кнопки для подбора предметов

В этом ресурсе Вы узнаете:
  • Как создать кнопку, которая при нажатии подберает предмет с земли;
Скачать исходники
Скачать мод

Немного кода:
Регистрируем кнопку
KeybindsRegister.java:
public static final KeyBinding
    PICKUP_KEY = new KeyBinding(Type.getTranslate("key.pickup"), Keyboard.KEY_F...

Узнать больше об этом ресурсе...
 
Ты специально сюда не приложил содержимое класса PickupPacket, чтобы народ не шокировать?
Я полез в репозиторий и офигел:
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(). Очень похоже на код, собранный из скопитыренных кусков.

Остальное решил не читать...
 
Последнее редактирование:
@Plasticable, в любом моде где есть пакеты, читер может отослать пакет с подменой или вызвать нужный пакет, когда ему удобно, здесь речь не об этом, имхо. Обмажся античитами и будет тебе счастье.
Я не гуру, никого не учу и учить не собираюсь и не говорю что нужно делать именно так, это чисто пример одной из реализаций, которая может быть. Кому нужно тот переделает под себя, кому нет, вообще юзать не будет. Вот по этому это и слив, а не гайд или туториал. Все остальное учту.
 
Последнее редактирование:
в любом моде где есть пакеты, читер может отослать пакет с подменой или вызвать нужный пакет, когда ему удобно
Верно. Но задача хорошего кодера - минимизировать вред таких пакетов с помощью всяческих серверных проверок.

Обмажся античитами
Клиентскими? В данном случае, это не панацея, в отличии от грамотной обработки пакетов на сервере.

не говорю что нужно делать именно так, это чисто пример одной из реализаций
Плохой пример, без обид.

Надеюсь, ты учтёшь мои рекомендации и исправишь это хотя бы на своём проекте.
 
Добрый день! Дописал мод. Файлы: 1) Скомпилированный мод 2) Исходники

Изменения в моде​

1. Подбор предметов (как было)​

  • Подбор дропа по назначенной клавише (по умолчанию F).

2. Взаимодействие с блоками​

  • Сундуки, двери, люки — открытие/закрытие.
  • Рычаги и кнопки — включение/выключение.

3. Взаимодействие с сущностями​

  • Жители — открытие торговли.
  • Custom NPCs (EntityCustomNpc) — запуск диалога.

4. Подсказки на экране​

При наведении на цель отображаются подсказки:
  • [F] Подобрать — предметы на земле
  • [F] Открыть/Закрыть — сундуки, двери, люки
  • [F] Активировать — рычаги, кнопки
  • [F] Говорить — жители, НПС
Все действия привязаны к одной клавише (по умолчанию F), которую можно поменять в настройках управления.
 

Вложения

  • pickup-0.0.1.jar
    16.4 KB · Просмотры: 0
  • mod src.zip
    219.4 KB · Просмотры: 0
Ты специально сюда не приложил содержимое класса PickupPacket, чтобы народ не шокировать?
Я полез в репозиторий и офигел:
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(). Очень похоже на код, собранный из скопитыренных кусков.

Остальное решил не читать...
Увидел замечания и пофиксил )

1. Проверка расстояния

  • На сервере добавлена проверка getDistanceToEntity(theItem) > 6.0 — подбор разрешён только в пределах 6 блоков.

2. Безопасность пакета

  • Игрок берётся из контекста: ctx.getServerHandler().playerEntity, а не из тела пакета. playerID в пакете больше не используется.

3. Меньше вызовов getEntityByID

  • Один вызов getEntityByID(message.entityID) для предмета; игрок берётся из контекста.

4. Убрана лишняя проверка на null

  • Используется entity instanceof EntityVillager || (entity != null && isNPC(entity)) — instanceof уже обрабатывает null.

5. Корректная работа события подбора

  • Перед уничтожением предмета вызывается MinecraftForge.EVENT_BUS.post(new EntityItemPickupEvent(thePlayer, theItem)), чтобы моды могли реагировать на подбор.

6. Учёт заполненного инвентаря

  • setDead() вызывается только при успешном addItemStackToInventory(). Порядок: добавление в инвентарь → событие → detectAndSendChanges() → setDead() → воспроизведение звука.

7. Лишние вызовы Minecraft.getMinecraft()

  • В ItemRenderOnFloor.drawItems используется уже объявленная переменная mc. В renderInventorySlot добавлен параметр mc вместо нового вызова getMinecraft().
 

Вложения

  • pickup-0.0.1.jar
    16.6 KB · Просмотры: 0
  • mod src.zip
    62.9 KB · Просмотры: 0
Назад
Сверху