Skip to content

Commit

Permalink
Beta31 (#94)
Browse files Browse the repository at this point in the history
* beta31

* add silk
  • Loading branch information
Hoshinonyaruko authored Nov 14, 2023
1 parent 4aad4b0 commit 77ffc84
Show file tree
Hide file tree
Showing 12 changed files with 354 additions and 3 deletions.
40 changes: 39 additions & 1 deletion echo/messageidmap.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package echo

import (
"fmt"
"log"
"math/rand"
"strconv"
"strings"
"sync"
"time"

"github.com/hoshinonyaruko/gensokyo/config"
"github.com/hoshinonyaruko/gensokyo/idmap"
)

type messageRecord struct {
Expand Down Expand Up @@ -55,7 +62,38 @@ func GetLazyMessagesId(groupID string) string {
randomIndex := rand.Intn(len(recentMessages))
randomMessageID = recentMessages[randomIndex]
} else {
randomMessageID = ""
msgType := GetMessageIDByUseridOrGroupidv2(config.GetAppIDStr(), groupID)
if strings.HasPrefix(msgType, "guild") {
randomMessageID = "1000" // 频道主动信息
} else {
randomMessageID = ""
}
}
return randomMessageID
}

// 通过user_id获取messageID
func GetMessageIDByUseridOrGroupidv2(appID string, userID interface{}) string {
// 从appID和userID生成key
var userIDStr string
switch u := userID.(type) {
case int:
userIDStr = strconv.Itoa(u)
case int64:
userIDStr = strconv.FormatInt(u, 10)
case float64:
userIDStr = strconv.FormatFloat(u, 'f', 0, 64)
case string:
userIDStr = u
default:
// 可能需要处理其他类型或报错
return ""
}
//将真实id转为int
userid64, err := idmap.StoreIDv2(userIDStr)
if err != nil {
log.Fatalf("Error storing ID 241: %v", err)
}
key := appID + "_" + fmt.Sprint(userid64)
return GetMsgIDByKey(key)
}
Empty file removed git
Empty file.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mvdan/xurls v1.1.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/wdvxdr1123/go-silk v0.0.0-20220304095002-f67345df09ea // indirect
modernc.org/libc v1.8.1 // indirect
modernc.org/mathutil v1.2.2 // indirect
modernc.org/memory v1.0.4 // indirect
)

