mpp-client-go/main.go

296 lines
6.1 KiB
Go

package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"net/url"
"os"
"os/signal"
"strconv"
"strings"
"time"
"github.com/Hri7566/mpp-client-go/mpp"
"github.com/gorilla/websocket"
"github.com/joho/godotenv"
)
var addr = flag.String("addr", "mppclone.com:8443", "websocket address")
var token string
func main() {
helpCommands = commands
SetupDb()
flag.Parse()
log.SetFlags(0)
err := godotenv.Load()
if err != nil {
log.Fatal(err)
}
token = os.Getenv("MPPNET_TOKEN")
StartSocket(addr)
}
func StartSocket(address *string) {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
url := url.URL{Scheme: "wss", Host: *addr}
ws, _, err := websocket.DefaultDialer.Dial(url.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer ws.Close()
done := make(chan struct{})
serverTicker := time.NewTicker(15 * time.Second)
serverTickerQuit := make(chan struct{})
go func() {
for {
select {
case <-serverTicker.C:
SendTimeMessage(ws)
case <-serverTickerQuit:
serverTicker.Stop()
}
}
}()
go func() {
defer close(done)
for {
_, message, err := ws.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
// log.Printf("recv: %s", message)
go ReceiveMessage(ws, message)
// if (!sentHi) {
// // histr := "[{\"m\":\"hi\"},{\"m\":\"ch\",\"_id\":\"✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧\"}]"
// histr := "[{\"m\":\"hi\",\"token\":\"" + *token + "\"}]"
// println("Sending hi message: " + histr)
// err := ws.WriteMessage(1, []byte(histr))
// if err != nil {
// log.Println(err)
// }
// SendTimeMessage(ws)
// sentHi = true
// }
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case <-interrupt:
log.Println("interrupt")
err := ws.WriteMessage(
websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""),
)
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
func ReceiveMessage(ws *websocket.Conn, data []byte) {
var tmp []json.RawMessage
err := json.Unmarshal(data, &tmp)
if err != nil {
log.Fatal(err)
return
}
var header struct {
Type string `json:"m"`
}
for _, raw := range tmp {
_ = json.Unmarshal(raw, &header)
switch header.Type {
case "hi":
msg := mpp.HiMppMessage{}
_ = json.Unmarshal(raw, &msg)
ReceiveHiMessage(ws, &msg)
case "nq":
msg := mpp.NoteQuotaMppMessage{}
_ = json.Unmarshal(raw, &msg)
ReceiveNqMessage(&msg)
case "t":
msg := mpp.TimeMppMessage{}
_ = json.Unmarshal(raw, &msg)
case "a":
msg := mpp.ChatMppMessage{}
_ = json.Unmarshal(raw, &msg)
ReceiveChatMessage(ws, &msg)
case "b":
SendHandshake(ws)
default:
return
}
}
// println("Correctly deserialized JSON")
// spew.Dump(tmp)
// for _, msg := range msgs {
// println(msg.Type)
// }
}
func ReceiveNqMessage(msg *mpp.NoteQuotaMppMessage) {
// println(msg.MaxHistLen)
}
func ReceiveHiMessage(ws *websocket.Conn, msg *mpp.HiMppMessage) {
println("I am " + msg.User.Name)
chstr := "[{\"m\":\"ch\",\"_id\":\"✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧\"}]"
// println("Sending ch message: " + chstr)
err2 := ws.WriteMessage(1, []byte(chstr))
if err2 != nil {
log.Println(err2)
}
}
func SendHandshake(ws *websocket.Conn) {
// histr := "[{\"m\":\"hi\"},{\"m\":\"ch\",\"_id\":\"✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧\"}]"
histr := "[{\"m\":\"hi\",\"token\":\"" + token + "\"}]"
// println("Sending hi message: " + histr)
err := ws.WriteMessage(1, []byte(histr))
if err != nil {
log.Println(err)
}
SendTimeMessage(ws)
// sentHi = true
}
type CommandData struct {
mpp.ChatMppMessage
Args []string
Cmd string
}
type Command struct {
Id string
Callback func(ws *websocket.Conn, data *CommandData) string
}
var helpCommands []Command
var commands []Command = []Command{
{
Id: "help",
Callback: func(ws *websocket.Conn, data *CommandData) string {
output := "Commands: "
for _, cmd := range helpCommands {
output += cmd.Id + ", "
}
return strings.Trim(output[:len(output)-2], " ")
},
},
{
Id: "about",
Callback: func(ws *websocket.Conn, data *CommandData) string {
return "written in go version go1.22.2 linux/amd64"
},
},
{
Id: "me",
Callback: func(ws *websocket.Conn, data *CommandData) string {
bal, err := GetBalance(data.Part.Uid)
if err != nil {
log.Println(err)
return "An error has occurred."
}
return "Your balance: " + strconv.FormatFloat(bal, 'f', -1, 64)
},
},
{
Id: "nu",
Callback: func(ws *websocket.Conn, data *CommandData) string {
return "I'd just like to interject for a moment. What you're refering to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX."
},
},
}
var botPrefix string = "g"
func ReceiveChatMessage(ws *websocket.Conn, msg *mpp.ChatMppMessage) {
log.Println(msg.Part.Uid[0:6] + " <" + msg.Part.Name + ">: " + msg.Message)
if strings.HasPrefix(msg.Message, botPrefix) {
args := strings.Split(msg.Message, " ")
cmd := args[0][1:]
var data CommandData = CommandData{
ChatMppMessage: *msg,
Args: args,
Cmd: cmd,
}
for _, command := range commands {
if data.Cmd == command.Id {
message := command.Callback(ws, &data)
if message != "" {
SendChat(ws, message)
}
break
}
}
// switch data.Cmd {
// case "help":
// SendChat(ws, "golang test");
// }
}
}
func SendTimeMessage(ws *websocket.Conn) {
unixtime := fmt.Sprintf("%d", time.Now().Unix())
tstr := "[{\"m\": \"t\", \"t\": " + unixtime + "}]"
// println("Sending t message: " + tstr)
ws.WriteMessage(1, []byte(tstr))
}
func SendChat(ws *websocket.Conn, message string) {
ws.WriteMessage(1, []byte("[{\"m\":\"a\",\"message\":\"\u034f"+message+"\"}]"))
}