Merge branch 'main' of github.com:72wo/blazing

This commit is contained in:
2025-11-04 10:47:35 +08:00
40 changed files with 1108 additions and 149 deletions

1
.gitignore vendored
View File

@@ -39,3 +39,4 @@ login/login
login/login
logic/logic1
logic/logic1
logic/logic1

View 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
)

View 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=

View 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)
}
}
}

View File

@@ -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

View File

@@ -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=

View File

@@ -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

View File

@@ -63,7 +63,7 @@ func (h *ServerHandler) RegisterLogic(ctx context.Context, id, port uint16) erro
}
Clientmap[port] = &revClient
Refurh()
//Refurh()
return nil
}

View File

@@ -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))
}

View File

@@ -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()
}
}

View 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.

View File

@@ -0,0 +1,71 @@
# QQWry [![Go Reference](https://pkg.go.dev/badge/github.com/xiaoqidun/qqwry.svg)](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 apicurl 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文件往你用到的项目中拷贝一份

View 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),
)
}

View 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
)

View 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
View 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
}

View 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),
)
}

View 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
View 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
}

View File

@@ -15,6 +15,7 @@ use (
./common/utils/goja
./common/utils/limit
./common/utils/log
./common/utils/qqwry
./common/utils/sturc
./common/utils/xml
./logic

View File

@@ -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

View File

@@ -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

View File

@@ -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=

View File

@@ -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)
}

View File

@@ -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,
},
})

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -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]...) //设置入参,施加方永远是我方
//给双方添加

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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--
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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())
}

View File

@@ -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)
}
}

View 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")
}

Binary file not shown.