-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
170 lines (142 loc) · 5.09 KB
/
main.go
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
package main
import (
"fmt"
"github.com/eddieivan01/nic"
"github.com/json-iterator/go"
"log"
"io/ioutil"
"strings"
"runtime"
"os"
)
var HttpClient nic.Session
var hostResult RequestResult
var hostPath string
func main() {
// 设置 Logger
log.SetFlags(log.Ltime)
log.Println("FiveM Host 修复工具 by Akkariin")
log.Println("版本 V1.3 - Let's Encrypt IP Fix")
// 设定 Hosts 路径
if runtime.GOOS == "windows" {
hostPath = "C:/Windows/System32/drivers/etc/hosts"
} else {
hostPath = "/etc/hosts"
}
log.Println("正在检测网络状态...")
_, err := HttpClient.Get("http://ocsp.int-x3.letsencrypt.org/", nic.H {
Timeout: 5,
})
if err != nil {
if strings.Contains(err.Error(), "Timeout") {
log.Println("检测到 Let's Encrypt 服务器可能被 DNS 污染,修复中...")
if FixLetsEncrypt() {
log.Println("Let's Encrypt 服务器 Hosts 修复成功")
} else {
log.Println("Let's Encrypt 服务器 Hosts 修复失败!")
if runtime.GOOS == "windows" {
log.Println("请检查是否用 [右键 -> 以管理员身份运行] 本程序,如果使用管理员权限运行后还是出错,请手动打开 C:/Windows/System32/drivers/etc/ 并右键查看 hosts 文件是否被设置为了只读,如果是请将只读取消然后重试。如果问题持续存在,请联系 QQ 204034。")
} else {
log.Println("请检查 /etc/hosts 文件是否是只读状态,以及您当前的用户组是否有读写权限,请尝试使用 root 身份执行本操作!")
}
fmt.Printf("\n请按回车键退出...")
os.Stdin.Read(make([]byte, 1))
log.Fatalln()
}
} else {
log.Println("检测时发生了未知错误")
log.Println(err.Error())
fmt.Printf("\n请按回车键退出...")
os.Stdin.Read(make([]byte, 1))
log.Fatalln()
}
}
// 获取服务器 IP
log.Println("正在获取最新的 Host...")
response, err := HttpClient.Get("https://api.zerodream.net/v2/fivemclient/host", nil)
if err != nil {
// 获取失败
log.Println("无法获取服务器 IP,请稍后重试,如问题持续存在请联系 QQ 204034。")
log.Println(fmt.Sprintf("错误内容:%s", err.Error()))
fmt.Printf("\n请按回车键退出...")
os.Stdin.Read(make([]byte, 1))
log.Fatalln()
}
err = jsoniter.Unmarshal(response.Bytes, &hostResult)
if err != nil {
log.Println(fmt.Sprintf("无法解析服务器返回的数据,请稍后重试。服务器返回内容:%s", response.Text))
fmt.Printf("\n请按回车键退出...")
os.Stdin.Read(make([]byte, 1))
log.Fatalln()
}
log.Println(fmt.Sprintf("获得服务器 IP:%s", hostResult.Ip))
// 解析 Hosts 文件
hostFile := GetFileData(hostPath)
for _, hostName := range hostResult.Host {
log.Println(fmt.Sprintf("已更新 %s 的 IP 地址为 %s", hostName, hostResult.Ip))
hostFile = SetHosts(hostFile, hostName, hostResult.Ip)
}
// 补齐结尾换行
hostFile += "\n"
// 写入到文件中
if SetFileData(hostPath, hostFile) {
log.Println("Hosts 文件写入成功!")
} else {
log.Println("Hosts 文件写入失败!")
if runtime.GOOS == "windows" {
log.Println("请检查是否用 [右键 -> 以管理员身份运行] 本程序,如果使用管理员权限运行后还是出错,请手动打开 C:/Windows/System32/drivers/etc/ 并右键查看 hosts 文件是否被设置为了只读,如果是请将只读取消然后重试。如果问题持续存在,请联系 QQ 204034。")
} else {
log.Println("请检查 /etc/hosts 文件是否是只读状态,以及您当前的用户组是否有读写权限,请尝试使用 root 身份执行本操作!")
}
}
fmt.Printf("\n请按回车键退出...")
os.Stdin.Read(make([]byte, 1))
}
// 修复 Let's Encrypt 服务器被劫持问题
func FixLetsEncrypt() (bool) {
// 读取 Hosts 文件
hostFile := GetFileData(hostPath)
hostFile = SetHosts(hostFile, "ocsp.int-x3.letsencrypt.org", "172.247.76.247")
return SetFileData(hostPath, hostFile)
}
// 设置 Hosts
func SetHosts(hostData string, hostName string, ipAddr string) (string) {
// 是否找到 Hosts
foundHost := false
allLines := strings.Split(hostData, "\n")
newHosts := ""
for _, line := range allLines {
if strings.Contains(line, fmt.Sprintf(" %s", hostName)) {
newHosts += fmt.Sprintf("%s %s\n", ipAddr, hostName)
foundHost = true
} else if line != "" {
newHosts += line + "\n"
}
}
if !foundHost {
newHosts += fmt.Sprintf("%s %s\n", ipAddr, hostName)
}
return newHosts
}
// 读文件
func GetFileData(fileName string) (string) {
f, err := ioutil.ReadFile(fileName)
if err != nil {
log.Fatalln("Failed to read file", err)
}
return string(f)
}
// 写文件
func SetFileData(fileName string, data string) (bool) {
var bytes = []byte(data)
err := ioutil.WriteFile(fileName, bytes, 0666)
if err != nil {
return false
}
return true
}
// 定义服务器返回文件类型
type RequestResult struct {
Ip string
Host []string
}