forked from ProjectWIND/ProjectWIND
项目初始化
This commit is contained in:
commit
b9856300aa
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/main/tmp
|
||||
/scripts
|
||||
/main/.git
|
||||
/main/.gitignore
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
9
.idea/ProjectWIND.iml
generated
Normal file
9
.idea/ProjectWIND.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/ProjectWIND.iml" filepath="$PROJECT_DIR$/.idea/ProjectWIND.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
7
.idea/vcs.xml
generated
Normal file
7
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/main" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
8
LICENSE
Normal file
8
LICENSE
Normal file
@ -0,0 +1,8 @@
|
||||
Copyright (C) 2024 Sheyiyuan
|
||||
|
||||
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.
|
12
go.mod
Normal file
12
go.mod
Normal file
@ -0,0 +1,12 @@
|
||||
module ProjectWIND
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require (
|
||||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||
github.com/dop251/goja v0.0.0-20241024094426-79f3a7efcdbd // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
|
||||
github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
)
|
18
go.sum
Normal file
18
go.sum
Normal file
@ -0,0 +1,18 @@
|
||||
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dop251/goja v0.0.0-20241024094426-79f3a7efcdbd h1:QMSNEh9uQkDjyPwu/J541GgSH+4hw+0skJDIj9HJ3mE=
|
||||
github.com/dop251/goja v0.0.0-20241024094426-79f3a7efcdbd/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q=
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
|
||||
github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b h1:SXO0REt4iu865upYCk8aKBBJQ4BqoE0ReP23ClMu60s=
|
||||
github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
17
main.go
Normal file
17
main.go
Normal file
@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"ProjectWIND/protocol"
|
||||
"log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
_, err := protocol.WebSocketHandler()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
39
protocol/api.go
Normal file
39
protocol/api.go
Normal file
@ -0,0 +1,39 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"ProjectWIND/typed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
}
|
||||
|
||||
func SendMessage(messageType string, message string, targetId int64, autoEscape bool) (bool, error) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData typed.APIRequest
|
||||
messageData.Action = "send_msg"
|
||||
switch messageType {
|
||||
case "private":
|
||||
messageData.Params.UserId = targetId
|
||||
break
|
||||
case "group":
|
||||
messageData.Params.GroupId = targetId
|
||||
break
|
||||
default:
|
||||
return false, errors.New("invalid type")
|
||||
}
|
||||
messageData.Params.Message = message
|
||||
messageData.Params.AutoEscape = autoEscape
|
||||
messageJson, err := json.Marshal(messageData)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// 发送消息
|
||||
_, err = wsSendMessage(messageJson)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
71
protocol/events_handler.go
Normal file
71
protocol/events_handler.go
Normal file
@ -0,0 +1,71 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"ProjectWIND/typed"
|
||||
"encoding/json"
|
||||
"log"
|
||||
)
|
||||
|
||||
func HandleMessage(msgJson []byte) {
|
||||
var msg typed.MessageEventInfo
|
||||
err := json.Unmarshal(msgJson, &msg)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] unmarshalling message: ", err)
|
||||
}
|
||||
// 处理消息
|
||||
log.Printf("[INFO] 收到消息:(来自:%v-%v:%v-%v)%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, msg.RawMessage)
|
||||
//一个简单的测试
|
||||
if msg.RawMessage == "wind test" {
|
||||
log.Println("[INFO] 收到wind test")
|
||||
switch msg.MessageType {
|
||||
case "group":
|
||||
{
|
||||
_, err := SendMessage(msg.MessageType, "wind test success", msg.GroupId, false)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] send message: ", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
case "private":
|
||||
{
|
||||
_, err := SendMessage(msg.MessageType, "wind test success", msg.UserId, false)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] send message: ", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
{
|
||||
log.Println("[ERROR] 不支持的消息类型")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func HandleNotice(msgJson []byte) {
|
||||
var notice typed.NoticeEventInfo
|
||||
err := json.Unmarshal(msgJson, ¬ice)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] unmarshalling notice: ", err)
|
||||
}
|
||||
// 处理通知
|
||||
}
|
||||
|
||||
func HandleRequest(msgJson []byte) {
|
||||
var request typed.NoticeEventInfo
|
||||
err := json.Unmarshal(msgJson, &request)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] unmarshalling request: ", err)
|
||||
}
|
||||
// 处理请求
|
||||
}
|
||||
|
||||
func HandleMetaEvent(msgJson []byte) {
|
||||
var meta typed.NoticeEventInfo
|
||||
err := json.Unmarshal(msgJson, &meta)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] unmarshalling meta: ", err)
|
||||
}
|
||||
// 处理元事件
|
||||
}
|
122
protocol/web_socket.go
Normal file
122
protocol/web_socket.go
Normal file
@ -0,0 +1,122 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const (
|
||||
severURL = "ws://110.41.4.138:3001"
|
||||
)
|
||||
|
||||
func WebSocketHandler() (*websocket.Conn, error) {
|
||||
u, err := url.Parse(severURL)
|
||||
if err != nil {
|
||||
log.Println("Parse URL error:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] Dial error:", err)
|
||||
return nil, err
|
||||
}
|
||||
defer func(conn *websocket.Conn) {
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
log.Println("[ERROR] Close error:", err)
|
||||
}
|
||||
}(conn)
|
||||
|
||||
for {
|
||||
messageType, message, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("[ERROR] Read error:", err)
|
||||
break
|
||||
}
|
||||
|
||||
// 将接收到的消息交给另一个函数处理
|
||||
processMessage(messageType, message)
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func processMessage(messageType int, message []byte) {
|
||||
if messageType != websocket.TextMessage {
|
||||
log.Println("[INFO] Invalid message type:", messageType)
|
||||
return
|
||||
}
|
||||
//message json解析
|
||||
var messageMap map[string]interface{}
|
||||
err := json.Unmarshal(message, &messageMap)
|
||||
if err != nil {
|
||||
log.Println("[ERROR] Unmarshal error:", err)
|
||||
return
|
||||
}
|
||||
// 处理接收到的消息
|
||||
messageTypeStr := messageMap["post_type"]
|
||||
switch messageTypeStr {
|
||||
case "message":
|
||||
{
|
||||
// 处理message消息
|
||||
HandleMessage(message)
|
||||
return
|
||||
}
|
||||
case "notice":
|
||||
{
|
||||
// 处理notice消息
|
||||
HandleNotice(message)
|
||||
return
|
||||
}
|
||||
case "request":
|
||||
{
|
||||
// 处理request消息
|
||||
HandleRequest(message)
|
||||
return
|
||||
}
|
||||
case "meta_event":
|
||||
{
|
||||
// 处理meta_event消息
|
||||
HandleMetaEvent(message)
|
||||
return
|
||||
}
|
||||
default:
|
||||
{
|
||||
// 打印接收到的消息
|
||||
log.Printf("[WARN] Received message: %s", message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wsSendMessage 向WebSocket服务器发送消息并返回发送状态
|
||||
func wsSendMessage(message []byte) (bool, error) {
|
||||
// 解析连接URL
|
||||
u, err := url.Parse(fmt.Sprintf("%v/api", severURL))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("无效的URL: %v", err)
|
||||
}
|
||||
|
||||
// 建立连接
|
||||
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("连接失败: %v", err)
|
||||
}
|
||||
defer func(conn *websocket.Conn) {
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
log.Println("[ERROR] Close error:", err)
|
||||
}
|
||||
}(conn)
|
||||
|
||||
// 发送消息
|
||||
err = conn.WriteMessage(websocket.TextMessage, message)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("发送消息失败: %v", err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
8
readme.md
Normal file
8
readme.md
Normal file
@ -0,0 +1,8 @@
|
||||
# ProjectWIND
|
||||
骰子框架,自用
|
||||
|
||||
<div style="text-align: center;"><img src="./icon.png" alt="ProjectWIND" width="50%" ></div>
|
||||
|
||||
license: [MIT](./LICENSE)
|
||||
|
||||
开发者很懒,什么都没有写。
|
132
typed/typed.go
Normal file
132
typed/typed.go
Normal file
@ -0,0 +1,132 @@
|
||||
package typed
|
||||
|
||||
type MessageEventInfo struct {
|
||||
Time int64 `json:"time,omitempty"`
|
||||
SelfId int64 `json:"self_id,omitempty"`
|
||||
PostType string `json:"post_type,omitempty"`
|
||||
MessageType string `json:"message_type,omitempty"`
|
||||
SubType string `json:"sub_type,omitempty"`
|
||||
MessageId int32 `json:"message_id,omitempty"`
|
||||
GroupId int64 `json:"group_id,omitempty"`
|
||||
UserId int64 `json:"user_id,omitempty"`
|
||||
Anonymous AnonymousInfo `json:"anonymous"`
|
||||
Message []MessageInfo `json:"message,omitempty"`
|
||||
RawMessage string `json:"raw_message,omitempty"`
|
||||
Font int32 `json:"font,omitempty"`
|
||||
Sender SenderInfo `json:"sender"`
|
||||
}
|
||||
|
||||
type NoticeEventInfo struct {
|
||||
Time int64 `json:"time,omitempty"`
|
||||
SelfId int64 `json:"self_id,omitempty"`
|
||||
PostType string `json:"post_type,omitempty"`
|
||||
NoticeType string `json:"notice_type,omitempty"`
|
||||
GroupId int64 `json:"group_id,omitempty"`
|
||||
UserId int64 `json:"user_id,omitempty"`
|
||||
File FileInfo `json:"file,omitempty"`
|
||||
SubType string `json:"sub_type,omitempty"`
|
||||
OperatorId int64 `json:"operator_id,omitempty"`
|
||||
Duration int64 `json:"duration,omitempty"`
|
||||
MessageId int64 `json:"message,omitempty"`
|
||||
TargetId int64 `json:"target_id,omitempty"`
|
||||
HonorType string `json:"honor_type,omitempty"`
|
||||
}
|
||||
|
||||
type RequestEventInfo struct {
|
||||
Time int64 `json:"time,omitempty"`
|
||||
SelfId int64 `json:"self_id,omitempty"`
|
||||
PostType string `json:"post_type,omitempty"`
|
||||
RequestType string `json:"request_type,omitempty"`
|
||||
SubType string `json:"sub_type,omitempty"`
|
||||
UserId int64 `json:"user_id,omitempty"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
Flag string `json:"flag,omitempty"`
|
||||
GroupId int64 `json:"group_id,omitempty"`
|
||||
}
|
||||
|
||||
type MetaEventInfo struct {
|
||||
Time int64 `json:"time,omitempty"`
|
||||
SelfId int64 `json:"self_id,omitempty"`
|
||||
PostType string `json:"post_type,omitempty"`
|
||||
MetaEventType string `json:"meta_event_type,omitempty"`
|
||||
SubType string `json:"sub_type,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Interval int64 `json:"interval,omitempty"`
|
||||
}
|
||||
|
||||
type FileInfo struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Busid int64 `json:"bucket,omitempty"`
|
||||
}
|
||||
|
||||
type SenderInfo struct {
|
||||
UserId int64 `json:"user_id,omitempty"`
|
||||
Nickname string `json:"nickname,omitempty"`
|
||||
Card string `json:"card,omitempty"`
|
||||
Sex string `json:"sex,omitempty"`
|
||||
Age int32 `json:"age,omitempty"`
|
||||
Area string `json:"area,omitempty"`
|
||||
Level string `json:"level,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
type AnonymousInfo struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Flag string `json:"flag,omitempty"`
|
||||
}
|
||||
|
||||
type MessageInfo struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Data MessageDataInfo `json:"data"`
|
||||
}
|
||||
|
||||
type MessageDataInfo struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Id string `json:"id,omitempty"`
|
||||
File string `json:"file,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
Magic string `json:"magic,omitempty"`
|
||||
Qq string `json:"qq,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
Audio string `json:"audio,omitempty"`
|
||||
Lat string `json:"lat,omitempty"`
|
||||
Lon string `json:"lon,omitempty"`
|
||||
Data string `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type APIRequest struct {
|
||||
Action string `json:"action,omitempty"`
|
||||
Params ParamsInfo `json:"params"`
|
||||
Echo string `json:"echo,omitempty"`
|
||||
}
|
||||
|
||||
type ParamsInfo struct {
|
||||
Message string `json:"message,omitempty"`
|
||||
UserId int64 `json:"user_id,omitempty"`
|
||||
GroupId int64 `json:"group_id,omitempty"`
|
||||
AutoEscape bool `json:"auto_escape,omitempty"`
|
||||
MessageId int32 `json:"message_id,omitempty"`
|
||||
Id string `json:"id,omitempty"`
|
||||
RejectAddRequest bool `json:"reject_add_request,omitempty"`
|
||||
Duration int32 `json:"duration,omitempty"`
|
||||
Enable bool `json:"enable,omitempty"`
|
||||
Card string `json:"card,omitempty"`
|
||||
GroupName string `json:"group_name,omitempty"`
|
||||
IsDismiss bool `json:"is_dismiss,omitempty"`
|
||||
SpecialTitle string `json:"special_title,omitempty"`
|
||||
Flag string `json:"flag,omitempty"`
|
||||
Approve bool `json:"approve,omitempty"`
|
||||
Remark string `json:"remark,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
SubType string `json:"sub_type,omitempty"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
NoCache bool `json:"no_cache,omitempty"`
|
||||
File string `json:"file,omitempty"`
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user