Rehber Paketleri İptal Etme ve Paket Oluşturma | ProtocolLib Kullanımı | Bölüm 2

Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...

why_shiro

Certified 3310 Enjoyer
Katılım
3 Haziran 2019
Mesajlar
281
Elmaslar
265
Puan
14.545
Yaş
24
Konum
Türkiye
Discord İzni
Minecraft
why_shiro
X
whyshiro_

Discord:

why_shiro

bannermctr.png



Bu makale ilk bölümün devamı niteliğindedir. Eğer ilk bölümde yapmış olduğumuz "ProtocolManager", "PacketListener" ve "PacketAdapter" farklılıkları, addPacketListener() metodu, PacketType, paketleri dinleme gibi konular hakkında bilginiz yoksa bu kurstan bir şey anlamayabilirsiniz. Bu yüzden lütfen ilk makaleyi okuduğunuza emin olunuz. İlk kursa gitmek için bana tıkla!
Bu bölümde sunucunun oyuncuya gönderdiği paketleri veya oyununun sunucuya gönderdiği paketleri iptal etmeyi ve kendi paketlerimizi oluşturmayı öğreneceğiz. ProtocolLib bittikten sonra NMS'ler üzerinden devam edeceğiz.



Bölüm 1 : Paketleri İptal Etme
Sunucunuza gelişmiş bir sohbet koruması yazmak istediğinizi varsayalım. Bunun için oyuncunun sunucuya gönderdiği Chat paketini (serverbound) dinlememiz gerekmekte. Paketimizi
Değerli ziyaretçimiz, içeriği görebilmek için şimdi giriş yapın veya kayıt olun.
üzerinden kontrol edelim:

1651661864168.png


Paketimiz sadece tek bir "String" değeri içermektedir. Bu yüzden container.getStrings().index(0); ile String değerini almamız gerekmekte. Bu yüzden bunu şu şekilde yapabiliriz:

Java:
String message = container.getStrings().read(0);

Sonra bu String değerimiz kötü bir kelime içeriyor mu diye kontrol etmemiz gerekiyor. Bunu küçük bir if-else ile yapabiliriz:


Java:
                if (message.contains("küfür") || message.contains("diğerKüfür")){
                    event.setCancelled(true); // Mesaj gönderimi iptal edildi
                    event.getPlayer().sendMessage("Küfür yasak!");
                }

Bu konumuz String manipülasyonu olmadığı için detaylı küfür veya website yakalamayı anlatmıyorum. Yukarıda gönderdiğimiz mesajı iptal ettik. Kodumuzun son görünümü şu şekilde olacaktır:

Java:
        protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.LOW, PacketType.Play.Client.CHAT) {

            @Override

            public void onPacketReceiving(PacketEvent event) {
                PacketContainer container = event.getPacket();

                String message = container.getStrings().read(0);

                if (message.contains("küfür") || message.contains("diğerKüfür")){
                    event.setCancelled(true);
                    event.getPlayer().sendMessage("Küfür yasak!");
                }
            }

        });




Bölüm 2 : Paketler Oluşturma
Paket oluşturma işi, dinlemede yaptığımız işe çok benzemektedir. Sadece bu sefer değerleri "read" etmektense "write" edeceğiz. Şimdi sunucuda bir patlama efekti oluşturalım. Bu bir clientbound işlemdir. Çünkü sunucu, oyuncuya sunucuda patlama olduğunu bildirecek paketler göndermektedir. Bu yüzden wiki sayfamızın Play kısmından Clientbound paketleri inceliyoruz. Oradan Explosion paketii bulup inceliyoruz:

1651662954833.png


Bu kursu yazarken bilerek Explosion paketini ele aldım. Çünkü wikide koordinalar "Float" olarak verilmiş. Ancak biz bunları yazarken Double olarak yazmalıyız. Aksi taktirde bir hatayla karşı karşıya kalacağız. Pluginimizin onEnable() metoduna yeni bir "Command Executor" oluşturuyorum ve adan komutumuzun çalışması için gereken class'ı oluşturuyorum (TestPluginCommand).

Java:
getServer().getPluginCommand("boom").setExecutor(new TestPluginCommand());

Java:
public class TestPluginCommand implements CommandExecutor {
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {



        return false;
    }
}

Ardından komutu kullanan kişinin oyuncu olduğunu doğrulamak için bir if-else kodu yazıyorum:

Java:
        if (sender instanceof Player){
            Player player = (Player) sender;
            }

