package logic import ( "ecs/proto" "github.com/oylshe1314/framework/client/rpc" "github.com/oylshe1314/framework/errors" "github.com/oylshe1314/framework/server" "github.com/oylshe1314/framework/util" "sync" ) type reportEvent struct { req any path string } type EventManager struct { manager wg sync.WaitGroup httpRpcClient rpc.HttpRpcClient eventFuns int eventChan chan *reportEvent } func NewEventManager(svr server.Server, httpRpcClient rpc.HttpRpcClient) *EventManager { return &EventManager{ manager: manager{ server: svr, }, httpRpcClient: httpRpcClient, } } func (this *EventManager) Init() error { if this.httpRpcClient == nil { return errors.Error("'httpRpcClient' is nil") } this.eventChan = make(chan *reportEvent, 4096) for i := 0; i < 8; i++ { go this.eventHandler() } return nil } func (this *EventManager) Close() error { close(this.eventChan) this.wg.Wait() return nil } func (this *EventManager) eventHandler() { this.wg.Add(1) this.eventFuns += 1 defer func() { this.wg.Done() this.eventFuns -= 1 }() for { event, ok := <-this.eventChan if !ok { return } if this.Logger().IsDebugEnabled() { this.Logger().Debugf("Log event report, url: %s, req: %s", event.path, util.ToJsonString(event.req)) } _, err := this.httpRpcClient.RandPost("event", event.path, nil, event.req, nil) if err != nil { this.Logger().Error("Log event report failed, ", err) } if this.eventFuns > 8 && len(this.eventChan) < 2000 { return } } } func (this *EventManager) reportEvent(path string, req any) { this.eventChan <- &reportEvent{req: req, path: path} if len(this.eventChan) > 4000 { this.Logger().Warn("The log event channel is going to be full, length: ", len(this.eventChan)) go this.eventHandler() } } func (this *EventManager) buildEventLogger(logType LogType) *proto.EventLogger { return &proto.EventLogger{ AppId: this.server.AppId(), LogType: uint32(logType), LogTime: util.NowUnix(), } } func (this *EventManager) ServerOperate(logType LogType, serverId, operate uint32) { this.reportEvent("/log/server/operate", &proto.MsgEventServerOperateReq{ EventLogger: this.buildEventLogger(logType), Operate: operate, Version: server.Version(), ProgramHash: server.ProgramHash, DataHash: server.DataHash, ConfigHash: server.ConfigHash, }) } func (this *EventManager) ServerOnline(logType LogType, serverId, create, online, offline, maxOnline uint32, maxOnlineTime int64) { this.reportEvent("/log/server/online", &proto.MsgEventServerOnlineReq{ EventLogger: this.buildEventLogger(logType), ServerId: serverId, Create: create, Online: online, MaxOnline: maxOnline, MaxOnlineTime: maxOnlineTime, }) } func (this *EventManager) buildEventPlayer(player *Player) *proto.EventPlayer { return &proto.EventPlayer{ Platform: player.Platform, Channel: player.Channel, ServerId: player.ServerId, UserId: player.UserId, RoleId: player.RoleId, Device: player.Temp.Device, Version: player.Temp.Version, } } func (this *EventManager) PlayerCommon(logType LogType, player *Player, numbers []int32, strings []string) { this.reportEvent("/log/player/common", &proto.MsgEventPlayerCommonReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), Numbers: numbers, Strings: strings, }) } func (this *EventManager) PlayerCreate(player *Player, logType LogType) { this.reportEvent("/log/player/create", &proto.MsgEventPlayerCreateReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), Name: player.RoleName, Gender: player.RoleGender, }) } func (this *EventManager) PlayerLogin(player *Player, logType LogType, optionType uint32, loginIp string) { this.reportEvent("/log/player/login", &proto.MsgEventPlayerLoginReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), OptionType: optionType, LoginIp: loginIp, }) } func (this *EventManager) PlayerRecharge(player *Player, logType LogType, rechargeId uint32, tipe uint32, subType uint32, count uint32, money uint32, status uint32) { this.reportEvent("/log/player/recharge", &proto.MsgEventPlayerRechargeReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), RechargeId: rechargeId, Type: tipe, SubType: subType, Count: count, Money: money, Status: status, }) } func (this *EventManager) PlayerLevelUpgrade(player *Player, logType LogType, preLevel uint32, curLevel uint32) { this.reportEvent("/log/player/level", &proto.MsgEventPlayerLevelReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), PreLevel: preLevel, CurLevel: curLevel, }) } func (this *EventManager) PlayerItemObtain(player *Player, logType LogType, itemId, itemNum uint32) { this.reportEvent("/log/player/item/obtain", &proto.MsgEventPlayerItemObtainReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), ItemId: itemId, ItemNum: itemNum, }) } func (this *EventManager) PlayerItemConsume(player *Player, logType LogType, itemId, itemNum uint32) { this.reportEvent("/log/player/item/Consume", &proto.MsgEventPlayerItemConsumeReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), ItemId: itemId, ItemNum: itemNum, }) } func (this *EventManager) PlayerMoneyObtain(player *Player, logType LogType, moneyType, amount, curAmount uint32) { this.reportEvent("/log/player/money/obtain", &proto.MsgEventPlayerMoneyObtainReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), MoneyType: moneyType, Amount: amount, CurAmount: curAmount, }) } func (this *EventManager) PlayerMoneyConsume(player *Player, logType LogType, moneyType uint32, amount, curAmount uint32) { this.reportEvent("/log/player/money/consume", &proto.MsgEventPlayerMoneyConsumeReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), MoneyType: moneyType, Amount: amount, CurAmount: curAmount, }) } func (this *EventManager) PlayerMailLog(player *Player, logType LogType, mailId uint64, mailType uint32, sentUserId uint64, sentServerId uint32, sentRoleId uint64, title, content string, createTime, expiration int64, args []string, items [][2]uint32) { var itemIds = make([]uint32, len(items)) var ItemNums = make([]uint32, len(items)) for i := range items { itemIds[i], ItemNums[i] = items[i][0], items[i][1] } this.reportEvent("/log/player/mail", &proto.MsgEventPlayerMailReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), MailId: mailId, MailType: mailType, SentUserId: sentUserId, SentServerId: sentServerId, SentRoleId: sentRoleId, Title: title, Content: content, CreateTime: createTime, Expiration: expiration, Args: args, ItemIds: itemIds, ItemNums: ItemNums, }) } func (this *EventManager) PlayerTaskLog(player *Player, logType LogType, taskId uint32, args1, args2, args3 []int) { this.reportEvent("/log/player/task", &proto.MsgEventPlayerTaskReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), TaskId: uint32(logType), Args1: args1, Args2: args2, Args3: args3, }) } func (this *EventManager) PlayerShopLog(player *Player, logType LogType, storeType, itemId, itemNum uint32, moneyType int32, moneyNum uint32) { this.reportEvent("/log/player/store", &proto.MsgEventPlayerStoreReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), StoreType: storeType, ItemId: itemId, ItemNum: itemNum, MoneyType: moneyType, MoneyNum: moneyNum, }) } func (this *EventManager) PlayerActivity(player *Player, logType LogType, tipe, status uint32) { this.reportEvent("/log/player/activity", &proto.MsgEventPlayerActivityReq{ EventLogger: this.buildEventLogger(logType), EventPlayer: this.buildEventPlayer(player), Type: tipe, Status: status, }) }