[Tutorial|1.6.4] Decompiling Minecraft's server.jar (And why you should)

Discussion in 'Resources' started by krazytraynz, Dec 2, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    krazytraynz

    Using my minuscule client modding experience, I decided to try decompiling Minecraft's server.jar using the Minecraft Coder Pack to see what I would get, and it was totally worth it. You may be asking yourself - Why would I decompile the Minecraft server, when it's already uploaded on github? Let's do a quick comparison, using EntitySkeleton.java.

    On Github:
    Show Spoiler

    Code:java
    1. package net.minecraft.server;
    2.  
    3. import java.util.Calendar;
    4.  
    5. public class EntitySkeleton extends EntityMonster implements IRangedEntity {
    6.  
    7. private PathfinderGoalArrowAttack bp = new PathfinderGoalArrowAttack(this, 1.0D, 20, 60, 15.0F);
    8. private PathfinderGoalMeleeAttack bq = new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.2D, false);
    9.  
    10. public EntitySkeleton(World world) {
    11. super(world);
    12. this.goalSelector.a(1, new PathfinderGoalFloat(this));
    13. this.goalSelector.a(2, new PathfinderGoalRestrictSun(this));
    14. this.goalSelector.a(3, new PathfinderGoalFleeSun(this, 1.0D));
    15. this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D));
    16. this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
    17. this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this));
    18. this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false));
    19. this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 0, true));
    20. if (world != null && !world.isStatic) {
    21. this.bT();
    22. }
    23. }
    24.  
    25. protected void az() {
    26. super.az();
    27. this.getAttributeInstance(GenericAttributes.d).setValue(0.25D);
    28. }
    29.  
    30. protected void a() {
    31. super.a();
    32. this.datawatcher.a(13, new Byte((byte) 0));
    33. }
    34.  
    35. public boolean bf() {
    36. return true;
    37. }
    38.  
    39. protected String r() {
    40. return "mob.skeleton.say";
    41. }
    42.  
    43. protected String aO() {
    44. return "mob.skeleton.hurt";
    45. }
    46.  
    47. protected String aP() {
    48. return "mob.skeleton.death";
    49. }
    50.  
    51. protected void a(int i, int j, int k, int l) {
    52. this.makeSound("mob.skeleton.step", 0.15F, 1.0F);
    53. }
    54.  
    55. public boolean m(Entity entity) {
    56. if (super.m(entity)) {
    57. if (this.getSkeletonType() == 1 && entity instanceof EntityLiving) {
    58. ((EntityLiving) entity).addEffect(new MobEffect(MobEffectList.WITHER.id, 200));
    59. }
    60.  
    61. return true;
    62. } else {
    63. return false;
    64. }
    65. }
    66.  
    67. public EnumMonsterType getMonsterType() {
    68. return EnumMonsterType.UNDEAD;
    69. }
    70.  
    71. public void c() {
    72. if (this.world.v() && !this.world.isStatic) {
    73. float f = this.d(1.0F);
    74.  
    75. if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.l(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ))) {
    76. boolean flag = true;
    77. ItemStack itemstack = this.getEquipment(4);
    78.  
    79. if (itemstack != null) {
    80. if (itemstack.g()) {
    81. itemstack.setData(itemstack.j() + this.random.nextInt(2));
    82. if (itemstack.j() >= itemstack.l()) {
    83. this.a(itemstack);
    84. this.setEquipment(4, (ItemStack) null);
    85. }
    86. }
    87.  
    88. flag = false;
    89. }
    90.  
    91. if (flag) {
    92. this.setOnFire(8);
    93. }
    94. }
    95. }
    96.  
    97. if (this.world.isStatic && this.getSkeletonType() == 1) {
    98. this.a(0.72F, 2.34F);
    99. }
    100.  
    101. super.c();
    102. }
    103.  
    104. public void V() {
    105. super.V();
    106. if (this.vehicle instanceof EntityCreature) {
    107. EntityCreature entitycreature = (EntityCreature) this.vehicle;
    108.  
    109. this.aN = entitycreature.aN;
    110. }
    111. }
    112.  
    113. public void die(DamageSource damagesource) {
    114. super.die(damagesource);
    115. if (damagesource.h() instanceof EntityArrow && damagesource.getEntity() instanceof EntityHuman) {
    116. EntityHuman entityhuman = (EntityHuman) damagesource.getEntity();
    117. double d0 = entityhuman.locX - this.locX;
    118. double d1 = entityhuman.locZ - this.locZ;
    119.  
    120. if (d0 * d0 + d1 * d1 >= 2500.0D) {
    121. entityhuman.a((Statistic) AchievementList.v);
    122. }
    123. }
    124. }
    125.  
    126. protected int getLootId() {
    127. return Item.ARROW.id;
    128. }
    129.  
    130. protected void dropDeathLoot(boolean flag, int i) {
    131. int j;
    132. int k;
    133.  
    134. if (this.getSkeletonType() == 1) {
    135. j = this.random.nextInt(3 + i) - 1;
    136.  
    137. for (k = 0; k < j; ++k) {
    138. this.b(Item.COAL.id, 1);
    139. }
    140. } else {
    141. j = this.random.nextInt(3 + i);
    142.  
    143. for (k = 0; k < j; ++k) {
    144. this.b(Item.ARROW.id, 1);
    145. }
    146. }
    147.  
    148. j = this.random.nextInt(3 + i);
    149.  
    150. for (k = 0; k < j; ++k) {
    151. this.b(Item.BONE.id, 1);
    152. }
    153. }
    154.  
    155. protected void l(int i) {
    156. if (this.getSkeletonType() == 1) {
    157. this.a(new ItemStack(Item.SKULL.id, 1, 1), 0.0F);
    158. }
    159. }
    160.  
    161. protected void bw() {
    162. super.bw();
    163. this.setEquipment(0, new ItemStack(Item.BOW));
    164. }
    165.  
    166. public GroupDataEntity a(GroupDataEntity groupdataentity) {
    167. groupdataentity = super.a(groupdataentity);
    168. if (this.world.worldProvider instanceof WorldProviderHell && this.aD().nextInt(5) > 0) {
    169. this.goalSelector.a(4, this.bq);
    170. this.setSkeletonType(1);
    171. this.setEquipment(0, new ItemStack(Item.STONE_SWORD));
    172. this.getAttributeInstance(GenericAttributes.e).setValue(4.0D);
    173. } else {
    174. this.goalSelector.a(4, this.bp);
    175. this.bw();
    176. this.bx();
    177. }
    178.  
    179. this.h(this.random.nextFloat() < 0.55F * this.world.b(this.locX, this.locY, this.locZ));
    180. if (this.getEquipment(4) == null) {
    181. Calendar calendar = this.world.W();
    182.  
    183. if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.random.nextFloat() < 0.25F) {
    184. this.setEquipment(4, new ItemStack(this.random.nextFloat() < 0.1F ? Block.JACK_O_LANTERN : Block.PUMPKIN));
    185. this.dropChances[4] = 0.0F;
    186. }
    187. }
    188.  
    189. return groupdataentity;
    190. }
    191.  
    192. public void bT() {
    193. this.goalSelector.a((PathfinderGoal) this.bq);
    194. this.goalSelector.a((PathfinderGoal) this.bp);
    195. ItemStack itemstack = this.aZ();
    196.  
    197. if (itemstack != null && itemstack.id == Item.BOW.id) {
    198. this.goalSelector.a(4, this.bp);
    199. } else {
    200. this.goalSelector.a(4, this.bq);
    201. }
    202. }
    203.  
    204. public void a(EntityLiving entityliving, float f) {
    205. EntityArrow entityarrow = new EntityArrow(this.world, this, entityliving, 1.6F, (float) (14 - this.world.difficulty * 4));
    206. int i = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_DAMAGE.id, this.aZ());
    207. int j = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_KNOCKBACK.id, this.aZ());
    208.  
    209. entityarrow.b((double) (f * 2.0F) + this.random.nextGaussian() * 0.25D + (double) ((float) this.world.difficulty * 0.11F));
    210. if (i > 0) {
    211. entityarrow.b(entityarrow.c() + (double) i * 0.5D + 0.5D);
    212. }
    213.  
    214. if (j > 0) {
    215. entityarrow.a(j);
    216. }
    217.  
    218. if (EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_FIRE.id, this.aZ()) > 0 || this.getSkeletonType() == 1) {
    219. entityarrow.setOnFire(100);
    220. }
    221.  
    222. this.makeSound("random.bow", 1.0F, 1.0F / (this.aD().nextFloat() * 0.4F + 0.8F));
    223. this.world.addEntity(entityarrow);
    224. }
    225.  
    226. public int getSkeletonType() {
    227. return this.datawatcher.getByte(13);
    228. }
    229.  
    230. public void setSkeletonType(int i) {
    231. this.datawatcher.watch(13, Byte.valueOf((byte) i));
    232. this.fireProof = i == 1;
    233. if (i == 1) {
    234. this.a(0.72F, 2.34F);
    235. } else {
    236. this.a(0.6F, 1.8F);
    237. }
    238. }
    239.  
    240. public void a(NBTTagCompound nbttagcompound) {
    241. super.a(nbttagcompound);
    242. if (nbttagcompound.hasKey("SkeletonType")) {
    243. byte b0 = nbttagcompound.getByte("SkeletonType");
    244.  
    245. this.setSkeletonType(b0);
    246. }
    247.  
    248. this.bT();
    249. }
    250.  
    251. public void b(NBTTagCompound nbttagcompound) {
    252. super.b(nbttagcompound);
    253. nbttagcompound.setByte("SkeletonType", (byte) this.getSkeletonType());
    254. }
    255.  
    256. public void setEquipment(int i, ItemStack itemstack) {
    257. super.setEquipment(i, itemstack);
    258. if (!this.world.isStatic && i == 0) {
    259. this.bT();
    260. }
    261. }
    262.  
    263. public double X() {
    264. return super.X() - 0.5D;
    265. }
    266. }



    Decompiled with MCP:
    Show Spoiler

    Code:java
    1. package net.minecraft.src;
    2.  
    3. import java.util.Calendar;
    4.  
    5. public class EntitySkeleton extends EntityMob implements IRangedAttackMob
    6. {
    7. private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
    8. private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
    9.  
    10. public EntitySkeleton(World par1World)
    11. {
    12. super(par1World);
    13. this.tasks.addTask(1, new EntityAISwimming(this));
    14. this.tasks.addTask(2, new EntityAIRestrictSun(this));
    15. this.tasks.addTask(3, new EntityAIFleeSun(this, 1.0D));
    16. this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
    17. this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
    18. this.tasks.addTask(6, new EntityAILookIdle(this));
    19. this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
    20. this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
    21.  
    22. if (par1World != null && !par1World.isRemote)
    23. {
    24. this.setCombatTask();
    25. }
    26. }
    27.  
    28. protected void applyEntityAttributes()
    29. {
    30. super.applyEntityAttributes();
    31. this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setAttribute(0.25D);
    32. }
    33.  
    34. protected void entityInit()
    35. {
    36. super.entityInit();
    37. this.dataWatcher.addObject(13, new Byte((byte)0));
    38. }
    39.  
    40. /**
    41.   * Returns true if the newer Entity AI code should be run
    42.   */
    43. public boolean isAIEnabled()
    44. {
    45. return true;
    46. }
    47.  
    48. /**
    49.   * Returns the sound this mob makes while it's alive.
    50.   */
    51. protected String getLivingSound()
    52. {
    53. return "mob.skeleton.say";
    54. }
    55.  
    56. /**
    57.   * Returns the sound this mob makes when it is hurt.
    58.   */
    59. protected String getHurtSound()
    60. {
    61. return "mob.skeleton.hurt";
    62. }
    63.  
    64. /**
    65.   * Returns the sound this mob makes on death.
    66.   */
    67. protected String getDeathSound()
    68. {
    69. return "mob.skeleton.death";
    70. }
    71.  
    72. /**
    73.   * Plays step sound at given x, y, z for the entity
    74.   */
    75. protected void playStepSound(int par1, int par2, int par3, int par4)
    76. {
    77. this.playSound("mob.skeleton.step", 0.15F, 1.0F);
    78. }
    79.  
    80. public boolean attackEntityAsMob(Entity par1Entity)
    81. {
    82. if (super.attackEntityAsMob(par1Entity))
    83. {
    84. if (this.getSkeletonType() == 1 && par1Entity instanceof EntityLivingBase)
    85. {
    86. ((EntityLivingBase)par1Entity).addPotionEffect(new PotionEffect(Potion.wither.id, 200));
    87. }
    88.  
    89. return true;
    90. }
    91. else
    92. {
    93. return false;
    94. }
    95. }
    96.  
    97. /**
    98.   * Get this Entity's EnumCreatureAttribute
    99.   */
    100. public EnumCreatureAttribute getCreatureAttribute()
    101. {
    102. return EnumCreatureAttribute.UNDEAD;
    103. }
    104.  
    105. /**
    106.   * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    107.   * use this to react to sunlight and start to burn.
    108.   */
    109. public void onLivingUpdate()
    110. {
    111. if (this.worldObj.isDaytime() && !this.worldObj.isRemote)
    112. {
    113. float var1 = this.getBrightness(1.0F);
    114.  
    115. if (var1 > 0.5F && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)))
    116. {
    117. boolean var2 = true;
    118. ItemStack var3 = this.getEquipmentInSlot(4);
    119.  
    120. if (var3 != null)
    121. {
    122. if (var3.isItemStackDamageable())
    123. {
    124. var3.setItemDamage(var3.getItemDamageForDisplay() + this.rand.nextInt(2));
    125.  
    126. if (var3.getItemDamageForDisplay() >= var3.getMaxDamage())
    127. {
    128. this.renderBrokenItemStack(var3);
    129. this.setCurrentItemOrArmor(4, (ItemStack)null);
    130. }
    131. }
    132.  
    133. var2 = false;
    134. }
    135.  
    136. if (var2)
    137. {
    138. this.setFire(8);
    139. }
    140. }
    141. }
    142.  
    143. if (this.worldObj.isRemote && this.getSkeletonType() == 1)
    144. {
    145. this.setSize(0.72F, 2.34F);
    146. }
    147.  
    148. super.onLivingUpdate();
    149. }
    150.  
    151. /**
    152.   * Handles updating while being ridden by an entity
    153.   */
    154. public void updateRidden()
    155. {
    156. super.updateRidden();
    157.  
    158. if (this.ridingEntity instanceof EntityCreature)
    159. {
    160. EntityCreature var1 = (EntityCreature)this.ridingEntity;
    161. this.renderYawOffset = var1.renderYawOffset;
    162. }
    163. }
    164.  
    165. /**
    166.   * Called when the mob's health reaches 0.
    167.   */
    168. public void onDeath(DamageSource par1DamageSource)
    169. {
    170. super.onDeath(par1DamageSource);
    171.  
    172. if (par1DamageSource.getSourceOfDamage() instanceof EntityArrow && par1DamageSource.getEntity() instanceof EntityPlayer)
    173. {
    174. EntityPlayer var2 = (EntityPlayer)par1DamageSource.getEntity();
    175. double var3 = var2.posX - this.posX;
    176. double var5 = var2.posZ - this.posZ;
    177.  
    178. if (var3 * var3 + var5 * var5 >= 2500.0D)
    179. {
    180. var2.triggerAchievement(AchievementList.snipeSkeleton);
    181. }
    182. }
    183. }
    184.  
    185. /**
    186.   * Returns the item ID for the item the mob drops on death.
    187.   */
    188. protected int getDropItemId()
    189. {
    190. return Item.arrow.itemID;
    191. }
    192.  
    193. /**
    194.   * Drop 0-2 items of this living's type
    195.   */
    196. protected void dropFewItems(boolean par1, int par2)
    197. {
    198. int var3;
    199. int var4;
    200.  
    201. if (this.getSkeletonType() == 1)
    202. {
    203. var3 = this.rand.nextInt(3 + par2) - 1;
    204.  
    205. for (var4 = 0; var4 < var3; ++var4)
    206. {
    207. this.dropItem(Item.coal.itemID, 1);
    208. }
    209. }
    210. else
    211. {
    212. var3 = this.rand.nextInt(3 + par2);
    213.  
    214. for (var4 = 0; var4 < var3; ++var4)
    215. {
    216. this.dropItem(Item.arrow.itemID, 1);
    217. }
    218. }
    219.  
    220. var3 = this.rand.nextInt(3 + par2);
    221.  
    222. for (var4 = 0; var4 < var3; ++var4)
    223. {
    224. this.dropItem(Item.bone.itemID, 1);
    225. }
    226. }
    227.  
    228. protected void dropRareDrop(int par1)
    229. {
    230. if (this.getSkeletonType() == 1)
    231. {
    232. this.entityDropItem(new ItemStack(Item.skull.itemID, 1, 1), 0.0F);
    233. }
    234. }
    235.  
    236. /**
    237.   * Makes entity wear random armor based on difficulty
    238.   */
    239. protected void addRandomArmor()
    240. {
    241. super.addRandomArmor();
    242. this.setCurrentItemOrArmor(0, new ItemStack(Item.bow));
    243. }
    244.  
    245. public EntityLivingData onSpawnWithEgg(EntityLivingData par1EntityLivingData)
    246. {
    247. par1EntityLivingData = super.onSpawnWithEgg(par1EntityLivingData);
    248.  
    249. if (this.worldObj.provider instanceof WorldProviderHell && this.getRNG().nextInt(5) > 0)
    250. {
    251. this.tasks.addTask(4, this.aiAttackOnCollide);
    252. this.setSkeletonType(1);
    253. this.setCurrentItemOrArmor(0, new ItemStack(Item.swordStone));
    254. this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setAttribute(4.0D);
    255. }
    256. else
    257. {
    258. this.tasks.addTask(4, this.aiArrowAttack);
    259. this.addRandomArmor();
    260. this.enchantEquipment();
    261. }
    262.  
    263. this.setCanPickUpLoot(this.rand.nextFloat() < 0.55F * this.worldObj.getLocationTensionFactor(this.posX, this.posY, this.posZ));
    264.  
    265. if (this.getEquipmentInSlot(4) == null)
    266. {
    267. Calendar var2 = this.worldObj.getCurrentDate();
    268.  
    269. if (var2.get(2) + 1 == 10 && var2.get(5) == 31 && this.rand.nextFloat() < 0.25F)
    270. {
    271. this.setCurrentItemOrArmor(4, new ItemStack(this.rand.nextFloat() < 0.1F ? Block.pumpkinLantern : Block.pumpkin));
    272. this.equipmentDropChances[4] = 0.0F;
    273. }
    274. }
    275.  
    276. return par1EntityLivingData;
    277. }
    278.  
    279. /**
    280.   * sets this entity's combat AI.
    281.   */
    282. public void setCombatTask()
    283. {
    284. this.tasks.removeTask(this.aiAttackOnCollide);
    285. this.tasks.removeTask(this.aiArrowAttack);
    286. ItemStack var1 = this.getHeldItem();
    287.  
    288. if (var1 != null && var1.itemID == Item.bow.itemID)
    289. {
    290. this.tasks.addTask(4, this.aiArrowAttack);
    291. }
    292. else
    293. {
    294. this.tasks.addTask(4, this.aiAttackOnCollide);
    295. }
    296. }
    297.  
    298. /**
    299.   * Attack the specified entity using a ranged attack.
    300.   */
    301. public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
    302. {
    303. EntityArrow var3 = new EntityArrow(this.worldObj, this, par1EntityLivingBase, 1.6F, (float)(14 - this.worldObj.difficultySetting * 4));
    304. int var4 = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem());
    305. int var5 = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem());
    306. var3.setDamage((double)(par2 * 2.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.difficultySetting * 0.11F));
    307.  
    308. if (var4 > 0)
    309. {
    310. var3.setDamage(var3.getDamage() + (double)var4 * 0.5D + 0.5D);
    311. }
    312.  
    313. if (var5 > 0)
    314. {
    315. var3.setKnockbackStrength(var5);
    316. }
    317.  
    318. if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0 || this.getSkeletonType() == 1)
    319. {
    320. var3.setFire(100);
    321. }
    322.  
    323. this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F));
    324. this.worldObj.spawnEntityInWorld(var3);
    325. }
    326.  
    327. /**
    328.   * Return this skeleton's type.
    329.   */
    330. public int getSkeletonType()
    331. {
    332. return this.dataWatcher.getWatchableObjectByte(13);
    333. }
    334.  
    335. /**
    336.   * Set this skeleton's type.
    337.   */
    338. public void setSkeletonType(int par1)
    339. {
    340. this.dataWatcher.updateObject(13, Byte.valueOf((byte)par1));
    341. this.isImmuneToFire = par1 == 1;
    342.  
    343. if (par1 == 1)
    344. {
    345. this.setSize(0.72F, 2.34F);
    346. }
    347. else
    348. {
    349. this.setSize(0.6F, 1.8F);
    350. }
    351. }
    352.  
    353. /**
    354.   * (abstract) Protected helper method to read subclass entity data from NBT.
    355.   */
    356. public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    357. {
    358. super.readEntityFromNBT(par1NBTTagCompound);
    359.  
    360. if (par1NBTTagCompound.hasKey("SkeletonType"))
    361. {
    362. byte var2 = par1NBTTagCompound.getByte("SkeletonType");
    363. this.setSkeletonType(var2);
    364. }
    365.  
    366. this.setCombatTask();
    367. }
    368.  
    369. /**
    370.   * (abstract) Protected helper method to write subclass entity data to NBT.
    371.   */
    372. public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    373. {
    374. super.writeEntityToNBT(par1NBTTagCompound);
    375. par1NBTTagCompound.setByte("SkeletonType", (byte)this.getSkeletonType());
    376. }
    377.  
    378. /**
    379.   * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
    380.   */
    381. public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack)
    382. {
    383. super.setCurrentItemOrArmor(par1, par2ItemStack);
    384.  
    385. if (!this.worldObj.isRemote && par1 == 0)
    386. {
    387. this.setCombatTask();
    388. }
    389. }
    390.  
    391. /**
    392.   * Returns the Y Offset of this entity.
    393.   */
    394. public double getYOffset()
    395. {
    396. return super.getYOffset() - 0.5D;
    397. }
    398. }
    399.  



    See the difference? The methods and variables have actual names, and there's even handy little comments explaining some of them. If this class alone doesn't convince you, I don't know what will. With this in mind, let's get started.

    Step 1: Downloading the Minecraft Coder Pack

    The Minecraft Coder Pack (MCP) is a tool used by anyone who is interested in producing client mods. It decompiles your minecraft.jar into readable .java files. You can download it from the official MCP website, and just extract the .zip file to whatever directory you please.

    Step 2: Configuring MCP for decompiling.

    When you look into the extracted folder, you'll notice a large array of folders, batch files, and shell scripts. This step only requires the "jars" folder, everything else can be ignored for now. Download minecraft_server.jar for whichever version you please (versions below 1.7.2 can be found here), and copy/paste it into the jars folder of MCP. Copy/paste your bin and resources folder from your .minecraft folder into the jars folder as well, as I'm 99% sure MCP won't decompile your jars without it.

    Step 3: Decompiling your jars

    After you've placed your folders/jars in the proper directory, just run decompile.bat, and let MCP work its magic. You may get a couple of errors, just ignore them.

    Step 4: Opening the files in Eclipse

    Assuming that everything decompiled correctly, all you have to do now is open Eclipse using the "eclipse" folder in MCP as your workspace.



    Congratulations! You've successfully decompiled the Minecraft server.jar, and now are ready to bask in the glory of understandable code. Keep in mind that you can't use the method names in the decompiled files, you'll have to match up the methods using the ones on the mc-dev github. Hopefully this will make it easier for people to learn how to do things like creating custom entities, which use a lot of NMS methods. Obviously, all code in this tutorial is copyrighted by Mojang AB. Happy Coding!
     
  2. Offline

    BungeeTheCookie

    MCPC isn't even out for 1.7 -_-
     
  3. Offline

    krazytraynz

    Bukkit doesn't have an officially stable build for 1.7 either, not everyone has switched over.
     
  4. Offline

    BungeeTheCookie

    At least bukkit has a build :)
     
  5. Offline

    Ultimate_n00b

    Though MCPC isn't out for 1.7, md_5 has a public repository for mc-dev (1.7).
     
  6. Offline

    Minecrell

    Actually, there is an alpha version of MCP 1.7 now for about 2 weeks. (Can only deobfuscate and decompile, not reobfuscate). I didn't test decompiling the server but the client has worked for me.
     
Thread Status:
Not open for further replies.

Share This Page