Sonra da ProtocolManager objemizi oluşturuyoruz: ProtocolManager manager = ProtocolLibrary.getProtocolManager();. Bu adımları tamamladıktan sonra oyuncunun baktığı bloğu almamız gerekiyor. Spigot bize getLineOfSight() metodu sağlamakta. Bu metot oyuncunun gözünden bir çizgi çekmekte ve o çizgi içerisindeki tüm blokları almakta. Bu metot iki adet değer almaktadır:

@NotNull public List<Block> getLineOfSight(@Nullable Set<Material> transparent, int maxDistance);

Biz burada transparent için "null" , maksimum görüş uzaklığımızı da 25 olarak belirleyeceğiz. Ardından bu aralıkta aldığımız blokları Java 8 ile gelen .stream() metodunu kullanarak filtreliyeceğiz. Son olarak bir forEach() döngüsü ile istediğimiz bloğa ulaşacağız. Eğer stream(), filter(), map() gibi fonksiyonları bilmiyorsanız daha fazla bilgi için "Java Doc"'lara bakabilirisiniz:
Değerli ziyaretçimiz, içeriği görebilmek için şimdi giriş yapın veya kayıt olun.



Java:
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {

        if (sender instanceof Player){
            Player player = (Player) sender;

            ProtocolManager manager = ProtocolLibrary.getProtocolManager();

            player.getLineOfSight(null,25).stream().filter(block -> block.getType() != Material.AIR).forEach(block -> {


            });


        }

        return false;
    }

Ardından bloğumuzun lokasyonunu Location location = block.getLocation(); ile alıyoruz. Sonrasında bir PacketContainer oluşturuyoruz ancak bu sefer ProtocolManager objemizden createPacket(PacketType); fonksiyonunu kullanıyoruz:

Java:
PacketContainer container = manager.createPacket(PacketType.Play.Server.EXPLOSION);

Ardından gerekli yerleri .write(index, value) şeklinde dolduruyoruz:

Java:
                container.getDoubles().write(0,location.getX()); // X
                container.getDoubles().write(1,location.getY()); // Y
                container.getDoubles().write(2,location.getZ()); // Z

                container.getFloat().write(0,5.0f); // Büyükük
                container.getFloat().write(1,0.0f); // X ivmesi
                container.getFloat().write(2,5.0f); // Y ivmesi
                container.getFloat().write(3,0.0f); // Z ivmesi

Sonunda ise paketi oyuncuya gönderiyoruz:

Kod:
                try {
                    manager.sendServerPacket(player,container);
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

Eklentimizi çalıştırmadan önce yapmamız gereken son şey "plugin.yml" dosyasına "boom" komudunu eklemek olacaktır:

Kod:
commands:
  boom:
    description: Haha patlamalar goes brrr


Son Söz

ProtocolLib ile ilgili genel bilgiler bu kadardı. Öneriler ve yardım için Discord sunucumuza katılabilirsiniz. Herkese iyi forumlar dilerim <3

Değerli ziyaretçimiz, içeriği görebilmek için şimdi giriş yapın veya kayıt olun.

 

Ekli dosyalar

  • joinDiscord.png
    joinDiscord.png
    12 KB · Görüntüleme: 209
Yine çok başarılı, eline emeğine sağlık dostum.
 
Güzel konu olmuş detaylı ve açık. getLineOfSight() kısmında konu paket oluşturmanın biraz dışına çıkmış yazılımcıya sadece 'buraya blok listesini vericen' diyip geçmek lazım ama olsun. Üçüncü bölümünde clientside entity'leri görmeyi çok isterim.
 
Güzel konu olmuş detaylı ve açık. getLineOfSight() kısmında konu paket oluşturmanın biraz dışına çıkmış yazılımcıya sadece 'buraya blok listesini vericen' diyip geçmek lazım ama olsun. Üçüncü bölümünde clientside entity'leri görmeyi çok isterim.

Yorumunuz için teşekkürler ? NMS kısmında Clientside Entity'leri anlatmayı düşünüyorum. Vize haftam geldiği için NMS ile ilgili kursu biraz erteleyeceğim :<
 
Eline sağlık, kaydettim daha sonra detaylıca inceleyeceğim.
 
güzel ve sade bir şekilde anlatılmış eline emeğine sağlık
 
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...

Hala Discord sunucumuza katılmadın mı?

Büyük bir topluluğun parçası ol, etkinliklere katıl ve özel hediyeler kazanma şansı yakala!

Şimdi Katıl
Üst