replace github.com/tencent-connect/botgo => ./botgo
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
Expand Down Expand Up @@ -101,6 +102,8 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZ
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand All @@ -123,6 +126,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/wdvxdr1123/go-silk v0.0.0-20220304095002-f67345df09ea h1:sl1pYm1kHtIndckTY8YDt+QFt77vI0JnKHP0U8rZtKc=
github.com/wdvxdr1123/go-silk v0.0.0-20220304095002-f67345df09ea/go.mod h1:ecFKZPX81BaB70I6ruUgEwYcDOtuNgJGnjdK+MIl5ko=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
Expand Down Expand Up @@ -152,9 +157,11 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down Expand Up @@ -199,6 +206,13 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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=
modernc.org/libc v1.8.1 h1:y9oPIhwcaFXxX7kMp6Qb2ZLKzr0mDkikWN3CV5GS63o=
modernc.org/libc v1.8.1/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
mvdan.cc/xurls v1.1.0 h1:kj0j2lonKseISJCiq1Tfk+iTv65dDGCl0rTbanXJGGc=
mvdan.cc/xurls v1.1.0/go.mod h1:TNWuhvo+IqbUCmtUIb/3LJSQdrzel8loVpgFm0HikbI=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
24 changes: 23 additions & 1 deletion handlers/send_group_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,29 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText
SrvSendMsg: true,
}
} else if voiceURLs, ok := foundItems["base64_record"]; ok && len(voiceURLs) > 0 {
// 目前不支持发语音 todo 适配base64 slik
// 适配base64 slik
if base64_record, ok := foundItems["base64_record"]; ok && len(base64_record) > 0 {
// 解码base64语音数据
fileRecordData, err := base64.StdEncoding.DecodeString(base64_record[0])
if err != nil {
mylog.Printf("failed to decode base64 record: %v", err)
return nil
}
// 将解码的语音数据转换回base64格式并上传
imageURL, err := images.UploadBase64RecordToServer(base64.StdEncoding.EncodeToString(fileRecordData))
if err != nil {
mylog.Printf("failed to upload base64 record: %v", err)
return nil
}
// 创建RichMediaMessage并返回
return &dto.RichMediaMessage{
EventID: id,
FileType: 3, // 3代表语音
URL: imageURL,
Content: "", // 这个字段文档没有了
SrvSendMsg: true,
}
}
} else if base64_image, ok := foundItems["base64_image"]; ok && len(base64_image) > 0 {
// todo 适配base64图片
//因为QQ群没有 form方式上传,所以在gensokyo内置了图床,需公网,或以lotus方式连接位于公网的gensokyo
Expand Down
2 changes: 1 addition & 1 deletion handlers/send_guild_channel_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func GenerateReplyMessage(id string, foundItems map[string][]string, messageText
MsgType: 0, // Assuming type 0 for images
}
} else if voiceURLs, ok := foundItems["base64_record"]; ok && len(voiceURLs) > 0 {
//还不支持发语音
//频道 还不支持发语音
// Sending a voice message
// reply = dto.MessageToCreate{
// EventID: id,
Expand Down
71 changes: 71 additions & 0 deletions images/upload_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,45 @@ func UploadBase64ImageToServer(base64Image string) (string, error) {
return "", errors.New("local server uses a private address; image upload failed")
}

// 将base64语音通过lotus转换成url
func UploadBase64RecordToServer(base64Image string) (string, error) {
// 根据serverPort确定协议
protocol := "http"
serverPort := config.GetPortValue()
if serverPort == "443" {
protocol = "https"
}

if config.GetLotusValue() {
serverDir := config.GetServer_dir()
url := fmt.Sprintf("%s://%s:%s/uploadrecord", protocol, serverDir, serverPort)

resp, err := postRecordToServer(base64Image, url)
if err != nil {
return "", err
}
return resp, nil
}

serverDir := config.GetServer_dir()
// 当端口是443时,使用HTTP和444端口
if serverPort == "443" {
protocol = "http"
serverPort = "444"
}

if isPublicAddress(serverDir) {
url := fmt.Sprintf("%s://127.0.0.1:%s/uploadrecord", protocol, serverPort)

resp, err := postRecordToServer(base64Image, url)
if err != nil {
return "", err
}
return resp, nil
}
return "", errors.New("local server uses a private address; image record failed")
}

// 请求图床api(图床就是lolus为false的gensokyo)
func postImageToServer(base64Image, targetURL string) (string, error) {
data := url.Values{}
Expand Down Expand Up @@ -84,6 +123,38 @@ func postImageToServer(base64Image, targetURL string) (string, error) {
return "", fmt.Errorf("URL not found in response")
}

// 请求语音床api(图床就是lolus为false的gensokyo)
func postRecordToServer(base64Image, targetURL string) (string, error) {
data := url.Values{}
data.Set("base64Record", base64Image) // 修改字段名以与服务器匹配

resp, err := http.PostForm(targetURL, data)
if err != nil {
return "", fmt.Errorf("failed to send request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("error response from server: %s", resp.Status)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("failed to read response body: %v", err)
}

var responseMap map[string]interface{}
if err := json.Unmarshal(body, &responseMap); err != nil {
return "", fmt.Errorf("failed to unmarshal response: %v", err)
}

if value, ok := responseMap["url"]; ok {
return fmt.Sprintf("%v", value), nil
}

return "", fmt.Errorf("URL not found in response")
}

// 判断是否公网ip 填写域名也会被认为是公网,但需要用户自己确保域名正确解析到gensokyo所在的ip地址
func isPublicAddress(addr string) bool {
if strings.Contains(addr, "localhost") || strings.HasPrefix(addr, "127.") || strings.HasPrefix(addr, "192.168.") {
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ func main() {
}
r.GET("/getid", server.GetIDHandler)
r.POST("/uploadpic", server.UploadBase64ImageHandler(rateLimiter))
r.POST("/uploadrecord", server.UploadBase64RecordHandler(rateLimiter))
r.Static("/channel_temp", "./channel_temp")
//webui和它的api
webuiGroup := r.Group("/webui")
Expand Down
8 changes: 8 additions & 0 deletions mylog/mylog.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ type EnhancedLogEntry struct {
Message string `json:"message"`
}

//todo 下面的不会存入文件,上头的,不会进入ws,改一改

// 日志频道,所有的 WebSocket 客户端都会在此监听日志事件
var logChannel = make(chan EnhancedLogEntry, 1000)

Expand All @@ -199,6 +201,12 @@ func Printf(format string, v ...interface{}) {
emitLog("INFO", message)
}

func Errorf(format string, v ...interface{}) {
log.Printf(format, v...)
message := fmt.Sprintf(format, v...)
emitLog("ERROR", message)
}

func emitLog(level, message string) {
entry := EnhancedLogEntry{
Time: time.Now().Format("2006-01-02T15:04:05"),
Expand Down
57 changes: 57 additions & 0 deletions server/uploadpic.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,63 @@ func UploadBase64ImageHandler(rateLimiter *RateLimiter) gin.HandlerFunc {
}
}

// 闭包,网页后端,语音床逻辑,基于gin和www静态文件的简易语音床
func UploadBase64RecordHandler(rateLimiter *RateLimiter) gin.HandlerFunc {
return func(c *gin.Context) {
ipAddress := c.ClientIP()
if !rateLimiter.CheckAndUpdateRateLimit(ipAddress) {
c.JSON(http.StatusTooManyRequests, gin.H{"error": "rate limit exceeded"})
return
}

base64REcord := c.PostForm("base64Record")
// Print the length of the received base64 data
mylog.Println("Received base64 data length:", len(base64REcord), "characters")

RecordBytes, err := base64.StdEncoding.DecodeString(base64REcord)
if err != nil {
mylog.Println("Error while decoding base64:", err) // Print error while decoding
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid base64 data"})
return
}

fileName := generateRandomMd5() + ".silk"
directoryPath := "./channel_temp/"
savePath := directoryPath + fileName

// Create the directory if it doesn't exist
err = os.MkdirAll(directoryPath, 0755)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "error creating directory"})
return
}

err = os.WriteFile(savePath, RecordBytes, 0644)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "error saving file"})
return
}

serverAddress := config.GetServer_dir()
serverPort := config.GetPortValue()
if serverAddress == "" {
// Handle the case where the server address is not configured
c.JSON(http.StatusInternalServerError, gin.H{"error": "server address is not configured"})
return
}

// 根据serverPort确定协议
protocol := "http"
if serverPort == "443" {
protocol = "https"
}

imageURL := fmt.Sprintf("%s://%s:%s/channel_temp/%s", protocol, serverAddress, serverPort, fileName)
c.JSON(http.StatusOK, gin.H{"url": imageURL})

}
}

// 检查是否超过调用频率限制
// 默认1分钟30次 todo 允许用户自行在config编辑限制次数
func (rl *RateLimiter) CheckAndUpdateRateLimit(ipAddress string) bool {
Expand Down
Loading

0 comments on commit 77ffc84

Please sign in to comment.