diff --git a/defs/callback.go b/defs/callback.go new file mode 100644 index 0000000..92fbbb0 --- /dev/null +++ b/defs/callback.go @@ -0,0 +1,39 @@ +package defs + +import "encoding/json" + +type Command struct { + Command string `json:"Command"` + Argstr string `json:"Argstr"` +} + +func (c *Command) ToJSON() string { + ans, _ := json.Marshal(c) + return string(ans) +} + +const ( + CMD_UNKNOWN = "unknown" + CMD_APPROVE = "approve" + CMD_REJECT = "reject" +) + +func NewApproveCommand(mcName string) *Command { + return &Command{ + Command: CMD_APPROVE, + Argstr: mcName, + } +} + +func NewRejectCommand(mcName string) *Command { + return &Command{ + Command: CMD_REJECT, + Argstr: mcName, + } +} + +func NewCommandFromJSON(jsonStr string) (*Command, error) { + var cmd Command + err := json.Unmarshal([]byte(jsonStr), &cmd) + return &cmd, err +} diff --git a/go.mod b/go.mod index 653f5a3..2a9e43a 100644 --- a/go.mod +++ b/go.mod @@ -3,35 +3,35 @@ module tg-mc go 1.20 require ( - github.com/Tnze/go-mc v1.19.4-pre1 - github.com/glebarez/sqlite v1.8.0 - github.com/go-co-op/gocron v1.28.3 + github.com/Tnze/go-mc v1.19.4 + github.com/glebarez/sqlite v1.9.0 + github.com/go-co-op/gocron v1.32.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 - github.com/ilyakaznacheev/cleanenv v1.4.2 + github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/joho/godotenv v1.5.1 github.com/samber/lo v1.38.1 - github.com/sirupsen/logrus v1.9.1 - gorm.io/gorm v1.25.1 + github.com/sirupsen/logrus v1.9.3 + gorm.io/gorm v1.25.4 ) require ( github.com/BurntSushi/toml v1.3.2 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/glebarez/go-sqlite v1.21.1 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/glebarez/go-sqlite v1.21.2 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - go.uber.org/atomic v1.9.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/sys v0.4.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/sys v0.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.22.3 // indirect - modernc.org/mathutil v1.5.0 // indirect - modernc.org/memory v1.5.0 // indirect - modernc.org/sqlite v1.21.1 // indirect + modernc.org/libc v1.24.1 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.1 // indirect + modernc.org/sqlite v1.25.0 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect ) diff --git a/go.sum b/go.sum index 83af5dd..0c4f2ba 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,11 @@ github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Tnze/go-mc v1.19.4-pre1 h1:0yBCeK9EGICdIzxSPbvD88HqcNRho8PRgKtpAC02W0E= +github.com/Tnze/go-mc v1.19.4-pre1/go.mod h1:c1znJQglgqa1Jjs3Dr29woN/msguiJrlNtWXhKedh2U= +github.com/Tnze/go-mc v1.19.4 h1:9qtxH+xRJWswOYnlf/dsFY4EI2f5jsFhtqTYOObaGIE= +github.com/Tnze/go-mc v1.19.4/go.mod h1:c1znJQglgqa1Jjs3Dr29woN/msguiJrlNtWXhKedh2U= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -9,17 +14,27 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY= github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E= +github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= +github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc= github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8= +github.com/glebarez/sqlite v1.9.0 h1:Aj6bPA12ZEx5GbSF6XADmCkYXlljPNUY+Zf1EQxynXs= +github.com/glebarez/sqlite v1.9.0/go.mod h1:YBYCoyupOao60lzp1MVBLEjZfgkq0tdB1voAQ09K9zw= github.com/go-co-op/gocron v1.28.3 h1:swTsge6u/1Ei51b9VLMz/YTzEzWpbsk5SiR7m5fklTI= github.com/go-co-op/gocron v1.28.3/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y= +github.com/go-co-op/gocron v1.32.1 h1:h+StA6Qzlv+ImlCaLfA26rLN9eS/l4sO7oWmPUbRVIY= +github.com/go-co-op/gocron v1.32.1/go.mod h1:UGz2oYvVS6PsqlwuOdo5L1Djsg/cQjxJ6T5ntkhp9Bg= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/ilyakaznacheev/cleanenv v1.4.2 h1:nRqiriLMAC7tz7GzjzUTBHfzdzw6SQ7XvTagkFqe/zU= github.com/ilyakaznacheev/cleanenv v1.4.2/go.mod h1:i0owW+HDxeGKE0/JPREJOdSCPIyOnmh6C0xhWAkF/xA= +github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4= +github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= @@ -37,6 +52,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/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= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -52,6 +69,8 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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= @@ -63,12 +82,19 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -79,13 +105,23 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64= gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= +gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY= modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw= +modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.7.1 h1:9J+2/GKTlV503mk3yv8QJ6oEpRCUrRy0ad8TXEPoV8M= +modernc.org/memory v1.7.1/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU= modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= +modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ= olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw= diff --git a/services/mc/auth.go b/services/mc/auth.go new file mode 100644 index 0000000..60295b6 --- /dev/null +++ b/services/mc/auth.go @@ -0,0 +1,52 @@ +package mc + +import ( + "sync" + "tg-mc/models" + "time" +) + +type Auth interface { + IsAuthed(u models.User, expireMode bool) bool + Auth(u models.User) + Reject(u models.User) +} + +type Authcator struct { + UserMap *sync.Map +} + +var authcator *Authcator + +func GetAuthcator() Auth { + if authcator == nil { + authcator = &Authcator{ + UserMap: &sync.Map{}, + } + } + return authcator +} + +func (a *Authcator) IsAuthed(u models.User, expireMode bool) bool { + if u.MCName != "VaalaCat" { + return true + } + if approveTime, ok := a.UserMap.Load(u.MCName); ok { + if !expireMode { + return true + } else if time.Since(approveTime.(time.Time)) < 30*time.Second { + return true + } else { + return false + } + } + return false +} + +func (a *Authcator) Auth(u models.User) { + a.UserMap.Store(u.MCName, time.Now()) +} + +func (a *Authcator) Reject(u models.User) { + a.UserMap.Delete(u.MCName) +} diff --git a/services/mc/helper.go b/services/mc/helper.go index ebd4bcc..383289f 100644 --- a/services/mc/helper.go +++ b/services/mc/helper.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "tg-mc/conf" + "tg-mc/defs" "tg-mc/models" su "tg-mc/services/utils" "tg-mc/utils" @@ -34,16 +35,26 @@ func GetLeftPlayer(m chat.Message) (userName string, err error) { return } -func HandleJoinGame(userName string, mention bool) { +func HandleJoinGame(userName string, mention bool, expireMode bool) { u, err := models.GetUserByMCName(userName) if err != nil { logrus.Error("get user name error: ", err) } - time.Sleep(3 * time.Second) switch u.Status { case StatusNormal: + if !GetAuthcator().IsAuthed(u, expireMode) { + m := tgbotapi.NewMessage(u.TGID, fmt.Sprintf("MC用户:%v 尝试登录,请手动允许,每次授权持续30秒", userName)) + m.ReplyMarkup = tgbotapi.NewInlineKeyboardMarkup( + tgbotapi.NewInlineKeyboardRow( + tgbotapi.NewInlineKeyboardButtonData("批准", defs.NewApproveCommand(u.MCName).ToJSON()), + tgbotapi.NewInlineKeyboardButtonData("拒绝", defs.NewRejectCommand(u.MCName).ToJSON())), + ) + conf.Bot.Send(m) + kickPlayer(userName) + return + } if mention { SendMsgToPlayer("欢迎回来!", userName) } @@ -93,14 +104,19 @@ func CronKick() { utils.CronStart(func() { users := su.GetAlivePlayerList() for _, u := range users { - HandleJoinGame(u, false) + HandleJoinGame(u, false, false) } }) } func isBotMsg(msg chat.Message) bool { - if msg.Translate == "commands.message.display.outgoing" { - return true - } - return false + return msg.Translate == "commands.message.display.outgoing" +} + +func HandleLeftGame(userName string) { + u, err := models.GetUserByMCName(userName) + if err != nil { + logrus.Error("get user name error: ", err) + } + GetAuthcator().Reject(u) } diff --git a/services/mc/mc.go b/services/mc/mc.go index e2d7c4d..802853d 100644 --- a/services/mc/mc.go +++ b/services/mc/mc.go @@ -80,7 +80,14 @@ func onSystemMsg(msg chat.Message, overlay bool) error { logrus.Error("user join error ", err) break } - go HandleJoinGame(userName, true) + go HandleJoinGame(userName, true, true) + case EventPlayerLeft: + userName, err := GetLeftPlayer(msg) + if err != nil { + logrus.Error("user left error ", err) + break + } + go HandleLeftGame(userName) default: break } diff --git a/services/tgbot/approve.go b/services/tgbot/approve.go new file mode 100644 index 0000000..a4f44f9 --- /dev/null +++ b/services/tgbot/approve.go @@ -0,0 +1,28 @@ +package tgbot + +import ( + "fmt" + "tg-mc/conf" + "tg-mc/defs" + "tg-mc/models" + "tg-mc/services/mc" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func ApproveHandler(update tgbotapi.Update, cmd defs.Command) { + u, err := models.GetUserByTGID(update.CallbackQuery.From.ID) + if err != nil { + return + } + mc.GetAuthcator().Auth(u) + callback := tgbotapi.NewCallback(update.CallbackQuery.ID, "已授权") + if _, err := conf.Bot.Request(callback); err != nil { + logrus.Panic(err) + } + conf.Bot.Send(tgbotapi.NewDeleteMessage(update.CallbackQuery.Message.Chat.ID, + update.CallbackQuery.Message.MessageID)) + conf.Bot.Send(tgbotapi.NewMessage(update.CallbackQuery.Message.Chat.ID, + fmt.Sprintf("已授权☑️: %s 登录MC", u.MCName))) +} diff --git a/services/tgbot/bind.go b/services/tgbot/bind.go new file mode 100644 index 0000000..3196333 --- /dev/null +++ b/services/tgbot/bind.go @@ -0,0 +1,29 @@ +package tgbot + +import ( + "fmt" + "tg-mc/conf" + "tg-mc/models" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func BindHandler(m *tgbotapi.Message, i interface{}) { + logrus.Infof("id is %d", m.Chat.ID) + err := models.CreateUser(&models.User{ + TGID: m.From.ID, + MCName: m.CommandArguments(), + Status: 1, + }) + if err != nil { + m := tgbotapi.NewMessage(m.Chat.ID, "绑定失败, err: "+err.Error()) + conf.Bot.Send(m) + return + } + + msg := tgbotapi.NewMessage(m.Chat.ID, + fmt.Sprintf("绑定成功,你的MCID是%v", m.CommandArguments())) + conf.Bot.Send(msg) + return +} diff --git a/services/tgbot/bot.go b/services/tgbot/bot.go index f241bc2..266428d 100644 --- a/services/tgbot/bot.go +++ b/services/tgbot/bot.go @@ -1,22 +1,31 @@ package tgbot import ( - "fmt" "log" "net/http" "net/url" - "strconv" "tg-mc/conf" - "tg-mc/models" - "tg-mc/services/utils" - commonUtils "tg-mc/utils" + "tg-mc/defs" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" - "github.com/samber/lo" "github.com/sirupsen/logrus" ) -func Run(sendFunc func(string)) { +var funcHandlers = map[string]func(*tgbotapi.Message, interface{}){ + "talk": TalkHandler, + "list": ListHandler, + "bind": BindHandler, + "unbind": UnbindHandler, + "get": GetHandler, + "set": SetHandler, +} + +var callBackHandlers = map[string]func(tgbotapi.Update, defs.Command){ + defs.CMD_APPROVE: ApproveHandler, + defs.CMD_REJECT: RejectHandler, +} + +func init() { var err error api := conf.GetBotSettings().BotAPI @@ -43,161 +52,33 @@ func Run(sendFunc func(string)) { if err != nil { log.Panic(err) } - conf.Bot.Debug = false - log.Printf("Authorized on account %s", conf.Bot.Self.UserName) +} +func Run(sendFunc func(string)) { u := tgbotapi.NewUpdate(0) u.Timeout = 60 updates := conf.Bot.GetUpdatesChan(u) for update := range updates { - if update.Message != nil { + if update.CallbackQuery != nil { + go func(update tgbotapi.Update) { + logrus.Infof("[%s] %s", update.CallbackQuery.From.UserName, update.CallbackQuery.Data) + cmd, err := defs.NewCommandFromJSON(update.CallbackQuery.Data) + if err != nil { + logrus.Error(err) + return + } + if handler, ok := callBackHandlers[cmd.Command]; ok { + handler(update, *cmd) + } + }(update) + } else if update.Message != nil { go func(m *tgbotapi.Message) { logrus.Infof("[%s] %s", m.From.UserName, m.Text) - if m.Command() == "talk" { - logrus.Infof("id is %d", m.Chat.ID) - m := fmt.Sprintf("%v: %v", m.From.UserName, m.CommandArguments()) - sendFunc(m) - if err != nil { - logrus.WithError(err).Error("send message error") - } - return - } - if m.Command() == "list" { - logrus.Infof("id is %d", m.Chat.ID) - m := tgbotapi.NewMessage(m.Chat.ID, utils.GetAlivePlayer()) - conf.Bot.Send(m) - return - } - if m.Command() == "bind" { - logrus.Infof("id is %d", m.Chat.ID) - err := models.CreateUser(&models.User{ - TGID: m.From.ID, - MCName: m.CommandArguments(), - Status: 1, - }) - if err != nil { - m := tgbotapi.NewMessage(m.Chat.ID, "绑定失败, err: "+err.Error()) - conf.Bot.Send(m) - return - } - m := tgbotapi.NewMessage(m.Chat.ID, - fmt.Sprintf("绑定成功,你的MCID是%v", m.CommandArguments())) - conf.Bot.Send(m) - return - } - if m.Command() == "unbind" { - logrus.Infof("id is %d", m.Chat.ID) - u, err := models.GetUserByTGID(m.From.ID) - if err != nil { - m := tgbotapi.NewMessage(m.Chat.ID, "你还没有绑定") - conf.Bot.Send(m) - return - } - err = u.Delete(m.From.ID) - if err != nil { - m := tgbotapi.NewMessage(m.Chat.ID, "解绑失败") - conf.Bot.Send(m) - return - } - m := tgbotapi.NewMessage(m.Chat.ID, "解绑成功") - conf.Bot.Send(m) - return - } - if m.Command() == "get" { - if !utils.IsAdmin(m) && - len(m.CommandArguments()) != 0 { - tm := tgbotapi.NewMessage(m.Chat.ID, "您不是管理员,没有该权限") - conf.Bot.Send(tm) - return - } else if utils.IsAdmin(m) && - len(m.CommandArguments()) != 0 { - a := commonUtils.GetArgs(m.CommandArguments()) - if len(a) != 2 { - tm := tgbotapi.NewMessage(m.Chat.ID, "参数错误,样例:\n```\n/get \n```") - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - return - } - if a[0] == "tgid" { - tgid, err := strconv.ParseInt(a[1], 10, 64) - if err != nil { - conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "ID错误,应该为int64")) - return - } - u, err := models.GetUserByTGID(tgid) - if err != nil { - tm := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("查询出错,err:\n```\n%+v\n```", err)) - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - return - } - tm := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("用户信息:\n```\n%+v\n```", u)) - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - } - if a[0] == "username" { - u, err := models.GetUserByMCName(a[1]) - if err != nil { - tm := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("查询出错,err:\n```\n%+v\n```", err)) - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - return - } - tm := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("用户信息:\n```\n%+v\n```", u)) - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - } - return - } - logrus.Infof("id is %d", m.Chat.ID) - u, err := models.GetUserByTGID(m.From.ID) - if err != nil { - m := tgbotapi.NewMessage(m.Chat.ID, "你还没有绑定") - conf.Bot.Send(m) - return - } - m := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("你的MCID是%v", u.MCName)) - conf.Bot.Send(m) - return - } - if m.Command() == "set" { - if !utils.IsAdmin(m) { - tm := tgbotapi.NewMessage(m.Chat.ID, "您不是管理员,没有该权限") - conf.Bot.Send(tm) - return - } - a := commonUtils.GetArgs(m.CommandArguments()) - if len(a) != 3 { - tm := tgbotapi.NewMessage(m.Chat.ID, "参数错误,样例:\n```\n/set username tgid status\n```") - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - return - } - tgid, err := strconv.ParseInt(a[1], 10, 64) - if err != nil { - conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "ID错误,应该为int64")) - return - } - status, err := strconv.ParseInt(a[2], 10, 64) - if err != nil || !lo.Contains([]int64{0, 1, 2}, status) { - conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "Status错误,应该为0(Pending),1(Normal),2(Banned)")) - return - } - if err := models.CreateUser(&models.User{ - TGID: tgid, - MCName: a[0], - Status: int(status), - }); err != nil { - tm := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("创建用户错误,err:\n```\n%+v\n```", err)) - tm.ParseMode = "Markdown" - conf.Bot.Send(tm) - return - } - conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "设置用户成功")) - return + if handler, ok := funcHandlers[m.Command()]; ok { + handler(m, sendFunc) } }(update.Message) } diff --git a/services/tgbot/get.go b/services/tgbot/get.go new file mode 100644 index 0000000..71e0dc1 --- /dev/null +++ b/services/tgbot/get.go @@ -0,0 +1,71 @@ +package tgbot + +import ( + "fmt" + "strconv" + "tg-mc/conf" + "tg-mc/models" + "tg-mc/services/utils" + commonUtils "tg-mc/utils" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func GetHandler(msg *tgbotapi.Message, i interface{}) { + if !utils.IsAdmin(msg) && + len(msg.CommandArguments()) != 0 { + tm := tgbotapi.NewMessage(msg.Chat.ID, "您不是管理员,没有该权限") + conf.Bot.Send(tm) + return + } else if utils.IsAdmin(msg) && + len(msg.CommandArguments()) != 0 { + a := commonUtils.GetArgs(msg.CommandArguments()) + if len(a) != 2 { + tm := tgbotapi.NewMessage(msg.Chat.ID, "参数错误,样例:\n```\n/get \n```") + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + return + } + if a[0] == "tgid" { + tgid, err := strconv.ParseInt(a[1], 10, 64) + if err != nil { + conf.Bot.Send(tgbotapi.NewMessage(msg.Chat.ID, "ID错误,应该为int64")) + return + } + u, err := models.GetUserByTGID(tgid) + if err != nil { + tm := tgbotapi.NewMessage(msg.Chat.ID, fmt.Sprintf("查询出错,err:\n```\n%+v\n```", err)) + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + return + } + tm := tgbotapi.NewMessage(msg.Chat.ID, fmt.Sprintf("用户信息:\n```\n%+v\n```", u)) + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + } + if a[0] == "username" { + u, err := models.GetUserByMCName(a[1]) + if err != nil { + tm := tgbotapi.NewMessage(msg.Chat.ID, fmt.Sprintf("查询出错,err:\n```\n%+v\n```", err)) + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + return + } + tm := tgbotapi.NewMessage(msg.Chat.ID, fmt.Sprintf("用户信息:\n```\n%+v\n```", u)) + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + } + return + } + logrus.Infof("id is %d", msg.Chat.ID) + u, err := models.GetUserByTGID(msg.From.ID) + if err != nil { + m := tgbotapi.NewMessage(msg.Chat.ID, "你还没有绑定") + conf.Bot.Send(m) + return + } + m := tgbotapi.NewMessage(msg.Chat.ID, fmt.Sprintf("你的MCID是%v", u.MCName)) + conf.Bot.Send(m) + return +} diff --git a/services/tgbot/list.go b/services/tgbot/list.go new file mode 100644 index 0000000..97359f3 --- /dev/null +++ b/services/tgbot/list.go @@ -0,0 +1,15 @@ +package tgbot + +import ( + "tg-mc/conf" + "tg-mc/services/utils" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func ListHandler(m *tgbotapi.Message, i interface{}) { + logrus.Infof("id is %d", m.Chat.ID) + msg := tgbotapi.NewMessage(m.Chat.ID, utils.GetAlivePlayer()) + conf.Bot.Send(msg) +} diff --git a/services/tgbot/reject.go b/services/tgbot/reject.go new file mode 100644 index 0000000..0d92b1f --- /dev/null +++ b/services/tgbot/reject.go @@ -0,0 +1,26 @@ +package tgbot + +import ( + "fmt" + "tg-mc/conf" + "tg-mc/defs" + "tg-mc/models" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func RejectHandler(update tgbotapi.Update, cmd defs.Command) { + u, err := models.GetUserByTGID(update.CallbackQuery.From.ID) + if err != nil { + return + } + callback := tgbotapi.NewCallback(update.CallbackQuery.ID, "已拒绝") + if _, err := conf.Bot.Request(callback); err != nil { + logrus.Panic(err) + } + conf.Bot.Send(tgbotapi.NewDeleteMessage(update.CallbackQuery.Message.Chat.ID, + update.CallbackQuery.Message.MessageID)) + conf.Bot.Send(tgbotapi.NewMessage(update.CallbackQuery.Message.Chat.ID, + fmt.Sprintf("已拒绝❌: %s 登录MC", u.MCName))) +} diff --git a/services/tgbot/set.go b/services/tgbot/set.go new file mode 100644 index 0000000..d33301e --- /dev/null +++ b/services/tgbot/set.go @@ -0,0 +1,50 @@ +package tgbot + +import ( + "fmt" + "strconv" + "tg-mc/conf" + "tg-mc/models" + "tg-mc/services/utils" + commonUtils "tg-mc/utils" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/samber/lo" +) + +func SetHandler(m *tgbotapi.Message, i interface{}) { + if !utils.IsAdmin(m) { + tm := tgbotapi.NewMessage(m.Chat.ID, "您不是管理员,没有该权限") + conf.Bot.Send(tm) + return + } + a := commonUtils.GetArgs(m.CommandArguments()) + if len(a) != 3 { + tm := tgbotapi.NewMessage(m.Chat.ID, "参数错误,样例:\n```\n/set username tgid status\n```") + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + return + } + tgid, err := strconv.ParseInt(a[1], 10, 64) + if err != nil { + conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "ID错误,应该为int64")) + return + } + status, err := strconv.ParseInt(a[2], 10, 64) + if err != nil || !lo.Contains([]int64{0, 1, 2}, status) { + conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "Status错误,应该为0(Pending),1(Normal),2(Banned)")) + return + } + if err := models.CreateUser(&models.User{ + TGID: tgid, + MCName: a[0], + Status: int(status), + }); err != nil { + tm := tgbotapi.NewMessage(m.Chat.ID, fmt.Sprintf("创建用户错误,err:\n```\n%+v\n```", err)) + tm.ParseMode = "Markdown" + conf.Bot.Send(tm) + return + } + conf.Bot.Send(tgbotapi.NewMessage(m.Chat.ID, "设置用户成功")) + return +} diff --git a/services/tgbot/talk.go b/services/tgbot/talk.go new file mode 100644 index 0000000..dea50d0 --- /dev/null +++ b/services/tgbot/talk.go @@ -0,0 +1,15 @@ +package tgbot + +import ( + "fmt" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func TalkHandler(m *tgbotapi.Message, i interface{}) { + sendFunc := i.(func(string)) + logrus.Infof("id is %d", m.Chat.ID) + msg := fmt.Sprintf("%v: %v", m.From.UserName, m.CommandArguments()) + sendFunc(msg) +} diff --git a/services/tgbot/unbind.go b/services/tgbot/unbind.go new file mode 100644 index 0000000..b41b815 --- /dev/null +++ b/services/tgbot/unbind.go @@ -0,0 +1,28 @@ +package tgbot + +import ( + "tg-mc/conf" + "tg-mc/models" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" +) + +func UnbindHandler(msg *tgbotapi.Message, i interface{}) { + logrus.Infof("id is %d", msg.Chat.ID) + u, err := models.GetUserByTGID(msg.From.ID) + if err != nil { + m := tgbotapi.NewMessage(msg.Chat.ID, "你还没有绑定") + conf.Bot.Send(m) + return + } + err = u.Delete(msg.From.ID) + if err != nil { + m := tgbotapi.NewMessage(msg.Chat.ID, "解绑失败") + conf.Bot.Send(m) + return + } + m := tgbotapi.NewMessage(msg.Chat.ID, "解绑成功") + conf.Bot.Send(m) + return +}