Загрузка чанков? энтити? ВСЕГО

Версия Minecraft
1.7.10
API
Forge
204
7
25
Захотелось увеличть дальность работы дронам в мсхели. Перекопал всё что можно в моде, вот небольшая хронология:
  • Убрал "обрыв связи"(хз как назвать) при достижении n-дистанции от игрока. Теперь можно улететь чуть дальше.
  • Следующая беда. Когда энтити дрона пропадает на клиенте, то и связь с упарвелнием тоже. Перехватываю пакет деспавна, проверяю кого именно деспавним и отменяю его обработку.
перехват 1:
@SubscribeEvent
    public void onClientConnect(FMLNetworkEvent.ClientConnectedToServerEvent event) {
        ChannelPipeline pipeline = event.manager.channel().pipeline();
        pipeline.addBefore("packet_handler", "custom_packet_handler", new W_PacketHandler());
    }

    class W_PacketHandler extends SimpleChannelInboundHandler<Packet> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception {
            if (msg instanceof S13PacketDestroyEntities) {
                S13PacketDestroyEntities packet = (S13PacketDestroyEntities) msg;
                int[] entityIds = packet.func_149098_c();
                List<Integer> newEntityIds = new ArrayList<>();

                for (int entityId : entityIds) {
                    Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(entityId);
                    if(Minecraft.getMinecraft().thePlayer.ridingEntity != null) {
                        if (entity != null && entity instanceof MCH_EntityAircraft && ((MCH_EntityAircraft) entity).getAcInfo().isUAV) {
                            if(Minecraft.getMinecraft().thePlayer.ridingEntity instanceof MCH_EntityUavStation){
                                MCH_EntityUavStation uavStation = (MCH_EntityUavStation) Minecraft.getMinecraft().thePlayer.ridingEntity;
                                if(uavStation.getControlAircract()!=null){
                                    if(entity.getEntityId() == uavStation.getControlAircract().getEntityId()){
                                        newEntityIds.add(entityId);
                                    }
                                }
                            }
                        }
                    }
                }

                if (!newEntityIds.isEmpty()) {
                    int[] remainingIds = Arrays.stream(entityIds)
                            .filter(id -> !newEntityIds.contains(id))
                            .toArray();

                    if (remainingIds.length > 0) {
                        S13PacketDestroyEntities newPacket = new S13PacketDestroyEntities(remainingIds);
                        ctx.fireChannelRead(newPacket);
                        return;
                    } else {
                        return;
                    }
                }
            }
            ctx.fireChannelRead(msg);
        }
  • Добавил постоянную загрузку чанков вокруг дрона на стороне сервера, что бы мог летать там где нет игроков. Работает! Теперь можно летать в пустоте и даже вернуться, правда для клиента дрон зависает на границе "непрогруза энетити", но....
  • Но когда дрон возвращается в зону прогрузки для игрока, то он как бы "переспавнивается"(entityID остаётся тотже, но сам обьект существа заменяется новым), добавил аналогичный перехват пакета со "спавном", теперь когда дрон взовращается в "зону прогрузки энтити", то всё как бы норм, снова видны все измение в полёте и т.д.
  • Начал изучать как игра передаёт клиенту инфу о существах. Пришёл почти к полному копипасту метода sendLocationToAllClients из класса EntityTrackerEntry. Код выполнял в методе обновления станции управления(MCH_EntityUavStation)
