• Chào bạn, hãy đăng ký hoặc đăng nhập để tham gia cùng bọn mình và sử dụng được đầy đủ chức năng của diễn đàn :).
undertalevn89

Java NMS Cho newbie

undertalevn89

THÀNH VIÊN
Tham gia
20/05/2022
Bài viết
4
*Lưu ý trước khi đọc bài post này bạn cần có các kiến thức căn bản về java cũng như là bukkitDev

1. NMS Là gì ?
NMS Màn ý nghĩa cho net.minecraft.server. Đây là nơi chứa toàn bộ code của 1 server minecraft (không bao gồm bukkiAPI).

2. Ưu điểm của NMS
Khi dùng NMS bạn có khả năng làm ra những thứ mà nếu chỉ sử dụng BukkitAPI không làm ra được:
- Chỉnh sửa hành động của các thực thể theo ý thích.
- Gửi và nhận packet.
- Chỉnh sửa cách thức tạo các công trình, kiến trúc..
- Nhanh hơn Bukkit/Spigot API rất nhiều lần.
- v.v..

3. Nhược điểm của NMS
NMS tuy là rất hữu ích nhưng nó gặp phải một số các vấn đề sau:
- NMS Rất khó để học.
- Các cú pháp rất lằng ngoằng.
- *Cách đặt tên cho các function cực kỳ khó hiểu (Vì nó là code bị decompile bởi Spigot/Bukkit).
- Sử dụng không cẩn thận có thể gây ảnh hưởng rới server.
- Không hỗ trợ nhiều phiên bản cho 1 plugin đc (VD: Khi Import nó sẽ như thế này net.minecraft.server.v_1_8_R1)


4. Làm thế nào để bắt đầu với NMS ?
Đọc đến đây tôi cá chắc là 70% sẽ không học vì những lí do đã nêu trên nhưng nếu bạn có hứng thú thì tôi sẽ hướng đẫn bạn :)
<-- Start -->
Để bắt đầu với NMS bạn cần file server của Spigot/Bukkit hoặc Vannila Minecraft (Không khuyến nghị).
Tiếp theo thêm file jar đó vào dự án của bạn.

B1. Hãy nói rằng chúng ta muốn tạo một con NPC theo ý thích của mình.

Java:
public class NPC extends EntityVillager {

    public NPC(World world) {
        super(world);


    }
}

B2. Tạo một cái goal cho nó (Chỉnh sửa cái gốc và thêm theo ý thíc của bạn)
Java:
    public CustomVillager(World world) {
            super (world);
  
          
  
            try {
                    Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
                    bField.setAccessible(true);
                    Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
                    cField.setAccessible(true);
          
                    bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
                    bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
                    cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
                    cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
            } catch (Exception e) {
                    e.printStackTrace();
            }   
  
            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this));
            this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 0.6D));
            this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F));
            this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityVillager.class, 5.0F, 0.02F));
            this.goalSelector.a(9, new PathfinderGoalRandomStroll(this, 0.6D));
            this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
    }

B3. Chỉnh sửa cái goal của nó theo ý thích thông qua việc Override (Chẳng hạn minh muốn nó)
Java:
@Override
    public void move(double d0, double d1, double d2) {
  
    }

    @Override
    public void collide(Entity entity) {
    }

    @Override
    public boolean damageEntity(DamageSource damagesource, float f) {
        return false;
    }

    @Override
    public void g(double d0, double d1, double d2) {
    }

B4. Triệu Hồi thực thể mà bạn vừa mới tạo
Java:
public static Villager spawn(Location loc){
        World mcWorld = ((CraftWorld) loc.getWorld()).getHandle();
        final NPC customEnt = new NPC(mcWorld);
        customEnt.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
        ((CraftLivingEntity) customEnt.getBukkitEntity()).setRemoveWhenFarAway(false); //Do we want to remove it when the NPC is far away? I won
        mcWorld.addEntity(customEnt, SpawnReason.CUSTOM);
        return (Villager) customEnt.getBukkitEntity();
    }

