如何評價我的世界中國版?
03-25
客戶端上有一個防沉迷Mod,當遊戲時間超過閾值後,就會執行一個指令(對,你沒聽錯,就是指令),這個指令不需要任何許可權即可執行,服務端上安裝的防沉迷插件收到指令後,就會按照客戶端的要求(對,沒聽錯,按照客戶端的要求)設置玩家打破方塊時有多少幾率不掉落物品。
然而。插件的「打破方塊不掉落物品」實現居然是直接把方塊的類型設為空氣,而且監聽器的優先順序還是 NORMAL,並且還不 ignoreCancelled,也就是說無視了所有其他插件的方塊破壞監聽器。······於是結果就是,當玩家進入防沉迷的時候,有幾率可以無視許可權破壞任何方塊。······
············於是,測試開始的當天,各個伺服器的主城均受到不同程度的破壞。而且還不止是主城,還包括小遊戲、領地等,總之就是能拆的都被拆了。等有玩家發現了那個指令,直接將幾率設為100%那就更有意思了之前這個回答有提到網易違反 Forge 開源協議的事,後來那部分我想想後又刪了。但發現一堆回答和其他論壇的帖子(比如Github上的issue)留了這個回答的鏈接,看起來我好像是第一個發現這個問題的…讓這些鏈接變成無意義的感覺不大好,所以我想還是應該再把那部分加回來。(並非之前的版本。更詳細。嫌太長或看不懂可只看加粗)網易啟動器下載的客戶端內置了幾個Mod,根據名字猜測,它們有用來做登錄驗證的,防沉迷的,等等。它們的類沒法直接被反編譯,因為網易對它們進行了AES加密。網易自己修改了 Forge 和 Launchwrapper,以在Mod的類被載入JVM時對其進行即時解密,並且阻止用戶私自安裝的「未授權」的Mod。*更新:網易於7/18凌晨時發布公告,表示同意開源。在此之後,Forge 的作者(非常良心的)花了一點時間寫了一份長長的分析報告,比我原來寫的詳細多了(畢竟作者本人嘛),於是我決定在此回答中將不必要的部分刪去,就保留兩點:看了 Forge原版 中這個類的注釋後,我發現網易並不是故意抹去版本號的,而是因為這個版本號會在被 Jenkins 自動構建平台構建時自動 +1s,而網易構建時沒有使用 Jenkins ,所以默認為 0。注釋見ForgeVersion.java#L37-L40") !important;">)
網易修改了 ASMModParser 類,在載入 class 文件時使用 ReflectionAPI 執行類文件解密。吐槽一下這讀取輸入流中所有的數據為 byte[] 的實現簡直了……即使你不會用各種別人已經幫你寫好的類庫,也沒必要這樣實現啊!這代碼真的不是開玩笑?……private static byte[] readClass(final InputStream is, boolean close)throws IOException {
if (is == null) { throw new IOException("Class not found"); } try { byte[] b = new byte[is.available()]; int len = 0; while (true) { int n = is.read(b, len, b.length - len); if (n == -1) {if (len < b.length) {
byte[] c = new byte[len]; System.arraycopy(b, 0, c, 0, len); b = c; } return b; } len += n; if (len == b.length) { int last = is.read();if (last < 0) {
return b; } byte[] c = new byte[b.length + 1000]; System.arraycopy(b, 0, c, 0, len); c[len++] = (byte) last; b = c; } } } finally {if (close) {
is.close(); } }}即使不用任何庫,非要自己實現的情況下,一般人至少也會寫成這樣吧:(舉例子,應該還有更簡單的,輕噴)private static byte[] readClass(InputStream in, boolean close) throws IOException { try{ ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[4096]; int len;while((len = in.read(buf)) != -1)
out.write(buf, 0, len); return out.toByteArray(); }finally{ if(close) in.close(); }}一個簡單的功能能寫這麼複雜真的活久見……天生自帶混淆……作者可以去參加國際C語言混亂代碼大賽") !important;">了。
推薦閱讀:
※我的世界中文版羊毛怎麼製作?
※《機械迷城》開發商的新作是個笑話
※模擬人生4有什麼奇葩玩法?
※火柴人遊戲系列合集?
※虛榮有什麼武器裝備?