MCFPP——字符串体系

||

在MCFPP中,字符串分为两种,一种是string,即我们通常意义上的字符串,另一种则是jstring,即原始JSON文本。前者主要用于say命令,后者用途则广泛得多,比如tellrawtitle等命令。MCFPP将这两种类型分开,让代码的操作更加清晰规范,同时也提供了转换方法,能将两者相护转换。

本文描述的特性在本文书写时仍未确定,API可能和实际版本有所出入

string

string表示一个字符串。要声明一个字符串,应该使用string类型,例如string abc = "abc"

string重写了+运算符,因此能够对字符串进行加运算。例如string ps = "abc" + "def",结果得到ps为”abcdef”。

和MCFPP中所有变量一样,string类型有编译时静态和动态两种方式。类似上文中的声明方式,编译器能发现自己能够跟踪到这个字符串的内容,因此在编译过程中会进行简单的替换。而动态则不同,动态字符串通常是由于将一个jstring转换成string类型而导致的。动态字符串储存在nbt中,以供操作。

得益于宏和data string命令,让字符串的动态操作成为了可能。在1.19.4-的版本中,MCFPP只支持静态的字符串和原始JSON文本功能。

下面列出了string的一些API,以及实现的原理。实现原理的前提是,这个字符串是动态的。因为静态字符串根本不需要考虑很多的原理嘛。

inline string split(int startIndex, int endIndex)

切割一个字符串,对应原版的data string命令。返回一个字符串。

bool contains(string subString)

查询字符串中是否包含目标字符串。执行此方法时,首先获取subString的长度,然后对原字符串进行复制。首先查询字符串的0~subString.length是否为subString,然后查询1~subString.length+1,以此内推。这里我们在每次查询完毕后,直接将复制的字符串长度去掉最开头的字符,这样每次我们判断都只需要判断0~subString.length部分的字符串,从而提高优化。

inline int length()

返回字符串的长度,对应原版的data get命令

bool startsWith(string prefix)

bool endsWith(string suffix)

是否以指定字符串开头或结尾。原理类似contains方法。

char[] toCharArray()

将字符串转换为一个字符数组。原理是遍历字符串并将其储存在一个nbt数组中。

jstring toJString()

将这个字符串转换为jstring。

jstring

原始Json文本是Minecraft中最重要的文本展示方式。在展示实体,自定义名称,标题,聊天栏中,都会广泛地使用到原始JSON文本。原始JSON文本可以做到类似富文本的格式,还能显示记分板数字,NBT内容,甚至键位等。

在MCFPP中,所有的原始JSON文本都被默认为带有[],从而更好地进行加运算。声明jstring的方式可以为jstring j = "qwq",可以有隐式转换jstring j = 114514。jstring重载了针对任意类型遍历的加操作。

动态的jstring被储存于nbt中。值得注意的是,储存状态下的jstring不带有[],这是为了更方便地进行加操作。同时,默认会携带有一个,作为结尾,这也是便于加操作。在调用jstring变量时,会自动在命令中加上[]以及在末尾加一个””作为终止符。即在命令中,会用类似tellraw @s [$(j)""]这样的方式调用。

动态的jstring的储存分为两个部分。第一个部分是调用在命令中时使用的,也就是传入宏参数的部分,是通常意义上的原始JSON文本。第二部分是以NBT形式储存的,表示jstring中的成员。例如jstring j = "the value is " + value中,jstring的NBT储存格式为:

j:{
    str:"\"the value is\", {\"score\" :{\"object\": \"test\", \"name\": \"value\"}}",
    data: [
        {
            type: "string", 
            value: "the value is"
        }, 
        {
            type: "int", 
            value: {
                name: "value"
            }
        }
    ]
}

为了更清晰,上述我们使用了换行来展示NBT的内容。

当使用加法新增内容时,会在str后加长字符串,同时在data中添加和新内容相关的内容。注意,如果新的内容是jstring,则会合并data列表。

jstring展示的文本内容是动态的。例如上文中,如果修改了value的值,那么使用print方法打印出的文本也是不同的。如果要保留静态的内容,可以使用toString方法获取它的string文本。转换为string后的jstring将失去成员数据的内容,即使稍后将其重新转换为jstring也是如此。

下面列出了jstring的一些api。同样的,这些api的实现原理是针对动态情况下提出的,也只支持1.19.4以上的版本。

string toString()

将这个jstring转换为string。通过宏完成。

jstring insert(int index, object o)

插入一个元素。需要对jstring的str进行重新计算。

jstring remove(int index)

移除一个元素。需要对jstring的str进行重新计算。

bool contains(object o)

是否包含某个元素。

static jstring getFromList(List list)

从列表中获取一个jstring。jstring本身便有一个data的list作为成员,因此从list中获取jstring成为了一件很自然的事情。这个方法会自动检查list中的每个元素是不是标准的mcfpp变量储存形式,以便jstring拥有可变性。

类似文章

发表回复