Minecraft村民职业与工作方块对照表

职业 工作方块
盔甲匠 高炉
屠夫 烟熏炉
制图师 制图台
牧师 酿造台
农民 堆肥桶
渔夫 木桶
制箭师 制箭台
皮匠 炼药锅
图书管理员 讲台
石匠 切石机
牧羊人 织布机
工具匠 锻造台
武器匠 砂轮

libcurl编译教程

一、简介

libcurl 是一个跨平台的网络协议库,支持 http, https, ftp, gopher, telnet, dict, file, 和 ldap 协议。libcurl 同样支持 HTTPS 证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP 基本表单上传,代理,cookies 和用户认证。想要知道更多关于 libcurl 的介绍,可以到官网 http://curl.haxx.se/上去了解,在这里不再详述。

二、下载 libcurl 源文件

libcurl 没有提供编译好的库,需要自己编译,先下载 libcurl 源代码。下载方式:

libcurl 官网:https://curl.haxx.se/download.html

三、编译 nmake

1.下载完成后解压,并进入文件夹,运行buildconf.bat(可选)

2.开始菜单中打开 x64 Native Tools Command Prompt for VS xxx

3.进入 curl 文件夹中的 winbuild 文件夹。

4.静态编译

nmake /f Makefile.vc mode=static VC=15 MACHINE=x64 DEBUG=no

如需动态编译,将 mode=static 改为 mode=dll。(本文仅演示静态编译,同时 curl 官方也不建议使用动态编译)

如需编译为 x86,将 MACHINE=x64 改为 MACHINE=x86。

如需编译为debug版,将DEBUG=no改为DEBUG=yes。

如果你是 VS2019,VC=15 建议改为 VC=14。

更详细的编译指令及说明可以打开 winbuild 文件夹中的 BUILD.WINDOWS.txt 查看。

输出位置: CURL代码位置\builds\libcurl-vc15-x64-release-static-ipv6-sspi-schannel。

x-ui一键安装脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/bin/bash

red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

cur_dir=$(pwd)

# check root
[[ $EUID -ne 0 ]] && echo -e "${red}错误:${plain} 必须使用root用户运行此脚本!\n" && exit 1

# check os
if [[ -f /etc/redhat-release ]]; then
release="centos"
elif cat /etc/issue | grep -Eqi "debian"; then
release="debian"
elif cat /etc/issue | grep -Eqi "ubuntu"; then
release="ubuntu"
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
release="centos"
elif cat /proc/version | grep -Eqi "debian"; then
release="debian"
elif cat /proc/version | grep -Eqi "ubuntu"; then
release="ubuntu"
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
release="centos"
else
echo -e "${red}未检测到系统版本,请联系脚本作者!${plain}\n" && exit 1
fi

arch=$(arch)

if [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then
arch="amd64"
elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then
arch="arm64"
elif [[ $arch == "s390x" ]]; then
arch="s390x"
else
arch="amd64"
echo -e "${red}检测架构失败,使用默认架构: ${arch}${plain}"
fi

echo "架构: ${arch}"

if [ $(getconf WORD_BIT) != '32' ] && [ $(getconf LONG_BIT) != '64' ]; then
echo "本软件不支持 32 位系统(x86),请使用 64 位系统(x86_64),如果检测有误,请联系作者"
exit -1
fi

os_version=""

# os version
if [[ -f /etc/os-release ]]; then
os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release)
fi
if [[ -z "$os_version" && -f /etc/lsb-release ]]; then
os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release)
fi

if [[ x"${release}" == x"centos" ]]; then
if [[ ${os_version} -le 6 ]]; then
echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1
fi
elif [[ x"${release}" == x"ubuntu" ]]; then
if [[ ${os_version} -lt 16 ]]; then
echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1
fi
elif [[ x"${release}" == x"debian" ]]; then
if [[ ${os_version} -lt 8 ]]; then
echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1
fi
fi

