banner
sakiko🐘

sakiko🐘

可怜的孩子 不再胆怯
twitter
twitter
discord server

云服务器自动追番

这半年来我都是在次元图书馆追番的,但前段时间她好像出了点问题导致番剧不更新了,于是就逼着自己弄了这个追番工具小祥の小窝

小窝搭建的那几天真的是磕磕绊绊浑浑噩噩,不过当问题一点点解决时真的很高兴,希望这些快乐能通过这个小文章传达出去,其实自己也是很享受这个过程的

这个小窝的材料是:

  • 一个每月 3 刀的 1 核 1G、硬盘 10G、月流量 500G、带宽 50Mbps 的服务器,安装了宝塔面板
  • 一个在 porkbun 买的.top 域名,首年 1.6 刀续费 4.9 刀
  • 一颗勇敢的心

这个小窝的构造是:

  • 使用 Rclone 挂载 Onedrive 用于储存番剧
  • qBittorrent 通过 RSS 自动下载番剧
  • 配置 qBittorrent 下载完成后自动上传到 Onedrive
  • 最后使用 AList 挂载 Onedrive 在 Web 端展示

这个小窝的搭建过程是:

获取微软 E5 账号,配置 onedrive#

参考

白嫖微软 E5 开发者 免费使用 Office 正版、OneDrive 5T 存储空间! PDF

微软的 E5 开发者账号可以白嫖 onedrive 的储存空间 5T*26(主账号和 25 个子账号都有 5T)

申请 E5 开发者账号#

进入官网点击 joinnow 进行申请 https://developer.microsoft.com/en-us/microsoft-365/dev-program ,跟着引导走就好了

image-20231201130634905

申请完成后就会跳转至这个界面

image-20231201133121617

在这里就可以看到刚刚申请的开发者账号主账号,“用户名 @域.onmicrosoft.com”

配置子账户与 onedrive#

(其实直接用主账户也可以,但是感觉新建一个子账户会比较好)

现在进入 Microsoft 365 admin center 用户管理页面
https://admin.microsoft.com/#/users

image-20231201135840739

点击 Add a user 即可添加子账户

image-20231201142400248

然后这个 Assign product licenses 我也不清楚怎么填,其实我的子账户是自动创建,我看它是这么填的

image-20231201142839550

后面直接点 Next 直至完成添加

添加子账户后,点击子账户,在弹出的账户管理页面再点击 OneDrive,找到 Storage used 并点击 Edit 即可将空间设置为 5T。创建用户时的默认空间为 1T,也可以点击 Manage default storage 进行修改

image-20231201141527828

现在使用子账户登录 onedrive,就可以看到 5T 空间了

image-20231202103427211

关于 E5 续订问题#

E5 开发者账号首次订阅将会获得 90 天的订阅时间,续订无硬性条件,关键是看微软的算法是否会认为我们是在进行开发活动。

后面使用的 rclone 和 alist 每天上传下载番剧都要调用自己创建应用的 api,所以自动续订成功率应该还是很高的

如果自动续订失败,也还有 30 天的数据保留期,可以再申请一个 E5 账号转存一下,或者也可以联系我帮忙存()。好像续订失败 60 天之后就可以再次申请 E5 账号

关闭 microsoft authenticator 验证#

在账号创建之后,登录时可能会出现这个界面

Pasted image 20231110230940

Office365 强制 Microsoft Authenticator 验证登录如何关闭_office365 双重验证_高远科技 - Project 软件服务的博客 - CSDN 博客
参考上面这个,但是设置界面应该是改了,又重新摸索了一遍

Microsoft 365 admin center的菜单中点击 Show all,找到Identity

image-20231201150626196

点击后即进入了Microsoft Entra 管理中心

image-20231201151733639

找到 标识 - 概述 - 属性,然后在页面最后点击【管理安全默认值】将其设置为已禁用

image-20231201151834072

此时再登录就不会出现 microsoft authenticator 验证登录了

Rclone 挂载 onedrive#

参考

Linux 上使用 Rclone 挂载 OneDrive 或 GoogleDrive 并设置开机自启 - 知乎 PDF

在 Debian/Ubuntu 上使用 rclone 挂载 OneDrive 网盘 - Rat's Blog PDF

