不开源地牢+破碎架构 如何逆向植入多语言?

一、引子

2025年11月5日,在我的AS/ADE综合讨论群,来了一位新群友。进来便在说自己在汉化 JOJO 的像素地牢,但汉化后发现了一个严重异常(如下图所示)

二、初步调查

当我看到这个截图时,第一时间是认为此群友在汉化直接翻译了韩文(JOJO地牢的源语言是韩文),便让他发了一个JOJO地牢原版地牢安装包,当我进入游戏后,浏览一遍发现:果不其然,语言按钮被删了。

这是很多外网地牢开发者喜欢干的好事,要怎么处理这个问题呢?

要想处理这个问题,我们要先来推测地牢对应的破碎版本了。

三、分析实现

因为是逆向植入调试,这里说一下最好需要哪些东西,如果没有这些东西,只是会更加麻烦一点。

工具准备:

手机一个,MT管理器(必选)

如果你这里只有手机,那么手机最好是能记录错误,如果手机无法记录错误,那就没有办法分析问题。

流程执行:

1、首先将手机与电脑连接,打开“开发者模式”(这个东西,百度一下就知道),然后启用USB调试功能

2、根据我们之前所说的,缺了选项卡只是因为少了一行,但是在逆向处理中,语言是Smali,这个可不怎么支持你去一个一个加。因此,我们要做的,就是全局处理。也就是直接替换WndSettings整个类!!!

3、如何替换整个类?首先,我们要通过【MT管理器】打开像素地牢的APK信息,如下图所示:

【这里以JOJO的像素地牢为例】

我们要使用【查看】按钮,然后会看到若干个classes.dex

选择其中一个classes.dex,然后选择 Dex编辑器++,勾选全部Dex并点击确定,进入Dex编辑工作环境。

然后点击【搜索】选项卡,搜索 Languages ,然后 搜索类型:类名 记得勾选 搜索子目录

搜索出来的结果,选择如下图所示的,也就是 选择 Languages 那个 C 图标

进入后,选择右上角的省略号,然后点击【转成Java】 MT此功能需要会员,还请留意

然后,看一下这个 java,接下来 我们需要修改 第9行,让它返回中文,并对于无多语言索引的返回韩文。

做到一种极简的多语言模块。

接下来返回刚才的代码界面,如下图所示。然后选择那个 指南针 图标

找到下面的这个M图标,M代表method,也就是方法。然后点进去。

找到以”ko”的代码行,将它修改为”zh”,实现一种极简汉化的渲染。

原理:原先应该渲染ko(韩文),改成zh就变成渲染zh(简体中文了)

现在,我们已经初步实现了一种极简渲染,从刚才的Java代码我们可以得知,缺少的zh索引,将自动返回韩文。因此,我们现在可以将自己的zh文件添加到语言文件了。

现在,请保存代码,退出Dex编辑器++,并重新编译Dex。

保存并退出,然后编译。

勾选确定,更新文件。

然后到asstes/messages/里面,添加各个zh后缀的中文语言文件,例如 actor_zh.properties

然后自动签名后,安装游戏。


其实,一般来说,到这里,你已经基本实现了一个极简汉化版本。

但是,我们能发现一个问题,部分地牢的开发者,把中文的适配删掉了,导致显示异常,

我们应该如何处理这个问题呢?

让我们回到Dex编辑器++,思考应该如何处理这个问题。

我们现在通过 Languages 制作了一个极简汉化语言环境,那么我们能否通过修改代码,来兼容中文呢?

答案当然是有的,这就是 接下来我们需要进行第二个修改的Java/类:RenderedTextBlock

搜索到后,进入此类,然后点击右上角省略号,然后点击 转成Java。

