diff --git a/patch-schema/op-accounts.sql b/patch-schema/op-accounts.sql new file mode 100644 index 000000000..bdf5dccd8 --- /dev/null +++ b/patch-schema/op-accounts.sql @@ -0,0 +1,12 @@ +BEGIN; + +ALTER TABLE IF EXISTS public.users ADD COLUMN op boolean; + +CREATE TABLE public.bans +( + user_id integer NOT NULL, + expires timestamp with time zone, + PRIMARY KEY (user_id) +); + +END; \ No newline at end of file diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 043403216..016e1f70c 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -88,7 +88,7 @@ func parseChatCommand(s *Session, command string) { args := strings.Split(command[len(s.server.erupeConfig.CommandPrefix):], " ") switch args[0] { case commands["PSN"].Prefix: - if commands["PSN"].Enabled { + if commands["PSN"].Enabled || s.isOp() { if len(args) > 1 { var exists int s.server.db.QueryRow(`SELECT count(*) FROM users WHERE psn_id = $1`, args[1]).Scan(&exists) @@ -107,7 +107,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["PSN"]) } case commands["Reload"].Prefix: - if commands["Reload"].Enabled { + if commands["Reload"].Enabled || s.isOp() { sendServerChatMessage(s, s.server.i18n.commands.reload) var temp mhfpacket.MHFPacket deleteNotif := byteframe.NewByteFrame() @@ -168,7 +168,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["Reload"]) } case commands["KeyQuest"].Prefix: - if commands["KeyQuest"].Enabled { + if commands["KeyQuest"].Enabled || s.isOp() { if s.server.erupeConfig.RealClientMode < _config.G10 { sendServerChatMessage(s, s.server.i18n.commands.kqf.version) } else { @@ -191,7 +191,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["KeyQuest"]) } case commands["Rights"].Prefix: - if commands["Rights"].Enabled { + if commands["Rights"].Enabled || s.isOp() { if len(args) > 1 { v, _ := strconv.Atoi(args[1]) _, 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) @@ -207,7 +207,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["Rights"]) } case commands["Course"].Prefix: - if commands["Course"].Enabled { + if commands["Course"].Enabled || s.isOp() { if len(args) > 1 { for _, course := range mhfcourse.Courses() { for _, alias := range course.Aliases() { @@ -250,7 +250,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["Course"]) } case commands["Raviente"].Prefix: - if commands["Raviente"].Enabled { + if commands["Raviente"].Enabled || s.isOp() { if len(args) > 1 { if s.server.getRaviSemaphore() != nil { switch args[1] { @@ -301,7 +301,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["Raviente"]) } case commands["Teleport"].Prefix: - if commands["Teleport"].Enabled { + if commands["Teleport"].Enabled || s.isOp() { if len(args) > 2 { x, _ := strconv.ParseInt(args[1], 10, 16) y, _ := strconv.ParseInt(args[2], 10, 16) @@ -324,7 +324,7 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["Teleport"]) } case commands["Discord"].Prefix: - if commands["Discord"].Enabled { + if commands["Discord"].Enabled || s.isOp() { var _token string err := s.server.db.QueryRow(`SELECT discord_token FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.charID).Scan(&_token) if err != nil { @@ -338,9 +338,9 @@ func parseChatCommand(s *Session, command string) { sendDisabledCommandMessage(s, commands["Discord"]) } case commands["Help"].Prefix: - if commands["Help"].Enabled { + if commands["Help"].Enabled || s.isOp() { for _, command := range commands { - if command.Enabled { + if command.Enabled || s.isOp() { sendServerChatMessage(s, fmt.Sprintf("%s%s: %s", s.server.erupeConfig.CommandPrefix, command.Prefix, command.Description)) } } diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index 30d63241f..19bd04123 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -378,6 +378,26 @@ func (s *Server) FindSessionByCharID(charID uint32) *Session { return nil } +func (s *Server) DisconnectUser(uid uint32) { + var cid uint32 + var cids []uint32 + rows, _ := s.db.Query(`SELECT id FROM characters WHERE user_id=$1`, uid) + for rows.Next() { + rows.Scan(&cid) + cids = append(cids, cid) + } + for _, c := range s.Channels { + for _, session := range c.sessions { + for _, cid := range cids { + if session.charID == cid { + session.rawConn.Close() + break + } + } + } + } +} + func (s *Server) FindObjectByChar(charID uint32) *Object { s.stagesLock.RLock() defer s.stagesLock.RUnlock() diff --git a/server/channelserver/sys_session.go b/server/channelserver/sys_session.go index d49e5264a..a0b30adb3 100644 --- a/server/channelserver/sys_session.go +++ b/server/channelserver/sys_session.go @@ -309,3 +309,12 @@ func (s *Session) NextObjectID() uint32 { bf.Seek(0, 0) return bf.ReadUint32() } + +func (s *Session) isOp() bool { + var op bool + err := s.server.db.QueryRow(`SELECT op FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.charID).Scan(&op) + if err == nil && op { + return true + } + return false +} diff --git a/server/signserver/dbutils.go b/server/signserver/dbutils.go index f23d3bdcc..dadf3f074 100644 --- a/server/signserver/dbutils.go +++ b/server/signserver/dbutils.go @@ -244,6 +244,15 @@ func (s *Server) validateLogin(user string, pass string) (uint32, RespID) { return 0, SIGN_EABORT } else { if bcrypt.CompareHashAndPassword([]byte(passDB), []byte(pass)) == nil { + var bans int + err = s.db.QueryRow(`SELECT count(*) FROM bans WHERE user_id=$1 AND expires IS NULL`, uid).Scan(&bans) + if err == nil && bans > 0 { + return uid, SIGN_EELIMINATE + } + err = s.db.QueryRow(`SELECT count(*) FROM bans WHERE user_id=$1 AND expires > now()`, uid).Scan(&bans) + if err == nil && bans > 0 { + return uid, SIGN_ESUSPEND + } return uid, SIGN_SUCCESS } return 0, SIGN_EPASS