Merge pull request #111 from ZeruLight/feature/moderation

feature/moderation
This commit is contained in:
wish
2024-01-11 23:04:29 +11:00
committed by GitHub
8 changed files with 198 additions and 10 deletions

View File

@@ -4,6 +4,7 @@ import (
"crypto/rand"
"encoding/hex"
"erupe-ce/common/byteframe"
"erupe-ce/common/mhfcid"
"erupe-ce/common/mhfcourse"
"erupe-ce/common/token"
"erupe-ce/config"
@@ -87,8 +88,64 @@ func sendServerChatMessage(s *Session, message string) {
func parseChatCommand(s *Session, command string) {
args := strings.Split(command[len(s.server.erupeConfig.CommandPrefix):], " ")
switch args[0] {
case commands["Ban"].Prefix:
if s.isOp() {
if len(args) > 1 {
var expiry time.Time
if len(args) > 2 {
var length int
var unit string
n, err := fmt.Sscanf(args[2], `%d%s`, &length, &unit)
if err == nil && n == 2 {
switch unit {
case "s", "second", "seconds":
expiry = time.Now().Add(time.Duration(length) * time.Second)
case "m", "mi", "minute", "minutes":
expiry = time.Now().Add(time.Duration(length) * time.Minute)
case "h", "hour", "hours":
expiry = time.Now().Add(time.Duration(length) * time.Hour)
case "d", "day", "days":
expiry = time.Now().Add(time.Duration(length) * time.Hour * 24)
case "mo", "month", "months":
expiry = time.Now().Add(time.Duration(length) * time.Hour * 24 * 30)
case "y", "year", "years":
expiry = time.Now().Add(time.Duration(length) * time.Hour * 24 * 365)
}
} else {
sendServerChatMessage(s, s.server.i18n.commands.ban.error)
return
}
}
cid := mhfcid.ConvertCID(args[1])
if cid > 0 {
var uid uint32
var uname string
err := s.server.db.QueryRow(`SELECT id, username FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, cid).Scan(&uid, &uname)
if err == nil {
if expiry.IsZero() {
s.server.db.Exec(`INSERT INTO bans VALUES ($1)
ON CONFLICT (user_id) DO UPDATE SET expires=NULL`, uid)
sendServerChatMessage(s, fmt.Sprintf(s.server.i18n.commands.ban.success, uname))
} else {
s.server.db.Exec(`INSERT INTO bans VALUES ($1, $2)
ON CONFLICT (user_id) DO UPDATE SET expires=$2`, uid, expiry)
sendServerChatMessage(s, fmt.Sprintf(s.server.i18n.commands.ban.success, uname)+fmt.Sprintf(s.server.i18n.commands.ban.length, expiry.Format(time.DateTime)))
}
s.server.DisconnectUser(uid)
} else {
sendServerChatMessage(s, s.server.i18n.commands.ban.noUser)
}
} else {
sendServerChatMessage(s, s.server.i18n.commands.ban.invalid)
}
} else {
sendServerChatMessage(s, s.server.i18n.commands.ban.error)
}
} else {
sendServerChatMessage(s, s.server.i18n.commands.noOp)
}
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 +164,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 +225,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 +248,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 +264,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 +307,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 +358,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 +381,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 +395,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))
}
}

View File

@@ -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()

View File

@@ -6,6 +6,7 @@ type i18n struct {
reset string
}
commands struct {
noOp string
disabled string
reload string
kqf struct {
@@ -38,6 +39,13 @@ type i18n struct {
discord struct {
success string
}
ban struct {
success string
noUser string
invalid string
error string
length string
}
ravi struct {
noCommand string
start struct {
@@ -95,6 +103,7 @@ func getLangStrings(s *Server) i18n {
i.language = "日本語"
i.cafe.reset = "%d/%dにリセット"
i.commands.noOp = "You don't have permission to use this command"
i.commands.disabled = "%sのコマンドは無効です"
i.commands.reload = "リロードします"
i.commands.kqf.get = "現在のキークエストフラグ:%x"
@@ -115,6 +124,12 @@ func getLangStrings(s *Server) i18n {
i.commands.discord.success = "あなたのDiscordトークン%s"
i.commands.ban.noUser = "Could not find user"
i.commands.ban.success = "Successfully banned %s"
i.commands.ban.invalid = "Invalid Character ID"
i.commands.ban.error = "Error in command. Format: %s <id> [length]"
i.commands.ban.length = " until %s"
i.commands.ravi.noCommand = "ラヴィコマンドが指定されていません"
i.commands.ravi.start.success = "大討伐を開始します"
i.commands.ravi.start.error = "大討伐は既に開催されています"
@@ -150,6 +165,7 @@ func getLangStrings(s *Server) i18n {
i.language = "English"
i.cafe.reset = "Resets on %d/%d"
i.commands.noOp = "You don't have permission to use this command"
i.commands.disabled = "%s command is disabled"
i.commands.reload = "Reloading players..."
i.commands.kqf.get = "KQF: %x"
@@ -170,6 +186,12 @@ func getLangStrings(s *Server) i18n {
i.commands.discord.success = "Your Discord token: %s"
i.commands.ban.noUser = "Could not find user"
i.commands.ban.success = "Successfully banned %s"
i.commands.ban.invalid = "Invalid Character ID"
i.commands.ban.error = "Error in command. Format: %s <id> [length]"
i.commands.ban.length = " until %s"
i.commands.ravi.noCommand = "No Raviente command specified!"
i.commands.ravi.start.success = "The Great Slaying will begin in a moment"
i.commands.ravi.start.error = "The Great Slaying has already begun!"

View File

@@ -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
}