forked from lonng/nanoserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
manager.go
159 lines (131 loc) · 3.58 KB
/
manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package game
import (
"github.com/lonnng/nanoserver/internal/protocol"
"time"
"github.com/lonnng/nano"
"github.com/lonnng/nano/component"
"github.com/lonnng/nano/session"
log "github.com/sirupsen/logrus"
)
const kickResetBacklog = 8
var defaultManager = NewManager()
type (
Manager struct {
component.Base
group *nano.Group // 广播channel
players map[int64]*Player // 所有的玩家
chKick chan int64 // 退出队列
chReset chan int64 // 重置队列
chRecharge chan RechargeInfo // 充值信息
}
RechargeInfo struct {
Uid int64 // 用户ID
Coin int64 // 房卡数量
}
)
func NewManager() *Manager {
return &Manager{
group: nano.NewGroup("_SYSTEM_MESSAGE_BROADCAST"),
players: map[int64]*Player{},
chKick: make(chan int64, kickResetBacklog),
chReset: make(chan int64, kickResetBacklog),
chRecharge: make(chan RechargeInfo, 32),
}
}
func (m *Manager) AfterInit() {
nano.OnSessionClosed(func(s *session.Session) {
m.group.Leave(s)
})
// 处理踢出玩家和重置玩家消息(来自http)
nano.NewTimer(time.Second, func() {
ctrl:
for {
select {
case uid := <-m.chKick:
p, ok := defaultManager.player(uid)
if !ok || p.session == nil {
logger.Errorf("玩家%d不在线", uid)
}
p.session.Close()
logger.Infof("踢出玩家, UID=%d", uid)
case uid := <-m.chReset:
p, ok := defaultManager.player(uid)
if !ok {
return
}
if p.session != nil {
logger.Errorf("玩家正在游戏中,不能重置: %d", uid)
return
}
p.desk = nil
logger.Infof("重置玩家, UID=%d", uid)
case ri := <-m.chRecharge:
player, ok := m.player(ri.Uid)
// 如果玩家在线
if s := player.session; ok && s != nil {
s.Push("onCoinChange", &protocol.CoinChangeInformation{Coin: ri.Coin})
}
default:
break ctrl
}
}
})
}
func (m *Manager) Login(s *session.Session, req *protocol.LoginToGameServerRequest) error {
uid := req.Uid
s.Bind(uid)
log.Infof("玩家: %d登录: %+v", uid, req)
if p, ok := m.player(uid); !ok {
log.Infof("玩家: %d不在线,创建新的玩家", uid)
p = newPlayer(s, uid, req.Name, req.HeadUrl, req.IP, req.Sex)
m.setPlayer(uid, p)
} else {
log.Infof("玩家: %d已经在线", uid)
// 移除广播频道
m.group.Leave(s)
// 重置之前的session
if prevSession := p.session; prevSession != nil && prevSession != s {
// 如果之前房间存在,则退出来
if p, err := playerWithSession(prevSession); err == nil && p != nil && p.desk != nil && p.desk.group != nil {
p.desk.group.Leave(prevSession)
}
prevSession.Clear()
prevSession.Close()
}
// 绑定新session
p.bindSession(s)
}
// 添加到广播频道
m.group.Add(s)
res := &protocol.LoginToGameServerResponse{
Uid: s.UID(),
Nickname: req.Name,
Sex: req.Sex,
HeadUrl: req.HeadUrl,
FangKa: req.FangKa,
}
return s.Response(res)
}
func (m *Manager) player(uid int64) (*Player, bool) {
p, ok := m.players[uid]
return p, ok
}
func (m *Manager) setPlayer(uid int64, p *Player) {
if _, ok := m.players[uid]; ok {
log.Warnf("玩家已经存在,正在覆盖玩家, UID=%d", uid)
}
m.players[uid] = p
}
func (m *Manager) CheckOrder(s *session.Session, msg *protocol.CheckOrderReqeust) error {
log.Infof("%+v", msg)
return s.Response(&protocol.CheckOrderResponse{
FangKa: 20,
})
}
func (m *Manager) sessionCount() int {
return len(m.players)
}
func (m *Manager) offline(uid int64) {
delete(m.players, uid)
log.Infof("玩家: %d从在线列表中删除, 剩余:%d", uid, len(m.players))
}