既然是布局上的问题,那么就应该与这个布局相关的方法的有关联。因此,我们寻找layout方法,如下图所示:

  @Override
        protected synchronized void layout() {
                super.layout();
                float x = this.x;
                float y = this.y;
                float height = 0;
                nLines = 1;

                ArrayList<ArrayList<RenderedText>> lines = new ArrayList<>();
                ArrayList<RenderedText> curLine = new ArrayList<>();
                lines.add(curLine);

                width = 0;
                for (int i = 0; i < words.size(); i++){
                        RenderedText word = words.get(i);
                        if (word == SPACE){
                                x += 1.667f;
                        } else if (word == NEWLINE) {
                                //newline
                                y += height+2f;
                                x = this.x;
                                nLines++;
                                curLine = new ArrayList<>();
                                lines.add(curLine);
                        } else {
                                if (word.height() > height) height = word.height();

                                float fullWidth = word.width();
                                int j = i+1;

                                //this is so that words split only by highlighting are still grouped in layout
                                //Chinese/Japanese always render every character separately without spaces however
                                while (Messages.lang() != Languages.CHI_SMPL && Messages.lang() != Languages.CHI_TRAD
                                                && Messages.lang() != Languages.JAPANESE
                                                && j < words.size() && words.get(j) != SPACE && words.get(j) != NEWLINE){
                                        fullWidth += words.get(j).width() - 0.667f;
                                        j++;
                                }

                                if ((x - this.x) + fullWidth - 0.001f > maxWidth && !curLine.isEmpty()){
                                        y += height+2f;
                                        x = this.x;
                                        nLines++;
                                        curLine = new ArrayList<>();
                                        lines.add(curLine);
                                }

                                word.x = x;
                                word.y = y;
                                PixelScene.align(word);
                                x += word.width();
                                curLine.add(word);

                                if ((x - this.x) > width) width = (x - this.x);

                                //Note that spacing currently doesn't factor in halfwidth and fullwidth characters
                                //(e.g. Ideographic full stop)
                                x -= 0.667f;

                        }
                }
                this.height = (y - this.y) + height;

                if (alignment != LEFT_ALIGN){
                        for (ArrayList<RenderedText> line : lines){
                                if (line.size() == 0) continue;
                                float lineWidth = line.get(line.size()-1).width() + line.get(line.size()-1).x - this.x;
                                if (alignment == CENTER_ALIGN){
                                        for (RenderedText text : line){
                                                text.x += (width() - lineWidth)/2f;
                                                PixelScene.align(text);
                                        }
                                } else if (alignment == RIGHT_ALIGN) {
                                        for (RenderedText text : line){
                                                text.x += width() - lineWidth;
                                                PixelScene.align(text);
                                        }
                                }
                        }
                }
        }

上面的代码是破碎的像素地牢的 RenderedTextBlock.java 的源代码,从这里,我们不难看出区别:

【破碎源代码Java】

【JoJo地牢反编译代码Java】

从这里,我们已经能初见端倪,为什么布局会出现错乱,就是因为这里的Chinese,被开发者删了。

但显然,我们发现了一个新的问题,韩文肯定无法与中文兼容,因此,之前的简化在这里行不通。

我们需要再次回到 Languages

然后,将下面的代码全部复制并粘贴回去

# classes2.dex

.class public final enum Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;
.super Ljava/lang/Enum;
.source "Languages.java"


# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;
    }
.end annotation

.annotation system Ldalvik/annotation/Signature;
    value = {
        "Ljava/lang/Enum<",
        "Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;",
        ">;"
    }
.end annotation


