package net import ( "github.com/gorilla/websocket" "log/slog" "slgserver/server/slgserver/conn" "slgserver/server/slgserver/pos" "sync" "sync/atomic" ) var ConnMgr = Mgr{} var cid int64 = 0 type Mgr struct { cm sync.RWMutex um sync.RWMutex rm sync.RWMutex connCache map[int64]WSConn userCache map[int]WSConn roleCache map[int]WSConn } func (this *Mgr) NewConn(wsSocket *websocket.Conn, needSecret bool) *ServerConn { this.cm.Lock() defer this.cm.Unlock() id := atomic.AddInt64(&cid, 1) if this.connCache == nil { this.connCache = make(map[int64]WSConn) } if this.userCache == nil { this.userCache = make(map[int]WSConn) } if this.roleCache == nil { this.roleCache = make(map[int]WSConn) } c := NewServerConn(wsSocket, needSecret) c.SetProperty("cid", id) this.connCache[id] = c return c } func (this *Mgr) UserLogin(conn WSConn, session string, uid int) { this.um.Lock() defer this.um.Unlock() oldConn, ok := this.userCache[uid] if ok { if conn != oldConn { slog.Warn("rob login", "uid", uid, "oldAddr", oldConn.Addr(), "newAddr", conn.Addr()) //这里需要通知旧端被抢登录 oldConn.Push("robLogin", nil) } } this.userCache[uid] = conn conn.SetProperty("session", session) conn.SetProperty("uid", uid) } func (this *Mgr) UserLogout(conn WSConn) { this.removeUser(conn) } func (this *Mgr) removeUser(conn WSConn) { this.um.Lock() uid, err := conn.GetProperty("uid") if err == nil { //只删除自己的conn id := uid.(int) c, ok := this.userCache[id] if ok && c == conn { delete(this.userCache, id) } } this.um.Unlock() this.rm.Lock() rid, err := conn.GetProperty("rid") if err == nil { //只删除自己的conn id := rid.(int) c, ok := this.roleCache[id] if ok && c == conn { delete(this.roleCache, id) } } this.rm.Unlock() conn.RemoveProperty("session") conn.RemoveProperty("uid") conn.RemoveProperty("role") conn.RemoveProperty("rid") } func (this *Mgr) RoleEnter(conn WSConn, rid int) { this.rm.Lock() defer this.rm.Unlock() conn.SetProperty("rid", rid) this.roleCache[rid] = conn } func (this *Mgr) RemoveConn(conn WSConn) { this.cm.Lock() cid, err := conn.GetProperty("cid") if err == nil { delete(this.connCache, cid.(int64)) conn.RemoveProperty("cid") } this.cm.Unlock() this.removeUser(conn) } func (this *Mgr) PushByRoleId(rid int, msgName string, data interface{}) bool { if rid <= 0 { return false } this.rm.Lock() defer this.rm.Unlock() conn, ok := this.roleCache[rid] if ok { conn.Push(msgName, data) return true } else { return false } } func (this *Mgr) Count() int { this.cm.RLock() defer this.cm.RUnlock() return len(this.connCache) } func (this *Mgr) Push(pushSync conn.PushSync) { proto := pushSync.ToProto() belongRIds := pushSync.BelongToRId() isCellView := pushSync.IsCellView() x, y := pushSync.Position() cells := make(map[int]int) //推送给开始位置 if isCellView { cellRIds := pos.RPMgr.GetCellRoleIds(x, y, 8, 6) for _, rid := range cellRIds { //是否能出现在视野 if can := pushSync.IsCanView(rid, x, y); can { this.PushByRoleId(rid, pushSync.PushMsgName(), proto) cells[rid] = rid } } } //推送给目标位置 tx, ty := pushSync.TPosition() if tx >= 0 && ty >= 0 { var cellRIds []int if isCellView { cellRIds = pos.RPMgr.GetCellRoleIds(tx, ty, 8, 6) } else { cellRIds = pos.RPMgr.GetCellRoleIds(tx, ty, 0, 0) } for _, rid := range cellRIds { if _, ok := cells[rid]; !ok { if can := pushSync.IsCanView(rid, tx, ty); can { this.PushByRoleId(rid, pushSync.PushMsgName(), proto) cells[rid] = rid } } } } //推送给自己 for _, rid := range belongRIds { if _, ok := cells[rid]; !ok { this.PushByRoleId(rid, pushSync.PushMsgName(), proto) } } } func (this *Mgr) pushAll(msgName string, data interface{}) { this.rm.Lock() defer this.rm.Unlock() for _, conn := range this.roleCache { conn.Push(msgName, data) } }