install_base() {
if [[ x"${release}" == x"centos" ]]; then
yum install wget curl tar -y
else
apt install wget curl tar -y
fi
}

#This function will be called when user installed x-ui out of sercurity
config_after_install() {
echo -e "${yellow}出于安全考虑,安装/更新完成后需要强制修改端口与账户密码${plain}"
read -p "确认是否继续?[y/n]": config_confirm
if [[ x"${config_confirm}" == x"y" || x"${config_confirm}" == x"Y" ]]; then
read -p "请设置您的账户名:" config_account
echo -e "${yellow}您的账户名将设定为:${config_account}${plain}"
read -p "请设置您的账户密码:" config_password
echo -e "${yellow}您的账户密码将设定为:${config_password}${plain}"
read -p "请设置面板访问端口:" config_port
echo -e "${yellow}您的面板访问端口将设定为:${config_port}${plain}"
echo -e "${yellow}确认设定,设定中${plain}"
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
echo -e "${yellow}账户密码设定完成${plain}"
/usr/local/x-ui/x-ui setting -port ${config_port}
echo -e "${yellow}面板端口设定完成${plain}"
else
echo -e "${red}已取消,所有设置项均为默认设置,请及时修改${plain}"
fi
}

install_x-ui() {
systemctl stop x-ui
cd /usr/local/

if [ $# == 0 ]; then
last_version=$(curl -Ls "https://api.github.com/repos/vaxilu/x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [[ ! -n "$last_version" ]]; then
echo -e "${red}检测 x-ui 版本失败,可能是超出 Github API 限制,请稍后再试,或手动指定 x-ui 版本安装${plain}"
exit 1
fi
echo -e "检测到 x-ui 最新版本:${last_version},开始安装"
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz https://github.com/vaxilu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz
if [[ $? -ne 0 ]]; then
echo -e "${red}下载 x-ui 失败,请确保你的服务器能够下载 Github 的文件${plain}"
exit 1
fi
else
last_version=$1
url="https://github.com/vaxilu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz"
echo -e "开始安装 x-ui v$1"
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz ${url}
if [[ $? -ne 0 ]]; then
echo -e "${red}下载 x-ui v$1 失败,请确保此版本存在${plain}"
exit 1
fi
fi

if [[ -e /usr/local/x-ui/ ]]; then
rm /usr/local/x-ui/ -rf
fi

tar zxvf x-ui-linux-${arch}.tar.gz
rm x-ui-linux-${arch}.tar.gz -f
cd x-ui
chmod +x x-ui bin/xray-linux-${arch}
cp -f x-ui.service /etc/systemd/system/
wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/vaxilu/x-ui/main/x-ui.sh
chmod +x /usr/local/x-ui/x-ui.sh
chmod +x /usr/bin/x-ui
config_after_install
#echo -e "如果是全新安装,默认网页端口为 ${green}54321${plain},用户名和密码默认都是 ${green}admin${plain}"
#echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保 54321 端口已放行${plain}"
# echo -e "若想将 54321 修改为其它端口,输入 x-ui 命令进行修改,同样也要确保你修改的端口也是放行的"
#echo -e ""
#echo -e "如果是更新面板,则按你之前的方式访问面板"
#echo -e ""
systemctl daemon-reload
systemctl enable x-ui
systemctl start x-ui
echo -e "${green}x-ui v${last_version}${plain} 安装完成,面板已启动,"
echo -e ""
echo -e "x-ui 管理脚本使用方法: "
echo -e "----------------------------------------------"
echo -e "x-ui - 显示管理菜单 (功能更多)"
echo -e "x-ui start - 启动 x-ui 面板"
echo -e "x-ui stop - 停止 x-ui 面板"
echo -e "x-ui restart - 重启 x-ui 面板"
echo -e "x-ui status - 查看 x-ui 状态"
echo -e "x-ui enable - 设置 x-ui 开机自启"
echo -e "x-ui disable - 取消 x-ui 开机自启"
echo -e "x-ui log - 查看 x-ui 日志"
echo -e "x-ui v2-ui - 迁移本机器的 v2-ui 账号数据至 x-ui"
echo -e "x-ui update - 更新 x-ui 面板"
echo -e "x-ui install - 安装 x-ui 面板"
echo -e "x-ui uninstall - 卸载 x-ui 面板"
echo -e "----------------------------------------------"
}

echo -e "${green}开始安装${plain}"
install_base
install_x-ui $1

socks5安装脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/bin/sh
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

#Check OS
if [ -n "$(grep 'Aliyun Linux release' /etc/issue)" -o -e /etc/redhat-release ];then
OS=CentOS
[ -n "$(grep ' 7\.' /etc/redhat-release)" ] && CentOS_RHEL_version=7
[ -n "$(grep ' 6\.' /etc/redhat-release)" -o -n "$(grep 'Aliyun Linux release6 15' /etc/issue)" ] && CentOS_RHEL_version=6
[ -n "$(grep ' 5\.' /etc/redhat-release)" -o -n "$(grep 'Aliyun Linux release5' /etc/issue)" ] && CentOS_RHEL_version=5
elif [ -n "$(grep 'Amazon Linux AMI release' /etc/issue)" -o -e /etc/system-release ];then
OS=CentOS
CentOS_RHEL_version=6
elif [ -n "$(grep bian /etc/issue)" -o "$(lsb_release -is 2>/dev/null)" == 'Debian' ];then
OS=Debian
[ ! -e "$(which lsb_release)" ] && { apt-get -y update; apt-get -y install lsb-release; clear; }
Debian_version=$(lsb_release -sr | awk -F. '{print $1}')
elif [ -n "$(grep Deepin /etc/issue)" -o "$(lsb_release -is 2>/dev/null)" == 'Deepin' ];then
OS=Debian
[ ! -e "$(which lsb_release)" ] && { apt-get -y update; apt-get -y install lsb-release; clear; }
Debian_version=$(lsb_release -sr | awk -F. '{print $1}')
elif [ -n "$(grep Ubuntu /etc/issue)" -o "$(lsb_release -is 2>/dev/null)" == 'Ubuntu' -o -n "$(grep 'Linux Mint' /etc/issue)" ];then
OS=Ubuntu
[ ! -e "$(which lsb_release)" ] && { apt-get -y update; apt-get -y install lsb-release; clear; }
Ubuntu_version=$(lsb_release -sr | awk -F. '{print $1}')
[ -n "$(grep 'Linux Mint 18' /etc/issue)" ] && Ubuntu_version=16
else
echo "Does not support this OS, Please contact the author! "
kill -9 $$
fi

#Install Basic Tools
if [[ ${OS} == Ubuntu ]];then
echo ""
echo "***********************"
echo "*目前不支持Ubuntu系统!*"
echo "*请使用CentOS搭建 *"
echo "**********************"
exit 0
apt-get install git unzip wget -y

fi
if [[ ${OS} == CentOS ]];then

yum install git unzip wget -y

fi
if [[ ${OS} == Debian ]];then
echo "***********************"
echo "*目前不支持Debian系统!*"
echo "*请使用CentOS搭建 *"
echo "**********************"
apt-get install git unzip wget -y

fi

#1.清理旧环境和配置新环境
Clear(){
unInstall
clear
echo "旧环境清理完毕!"
echo ""
echo "安装Socks5所依赖的组件,请稍等..."
yum -y install gcc gcc-c++ automake make pam-devel openldap-devel cyrus-sasl-devel openssl-devel
yum update -y nss curl libcurl

#配置环境变量
sed -i '$a export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin' ~/.bash_profile
source ~/.bash_profile

#关闭防火墙
newVersion=`cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'`
if [[ ${newVersion} = "7" ]] ; then
systemctl stop firewalld
systemctl disable firewalld

elif [[ ${newVersion} = "6" ]] ;then
service iptables stop
chkconfig iptables off
else
echo "Exception version"
fi
}

#2.下载Socks5服务
Download()
{
echo ""
echo "下载Socks5服务中..."
cd /root
git clone https://github.com/wyx176/Socks5
}


#3.安装Socks5服务程序
InstallSock5()
{
echo ""
echo "解压文件中..."
cd /root/Socks5
tar zxvf ./ss5-3.8.9-8.tar.gz

echo "安装中..."
cd /root/Socks5/ss5-3.8.9
./configure
make
make install
}

#4.安装控制面板配置参数
InstallPanel()
{
#cd /root/Socks5
mv /root/Socks5/service.sh /etc/opt/ss5/
mv /root/Socks5/user.sh /etc/opt/ss5/
mv /root/Socks5/version.txt /etc/opt/ss5/
mv /root/Socks5/ss5 /etc/sysconfig/
mv /root/Socks5/s5 /usr/local/bin/
chmod +x /usr/local/bin/s5

#设置默认用户名、默认开启帐号验证
uname="123456"
upasswd="654321"
port="5555"
confFile=/etc/opt/ss5/ss5.conf
echo -e $uname $upasswd >> /etc/opt/ss5/ss5.passwd
sed -i '87c auth 0.0.0.0/0 - u' $confFile
sed -i '203c permit u 0.0.0.0/0 - 0.0.0.0/0 - - - - -' $confFile


#添加开机启动
chmod +x /etc/init.d/ss5
chkconfig --add ss5
chkconfig --level 345 ss5 on
confFile=/etc/rc.d/init.d/ss5
sed -i '/echo -n "Starting ss5... "/a if [ ! -d "/var/run/ss5/" ];then mkdir /var/run/ss5/; fi' $confFile
sed -i '54c rm -rf /var/run/ss5/' $confFile
sed -i '18c [[ ${NETWORKING} = "no" ]] && exit 0' $confFile

#判断ss5文件夹是否存在、
if [ ! -d "/var/run/ss5/" ];then
mkdir /var/run/ss5/
echo "create ss5 success!"
else
echo "/ss5/ is OK!"
fi
}

#5.检测是否安装完整
check(){
cd /root
rm -rf /root/Socks5
rm -rf /root/install.sh
errorMsg=""
isError=false
if [ ! -f "/usr/local/bin/s5" ] ; then
errorMsg=${errorMsg}"001|"
isError=true

fi
if [ ! -f "/etc/opt/ss5/service.sh" ]; then
errorMsg=${errorMsg}"002|"
isError=true

fi
if [ ! -f "/etc/opt/ss5/user.sh" ]; then
errorMsg=${errorMsg}"003|"
isError=true
fi

if [ ! -f "/etc/opt/ss5/ss5.conf" ]; then
errorMsg=${errorMsg}"004|"
isError=true
fi

if [ "$isError" = "true" ] ; then
unInstall
clear
echo ""
echo "缺失文件,安装失败!!!"
echo "错误提示:"${errorMsg}
echo "发送邮件反馈bug :wyx176@gmail.com"
echo "或者添加Telegram群反馈"
echo "Telegram群:t.me/Socks55555"
exit 0
else
clear
echo ""
#service ss5 start
if [[ ${newVersion} = "7" ]] ; then
systemctl daemon-reload
fi
service ss5 start
echo ""
echo "Socks5安装完毕!"
echo ""
echo "输入"s5"启动Socks5控制面板"
echo ""
echo "默认用户名: "${uname}
echo "默认密码 : "${upasswd}
echo "默认端口 : "${port}
echo ""
echo "添加Telegram群组@Socks55555及时获取更新"
echo ""
exit 0
fi
}

#6.卸载
unInstall(){
service ss5 stop
rm -rf /run/ss5
rm -f /run/lock/subsys/ss5
rm -rf /etc/opt/ss5
rm -f /usr/local/bin/s5
rm -rf /usr/lib/ss5
rm -f /usr/sbin/ss5
rm -rf /usr/share/doc/ss5
rm -rf /root/ss5-3.8.9
rm -f /etc/sysconfig/ss5
rm -f /etc/rc.d/init.d/ss5
rm -f /etc/pam.d/ss5
rm -rf /var/log/ss5
}

Clear
Download
InstallSock5
InstallPanel
check

ShortLink

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
const admin_path = '/yearcakes'
const api_path = '/api'
const url_key = 'orgi_url' // original url key
const url_name = 'short_code' // short code key
const short_url_key = 'short_url'; // full short url

const index = `<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">


<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

<title>🔗 ShortLink</title>
</head>

<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}

@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}

.btn-secondary,
.btn-secondary:hover,
.btn-secondary:focus {
color: #333;
text-shadow: none;
}

body {
text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);
}

.cover-container {
max-width: 42em;
}

.nav-masthead .nav-link {
padding: .25rem 0;
font-weight: 700;
color: rgba(255, 255, 255, .5);
background-color: transparent;
border-bottom: .25rem solid transparent;
}

.nav-masthead .nav-link:hover,
.nav-masthead .nav-link:focus {
border-bottom-color: rgba(255, 255, 255, .25);
}

.nav-masthead .nav-link+.nav-link {
margin-left: 1rem;
}

.nav-masthead .active {
color: #fff;
border-bottom-color: #fff;
}
</style>

</head>

<body class="d-flex h-100 text-center text-white bg-dark">

<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
<header class="mb-auto">
<div>
<h3 class="float-md-start mb-0">🔗 ShortLink</h3>

</div>
</header>
<br>
<br>
<main class="px-3">
<p id="result" class="lead"></p>

<br>
<div id="link_div" class="input-group mb-3">
<!-- <input type="text" id="link" class="form-control" placeholder="link" aria-label="link"> -->
<select class="form-control" id="select">
<option value="link">🔗 Link</option>
<option value="text">📄 Text</option>
</select>
<input type="text" id="name" placeholder="short code" class="input-group-text">
</div>
<div id="text_div">
<textarea id="link" placeholder="link/text.." class="form-control" rows="10"></textarea><br>
</div>
<p class="lead">
<a href="#" onclick="getlink()" class="btn btn-lg btn-secondary fw-bold border-white bg-white">🚀 Get</a>
</p>
</main>




</div>
<script>
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}

function getlink() {
document.getElementById('result').innerHTML = "Adding to database.."
let link = document.getElementById('link').value
const name = document.getElementById('name').value
const type = document.getElementById('select').value
if (link.indexOf('http') == -1 && type == "link") {
link = 'http://' + link
}
postData("${api_path}", {
"${url_key}": link,
"${url_name}": name,
"type": type
}).then(resp => {
var url = document.location.protocol + '//' + document.location.host + '/' + resp['${url_name}']
document.getElementById('result').innerHTML = url
document.getElementById('name').value = resp['${url_name}']
})
}
</script>

</html>`



addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})

