@@ -3,19 +3,29 @@ package mobius
33import (
44 "bufio"
55 "bytes"
6+ "context"
67 "encoding/binary"
78 "fmt"
8- "github.com/jhalter/mobius/hotline"
9- "golang.org/x/text/encoding/charmap"
109 "io"
1110 "math/big"
1211 "os"
1312 "path"
1413 "path/filepath"
1514 "strings"
1615 "time"
16+
17+ "github.com/jhalter/mobius/hotline"
18+ "golang.org/x/text/encoding/charmap"
1719)
1820
21+ // This function is used to extract the IP address from a given address string, exluding the port.
22+ func extractIP (addr string ) string {
23+ if idx := strings .LastIndex (addr , ":" ); idx != - 1 {
24+ return addr [:idx ]
25+ }
26+ return addr
27+ }
28+
1929// Converts bytes from Mac Roman encoding to UTF-8
2030var txtDecoder = charmap .Macintosh .NewDecoder ()
2131
@@ -852,6 +862,27 @@ func HandleTranAgreed(cc *hotline.ClientConn, t *hotline.Transaction) (res []hot
852862 }
853863 }
854864
865+ if cc .Server .Redis != nil {
866+ login := cc .Account .Login
867+ ip := extractIP (cc .RemoteAddr )
868+ // Remove old entry (login::ip)
869+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + "::" + ip )
870+ // Add new entry with login, nickname, ip
871+ cc .Server .Redis .SAdd (context .Background (), "mobius:online" , login + ":" + string (cc .UserName )+ ":" + ip )
872+ // Ban check for nickname
873+ bannedNick , _ := cc .Server .Redis .SIsMember (context .Background (), "mobius:banned:nicknames" , string (cc .UserName )).Result ()
874+ if bannedNick {
875+ // Remove all possible online entries for this login and IP
876+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + "::" + ip )
877+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + ":" + string (cc .UserName )+ ":" + ip )
878+ // If we track the previous nickname, remove that too:
879+ // cc.Server.Redis.SRem(context.Background(), "mobius:online", login+":"+oldNickname+":"+ip)
880+ cc .Server .Redis .SAdd (context .Background (), "mobius:banned:ips" , ip )
881+ cc .Disconnect ()
882+ return res
883+ }
884+ }
885+
855886 cc .Icon = t .GetField (hotline .FieldUserIconID ).Data
856887
857888 cc .Logger = cc .Logger .With ("Name" , string (cc .UserName ))
@@ -1477,7 +1508,33 @@ func HandleSetClientUserInfo(cc *hotline.ClientConn, t *hotline.Transaction) (re
14771508 cc .Icon = t .GetField (hotline .FieldUserIconID ).Data
14781509 }
14791510 if cc .Authorize (hotline .AccessAnyName ) {
1511+ oldNickname := string (cc .UserName )
1512+ newNickname := string (t .GetField (hotline .FieldUserName ).Data )
14801513 cc .UserName = t .GetField (hotline .FieldUserName ).Data
1514+ if cc .Server .Redis != nil {
1515+ login := cc .Account .Login
1516+ ip := extractIP (cc .RemoteAddr )
1517+ // Remove old entry (login:oldnickname:ip) and (login::ip)
1518+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + "::" + ip )
1519+ if oldNickname != "" {
1520+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + ":" + oldNickname + ":" + ip )
1521+ }
1522+ // Add new entry
1523+ cc .Server .Redis .SAdd (context .Background (), "mobius:online" , login + ":" + newNickname + ":" + ip )
1524+ // Ban check for nickname
1525+ bannedNick , _ := cc .Server .Redis .SIsMember (context .Background (), "mobius:banned:nicknames" , newNickname ).Result ()
1526+ if bannedNick {
1527+ // Remove all possible online entries for this login and IP
1528+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + "::" + ip )
1529+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + ":" + newNickname + ":" + ip )
1530+ if oldNickname != "" {
1531+ cc .Server .Redis .SRem (context .Background (), "mobius:online" , login + ":" + oldNickname + ":" + ip )
1532+ }
1533+ cc .Server .Redis .SAdd (context .Background (), "mobius:banned:ips" , ip )
1534+ cc .Disconnect ()
1535+ return res
1536+ }
1537+ }
14811538 }
14821539
14831540 // the options field is only passed by the client versions > 1.2.3.
0 commit comments