func (p *BasePlayer) LoadPlayer(data share.LoadUserBak) error { p.trans = server.Transform{data.Scene, Vector3{data.X, data.Y, data.Z}, data.Dir} p.RoleInfo = data.Data.RoleInfo p.LandTimes = data.LandTimes var err error p.Entity, err = App.CreateFromDb(data.Data) if err != nil { log.LogError(err) return err } p.State = STATE_READY player := p.Entity.(*entity.Player) App.SetRoleInfo(p.Entity, p.RoleInfo) App.SetLandpos(p.Entity, p.trans) p.Entity.SetExtraData("account", p.Account) p.Entity.SetExtraData("mailbox", p.Mailbox) log.LogInfo("load player succeed,", player.GetName()) p.saveid = App.AddTimer(time.Minute*5, -1, p.TimeToSave, nil) if player.GetLastUpdateTime() == 0 { player.SetLastUpdateTime(time.Now().Unix()) p.lastupdate = time.Now() } else { p.lastupdate = time.Unix(player.GetLastUpdateTime(), 0) } //同步玩家 App.AttachPlayer(p.Entity, p.Mailbox) return err }
func (b *BaseApp) OnFrame() { b.Players.ClearDeleted() if b.Players.Count() == 0 && b.Closing { log.LogInfo("shutdown") b.Shutdown() } }
//增加一个远程进程 func AddApp(typ string, id int32, name string, host string, port int, clienthost string, clientport int, ready bool, enableglobaldata bool) { if core.Name == name { return } applock.Lock() if appid, ok := RemoteAppName[name]; ok { app := RemoteApps[appid] if app.Id == id && app.Host == host && app.Port == port && app.ClientHost == clienthost && app.ClientPort == clientport { //已经存在 applock.Unlock() return } app.Close() delete(RemoteAppName, name) delete(RemoteApps, appid) } RemoteApps[id] = &RemoteApp{Id: id, Type: typ, Name: name, Host: host, Port: port, ClientHost: clienthost, ClientPort: clientport, Ready: ready, EnableGlobalData: enableglobaldata} RemoteAppName[name] = id log.LogInfo(core.Name, "> add server:", *RemoteApps[id]) if ready { RemoteApps[id].SetReady(ready) core.Eventer.DispatchEvent("ready", name) } applock.Unlock() }
//客户端断开连接 func (b *BaseApp) OnClientLost(id int64) { pl := b.Players.GetPlayer(id) if pl == nil || pl.Deleted { return } log.LogInfo("client offline,", id) pl.Disconnect() }
func (app *app) Close() { if !app.Shutdown { data, err := util.CreateMsg(nil, []byte{}, share.M_SHUTDOWN) if err != nil { log.LogFatalf(err) } _, err = app.conn.Write(data) if err != nil { log.LogInfo(app.id, " closed") } else { log.LogInfo(app.id, " send shutdown") } app.Shutdown = true } }
func (al *AgentList) CloseAll() { al.Lock() defer al.Unlock() data, err := util.CreateMsg(nil, []byte{}, share.M_SHUTDOWN) if err != nil { log.LogFatalf(err) } for k, agent := range al.agents { _, err = agent.rwc.Write(data) if err != nil { log.LogInfo(k, " closed") } else { log.LogInfo(k, " send shutdown") } } }
//客户端断开连接 func (p *BasePlayer) Disconnect() { if p.Offline { return } p.Offline = true App.Disconnect(p.Entity) p.Leave() log.LogInfo("player disconnect:", p.ChooseRole, " session:", p.Session) }
func (p *BasePlayer) DeletePlayer() { if p.Entity != nil { App.DetachPlayer(p.Entity) p.Entity.SetQuiting() App.Destroy(p.Entity.GetObjId()) log.LogInfo("player destroy:", p.ChooseRole, " session:", p.Session) } App.CancelTimer(p.saveid) App.CancelTimer(p.updateid) }
//移除一个远程进程 func RemoveAppById(id int32) { if core.AppId == id { return } applock.Lock() if app, ok := RemoteApps[id]; ok { app.Close() delete(RemoteApps, id) log.LogInfo(core.Name, "> remove server:", app.Name) applock.Unlock() return } log.LogError(core.Name, "> remove server failed, ", id) applock.Unlock() }
func CreateService(rs *Server, l net.Listener) { log.LogMessage("rpc start at:", l.Addr().String()) for { conn, err := l.Accept() if nerr, ok := err.(net.Error); ok && nerr.Temporary() { log.LogWarning("TCP", "temporary Accept() failure - ", err.Error()) runtime.Gosched() continue } if err != nil { log.LogWarning("rpc accept quit") break } //启动服务 log.LogInfo("new rpc client,", conn.RemoteAddr()) go rs.ServeConn(conn, MAX_BUF_LEN) } }
func RemoveAppByName(name string) { if core.Name == name { return } applock.Lock() if appid, ex := RemoteAppName[name]; ex { app := RemoteApps[appid] app.Close() delete(RemoteApps, appid) delete(RemoteAppName, name) log.LogInfo(core.Name, "> remove server:", name) applock.Unlock() return } log.LogError(core.Name, "> remove server failed, ", name) applock.Unlock() }
func (a *Agent) readloop() { buffer := make([]byte, 2048) for !a.quit { id, msg, err := util.ReadPkg(a.rwc, buffer) if err != nil { if err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") { log.LogError(err) } break } if err := a.Handle(id, msg); err != nil { log.LogError(err) break } } log.LogInfo("agent pipe quit") a.Close() }
func (a *AgentNode) readloop() { buffer := make([]byte, 2048) for !a.quit { id, msg, err := util.ReadPkg(a.rwc, buffer) if err != nil { if err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") { log.LogError(err) } break } if err := a.HandleMsg(id, msg); err != nil { log.LogError(err) break } } log.LogInfo("agent node closed") a.Close() context.agentlist.RemoveAgent(a.id) }
func (c *WSClientHandler) Handle(ws *websocket.Conn) { if core.Closing { ws.Close() return } rwc := NewWSConn(ws) id := core.clientList.Add(rwc, ws.RemoteAddr().String()) mailbox := rpc.NewMailBox(1, id, core.AppId) core.Emitter.Push(NEWUSERCONN, map[string]interface{}{"id": id}, true) cl := core.clientList.FindNode(id) cl.MailBox = mailbox cl.Run() codec := &ClientCodec{} codec.rwc = rwc codec.cachebuf = make([]byte, SENDBUFLEN) codec.node = cl log.LogInfo("new client:", mailbox, ",", ws.RemoteAddr()) core.rpcServer.ServeCodec(codec, rpc.MAX_BUF_LEN) core.Emitter.Push(LOSTUSERCONN, map[string]interface{}{"id": cl.Session}, true) log.LogMessage("client handle quit") }
func (p *PlayerList) SwitchPlayer(player *BasePlayer) error { oldsession := player.Session //被顶替的玩家 replace := p.FindPlayer(player.Account, player.ChooseRole, player.Session) if replace == nil { log.LogError("old player not found") return nil } //交换连接 App.SwitchConn(replace.Session, player.Session) //把原来的玩家踢下线 server.Error(nil, &player.Mailbox, "Login.Error", share.ERROR_ROLE_REPLACE) App.DelayKickUser(oldsession, 5) //同步玩家数据 App.AttachPlayer(replace.Entity, replace.Mailbox) player.Account += "*replace*" player.ChooseRole += "*replace*" log.LogInfo("switch player: old:", oldsession, " new:", replace.Session) return nil }
func (p *peer) readloop() { buffer := make([]byte, 2048) for !core.quit { id, msg, err := util.ReadPkg(p.rwc, buffer) if err != nil { if err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") { log.LogError(err) } break } if p.h != nil { if err := p.h.Handle(id, msg); err != nil { log.LogError(err) break } } } log.LogInfo("peer node closed") p.Close() }
func (p *BasePlayer) SaveToDb(offline bool) { typ := share.SAVETYPE_TIMER if offline { p.State = STATE_SAVING typ = share.SAVETYPE_OFFLINE } if typ == share.SAVETYPE_TIMER { if !p.Entity.NeedSave() { return } } log.LogInfo("save player,", p.ChooseRole, ", type ", typ) //写数据到数据库 if err := App.DbBridge.savePlayer(p, typ); err != nil { log.LogError(err) if p.Entity != nil { p.SaveFailed() } } }
func (m *Master) Exit() { log.TraceInfo("master", "stop") if m.Agent { m.agent.Close() } else { m.agentlist.CloseAll() } for _, a := range m.app { a.Close() } if m.tcpListener != nil { m.tcpListener.Close() } log.LogInfo("wait all app quit") for len(m.app) != 0 { time.Sleep(time.Second) } m.waitGroup.Wait() }
func (b *BaseApp) OnMustAppReady() { log.LogInfo("must app ready") b.startinit.Do(b.StartInit) }
//进程就绪 func (app *RemoteApp) SetReady(ready bool) { app.Ready = ready log.LogInfo(app.Name, " is ready") core.Emitter.Push(NEWAPPREADY, map[string]interface{}{"id": app.Name}, true) }
func (b *BaseApp) OnShutdown() bool { c := b.GetClientList() c.CloseAll() log.LogInfo("kick all user") return false }
func (hd *handler) Handle(conn net.Conn) { log.LogInfo("new client: ", conn.RemoteAddr()) if !App.MustAppReady { log.LogError("must app not ready") conn.Close() return } r := &s2c.Rpc{} r.Sender = proto.String(App.Name) h, p, err := GetLogin() if err != nil { e := &s2c.Error{} e.ErrorNo = proto.Int32(share.ERROR_NOLOGIN) b, err := proto.Marshal(e) if err != nil { conn.Close() log.LogFatalf(err) } r.Servicemethod = proto.String("Login.Error") r.Data = b data, err := proto.Marshal(r) if err != nil { log.LogFatalf(err) return } out, _ := util.CreateMsg(nil, data, share.S2C_RPC) _, err = conn.Write(out) if err != nil { conn.Close() log.LogError(err) return } } else { l := &s2c.Login{} l.Host = proto.String(h) l.Port = proto.Int32(int32(p)) b, err := proto.Marshal(l) if err != nil { conn.Close() log.LogFatalf(err) } log.LogInfo("client choose login:"******":", p) r.Servicemethod = proto.String("Login.LoginInfo") r.Data = b data, err := proto.Marshal(r) if err != nil { log.LogFatalf(err) return } out, _ := util.CreateMsg(nil, data, share.S2C_RPC) _, err = conn.Write(out) if err != nil { conn.Close() log.LogError(err) return } } conn.SetReadDeadline(time.Now().Add(time.Second * 10)) conn.Read(hd.ignore[:]) log.LogMessage("client close: ", conn.RemoteAddr()) conn.Close() }
func (p *Player) OnDestroy(self Entityer, sender Entityer) int { log.LogInfo("player destroy,", self.GetObjId()) return 1 }