Rclone 进阶使用教程 – 自建私有 API 挂载 OneDrive | 安云网 – AnYun.ORG PDF

可以使用 Rclone 自带的 api(id 和密钥留空),也可以自建 api 来挂载。自建 api 应该更有助于 E5 续订

Windows 电脑上下载 Rclone 用于获取 token,下载地址https://rclone.org/downloads/

Linux 上安装 Rclone:curl https://rclone.org/install.sh | bash

自建私有 API#

自建私有 API 主要是要拿到客户端 ID:client_id客户端密钥:client_secret

登录进入 https://portal.azure.com/#home ,注意分清主账号与子账号,要挂载哪个账号的 onedrive 就用哪个

搜索应用注册,点击 服务 - 应用注册,点击新注册。
名称填写 rclone(随便起)
受支持的帐户类型:任何组织目录 (...) 中的帐户和个人 Microsoft 帐户 (...),
重定向 URI:Web http://localhost

Pasted image 20231119113214

完成注册后得到应用程序 (客户端) ID(client_id

image-20231201180737360

再选择 "证书和密码",点击 "新客户端密码",说明随便写可以为空,选择时间为最长的那个,点击 "添加"

image-20231201181420468

之后就得到客户端密码 client_secret

image-20231201182019817

(注:client_secret 是 “值” 而不是 “机密 ID”,在添加之后密码之后会消失,请及时记录下来)

设置 API 权限
点击API 权限,点击 "Microsoft Graph",添加Files.ReadFiles.ReadWriteFiles.Read.AllFiles.ReadWrite.Alloffline_accessUser.Read这些权限(可以搜索添加)。

image-20231201182619972

点击更新权限后,再确认一下权限

Pasted image 20231119121121

Rclone 使用自建 api 挂载 onedrive#

获取 token

在本地电脑上下载 rclone。以 Windows 为例子,解压并进入rclone.exe所在文件夹,在资源管理器地址栏输入cmd,回车就会在当前路径打开命令提示符。

使用上一步获取的客户端 ID:client_id客户端密钥:client_secret,替换以下命令中的Client_IDClient_secret并执行。
rclone authorize "onedrive" "Client_ID" "Client_secret"

在浏览器弹出的微软登录窗口登陆并授权后(注意分清登录的账号),命令提示符窗口会出现token,复制并保存好

Rclone 连接配置

在 linux 中输入命令rclone config并根据提示进行设置
TIPS: 因为 RCLONE 会时不时进行更新,当你看到这篇教程时菜单选项可能已经发生了略微的改动,但大致思路不会变,不要无脑照搬操作。)

挂载 OneDrive

创建挂载目录,根据个人喜好选位置,我选择在了 /home/onedrive

DriveName为初始化配置填的nameFolderOneDrive里的文件夹,LocalFolderVPS上的本地文件夹。

如果挂载过程中出现NOTICE: One drive root 'test': poll-interval is not supported by this remote错误,可以无视该错误。

如果出现含有 "fusermount3" 的报错,则要安装 fuse3:yum install fuse3

执行挂载命令后,在新终端窗口输入df -h命令查看

image-20231202102411407

确保挂载成功后,ctrl+c停止或关闭执行挂载命令的窗口,开始设置开机自启

开机自启#

适用于使用systemctl命令的 linux

#将后面修改成你上面手动运行命令中,除了rclone的全部参数
command=" mount onedrive:/ /home/onedrive  --copy-links --no-gzip-encoding --no-check-certificate --allow-other --allow-non-empty --umask 000"
#以下是一整条命令,一起复制到SSH客户端运行
cat > /etc/systemd/system/rclone.service <<EOF
[Unit]
Description=Rclone
After=network-online.target

[Service]
Type=simple
ExecStart=$(command -v rclone) ${command}
Restart=on-abort
User=root

[Install]
WantedBy=default.target
EOF

启动:systemctl start rclone
设置开机自启: systemctl enable rclone
重启:systemctl restart rclone
停止:systemctl stop rclone
状态:systemctl status rclone

重启一下,如果没问题的话,rclone 挂载 onedrive 就完成啦

安装配置 qBittorrent-nox#

参考

qBittorrent+Rclone 实现自动上传到 Onedrive,Google Drive 等储存,并自动删除本地文件 – 极客轩 PDF

