AI
2023-05-05
体验
获得 ChatGPT 4 的资格(购买 Pro)之后,就可以看到左边页面多了一个 Model 选项,选中了 GPT 4
如果 Model 选择 Plugin 那一项,右边又会多出来一个 Plugins 选项
右边的 Plugins 选项一直往下拖,最下面一栏是 Plugin store,点击进入。
上面的插件可以选中体验体验。
安装
可以看到下方有 Install an unverified plugin
,Develop your own plugin
两项。
我们开发的插件就是服务器端 API + 相关声明文件,如果就只是放在自己的服务器上,那就算 unverified plugin。
第一选项就是用来安装这样未经验证的插件,可以在 https://www.gptplugins.app/ 找一个试一下。
输入域名,ChatGPT 自动去获取声明文件 https://域名/.well-known/ai-plugin.json。
第二项是用来注册插件到 ChatGPT,也可以用来调试本地插件。
如果是注册插件就填域名好了,如果是调试就输入 localhost:3000 这样的地址。
我用局域网 IP,似乎是不行的,可能只支持 localhost 这个主机名。
使用
现阶段最多能够同时勾选三个插件。
聊天过程中,ChatGPT 自动判断是否需要触发插件的使用。
开发
经过我的体验,开发非常简单,除了原本的服务之外,需要的额外工作就两项:清单文件,OpenAPI(如果原本没有的话)。
清单文件:
{
"schema_version": "v1",
"name_for_model": "todo",
"name_for_human": "Todo Plugin",
"description_for_model": "Simple task management, task description, task date, task completion. Supports adding, deleting, and querying.",
"description_for_human": "Simple task management.",
"auth": {
// 本地测试 Auth Type 必须是 none
"type": "none"
},
"api": {
"url": "http://localhost:8080/.well-known/openapi.yaml",
"has_user_authentication": true,
"type": "openapi"
},
"logo_url": "http://localhost:8080/.well-known/logo.png",
"contact_email": "hello@contact.com",
"legal_info_url": "hello@legal.com"
}
Redis
2023-04-30
我一两年前设计的一个通过 Redis ZSet 做事件广播的方案,刚用 Python 写了一个示例代码贴出来。
- 这是一个 Push / Pull 方式的广播机制。
- 推送方将消息推送到一个 zset key 中,score 为毫秒时间戳。
- key 名为 xxx:timestamp//10,也就是精确到 10 秒的时间戳。
也就是说每 10 秒一个 key,通过 TTL(5 分钟)实现历史数据自动清除,也避免 event 太多导致大 key 的问题。
- 拉取方用上一次拉取时间和当前时间做 score range,从最近的三个 zset 中读到这个时间段内的事件。
import logging
import threading
import time
import redis
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s %(message)s')
redis_host = '127.0.0.1'
redis_port = 6379
redis_db = 1
redis_password = None
redis_prefix = 'broadcast:'
redis_conn = redis.StrictRedis(host=redis_host, port=redis_port, db=redis_db, password=redis_password)
def handle_broadcast(data):
# 这里是处理收到的广播请求数据的函数
# 你需要根据具体需求来实现这个函数
logging.info(f'处理广播请求数据:{data} ===== ===== ===== =====')
def event_broadcast(data):
now = time.time()
now_ms = int(now * 1000)
now_10s = int(now) // 10
key = redis_prefix + str(now_10s)
score = now_ms
pipeline = redis_conn.pipeline()
pipeline.zadd(key, {data: score})
pipeline.expire(key, 300)
pipeline.execute()
# function event_broadcast(data) {
# const now = Date.now();
# const now_ms = now;
# const now_10s = Math.floor(now / 10000);
#
# const key = redis_prefix + now_10s;
# const score = now_ms;
#
# const pipeline = redis_conn.pipeline();
# pipeline.zadd(key, score, data);
# pipeline.expire(key, 300);
# pipeline.exec();
# }
last_score = 0
def event_fetch():
global last_score
now = time.time()
now_ms = int(now * 1000)
now_10s = int(now) // 10
keys = [
redis_prefix + str(now_10s - 2),
redis_prefix + str(now_10s - 1),
redis_prefix + str(now_10s),
]
pipeline = redis_conn.pipeline()
for key in keys:
logging.info('%s %20s %20s', key, last_score, now_ms)
pipeline.zrangebyscore(key, last_score, now_ms, withscores=True)
results = pipeline.execute()
for data_list in results:
for data, _ in data_list:
handle_broadcast(data.decode('utf-8'))
last_score = now_ms
def broadcast_loop():
i = 0
while True:
i += 1
data = f'广播请求数据 {i}'
event_broadcast(data)
logging.info(f'广播请求:{data}')
time.sleep(0.5)
def main():
broadcast_thread = threading.Thread(target=broadcast_loop, daemon=True)
broadcast_thread.start()
while True:
event_fetch()
time.sleep(5)
main()
Golang
2023-04-27
看到微信公众号 Go语言教程 的文章《golang 实现简单网关》才知道还有 httputil.ReverseProxy 这么个东西。
PS:这玩意儿有什么必要放在标准库?
还挺有趣,在作者示例的基础之上完善了一下,实现多服务,多后端节点的一个负载均衡(还可以再补上权重)。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"math/rand"
"net/http"
"net/http/httputil"
"net/url"
"strings"
"time"
)
func main() {
addr := "127.0.0.1:2002"
backends := map[string][]string{
"service1": {"http://127.0.0.1:2003", "http://127.0.0.1:2004"},
}
reversePorxy := NewReverseProxy(backends)
log.Println("Starting httpserver at " + addr)
log.Fatal(http.ListenAndServe(addr, reversePorxy))
}
func reqConvert(req *http.Request, target *url.URL) {
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
if target.RawQuery == "" || req.URL.RawQuery == "" {
req.URL.RawQuery = target.RawQuery + req.URL.RawQuery
} else {
req.URL.RawQuery = target.RawQuery + "&" + req.URL.RawQuery
}
if _, ok := req.Header["User-Agent"]; !ok {
req.Header.Set("User-Agent", "")
}
req.Header.Set("X-Real-Ip", strings.Split(req.RemoteAddr, ":")[0])
}
func NewReverseProxy(backends map[string][]string) *httputil.ReverseProxy {
var targets = make(map[string][]*url.URL)
for srv, nodes := range backends {
for _, nodeUrl := range nodes {
target, _ := url.Parse(nodeUrl)
targets[srv] = append(targets[srv], target)
}
}
director := func(req *http.Request) {
segments := strings.SplitN(req.URL.Path, "/", 3)
if len(segments) != 3 {
return
}
srv := segments[1]
req.URL.Path = segments[2]
if _, ok := targets[srv]; !ok {
log.Printf("unknown path: %s", req.URL.Path)
return
}
rand.Seed(time.Now().UnixNano())
randomIndex := rand.Intn(len(targets[srv]))
target := targets[srv][randomIndex]
reqConvert(req, target)
}
modifyFunc := func(res *http.Response) error {
if res.StatusCode != http.StatusOK {
oldPayLoad, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
newPayLoad := []byte("hello " + string(oldPayLoad))
res.Body = ioutil.NopCloser(bytes.NewBuffer(newPayLoad))
res.ContentLength = int64(len(newPayLoad))
res.Header.Set("Content-Length", fmt.Sprint(len(newPayLoad)))
}
return nil
}
return &httputil.ReverseProxy{Director: director, ModifyResponse: modifyFunc}
}
func singleJoiningSlash(a, b string) string {
aslash := strings.HasSuffix(a, "/")
bslash := strings.HasPrefix(b, "/")
switch {
case aslash && bslash:
return a + b[1:]
case !aslash && !bslash:
return a + "/" + b
}
return a + b
}
Git
2023-04-26
开源中国文章 紧跟 AI 步伐, Gitee 已支持 AI 模型托管 中介绍了 Git LFS 的使用。
结合 git lfs help,记录如下:
- 需要先 install 一下,启用 LFS 功能
$ git lfs install
Updated Git hooks.
Git LFS initialized.
- 追踪大文件
git lfs trace path/to/largefile
# 会记录在 .gitattributes 文件中
# path/to/largefile filter=lfs diff=lfs merge=lfs -text
- 推送大文件
# 正常提交
git add .gitattributes path/to/largefile
git commit -m "..."
# 推送
git lfs push --all
git lfs push --all origin
- 拉取大文件
git lfs pull --all
# 指定文件
git lfs pull -I <filepath>
git lfs ls-files
列出大文件
i18n
2023-04-24
做开发有时会需要系统支持在多个地区提供支持,主要是语言,其实还应该包括时区,货币单位等其他信息。
这一套动作叫做国际化和本地化。
国际化是指不要把一些东西写死,是指能够简单灵活改造适应不同地区的需求。
而本地化是指,将这套国际化的产品,针对不同区域做一个适配。
也就是说国际化和本地化是相辅相成的,是一套组合拳。
国际化的英语单词是 internationalization,缩写成 i18n(i 和 n 之间有 18 个字母)。
本地话的英语单词是 localization,缩写成 l10n(l 和 n 之间有 10 个字母)。
明明是一件事,有些地方叫国际化,有些地方写本地化,混乱!我更喜欢全球化 Globalization 这个词。
在如微软及IBM等企业中,则会使用全球化(globalization)来表示此两者的合称。
在英文中,也会使用g11n做为简称。
也有使用缩写 GILT (globalization、internationalization、localization和translation),即“全球化、国际化、本地化和翻译”。
相关工作内容(继续参考维基百科):
- 语言
- 电子文件
- 字母。目前大部分的系统都采用Unicode为标准来解决字符编码。
- 不同的数字命名系统。
- 书写方向。譬如德语、英语是从左到右,而波斯语、希伯来语和阿拉伯语是由右到左。
- 相同语言在不同地区的拼法差异,如美国英语、加拿大英语使用localization,而英国英语和澳洲英语使用localisation。
- 文件处理上的差异,如某些文字存在大小写,其它则否。字母顺序。
- 文字的图像表示(打印物、内含在线图片)。
- 读法(音频)
- 视频的字幕
- 文化
- 图片和颜色:这牵涉到理解和文化适宜的议题。
- 名字和称谓
- 政府给定的编码(如美国的社会安全码,英国的National Insurance number,爱沙尼亚的Isikukood及其它各国的身份证号码)和护照
- 电话号码、地址和国际邮递区号
- 货币(符号、货币标志的位置)
- 度量衡
- 纸张大小
- 书写习惯
- 日期跟时间的格式,包含各式日历。
- 时区(在国际场合会使用世界标准时间)
- 数字格式(小数点、分隔点的位置、分隔所用的字符)
- 产品和服务所要面向的法规
只属于本地化的主题有:
- 翻译
- 针对特定语言(如东亚语言)的特别支持
- 符合当地习惯
- 符合当地的道德观念
- 针对当地撰写内容
- 符号
- 排序方法
- 美学
- 当地的文化价值和社会环境
我们绝大多数场景应该只能关注到上面标粗的三个点:翻译,货币,合规。
参考资料与拓展阅读
开发工具 计算机网络 VPN NAT iptables
2023-04-23
2021/05/09,VPN 与 NAT 讲了我使用 Windows route 命令和 Linux iptables 命令做 NAT,实现 Windows 机器的 VPN 流量走 Linux 的指定网络设备。
现在情况可能会发生一些新的变化,所以这里记录一下我的几点思路。
WebDev JavaScript
2023-04-21
看了 How to split JavaScript strings into sentences, words or graphemes with "Intl.Segmenter" 了解到,现在 Web 已经支持分词了:
const text = `我爱北京天安门,天安门上太阳升。伟大领袖毛主席,指引我们向前进。`;
const granularities = ["sentence", "word", "grapheme"];
granularities.forEach(function (granularity) {
// console.log([granularity, index, self])
let segmenter = new Intl.Segmenter("zh", { granularity: granularity });
let seg = segmenter.segment(text);
// console.log(seg) // Segments{}
let result = Array.from(seg, (s) => s.segment);
console.log(result);
});
// ['我爱北京天安门,天安门上太阳升。', '伟大领袖毛主席,指引我们向前进。']
// ['我', '爱', '北京', '天安门', ',', '天安门', '上', '太阳', '升', '。', '伟大', '领袖', '毛主席', ',', '指引', '我们', '向', '前进', '。']
// ['我', '爱', '北', '京', '天', '安', '门', ',', '天', '安', '门', '上', '太', '阳', '升', '。', '伟', '大', '领', '袖', '毛', '主', '席', ',', '指', '引', '我', '们', '向', '前', '进', '。']
Golang
2023-04-19
package main
import (
"fmt"
"github.com/Shopify/go-lua"
)
func main() {
state := lua.NewState()
defer state.Close()
// 加载 Lua 代码
lua.DoString(state, `
function add(a, b)
return a + b
end
`)
// 调用 Lua 函数
lua.GetGlobal(state, "add")
lua.PushInteger(state, 1)
lua.PushInteger(state, 2)
lua.Call(state, 2, 1)
// 获取 Lua 函数返回值
result := lua.ToInteger(state, -1)
lua.Pop(state, 1)
fmt.Println(result)
}
漫画 动画 日本文化
2023-04-18
人物关系
时间线
-
两千年前,尤弥尔生活的村子遭遇艾尔迪亚人入侵,尤弥尔与其他村民一样,被割去舌头,成为初代弗里茨王的奴隶。
-
谁放跑了猪事件:猪圈没有关,猪逃跑了。初代弗里茨王要求犯人主动承认,否则所有奴隶挖掉一只眼睛。众奴隶指认尤弥尔,尤弥尔被当做猎杀游戏的猎物。
-
尤弥尔是一个心地善良,时刻为他人着想的人。放走小猪可能真是她做的。
-
你自由了,然后开始猎杀。这和后面“自由”这个词每每包含不好的寓意相呼应(艾伦放弃了所有一生追寻的自由也是毫无意义,反而成为自由的奴隶)。
-
受伤的尤弥尔逃到一棵大树下,意外跌落到树洞里的水坑中,接触怪诞虫,获得巨人之力。
-
始祖尤弥尔的巨人形态看起来非常巨大。
-
奴性太强,导致尤弥尔继续回到了初代弗里茨王的身边,继续做奴隶,并成为生育机器为其生下三个女儿:玛利亚,罗塞,希娜。
-
帕拉迪岛(乐园)三堵墙的名字就是从这里来的。
-
驻足观望他人婚礼的画面似乎想说明她对爱情的渴望。加上奴性的缘故,和弗里茨王生育子女可能使其产生了一种畸形的、单向的、受虐狂的爱。
-
艾尔迪亚人获得尤弥尔这个大杀器之后疯狂使用,使艾尔迪亚从一个小部落一跃而成当时最强大的帝国。与之相随的是曾经强大的马莱帝国覆灭。
-
枭对格里沙说的话可以参考:
马莱人讲,艾尔迪亚人对他们实行民族清洗。
可是哪有能经历两千年的清洗不被消灭,反而能迅速崛起,称霸全球的民族。
艾族人说,他们只是利用巨人之路修路搭桥搞建设。
这恐怕也不符合我对人性的认知。
-
十三年后,被压迫的人(可能是同族,也可能是他族)反抗,刺杀初代弗里茨王。始祖尤弥尔替王挡枪。
王命令尤弥尔站起来:“这根本不能伤害到你!”
可是尤弥尔没有生的欲望,违背了王的命令,然后闭上眼睛死去。
-
这导致后面每一代巨人获得巨人之力 13 年之后死亡(就是一个强设定,没有原因)。
-
初代弗里茨王命令尤弥尔的三个女儿吃掉尤弥尔的身体,从而使得巨人之力继续传承。
-
不知道怎么回事,最后巨人之力分裂成了 9 份,分别是始祖巨人、超大型巨人、进击的巨人、女型巨人、铠之巨人、颚之巨人、兽之巨人、战锤巨人、车力巨人。
- 始祖巨人的能力最为逆天,能控制艾族人的思想,改变艾族人的基因等等等等。
- 这 9 个巨人也被称之为智慧巨人,持有者(宿主)在有强烈意愿并受伤的情况下能够变身,然后也可以从巨人脖子上剥离出来。
- 根据后面的剧情,持有者刚继承的时候可能会失忆,操作也不熟练。
-
巨人只能由艾尔迪亚人继承,一个艾尔迪亚人能够同时继承多份巨人之力。
- 主角艾伦最后同时拥有始祖巨人、进击的巨人、战锤巨人
- 进击巨人:枭 -> 格里沙 -> 艾伦
- 始祖巨人:乌利 -> 弗丽达 -> 格里沙 -> 艾伦
- 战锤巨人:戴巴家族 -> 艾伦
-
145 代弗里茨王 —— 卡尔·弗里茨,不战之约。
-
巨人信息:
-
始祖巨人 :墙内之王
- 进击的巨人 :追求自由,枭 -> 格里沙
- 战锤巨人 :马莱高层
- 超大型巨人 :马莱战士,体型大
- 女型巨人 :马莱战士,
- 铠之巨人 :马莱战士,
- 颚之巨人 :马莱战士,灵活,咬合力
- 兽之巨人 :马莱战士,远程攻击
- 车力巨人 :马莱战士,战力有限
巨人不用吃东西,可以永生。
吃了人也无法消化,之后又会吐出来。
网上有资料说,曾经有孕妇被巨人吃下去,然后吐出来,肚子里的孩子存活。
-
帕拉迪岛信息:
- 100 多年前,巨人突然出现,人类几乎被炫干净了,只剩最后一小部分人筑墙,挡住巨人攻势。
- 立体机动装置(可以让人变成蜘蛛侠,需要 “瓦斯” 喷气反作用力推进)。
- 巨人可以通过切断脖子斩杀。但是故事开始的时候斩杀巨人还非常困难。
- 曾经有一个矿工试图尝试从地下挖出去,结果发现墙壁在地下还有很深,挖了几个小时都没有挖到头。
后来和朋友都失踪了。
- 宗教,牧师,墙崇拜。
-
格里沙·耶格尔是调查兵团团长基斯·夏迪斯在墙外调查救回来的。
格里沙自称失忆,只记得自己是一名医生。后来和基斯成为好友,了解到墙内的很多事情。
当时基斯暗恋着卡尔菈·耶格尔。也正因为这个关系,格里沙和卡尔菈相识,后面结婚了,生下艾伦。
-
尤弥尔还是马莱的一个无名小乞丐,被一些人选中,取尤弥尔这个名字,冒充艾尔迪亚王室,充当救世主,接受马莱收容所艾族人跪拜。
-
785 年(大约),尤弥尔所在团体被查获,尤弥尔和组织者被放逐到帕拉迪岛。
-
832 年,牺牲 20 人的代价,成功捕捉巨人(伊尔泽剧情提及)。
-
843 年,马莱巨人战士候补生的选拔(六选五)中,马赛为了保护弟弟波尔克(智慧巨人只有 13 年寿命),在评比中动了手脚,刻意将弟弟刷下去,从而吊车尾的莱纳才有了机会继承铠之巨人。
不知情的莱纳非常开心,获得荣誉马来人身份,找到亲生父亲,希望得到父亲的认可,从而可以一家人开心的生活在一起。但是父亲对他们母子依然非常厌恶。
-
844 年,埃尔文胁迫利威尔加入调查兵团。
第一次参与壁外调查(#23)时,利威尔的两个伙伴死亡。
-
844 年,三笠(也被翻译为米卡莎)父母双亡,被艾伦父母收养。重要节点:第一季开始
-
845 年,马莱派遣巨人战士队四位成员潜伏上岛,试图夺取始祖巨人。
- 颚之巨人 马赛‧加里亚德
- 铠之巨人 莱纳·布朗,后面的剧情中战绩感人,可以称得上“不胜巨人”
- 超大巨人 贝特霍尔德(贝尔托特)·胡佛
- 女巨人 阿尼·利昂纳德
刚一登岛,马赛向莱纳坦白巨人战士候补生选拔中的事情,莱纳愣住了。
结果埋在土了的尤弥尔突然冒出来,扑向莱纳,在场众人都懵了。
只有队长马赛反应过来,救下莱纳,但自己被吃掉。
剩下的几个人竟然都吓得逃跑了,包括被救下的莱纳。
结果马赛牺牲,颚之巨人也被夺走了。
马莱小队没有战斗觉悟的体现。
-
845 年,故事开始此时好友三人都 10 岁。希干希纳区沦陷
- 艾伦的梦境,流泪 伏笔
- 责备汉尼斯叔叔他们驻屯兵团不应该喝酒,应该有随时战斗的觉悟
- 调查兵团回城
基斯·夏迪斯,现任调查兵团团长
埃尔文·史密斯,分队长
- 三笠告密:艾伦想加入调查兵团
妈妈卡尔菈非常生气
爸爸格里沙·耶格尔许诺回家之后带艾伦去秘密地下室
阿明·阿诺德出场,被欺负,然后被艾伦和三笠救下,随即一起聊天,直到巨人来袭
- 超大巨人来袭,踢开大门,玛利亚之墙南部瓮城希干希纳区沦陷
- 被汉尼斯扛在肩上的三笠头疼:“又来了” 伏笔
- 几个小时之后,铠之巨人洞穿玛利亚之墙南门。
-
破墙的那天晚上,格里沙找到雷伊斯家,希望他们能出来拯救民众。
正好雷伊斯家正在举行巨人之力传承的仪式,乌利·雷伊斯被侄女弗丽达吃掉。弗丽达和叔叔一样,还是没有摆脱先辈不战之约的影响,放弃作战,拒绝拯救民众。
格里沙吃掉刚刚继承巨人之力的弗丽达,抢走了始祖巨人。
疑问:为什么这个时候格里沙自己没有出来战斗?可能是去治病的地方太远,赶回来的时候已经来不及了。然后打不过?
疑问:为什么夺始祖巨人,并杀光王血?艾伦的唆使,艾伦想拥有始祖巨人的力量。
-
不知道具体的时间点,格里沙找到艾伦,想让艾伦继承巨人之力。
这个时候基斯看到,对他说:“你又要对人施加诅咒了吗?”
随后在树林中,给艾伦地下室的钥匙,叮嘱他回去看看,然后给艾伦注射脊髓液,让艾伦吃掉自己继承进击巨人和始祖巨人。
第二集,艾伦梦境里有回忆到。艾伦一直在哭喊,“妈妈去世之后,爸爸就变得很奇怪”。
-
粮食危机 -> 开荒 -> 没起到什么作用
-
846 年,玛利亚之墙夺还战
总人口的 20%,大概 25 万人牺牲,最后只活下来一百多人。阿明的爷爷(漫画版是父母)也牺牲了。
-
847 年,伊尔泽·兰纳参与第 34 次壁外调查,牺牲。
失去马匹,立体机动装置损坏,孤身一人,在野外逃亡。一边记录壁外情报,一边向城墙方面赶路。
中途遭遇一个会说话的巨人,对伊尔泽跪拜,并说出:“尤弥尔大人,欢迎回来”。(认错人了,应该是和尤弥尔一起被放逐的那个组织的成员)
伊尔泽震惊之余,愤怒责问巨人为什么要吃人,明明不用吃人也能一直活着,你们应该从这个世界消失!这也是为了进一步获取情报。
不料,巨人随即失控,咬掉了伊尔泽的脑袋,将身体部分存放在树洞里面。
直到死亡的最后一刻,在巨人口中,还在记录巨人的情报:牙齿很大,嘴有点臭。
-
847 年,好友三人加入训练兵团 104 期,开始了 3 年的训练
基斯教官(受不了现实和理想的巨大反差,战士惨死带来的负罪感,兵团长职务已经换埃尔文了)
- 艾伦平衡性测试始终通不过,最后在卖命的训练下勉强合格。这时发现是艾伦的设备有故障,所以很难平衡。
- 后面《旁观者》中说,是基斯教官故意破坏的。应该是出于对卡尔菈的爱,就像斯内普对莉莉一样。
-
除好友三人之外,同一期的战友清单:
- 莎夏
- 让
- 故乡三人组
- 莱纳
- 贝尔托特
- 阿尼
- 尤弥尔
- 克里斯塔(真名:希斯特莉亚·雷伊斯,真王族罗德·雷伊斯的私生女)
- 柯尼
- 马可
- 约翰
-
849 年,第 49 次壁外调查,回收伊尔泽的笔记本。
里面关于巨人说话的情报还是给韩吉队长和调查兵团不小的震惊,随即调查兵团通过了韩吉的巨人捕捉计划,研究巨人。
-
850 年,104 期毕业
- 为什么能力强的去最安全的地方,远离战斗?
- 这一期中出了 6 个智慧巨人,一个女王。
- 一共 12 人加入调查兵团。
- 一共 n 人加入宪兵团。
-
850 年,第 57 次壁外调查,前往艾伦家的地下室,查明世界的真相。
真实目的是找奸细。
遭遇女巨人,损失惨重,伤亡过半。
最后推断出故乡三人组的奸细身份。
利威尔,艾伦,三笠几人进入地下室,了解到格里沙医生和墙外世界的信息。
随即 104 期新兵被解除武装,软禁在外面的一个地方(?),说是保护,其实是接受调查。
-
850 年,史托黑斯区作战,成功捕获女巨人阿尼,但阿尼最后时候将自己硬质化,没能获取更多情报。重要节点:第一季结束,第二季开始
但是阿尼逃跑的时候,将城墙外沿抓破,漏出一个可怖的超大巨人脸,眼睛还在动,众人吓傻。
尼克神父站出来请众人立即挡住巨人的脸,不能使之见到阳光。证实了墙内部分人知道世界的真相。
-
巨人来袭。直扑 104 期驻地。军团不知道是不是罗塞墙已被攻破。于是分兵三路,前往城墙调查。
兽之巨人出场(17 米)。
经过仔细检查之后,兵团发现城墙完全没有损坏,不过康尼村子被破坏了。
提出假想,巨人是康尼村子的人变成的。
-
尼克神父看到人民的惨状,只吐露了一个名字:104 期的战友,克里斯塔,她身上有真相的线索。随后被中央宪兵灭口。
韩吉队长不认识克里斯塔,三笠介绍:就是经常和尤弥尔在一起的女生。韩吉大为惊讶。(对应 VOA(伊尔泽的笔记)中,说话巨口中念叨的尤弥尔大人)
-
104 期逃到高塔上,被兽之巨人指挥无脑巨人围攻。
尤弥尔认识马莱那边的文字(罐头,兽之巨人带来的),被莱纳识破身份。
尤弥尔跳出,暴露自己,保护克里斯塔(S2E5 倒叙尤弥尔的经历,以及和克里斯塔的感情)。
危险关头,韩吉队长带人过来救援(三笠,艾伦等),终于化险为夷。尤弥尔的巨人身份也被完全公开了。
-
调查兵团就被王政府取缔,所有成员都即将被逮捕,因为在内城战斗,导致史托黑斯区 100 多人牺牲,还有财产损失。
-
种种证据指向王政府,埃尔文联合总统演戏,假装罗塞墙被攻破,测试王政府对人民的责任心。
王政府冷血的下令关闭城门禁止难民涌入。
随机政变发起,宣布王政府解散。
-
850 年,莱纳和贝尔托特在城墙上自曝身份(我凯他超),将艾伦掳走。
随即,调查兵团、驻屯兵团、宪兵团联合作战。
最后成功夺回艾伦,埃尔文团长被巨人咬断右臂,大部分人几乎全军覆没。
-
罗德·雷伊斯抓住艾伦,要女儿克里斯塔吃掉艾伦,夺回始祖巨人。
克里斯塔拒绝了自私的父亲,打翻针剂,并在摔爹 BGM 里把罗德摔断了腰。
罗德爬过去舔食脊髓液,结果变成前所未见的 120 米特大型奇行种(城墙超大巨高度的两倍),下半身依旧无法动弹,只能靠两只手往爬。
最后,罗德巨被克里斯塔当众斩杀。这个操作应该是在作秀,为了在不明真相的民众面前将克里斯塔打造成救世英雄,然后在伪王被政变推翻之后顺利继承王位。
-
850 年,玛利亚之墙夺回作战。
-
马赛的弟弟,波尔克,吃掉自愿回到马莱的颚之巨人尤弥尔,还是与马赛意愿相违地,继承了巨人之力。
-
854 年,马莱雷贝里欧收容区远征作战。
-
地鸣。
作战中,波尔克因为与艾伦接触,而看到哥哥的记忆,解除了和莱纳的误会。并同哥哥一样,为了救下莱纳,被无脑巨人法尔克吃掉。
KV
2023-04-16
有几个不是磁盘 KV,注意分辨。
库
服务