/**
* Respond with hello worker text
* @param {Request} request
*/

async function handleRequest(request) {
const { protocol, hostname, pathname } = new URL(request.url);
// index.html
if (pathname == admin_path) {
return new Response(index, {
headers: { 'content-type': 'text/html; charset=utf-8' },
})
}
// short api
if (pathname.startsWith(api_path)) {
const body = JSON.parse(await request.text());
console.log(body)
var short_type = 'link'
if (body['type'] != undefined && body['type'] != "") {
short_type = body['type'];
}

if (body[url_name] == undefined || body[url_name] == "" || body[url_name].length < 2) {
body[url_name] = Math.random().toString(36).slice(-5)
}
await shortlink.put(body[url_name], JSON.stringify({
"type": short_type,
"value": body[url_key]
}))
body[short_url_key] = `${protocol}//${hostname}/${body[url_name]}`
return new Response(JSON.stringify(body), {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
}
const key = pathname.replace('/', '')
if (key == "") {
return new Response(`Please login your account first`, {
headers: { 'content-type': 'text/plain; charset=utf-8' },
})
}
let link = await shortlink.get(key)
if (link != null) {
link = JSON.parse(link)
console.log(link)
// redirect
if (link['type'] == "link") {
return Response.redirect(link['value'], 302);
} else {
// textarea
return new Response(`${link['value']}`, {
headers: { 'content-type': 'text/plain; charset=utf-8' },
})
}
}
return new Response(`Page Not Found`, {
headers: { 'content-type': 'text/plain; charset=utf-8' },
})
}

TodoListApp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const html = todos => `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Todos</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet"></link>
</head>
<body class="bg-blue-100">
<div class="w-full h-full flex content-center justify-center mt-8">
<div class="bg-white shadow-md rounded px-8 pt-6 py-8 mb-4">
<h1 class="block text-grey-800 text-md font-bold mb-2">Todos</h1>
<div class="flex">
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-800 leading-tight focus:outline-none focus:shadow-outline" type="text" name="name" placeholder="A new todo"></input>
<button class="bg-blue-500 hover:bg-blue-800 text-white font-bold ml-2 py-2 px-4 rounded focus:outline-none focus:shadow-outline" id="create" type="submit">Create</button>
</div>
<div class="mt-4" id="todos"></div>
</div>
</div>
</body>
<script>
window.todos = ${todos}
var updateTodos = function() {
fetch("/", { method: 'PUT', body: JSON.stringify({ todos: window.todos }) })
populateTodos()
}
var completeTodo = function(evt) {
var checkbox = evt.target
var todoElement = checkbox.parentNode
var newTodoSet = [].concat(window.todos)
var todo = newTodoSet.find(t => t.id == todoElement.dataset.todo)
todo.completed = !todo.completed
window.todos = newTodoSet
updateTodos()
}
var populateTodos = function() {
var todoContainer = document.querySelector("#todos")
todoContainer.innerHTML = null
window.todos.forEach(todo => {
var el = document.createElement("div")
el.className = "border-t py-4"
el.dataset.todo = todo.id
var name = document.createElement("span")
name.className = todo.completed ? "line-through" : ""
name.textContent = todo.name
var checkbox = document.createElement("input")
checkbox.className = "mx-4"
checkbox.type = "checkbox"
checkbox.checked = todo.completed ? 1 : 0
checkbox.addEventListener('click', completeTodo)
el.appendChild(checkbox)
el.appendChild(name)
todoContainer.appendChild(el)
})
}
populateTodos()
var createTodo = function() {
var input = document.querySelector("input[name=name]")
if (input.value.length) {
window.todos = [].concat(todos, { id: window.todos.length + 1, name: input.value, completed: false })
input.value = ""
updateTodos()
}
}
document.querySelector("#create").addEventListener('click', createTodo)
</script>
</html>
`

const defaultData = { todos: [] }

const setCache = (key, data) => TODOS.put(key, data)
const getCache = key => TODOS.get(key)

async function getTodos(request) {
const ip = request.headers.get('CF-Connecting-IP')
const cacheKey = `data-${ip}`
let data
const cache = await getCache(cacheKey)
if (!cache) {
await setCache(cacheKey, JSON.stringify(defaultData))
data = defaultData
} else {
data = JSON.parse(cache)
}
const body = html(JSON.stringify(data.todos || []).replace(/</g, "\ "))
return new Response(body, {
headers: { 'Content-Type': 'text/html' },
})
}

async function updateTodos(request) {
const body = await request.text()
const ip = request.headers.get('CF-Connecting-IP')
const cacheKey = `data-${ip}`
try {
JSON.parse(body)
await setCache(cacheKey, body)
return new Response(body, { status: 200 })
} catch (err) {
return new Response(err, { status: 500 })
}
}

async function handleRequest(request) {
if (request.method === 'PUT') {
return updateTodos(request)
} else {
return getTodos(request)
}
}

addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})