yum 安装的 qb 版本太低(AutoBangumi 会连不上,困扰了好久),而编译安装太麻烦好像还需要大内存,所以使用可执行版的 qb。这是上面的文章提到的
Releases · userdocs/qbittorrent-nox-static

安装 qbittorrent-nox#

#下载
wget "https://github.com/userdocs/qbittorrent-nox-static/releases/download/release-4.6.0_v2.0.9/x86_64-qbittorrent-nox"
#移动到程序目录并重命名qbittorrent-nox
mv ./x86_64-qbittorrent-nox /usr/bin/qbittorrent-nox
#赋予执行权
chmod a+x /usr/bin/qbittorrent-nox

初始化 qb

完成后执行命令qbittorrent-nox,输入 y 并回车以确认使用协议。访问 http://服务器公网IP地址:8080 来控制 qb,要开放 8080 端口

输入 Web UI 的初始用户名 admin 和初始密码 adminadmin登录。然后马上重新设置新用户名和密码并保存

image-20231202113937707

如果一切正常,在终端Ctrl + C停止 qb,开始设置开机自启

设置开机自启

cat > /etc/systemd/system/qbittorrent.service << EOF
[Unit]
Description=qBittorrent Daemon Service
After=network.target

[Service]
LimitNOFILE=512000
User=root
ExecStart=/usr/bin/qbittorrent-nox
ExecStop=/usr/bin/killall -w qbittorrent-nox

[Install]
WantedBy=multi-user.target

EOF

启动:systemctl start qbittorrent
设置开机自启: systemctl enable qbittorrent

现在 qBittorrent-nox 的安装就基本完成了,以下是根据自己情况的一些设置

配置 qBittorrent-nox

开放 qb 的监听端口

image-20231202114747908

image-20231202115159633

下载 - 为所有文件预分配磁盘空间,以防止下载空间不够

速度 - 全局速度限制,限制一下下载速度,防止后面设置的自动上传 onedrive 跟不上下载速度

BitTorrent-Torrent 排队,设置最大活动下载数为 1

BTTracker:https://github.com/XIU2/TrackersListCollection/blob/master/README-ZH.md

下载完成后自动上传#

准备自动上传脚本

自动上传脚本:qBittorrent+Rclone 实现自动上传到 Onedrive,Google Drive 等储存,并自动删除本地文件 – 极客轩

为了将番剧保存在合适的目录,我又做了一点修改:qb_auto.sh

按照自己的信息修改脚本上面的配置,然后将脚本上传到服务器,我保存在了/root/qbauto/qb_auto.sh

还要给脚本执行权限 chmod a+x /root/qbauto/qb_auto.sh

#!/bin/bash
torrent_name=$1
content_dir=$2
root_dir=$3
save_dir=$4
files_num=$5
torrent_size=$6
file_hash=$7
qb_version="4.6.0"    # 改成你的qbit版本
qb_username="xxxxxx"    # qbit用户名
qb_password="xxxxxxxxx"    # qbit密码
qb_web_url="http://localhost:8080"    # qbit webui地址
leeching_mode="true"    # 吸血模式,true下载完成后自动删除本地种子和文件
log_dir="/root/qbauto"    # 日志输出目录
rclone_dest="onedrive"    # rclone配置的储存名
rclone_parallel="32"    # qbit上传线程,默认4
auto_del_flag="rclone"    # 添加标签或者分类来标识已上传的种子 v4.0.4+版本添加标签“rclone”,低版本通过添加分类“rclone”标识
# 改上面的那些参数即可

