Minecraft正版点macbook自动登录灰色一直是灰色怎么办 还有就是改名字一直是错误改不了

购买正版Minecraft无法付款怎么办?一直说系统错误 如图_百度知道
购买正版Minecraft无法付款怎么办?一直说系统错误 如图
我有更好的答案
国外网站是不支持国内一般的借记卡支付的,如果你有信用卡的话最好(如果可以的话让父母帮忙),或者找代购,就是要多收点钱,但是挺方便.
采纳率:73%
买啥啊单机游戏还买脑残吧游民就能下载
撒比啊,你买不起也不懂,别瞎比比
撒比啊,你买不起也不懂,别瞎比比
找代购,支持正版的赞一个
呵呵楼上的逗比你说世界上能一次打破12项难得吉尼斯纪录的游戏是单机?
其他1条回答
为您推荐:
其他类似问题
minecraft的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。后使用快捷导航没有帐号?
您尚未登录,请登录后浏览更多内容!
只需一步,快速开始
请完成以下验证码
只需一步,快速开始
请完成以下验证码
请完成以下验证码
查看: 5566|回复: 13
【正版福利】正版可以改名字滴哟{每30天一次}
阅读权限100
在线时间 小时
TA的每日心情无聊 17:31签到天数: 302 天[LV.8]以坛为家I
https://account.mojang.com/ 点击Login
然后将邮箱账号与密码填入,确定后会发现Minecraft一行(mojang并不是只有mc这个游戏)看到自已的游戏名,旁边有一个change 点击一下并填写要修改的名字!即可~
阅读权限70
在线时间 小时
TA的每日心情难过 21:09签到天数: 489 天[LV.9]以坛为家II
我觉得你上了图会更加明白
你(づ ̄3 ̄)づ╭?~我我就上图&
阅读权限100
在线时间 小时
TA的每日心情无聊 17:31签到天数: 302 天[LV.8]以坛为家I
EDC 发表于
我觉得你上了图会更加明白
你(づ ̄3 ̄)づ╭?~我我就上图
阅读权限70
在线时间 小时
TA的每日心情难过 21:09签到天数: 489 天[LV.9]以坛为家II
grim_fly 发表于
你(づ ̄3 ̄)づ╭?~我我就上图
(づ ̄3 ̄)づ╭?~
你是男的》?!&
阅读权限100
在线时间 小时
TA的每日心情无聊 17:31签到天数: 302 天[LV.8]以坛为家I
EDC 发表于
(づ ̄3 ̄)づ╭?~
你是男的》?!
阅读权限70
在线时间 小时
TA的每日心情难过 21:09签到天数: 489 天[LV.9]以坛为家II
grim_fly 发表于
你是男的》?!
对啊(づ ̄3 ̄)づ╭?~
那 我们好像成为了一对基佬&
阅读权限100
在线时间 小时
TA的每日心情无聊 17:31签到天数: 302 天[LV.8]以坛为家I
EDC 发表于
对啊(づ ̄3 ̄)づ╭?~
那& & 我们好像成为了一对基佬
(づ ̄3 ̄)づ╭?~
三个基佬是一家&
阅读权限70
在线时间 小时
TA的每日心情难过 21:09签到天数: 489 天[LV.9]以坛为家II
grim_fly 发表于
那& & 我们好像成为了一对基佬
没事(づ ̄3 ̄)づ╭?~摸摸大
好吧 拿来QQ X聊吧&
阅读权限100
在线时间 小时
TA的每日心情无聊 17:31签到天数: 302 天[LV.8]以坛为家I
EDC 发表于
没事(づ ̄3 ̄)づ╭?~摸摸大
好吧& &拿来QQ&&X聊吧
阅读权限150
在线时间 小时
TA的每日心情开心 05:18签到天数: 1283 天[LV.10]以坛为家III
现在Mojang更新了以后,已经可以改名字了我的世界正版改名字_百度知道
我的世界正版改名字
我今天想改个名字,输入正确名字{名字没有冲突的}和正确密码后他给我说我密码错了是为什么呀?你们能改名吗
我有更好的答案
你可以参考[]的经验:
不能哎~!好像要翻墙(MC官网加了个谷歌验证)
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。从编程的角度来看,Minecraft 是怎么样设计的? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。<strong class="NumberBoard-itemValue" title="被浏览<strong class="NumberBoard-itemValue" title="7,943分享邀请回答protected void mouseClicked(int x, int y, int enable)
if (enable == 0)
for (int l = 0; l & this.buttonList.size(); ++l)
GuiButton guibutton = (GuiButton)this.buttonList.get(l);
if (guibutton.mousePressed(this.mc, x, y))
this.selectedButton = guibutton;
guibutton.playsound(this.mc.getSoundHandler());
this.actionPerformed(guibutton);
GuiButton.mousePressed()长这样:public boolean mousePressed(Minecraft p__, int p__, int p__)
return this.enabled && this.visible && p__ &= this.xPosition && p__ &= this.yPosition && p__ & this.xPosition + this.width && p__ & this.yPosition + this.
对,根本没有事件,也没有回调,逻辑必须在主窗口类的actionPerformed里处理,这是上个世纪90年代的写法。所以说稍微有点档次的mod都要重写GUI,因为MC本来写的真是太难看了。(顺便一提,forge用ASM在这里生插进去了一个事件,虽然这个事件会把别人的按钮事件也发送给你。所以还算有事件可用,但是这就不算MC本身写的了。)2、注册我又回头看了看,注册这个问题很大,所以我决定不止讲那个硬编码的部分,展开说。首先就是一段硬编码的注册代码。这是Block类里的:public static void registerBlocks()
blockRegistry.addObject(0, "air", (new BlockAir()).setBlockName("air"));
blockRegistry.addObject(1, "stone", (new BlockStone()).setHardness(1.5F).setResistance(10.0F).setStepSound(soundTypePiston).setBlockName("stone").setBlockTextureName("stone"));
blockRegistry.addObject(2, "grass", (new BlockGrass()).setHardness(0.6F).setStepSound(soundTypeGrass).setBlockName("grass").setBlockTextureName("grass"));
blockRegistry.addObject(3, "dirt", (new BlockDirt()).setHardness(0.5F).setStepSound(soundTypeGravel).setBlockName("dirt").setBlockTextureName("dirt"));
Block block = (new Block(Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundTypePiston).setBlockName("stonebrick").setCreativeTab(CreativeTabs.tabBlock).setBlockTextureName("cobblestone");
blockRegistry.addObject(4, "cobblestone", block);
Block block1 = (new BlockWood()).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setBlockName("wood").setBlockTextureName("planks");
blockRegistry.addObject(5, "planks", block1);
blockRegistry.addObject(6, "sapling", (new BlockSapling()).setHardness(0.0F).setStepSound(soundTypeGrass).setBlockName("sapling").setBlockTextureName("sapling"));
blockRegistry.addObject(7, "bedrock", (new Block(Material.rock)).setBlockUnbreakable().setResistance(F).setStepSound(soundTypePiston).setBlockName("bedrock").disableStats().setCreativeTab(CreativeTabs.tabBlock).setBlockTextureName("bedrock"));
blockRegistry.addObject(8, "flowing_water", (new BlockDynamicLiquid(Material.water)).setHardness(100.0F).setLightOpacity(3).setBlockName("water").disableStats().setBlockTextureName("water_flow"));
blockRegistry.addObject(9, "water", (new BlockStaticLiquid(Material.water)).setHardness(100.0F).setLightOpacity(3).setBlockName("water").disableStats().setBlockTextureName("water_still"));
blockRegistry.addObject(10, "flowing_lava", (new BlockDynamicLiquid(Material.lava)).setHardness(100.0F).setLightLevel(1.0F).setBlockName("lava").disableStats().setBlockTextureName("lava_flow"));
blockRegistry.addObject(11, "lava", (new BlockStaticLiquid(Material.lava)).setHardness(100.0F).setLightLevel(1.0F).setBlockName("lava").disableStats().setBlockTextureName("lava_still"));
blockRegistry.addObject(12, "sand", (new BlockSand()).setHardness(0.5F).setStepSound(soundTypeSand).setBlockName("sand").setBlockTextureName("sand"));
blockRegistry.addObject(13, "gravel", (new BlockGravel()).setHardness(0.6F).setStepSound(soundTypeGravel).setBlockName("gravel").setBlockTextureName("gravel"));
blockRegistry.addObject(14, "gold_ore", (new BlockOre()).setHardness(3.0F).setResistance(5.0F).setStepSound(soundTypePiston).setBlockName("oreGold").setBlockTextureName("gold_ore"));
后面不往下写了,都是这样,直到把所有方块注册完。这是flash小游戏的写法吧。不过硬编码和硬编码也不一样。你应该注意一下细节,blockRegistry.addObject()的第一个参数是一个int,它是方块的序号。在RegistryNamespaced里,这个序号作map的key值。序号硬编码会造成什么恶果呢?对,序号冲突。自己改序号不好改(所以你看到MC从来没有删除过物品或者方块,也没有在中间添加过,因为会导致序号改变),别人加物品更头痛。所以1.6以及之前,mod一直有一个序号冲突的问题。那么在1.7是否解决了序号问题呢?实际上,没有。1.7的方块问题最大的改动是加进了一个UnlocalizedName,意思就是说你以后用这个名字来找方块,但是实际上代码内部还是用int编号硬编码。而1.8最大的改动是让你在游戏内命令里不能按照序号give方块了,而代码内部还是跟上面没什么区别,用int硬编码。于是在1.7,fml加进了自动分配序号的功能:package cpw.mods.fml.common.registry;
private int registerBlock(Block block, String name, int idHint)
// handle ItemBlock-before-Block registrations
ItemBlock itemBlock = null;
for (Item item : iItemRegistry.typeSafeIterable()) // find matching ItemBlock
if (item instanceof ItemBlock && ((ItemBlock) item).field_150939_a == block)
itemBlock = (ItemBlock) item;
if (itemBlock != null) // has ItemBlock, adjust id and clear the slot already occupied by the corresponding item
idHint = iItemRegistry.getId(itemBlock);
FMLLog.fine("Found matching ItemBlock %s for Block %s at id %d", itemBlock, block, idHint);
freeSlot(idHint, block); // temporarily free the slot occupied by the Item for the block registration
int blockId = iBlockRegistry.add(idHint, name, block, availabilityMap);
if (itemBlock != null) // verify
if (blockId != idHint) throw new IllegalStateException(String.format("Block at itemblock id %d insertion failed, got id %d.", idHint, blockId));
verifyItemBlockName(itemBlock);
useSlot(blockId);
((RegistryDelegate.Delegate&Block&) block.delegate).setName(name);
return blockId;
用的namespace都不是原来的RegistryNamespaced,是fml自己的FMLControlledNamespacedRegistry&I&,也就是说原来那个已经没法用了。对,你看fml还加泛型,可以限定这个命名空间给方块用或者给物品用,这就是人的写法。看中间那个if,就是在判断命名空间里有没有;如果没有,重新分配序号。这个就是有fml,帮我们解决了MC的代码问题。如果fml没解决呢?public class Potion
/** The array of potion types. */
public static final Potion[] potionTypes = new Potion[32];
public static final Potion field_76423_b = null;
public static final Potion moveSpeed = (new Potion(1, false, 8171462)).setPotionName("potion.moveSpeed").setIconIndex(0, 0).func_111184_a(SharedMonsterAttributes.movementSpeed, "91AEAA56-376B-F7F", 0.23224D, 2);
public static final Potion moveSlowdown = (new Potion(2, true, 5926017)).setPotionName("potion.moveSlowdown").setIconIndex(1, 0).func_111184_a(SharedMonsterAttributes.movementSpeed, "CE8-4C1F160890", -0.46448D, 2);
public static final Potion digSpeed = (new Potion(3, false, )).setPotionName("potion.digSpeed").setIconIndex(2, 0).setEffectiveness(1.5D);
public static final Potion digSlowdown = (new Potion(4, true, 4866583)).setPotionName("potion.digSlowDown").setIconIndex(3, 0);
public static final Potion damageBoost = (new PotionAttackDamage(5, false, 9643043)).setPotionName("potion.damageBoost").setIconIndex(4, 0).func_111184_a(SharedMonsterAttributes.attackDamage, "648D-4F59-8ABE-C2C23A6DD7A9", 3.0D, 2);
public static final Potion heal = (new PotionHealth(6, false, )).setPotionName("potion.heal");
public static final Potion harm = (new PotionHealth(7, true, 4393481)).setPotionName("potion.harm");
public static final Potion jump = (new Potion(8, false, 7889559)).setPotionName("potion.jump").setIconIndex(2, 1);
public static final Potion confusion = (new Potion(9, true, 5578058)).setPotionName("potion.confusion").setIconIndex(3, 1).setEffectiveness(0.25D);
/** The regeneration Potion object. */
public static final Potion regeneration = (new Potion(10, false, )).setPotionName("potion.regeneration").setIconIndex(7, 0).setEffectiveness(0.25D);
public static final Potion resistance = (new Potion(11, false, )).setPotionName("potion.resistance").setIconIndex(6, 1);
/** The fire resistance Potion object. */
public static final Potion fireResistance = (new Potion(12, false, )).setPotionName("potion.fireResistance").setIconIndex(7, 1);
/** The water breathing Potion object. */
public static final Potion waterBreathing = (new Potion(13, false, 3035801)).setPotionName("potion.waterBreathing").setIconIndex(0, 2);
/** The invisibility Potion object. */
public static final Potion invisibility = (new Potion(14, false, 8356754)).setPotionName("potion.invisibility").setIconIndex(0, 1);
/** The blindness Potion object. */
public static final Potion blindness = (new Potion(15, true, 2039587)).setPotionName("potion.blindness").setIconIndex(5, 1).setEffectiveness(0.25D);
/** The night vision Potion object. */
public static final Potion nightVision = (new Potion(16, false, 2039713)).setPotionName("potion.nightVision").setIconIndex(4, 1);
/** The hunger Potion object. */
public static final Potion hunger = (new Potion(17, true, 5797459)).setPotionName("potion.hunger").setIconIndex(1, 1);
/** The weakness Potion object. */
public static final Potion weakness = (new PotionAttackDamage(18, true, 4738376)).setPotionName("potion.weakness").setIconIndex(5, 0).func_111184_a(SharedMonsterAttributes.attackDamage, "E-49DC-9B6B-BE5", 2.0D, 0);
/** The poison Potion object. */
public static final Potion poison = (new Potion(19, true, 5149489)).setPotionName("potion.poison").setIconIndex(6, 0).setEffectiveness(0.25D);
/** The wither Potion object. */
public static final Potion wither = (new Potion(20, true, 3484199)).setPotionName("potion.wither").setIconIndex(1, 2).setEffectiveness(0.25D);
public static final Potion field_76434_w = (new PotionHealthBoost(21, false, )).setPotionName("potion.healthBoost").setIconIndex(2, 2).func_111184_a(SharedMonsterAttributes.maxHealth, "5D6F0BA2-1186-46AC-B896-C61C5CEE99CC", 4.0D, 0);
public static final Potion field_76444_x = (new PotionAbsoption(22, false, 2445989)).setPotionName("potion.absorption").setIconIndex(2, 2);
public static final Potion field_76443_y = (new PotionHealth(23, false, )).setPotionName("potion.saturation");
public static final Potion field_76442_z = null;
public static final Potion field_76409_A = null;
public static final Potion field_76410_B = null;
public static final Potion field_76411_C = null;
public static final Potion field_76405_D = null;
public static final Potion field_76406_E = null;
public static final Potion field_76407_F = null;
public static final Potion field_76408_G = null;
没错,这就是药水类的注册。也不用什么register了,直接写static了。好吧,你是怎么写的我也不想管了,我就想加几种自己定义的药水效果。然后我们就看到了一行代码:public static final Potion[] potionTypes = new Potion[32];
尼玛。数组,而且还是定长数组。怎么办?老实说,没什么好办法,因为fml没帮你解决这个问题。固然你可以换掉这个数组给它扩容,但是这必然会导致mod和mod不兼容。反正,现在版本依然有大量的药水效果冲突的问题存在。比如你可以在1.7.10装个IC再装个环境,看饥渴效果是怎么变成辐射效果把你秒了的。TC的药水数量已经自己都在那几个空里装不下了,他自己实现了一个potion数组,但是他不是fml,我们也没法都转移过去,所以这个问题也没什么好办法。public abstract class Enchantment
public static final Enchantment[] enchantmentsList = new Enchantment[256];
/** The list of enchantments applicable by the anvil from a book */
public static final Enchantment[] enchantmentsBookList;
/** Converts environmental damage to armour damage */
public static final Enchantment protection = new EnchantmentProtection(0, 10, 0);
/** Protection against fire */
public static final Enchantment fireProtection = new EnchantmentProtection(1, 5, 1);
/** Less fall damage */
public static final Enchantment featherFalling = new EnchantmentProtection(2, 5, 2);
/** Protection against explosions */
public static final Enchantment blastProtection = new EnchantmentProtection(3, 2, 3);
/** Protection against projectile entities (e.g. arrows) */
public static final Enchantment projectileProtection = new EnchantmentProtection(4, 5, 4);
/** Decreases the rate of increases time between damage while suffocating */
public static final Enchantment respiration = new EnchantmentOxygen(5, 2);
/** Increases underwater mining rate */
public static final Enchantment aquaAffinity = new EnchantmentWaterWorker(6, 2);
public static final Enchantment thorns = new EnchantmentThorns(7, 1);
/** Extra damage to mobs */
public static final Enchantment sharpness = new EnchantmentDamage(16, 10, 0);
/** Extra damage to zombies, zombie pigmen and skeletons */
public static final Enchantment smite = new EnchantmentDamage(17, 5, 1);
/** Extra damage to spiders, cave spiders and silverfish */
public static final Enchantment baneOfArthropods = new EnchantmentDamage(18, 5, 2);
/** Knocks mob and players backwards upon hit */
public static final Enchantment knockback = new EnchantmentKnockback(19, 5);
/** Lights mobs on fire */
public static final Enchantment fireAspect = new EnchantmentFireAspect(20, 2);
/** Mobs have a chance to drop more loot */
public static final Enchantment looting = new EnchantmentLootBonus(21, 2, EnumEnchantmentType.weapon);
/** Faster resource gathering while in use */
public static final Enchantment efficiency = new EnchantmentDigging(32, 10);
* Blocks mined will drop themselves, even if it should drop something else (e.g. stone will drop stone, not
* cobblestone)
public static final Enchantment silkTouch = new EnchantmentUntouching(33, 1);
/** Sometimes, the tool's durability will not be spent when the tool is used */
public static final Enchantment unbreaking = new EnchantmentDurability(34, 5);
/** Can multiply the drop rate of items from blocks */
public static final Enchantment fortune = new EnchantmentLootBonus(35, 2, EnumEnchantmentType.digger);
/** Power enchantment for bows, add's extra damage to arrows. */
public static final Enchantment power = new EnchantmentArrowDamage(48, 10);
/** Knockback enchantments for bows, the arrows will knockback the target when hit. */
public static final Enchantment punch = new EnchantmentArrowKnockback(49, 2);
/** Flame enchantment for bows. Arrows fired by the bow will be on fire. Any target hit will also set on fire. */
public static final Enchantment flame = new EnchantmentArrowFire(50, 2);
* Infinity enchantment for bows. The bow will not consume arrows anymore, but will still required at least one
* arrow on inventory use the bow.
public static final Enchantment infinity = new EnchantmentArrowInfinite(51, 1);
public static final Enchantment field_151370_z = new EnchantmentLootBonus(61, 2, EnumEnchantmentType.fishing_rod);
public static final Enchantment field_151369_A = new EnchantmentFishingSpeed(62, 2, EnumEnchantmentType.fishing_rod);
附魔的问题好一些,好在什么地方呢?他的数组长。有时候想想挺可笑的,写mod遇到这么大麻烦,就是因为mojang有个数写的不够大。3、性能性能这一块我要分两部分,先黑java,再黑mojang。没错,java性能就是差,你来打我啊。打完了没有,我要回家了。好吧,让我们认真来说,java性能就是差。当然mc也跟所有的java程序一样,里面充满了new new new new,耗内存比耗CPU还多,这么个小游戏居然没个2G内存带不起来。画图性能也不咋地,当然最新的lwjgl3.0有了一定的好转,不过稍早的mc用的还是2.4,简直惨,就这么个根本没有几个多边形的游戏,看着不同的地方能差十几帧。算法倒没什么可黑的,mc主要吃CPU的算法都写的中规中矩网上抄的,按照java规范来,快不到哪去但也没法写的再快了。比如PathNavigate和WorldGen系列,算法比较复杂,详细的就不贴了。好,黑java差不多,该黑mojang了。先给你们看看1.8特性列表里的一栏。渲染 & 图像优化显著的提高 FPS 和性能每个世界(主世界、下界、末路之地) 现在各自独立运作区块渲染和区块重建现在使用多线程- 超快速的区块渲染!重写了区块序列Better visibility culling code生物寻路现在是多线程的重写储物系统矿物生成现在较以前快了2倍现在只有透明方块才可以被渲染为透明的(移除X光材质包的使用)Dropped items now face the player in all three directions on fast graphics重写方块是如何被渲染的重写方块数据是如何被处理的改善游戏并使"cooler things" 得以被实现也就是说,直到1.8之前,区块重建、矿物生成、多世界、生物寻路都是单线程的。你要知道,这些可都是性能大头,这些部分是单线程的,意味着mc服务器基本上就是单线程的……坑爹啊!还是给你们看一看mc的线程状况吧。以下以1.7.10版本为准。怎么知道mc哪里有线程呢?搜索Thread和synchronized关键字。好嘛,有OpenGL用的,有OpenAL用的,有twitch流用的,有Crash的时候打印错误信息用的,有网关IO用的,就是没有算法用的……再看看synchronized跟上面差不多,有文件IO的,有网络IO的,有图像IO的,有视频IO的……不过world类里那两个是真的,Chunk和Gen确实有多线程,这个等黑完了我再夸一夸。好吧,有没有可能我们漏掉了什么地方,实际上mc多数代码早已悄悄躲进几个大线程里,普通代码根本不用加锁呢?我们来调试一下看看:什么乱七八糟线程都有,就是看不见算法分线程。实际上MC代码就全都运行在就那一个高亮的Server Thread里面。1.8进步了,不过有限。如果照样搜一遍的话,我们会看到ChunkRender里有了Thread和synchronized,对应上面的方块渲染。珍爱服务器,远离1.7。希望微软赶紧用C++把mc重写。然后把学不会C++的都赶走,这样我就是领军人物了。如果能招我进微软就更好了。4、API现在想了想,API的问题应该放到第一去讲的。但是实际上上面三个都是我们modder的眼中钉肉中刺,相比之下API的问题都已经习惯了,所以我现在才想起来这个问题。那么我们就讲讲mc里的API怎么写的。问:MC里的API怎么写的?答:MC根本没有API。我们刚刚提过,MC是从一个小游戏慢慢变大的,所以里面有很多历史遗留写法。细节上的历史遗留讲的很多了,那么架构上最大的遗留问题是什么呢?那就是API。MC的架构,根本没有给写API留下什么空间。仍以一个方块为例,MC里采用一种类似享元模式的设计模式处理方块,每一种方块都是一个对象。为了创造具有特殊行为的方块,需要写一个新类继承Block类,并且Override相应的函数以实现自己的行为。那么,Block类大概有多大呢?2631行,大概200个可以被重载的函数,其中大部分都在某个方块类里被重载了。举个特定方块类的例子,比如矿物方块。public class BlockOre extends Block
public BlockOre()
super(Material.rock);
this.setCreativeTab(CreativeTabs.tabBlock);
public Item getItemDropped(int p__, Random p__, int p__)
return this == Blocks.coal_ore ? Items.coal : (this == Blocks.diamond_ore ? Items.diamond : (this == Blocks.lapis_ore ? Items.dye : (this == Blocks.emerald_ore ? Items.emerald : (this == Blocks.quartz_ore ? Items.quartz : Item.getItemFromBlock(this)))));
public int quantityDropped(Random p__)
return this == Blocks.lapis_ore ? 4 + p__.nextInt(5) : 1;
public int quantityDroppedWithBonus(int p__, Random p__)
if (p__ & 0 && Item.getItemFromBlock(this) != this.getItemDropped(0, p__, p__))
int j = p__.nextInt(p__ + 2) - 1;
if (j & 0)
return this.quantityDropped(p__) * (j + 1);
return this.quantityDropped(p__);
public void dropBlockAsItemWithChance(World p__, int p__, int p__, int p__, int p__, float p__, int p__)
super.dropBlockAsItemWithChance(p__, p__, p__, p__, p__, p__, p__);
private Random rand = new Random();
public int getExpDrop(IBlockAccess p__, int p__, int p__)
if (this.getItemDropped(p__, rand, p__) != Item.getItemFromBlock(this))
int j1 = 0;
if (this == Blocks.coal_ore)
j1 = MathHelper.getRandomIntegerInRange(rand, 0, 2);
else if (this == Blocks.diamond_ore)
j1 = MathHelper.getRandomIntegerInRange(rand, 3, 7);
else if (this == Blocks.emerald_ore)
j1 = MathHelper.getRandomIntegerInRange(rand, 3, 7);
else if (this == Blocks.lapis_ore)
j1 = MathHelper.getRandomIntegerInRange(rand, 2, 5);
else if (this == Blocks.quartz_ore)
j1 = MathHelper.getRandomIntegerInRange(rand, 2, 5);
return j1;
public int damageDropped(int p__)
return this == Blocks.lapis_ore ? 4 : 0;
看,新方块类就这么写,继承一下Block,然后就开始胡改了。不管是被按照Block调用还是调用别的函数,都没有中间层抽象,都是直接调用。耦合成这个样子,怎么写API?无怪mojang 1.6的时候就说要写API了,都这么久了还一点消息没有,这怎么能写出来API。现在所有的modder写mod,都必须拿着反编译反混淆过的源码,大量地直接使用MC里原有的基类和调用函数,把自己的代码完全嵌入MC的架构里,否则没法写。反编译是否违法呢?当然违法,人家可是商业软件。但是有什么办法,我还想有成熟的API可用呢,mojang自己不争气写不出来API,又不敢关门撵人,所以就变成了现在这个样子,mojang默许整个MC社区使用MC的反编译代码(这个工程叫MCP)来写mod。所以说mod社区对微软收购这件事这么敏感,因为本来就名不正言不顺。如果MC有了API,大概会是什么样子呢?虽然目前还没有可以整个用来写mod的API,不过一个子集已经有了,叫bukkit。bukkit很能说明一个有了API的开发,是一种什么感受。bukkit大概总共就这么长:org.bukkit
More generalized classes in the API.
org.bukkit.block
Classes used to manipulate the voxels in a world, including special states.
org.bukkit.block.banner
org.bukkit.command
Classes relating to handling specialized non-chat player input.
org.bukkit.command.defaults
Commands for emulating the Minecraft commands and other necessary ones for use by a Bukkit implementation.
org.bukkit.configuration
Classes dedicated to handling a plugin's runtime configuration.
org.bukkit.configuration.file
Classes dedicated facilitating configurations to be read and stored on the filesystem.
org.bukkit.configuration.serialization
Classes dedicated to being able to perform serialization specialized for the Bukkit configuration implementation.
org.bukkit.conversations
Classes dedicated to facilitate direct player-to-plugin communication.
org.bukkit.enchantments
Classes relating to the specialized enhancements to item stacks, as part of the meta data.
org.bukkit.entity
Interfaces for non-voxel objects that can exist in a world, including all players, monsters, projectiles, etc.
org.bukkit.entity.minecart
Interfaces for various Minecart types.
org.bukkit.event
Classes dedicated to handling triggered code executions.
org.bukkit.event.block
Events relating to when a block is changed or interacts with the world.
org.bukkit.event.enchantment
Events triggered from an enchantment table.
org.bukkit.event.entity
Events relating to entities, excluding some directly referencing some more specific entity types.
org.bukkit.event.hanging
Events relating to entities that hang.
org.bukkit.event.inventory
Events relating to inventory manipulation.
org.bukkit.event.painting
Events relating to paintings, but deprecated for more general hanging events.
org.bukkit.event.player
Events relating to players.
org.bukkit.event.server
Events relating to programmatic state changes on the server.
org.bukkit.event.vehicle
Events relating to vehicular entities.
org.bukkit.event.weather
Events relating to weather.
org.bukkit.event.world
Events triggered by various world states or changes.
org.bukkit.generator
Classes to facilitate world generation implementation.
org.bukkit.help
Classes used to manipulate the default command and topic assistance system.
org.bukkit.inventory
Classes involved in manipulating player inventories and item interactions.
org.bukkit.inventory.meta
The interfaces used when manipulating extra data can can be stored inside item stacks.
org.bukkit.map
Classes to facilitate plugin handling of map displays.
org.bukkit.material
Classes that represents various voxel types and states.
org.bukkit.metadata
Classes dedicated to providing a layer of plugin specified data on various Minecraft concepts.
org.bukkit.permissions
Classes dedicated to providing binary state properties to players.
org.bukkit.plugin
Classes specifically relating to loading software modules at runtime.
org.bukkit.plugin.java
Classes for handling plugins written in java.
org.bukkit.plugin.messaging
Classes dedicated to specialized plugin to client protocols.
org.bukkit.potion
Classes to represent various potion properties and manipulation.
org.bukkit.projectiles
Classes to represent the source of a projectile
org.bukkit.scheduler
Classes dedicated to letting plugins run code at specific time intervals, including thread safety.
org.bukkit.scoreboard
Interfaces used to manage the client side score display system.
org.bukkit.util
Multi and single purpose classes to facilitate various programmatic concepts.
org.bukkit.util.io
Classes used to facilitate stream processing for specific Bukkit concepts.
org.bukkit.util.noise
Classes dedicated to facilitating deterministic noise.
org.bukkit.util.permissions
Static methods for miscellaneous permission functionality.
相比之下MC包的数量大概是他的三倍,类的数量……我不想算了,因为每个物品\方块都是类。你要知道,这些部分全都是解耦的。bukkit这些接口是真正的接口,bukkit并不会规定其具体实现,每一版craftbukkit都会有所不同。而且bukkit向下兼容,其内容简洁易懂,符合软件工程原则,使用舒适度远超读MC那些诘屈聱牙的大段代码。这就是一个真正的API该有的样子。forge是不是API呢?实际上,不是。在写mod的时候,只有两个部分要跟forge交互:1.forge.event。原版MC是没有事件系统的,这个样子连调用自己的代码都办不到。forge加进了一些事件,包括MC初始化事件,让你有机会处理事务。2.register。这基本上是一些便利类,能简化你注册方块、物品、翻译文件一类的流程,可以写一个函数搞定。这些不是API,实际上它们没有抽象任何事情,你真正需要解决的问题还是得到源码里搞定,他只是帮你解决不该由你解决的问题而已。5、网络相信眼尖的同学在线程里已经看见了,MC的网络连接用的是netty。netty设计的大致还是没什么问题的,有问题这里也不提了。我们就看看netty IO的上下游,MC发包和解包怎么写的。先看一下类,有Packet类,每种Packet有个类,有INetHandler,有NetHandler,写的挺好嘛,一个一个看。public abstract class Packet
public static Packet generatePacket(BiMap p__, int p__)
Class oclass = (Class)p__.get(Integer.valueOf(p__));
return oclass == null ? null : (Packet)oclass.newInstance();
catch (Exception exception)
logger.error("Couldn\'t create packet " + p__, exception);
return null;
public abstract void readPacketData(PacketBuffer p__) throws IOException;
public abstract void writePacketData(PacketBuffer p__) throws IOException;
public abstract void processPacket(INetHandler p__);
不错,有抽象基类,还自带一个小工厂。找个类看看。public class C09PacketHeldItemChange extends Packet
public C09PacketHeldItemChange(int slot)
this.hold = slot;
public void readPacketData(PacketBuffer buffer) throws IOException
this.bit= buffer.readShort();
public void writePacketData(PacketBuffer buffer) throws IOException
buffer.writeShort(this.bit);
public void processPacket(INetHandlerPlayServer nethandler)
nethandler.processHeldItemChange(this);
public void processPacket(INetHandler nethandler)
this.processPacket((INetHandlerPlayServer)nethandler);
……等等,解包之后的实现哪去了?public class NetworkManager extends SimpleChannelInboundHandler
public void processReceivedPackets()
if (this.netHandler != null)
for (int i = 1000; !this.receivedPacketsQueue.isEmpty() && i &= 0; --i)
Packet packet = (Packet)this.receivedPacketsQueue.poll();
packet.processPacket(this.netHandler);
this.netHandler.onNetworkTick();
this.channel.flush();
这……public class NetHandlerPlayServer implements INetHandlerPlayServer
public void processAnimation(C0APacketAnimation p__)
this.playerEntity.func_143004_u();
if (p__.func_149421_d() == 1)
this.playerEntity.swingItem();
public void processEntityAction(C0BPacketEntityAction p__)
this.playerEntity.func_143004_u();
if (p__.func_149513_d() == 1)
this.playerEntity.setSneaking(true);
else if (p__.func_149513_d() == 2)
this.playerEntity.setSneaking(false);
else if (p__.func_149513_d() == 4)
this.playerEntity.setSprinting(true);
else if (p__.func_149513_d() == 5)
this.playerEntity.setSprinting(false);
else if (p__.func_149513_d() == 3)
this.playerEntity.wakeUpPlayer(false, true, true);
this.hasMoved = false;
else if (p__.func_149513_d() == 6)
if (this.playerEntity.ridingEntity != null && this.playerEntity.ridingEntity instanceof EntityHorse)
((EntityHorse)this.playerEntity.ridingEntity).setJumpPower(p__.func_149512_e());
else if (p__.func_149513_d() == 7 && this.playerEntity.ridingEntity != null && this.playerEntity.ridingEntity instanceof EntityHorse)
((EntityHorse)this.playerEntity.ridingEntity).openGUI(this.playerEntity);
public void processHeldItemChange(C09PacketHeldItemChange p__)
if (p__.func_149614_c() &= 0 && p__.func_149614_c() & InventoryPlayer.getHotbarSize())
this.playerEntity.inventory.currentItem = p__.func_149614_c();
this.playerEntity.func_143004_u();
logger.warn(this.playerEntity.getCommandSenderName() + " tried to set an invalid carried item");
……尼玛。这解包的具体实现是写在Handler类里的,把每个被Handle的类的实现都写在Handler里 ,比硬编码还硬编码。注册那些硬编码至少还是数据,只是难看点,不妨碍你继续往数组里加数据;这硬编码的是函数,根本不可能加。于是我们很奇怪,接口呢?我们不是还有一个接口,可以用来实现具体解包过程吗?public interface INetHandlerPlayServer extends INetHandler
void processAnimation(C0APacketAnimation p__);
void processChatMessage(C01PacketChatMessage p__);
void processPlayerDigging(C07PacketPlayerDigging p__);
void processHeldItemChange(C09PacketHeldItemChange p__);
让我笑一会,哈哈哈哈哈哈哈。正常人写接口会有很多子类,然后在接口里定义一组对应同一个抽象概念的函数。这个接口只有一个子类,然后在接口里定义一堆互相平行的具体实现。这个接口存在的意义是什么。MC的网络的抽象层烂到这个地步,已经完全没法复用了。幸好,天无绝人之路,netty的抽象层够多,可以给我们其他的解决方案。这是netty的管道图,可以非常直观地看出,在一个Channel内部,还可以定义许多个Handler进行处理。MC只用了他自己的几个Handler,我们可以再定义自己的Handler处理packet。实际上,大型mod多半这么处理的。FML也给了相应的注册类和API,首先提供了FMLEventChannel来直达netty层,适合熟练使用netty的用户;对于需求简单、不会netty的用户(比如我)还封装了一个SimpleNetworkWrapper,提供了简单的直接IO。和MC一比,FML写的真是好,各个抽象层都考虑到,而且都对齐。谁叫MC已经烂到一定程度了呢。想吐的槽都吐差不多了,再写点总结补充就结束了吧。80092 条评论分享收藏感谢收起public Chunk provideChunk(int x, int z)
// 生成一个区块专属的伪随机种子,这个种子只跟x和z的位置有关
this.rand.setSeed((long)x * L + (long)z * L);
ChunkPrimer chunkprimer = new ChunkPrimer(); // 封装了一下方块设置的操作
// 生成低分辨率的生物群系、密度图、方块,后面会讲
this.setBlocksInChunk(x, z, chunkprimer);
// 生成标准大小的生物群系
this.biomesForGeneration = this.worldObj.getBiomeProvider().loadBlockGeneratorData(this.biomesForGeneration, x * 16, z * 16, 16, 16);
// 按照生物群系替换掉高度图里面的普通方块
this.replaceBiomeBlocks(x, z, chunkprimer, this.biomesForGeneration);
// 前面生成选项里面看到的各种设置,要不要洞穴之类的
if (this.settings.useCaves)
this.caveGenerator.generate(this.worldObj, x, z, chunkprimer);
if (this.settings.useRavines)
this.ravineGenerator.generate(this.worldObj, x, z, chunkprimer);
if (this.mapFeaturesEnabled)
if (this.settings.useMineShafts)
this.mineshaftGenerator.generate(this.worldObj, x, z, chunkprimer);
if (this.settings.useVillages)
this.villageGenerator.generate(this.worldObj, x, z, chunkprimer);
if (this.settings.useStrongholds)
this.strongholdGenerator.generate(this.worldObj, x, z, chunkprimer);
if (this.settings.useTemples)
this.scatteredFeatureGenerator.generate(this.worldObj, x, z, chunkprimer);
if (this.settings.useMonuments)
this.oceanMonumentGenerator.generate(this.worldObj, x, z, chunkprimer);
// 构造区块对象,把方块和生物群系数据填进去
Chunk chunk = new Chunk(this.worldObj, chunkprimer, x, z);
byte[] abyte = chunk.getBiomeArray();
for (int i = 0; i & abyte. ++i)
abyte[i] = (byte)Biome.getIdForBiome(this.biomesForGeneration[i]);
// 生成基础的天空光照(见前文)
chunk.generateSkylightMap();
重点的setBlocksInChunk函数:public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
this.biomesForGeneration = this.worldObj.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10); // 这是一个低分辨率的生物群系表,用在generateHeightmap里面的
// 生成密度图,原文虽然写的是高度图,但是实际上是密度图,可能是fml的人理解有问题
this.generateHeightmap(x * 4, 0, z * 4);
// 这里往下的这么一大段都是在插值,密度大于0的填上石头,低于海平面而且不是石头的
// 填上海水,别的都是空气。
// 话说这段真是乱七八糟,一堆magic number,估计fml的人也懒得看懂,
// 既没加注释也没改变量名。。。
for (int i = 0; i & 4; ++i)
// 为什么是33和5呢? 33=32+1, 5=4+1
int j = i * 5;
int k = (i + 1) * 5;
for (int l = 0; l & 4; ++l)
int i1 = (j + l) * 33;
int j1 = (j + l + 1) * 33;
int k1 = (k + l) * 33;
int l1 = (k + l + 1) * 33;
for (int i2 = 0; i2 & 32; ++i2)
double d0 = 0.125D;
double d1 = this.heightMap[i1 + i2];
double d2 = this.heightMap[j1 + i2];
double d3 = this.heightMap[k1 + i2];
double d4 = this.heightMap[l1 + i2];
// 于高度y方向线性插值
double d5 = (this.heightMap[i1 + i2 + 1] - d1) * 0.125D;
double d6 = (this.heightMap[j1 + i2 + 1] - d2) * 0.125D;
double d7 = (this.heightMap[k1 + i2 + 1] - d3) * 0.125D;
double d8 = (this.heightMap[l1 + i2 + 1] - d4) * 0.125D;
// 于x和z方向线性插值
for (int j2 = 0; j2 & 8; ++j2)
double d9 = 0.25D;
double d10 = d1;
double d11 = d2;
double d12 = (d3 - d1) * 0.25D;
double d13 = (d4 - d2) * 0.25D;
for (int k2 = 0; k2 & 4; ++k2)
double d14 = 0.25D;
double d16 = (d11 - d10) * 0.25D;
double lvt_45_1_ = d10 - d16;
for (int l2 = 0; l2 & 4; ++l2)
if ((lvt_45_1_ += d16) & 0.0D)
primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, STONE);
else if (i2 * 8 + j2 & this.settings.seaLevel)
primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, this.oceanBlock);
d10 += d12;
d11 += d13;
感觉这一段还要解释一下。x和z不是16,32这样的世界坐标,而是区块坐标,是世界坐标的16/1,也就是区块(1, 2)代表了世界坐标上面的(16,32)到(31,47)的矩形区域。这里首先生成了一个低分辨率的生物群系,长宽是10*10,是因为接下来要用的密度图长宽是5*5。然后生成密度图,这个待会儿也会讲。之所以说是密度图而不是高度图是因为它是三维的5*33*5,而不是二维的结构,所以只能称之为密度。接下来是线性插值。一个区块是16*256*16,而为了让密度更为平滑,这里把密度图的长宽各放大4倍,高度放大8倍,再做线性插值就会比较光滑不会变化特别突兀。有人要问,5*4不是20吗?33*8不是264吗?其实因为5*33*5多出来的一圈是不用的,而且插值需要两个值才能计算,所以四个采样点其实需要5个数据,33也一样是这个道理。再浅显一点来说,密度图里面的0,1,2,3,4(java数组从0开始)对应的是区块x或z轴里面的0, 4, 8, 12, 16,既然我们要计算位置为13,14,15的方块,那就得用12和16对应的3和4来插值。插值的过程从循环变量为j2的那个循环开始,0.125就是8分之1,因为高度上放大8倍,后面的0.25也是因为放大了4倍,lvt_45_1其实可以写得易懂一点的,也是一个插值变量,跟前面的d1,d2,d3,d4,d10,d11是一样的,只不过mojang的程序猿为了装逼特地写了这么个东西罢了。。所以说代码质量差不仅在于架构,还在于其中各种细节的写法,像这种绝对就不算优秀的代码。先到这里吧。。还有好多。。各位先看着哈。。--------------------------------------------分割线-------------------------------------------------总结全文,深化主旨,首尾呼应:Minecraft是个好游戏,但代码写的确实不咋地。我最初接触MC还是13年,那时候大部分还在用1.4.2或者1.5,当然,都是盗版。一开始只是玩单机,打生存,搭房子,有时候开创造玩玩红石电路,特别喜欢一个人晚上独自边打MC边听他的bgm。C418的歌,很宁静,让人很放松。后来基本上大部分玩法都玩儿遍了,也不怎么愿意去花功夫做那种超大的红石电路或者建筑之类的,总想着找点别的花样。于是我装了Forge,下了很多mod,比如IndustrialCraft这种大名鼎鼎的,还有一些辅助性的mod,比如1.6.2之后就停止开发的SPC(Single Player Command 卖安利)。SPC是模仿WorldEdit的担任命令行mod,就是各种批量编辑,一个人搭建筑非常方便(因为WorldEdit WE只有多人能用,SPC可以单人模式用)。结果换1.7.2之后SPC不支持了,于是就萌生了自己开发一个的想法。(好吧最后还是流产了,当时水平不够做出来的性能很差,现在有能力做了又没了当初那种激情)又因为刚好学java,听说MC也是用java写的,所以就网上找教程写mod。我还记得14年的时候架着100K不到的梯子屁颠屁颠地装fml的时候,去maven central仓库上下东西动不动就停住了,结果一晚上都没装好。国内(哪怕到今天)都缺少真正有质量的mod开发教程,特别是中文的基本没有。贴吧上曾找到过一篇讲mod开发环境配置的,不过也止于1.6.2,到了1.7之后FML的整个API变了好多,原来的教程都用不了了。后来在网上找到了一篇文章: ,是MC最早的开发者Markus Persson(马库斯·泊松,网名notch)的个人博客,还有一篇讲述他的地形生成算法的博文:大概翻译一段(水平有限):In the very earliest version of Minecraft, I used a 2D Perlin noise heightmap to set the shape of the world. Or, rather, I used quite a few of them. One for overall elevation, one for terrain roughness, and one for local detail. For each column of blocks, the height was (elevation + (roughness*detail))*64+64. Both elevation and roughness were smooth, large scale noises, and detail was a more intricate one. This method had the great advantage of being very fast as there’s just 16*16*(noiseNum) samples per chunk to generate, but the disadvantage of being rather dull. Specifically, there’s no way for this method to generate any overhangs.在Minecraft最早的版本中,我将一张2维perlin noise图作为高度图来确定世界的形状。或者说,好几张perlin noise图。一张是整体海拔,一张是地形的粗糙度,一张是小范围的细节。对于每一列方块,其高度是 (海拔+(粗糙度*细节))*64+64。 海拔和粗糙度的图都是连续光滑的,大尺度的噪声图,而细节则更加参差不齐。这个生成方式有一个巨大的优点就是奇快无比,因为对于每个区块,只不过需要生成16*16*(噪声图的数量) 个采样点,然而缺点就是地图相当单调无趣。更重要的是,这种方式根本生成不了悬崖。So I switched the system over into a similar system based off 3D Perlin noise. Instead of sampling the “ground height”, I treated the noise value as the “density”, where anything lower than 0 would be air, and anything higher than or equal to 0 would be ground. To make sure the bottom layer is solid and the top isn’t, I just add the height (offset by the water level) to the sampled result.于是我改成了一种有些相似的、基于3维perlin noise的生成方式。我并不是对“地面高度”进行采样,而是将这个噪声的数值看做是“密度”(因此我说前面代码中应该是密度图而不是高度图 ——译者注),其中密度小于0的点都是空气而大于等于0的会成为大地(其实就是实心方块 ——译者注)。为了确保地图底端是地面而顶端是空气,我便把采样值加上采样点的高度(海拔高度)。(其实应该说是“减去采样点的高度”更易懂,因为大于0的才是方块,而水下的高度是负值 ——译者注)Unfortunately, I immediately ran into both performance issues and playability issues. Performance issues because of the huge amount of sampling needed to be done, and playability issues because there were no flat areas or smooth hills. The solution to both problems turned out to be just sampling at a lower resolution (scaled 8x along the horizontals, 4x along the vertical) and doing a linear interpolation. Suddenly, the game had flat areas, smooth hills, and also most single floating blocks were gone.不幸的是,我立刻碰上了可玩性和效率两方面的麻烦。因为有大量的点需要被采样所以效率很成问题,又因为缺乏大片的平地或平滑的山丘而缺乏可玩性。这两个问题共同的解决方案最终定为了这样:用一个更低的分辨率去采样噪声图(横向8倍,纵向4倍)(代码里面是横向4倍纵向8倍,可能跟后来的代码改动有关 ——译者注)并且进行线性插值(见setBlocksInChunk函数 ——译者注)。突如其来地,世界上有了平原、丘陵,而且单独浮在空中的诡异方块中的绝大部分也都消失无踪了。(其实还有很多了啦 ——译者注)这激起了我浓厚的兴趣。于是我把长长的代码打印下来,8号字体,一面3列,足足十几张纸,每天一有空就看代码,读代码,用笔做注释,并且为我觉得命名不当的部分想一个更好的名称。到现在这些还藏在我的书桌里面。这些东西百度根本搜不到,google也很少有结果,而以fml对这些代码的注释程度来看他们根本懒得去读这些既混乱又不必要读懂的代码。当然后来还是不了了之了。我自己也仿造过MC,当时就是完全追星似的疯狂模仿,用的java,跟MC一样的LWJGL库,同样(好吧我承认这么做有盗版的嫌疑)的纹理,几乎相同的文件格式、区块大小、渲染原理、(基于notch文章的)地形生成、体系架构,几乎就是我前面写的这么多的一个自己的重现。我甚至还学习MC混淆了编译后的代码。可笑的是,迫于当时的水平,效率竟比MC原版还要低。最后开发进程是因为我U盘的丢失而终止的,源码自然也丢了,只剩一份速度奇慢的编译版本,下载地址:,有兴趣的自己下载来玩玩吧。今年想过要重制,结果忙了一个夏天又泡汤了,现在想来总觉得有点可惜。后来被朋友忽悠着去打了一段时间MC服务器,也买了正版,不过服务器没有打过一个月的,基本两三个星期就崩掉关服不开放了,也不知道是我的问题还是整个现状都这样。(我真的没有干过坏事啊!)据说国内开一个服很快就会有黑客来勒索要钱否则就DDoS攻击(Distributed Denial of Service分布式拒绝服务攻击,用大量肉鸡的流量淹没对方,让对方或因为过高的流量费用而关闭服务,或因为过低的响应速度而降低服务质量到一个不可接受的程度),也不知道是不是真的,反正崩了好几个服,打拼好久的家园东西都没了,也就不打了。最近确实玩的不多,也就偶尔休息的时候像以前那样,搞搞建筑,搭搭红石电路之类的,都是单机玩,一方面没空,一方面也有点享受那种独自一人的感觉和C418的背景音乐。我知道这段算不上问题的“从编程的角度来看”,不过写了前面这么多,也使我回想起来以前发生过的不少。要不是这个答案,也不知道这段往事会被封存到什么时候。就借此机会,一吐为快吧。希望大家不必计较,并且欢迎任何技术上的讨论。以上。各位看官看完记得点个赞再走啊。。。谢啦。。。96897 条评论分享收藏感谢收起

我要回帖

更多关于 psn登录灰色 的文章

 

随机推荐