# static fields
.field private static final synthetic $VALUES:[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

.field public static final enum CHINESE:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

.field public static final enum KOREAN:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;


# instance fields
.field private code:Ljava/lang/String;

.field private name:Ljava/lang/String;

.field private reviewers:[Ljava/lang/String;

.field private status:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;

.field private translators:[Ljava/lang/String;


# direct methods
.method private static synthetic $values()[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;
    .registers 3

    .line 1
    const/4 v0, 0x2

    .line 2
    new-array v0, v0, [Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 4
    const/4 v1, 0x0

    .line 5
    sget-object v2, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->KOREAN:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 7
    aput-object v2, v0, v1

    .line 9
    const/4 v1, 0x1

    .line 10
    sget-object v2, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->CHINESE:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 12
    aput-object v2, v0, v1

    .line 14
    return-object v0
.end method

.method public static constructor <clinit>()V
    .registers 30

    .line 1
    new-instance v8, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 3
    const-string v1, "KOREAN"

    .line 5
    const/4 v2, 0x0

    .line 6
    const-string v3, "한국어"

    .line 8
    const-string v4, "ko"

    .line 10
    sget-object v5, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;->O_COMPLETE:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;

    .line 12
    const/4 v6, 0x0

    .line 13
    const/4 v7, 0x0

    .line 14
    move-object v0, v8

    .line 15
    invoke-direct/range {v0 .. v7}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;-><init>(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;[Ljava/lang/String;[Ljava/lang/String;)V

    .line 18
    sput-object v8, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->KOREAN:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 20
    new-instance v0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 22
    const-string v10, "CHINESE"

    .line 24
    const/4 v11, 0x1

    .line 25
    const-string v12, "中文"

    .line 27
    const-string v13, "zh"

    .line 29
    sget-object v14, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;->O_COMPLETE:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;

    .line 31
    const-string v1, "Jinkeloid(zdx00793)"

    .line 33
    const-string v2, "endlesssolitude"

    .line 35
    filled-new-array {v1, v2}, [Ljava/lang/String;

    .line 38
    move-result-object v15

    .line 39
    const-string v16, "破碎原版汉化组"

    .line 65
    const-string v17, "无名汉化"

    .line 67
    filled-new-array/range {v16 .. v17}, [Ljava/lang/String;

    .line 70
    move-result-object v16

    .line 71
    move-object v9, v0

    .line 72
    invoke-direct/range {v9 .. v16}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;-><init>(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;[Ljava/lang/String;[Ljava/lang/String;)V

    .line 75
    sput-object v0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->CHINESE:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 77
    invoke-static {}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->$values()[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 80
    move-result-object v0

    .line 81
    sput-object v0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->$VALUES:[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 83
    return-void
.end method

.method private constructor <init>(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;[Ljava/lang/String;[Ljava/lang/String;)V
    .registers 8
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "(",
            "Ljava/lang/String;",
            "Ljava/lang/String;",
            "Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;",
            "[",
            "Ljava/lang/String;",
            "[",
            "Ljava/lang/String;",
            ")V"
        }
    .end annotation

    .line 1
    invoke-direct {p0, p1, p2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V

    .line 4
    iput-object p3, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->name:Ljava/lang/String;

    .line 6
    iput-object p4, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->code:Ljava/lang/String;

    .line 8
    iput-object p5, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->status:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;

    .line 10
    iput-object p6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->reviewers:[Ljava/lang/String;

    .line 12
    iput-object p7, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->translators:[Ljava/lang/String;

    .line 14
    return-void
.end method

.method public static matchCode(Ljava/lang/String;)Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;
    .registers 6

    .line 1
    invoke-static {}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->values()[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 4
    move-result-object v0

    .line 5
    array-length v1, v0

    .line 6
    const/4 v2, 0x0

    .line 7
    :goto_6
    if-ge v2, v1, :cond_18

    .line 9
    aget-object v3, v0, v2

    .line 11
    invoke-virtual {v3}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->code()Ljava/lang/String;

    .line 14
    move-result-object v4

    .line 15
    invoke-virtual {v4, p0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    .line 18
    move-result v4

    .line 19
    if-eqz v4, :cond_15

    .line 21
    return-object v3

    .line 22
    :cond_15
    add-int/lit8 v2, v2, 0x1

    .line 24
    goto :goto_6

    .line 25
    :cond_18
    sget-object p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->KOREAN:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 27
    return-object p0
.end method

.method public static matchLocale(Ljava/util/Locale;)Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;
    .registers 1

    .line 1
    invoke-virtual {p0}, Ljava/util/Locale;->getLanguage()Ljava/lang/String;

    .line 4
    move-result-object p0

    .line 5
    invoke-static {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->matchCode(Ljava/lang/String;)Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 8
    move-result-object p0

    .line 9
    return-object p0
.end method

.method public static valueOf(Ljava/lang/String;)Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;
    .registers 2

    .line 1
    const-class v0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 3
    invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;

    .line 6
    move-result-object p0

    .line 7
    check-cast p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 9
    return-object p0
.end method

.method public static values()[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;
    .registers 1

    .line 1
    sget-object v0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->$VALUES:[Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 3
    invoke-virtual {v0}, [Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->clone()Ljava/lang/Object;

    .line 6
    move-result-object v0

    .line 7
    check-cast v0, [Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 9
    return-object v0
.end method


# virtual methods
.method public code()Ljava/lang/String;
    .registers 2

    .line 1
    iget-object v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->code:Ljava/lang/String;

    .line 3
    return-object v0
.end method

.method public nativeName()Ljava/lang/String;
    .registers 2

    .line 1
    iget-object v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->name:Ljava/lang/String;

    .line 3
    return-object v0
.end method

.method public reviewers()[Ljava/lang/String;
    .registers 2

    .line 1
    iget-object v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->reviewers:[Ljava/lang/String;

    .line 3
    if-nez v0, :cond_8

    .line 5
    const/4 v0, 0x0

    .line 6
    new-array v0, v0, [Ljava/lang/String;

    .line 8
    return-object v0

    .line 9
    :cond_8
    invoke-virtual {v0}, [Ljava/lang/String;->clone()Ljava/lang/Object;

    .line 12
    move-result-object v0

    .line 13
    check-cast v0, [Ljava/lang/String;

    .line 15
    return-object v0
.end method

.method public status()Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;
    .registers 2

    .line 1
    iget-object v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->status:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages$Status;

    .line 3
    return-object v0
.end method

.method public translators()[Ljava/lang/String;
    .registers 2

    .line 1
    iget-object v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->translators:[Ljava/lang/String;

    .line 3
    if-nez v0, :cond_8

    .line 5
    const/4 v0, 0x0

    .line 6
    new-array v0, v0, [Ljava/lang/String;

    .line 8
    return-object v0

    .line 9
    :cond_8
    invoke-virtual {v0}, [Ljava/lang/String;->clone()Ljava/lang/Object;

    .line 12
    move-result-object v0

    .line 13
    check-cast v0, [Ljava/lang/String;

    .line 15
    return-object v0
.end method

当我们编译成功,再次安装测试时,我们会发现一个新的问题:

因为新增了中文,但是没有做系统语言的适配,所以默认又返回了韩文。

我们应该如何处理这个问题呢?

现在让我们再次回到Dex编辑器++,并寻找 Messages (仍然类名查找)

然后转成 Java,找到setup方法

从这里的代码,我们不难看出,JOJO地牢的开发者把这里改的面目全非,我们要替换这里原有的setup方法

.method public static setup(Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;)V
    .registers 8
    .param p0, "lang"  # Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 83
    const/4 v0, 0x0

    invoke-static {v0}, Lcom/badlogic/gdx/utils/I18NBundle;->setExceptionOnMissingKey(Z)V

    .line 86
    sput-object p0, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->lang:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    .line 87
    sget-object v1, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->ENGLISH:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    if-ne p0, v1, :cond_f

    .line 88
    sget-object v1, Ljava/util/Locale;->ENGLISH:Ljava/util/Locale;

    sput-object v1, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->locale:Ljava/util/Locale;

    goto :goto_1a

    .line 90
    :cond_f
    new-instance v1, Ljava/util/Locale;

    invoke-virtual {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->code()Ljava/lang/String;

    move-result-object v2

    invoke-direct {v1, v2}, Ljava/util/Locale;-><init>(Ljava/lang/String;)V

    sput-object v1, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->locale:Ljava/util/Locale;

    .line 94
    :goto_1a
    new-instance v1, Ljava/util/ArrayList;

    invoke-direct {v1}, Ljava/util/ArrayList;-><init>()V

    sput-object v1, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->bundles:Ljava/util/ArrayList;

    .line 95
    new-instance v1, Ljava/util/Locale;

    invoke-virtual {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->code()Ljava/lang/String;

    move-result-object v2

    invoke-direct {v1, v2}, Ljava/util/Locale;-><init>(Ljava/lang/String;)V

    .line 96
    .local v1, "bundleLocal":Ljava/util/Locale;
    sget-object v2, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->prop_files:[Ljava/lang/String;

    array-length v3, v2

    :goto_2d
    if-ge v0, v3, :cond_43

    aget-object v4, v2, v0

    .line 97
    .local v4, "file":Ljava/lang/String;
    sget-object v5, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->bundles:Ljava/util/ArrayList;

    sget-object v6, Lcom/badlogic/gdx/Gdx;->files:Lcom/badlogic/gdx/Files;

    invoke-interface {v6, v4}, Lcom/badlogic/gdx/Files;->internal(Ljava/lang/String;)Lcom/badlogic/gdx/files/FileHandle;

    move-result-object v6

    invoke-static {v6, v1}, Lcom/badlogic/gdx/utils/I18NBundle;->createBundle(Lcom/badlogic/gdx/files/FileHandle;Ljava/util/Locale;)Lcom/badlogic/gdx/utils/I18NBundle;

    move-result-object v6

    invoke-virtual {v5, v6}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 96
    .end local v4  # "file":Ljava/lang/String;
    add-int/lit8 v0, v0, 0x1

    goto :goto_2d

    .line 99
    :cond_43
    return-void
.end method

这里要注意,ENGLISH要替换成KOREAN,否则会闪退。因为在Languages中并没有KOREAN

当然这里主要针对于JOJO地牢,大部分地牢都是英文 ENGLISH 的,所以可以直接使用。

再次编译安装,我们仍然发现布局有问题。

是的 因为 RenderedTextBlock 还没有修改,我们再次回到这个RenderedTextBlock类里面,找到layout方法【下面的代码不要复制】

.method protected declared-synchronized layout()V
    .registers 15

    monitor-enter p0

    .line 206
    :try_start_1
    invoke-super {p0}, Lcom/watabou/noosa/ui/Component;->layout()V

    .line 207
    iget v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    .line 208
    .local v0, "x":F
    iget v1, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->y:F

    .line 209
    .local v1, "y":F
    const/4 v2, 0x0

    .line 210
    .local v2, "height":F
    const/4 v3, 0x1

    iput v3, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    .line 212
    new-instance v4, Ljava/util/ArrayList;

    invoke-direct {v4}, Ljava/util/ArrayList;-><init>()V

    .line 213
    .local v4, "lines":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;>;"
    new-instance v5, Ljava/util/ArrayList;

    invoke-direct {v5}, Ljava/util/ArrayList;-><init>()V

    .line 214
    .local v5, "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    invoke-virtual {v4, v5}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 216
    const/4 v6, 0x0

    iput v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width:F

    .line 217
    const/4 v6, 0x0

    .local v6, "i":I
    :goto_1d
    iget-object v7, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v7

    const/high16 v8, 0x40000000  # 2.0f

    if-ge v6, v7, :cond_e2

    .line 218
    iget-object v7, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v7, v6}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v7

    check-cast v7, Lcom/watabou/noosa/RenderedText;

    .line 219
    .local v7, "word":Lcom/watabou/noosa/RenderedText;
    sget-object v9, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->SPACE:Lcom/watabou/noosa/RenderedText;

    if-ne v7, v9, :cond_39

    .line 220
    const v8, 0x3fd56042  # 1.667f

    add-float/2addr v0, v8

    goto/16 :goto_de

    .line 221
    :cond_39
    sget-object v9, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->NEWLINE:Lcom/watabou/noosa/RenderedText;

    if-ne v7, v9, :cond_52

    .line 223
    add-float/2addr v8, v2

    add-float/2addr v1, v8

    .line 224
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    .line 225
    .end local v0  # "x":F
    .local v8, "x":F
    iget v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    add-int/2addr v0, v3

    iput v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    .line 226
    new-instance v0, Ljava/util/ArrayList;

    invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V

    .line 227
    .end local v5  # "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    .local v0, "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    invoke-virtual {v4, v0}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    move-object v5, v0

    move v0, v8

    goto/16 :goto_de

    .line 229
    .end local v8  # "x":F
    .end local p0  # "this":Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;
    .local v0, "x":F
    .restart local v5  # "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    :cond_52
    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->height()F

    move-result v9

    cmpl-float v9, v9, v2

    if-lez v9, :cond_5f

    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->height()F

    move-result v9

    move v2, v9

    .line 231
    :cond_5f
    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v9

    .line 232
    .local v9, "fullWidth":F
    add-int/lit8 v10, v6, 0x1

    .line 236
    .local v10, "j":I
    :goto_65
    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11}, Ljava/util/ArrayList;->size()I

    move-result v11

    const v12, 0x3f2ac083  # 0.667f

    if-ge v10, v11, :cond_95

    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v11

    sget-object v13, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->SPACE:Lcom/watabou/noosa/RenderedText;

    if-eq v11, v13, :cond_95

    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v11

    sget-object v13, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->NEWLINE:Lcom/watabou/noosa/RenderedText;

    if-eq v11, v13, :cond_95

    .line 237
    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v11

    check-cast v11, Lcom/watabou/noosa/RenderedText;

    invoke-virtual {v11}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v11

    sub-float/2addr v11, v12

    add-float/2addr v9, v11

    .line 238
    add-int/lit8 v10, v10, 0x1

    goto :goto_65

    .line 241
    :cond_95
    iget v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float v11, v0, v11

    add-float/2addr v11, v9

    const v13, 0x3a83126f  # 0.001f

    sub-float/2addr v11, v13

    iget v13, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->maxWidth:I

    int-to-float v13, v13

    cmpl-float v11, v11, v13

    if-lez v11, :cond_be

    invoke-virtual {v5}, Ljava/util/ArrayList;->isEmpty()Z

    move-result v11

    if-nez v11, :cond_be

    .line 242
    add-float/2addr v8, v2

    add-float/2addr v1, v8

    .line 243
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    move v0, v8

    .line 244
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    add-int/2addr v8, v3

    iput v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    .line 245
    new-instance v8, Ljava/util/ArrayList;

    invoke-direct {v8}, Ljava/util/ArrayList;-><init>()V

    move-object v5, v8

    .line 246
    invoke-virtual {v4, v5}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 249
    :cond_be
    iput v0, v7, Lcom/watabou/noosa/RenderedText;->x:F

    .line 250
    iput v1, v7, Lcom/watabou/noosa/RenderedText;->y:F

    .line 251
    invoke-static {v7}, Lcom/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene;->align(Lcom/watabou/noosa/Visual;)V

    .line 252
    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v8

    add-float/2addr v0, v8

    .line 253
    invoke-virtual {v5, v7}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 255
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float v8, v0, v8

    iget v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width:F

    cmpl-float v8, v8, v11

    if-lez v8, :cond_dd

    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float v8, v0, v8

    iput v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width:F

    .line 259
    :cond_dd
    sub-float/2addr v0, v12

    .line 217
    .end local v7  # "word":Lcom/watabou/noosa/RenderedText;
    .end local v9  # "fullWidth":F
    .end local v10  # "j":I
    :goto_de
    add-int/lit8 v6, v6, 0x1

    goto/16 :goto_1d

    .line 263
    .end local v6  # "i":I
    :cond_e2
    iget v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->y:F

    sub-float v6, v1, v6

    add-float/2addr v6, v2

    iput v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->height:F

    .line 265
    iget v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->alignment:I

    if-eq v6, v3, :cond_16d

    .line 266
    invoke-virtual {v4}, Ljava/util/ArrayList;->iterator()Ljava/util/Iterator;

    move-result-object v6

    :goto_f1
    invoke-interface {v6}, Ljava/util/Iterator;->hasNext()Z

    move-result v7

    if-eqz v7, :cond_16d

    invoke-interface {v6}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v7

    check-cast v7, Ljava/util/ArrayList;

    .line 267
    .local v7, "line":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v9

    if-nez v9, :cond_104

    goto :goto_f1

    .line 268
    :cond_104
    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v9

    sub-int/2addr v9, v3

    invoke-virtual {v7, v9}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v9

    check-cast v9, Lcom/watabou/noosa/RenderedText;

    invoke-virtual {v9}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v9

    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v10

    sub-int/2addr v10, v3

    invoke-virtual {v7, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v10

    check-cast v10, Lcom/watabou/noosa/RenderedText;

    iget v10, v10, Lcom/watabou/noosa/RenderedText;->x:F

    add-float/2addr v9, v10

    iget v10, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float/2addr v9, v10

    .line 269
    .local v9, "lineWidth":F
    iget v10, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->alignment:I

    const/4 v11, 0x2

    if-ne v10, v11, :cond_149

    .line 270
    invoke-virtual {v7}, Ljava/util/ArrayList;->iterator()Ljava/util/Iterator;

    move-result-object v10

    :goto_12d
    invoke-interface {v10}, Ljava/util/Iterator;->hasNext()Z

    move-result v11

    if-eqz v11, :cond_148

    invoke-interface {v10}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v11

    check-cast v11, Lcom/watabou/noosa/RenderedText;

    .line 271
    .local v11, "text":Lcom/watabou/noosa/RenderedText;
    iget v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    invoke-virtual {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width()F

    move-result v13

    sub-float/2addr v13, v9

    div-float/2addr v13, v8

    add-float/2addr v12, v13

    iput v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    .line 272
    invoke-static {v11}, Lcom/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene;->align(Lcom/watabou/noosa/Visual;)V

    .line 273
    .end local v11  # "text":Lcom/watabou/noosa/RenderedText;
    goto :goto_12d

    :cond_148
    goto :goto_16c

    .line 274
    :cond_149
    iget v10, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->alignment:I

    const/4 v11, 0x3

    if-ne v10, v11, :cond_16c

    .line 275
    invoke-virtual {v7}, Ljava/util/ArrayList;->iterator()Ljava/util/Iterator;

    move-result-object v10

    :goto_152
    invoke-interface {v10}, Ljava/util/Iterator;->hasNext()Z

    move-result v11

    if-eqz v11, :cond_16c

    invoke-interface {v10}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v11

    check-cast v11, Lcom/watabou/noosa/RenderedText;

    .line 276
    .restart local v11  # "text":Lcom/watabou/noosa/RenderedText;
    iget v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    invoke-virtual {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width()F

    move-result v13

    sub-float/2addr v13, v9

    add-float/2addr v12, v13

    iput v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    .line 277
    invoke-static {v11}, Lcom/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene;->align(Lcom/watabou/noosa/Visual;)V
    :try_end_16b
    .catchall {:try_start_1 .. :try_end_16b} :catchall_16f

    .line 278
    .end local v11  # "text":Lcom/watabou/noosa/RenderedText;
    goto :goto_152

    .line 280
    .end local v7  # "line":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    .end local v9  # "lineWidth":F
    :cond_16c
    :goto_16c
    goto :goto_f1

    .line 282
    :cond_16d
    monitor-exit p0

    return-void

    .line 205
    .end local v0  # "x":F
    .end local v1  # "y":F
    .end local v2  # "height":F
    .end local v4  # "lines":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;>;"
    .end local v5  # "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    :catchall_16f
    move-exception v0

    :try_start_170
    monitor-exit p0
    :try_end_171
    .catchall {:try_start_170 .. :try_end_171} :catchall_16f

    throw v0
.end method

现在,我们需要修改layout方法,这里很难进行修改,因此复制下面的代码即可:

.method protected declared-synchronized layout()V
    .registers 15

    monitor-enter p0

    .line 206
    :try_start_1
    invoke-super {p0}, Lcom/watabou/noosa/ui/Component;->layout()V

    .line 207
    iget v0, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    .line 208
    .local v0, "x":F
    iget v1, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->y:F

    .line 209
    .local v1, "y":F
    const/4 v2, 0x0

    .line 210
    .local v2, "height":F
    const/4 v3, 0x1

    iput v3, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    .line 212
    new-instance v4, Ljava/util/ArrayList;

    invoke-direct {v4}, Ljava/util/ArrayList;-><init>()V

    .line 213
    .local v4, "lines":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;>;"
    new-instance v5, Ljava/util/ArrayList;

    invoke-direct {v5}, Ljava/util/ArrayList;-><init>()V

    .line 214
    .local v5, "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    invoke-virtual {v4, v5}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 216
    const/4 v6, 0x0

    iput v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width:F

    .line 217
    const/4 v6, 0x0

    .local v6, "i":I
    :goto_1d
    iget-object v7, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v7

    const/high16 v8, 0x40000000  # 2.0f

    if-ge v6, v7, :cond_fa

    .line 218
    iget-object v7, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v7, v6}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v7

    check-cast v7, Lcom/watabou/noosa/RenderedText;

    .line 219
    .local v7, "word":Lcom/watabou/noosa/RenderedText;
    sget-object v9, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->SPACE:Lcom/watabou/noosa/RenderedText;

    if-ne v7, v9, :cond_39

    .line 220
    const v8, 0x3fd56042  # 1.667f

    add-float/2addr v0, v8

    goto/16 :goto_f6

    .line 221
    :cond_39
    sget-object v9, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->NEWLINE:Lcom/watabou/noosa/RenderedText;

    if-ne v7, v9, :cond_52

    .line 223
    add-float/2addr v8, v2

    add-float/2addr v1, v8

    .line 224
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    move v0, v8

    .line 225
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    add-int/2addr v8, v3

    iput v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    .line 226
    new-instance v8, Ljava/util/ArrayList;

    invoke-direct {v8}, Ljava/util/ArrayList;-><init>()V

    move-object v5, v8

    .line 227
    invoke-virtual {v4, v5}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    goto/16 :goto_f6

    .line 229
    .end local p0  # "this":Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;
    :cond_52
    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->height()F

    move-result v9

    cmpl-float v9, v9, v2

    if-lez v9, :cond_5f

    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->height()F

    move-result v9

    move v2, v9

    .line 231
    :cond_5f
    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v9

    .line 232
    .local v9, "fullWidth":F
    add-int/lit8 v10, v6, 0x1

    .line 236
    .local v10, "j":I
    :goto_65
    invoke-static {}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->lang()Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    move-result-object v11

    sget-object v12, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->CHI_SMPL:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    const v13, 0x3f2ac083  # 0.667f

    if-eq v11, v12, :cond_ad

    invoke-static {}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->lang()Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    move-result-object v11

    sget-object v12, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->CHI_TRAD:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    if-eq v11, v12, :cond_ad

    .line 237
    invoke-static {}, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Messages;->lang()Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    move-result-object v11

    sget-object v12, Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;->JAPANESE:Lcom/shatteredpixel/shatteredpixeldungeon/messages/Languages;

    if-eq v11, v12, :cond_ad

    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    .line 238
    invoke-virtual {v11}, Ljava/util/ArrayList;->size()I

    move-result v11

    if-ge v10, v11, :cond_ad

    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v11

    sget-object v12, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->SPACE:Lcom/watabou/noosa/RenderedText;

    if-eq v11, v12, :cond_ad

    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v11

    sget-object v12, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->NEWLINE:Lcom/watabou/noosa/RenderedText;

    if-eq v11, v12, :cond_ad

    .line 239
    iget-object v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->words:Ljava/util/ArrayList;

    invoke-virtual {v11, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v11

    check-cast v11, Lcom/watabou/noosa/RenderedText;

    invoke-virtual {v11}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v11

    sub-float/2addr v11, v13

    add-float/2addr v9, v11

    .line 240
    add-int/lit8 v10, v10, 0x1

    goto :goto_65

    .line 243
    :cond_ad
    iget v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float v11, v0, v11

    add-float/2addr v11, v9

    const v12, 0x3a83126f  # 0.001f

    sub-float/2addr v11, v12

    iget v12, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->maxWidth:I

    int-to-float v12, v12

    cmpl-float v11, v11, v12

    if-lez v11, :cond_d6

    invoke-virtual {v5}, Ljava/util/ArrayList;->isEmpty()Z

    move-result v11

    if-nez v11, :cond_d6

    .line 244
    add-float/2addr v8, v2

    add-float/2addr v1, v8

    .line 245
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    move v0, v8

    .line 246
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    add-int/2addr v8, v3

    iput v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->nLines:I

    .line 247
    new-instance v8, Ljava/util/ArrayList;

    invoke-direct {v8}, Ljava/util/ArrayList;-><init>()V

    move-object v5, v8

    .line 248
    invoke-virtual {v4, v5}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 251
    :cond_d6
    iput v0, v7, Lcom/watabou/noosa/RenderedText;->x:F

    .line 252
    iput v1, v7, Lcom/watabou/noosa/RenderedText;->y:F

    .line 253
    invoke-static {v7}, Lcom/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene;->align(Lcom/watabou/noosa/Visual;)V

    .line 254
    invoke-virtual {v7}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v8

    add-float/2addr v0, v8

    .line 255
    invoke-virtual {v5, v7}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    .line 257
    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float v8, v0, v8

    iget v11, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width:F

    cmpl-float v8, v8, v11

    if-lez v8, :cond_f5

    iget v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float v8, v0, v8

    iput v8, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width:F

    .line 261
    :cond_f5
    sub-float/2addr v0, v13

    .line 217
    .end local v7  # "word":Lcom/watabou/noosa/RenderedText;
    .end local v9  # "fullWidth":F
    .end local v10  # "j":I
    :goto_f6
    add-int/lit8 v6, v6, 0x1

    goto/16 :goto_1d

    .line 265
    .end local v6  # "i":I
    :cond_fa
    iget v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->y:F

    sub-float v6, v1, v6

    add-float/2addr v6, v2

    iput v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->height:F

    .line 267
    iget v6, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->alignment:I

    if-eq v6, v3, :cond_185

    .line 268
    invoke-virtual {v4}, Ljava/util/ArrayList;->iterator()Ljava/util/Iterator;

    move-result-object v6

    :goto_109
    invoke-interface {v6}, Ljava/util/Iterator;->hasNext()Z

    move-result v7

    if-eqz v7, :cond_185

    invoke-interface {v6}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v7

    check-cast v7, Ljava/util/ArrayList;

    .line 269
    .local v7, "line":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v9

    if-nez v9, :cond_11c

    goto :goto_109

    .line 270
    :cond_11c
    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v9

    sub-int/2addr v9, v3

    invoke-virtual {v7, v9}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v9

    check-cast v9, Lcom/watabou/noosa/RenderedText;

    invoke-virtual {v9}, Lcom/watabou/noosa/RenderedText;->width()F

    move-result v9

    invoke-virtual {v7}, Ljava/util/ArrayList;->size()I

    move-result v10

    sub-int/2addr v10, v3

    invoke-virtual {v7, v10}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v10

    check-cast v10, Lcom/watabou/noosa/RenderedText;

    iget v10, v10, Lcom/watabou/noosa/RenderedText;->x:F

    add-float/2addr v9, v10

    iget v10, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->x:F

    sub-float/2addr v9, v10

    .line 271
    .local v9, "lineWidth":F
    iget v10, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->alignment:I

    const/4 v11, 0x2

    if-ne v10, v11, :cond_161

    .line 272
    invoke-virtual {v7}, Ljava/util/ArrayList;->iterator()Ljava/util/Iterator;

    move-result-object v10

    :goto_145
    invoke-interface {v10}, Ljava/util/Iterator;->hasNext()Z

    move-result v11

    if-eqz v11, :cond_160

    invoke-interface {v10}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v11

    check-cast v11, Lcom/watabou/noosa/RenderedText;

    .line 273
    .local v11, "text":Lcom/watabou/noosa/RenderedText;
    iget v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    invoke-virtual {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width()F

    move-result v13

    sub-float/2addr v13, v9

    div-float/2addr v13, v8

    add-float/2addr v12, v13

    iput v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    .line 274
    invoke-static {v11}, Lcom/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene;->align(Lcom/watabou/noosa/Visual;)V

    .line 275
    .end local v11  # "text":Lcom/watabou/noosa/RenderedText;
    goto :goto_145

    :cond_160
    goto :goto_184

    .line 276
    :cond_161
    iget v10, p0, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->alignment:I

    const/4 v11, 0x3

    if-ne v10, v11, :cond_184

    .line 277
    invoke-virtual {v7}, Ljava/util/ArrayList;->iterator()Ljava/util/Iterator;

    move-result-object v10

    :goto_16a
    invoke-interface {v10}, Ljava/util/Iterator;->hasNext()Z

    move-result v11

    if-eqz v11, :cond_184

    invoke-interface {v10}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v11

    check-cast v11, Lcom/watabou/noosa/RenderedText;

    .line 278
    .restart local v11  # "text":Lcom/watabou/noosa/RenderedText;
    iget v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    invoke-virtual {p0}, Lcom/shatteredpixel/shatteredpixeldungeon/ui/RenderedTextBlock;->width()F

    move-result v13

    sub-float/2addr v13, v9

    add-float/2addr v12, v13

    iput v12, v11, Lcom/watabou/noosa/RenderedText;->x:F

    .line 279
    invoke-static {v11}, Lcom/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene;->align(Lcom/watabou/noosa/Visual;)V
    :try_end_183
    .catchall {:try_start_1 .. :try_end_183} :catchall_187

    .line 280
    .end local v11  # "text":Lcom/watabou/noosa/RenderedText;
    goto :goto_16a

    .line 282
    .end local v7  # "line":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    .end local v9  # "lineWidth":F
    :cond_184
    :goto_184
    goto :goto_109

    .line 284
    :cond_185
    monitor-exit p0

    return-void

    .line 205
    .end local v0  # "x":F
    .end local v1  # "y":F
    .end local v2  # "height":F
    .end local v4  # "lines":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;>;"
    .end local v5  # "curLine":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Lcom/watabou/noosa/RenderedText;>;"
    :catchall_187
    move-exception v0

    :try_start_188
    monitor-exit p0
    :try_end_189
    .catchall {:try_start_188 .. :try_end_189} :catchall_187

    throw v0
.end method

注意,将里面的 CHI_SMPL CHI_TRAD JAPANESE 这三个,全部改成CHINESE(严格区分大小写)

有关详情,可参考下方演示视频

按照视频OK后,再次安装游戏,你应该能获得以下效果:

关于汉化的初步教程就到这里,其实还有一些补充内容,但那个就下次再提了。

教程结束,感谢你的阅读。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注