From 44a42a3365ee8c46c9ccc42b283dd33419209a17 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sun, 18 Sep 2022 14:15:11 -0400 Subject: [PATCH] Implemented the ability to enable and disable commands in configuration as well as increased scope of the config to the entire project. --- config.json | 25 ++ config/config.go | 55 ++++ go.mod | 2 +- go.sum | 9 + main.go | 54 ++- server/channelserver/handlers_cast_binary.go | 329 +++++++++++-------- 6 files changed, 309 insertions(+), 165 deletions(-) diff --git a/config.json b/config.json index 00e541adf..505249cf1 100644 --- a/config.json +++ b/config.json @@ -30,6 +30,31 @@ "bottoken": "", "realtimeChannelID": "" }, + "ServerCommands": { + "enabled": true, + "Commands": [ + { + "name": "Rights", + "enabled": true, + "prefix": "!rights" + }, + { + "name": "Ravi", + "enabled": true, + "prefix": "!ravi" + }, + { + "name": "Tele", + "enabled": true, + "prefix": "!tele" + }, + { + "name": "Reload", + "enabled": true, + "prefix": "!reload" + } + ] + }, "database": { "host": "localhost", "port": 5432, diff --git a/config/config.go b/config/config.go index bfbf8086a..45873074b 100644 --- a/config/config.go +++ b/config/config.go @@ -1,8 +1,11 @@ package config import ( + "fmt" "log" "net" + "os" + "time" "github.com/spf13/viper" ) @@ -16,6 +19,7 @@ type Config struct { DevModeOptions DevModeOptions Discord Discord + ServerCommands ServerCommands Database Database Launcher Launcher Sign Sign @@ -59,6 +63,18 @@ type Discord struct { DevMode bool } +// Server commands +type ServerCommands struct { + Enabled bool + Commands []ServerCommand +} + +type ServerCommand struct { + Name string + Enabled bool + Prefix string +} + // Database holds the postgres database config. type Database struct { Host string @@ -107,6 +123,28 @@ type EntranceChannelInfo struct { CurrentPlayers uint16 } +var ErupeConfig *Config + +func init() { + var err error + ErupeConfig, err = LoadConfig() + if err != nil { + preventClose(fmt.Sprintf("Failed to load config: %s", err.Error())) + } + +} + +func GetServerCommandByName(cmdName string) ServerCommand { + var val ServerCommand + for _, c := range ErupeConfig.ServerCommands.Commands { + if c.Name == cmdName { + return c + } + } + + return val +} + // getOutboundIP4 gets the preferred outbound ip4 of this machine // From https://stackoverflow.com/a/37382208 func getOutboundIP4() net.IP { @@ -148,3 +186,20 @@ func LoadConfig() (*Config, error) { return c, nil } + +func preventClose(text string) { + if ErupeConfig.DisableSoftCrash { + os.Exit(0) + } + fmt.Println("\nFailed to start Erupe:\n" + text) + go wait() + fmt.Println("\nPress Enter/Return to exit...") + fmt.Scanln() + os.Exit(0) +} + +func wait() { + for { + time.Sleep(time.Millisecond * 100) + } +} diff --git a/go.mod b/go.mod index 8107625a2..3ac44e932 100644 --- a/go.mod +++ b/go.mod @@ -19,5 +19,5 @@ require ( golang.org/x/crypto v0.0.0-20211202192323-5770296d904e golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect golang.org/x/text v0.3.7 - golang.org/x/tools v0.1.8 // indirect + honnef.co/go/tools v0.3.3 ) diff --git a/go.sum b/go.sum index 9750b4732..91403fd95 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -295,6 +297,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -307,6 +310,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -334,6 +338,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -510,6 +515,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f h1:OKYpQQVE3DKSc3r3zHVzq46vq5YH7x8xpR3/k9ixmUg= +golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -638,6 +645,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= +honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/main.go b/main.go index a9c796f29..a6074c7b2 100644 --- a/main.go +++ b/main.go @@ -20,8 +20,6 @@ import ( "go.uber.org/zap" ) -var erupeConfig *config.Config - // Temporary DB auto clean on startup for quick development & testing. func cleanDB(db *sqlx.DB) { _ = db.MustExec("DELETE FROM guild_characters") @@ -39,25 +37,19 @@ func main() { logger.Info("Starting Erupe") - // Load the configuration. - erupeConfig, err = config.LoadConfig() - if err != nil { - preventClose(fmt.Sprintf("Failed to load config: %s", err.Error())) - } - - if erupeConfig.Database.Password == "" { + if config.ErupeConfig.Database.Password == "" { preventClose("Database password is blank") } - if net.ParseIP(erupeConfig.Host) == nil { - ips, _ := net.LookupIP(erupeConfig.Host) + if net.ParseIP(config.ErupeConfig.Host) == nil { + ips, _ := net.LookupIP(config.ErupeConfig.Host) for _, ip := range ips { if ip != nil { - erupeConfig.Host = ip.String() + config.ErupeConfig.Host = ip.String() break } } - if net.ParseIP(erupeConfig.Host) == nil { + if net.ParseIP(config.ErupeConfig.Host) == nil { preventClose("Invalid host address") } } @@ -65,10 +57,10 @@ func main() { // Discord bot var discordBot *discordbot.DiscordBot = nil - if erupeConfig.Discord.Enabled { + if config.ErupeConfig.Discord.Enabled { bot, err := discordbot.NewDiscordBot(discordbot.Options{ Logger: logger, - Config: erupeConfig, + Config: config.ErupeConfig, }) if err != nil { @@ -91,11 +83,11 @@ func main() { // Create the postgres DB pool. connectString := fmt.Sprintf( "host=%s port=%d user=%s password=%s dbname= %s sslmode=disable", - erupeConfig.Database.Host, - erupeConfig.Database.Port, - erupeConfig.Database.User, - erupeConfig.Database.Password, - erupeConfig.Database.Database, + config.ErupeConfig.Database.Host, + config.ErupeConfig.Database.Port, + config.ErupeConfig.Database.User, + config.ErupeConfig.Database.Password, + config.ErupeConfig.Database.Database, ) db, err := sqlx.Open("postgres", connectString) @@ -117,7 +109,7 @@ func main() { _ = db.MustExec("UPDATE characters SET cafe_time=0") // Clean the DB if the option is on. - if erupeConfig.DevMode && erupeConfig.DevModeOptions.CleanDB { + if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.CleanDB { logger.Info("Cleaning DB") cleanDB(db) logger.Info("Done cleaning DB") @@ -127,13 +119,13 @@ func main() { // Launcher HTTP server. var launcherServer *launcherserver.Server - if erupeConfig.DevMode && erupeConfig.DevModeOptions.EnableLauncherServer { + if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.EnableLauncherServer { launcherServer = launcherserver.NewServer( &launcherserver.Config{ Logger: logger.Named("launcher"), - ErupeConfig: erupeConfig, + ErupeConfig: config.ErupeConfig, DB: db, - UseOriginalLauncherFiles: erupeConfig.Launcher.UseOriginalLauncherFiles, + UseOriginalLauncherFiles: config.ErupeConfig.Launcher.UseOriginalLauncherFiles, }) err = launcherServer.Start() if err != nil { @@ -146,7 +138,7 @@ func main() { entranceServer := entranceserver.NewServer( &entranceserver.Config{ Logger: logger.Named("entrance"), - ErupeConfig: erupeConfig, + ErupeConfig: config.ErupeConfig, DB: db, }) err = entranceServer.Start() @@ -159,7 +151,7 @@ func main() { signServer := signserver.NewServer( &signserver.Config{ Logger: logger.Named("sign"), - ErupeConfig: erupeConfig, + ErupeConfig: config.ErupeConfig, DB: db, }) err = signServer.Start() @@ -173,18 +165,18 @@ func main() { si := 0 ci := 0 count := 1 - for _, ee := range erupeConfig.Entrance.Entries { + for _, ee := range config.ErupeConfig.Entrance.Entries { for i, ce := range ee.Channels { sid := (4096 + si*256) + (16 + ci) c := *channelserver.NewServer(&channelserver.Config{ ID: uint16(sid), Logger: logger.Named("channel-" + fmt.Sprint(count)), - ErupeConfig: erupeConfig, + ErupeConfig: config.ErupeConfig, DB: db, DiscordBot: discordBot, }) if ee.IP == "" { - c.IP = erupeConfig.Host + c.IP = config.ErupeConfig.Host } else { c.IP = ee.IP } @@ -223,7 +215,7 @@ func main() { } signServer.Shutdown() entranceServer.Shutdown() - if erupeConfig.DevModeOptions.EnableLauncherServer { + if config.ErupeConfig.DevModeOptions.EnableLauncherServer { launcherServer.Shutdown() } @@ -237,7 +229,7 @@ func wait() { } func preventClose(text string) { - if erupeConfig.DisableSoftCrash { + if config.ErupeConfig.DisableSoftCrash { os.Exit(0) } fmt.Println("\nFailed to start Erupe:\n" + text) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 35538e0fb..35c9adf0c 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -8,8 +8,11 @@ import ( "time" "erupe-ce/common/byteframe" + "erupe-ce/config" "erupe-ce/network/binpacket" "erupe-ce/network/mhfpacket" + + "go.uber.org/zap" ) // MSG_SYS_CAST[ED]_BINARY types enum @@ -29,6 +32,47 @@ const ( BroadcastTypeWorld = 0x0a ) +var raviCmd config.ServerCommand +var rightsCmd config.ServerCommand +var teleCmd config.ServerCommand +var reloadCmd config.ServerCommand +var logger *zap.Logger + +func init() { + zapLogger, _ := zap.NewDevelopment() + defer zapLogger.Sync() + logger = zapLogger.Named("channelserver") + + raviCmd = config.GetServerCommandByName("Ravi") + if raviCmd.Enabled { + logger.Info(raviCmd.Name + " command is enabled") + } else { + logger.Info(raviCmd.Name + " command is disabled") + } + + rightsCmd = config.GetServerCommandByName("Rights") + if rightsCmd.Enabled { + logger.Info(rightsCmd.Name + " command is enabled") + } else { + logger.Info(rightsCmd.Name + " command is disabled") + } + + teleCmd = config.GetServerCommandByName("Tele") + if teleCmd.Enabled { + logger.Info(teleCmd.Name + " command is enabled") + } else { + logger.Info(teleCmd.Name + " command is disabled") + } + + reloadCmd = config.GetServerCommandByName("Reload") + if reloadCmd.Enabled { + logger.Info(reloadCmd.Name + " command is enabled") + } else { + logger.Info(reloadCmd.Name + " command is disabled") + } + +} + func sendServerChatMessage(s *Session, message string) { // Make the inside of the casted binary bf := byteframe.NewByteFrame() @@ -165,78 +209,88 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { fmt.Printf("Got chat message: %+v\n", chatMessage) - // Flush all objects and users and reload - if strings.HasPrefix(chatMessage.Message, "!reload") { - sendServerChatMessage(s, "Reloading players...") - var temp mhfpacket.MHFPacket - deleteNotif := byteframe.NewByteFrame() - for _, object := range s.stage.objects { - if object.ownerCharID == s.charID { - continue + if strings.HasPrefix(chatMessage.Message, reloadCmd.Prefix) { + // Flush all objects and users and reload + if reloadCmd.Enabled { + sendServerChatMessage(s, "Reloading players...") + var temp mhfpacket.MHFPacket + deleteNotif := byteframe.NewByteFrame() + for _, object := range s.stage.objects { + if object.ownerCharID == s.charID { + continue + } + temp = &mhfpacket.MsgSysDeleteObject{ObjID: object.id} + deleteNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(deleteNotif, s.clientContext) } - temp = &mhfpacket.MsgSysDeleteObject{ObjID: object.id} - deleteNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(deleteNotif, s.clientContext) - } - for _, session := range s.server.sessions { - if s == session { - continue + for _, session := range s.server.sessions { + if s == session { + continue + } + temp = &mhfpacket.MsgSysDeleteUser{CharID: session.charID} + deleteNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(deleteNotif, s.clientContext) } - temp = &mhfpacket.MsgSysDeleteUser{CharID: session.charID} - deleteNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(deleteNotif, s.clientContext) - } - deleteNotif.WriteUint16(0x0010) - s.QueueSend(deleteNotif.Data()) - time.Sleep(500 * time.Millisecond) - reloadNotif := byteframe.NewByteFrame() - for _, session := range s.server.sessions { - if s == session { - continue + deleteNotif.WriteUint16(0x0010) + s.QueueSend(deleteNotif.Data()) + time.Sleep(500 * time.Millisecond) + reloadNotif := byteframe.NewByteFrame() + for _, session := range s.server.sessions { + if s == session { + continue + } + temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID} + reloadNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(reloadNotif, s.clientContext) + for i := 0; i < 3; i++ { + temp = &mhfpacket.MsgSysNotifyUserBinary{ + CharID: session.charID, + BinaryType: uint8(i + 1), + } + reloadNotif.WriteUint16(uint16(temp.Opcode())) + temp.Build(reloadNotif, s.clientContext) + } } - temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID} - reloadNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(reloadNotif, s.clientContext) - for i := 0; i < 3; i++ { - temp = &mhfpacket.MsgSysNotifyUserBinary{ - CharID: session.charID, - BinaryType: uint8(i + 1), + for _, obj := range s.stage.objects { + if obj.ownerCharID == s.charID { + continue + } + temp = &mhfpacket.MsgSysDuplicateObject{ + ObjID: obj.id, + X: obj.x, + Y: obj.y, + Z: obj.z, + Unk0: 0, + OwnerCharID: obj.ownerCharID, } reloadNotif.WriteUint16(uint16(temp.Opcode())) temp.Build(reloadNotif, s.clientContext) } + reloadNotif.WriteUint16(0x0010) + s.QueueSend(reloadNotif.Data()) + } else { + sendServerChatMessage(s, reloadCmd.Name+" command is disabled") } - for _, obj := range s.stage.objects { - if obj.ownerCharID == s.charID { - continue - } - temp = &mhfpacket.MsgSysDuplicateObject{ - ObjID: obj.id, - X: obj.x, - Y: obj.y, - Z: obj.z, - Unk0: 0, - OwnerCharID: obj.ownerCharID, - } - reloadNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(reloadNotif, s.clientContext) - } - reloadNotif.WriteUint16(0x0010) - s.QueueSend(reloadNotif.Data()) + } - // Set account rights - if strings.HasPrefix(chatMessage.Message, "!rights") { - var v uint32 - n, err := fmt.Sscanf(chatMessage.Message, "!rights %d", &v) - if err != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !rights n") - } else { - _, err = s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID) - if err == nil { - sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v)) + if strings.HasPrefix(chatMessage.Message, rightsCmd.Prefix) { + // Set account rights + if rightsCmd.Enabled { + var v uint32 + n, err := fmt.Sscanf(chatMessage.Message, "!rights %d", &v) + if err != nil || n != 1 { + sendServerChatMessage(s, "Error in command. Format: !rights n") + } else { + _, err = s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID) + if err == nil { + sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v)) + } } + } else { + sendServerChatMessage(s, rightsCmd.Name+" command is disabled") } + } // Discord integration @@ -244,88 +298,97 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message) } - // RAVI COMMANDS V2 - if strings.HasPrefix(chatMessage.Message, "!ravi") { - if getRaviSemaphore(s) != "" { - s.server.raviente.Lock() - if !strings.HasPrefix(chatMessage.Message, "!ravi ") { - sendServerChatMessage(s, "No Raviente command specified!") - } else { - if strings.HasPrefix(chatMessage.Message, "!ravi start") { - if s.server.raviente.register.startTime == 0 { - s.server.raviente.register.startTime = s.server.raviente.register.postTime - sendServerChatMessage(s, "The Great Slaying will begin in a moment") - s.notifyRavi() - } else { - sendServerChatMessage(s, "The Great Slaying has already begun!") - } - } else if strings.HasPrefix(chatMessage.Message, "!ravi sm") || strings.HasPrefix(chatMessage.Message, "!ravi setmultiplier") { - var num uint16 - n, numerr := fmt.Sscanf(chatMessage.Message, "!ravi sm %d", &num) - if numerr != nil || n != 1 { - sendServerChatMessage(s, "Error in command. Format: !ravi sm n") - } else if s.server.raviente.state.damageMultiplier == 1 { - if num > 32 { - sendServerChatMessage(s, "Raviente multiplier too high, defaulting to 32x") - s.server.raviente.state.damageMultiplier = 32 - } else { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier set to %dx", num)) - s.server.raviente.state.damageMultiplier = uint32(num) - } - } else { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is already set to %dx!", s.server.raviente.state.damageMultiplier)) - } - } else if strings.HasPrefix(chatMessage.Message, "!ravi cm") || strings.HasPrefix(chatMessage.Message, "!ravi checkmultiplier") { - sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.state.damageMultiplier)) - } else if strings.HasPrefix(chatMessage.Message, "!ravi sr") || strings.HasPrefix(chatMessage.Message, "!ravi sendres") { - if s.server.raviente.state.stateData[28] > 0 { - sendServerChatMessage(s, "Sending resurrection support!") - s.server.raviente.state.stateData[28] = 0 - } else { - sendServerChatMessage(s, "Resurrection support has not been requested!") - } - } else if strings.HasPrefix(chatMessage.Message, "!ravi ss") || strings.HasPrefix(chatMessage.Message, "!ravi sendsed") { - sendServerChatMessage(s, "Sending sedation support if requested!") - // Total BerRavi HP - HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] - s.server.raviente.support.supportData[1] = HP - } else if strings.HasPrefix(chatMessage.Message, "!ravi rs") || strings.HasPrefix(chatMessage.Message, "!ravi reqsed") { - sendServerChatMessage(s, "Requesting sedation support!") - // Total BerRavi HP - HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] - s.server.raviente.support.supportData[1] = HP + 12 + if strings.HasPrefix(chatMessage.Message, raviCmd.Prefix) { + // RAVI COMMANDS V2 + if raviCmd.Enabled { + if getRaviSemaphore(s) != "" { + s.server.raviente.Lock() + if !strings.HasPrefix(chatMessage.Message, "!ravi ") { + sendServerChatMessage(s, "No Raviente command specified!") } else { - sendServerChatMessage(s, "Raviente command not recognised!") + if strings.HasPrefix(chatMessage.Message, "!ravi start") { + if s.server.raviente.register.startTime == 0 { + s.server.raviente.register.startTime = s.server.raviente.register.postTime + sendServerChatMessage(s, "The Great Slaying will begin in a moment") + s.notifyRavi() + } else { + sendServerChatMessage(s, "The Great Slaying has already begun!") + } + } else if strings.HasPrefix(chatMessage.Message, "!ravi sm") || strings.HasPrefix(chatMessage.Message, "!ravi setmultiplier") { + var num uint16 + n, numerr := fmt.Sscanf(chatMessage.Message, "!ravi sm %d", &num) + if numerr != nil || n != 1 { + sendServerChatMessage(s, "Error in command. Format: !ravi sm n") + } else if s.server.raviente.state.damageMultiplier == 1 { + if num > 32 { + sendServerChatMessage(s, "Raviente multiplier too high, defaulting to 32x") + s.server.raviente.state.damageMultiplier = 32 + } else { + sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier set to %dx", num)) + s.server.raviente.state.damageMultiplier = uint32(num) + } + } else { + sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is already set to %dx!", s.server.raviente.state.damageMultiplier)) + } + } else if strings.HasPrefix(chatMessage.Message, "!ravi cm") || strings.HasPrefix(chatMessage.Message, "!ravi checkmultiplier") { + sendServerChatMessage(s, fmt.Sprintf("Raviente multiplier is currently %dx", s.server.raviente.state.damageMultiplier)) + } else if strings.HasPrefix(chatMessage.Message, "!ravi sr") || strings.HasPrefix(chatMessage.Message, "!ravi sendres") { + if s.server.raviente.state.stateData[28] > 0 { + sendServerChatMessage(s, "Sending resurrection support!") + s.server.raviente.state.stateData[28] = 0 + } else { + sendServerChatMessage(s, "Resurrection support has not been requested!") + } + } else if strings.HasPrefix(chatMessage.Message, "!ravi ss") || strings.HasPrefix(chatMessage.Message, "!ravi sendsed") { + sendServerChatMessage(s, "Sending sedation support if requested!") + // Total BerRavi HP + HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] + s.server.raviente.support.supportData[1] = HP + } else if strings.HasPrefix(chatMessage.Message, "!ravi rs") || strings.HasPrefix(chatMessage.Message, "!ravi reqsed") { + sendServerChatMessage(s, "Requesting sedation support!") + // Total BerRavi HP + HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4] + s.server.raviente.support.supportData[1] = HP + 12 + } else { + sendServerChatMessage(s, "Raviente command not recognised!") + } } + s.server.raviente.Unlock() + } else { + sendServerChatMessage(s, "No one has joined the Great Slaying!") } - s.server.raviente.Unlock() } else { - sendServerChatMessage(s, "No one has joined the Great Slaying!") + sendServerChatMessage(s, raviCmd.Name+" command is disabled") } } + // END RAVI COMMANDS V2 - if strings.HasPrefix(chatMessage.Message, "!tele ") { - var x, y int16 - n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y) - if err != nil || n != 2 { - sendServerChatMessage(s, "Invalid command. Usage:\"!tele 500 500\"") + if strings.HasPrefix(chatMessage.Message, teleCmd.Prefix) { + if teleCmd.Enabled { + var x, y int16 + n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y) + if err != nil || n != 2 { + sendServerChatMessage(s, "Invalid command. Usage:\"!tele 500 500\"") + } else { + sendServerChatMessage(s, fmt.Sprintf("Teleporting to %d %d", x, y)) + + // Make the inside of the casted binary + payload := byteframe.NewByteFrame() + payload.SetLE() + payload.WriteUint8(2) // SetState type(position == 2) + payload.WriteInt16(x) // X + payload.WriteInt16(y) // Y + payloadBytes := payload.Data() + + s.QueueSendMHF(&mhfpacket.MsgSysCastedBinary{ + CharID: s.charID, + MessageType: BinaryMessageTypeState, + RawDataPayload: payloadBytes, + }) + } } else { - sendServerChatMessage(s, fmt.Sprintf("Teleporting to %d %d", x, y)) - - // Make the inside of the casted binary - payload := byteframe.NewByteFrame() - payload.SetLE() - payload.WriteUint8(2) // SetState type(position == 2) - payload.WriteInt16(x) // X - payload.WriteInt16(y) // Y - payloadBytes := payload.Data() - - s.QueueSendMHF(&mhfpacket.MsgSysCastedBinary{ - CharID: s.charID, - MessageType: BinaryMessageTypeState, - RawDataPayload: payloadBytes, - }) + sendServerChatMessage(s, teleCmd.Name+" command is disabled") } } }