onUpdate_Server в MCH_EntityUavStation:
private void onUpdate_Server() {
      //ориг код
      if(super.riddenByEntity != null) {
         if(super.riddenByEntity.isDead) {
            //ориг код
         } else {
            if(getControlAircract()!=null){ //мой код обновления
               MCH_EntityAircraft cac = getControlAircract();
               if(super.riddenByEntity instanceof EntityPlayerMP){

                  ((EntityPlayerMP) super.riddenByEntity).addChatMessage(new ChatComponentText("Дистанция до дрона -> "+cac.getDistanceToEntity(this)));

                  int i = cac.myEntitySize.multiplyBy32AndRound(cac.posX);
                  int j = MathHelper.floor_double(cac.posY * 32.0D);
                  int k = cac.myEntitySize.multiplyBy32AndRound(cac.posZ);
                  int l = MathHelper.floor_float(cac.rotationYaw * 256.0F / 360.0F);
                  int i1 = MathHelper.floor_float(cac.rotationPitch * 256.0F / 360.0F);
                  int j1 = i - this.lastScaledXPosition;
                  int k1 = j - this.lastScaledYPosition;
                  int l1 = k - this.lastScaledZPosition;
                  Object object = null;
                  boolean flag = Math.abs(j1) >= 4 || Math.abs(k1) >= 4 || Math.abs(l1) >= 4 || cac.ticksExisted % 60 == 0;
                  boolean flag1 = Math.abs(l - this.lastYaw) >= 4 || Math.abs(i1 - this.lastPitch) >= 4;

                  if (this.ticksExisted > 0) {
                     if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128) {
                        if (flag && flag1) {
                           object = new S14PacketEntity.S17PacketEntityLookMove(cac.getEntityId(), (byte)j1, (byte)k1, (byte)l1, (byte)l, (byte)i1);
                        } else if (flag) {
                           object = new S14PacketEntity.S15PacketEntityRelMove(cac.getEntityId(), (byte)j1, (byte)k1, (byte)l1);
                        } else if (flag1) {
                           object = new S14PacketEntity.S16PacketEntityLook(cac.getEntityId(), (byte)l, (byte)i1);
                        }
                     } else {
                        object = new S18PacketEntityTeleport(cac.getEntityId(), i, j, k, (byte)l, (byte)i1);
                     }
                  }

                  if (false) {
                     double d0 = cac.motionX - this.motionX;
                     double d1 = cac.motionY - this.motionY;
                     double d2 = cac.motionZ - this.motionZ;
                     double d3 = 0.02D;
                     double d4 = d0 * d0 + d1 * d1 + d2 * d2;

                     if (d4 > d3 * d3 || d4 > 0.0D && cac.motionX == 0.0D && cac.motionY == 0.0D && cac.motionZ == 0.0D) {
                        this.motionX = cac.motionX;
                        this.motionY = cac.motionY;
                        this.motionZ = cac.motionZ;
                        ((EntityPlayerMP)this.riddenByEntity).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(cac.getEntityId(), this.motionX, this.motionY, this.motionZ));
                     }
                  }

                  if (object != null) {
                     ((EntityPlayerMP)this.riddenByEntity).playerNetServerHandler.sendPacket((Packet)object);
                  }

//                  this.sendMetadataToAllAssociatedPlayers();
                  DataWatcher datawatcher = cac.getDataWatcher();

                  if (datawatcher.hasChanges()) {
                     ((EntityPlayerMP)this.riddenByEntity).playerNetServerHandler.sendPacket(new S1CPacketEntityMetadata(cac.getEntityId(), datawatcher, false));
                  }

                  if (flag) {
                     this.lastScaledXPosition = i;
                     this.lastScaledYPosition = j;
                     this.lastScaledZPosition = k;
                  }

                  if (flag1) {
                     this.lastYaw = l;
                     this.lastPitch = i1;
                  }
               }
            }
         }
      }
      //ориг код
   }

- Теперь можно полноценно летать гдето в еб**ях очень далеко и возвращаться, но летаем мы в полной пустоте без чанков. И вот тут я пришёл в тупик, несколько дней уже пытаюсь как то использовать ванильные пакеты чанков, но успеха нет.
Выглядит это вот так -
1730564612426.png

Прошу помощи у гениев моддинга. Как передвавать и рисовать дальние чанки? Может всё что я сделал говно полное и моежет предложить более правильный и простой вариант реализации?
Спасибо.
 
Ты по факту занимаешься извращением над трекерами

В общем, то что тебе нужно - находится на серверной стороне в трекере чанков (смотри нечто похожее на PlayerChunkMap)

Когда игрок изменяет позицию, трекер чанков меняет свое состояние, определяет какие чанки игроку не отправлены и отправляет их.

Так же трекер чанков прямо отвечает за загрузку/выгрузку чанков, так что повредить что-нибудь и создать утечку памяти там - раз плюнуть
 
S21PacketChunkData
Я нигде не увидел отправку этого пакета на клиент или подобных.
Minecraft использует S21PacketChunkData для передачи данных чанков на клиент.

Соглашусь с Хомой, аккуратно с этим работай.
Ибо в таком деле ошибки будут очень дорого стоить)
 
Назад
Сверху