B5. Đăng kí thực thể của bạn vào server (Bạn cần phải call cái này trong #onEnable)
Java:
public void registerEntity(String name, int id, Class<? extends EntityInsentient> nmsClass, Class<? extends EntityInsentient> customClass){
        try {
    
            List<Map<?, ?>> dataMap = new ArrayList<Map<?, ?>>();
            for (Field f : EntityTypes.class.getDeclaredFields()){
                if (f.getType().getSimpleName().equals(Map.class.getSimpleName())){
                    f.setAccessible(true);
                    dataMap.add((Map<?, ?>) f.get(null));
                }
            }
    
            if (dataMap.get(2).containsKey(id)){
                dataMap.get(0).remove(name);
                dataMap.get(2).remove(id);
            }
    
            Method method = EntityTypes.class.getDeclaredMethod("a", Class.class, String.class, int.class);
            method.setAccessible(true);
            method.invoke(null, customClass, name, id);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Chúc mừng bạn đã tạo ra một thực thể theo ý thích của minh và đây là mọt số lưu ý:
- Cái String là tên của thực thể đó.
- Cái int là id của nó.
- Cái thứ 3 là cái class mà bạn đang Override lên.
- Cái thứ 4 là cái class mà bạn vừa mới làm :)

Bạn có thể tìm các Tên / ID Của thực thể mc ở đây: minecraft.gamepedia.com

5. Q&A
- Tại sao NMS lại bị decompile ?
Vì minecraft ko phải là 1 game opensrc nên phải decompile mới sử dụng code của nó.
Cũng vì lí do đó mà các cú pháp của nó rất khó hiểu BT: move(), Decompiled: a() , b(), ab(),...
[Trước 1.14.4]

- Nếu bạn cần gì thì cứ hỏi thêm ở phần bình luận mình sẽ trả lời ^.^
 
Rất hữu ích nhưng mà Paper có sẵn tool để làm trò này với official mappings bạn ạ. Cụm NMS chỉ là cách gọi legacy thôi, còn đối với các modder dùng Forge hay Fabric thì bắt buộc phải biết.
 
Hú hú khẹc khẹc

Nếu nms của phiên bản cao thì dùng paperweight.userdev
 
Cách đặt tên cho các function cực kỳ khó hiểu (Vì nó là code bị decompile bởi Spigot/Bukkit)
Thêm nữa CraftBukkit ( Cụ tổ của Tất cả các loại Server sử dụng bukkit API) bị kiện và cái github repo của họ bị xóa bởi Mojang vì lí do bản quyển :
Cái này sai rồi nhé
- Craftbukkit là server implementation, còn bukkit api nếu để ý kĩ thì nó thiết kế theo interface để craftbukkit implement vào

- Không có ai bị kiện cả, Craftbukkit không trực tiếp can thiệp hay công khai source code của minecraft server mà sử dụng kĩ thuật patching.

Nếu bạn vào repo của spigot hay paper, sẽ thấy có các file .patch, mỗi patch là một commit chỉnh sửa lên server code của minecraft. (Tham khảo Paperclip để biết thêm)

- Sau khi cộng đồng biết về chuyện Mojang sở hữu Bukkit được giấu kín 2 năm, một developer của dự án với contribution cao, cảm thấy mình bị phản bội nên đã issue DMCA report để gỡ hết những sản phẩm của mình
 
Rất hữu ích nhưng mà Paper có sẵn tool để làm trò này với official mappings bạn ạ. Cụm NMS chỉ là cách gọi legacy thôi, còn đối với các modder dùng Forge hay Fabric thì bắt buộc phải biết.
Cảm ơn đã bổ sung thêm vào bài viết này giúp tôi. Tôi ko biết là Paper có lun á. Đa số tôi toàn gọi trực tiếp ko à.
 
Example code cũng hơi khó hiểu, mình đọc mà không hiểu bạn đang Override class nào, nếu rảnh thì bạn chỉnh sửa lại và ghi kèm cả import nữa nhé
 

Cái này sai rồi nhé
- Craftbukkit là server implementation, còn bukkit api nếu để ý kĩ thì nó thiết kế theo interface để craftbukkit implement vào

- Không có ai bị kiện cả, Craftbukkit không trực tiếp can thiệp hay công khai source code của minecraft server mà sử dụng kĩ thuật patching.

Nếu bạn vào repo của spigot hay paper, sẽ thấy có các file .patch, mỗi patch là một commit chỉnh sửa lên server code của minecraft. (Tham khảo Paperclip để biết thêm)

- Sau khi cộng đồng biết về chuyện Mojang sở hữu Bukkit được giấu kín 2 năm, một developer của dự án với contribution cao, cảm thấy mình bị phản bội nên đã issue DMCA report để gỡ hết những sản phẩm của mình
Ok Xin lỗi vì các sai sót nha. Tôi viết nhanh qua nên ko để ý kỹ đến mấy chuyện ấy :(
 
còn mojang mappings là gì hả b, mình đọc nhiều tài liệu mà ko hiểu lắm
 
Similar content Most view Xem thêm
Back
Top Bottom