# 2023-11-15, 由Sakiko添加
# 云盘的保存路径,用主机上的下载路径截取出云盘的保存路径
# 如下载路径为/root/Downloads/Sakiko/Bangumi/xxx,则将截取出/Sakiko/Bangumi/xxx,并会以此路径保存在云盘
# 可根据自己的下载路径修改“/root/Downloads”
rclone_dest_save_dir=${save_dir#*/root/Downloads}

 
if [ ! -d ${log_dir} ]
then
        mkdir -p ${log_dir}
fi
 
version=$(echo $qb_version | grep -P -o "([0-9]\.){2}[0-9]" | sed s/\\.//g)
 
function qb_login(){
        if [ ${version} -gt 404 ]
        then
                qb_v="1"
                cookie=$(curl -i --header "Referer: ${qb_web_url}" --data "username=${qb_username}&password=${qb_password}" "${qb_web_url}/api/v2/auth/login" | grep -P -o 'SID=\S{32}')
                if [ -n ${cookie} ]
                then
                        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录成功!cookie:${cookie}" >> ${log_dir}/autodel.log
 
                else
                        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录失败!" >> ${log_dir}/autodel.log
                fi
        elif [[ ${version} -le 404 && ${version} -ge 320 ]]
        then
                qb_v="2"
                cookie=$(curl -i --header "Referer: ${qb_web_url}" --data "username=${qb_username}&password=${qb_password}" "${qb_web_url}/login" | grep -P -o 'SID=\S{32}')
                if [ -n ${cookie} ]
                then
                        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录成功!cookie:${cookie}" >> ${log_dir}/autodel.log
                else
                        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录失败" >> ${log_dir}/autodel.log
                fi
        elif [[ ${version} -ge 310 && ${version} -lt 320 ]]
        then
                qb_v="3"
                echo "陈年老版本,请及时升级"
                exit
        else
                qb_v="0"
                exit
        fi
}
 
 
 
function qb_del(){
        if [ ${leeching_mode} == "true" ]
        then
                if [ ${qb_v} == "1" ]
                then
                        curl -X POST -d "hashes=${file_hash}&deleteFiles=true" "${qb_web_url}/api/v2/torrents/delete" --cookie ${cookie}
                        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 删除成功!种子名称:${torrent_name}" >> ${log_dir}/qb.log
                elif [ ${qb_v} == "2" ]
                then
                        curl -X POST -d "hashes=${file_hash}&deleteFiles=true" "${qb_web_url}/api/v2/torrents/delete" --cookie ${cookie}
                else
                        curl -X POST -d "hashes=${file_hash}&deleteFiles=true" "${qb_web_url}/api/v2/torrents/delete" --cookie ${cookie}
                        echo "[$(date '+%Y-%m-%d %H:%M:%S')] 删除成功!种子文件:${torrent_name}" >> ${log_dir}/qb.log
                        echo "qb_v=${qb_v}" >> ${log_dir}/qb.log
                fi
        else
                echo "[$(date '+%Y-%m-%d %H:%M:%S')] 不自动删除已上传种子" >> ${log_dir}/qb.log
        fi
}

# 2023-11-15, 由Sakiko注释
# function rclone_copy(){
#         if [ ${type} == "file" ]
#         then
#                 rclone_copy_cmd=$(rclone -v copy --transfers ${rclone_parallel} --log-file  ${log_dir}/qbauto_copy.log "${content_dir}" ${rclone_dest}:/qbit/)
#         elif [ ${type} == "dir" ]
#         then
#                 rclone_copy_cmd=$(rclone -v copy --transfers ${rclone_parallel} --log-file ${log_dir}/qbauto_copy.log "${content_dir}"/ ${rclone_dest}:/qbit/"${torrent_name}")
#         fi
# }

# 2023-11-15, 由Sakiko添加
# 修改rclone_copy函数,使其在云盘上传时,保存在自定义自动截取后的下载路径rclone_dest_save_dir
function rclone_copy(){
        if [ ${type} == "file" ]
        then
                rclone_copy_cmd=$(rclone -v copy --transfers ${rclone_parallel} --log-file  ${log_dir}/qbauto_copy.log "${content_dir}" ${rclone_dest}:"${rclone_dest_save_dir}"/)
        elif [ ${type} == "dir" ]
        then
                rclone_copy_cmd=$(rclone -v copy --transfers ${rclone_parallel} --log-file ${log_dir}/qbauto_copy.log "${content_dir}"/ ${rclone_dest}:"${rclone_dest_save_dir}"/"${torrent_name}")
        fi
}


function qb_add_auto_del_tags(){
        if [ ${qb_v} == "1" ]
        then
                curl -X POST -d "hashes=${file_hash}&tags=${auto_del_flag}" "${qb_web_url}/api/v2/torrents/addTags" --cookie "${cookie}"
        elif [ ${qb_v} == "2" ]
        then
                curl -X POST -d "hashes=${file_hash}&category=${auto_del_flag}" "${qb_web_url}/command/setCategory" --cookie ${cookie}
        else
                echo "qb_v=${qb_v}" >> ${log_dir}/qb.log
        fi
}
 
if [ -f "${content_dir}" ]
then
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:文件" >> ${log_dir}/qb.log
   type="file"
   rclone_copy
   qb_login
   qb_add_auto_del_tags
   qb_del
#   rm -rf ${content_dir}
elif [ -d "${content_dir}" ]
then 
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:目录" >> ${log_dir}/qb.log
   type="dir"
   rclone_copy
   qb_login
   qb_add_auto_del_tags
   qb_del
#   rm -rf ${content_dir}
else
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 未知类型,取消上传" >> ${log_dir}/qb.log
fi
 
echo "种子名称:${torrent_name}" >> ${log_dir}/qb.log
echo "内容路径:${content_dir}" >> ${log_dir}/qb.log
echo "根目录:${root_dir}" >> ${log_dir}/qb.log
echo "保存路径:${save_dir}" >> ${log_dir}/qb.log
echo "文件数:${files_num}" >> ${log_dir}/qb.log
echo "文件大小:${torrent_size}Bytes" >> ${log_dir}/qb.log
echo "HASH:${file_hash}" >> ${log_dir}/qb.log
echo "Cookie:${cookie}" >> ${log_dir}/qb.log
echo -e "-------------------------------------------------------------\n" >> ${log_dir}/qb.log

配置 qb 自动上传

来到 qbit 设置,下载选项,找到 torrent 完成时运行外部程序,勾选,填入下面的命令,/root/qbauto/qb_auto.sh 是我脚本的地址,改成你自己的,最后保存即可

bash /root/qbauto/qb_auto.sh  "%N" "%F" "%R" "%D" "%C" "%Z" "%I"

image-20231202140049439

到此已经实现了自动上传的功能,可以下个磁力试试啦

有一点需要道歉,一直在吸血真的对不起捏,硬盘真的太小了🥺,加硬盘每月还要多花 1 刀😢

通过 RSS 下载番剧#

其实现在我也用 AutoBangumi 进行下载。不过作者发推说担心法律之类的问题,有点愧疚,还是低调一点使用比较好。

AB 也不是必须的,qb 也有 RSS 订阅功能,只是会麻烦一点

主要使用以下番剧下载站点:

一,蜜柑计划
网站地址 : https://mikanani.me/ https://mikanime.tv/

二,动漫花园
网站地址 : https://share.dmhy.org/

【网站收藏夹】番剧下载站点推荐

通过蜜柑计划下载番剧

通过主页的链接或者搜搜进入番剧的页面,选择心仪的字幕组(个人喜欢 ANI),

image-20231202155743825

然后点击 RSS 图标并在跳转的页面复制地址

image-20231202160042198

打开自己的 qb,点击右上角 RSS,再点击新 RSS 订阅,输入刚才复制的链接并确定

image-20231202174134105

RSS 订阅添加完毕之后,再点击右上角的 RSS 下载器,点击加号添加下载规则并取名

image-20231202175759335

RSS 订阅添加完毕之后,点击规则进行设置。设置保存目录,选择正确的订阅源应用规则。
还要设置必须不含\d+-\d防止其下载合集(虽然蜜柑的 [ANI] 一般没合集但还是加上比较好)

image-20231202190613753

点击保存后右侧就会出现匹配的番剧并开始下载。

下载完成后,自动上传脚本上传就会根据我设置的保存路径上传到 onedrive 的/Sakiko/Bangumi/狩龙人拉格纳/Season 1目录里。

RSS 订阅源更新间隔 默认是 30 分钟,可以在 选项 - RSS 里设置。每 30 分钟就会检查番剧更新并下载

简繁筛选

蜜柑中有的字幕组简体繁体都有,此时设置必须包含简体即可。更复杂的筛选可使用正则表达式

动漫花园番剧下载

动漫花园要灵活使用搜索筛选番剧获取 RSS

image-20231202192855184

安装配置 AList 挂载 onedrive#

🗂️A file list/WebDAV program that supports multiple storages, powered by Gin and Solidjs. / 一个支持多存储的文件列表/WebDAV程序,使用 Gin 和 Solidjs。

Home | AList 文档

安装#

根据官网的教程安装,我是使用 Docker 安装的

官网教程:https://alist.nn.ci/zh/guide/install/docker.html

# docker-cli
docker run -d --restart=always -v /etc/alist:/opt/alist/data -p 5244:5244 -e PUID=0 -e PGID=0 -e UMASK=022 --name="alist" xhofe/alist:latest

# 安装完成后需手动设置密码
# 随机生成一个密码
docker exec -it alist ./alist admin random
# 手动设置一个密码,`NEW_PASSWORD`是指你需要设置的密码
docker exec -it alist ./alist admin set NEW_PASSWORD

安装后访问 http://服务器公网IP地址:5244 来登录 Alist,用户名为 admin,密码为刚才设置的

image-20231202194715507

登陆后点击页面下方的管理即可再次设置用户名密码,还可以设置图标、标题

挂载 onedrive#

官网教程:https://alist.nn.ci/zh/guide/drivers/onedrive.html

在 AList 管理页面选择储存,点击添加,驱动选择 Onedrive 即可看到下面的页面

image-20231202201004366

这么多选项之中,需要自己获取的主要是客户端 ID、客户端密钥、刷新令牌

这些东西就和上面 Rclone 挂载 onedrive 中的东西是一个性质,要像上面一样创建应用来获取。

还是有一点不一样的,主要还是看官网教程 https://alist.nn.ci/zh/guide/drivers/onedrive.html ,注册应用时重定向 URL 为 https://alist.nn.ci/tool/onedrive/callback

注册应用后得到了客户端 ID、客户端密钥,再在https://alist.nn.ci/tool/onedrive/request 填写即可获得刷新令牌

现在即可开始onedrive 添加内容填写

点击添加,完成

image-20231202205435281

现在访问主页即可看到 onedrive 文件夹

image-20231202210120707

游客配置#

现在自己的 AList 只能登陆后查看,通过配置游客账户不登陆就可以查看

在 AList 管理页面选择用户,然后启用 guest 游客账户即可

image-20231202210750990

通过设置基本路径可以让指定的目录为主页,现在游客看的目录就是 Sakiko

image-20231202211052419

至于下面的介绍,在 onedrive 里的 / Sakiko 目录里上传一个 readme.md 就可以了

到现在都是还在用 ip + 端口号访问,配置反向代理就可以通过域名访问了

配置反向代理映射域名#

还是看 AList 官方的教程:https://alist.nn.ci/zh/guide/install/reverse-proxy.html

使用宝塔面板的话很简单,可以模仿着给 qbittorrent 也弄一下

最终的效果就是这样,可以在线观看或下载,速度是比较快的,因为其不走服务器的流量而是直接从 Onedrive 下载(好像是 WebDAV 策略 302 重定向?),这一点非常好

image-20231202212136159

F-_m7xZaYAE0LgZ

其他#

在 qb 无下载时重启#

我一直是在宝塔面板设置了周一凌晨重启服务器,但如果 qb 还有下载任务就可能出问题,

于是就在重启脚本里判断下载目录里还有没有文件,没有文件即代表没有下载任务,再重启

#!/bin/bash  
  
folder="/root/Downloads"  
files=$(find "$folder" -type f)  

echo "$(date +%Y-%m-%d)"
if [ -n "$files" ]; then  
    echo "疑似正在下载:"  
    echo "$files"  
    echo "取消重启"
else  
    echo "状态正常,进行重启"  
    reboot
fi

解决 Alist 打开页面缓慢#

Alist 管理后台 - 设置 - 全局,将自定义头部内容替换成阿里云 CDN 解决 Alist 打开页面缓慢、加载慢 - 哔哩哔哩

后记#

啊,终于写完了,其中肯定还会有许多 baka 的地方吧,还希望大家能教我。

小窝的灵感正是来自次元图书馆馆长的我的追番解决方案,当时看到时是有点被小小的震撼到的。其实这段时间之前我连 docker 都不知道,这个小窝与这个小文章真的让我学到了很多,让我给 xlog 配置了域名,又让我弄了 MetaMask 钱包,终于让我向着憧憬的靠近了一点

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.