Merge branch 'main' of github.com:72wo/blazing
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,3 +39,4 @@ login/login
|
||||
login/login
|
||||
logic/logic1
|
||||
logic/logic1
|
||||
logic/logic1
|
||||
|
||||
34
common/contrib/files/pngcm/go.mod
Normal file
34
common/contrib/files/pngcm/go.mod
Normal file
@@ -0,0 +1,34 @@
|
||||
module blazing/contrib/files/pngcm
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/gogf/gf/v2 v2.6.3
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
59
common/contrib/files/pngcm/go.sum
Normal file
59
common/contrib/files/pngcm/go.sum
Normal file
@@ -0,0 +1,59 @@
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gogf/gf/v2 v2.6.3 h1:DoqeuwU98wotpFoDSQEx8RZbmJdK8KdGiJtzJeqpyIo=
|
||||
github.com/gogf/gf/v2 v2.6.3/go.mod h1:x2XONYcI4hRQ/4gMNbWHmZrNzSEIg20s2NULbzom5k0=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
170
common/contrib/files/pngcm/local.go
Normal file
170
common/contrib/files/pngcm/local.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package pngcm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"blazing/cool"
|
||||
"blazing/cool/coolfile"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// Pngcm 实现coolfile.Driver接口,用于远程图片上传
|
||||
type Pngcm struct{}
|
||||
|
||||
// 远程上传接口响应结构
|
||||
type uploadResponse struct {
|
||||
Code int `json:"code"`
|
||||
Url string `json:"url"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Upload 上传文件到远程服务
|
||||
func (p *Pngcm) Upload(ctx g.Ctx, filepath, filename string) (string, error) {
|
||||
// 检查本地文件是否存在
|
||||
if _, err := os.Stat(filepath); err != nil {
|
||||
return "", gerror.Newf("上传文件不存在: %s, 错误: %v", filepath, err)
|
||||
}
|
||||
|
||||
// 生成27位随机字符串,类似PHP的Str::random(27)
|
||||
randomStr, err := randString(27)
|
||||
if err != nil {
|
||||
return "", gerror.Newf("生成随机字符串失败: %v", err)
|
||||
}
|
||||
uuid := "o_" + randomStr
|
||||
|
||||
// 构建表单数据
|
||||
var requestBody bytes.Buffer
|
||||
writer := multipart.NewWriter(&requestBody)
|
||||
|
||||
// 添加普通表单字段
|
||||
if err := writer.WriteField("name", filename); err != nil {
|
||||
return "", gerror.Newf("写入name字段失败: %v", err)
|
||||
}
|
||||
if err := writer.WriteField("uuid", uuid); err != nil {
|
||||
return "", gerror.Newf("写入uuid字段失败: %v", err)
|
||||
}
|
||||
if err := writer.WriteField("sign", fmt.Sprintf("%d", time.Now().Unix())); err != nil {
|
||||
return "", gerror.Newf("写入sign字段失败: %v", err)
|
||||
}
|
||||
|
||||
// 添加文件字段
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return "", gerror.Newf("打开文件失败: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fileField, err := writer.CreateFormFile("file", filename)
|
||||
if err != nil {
|
||||
return "", gerror.Newf("创建文件表单字段失败: %v", err)
|
||||
}
|
||||
if _, err := io.Copy(fileField, file); err != nil {
|
||||
return "", gerror.Newf("复制文件内容失败: %v", err)
|
||||
}
|
||||
|
||||
// 完成表单构建
|
||||
if err := writer.Close(); err != nil {
|
||||
return "", gerror.Newf("关闭表单写入器失败: %v", err)
|
||||
}
|
||||
|
||||
// 创建HTTP请求
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", "https://img.wnflb2023.com/application/upload.php", &requestBody)
|
||||
if err != nil {
|
||||
return "", gerror.Newf("创建请求失败: %v", err)
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
req.Header.Set("Referer", "https://img.wnflb2023.com/")
|
||||
|
||||
// 发送请求
|
||||
client := &http.Client{
|
||||
Timeout: 30 * time.Second, // 设置超时时间
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", gerror.Newf("发送请求失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 读取响应内容
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", gerror.Newf("读取响应内容失败: %v", err)
|
||||
}
|
||||
|
||||
// 检查HTTP状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", gerror.Newf("接口返回非200状态码: %d, 响应内容: %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
// 解析JSON响应
|
||||
var uploadResp uploadResponse
|
||||
if err := json.Unmarshal(respBody, &uploadResp); err != nil {
|
||||
return "", gerror.Newf("解析响应JSON失败: %v, 响应内容: %s", err, string(respBody))
|
||||
}
|
||||
|
||||
// 处理业务响应
|
||||
if uploadResp.Code == 200 {
|
||||
return uploadResp.Url, nil
|
||||
} else if uploadResp.Message != "" {
|
||||
return "", gerror.Newf("上传失败请重试: %s", uploadResp.Message)
|
||||
} else {
|
||||
return "", gerror.Newf("上传失败!接口错误,响应内容: %s", string(respBody))
|
||||
}
|
||||
}
|
||||
|
||||
// GetMode 获取驱动模式信息
|
||||
func (p *Pngcm) GetMode() (data interface{}, err error) {
|
||||
data = g.MapStrStr{
|
||||
"mode": cool.Config.File.Mode,
|
||||
"type": "pngcm",
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// New 创建驱动实例
|
||||
func (p *Pngcm) New() coolfile.Driver {
|
||||
return &Pngcm{}
|
||||
}
|
||||
|
||||
// New 实例化驱动
|
||||
func New() coolfile.Driver {
|
||||
return &Pngcm{}
|
||||
}
|
||||
|
||||
// 生成指定长度的随机字符串(字母数字混合)
|
||||
func randString(length int) (string, error) {
|
||||
b := make([]byte, length)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// 使用base64编码确保字符安全,然后截取指定长度
|
||||
return base64.URLEncoding.EncodeToString(b)[:length], nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
var (
|
||||
err error
|
||||
driverObj = New()
|
||||
driverNames = g.SliceStr{"pngcm"}
|
||||
)
|
||||
// 注册驱动
|
||||
for _, driverName := range driverNames {
|
||||
if err = coolfile.Register(driverName, driverObj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ require github.com/antchfx/xmlquery v1.4.4
|
||||
|
||||
require (
|
||||
github.com/antchfx/xpath v1.3.3 // indirect
|
||||
github.com/butoften/array v1.0.9 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/ECUST-XX/xml v1.20.2 h1:xqg5JaYfcGtkXtLcAN0H1sbTWwRdIHjmU/ZRPmtj+8k=
|
||||
github.com/ECUST-XX/xml v1.20.2/go.mod h1:AHwv/5bl6dD2mohWd7efbLVKEF+SllOsrynpQVhWM0o=
|
||||
github.com/antchfx/xmlquery v1.4.4 h1:mxMEkdYP3pjKSftxss4nUHfjBhnMk4imGoR96FRY2dg=
|
||||
@@ -7,29 +8,37 @@ github.com/antchfx/xmlquery v1.4.4/go.mod h1:AEPEEPYE9GnA2mj5Ur2L5Q5/2PycJ0N9Fus
|
||||
github.com/antchfx/xpath v1.3.3 h1:tmuPQa1Uye0Ym1Zn65vxPgfltWb/Lxu2jeqIGteJSRs=
|
||||
github.com/antchfx/xpath v1.3.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/butoften/array v1.0.9 h1:/kPHAc+fHz72u5B23p2W1RzIoT2eOYvhsY0tKMvsHEc=
|
||||
github.com/butoften/array v1.0.9/go.mod h1:RgJ3XIUy/Z2rQllTkXmS4LtfqJeD3mjYJ4XoP3odTqM=
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gogf/gf/v2 v2.6.3 h1:DoqeuwU98wotpFoDSQEx8RZbmJdK8KdGiJtzJeqpyIo=
|
||||
github.com/gogf/gf/v2 v2.6.3/go.mod h1:x2XONYcI4hRQ/4gMNbWHmZrNzSEIg20s2NULbzom5k0=
|
||||
github.com/gogf/gf/v2 v2.7.0/go.mod h1:Qu8nimKt9aupJQcdUL85tWF4Mfxocz97zUt8UC4abVI=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@@ -48,11 +57,13 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tnnmigga/enum v1.0.2 h1:Yvchx0Esc01X5HiphW78sKzH/RXKttdFsfPO1ARiOa4=
|
||||
github.com/tnnmigga/enum v1.0.2/go.mod h1:QaBFBwGJi/2GAM34b2pz6UL2NRtl2TRZ8lXp4vGwqhA=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
@@ -60,9 +71,13 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
@@ -149,6 +164,7 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
||||
@@ -5,12 +5,11 @@ import (
|
||||
"blazing/modules/base/service"
|
||||
"blazing/modules/blazing/model"
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/butoften/array"
|
||||
)
|
||||
|
||||
func GetServerInfoList1() []ServerInfo {
|
||||
func GetServerInfoList() []ServerInfo {
|
||||
dictInfoModel1 := model.NewServerList()
|
||||
mType := cool.DBM(dictInfoModel1)
|
||||
t, _ := mType.All()
|
||||
@@ -32,10 +31,15 @@ func GetServerInfoList1() []ServerInfo {
|
||||
}
|
||||
tt.Port = v.Port
|
||||
t, ok := Clientmap[v.Port]
|
||||
if ok && t != nil {
|
||||
|
||||
// tt.Friends = v.Friends
|
||||
ret1 = append(ret1, *tt)
|
||||
if ok {
|
||||
cool.Loger.Info(context.TODO(), "服务器假踢人")
|
||||
err := t.KickPerson(0) //实现指定服务器踢人
|
||||
if err == nil {
|
||||
// tt.Friends = v.Friends
|
||||
ret1 = append(ret1, *tt)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,19 +116,19 @@ type BlackInfo struct {
|
||||
//TimePoke uint32
|
||||
}
|
||||
|
||||
func Refurh() {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
GetServerInfoList = GetServerInfoList1()
|
||||
// func Refurh() {
|
||||
// l.Lock()
|
||||
// defer l.Unlock()
|
||||
// GetServerInfoList = GetServerInfoList1()
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
func GetServer() []ServerInfo {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
return GetServerInfoList
|
||||
// func GetServer() []ServerInfo {
|
||||
// l.RLock()
|
||||
// defer l.RUnlock()
|
||||
// return GetServerInfoList
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
var GetServerInfoList = GetServerInfoList1()
|
||||
var l sync.RWMutex
|
||||
// var GetServerInfoList = GetServerInfoList1()
|
||||
// var l sync.RWMutex
|
||||
|
||||
@@ -63,7 +63,7 @@ func (h *ServerHandler) RegisterLogic(ctx context.Context, id, port uint16) erro
|
||||
}
|
||||
Clientmap[port] = &revClient
|
||||
|
||||
Refurh()
|
||||
//Refurh()
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ import (
|
||||
|
||||
func (h *Server) KickPerson(a int) error {
|
||||
cool.Loger.Info(context.TODO(), "检测到踢人请求", a)
|
||||
if a == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return player.KickPlayer(uint32(a))
|
||||
}
|
||||
|
||||
@@ -7,15 +7,14 @@ import (
|
||||
func BenchmarkByteArray(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
//写入
|
||||
testbyte:=CreateByteArray()
|
||||
for i := 0; i < b.N; i++ {
|
||||
testbyte.writeNumber(42)
|
||||
testbyte.writeNumber(12345.4)
|
||||
testbyte.writeNumber(123456789)
|
||||
testbyte.writeNumber(1234567890123456789)
|
||||
testbyte.WriteString("test string")
|
||||
testbyte.Bytes()
|
||||
}
|
||||
|
||||
testbyte := CreateByteArray(nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
testbyte.writeNumber(42)
|
||||
testbyte.writeNumber(12345.4)
|
||||
testbyte.writeNumber(123456789)
|
||||
testbyte.writeNumber(1234567890123456789)
|
||||
testbyte.WriteString("test string")
|
||||
testbyte.Bytes()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
21
common/utils/qqwry/LICENSE
Normal file
21
common/utils/qqwry/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 xiaoqidun
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
71
common/utils/qqwry/README.md
Normal file
71
common/utils/qqwry/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# QQWry [](https://pkg.go.dev/github.com/xiaoqidun/qqwry)
|
||||
|
||||
Golang QQWry,高性能纯真IP查询库。
|
||||
|
||||
# 使用须知
|
||||
|
||||
1. dat格式仅支持ipv4查询。
|
||||
2. ipdb格式支持ipv4和ipv6查询。
|
||||
|
||||
# 使用说明
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/xiaoqidun/qqwry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 从文件加载IP数据库
|
||||
if err := qqwry.LoadFile("qqwry.ipdb"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// 从内存或缓存查询IP
|
||||
location, err := qqwry.QueryIP("119.29.29.29")
|
||||
if err != nil {
|
||||
fmt.Printf("错误:%v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("国家:%s,省份:%s,城市:%s,区县:%s,运营商:%s\n",
|
||||
location.Country,
|
||||
location.Province,
|
||||
location.City,
|
||||
location.District,
|
||||
location.ISP,
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
# IP数据库
|
||||
|
||||
- DAT格式:[https://aite.xyz/share-file/qqwry/qqwry.dat](https://aite.xyz/share-file/qqwry/qqwry.dat)
|
||||
- IPDB格式:[https://aite.xyz/share-file/qqwry/qqwry.ipdb](https://aite.xyz/share-file/qqwry/qqwry.ipdb)
|
||||
|
||||
# 编译说明
|
||||
|
||||
1. 下载IP数据库并放置于assets目录中。
|
||||
2. client和server需要go1.16的内嵌资源特性。
|
||||
3. 作为库使用,请直接引包,并不需要go1.16+才能编译。
|
||||
|
||||
# 数据更新
|
||||
|
||||
- 由于qqwry.dat缺乏更新,官方czdb格式又难以获得和分发,建议使用ipdb格式。
|
||||
- 这里的ipdb格式指metowolf提供的官方czdb格式转换而来的ipdb格式(纯真格式原版)。
|
||||
|
||||
# 服务接口
|
||||
|
||||
1. 自行根据需要调整server下源码。
|
||||
2. 可以通过-listen参数指定http服务地址。
|
||||
3. json api:curl http://127.0.0.1/ip/119.29.29.29
|
||||
|
||||
# 特别感谢
|
||||
|
||||
- 感谢[纯真IP库](https://www.cz88.net/)一直坚持为大家提供免费IP数据库。
|
||||
- 感谢[yinheli](https://github.com/yinheli)的[qqwry](https://github.com/yinheli/qqwry)项目,为我提供纯真ip库解析算法参考。
|
||||
- 感谢[metowolf](https://github.com/metowolf)的[qqwry.ipdb](https://github.com/metowolf/qqwry.ipdb)项目,提供纯真czdb转ipdb数据库。
|
||||
|
||||
# 授权说明
|
||||
|
||||
使用本类库你唯一需要做的就是把LICENSE文件往你用到的项目中拷贝一份。
|
||||
37
common/utils/qqwry/client/client.go
Normal file
37
common/utils/qqwry/client/client.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/xiaoqidun/qqwry"
|
||||
"github.com/xiaoqidun/qqwry/assets"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
qqwry.LoadData(assets.QQWryIpdb)
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
return
|
||||
}
|
||||
queryIp := os.Args[1]
|
||||
location, err := qqwry.QueryIP(queryIp)
|
||||
if err != nil {
|
||||
fmt.Printf("错误:%v\n", err)
|
||||
return
|
||||
}
|
||||
emptyVal := func(val string) string {
|
||||
if val != "" {
|
||||
return val
|
||||
}
|
||||
return "未知"
|
||||
}
|
||||
fmt.Printf("国家:%s,省份:%s,城市:%s,区县:%s,运营商:%s\n",
|
||||
emptyVal(location.Country),
|
||||
emptyVal(location.Province),
|
||||
emptyVal(location.City),
|
||||
emptyVal(location.District),
|
||||
emptyVal(location.ISP),
|
||||
)
|
||||
}
|
||||
8
common/utils/qqwry/go.mod
Normal file
8
common/utils/qqwry/go.mod
Normal file
@@ -0,0 +1,8 @@
|
||||
module github.com/xiaoqidun/qqwry
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/ipipdotnet/ipdb-go v1.3.3
|
||||
golang.org/x/text v0.8.0
|
||||
)
|
||||
4
common/utils/qqwry/go.sum
Normal file
4
common/utils/qqwry/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
github.com/ipipdotnet/ipdb-go v1.3.3 h1:GLSAW9ypLUd6EF9QNK2Uhxew9Jzs4XMJ9gOZEFnJm7U=
|
||||
github.com/ipipdotnet/ipdb-go v1.3.3/go.mod h1:yZ+8puwe3R37a/3qRftXo40nZVQbxYDLqls9o5foexs=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
235
common/utils/qqwry/qqwry.go
Normal file
235
common/utils/qqwry/qqwry.go
Normal file
@@ -0,0 +1,235 @@
|
||||
package qqwry
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"github.com/ipipdotnet/ipdb-go"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
data []byte
|
||||
dataLen uint32
|
||||
ipdbCity *ipdb.City
|
||||
dataType = dataTypeDat
|
||||
locationCache = &sync.Map{}
|
||||
)
|
||||
|
||||
const (
|
||||
dataTypeDat = 0
|
||||
dataTypeIpdb = 1
|
||||
)
|
||||
|
||||
const (
|
||||
indexLen = 7
|
||||
redirectMode1 = 0x01
|
||||
redirectMode2 = 0x02
|
||||
)
|
||||
|
||||
type Location struct {
|
||||
Country string // 国家
|
||||
Province string // 省份
|
||||
City string // 城市
|
||||
District string // 区县
|
||||
ISP string // 运营商
|
||||
IP string // IP地址
|
||||
}
|
||||
|
||||
func byte3ToUInt32(data []byte) uint32 {
|
||||
i := uint32(data[0]) & 0xff
|
||||
i |= (uint32(data[1]) << 8) & 0xff00
|
||||
i |= (uint32(data[2]) << 16) & 0xff0000
|
||||
return i
|
||||
}
|
||||
|
||||
func gb18030Decode(src []byte) string {
|
||||
in := bytes.NewReader(src)
|
||||
out := transform.NewReader(in, simplifiedchinese.GB18030.NewDecoder())
|
||||
d, _ := io.ReadAll(out)
|
||||
return string(d)
|
||||
}
|
||||
|
||||
// QueryIP 从内存或缓存查询IP
|
||||
func QueryIP(ip string) (location *Location, err error) {
|
||||
if v, ok := locationCache.Load(ip); ok {
|
||||
return v.(*Location), nil
|
||||
}
|
||||
switch dataType {
|
||||
case dataTypeDat:
|
||||
return QueryIPDat(ip)
|
||||
case dataTypeIpdb:
|
||||
return QueryIPIpdb(ip)
|
||||
default:
|
||||
return nil, errors.New("data type not support")
|
||||
}
|
||||
}
|
||||
|
||||
// QueryIPDat 从dat查询IP,仅加载dat格式数据库时使用
|
||||
func QueryIPDat(ipv4 string) (location *Location, err error) {
|
||||
ip := net.ParseIP(ipv4).To4()
|
||||
if ip == nil {
|
||||
return nil, errors.New("ip is not ipv4")
|
||||
}
|
||||
ip32 := binary.BigEndian.Uint32(ip)
|
||||
posA := binary.LittleEndian.Uint32(data[:4])
|
||||
posZ := binary.LittleEndian.Uint32(data[4:8])
|
||||
var offset uint32 = 0
|
||||
for {
|
||||
mid := posA + (((posZ-posA)/indexLen)>>1)*indexLen
|
||||
buf := data[mid : mid+indexLen]
|
||||
_ip := binary.LittleEndian.Uint32(buf[:4])
|
||||
if posZ-posA == indexLen {
|
||||
offset = byte3ToUInt32(buf[4:])
|
||||
buf = data[mid+indexLen : mid+indexLen+indexLen]
|
||||
if ip32 < binary.LittleEndian.Uint32(buf[:4]) {
|
||||
break
|
||||
} else {
|
||||
offset = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
if _ip > ip32 {
|
||||
posZ = mid
|
||||
} else if _ip < ip32 {
|
||||
posA = mid
|
||||
} else if _ip == ip32 {
|
||||
offset = byte3ToUInt32(buf[4:])
|
||||
break
|
||||
}
|
||||
}
|
||||
if offset <= 0 {
|
||||
return nil, errors.New("ip not found")
|
||||
}
|
||||
posM := offset + 4
|
||||
mode := data[posM]
|
||||
var ispPos uint32
|
||||
var addr, isp string
|
||||
switch mode {
|
||||
case redirectMode1:
|
||||
posC := byte3ToUInt32(data[posM+1 : posM+4])
|
||||
mode = data[posC]
|
||||
posCA := posC
|
||||
if mode == redirectMode2 {
|
||||
posCA = byte3ToUInt32(data[posC+1 : posC+4])
|
||||
posC += 4
|
||||
}
|
||||
for i := posCA; i < dataLen; i++ {
|
||||
if data[i] == 0 {
|
||||
addr = string(data[posCA:i])
|
||||
break
|
||||
}
|
||||
}
|
||||
if mode != redirectMode2 {
|
||||
posC += uint32(len(addr) + 1)
|
||||
}
|
||||
ispPos = posC
|
||||
case redirectMode2:
|
||||
posCA := byte3ToUInt32(data[posM+1 : posM+4])
|
||||
for i := posCA; i < dataLen; i++ {
|
||||
if data[i] == 0 {
|
||||
addr = string(data[posCA:i])
|
||||
break
|
||||
}
|
||||
}
|
||||
ispPos = offset + 8
|
||||
default:
|
||||
posCA := offset + 4
|
||||
for i := posCA; i < dataLen; i++ {
|
||||
if data[i] == 0 {
|
||||
addr = string(data[posCA:i])
|
||||
break
|
||||
}
|
||||
}
|
||||
ispPos = offset + uint32(5+len(addr))
|
||||
}
|
||||
if addr != "" {
|
||||
addr = strings.TrimSpace(gb18030Decode([]byte(addr)))
|
||||
}
|
||||
ispMode := data[ispPos]
|
||||
if ispMode == redirectMode1 || ispMode == redirectMode2 {
|
||||
ispPos = byte3ToUInt32(data[ispPos+1 : ispPos+4])
|
||||
}
|
||||
if ispPos > 0 {
|
||||
for i := ispPos; i < dataLen; i++ {
|
||||
if data[i] == 0 {
|
||||
isp = string(data[ispPos:i])
|
||||
if isp != "" {
|
||||
if strings.Contains(isp, "CZ88.NET") {
|
||||
isp = ""
|
||||
} else {
|
||||
isp = strings.TrimSpace(gb18030Decode([]byte(isp)))
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
location = SplitResult(addr, isp, ipv4)
|
||||
locationCache.Store(ipv4, location)
|
||||
return location, nil
|
||||
}
|
||||
|
||||
// QueryIPIpdb 从ipdb查询IP,仅加载ipdb格式数据库时使用
|
||||
func QueryIPIpdb(ip string) (location *Location, err error) {
|
||||
ret, err := ipdbCity.Find(ip, "CN")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
location = SplitResult(ret[0], ret[1], ip)
|
||||
locationCache.Store(ip, location)
|
||||
return location, nil
|
||||
}
|
||||
|
||||
// LoadData 从内存加载IP数据库
|
||||
func LoadData(database []byte) {
|
||||
if string(database[6:11]) == "build" {
|
||||
dataType = dataTypeIpdb
|
||||
loadCity, err := ipdb.NewCityFromBytes(database)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ipdbCity = loadCity
|
||||
return
|
||||
}
|
||||
data = database
|
||||
dataLen = uint32(len(data))
|
||||
}
|
||||
|
||||
// LoadFile 从文件加载IP数据库
|
||||
func LoadFile(filepath string) (err error) {
|
||||
body, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
LoadData(body)
|
||||
return
|
||||
}
|
||||
|
||||
// SplitResult 按照调整后的纯真社区版IP库地理位置格式返回结果
|
||||
func SplitResult(addr string, isp string, ipv4 string) (location *Location) {
|
||||
location = &Location{ISP: isp, IP: ipv4}
|
||||
splitList := strings.Split(addr, "–")
|
||||
for i := 0; i < len(splitList); i++ {
|
||||
switch i {
|
||||
case 0:
|
||||
location.Country = splitList[i]
|
||||
case 1:
|
||||
location.Province = splitList[i]
|
||||
case 2:
|
||||
location.City = splitList[i]
|
||||
case 3:
|
||||
location.District = splitList[i]
|
||||
}
|
||||
}
|
||||
if location.Country == "局域网" {
|
||||
location.ISP = location.Country
|
||||
}
|
||||
return
|
||||
}
|
||||
32
common/utils/qqwry/qqwry_test.go
Normal file
32
common/utils/qqwry/qqwry_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package qqwry
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := LoadFile("assets/qqwry.ipdb"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryIP(t *testing.T) {
|
||||
queryIp := "119.29.29.29"
|
||||
location, err := QueryIP(queryIp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
emptyVal := func(val string) string {
|
||||
if val != "" {
|
||||
return val
|
||||
}
|
||||
return "未知"
|
||||
}
|
||||
t.Logf("国家:%s,省份:%s,城市:%s,区县:%s,运营商:%s",
|
||||
emptyVal(location.Country),
|
||||
emptyVal(location.Province),
|
||||
emptyVal(location.City),
|
||||
emptyVal(location.District),
|
||||
emptyVal(location.ISP),
|
||||
)
|
||||
}
|
||||
46
common/utils/qqwry/server/server.go
Normal file
46
common/utils/qqwry/server/server.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"github.com/xiaoqidun/qqwry"
|
||||
"github.com/xiaoqidun/qqwry/assets"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type resp struct {
|
||||
Data *qqwry.Location `json:"data"`
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
qqwry.LoadData(assets.QQWryIpdb)
|
||||
}
|
||||
|
||||
func main() {
|
||||
listen := flag.String("listen", "127.0.0.1:80", "http server listen addr")
|
||||
flag.Parse()
|
||||
http.HandleFunc("/ip/", IpAPI)
|
||||
if err := http.ListenAndServe(*listen, nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func IpAPI(writer http.ResponseWriter, request *http.Request) {
|
||||
ip := request.URL.Path[4:]
|
||||
if ip == "" {
|
||||
ip, _, _ = net.SplitHostPort(request.RemoteAddr)
|
||||
}
|
||||
response := &resp{}
|
||||
location, err := qqwry.QueryIP(ip)
|
||||
if err != nil {
|
||||
response.Message = err.Error()
|
||||
} else {
|
||||
response.Data = location
|
||||
response.Success = true
|
||||
}
|
||||
b, _ := json.MarshalIndent(response, "", " ")
|
||||
_, _ = writer.Write(b)
|
||||
}
|
||||
17
common/utils/tcpping.go
Normal file
17
common/utils/tcpping.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TcpPing(address string) (n int64, err error) {
|
||||
s := time.Now()
|
||||
tcpConn, err := net.Dial("tcp", address)
|
||||
n = time.Now().Sub(s).Nanoseconds()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tcpConn.Close()
|
||||
return
|
||||
}
|
||||
1
go.work
1
go.work
@@ -15,6 +15,7 @@ use (
|
||||
./common/utils/goja
|
||||
./common/utils/limit
|
||||
./common/utils/log
|
||||
./common/utils/qqwry
|
||||
./common/utils/sturc
|
||||
./common/utils/xml
|
||||
./logic
|
||||
|
||||
@@ -17,7 +17,7 @@ func (h *Controller) COMMEND_ONLINE(data *user.SidInfo, c gnet.Conn) (result *rp
|
||||
result.IsVip = 1
|
||||
}
|
||||
|
||||
result.ServerList = rpc.GetServerInfoList1() //todo 待修改增加缓存
|
||||
result.ServerList = rpc.GetServerInfoList() //todo 待修改增加缓存
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@ module blazing/logic
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/antlabs/timer v0.1.4
|
||||
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df
|
||||
github.com/brunoga/deep v1.2.5
|
||||
github.com/butoften/array v1.0.9
|
||||
github.com/creasty/defaults v1.8.0
|
||||
github.com/gobwas/ws v1.4.0
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.3
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/lunixbochs/struc v0.0.0-20241101090106-8d528fa2c543
|
||||
github.com/panjf2000/ants/v2 v2.11.3
|
||||
github.com/panjf2000/gnet v1.6.7
|
||||
github.com/pointernil/bitset32 v0.0.1
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
github.com/tnnmigga/enum v1.0.2
|
||||
golang.org/x/sync v0.11.0
|
||||
@@ -20,7 +20,8 @@ require (
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/bruceshao/lockfree v1.1.2 // indirect
|
||||
github.com/antlabs/stl v0.0.2 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.5.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
|
||||
66
logic/go.sum
66
logic/go.sum
@@ -1,17 +1,17 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/antlabs/stl v0.0.2 h1:sna1AXR5yIkNE9lWhCcKbheFJSVfCa3vugnGyakI79s=
|
||||
github.com/antlabs/stl v0.0.2/go.mod h1:kKrO4xrn9cfS1mJVo+/BqePZjAYMXqD0amGF2Ouq7ac=
|
||||
github.com/antlabs/timer v0.1.4 h1:MHdE00MDnNfhJCmqSOdLXs35uGNwfkMwfbynxrGmQ1c=
|
||||
github.com/antlabs/timer v0.1.4/go.mod h1:mpw4zlD5KVjstEyUDp43DGLWsY076Mdo4bS78NTseRE=
|
||||
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0=
|
||||
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df/go.mod h1:hiVxq5OP2bUGBRNS3Z/bt/reCLFNbdcST6gISi1fiOM=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bruceshao/lockfree v1.1.2 h1:V3j7bZWS+yDjazffbobpR+ZCVq98DNJcZMvO8vWFLmc=
|
||||
github.com/bruceshao/lockfree v1.1.2/go.mod h1:zkhImea4VTfzWvFF1Lleo1esCZeJLGgrYN+mUuqNrMA=
|
||||
github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8=
|
||||
github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/brunoga/deep v1.2.5 h1:bigq4eooqbeJXfvTfZBn3AH3B1iW+rtetxVeh0GiLrg=
|
||||
github.com/brunoga/deep v1.2.5/go.mod h1:GDV6dnXqn80ezsLSZ5Wlv1PdKAWAO4L5PnKYtv2dgaI=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/butoften/array v1.0.9 h1:/kPHAc+fHz72u5B23p2W1RzIoT2eOYvhsY0tKMvsHEc=
|
||||
github.com/butoften/array v1.0.9/go.mod h1:RgJ3XIUy/Z2rQllTkXmS4LtfqJeD3mjYJ4XoP3odTqM=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
@@ -19,9 +19,7 @@ github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creasty/defaults v1.8.0 h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk=
|
||||
github.com/creasty/defaults v1.8.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
@@ -50,7 +48,6 @@ github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtg
|
||||
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
@@ -72,17 +69,14 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/panjf2000/ants/v2 v2.4.7/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
|
||||
github.com/panjf2000/ants/v2 v2.11.3 h1:AfI0ngBoXJmYOpDh9m516vjqoUu2sLrIVgppI9TZVpg=
|
||||
github.com/panjf2000/ants/v2 v2.11.3/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek=
|
||||
github.com/panjf2000/gnet v1.6.7 h1:zv1k6kw80sG5ZQrLpbbFDheNCm50zm3z2e3ck5GwMOM=
|
||||
github.com/panjf2000/gnet v1.6.7/go.mod h1:KcOU7QsCaCBjeD5kyshBIamG3d9kAQtlob4Y0v0E+sc=
|
||||
github.com/panjf2000/gnet/v2 v2.9.1 h1:bKewICy/0xnQ9PMzNaswpe/Ah14w1TrRk91LHTcbIlA=
|
||||
github.com/panjf2000/gnet/v2 v2.9.1/go.mod h1:WQTxDWYuQ/hz3eccH0FN32IVuvZ19HewEWx0l62fx7E=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pointernil/bitset32 v0.0.1 h1:GL7o6ehG4W5ztXic75ncAmKzSxYQRSKxyaz2wOdz2aM=
|
||||
github.com/pointernil/bitset32 v0.0.1/go.mod h1:naghmAYTkvJhKSCVPbBwLAXkHMF2WBIJ1bJpnFpmQwI=
|
||||
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
|
||||
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@@ -93,17 +87,12 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tnnmigga/enum v1.0.2 h1:Yvchx0Esc01X5HiphW78sKzH/RXKttdFsfPO1ARiOa4=
|
||||
github.com/tnnmigga/enum v1.0.2/go.mod h1:QaBFBwGJi/2GAM34b2pz6UL2NRtl2TRZ8lXp4vGwqhA=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
@@ -112,64 +101,25 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211204120058-94396e421777/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -17,10 +17,10 @@ type Effect62 struct {
|
||||
func init() {
|
||||
t := &Effect62{
|
||||
EffectNode: node.EffectNode{
|
||||
Owner: true,
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
t.Owner(true)
|
||||
input.InitEffect(input.EffectType.Skill, 62, t)
|
||||
|
||||
}
|
||||
|
||||
@@ -14,9 +14,13 @@ type Effect67 struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
t := &Effect67{
|
||||
EffectNode: node.EffectNode{},
|
||||
}
|
||||
t.Owner(true)
|
||||
input.InitEffect(input.EffectType.Skill, 67, &Effect67{
|
||||
EffectNode: node.EffectNode{
|
||||
Owner: true,
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ type Effect9 struct {
|
||||
|
||||
func (e *Effect9) Skill_Hit(ctx input.Ctx) bool {
|
||||
if e.Skillid != 0 && ctx.SkillEntity.ID != e.Skillid {
|
||||
e.NotALive()
|
||||
e.Alive(false)
|
||||
e.UseSkillCount = 0
|
||||
return true
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
if a.SkillEntity.Category() != info.Category.STATUS {
|
||||
t := defender.GetEffect(input.EffectType.Status, int(info.PetStatus.Sleep))
|
||||
if t != nil {
|
||||
t.NotALive()
|
||||
t.Alive(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,11 +53,11 @@ type Effect interface {
|
||||
//回合数,然后次数另外维护
|
||||
Duration(...int) int
|
||||
Hit(...bool) bool
|
||||
Alive() bool
|
||||
Alive(...bool) bool
|
||||
Stack(...int) int
|
||||
MaxStack(...int) int
|
||||
NotALive()
|
||||
GetOwner() bool // 技能属主,比如寄生和镇魂歌,属主是对方)
|
||||
|
||||
Owner(...bool) bool // 技能属主,比如寄生和镇魂歌,属主是对方)
|
||||
GetInput() *Input
|
||||
ID(...int) int
|
||||
//GetSkill() *BattleSkillEntity //获得技能ctx
|
||||
|
||||
@@ -118,7 +118,7 @@ func (i *Input) Parseskill(defender *Input, skill *action.SelectSkillAction) {
|
||||
if t != nil {
|
||||
t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
|
||||
|
||||
if t.GetOwner() { //如果取反,说明是给对方添加的回合效果
|
||||
if t.Owner() { //如果取反,说明是给对方添加的回合效果
|
||||
//实际上,owner永远为反,说明是对方给我添加的
|
||||
t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
|
||||
//给双方添加
|
||||
|
||||
@@ -34,7 +34,7 @@ func Geteffect(etype EnumEffectType, id int) Effect {
|
||||
//todo 获取前GetEffect
|
||||
|
||||
eff := deep.MustCopy(ret)
|
||||
|
||||
eff.Alive(true) //添加后默认激活
|
||||
return eff
|
||||
//todo 获取后GetEffect
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func (c *Input) AddEffect(e Effect) {
|
||||
if v.ID() == e.ID() && v.Alive() {
|
||||
|
||||
if v.MaxStack() > 0 {
|
||||
v.NotALive() //取消之前效果
|
||||
e.Alive(false) //取消之前效果
|
||||
if v.Stack() <= v.MaxStack() { //如果小于最大叠层,状态可以叠层
|
||||
e.SetArgs(v.GetInput(), v.GetArgs()...) //参数输入
|
||||
e.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加
|
||||
@@ -152,9 +152,8 @@ func (c *Input) CancelTurn(efftype bool) {
|
||||
for _, value := range c.Effects {
|
||||
if value.Duration() > 0 { //false是自身,true是对方,反转后为真就是自己的
|
||||
//slice = append(slice[:i], slice[i+1:]...)
|
||||
value.NotALive()
|
||||
value.Alive(false)
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ func (f *FightC) handleTimeout(ourID, oppID uint32, actions map[uint32]action.Ba
|
||||
fmt.Printf("玩家%d 超时\n", pid)
|
||||
player := f.GetInputByPlayer(f.getPlayerByID(pid), true).Player
|
||||
if !f.GetInputByPlayer(f.getPlayerByID(pid), false).Finished {
|
||||
fmt.Printf("玩家%d 加载超时\n", pid)
|
||||
f.UseSkill(player, 0) //卡加载,给对方也一个action
|
||||
}
|
||||
f.Over(f.getPlayerByID(pid), info.BattleOverReason.PlayerOVerTime)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/logic/service/fight/input"
|
||||
)
|
||||
|
||||
@@ -24,6 +23,6 @@ func (e *EffectNode) OnOwnerSwitchIn(ctx input.Ctx) bool {
|
||||
|
||||
// 自身下场,清除掉技能效果
|
||||
func (e *EffectNode) OnOwnerSwitchOut(ctx input.Ctx) bool {
|
||||
e.Input.AttackValue = info.NewAttackValue(e.Input.UserID)
|
||||
// e.Input.AttackValue = info.NewAttackValue(e.Input.UserID)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func (e *EffectNode) Turn_Start(ctx input.Ctx) {
|
||||
func (e *EffectNode) Turn_End(ctx input.Ctx) {
|
||||
|
||||
if e.duration == 0 { // 保留 (负数表示永久)
|
||||
e.NotALive()
|
||||
e.Alive(false)
|
||||
} else {
|
||||
e.duration--
|
||||
}
|
||||
|
||||
@@ -15,18 +15,21 @@ type EffectNode struct {
|
||||
id int
|
||||
maxStack int // 最大叠加层数 ,正常都是不允许叠加的,除了衰弱特殊效果 ,异常和能力的叠层
|
||||
SideEffectArgs []int // 附加效果参数
|
||||
Owner bool //是否作用自身
|
||||
owner bool //是否作用自身
|
||||
Success bool // 是否执行成功 成功XXX,失败XXX
|
||||
arget bool // 传出作用对象,默认0是自身,1是作用于对面
|
||||
Flag int //过滤掉的战斗类型 pvp pve boss战斗,野怪全部生效
|
||||
notAlive bool // 是否失效 effect返回值是否被取消,是否被删除
|
||||
alive bool // 是否失效 effect返回值是否被取消,是否被删除
|
||||
hit bool
|
||||
//增加owner target,如果owner target都为自身,就回合效果结束后再使用回合效果
|
||||
}
|
||||
|
||||
func (this *EffectNode) Alive() bool {
|
||||
func (e *EffectNode) Alive(t ...bool) bool {
|
||||
if len(t) > 0 {
|
||||
e.alive = t[0]
|
||||
}
|
||||
|
||||
return !this.notAlive
|
||||
return e.alive
|
||||
|
||||
}
|
||||
func (e *EffectNode) GetInput() *input.Input {
|
||||
@@ -34,74 +37,69 @@ func (e *EffectNode) GetInput() *input.Input {
|
||||
return e.Input
|
||||
|
||||
}
|
||||
func (e *EffectNode) NotALive() {
|
||||
|
||||
e.notAlive = true
|
||||
|
||||
}
|
||||
func (e *EffectNode) GetOwner() bool {
|
||||
|
||||
return e.Owner
|
||||
|
||||
}
|
||||
func (e *EffectNode) SetOwner(b bool) {
|
||||
|
||||
e.Owner = b
|
||||
|
||||
}
|
||||
func (this *EffectNode) Stack(t ...int) int {
|
||||
func (e *EffectNode) Owner(t ...bool) bool {
|
||||
if len(t) > 0 {
|
||||
this.stacks = t[0]
|
||||
e.owner = t[0]
|
||||
}
|
||||
|
||||
return this.stacks
|
||||
return e.owner
|
||||
|
||||
}
|
||||
func (this *EffectNode) ID(t ...int) int {
|
||||
|
||||
func (e *EffectNode) Stack(t ...int) int {
|
||||
if len(t) > 0 {
|
||||
this.id = t[0]
|
||||
e.stacks = t[0]
|
||||
}
|
||||
|
||||
return this.id
|
||||
return e.stacks
|
||||
|
||||
}
|
||||
func (this *EffectNode) Hit(t ...bool) bool {
|
||||
func (e *EffectNode) ID(t ...int) int {
|
||||
if len(t) > 0 {
|
||||
this.hit = t[0]
|
||||
e.id = t[0]
|
||||
}
|
||||
|
||||
return this.hit
|
||||
return e.id
|
||||
|
||||
}
|
||||
func (this *EffectNode) MaxStack(t ...int) int {
|
||||
|
||||
func (e *EffectNode) Hit(t ...bool) bool {
|
||||
if len(t) > 0 {
|
||||
this.maxStack = t[0]
|
||||
e.hit = t[0]
|
||||
}
|
||||
return this.maxStack
|
||||
|
||||
return e.hit
|
||||
|
||||
}
|
||||
func (this *EffectNode) Duration(t ...int) int {
|
||||
func (e *EffectNode) MaxStack(t ...int) int {
|
||||
|
||||
if len(t) > 0 {
|
||||
this.duration = t[0]
|
||||
e.maxStack = t[0]
|
||||
}
|
||||
return this.duration
|
||||
return e.maxStack
|
||||
|
||||
}
|
||||
func (e *EffectNode) Duration(t ...int) int {
|
||||
if len(t) > 0 {
|
||||
e.duration = t[0]
|
||||
}
|
||||
return e.duration
|
||||
|
||||
}
|
||||
|
||||
// 设置参数,加上设置输入源
|
||||
func (this *EffectNode) SetArgs(t *input.Input, a ...int) {
|
||||
this.Input = t
|
||||
this.SideEffectArgs = a
|
||||
func (e *EffectNode) SetArgs(t *input.Input, a ...int) {
|
||||
e.Input = t
|
||||
e.SideEffectArgs = a
|
||||
|
||||
}
|
||||
func (this *EffectNode) GetArgs() []int {
|
||||
func (e *EffectNode) GetArgs() []int {
|
||||
|
||||
return this.SideEffectArgs
|
||||
return e.SideEffectArgs
|
||||
|
||||
}
|
||||
|
||||
func (this *EffectNode) AttackTime(*input.Input, *input.Input) bool {
|
||||
func (e *EffectNode) AttackTime(*input.Input, *input.Input) bool {
|
||||
|
||||
return true
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ var (
|
||||
if cool.IsRedisMode {
|
||||
go cool.ListenFunc(ctx)
|
||||
}
|
||||
go robot()
|
||||
//go robot()
|
||||
s := g.Server()
|
||||
s.Use(Limiter, ghttp.MiddlewareHandlerResponse)
|
||||
s.EnableAdmin()
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||
|
||||
_ "blazing/contrib/drivers/pgsql"
|
||||
"blazing/modules/base/service"
|
||||
|
||||
_ "blazing/contrib/files/local"
|
||||
|
||||
@@ -30,7 +31,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
service.TestSendVerificationCode()
|
||||
cmd.Main.Run(gctx.New())
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ package service
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"fmt"
|
||||
|
||||
"blazing/modules/base/model"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/xiaoqidun/qqwry"
|
||||
)
|
||||
|
||||
type BaseSysLogService struct {
|
||||
@@ -44,7 +46,19 @@ func (s *BaseSysLogService) Record(ctx g.Ctx) {
|
||||
baseSysLog.UserID = admin.UserId
|
||||
baseSysLog.Action = r.Method + ":" + r.URL.Path
|
||||
baseSysLog.IP = r.GetClientIp()
|
||||
baseSysLog.IPAddr = r.GetClientIp()
|
||||
// 从内存或缓存查询IP
|
||||
location, err := qqwry.QueryIP(baseSysLog.IP)
|
||||
if err != nil {
|
||||
fmt.Printf("错误:%v\n", err)
|
||||
return
|
||||
}
|
||||
baseSysLog.IPAddr = fmt.Sprintf("国家:%s,省份:%s,城市:%s,区县:%s,运营商:%s\n",
|
||||
location.Country,
|
||||
location.Province,
|
||||
location.City,
|
||||
location.District,
|
||||
location.ISP,
|
||||
)
|
||||
baseSysLog.Params = r.GetBodyString()
|
||||
m := cool.DBM(s.Model)
|
||||
m.Insert(g.Map{
|
||||
@@ -68,3 +82,11 @@ func (s *BaseSysLogService) Clear(isAll bool) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func init() {
|
||||
// 从文件加载IP数据库
|
||||
if err := qqwry.LoadFile("public/qqwry.ipdb"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
225
modules/base/service/base_sys_reg.go
Normal file
225
modules/base/service/base_sys_reg.go
Normal file
@@ -0,0 +1,225 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SMTPConfig 邮件发送配置
|
||||
type SMTPConfig struct {
|
||||
Host string // SMTP服务器地址
|
||||
Port int // SMTP端口
|
||||
Username string // 发件人邮箱
|
||||
Password string // SMTP授权密码
|
||||
}
|
||||
|
||||
// 默认腾讯企业邮配置(可根据实际情况修改)
|
||||
var DefaultSMTPConfig = SMTPConfig{
|
||||
Host: "smtp.qcloudmail.com",
|
||||
Port: 465,
|
||||
Username: "1@seersun.com",
|
||||
Password: "z1Tq6v45vXbYQGBrqOUE",
|
||||
}
|
||||
|
||||
// VerificationCodeData 验证码邮件模板数据
|
||||
type VerificationCodeData struct {
|
||||
Code string // 验证码
|
||||
ValidMin int // 有效期(分钟)
|
||||
Platform string // 平台名称
|
||||
Hotline string // 客服热线
|
||||
}
|
||||
|
||||
// 验证码邮件HTML模板
|
||||
const verificationCodeTemplate = `<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>验证码通知</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", Arial, sans-serif; }
|
||||
body { background: #f5f7fa; padding: 20px 0; }
|
||||
.email-container { max-width: 550px; margin: 0 auto; background: #fff; border-radius: 12px; box-shadow: 0 3px 15px rgba(0,0,0,0.05); overflow: hidden; }
|
||||
.email-header { background: linear-gradient(135deg, #667eea, #764ba2); padding: 28px; text-align: center; }
|
||||
.header-icon { width: 48px; height: 48px; margin: 0 auto 12px; background: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
|
||||
.icon-code { color: #667eea; font-size: 24px; font-weight: 700; }
|
||||
.header-title { color: #fff; font-size: 20px; font-weight: 600; }
|
||||
.email-content { padding: 30px 24px; text-align: center; }
|
||||
.content-desc { font-size: 15px; color: #666; line-height: 1.8; margin-bottom: 28px; }
|
||||
.code-box { display: inline-block; background: #f8f9fa; border-radius: 8px; padding: 16px 32px; margin-bottom: 28px; }
|
||||
.verify-code { font-size: 28px; color: #667eea; font-weight: 700; letter-spacing: 8px; }
|
||||
.warning-box { background: #fff8e1; border-radius: 8px; padding: 14px; margin: 0 20px 24px; }
|
||||
.warning-text { font-size: 13px; color: #e65100; line-height: 1.6; }
|
||||
.footer-note { font-size: 12px; color: #999; line-height: 1.5; }
|
||||
.email-footer { background: #f8f9fa; padding: 20px; text-align: center; font-size: 11px; color: #999; margin-top: 16px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="email-container">
|
||||
<!-- 邮件头部 -->
|
||||
<div class="email-header">
|
||||
<div class="header-icon">
|
||||
<span class="icon-code">注册</span>
|
||||
</div>
|
||||
<div class="header-title">验证码通知</div>
|
||||
</div>
|
||||
<!-- 邮件内容 -->
|
||||
<div class="email-content">
|
||||
<p class="content-desc">尊敬的用户,您好!您正在进行身份验证操作,本次验证码如下:</p>
|
||||
<!-- 验证码展示框 -->
|
||||
<div class="code-box">
|
||||
<span class="verify-code">{{.Code}}</span>
|
||||
</div>
|
||||
<!-- 提醒框 -->
|
||||
<div class="warning-box">
|
||||
<p class="warning-text">⚠ 验证码有效期为{{.ValidMin}}分钟,请尽快完成验证。如非本人操作,请忽略此邮件。</p>
|
||||
</div>
|
||||
<p class="footer-note">为保障您的账号安全,请勿将验证码泄露给他人。</p>
|
||||
</div>
|
||||
<!-- 邮件底部 -->
|
||||
<div class="email-footer">
|
||||
<p>© 2025 {{.Platform}} 版权所有 | 官网:{{.Hotline}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
// SendVerificationCode 发送验证码邮件
|
||||
// to: 收件人邮箱
|
||||
// code: 验证码
|
||||
// 返回错误信息
|
||||
func SendVerificationCode(to, code string) error {
|
||||
// 模板数据
|
||||
data := VerificationCodeData{
|
||||
Code: code,
|
||||
ValidMin: 10, // 有效期10分钟
|
||||
Platform: "骄阳号", // 可替换为实际平台名称
|
||||
Hotline: "seersun.com", // 可替换为实际客服热线
|
||||
}
|
||||
|
||||
// 生成邮件内容
|
||||
body, err := renderTemplate(verificationCodeTemplate, data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("渲染模板失败: %w", err)
|
||||
}
|
||||
|
||||
// 发送邮件
|
||||
return sendMail(
|
||||
DefaultSMTPConfig,
|
||||
to,
|
||||
"验证码通知",
|
||||
body,
|
||||
)
|
||||
}
|
||||
|
||||
// renderTemplate 渲染模板
|
||||
func renderTemplate(tplStr string, data interface{}) (string, error) {
|
||||
tpl, err := template.New("verification").Parse(tplStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
buf := new(strings.Builder)
|
||||
if err := tpl.Execute(buf, data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// sendMail 发送邮件核心函数
|
||||
func sendMail(config SMTPConfig, to, subject, body string) error {
|
||||
// 构建邮件头部
|
||||
header := make(map[string]string)
|
||||
header["From"] = fmt.Sprintf("骄阳号 <%s>", config.Username)
|
||||
header["To"] = to
|
||||
header["Subject"] = subject
|
||||
header["Content-Type"] = "text/html; charset=UTF-8"
|
||||
|
||||
// 拼接邮件内容
|
||||
message := ""
|
||||
for k, v := range header {
|
||||
message += fmt.Sprintf("%s: %s\r\n", k, v)
|
||||
}
|
||||
message += "\r\n" + body
|
||||
|
||||
// 认证信息
|
||||
auth := smtp.PlainAuth(
|
||||
"",
|
||||
config.Username,
|
||||
config.Password,
|
||||
config.Host,
|
||||
)
|
||||
|
||||
// 发送邮件
|
||||
addr := fmt.Sprintf("%s:%d", config.Host, config.Port)
|
||||
return SendMailWithTLS(addr, auth, config.Username, []string{to}, []byte(message))
|
||||
}
|
||||
|
||||
// Dial 创建TLS连接的SMTP客户端
|
||||
func Dial(addr string) (*smtp.Client, error) {
|
||||
conn, err := tls.Dial("tcp", addr, nil)
|
||||
if err != nil {
|
||||
log.Println("tls.Dial Error:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host, _, _ := net.SplitHostPort(addr)
|
||||
return smtp.NewClient(conn, host)
|
||||
}
|
||||
|
||||
// SendMailWithTLS 使用TLS发送邮件
|
||||
func SendMailWithTLS(addr string, auth smtp.Auth, from string,
|
||||
to []string, msg []byte) (err error) {
|
||||
c, err := Dial(addr)
|
||||
if err != nil {
|
||||
log.Println("创建SMTP客户端失败:", err)
|
||||
return err
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
if auth != nil {
|
||||
if ok, _ := c.Extension("AUTH"); ok {
|
||||
if err = c.Auth(auth); err != nil {
|
||||
log.Println("认证失败:", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = c.Mail(from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, addr := range to {
|
||||
if err = c.Rcpt(addr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
w, err := c.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Quit()
|
||||
}
|
||||
|
||||
// TestSendVerificationCode 测试发送验证码邮件
|
||||
func TestSendVerificationCode() error {
|
||||
// 测试发送验证码为123456的邮件
|
||||
return SendVerificationCode("3361562035@qq.com", "123456")
|
||||
}
|
||||
BIN
public/login
BIN
public/login
Binary file not shown.
Reference in New Issue
Block a user