205 lines
4.9 KiB
Go
205 lines
4.9 KiB
Go
package controller
|
|
|
|
import (
|
|
"github.com/mitchellh/mapstructure"
|
|
"log/slog"
|
|
"slgserver/constant"
|
|
"slgserver/middleware"
|
|
"slgserver/net"
|
|
"slgserver/server/chatserver/logic"
|
|
"slgserver/server/chatserver/proto"
|
|
"slgserver/util"
|
|
"sync"
|
|
)
|
|
|
|
var DefaultChat = Chat{
|
|
worldGroup: logic.NewGroup(),
|
|
unionGroups: make(map[int]*logic.Group),
|
|
ridToUnionGroups: make(map[int]int),
|
|
}
|
|
|
|
type Chat struct {
|
|
unionMutex sync.RWMutex
|
|
worldGroup *logic.Group //世界频道
|
|
unionGroups map[int]*logic.Group //联盟频道
|
|
ridToUnionGroups map[int]int //rid对应的联盟频道
|
|
}
|
|
|
|
func (this*Chat) InitRouter(r *net.Router) {
|
|
g := r.Group("chat").Use(middleware.ElapsedTime(), middleware.Log())
|
|
|
|
g.AddRouter("login", this.login)
|
|
g.AddRouter("logout", this.logout, middleware.CheckRId())
|
|
g.AddRouter("chat", this.chat, middleware.CheckRId())
|
|
g.AddRouter("history", this.history, middleware.CheckRId())
|
|
g.AddRouter("join", this.join, middleware.CheckRId())
|
|
g.AddRouter("exit", this.exit, middleware.CheckRId())
|
|
}
|
|
|
|
func (this*Chat) login(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
|
reqObj := &proto.LoginReq{}
|
|
rspObj := &proto.LoginRsp{}
|
|
rsp.Body.Code = constant.OK
|
|
rsp.Body.Msg = rspObj
|
|
|
|
mapstructure.Decode(req.Body.Msg, reqObj)
|
|
rspObj.RId = reqObj.RId
|
|
rspObj.NickName = reqObj.NickName
|
|
|
|
sess, err := util.ParseSession(reqObj.Token)
|
|
if err != nil{
|
|
rsp.Body.Code = constant.InvalidParam
|
|
return
|
|
}
|
|
if sess.IsValid() == false || sess.Id != reqObj.RId{
|
|
rsp.Body.Code = constant.InvalidParam
|
|
return
|
|
}
|
|
net.ConnMgr.RoleEnter(req.Conn, reqObj.RId)
|
|
|
|
this.worldGroup.Enter(logic.NewUser(reqObj.RId, reqObj.NickName))
|
|
}
|
|
|
|
func (this*Chat) logout(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
|
reqObj := &proto.LogoutReq{}
|
|
rspObj := &proto.LogoutRsp{}
|
|
rsp.Body.Code = constant.OK
|
|
rsp.Body.Msg = rspObj
|
|
|
|
mapstructure.Decode(req.Body.Msg, reqObj)
|
|
rspObj.RId = reqObj.RId
|
|
|
|
net.ConnMgr.UserLogout(req.Conn)
|
|
this.worldGroup.Exit(reqObj.RId)
|
|
}
|
|
|
|
func (this*Chat) chat(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
|
reqObj := &proto.ChatReq{}
|
|
rspObj := &proto.ChatMsg{}
|
|
rsp.Body.Code = constant.OK
|
|
rsp.Body.Msg = rspObj
|
|
|
|
mapstructure.Decode(req.Body.Msg, reqObj)
|
|
|
|
p, _ := req.Conn.GetProperty("rid")
|
|
rid := p.(int)
|
|
if reqObj.Type == 0 {
|
|
//世界聊天
|
|
rsp.Body.Msg = this.worldGroup.PutMsg(reqObj.Msg, rid, 0)
|
|
}else if reqObj.Type == 1{
|
|
//联盟聊天
|
|
this.unionMutex.RLock()
|
|
id, ok := this.ridToUnionGroups[rid]
|
|
if ok {
|
|
g, ok := this.unionGroups[id]
|
|
if ok {
|
|
g.PutMsg(reqObj.Msg, rid, 1)
|
|
}else{
|
|
slog.Warn("chat not found rid in unionGroups", "rid", rid)
|
|
}
|
|
}else{
|
|
slog.Warn("chat not found rid in ridToUnionGroups", "rid", rid)
|
|
}
|
|
this.unionMutex.RUnlock()
|
|
}
|
|
|
|
}
|
|
|
|
//历史记录
|
|
func (this*Chat) history(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
|
reqObj := &proto.HistoryReq{}
|
|
rspObj := &proto.HistoryRsp{}
|
|
rsp.Body.Code = constant.OK
|
|
|
|
mapstructure.Decode(req.Body.Msg, reqObj)
|
|
rspObj.Msgs = []proto.ChatMsg{}
|
|
p, _ := req.Conn.GetProperty("rid")
|
|
rid := p.(int)
|
|
|
|
if reqObj.Type == 0 {
|
|
r := this.worldGroup.History()
|
|
rspObj.Msgs = r
|
|
}else if reqObj.Type == 1 {
|
|
this.unionMutex.RLock()
|
|
id, ok := this.ridToUnionGroups[rid]
|
|
if ok {
|
|
g, ok := this.unionGroups[id]
|
|
if ok {
|
|
rspObj.Msgs = g.History()
|
|
}
|
|
}
|
|
this.unionMutex.RUnlock()
|
|
}
|
|
rspObj.Type = reqObj.Type
|
|
rsp.Body.Msg = rspObj
|
|
}
|
|
|
|
func (this*Chat) join(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
|
reqObj := &proto.JoinReq{}
|
|
rspObj := &proto.JoinRsp{}
|
|
rsp.Body.Code = constant.OK
|
|
rsp.Body.Msg = rspObj
|
|
rspObj.Type = reqObj.Type
|
|
mapstructure.Decode(req.Body.Msg, reqObj)
|
|
p, _ := req.Conn.GetProperty("rid")
|
|
rid := p.(int)
|
|
if reqObj.Type == 1 {
|
|
u := this.worldGroup.GetUser(rid)
|
|
if u == nil {
|
|
rsp.Body.Code = constant.InvalidParam
|
|
return
|
|
}
|
|
|
|
this.unionMutex.Lock()
|
|
gId, ok := this.ridToUnionGroups[rid]
|
|
if ok {
|
|
if gId != reqObj.Id {
|
|
//联盟聊天只能有一个,顶掉旧的
|
|
if g,ok := this.unionGroups[gId]; ok {
|
|
g.Exit(rid)
|
|
}
|
|
|
|
_, ok = this.unionGroups[reqObj.Id]
|
|
if ok == false {
|
|
this.unionGroups[reqObj.Id] = logic.NewGroup()
|
|
}
|
|
this.ridToUnionGroups[rid] = reqObj.Id
|
|
this.unionGroups[reqObj.Id].Enter(u)
|
|
}
|
|
}else{
|
|
//新加入
|
|
_, ok = this.unionGroups[reqObj.Id]
|
|
if ok == false {
|
|
this.unionGroups[reqObj.Id] = logic.NewGroup()
|
|
}
|
|
this.ridToUnionGroups[rid] = reqObj.Id
|
|
this.unionGroups[reqObj.Id].Enter(u)
|
|
}
|
|
this.unionMutex.Unlock()
|
|
}
|
|
}
|
|
|
|
func (this*Chat) exit(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
|
reqObj := &proto.ExitReq{}
|
|
rspObj := &proto.ExitRsp{}
|
|
rsp.Body.Code = constant.OK
|
|
rsp.Body.Msg = rspObj
|
|
rspObj.Type = reqObj.Type
|
|
mapstructure.Decode(req.Body.Msg, reqObj)
|
|
p, _ := req.Conn.GetProperty("rid")
|
|
rid := p.(int)
|
|
|
|
if reqObj.Type == 1 {
|
|
this.unionMutex.Lock()
|
|
id, ok := this.ridToUnionGroups[rid]
|
|
if ok {
|
|
g, ok := this.unionGroups[id]
|
|
if ok {
|
|
g.Exit(rid)
|
|
}
|
|
}
|
|
delete(this.ridToUnionGroups, rid)
|
|
this.unionMutex.Unlock()
|
|
}
|
|
}
|