diff --git a/gdxsv/db.go b/gdxsv/db.go index 5737640..581894d 100644 --- a/gdxsv/db.go +++ b/gdxsv/db.go @@ -39,7 +39,7 @@ type DBAccount struct { Created time.Time `db:"created" json:"created,omitempty"` CreatedIP string `db:"created_ip" json:"created_ip,omitempty"` LastLogin time.Time `db:"last_login" json:"last_login,omitempty"` - LastLoginIP string `db:"last_login_ip" json:"last_login,omitempty"` + LastLoginIP string `db:"last_login_ip" json:"last_login_ip,omitempty"` System byte `db:"system" json:"system,omitempty"` } @@ -111,6 +111,12 @@ type RankingRecord struct { DBUser } +type UserBan struct { + Key string `db:"key" json:"key,omitempty"` + Until time.Time `db:"until" json:"until,omitempty"` + Created time.Time `db:"created" json:"created,omitempty"` +} + // DB is an interface of database operation. type DB interface { // Init initializes the database. @@ -176,4 +182,7 @@ type DB interface { // GetString returns a string that corresponds to the key. GetString(key string) (value string, err error) + + // GetBan returns user's ban information. + GetBan(key string) (ban UserBan, err error) } diff --git a/gdxsv/db_sqlite.go b/gdxsv/db_sqlite.go index 76d7538..6b9c3ba 100644 --- a/gdxsv/db_sqlite.go +++ b/gdxsv/db_sqlite.go @@ -102,6 +102,12 @@ CREATE TABLE IF NOT EXISTS strings ( value text, PRIMARY KEY (key) ); +CREATE TABLE IF NOT EXISTS m_ban ( + key text, + until timestamp, + created timestamp, + PRIMARY KEY (key) +); ` const indexes = ` @@ -525,3 +531,9 @@ func (db SQLiteDB) GetString(key string) (string, error) { err := db.QueryRowx(`SELECT value FROM strings WHERE key = ? LIMIT 1`, key).Scan(&value) return value, err } + +func (db SQLiteDB) GetBan(key string) (UserBan, error) { + var userBan UserBan + err := db.QueryRowx(`SELECT key, until, created FROM m_ban WHERE key = ? LIMIT 1`, key).StructScan(&userBan) + return userBan, err +} diff --git a/gdxsv/lbs.go b/gdxsv/lbs.go index a1ecbaa..d1d8f9d 100644 --- a/gdxsv/lbs.go +++ b/gdxsv/lbs.go @@ -2,6 +2,7 @@ package main import ( "context" + "database/sql" "encoding/json" "fmt" "go.uber.org/zap" @@ -81,10 +82,29 @@ func (lbs *Lbs) NoBan() { lbs.noban = true } +func (lbs *Lbs) IsBan(p *LbsPeer) bool { + ban, err := getDB().GetBan(p.IP()) + if err == sql.ErrNoRows { + return false + } + if err != nil { + logger.Warn("GetBan returned err", zap.Error(err)) + return false + } + if 0 < time.Until(ban.Until) { + if lbs.noban { + logger.Warn("passed banned user", zap.String("user_id", p.UserID), zap.String("name", p.Name)) + return false + } + return true + } + return false +} + func (lbs *Lbs) IsTempBan(p *LbsPeer) bool { if t, ok := p.app.bannedIPs[p.IP()]; ok && time.Since(t).Minutes() <= 10 { if lbs.noban { - logger.Warn("passed banned user", zap.String("user_id", p.UserID)) + logger.Warn("passed temp banned user", zap.String("user_id", p.UserID), zap.String("name", p.Name)) return false } return true diff --git a/gdxsv/lbs_handler.go b/gdxsv/lbs_handler.go index 341e994..b63e366 100644 --- a/gdxsv/lbs_handler.go +++ b/gdxsv/lbs_handler.go @@ -265,6 +265,12 @@ var _ = register(lbsLoginType, func(p *LbsPeer, m *LbsMessage) { return } + if p.app.IsBan(p) { + p.SendMessage(NewServerNotice(lbsShutDown).Writer(). + WriteString("
YOU ARE BANNED").Msg()) + return + } + switch loginType { case 2: if p.PlatformInfo["flycast"] != "" {