项目初始化

This commit is contained in:
Sheyiyuan 2024-11-28 15:20:29 +08:00
commit b9856300aa
15 changed files with 463 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/main/tmp
/scripts
/main/.git
/main/.gitignore

8
.idea/.gitignore generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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=

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

17
main.go Normal file
View 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
View 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
}

View 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, &notice)
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
View 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
View 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
View 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"`
}