- 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.
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)
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ó)
B4. Triệu Hồi thực thể mà bạn vừa mới tạo
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)
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 ^.^
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 ^.^




