2024-04-18 13:45:29 +02:00
package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"net/url"
"os"
"os/signal"
"strconv"
"strings"
"time"
2024-04-20 11:27:00 +02:00
"github.com/Hri7566/mpp-client-go/mpp"
2024-04-18 13:45:29 +02:00
"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 {
2024-04-20 11:27:00 +02:00
case <- serverTicker . C :
2024-04-18 13:45:29 +02:00
SendTimeMessage ( ws )
2024-04-20 11:27:00 +02:00
case <- serverTickerQuit :
2024-04-18 13:45:29 +02:00
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" :
2024-04-20 11:27:00 +02:00
msg := mpp . HiMppMessage { }
2024-04-18 13:45:29 +02:00
_ = json . Unmarshal ( raw , & msg )
ReceiveHiMessage ( ws , & msg )
case "nq" :
2024-04-20 11:27:00 +02:00
msg := mpp . NoteQuotaMppMessage { }
2024-04-18 13:45:29 +02:00
_ = json . Unmarshal ( raw , & msg )
ReceiveNqMessage ( & msg )
case "t" :
2024-04-20 11:27:00 +02:00
msg := mpp . TimeMppMessage { }
2024-04-18 13:45:29 +02:00
_ = json . Unmarshal ( raw , & msg )
case "a" :
2024-04-20 11:27:00 +02:00
msg := mpp . ChatMppMessage { }
2024-04-18 13:45:29 +02:00
_ = json . Unmarshal ( raw , & msg )
ReceiveChatMessage ( ws , & msg )
case "b" :
2024-04-20 21:41:10 +02:00
SendHandshake ( ws )
2024-04-18 13:45:29 +02:00
default :
return
}
}
// println("Correctly deserialized JSON")
// spew.Dump(tmp)
// for _, msg := range msgs {
// println(msg.Type)
// }
}
2024-04-20 11:27:00 +02:00
func ReceiveNqMessage ( msg * mpp . NoteQuotaMppMessage ) {
2024-04-18 13:45:29 +02:00
// println(msg.MaxHistLen)
}
2024-04-20 11:27:00 +02:00
func ReceiveHiMessage ( ws * websocket . Conn , msg * mpp . HiMppMessage ) {
2024-04-18 13:45:29 +02:00
println ( "I am " + msg . User . Name )
2024-04-20 11:27:00 +02:00
chstr := "[{\"m\":\"ch\",\"_id\":\"✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧\"}]"
2024-04-18 13:45:29 +02:00
// println("Sending ch message: " + chstr)
err2 := ws . WriteMessage ( 1 , [ ] byte ( chstr ) )
if err2 != nil {
log . Println ( err2 )
}
}
2024-04-20 21:41:10 +02:00
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
}
2024-04-18 13:45:29 +02:00
type CommandData struct {
2024-04-20 11:27:00 +02:00
mpp . ChatMppMessage
2024-04-18 13:45:29 +02:00
Args [ ] string
2024-04-20 11:27:00 +02:00
Cmd string
2024-04-18 13:45:29 +02:00
}
type Command struct {
2024-04-20 11:27:00 +02:00
Id string
2024-04-18 13:45:29 +02:00
Callback func ( ws * websocket . Conn , data * CommandData ) string
}
var helpCommands [ ] Command
var commands [ ] Command = [ ] Command {
{
Id : "help" ,
2024-04-20 11:27:00 +02:00
Callback : func ( ws * websocket . Conn , data * CommandData ) string {
2024-04-18 13:45:29 +02:00
output := "Commands: "
2024-04-20 11:27:00 +02:00
2024-04-18 13:45:29 +02:00
for _ , cmd := range helpCommands {
output += cmd . Id + ", "
}
2024-04-20 11:27:00 +02:00
return strings . Trim ( output [ : len ( output ) - 2 ] , " " )
2024-04-18 13:45:29 +02:00
} ,
} ,
{
Id : "about" ,
2024-04-20 11:27:00 +02:00
Callback : func ( ws * websocket . Conn , data * CommandData ) string {
2024-04-18 13:45:29 +02:00
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 )
2024-04-20 11:27:00 +02:00
2024-04-18 13:45:29 +02:00
if err != nil {
log . Println ( err )
return "An error has occurred."
}
return "Your balance: " + strconv . FormatFloat ( bal , 'f' , - 1 , 64 )
} ,
} ,
2024-04-20 11:27:00 +02:00
{
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."
} ,
} ,
2024-04-18 13:45:29 +02:00
}
var botPrefix string = "g"
2024-04-20 11:27:00 +02:00
func ReceiveChatMessage ( ws * websocket . Conn , msg * mpp . ChatMppMessage ) {
2024-04-18 13:45:29 +02:00
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 {
2024-04-20 11:27:00 +02:00
ChatMppMessage : * msg ,
Args : args ,
Cmd : cmd ,
2024-04-18 13:45:29 +02:00
}
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 ) {
2024-04-20 11:27:00 +02:00
ws . WriteMessage ( 1 , [ ] byte ( "[{\"m\":\"a\",\"message\":\"\u034f" + message + "\"}]" ) )
2024-04-18 13:45:29 +02:00
}