From b70343187364499cd4ba477047c75808c3895051 Mon Sep 17 00:00:00 2001 From: linquan <349589071@qq.com> Date: Mon, 15 Dec 2025 14:21:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=BF=E5=91=8A=E3=80=82=20=E5=85=AC?= =?UTF-8?q?=E5=91=8A=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/game/advertisement.go | 11 ++ api/v1/game/basicinfo.go | 11 ++ internal/controller/game_pub.go | 8 + internal/controller/game_server.go | 5 + internal/dao/advertisement_oceanegine_1.go | 27 +++ .../internal/advertisement_oceanegine_1.go | 99 ++++++++++ internal/dao/internal/game_ccd_version.go | 2 + .../model/do/advertisement_oceanegine_1.go | 29 +++ internal/model/do/game_ccd_version.go | 1 + .../entity/advertisement_oceanegine_1.go | 27 +++ internal/model/entity/game_ccd_version.go | 1 + internal/service/aliyunSms.go | 7 +- internal/service/email.go | 7 +- internal/service/tencentSms.go | 7 +- internal/serviceGame/advertisement.go | 173 +++++++++++++++++- internal/serviceGame/cron.go | 23 ++- internal/serviceGame/game_role.go | 6 + .../serviceGame/internal/advertisement.go | 88 +++++---- internal/serviceGame/internal/basicinfo.go | 49 +++++ internal/serviceGame/internal/dbinit.go | 45 +++++ internal/serviceGame/notice.go | 12 +- 21 files changed, 583 insertions(+), 55 deletions(-) create mode 100644 internal/dao/advertisement_oceanegine_1.go create mode 100644 internal/dao/internal/advertisement_oceanegine_1.go create mode 100644 internal/model/do/advertisement_oceanegine_1.go create mode 100644 internal/model/entity/advertisement_oceanegine_1.go diff --git a/api/v1/game/advertisement.go b/api/v1/game/advertisement.go index eb9f52b..67d542e 100644 --- a/api/v1/game/advertisement.go +++ b/api/v1/game/advertisement.go @@ -233,3 +233,14 @@ type GetCostReportRes struct { g.Meta `mime:"application/json"` List []CostReport `json:"list"` } + +type RefreshAdvertisementOceanegineReq struct { + g.Meta `path:"/advertise/refreshAdvertisementOceanegine" tags:"ad" method:"get" summary:"refreshAdvertisementOceanegine"` + AD string `p:"ad"` + Page int `p:"page"` + Limit int `p:"limit"` +} + +type RefreshAdvertisementOceanegineRes struct { + g.Meta `mime:"application/json"` +} diff --git a/api/v1/game/basicinfo.go b/api/v1/game/basicinfo.go index 4f1dd06..56bfdc0 100644 --- a/api/v1/game/basicinfo.go +++ b/api/v1/game/basicinfo.go @@ -251,3 +251,14 @@ type GameChangeNameReq struct { type GameChangeNameRes struct { g.Meta `mime:"application/json"` } + +type HarmonyChangeEventReq struct { + g.Meta `path:"/harmonyChangeEvent" tags:"game" method:"post" summary:"鸿蒙账号改变事件"` + Account string `p:"account"` + Server int `p:"server"` + Name string `p:"name"` +} + +type HarmonyChangeEventRes struct { + g.Meta `mime:"application/json"` +} diff --git a/internal/controller/game_pub.go b/internal/controller/game_pub.go index fff377f..0ab4daa 100644 --- a/internal/controller/game_pub.go +++ b/internal/controller/game_pub.go @@ -49,6 +49,7 @@ func (c *pubController) GetCCD(ctx context.Context, req *game.GetGameCCDReq) (re set["Android"] = struct{}{} set["Ios"] = struct{}{} set["Editor"] = struct{}{} + set["OpenHarmony"] = struct{}{} err = g.Try(ctx, func(ctx context.Context) { if _, ok := set[req.Platform]; !ok { @@ -69,6 +70,7 @@ func (c *pubController) GetCCD1(ctx context.Context, req *game.GetGameCCD1Req) ( set["Android"] = struct{}{} set["Ios"] = struct{}{} set["Editor"] = struct{}{} + set["OpenHarmony"] = struct{}{} err = g.Try(ctx, func(ctx context.Context) { if _, ok := set[req.Platform]; !ok { @@ -178,6 +180,12 @@ func (c *pubController) AdvertiseHugeAmount5(ctx context.Context, req *game.Adve return } +func (c *pubController) RefreshAdvertisementOceanegine(ctx context.Context, req *game.RefreshAdvertisementOceanegineReq) (res *game.RefreshAdvertisementOceanegineRes, err error) { + res = new(game.RefreshAdvertisementOceanegineRes) + res, err = serviceGame.Advertisement().RefreshAdvertisementOceanegine(ctx, req) + return +} + func (c *pubController) GetAccessToken(ctx context.Context, req *game.GetAccessTokenReq) (res *game.GetAccessTokenRes, err error) { res, err = serviceGame.Advertisement().GetAccessToken(ctx, req) return diff --git a/internal/controller/game_server.go b/internal/controller/game_server.go index 9f1e8d7..defacb5 100644 --- a/internal/controller/game_server.go +++ b/internal/controller/game_server.go @@ -152,3 +152,8 @@ func (c *serverController) SetOfficialView(ctx context.Context, req *game.SetOff res, err = serviceGame.GameManage().SetOfficialView(ctx, req) return } + +func (c *serverController) HarmonyChangeEvent(ctx context.Context, req *game.HarmonyChangeEventReq) (res *game.HarmonyChangeEventRes, err error) { + res, err = serviceGame.GameRole().HarmonyChangeEvent(ctx, req) + return +} diff --git a/internal/dao/advertisement_oceanegine_1.go b/internal/dao/advertisement_oceanegine_1.go new file mode 100644 index 0000000..5fc3ceb --- /dev/null +++ b/internal/dao/advertisement_oceanegine_1.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalAdvertisementOceanegine1Dao is internal type for wrapping internal DAO implements. +type internalAdvertisementOceanegine1Dao = *internal.AdvertisementOceanegine1Dao + +// advertisementOceanegine1Dao is the data access object for table advertisement_oceanegine_1. +// You can define custom methods on it to extend its functionality as you wish. +type advertisementOceanegine1Dao struct { + internalAdvertisementOceanegine1Dao +} + +var ( + // AdvertisementOceanegine1 is globally public accessible object for table advertisement_oceanegine_1 operations. + AdvertisementOceanegine1 = advertisementOceanegine1Dao{ + internal.NewAdvertisementOceanegine1Dao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/internal/advertisement_oceanegine_1.go b/internal/dao/internal/advertisement_oceanegine_1.go new file mode 100644 index 0000000..31a219d --- /dev/null +++ b/internal/dao/internal/advertisement_oceanegine_1.go @@ -0,0 +1,99 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdvertisementOceanegine1Dao is the data access object for table advertisement_oceanegine_1. +type AdvertisementOceanegine1Dao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdvertisementOceanegine1Columns // columns contains all the column names of Table for convenient usage. +} + +// AdvertisementOceanegine1Columns defines and stores column names for table advertisement_oceanegine_1. +type AdvertisementOceanegine1Columns struct { + Id string // + AdvIdfv string // + AdvAndroidId string // + CallbackParam string // + CallbackUrl string // + LastTouchTime string // + CDate string // + Idfa string // + Os string // 安卓:0 IOS:1 其他:3 + UnitId string // + Caid string // + Ip string // + Register string // 注册 + Active string // 激活 +} + +// advertisementOceanegine1Columns holds the columns for table advertisement_oceanegine_1. +var advertisementOceanegine1Columns = AdvertisementOceanegine1Columns{ + Id: "id", + AdvIdfv: "adv_idfv", + AdvAndroidId: "adv_android_id", + CallbackParam: "callback_param", + CallbackUrl: "callback_url", + LastTouchTime: "last_touch_time", + CDate: "c_date", + Idfa: "idfa", + Os: "os", + UnitId: "unitId", + Caid: "caid", + Ip: "ip", + Register: "register", + Active: "active", +} + +// NewAdvertisementOceanegine1Dao creates and returns a new DAO object for table data access. +func NewAdvertisementOceanegine1Dao() *AdvertisementOceanegine1Dao { + return &AdvertisementOceanegine1Dao{ + group: "default", + table: "advertisement_oceanegine_1", + columns: advertisementOceanegine1Columns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdvertisementOceanegine1Dao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdvertisementOceanegine1Dao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdvertisementOceanegine1Dao) Columns() AdvertisementOceanegine1Columns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdvertisementOceanegine1Dao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdvertisementOceanegine1Dao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdvertisementOceanegine1Dao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/game_ccd_version.go b/internal/dao/internal/game_ccd_version.go index a8f762e..d1d7aec 100644 --- a/internal/dao/internal/game_ccd_version.go +++ b/internal/dao/internal/game_ccd_version.go @@ -22,12 +22,14 @@ type GameCcdVersionDao struct { type GameCcdVersionColumns struct { Id string // Data string // + Name string // } // gameCcdVersionColumns holds the columns for table game_ccd_version. var gameCcdVersionColumns = GameCcdVersionColumns{ Id: "id", Data: "data", + Name: "name", } // NewGameCcdVersionDao creates and returns a new DAO object for table data access. diff --git a/internal/model/do/advertisement_oceanegine_1.go b/internal/model/do/advertisement_oceanegine_1.go new file mode 100644 index 0000000..ac92269 --- /dev/null +++ b/internal/model/do/advertisement_oceanegine_1.go @@ -0,0 +1,29 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdvertisementOceanegine1 is the golang structure of table advertisement_oceanegine_1 for DAO operations like Where/Data. +type AdvertisementOceanegine1 struct { + g.Meta `orm:"table:advertisement_oceanegine_1, do:true"` + Id interface{} // + AdvIdfv interface{} // + AdvAndroidId interface{} // + CallbackParam interface{} // + CallbackUrl interface{} // + LastTouchTime interface{} // + CDate *gtime.Time // + Idfa interface{} // + Os interface{} // 安卓:0 IOS:1 其他:3 + UnitId interface{} // + Caid interface{} // + Ip interface{} // + Register interface{} // 注册 + Active interface{} // 激活 +} diff --git a/internal/model/do/game_ccd_version.go b/internal/model/do/game_ccd_version.go index c32072a..3464750 100644 --- a/internal/model/do/game_ccd_version.go +++ b/internal/model/do/game_ccd_version.go @@ -13,4 +13,5 @@ type GameCcdVersion struct { g.Meta `orm:"table:game_ccd_version, do:true"` Id interface{} // Data interface{} // + Name interface{} // } diff --git a/internal/model/entity/advertisement_oceanegine_1.go b/internal/model/entity/advertisement_oceanegine_1.go new file mode 100644 index 0000000..db4f61d --- /dev/null +++ b/internal/model/entity/advertisement_oceanegine_1.go @@ -0,0 +1,27 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdvertisementOceanegine1 is the golang structure for table advertisement_oceanegine_1. +type AdvertisementOceanegine1 struct { + Id int64 `json:"id" description:""` + AdvIdfv string `json:"advIdfv" description:""` + AdvAndroidId string `json:"advAndroidId" description:""` + CallbackParam string `json:"callbackParam" description:""` + CallbackUrl string `json:"callbackUrl" description:""` + LastTouchTime int64 `json:"lastTouchTime" description:""` + CDate *gtime.Time `json:"cDate" description:""` + Idfa string `json:"idfa" description:""` + Os int `json:"os" description:"安卓:0 IOS:1 其他:3"` + UnitId int64 `json:"unitId" description:""` + Caid string `json:"caid" description:""` + Ip string `json:"ip" description:""` + Register int `json:"register" description:"注册"` + Active int `json:"active" description:"激活"` +} diff --git a/internal/model/entity/game_ccd_version.go b/internal/model/entity/game_ccd_version.go index 8011d9b..1510790 100644 --- a/internal/model/entity/game_ccd_version.go +++ b/internal/model/entity/game_ccd_version.go @@ -8,4 +8,5 @@ package entity type GameCcdVersion struct { Id int `json:"id" description:""` Data string `json:"data" description:""` + Name string `json:"name" description:""` } diff --git a/internal/service/aliyunSms.go b/internal/service/aliyunSms.go index 9ccc6c3..9c9e524 100644 --- a/internal/service/aliyunSms.go +++ b/internal/service/aliyunSms.go @@ -1,6 +1,7 @@ package service import ( + "context" "encoding/json" "errors" "fmt" @@ -44,7 +45,11 @@ var ( ) func init() { - aliYunSmsService.ConfigInit() + ctx := context.TODO() + mail, err := g.Cfg().Get(ctx, "game.state.aliYunSms") + if err == nil && mail.Int() == 1 { + aliYunSmsService.ConfigInit() + } } func (a *aliYunSmsServiceTmpl) ConfigInit() { diff --git a/internal/service/email.go b/internal/service/email.go index d62d9f1..9e89db8 100644 --- a/internal/service/email.go +++ b/internal/service/email.go @@ -1,6 +1,7 @@ package service import ( + "context" "crypto/tls" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" @@ -40,7 +41,11 @@ var ( ) func init() { - emailService.ConfigInit() + ctx := context.TODO() + mail, err := g.Cfg().Get(ctx, "game.state.email") + if err == nil && mail.Int() == 1 { + emailService.ConfigInit() + } } func (a *emailServiceTmpl) ConfigInit() { diff --git a/internal/service/tencentSms.go b/internal/service/tencentSms.go index 086e604..d342feb 100644 --- a/internal/service/tencentSms.go +++ b/internal/service/tencentSms.go @@ -1,6 +1,7 @@ package service import ( + "context" "fmt" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" @@ -39,7 +40,11 @@ var ( ) func init() { - tencentSmsService.ConfigInit() + ctx := context.TODO() + mail, err := g.Cfg().Get(ctx, "game.state.tencentSms") + if err == nil && mail.Int() == 1 { + tencentSmsService.ConfigInit() + } } func (a *tencentSmsServiceTmpl) ConfigInit() { diff --git a/internal/serviceGame/advertisement.go b/internal/serviceGame/advertisement.go index 05d104f..f15bdef 100644 --- a/internal/serviceGame/advertisement.go +++ b/internal/serviceGame/advertisement.go @@ -4,10 +4,13 @@ import ( "context" "encoding/json" "errors" + "log" + "math" "strconv" "tyj_admin/api/v1/game" "tyj_admin/internal/dao" "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" "tyj_admin/internal/serviceGame/internal" ) @@ -20,6 +23,7 @@ type IAdvertisement interface { AdvertiseHugeAmount1(ctx context.Context, androidId, idfa, os, callBack, timestamp, caid, ip string) (err error) GetAccessToken(ctx context.Context, req *game.GetAccessTokenReq) (res *game.GetAccessTokenRes, err error) RefreshAccessToken(ctx context.Context, req *game.RefreshAccessTokenReq) (res *game.RefreshAccessTokenRes, err error) + RefreshAdvertisementOceanegine(ctx context.Context, req *game.RefreshAdvertisementOceanegineReq) (res *game.RefreshAdvertisementOceanegineRes, err error) } type advertisementImpl struct { @@ -69,10 +73,13 @@ func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId, if osInt != 0 && osInt != 1 { return errors.New("系统类型错误!") } - if osInt == 1 && idfa == "__IDFA__" { + if callBack == "__CALLBACK_PARAM__" { return } - if osInt == 0 && androidId == "__ANDROIDID__" { + if osInt == 1 && caidList == "" && (idfa == "__IDFA__" || idfa == "00000000-0000-0000-0000-000000000000") { + return + } + if osInt == 0 && (androidId == "__ANDROIDID__" || androidId == "") { return } caid := "" @@ -88,7 +95,48 @@ func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId, } } } - _, err = dao.AdvertisementOceanegine.Ctx(ctx).Insert(do.AdvertisementOceanegine{ + model := dao.AdvertisementOceanegine1.Ctx(ctx) + lastTouchTime, _ := strconv.ParseInt(timestamp, 10, 64) + adDatas := []entity.AdvertisementOceanegine1{} + if osInt == 0 { + _ = model.Where("adv_android_id=?", androidId).Where("os=?", os).Scan(&adDatas) + } else if osInt == 1 { + if caidList != "" { + var list []map[string]string + _ = json.Unmarshal([]byte(caidList), &list) + for _, v := range list { + adDatas1 := []entity.AdvertisementOceanegine1{} + _ = model.Where("caid=?", v["caid"]).Where("os=?", os).Scan(&adDatas1) + if len(adDatas) > 0 { + adDatas = append(adDatas, adDatas1...) + } + } + } + if idfa != "" { + adDatas1 := []entity.AdvertisementOceanegine1{} + _ = model.Where("idfa=?", idfa).Where("os=?", os).Scan(&adDatas1) + if len(adDatas1) > 0 { + adDatas = append(adDatas, adDatas1...) + } + } + } + if len(adDatas) > 0 { + var adData entity.AdvertisementOceanegine1 + for _, v := range adDatas { + if adData.Id == 0 || v.LastTouchTime > adData.LastTouchTime || (v.LastTouchTime == adData.LastTouchTime && v.CDate.Unix() > adData.CDate.Unix()) { + adData = v + } + } + if adData.LastTouchTime > lastTouchTime { + err = errors.New("不是最后一次!") + return + } + + _, err = model.WherePri(adData.Id).Update(do.AdvertisementOceanegine1{CallbackParam: callBack, LastTouchTime: timestamp, Caid: caid}) + return + } + + _, err = dao.AdvertisementOceanegine1.Ctx(ctx).Insert(do.AdvertisementOceanegine1{ AdvAndroidId: androidId, Idfa: idfa, Os: os, @@ -110,3 +158,122 @@ func (g *advertisementImpl) RefreshAccessToken(ctx context.Context, req *game.Re internal.RefreshAccessToken(ctx) return } + +func (g *advertisementImpl) RefreshAdvertisementOceanegine(ctx context.Context, req *game.RefreshAdvertisementOceanegineReq) (res *game.RefreshAdvertisementOceanegineRes, err error) { + if req.AD != "idfa" && req.AD != "caid" && req.AD != "advAndroidId" && req.AD != "advIdfv" { + return + } + adDatas := []entity.AdvertisementOceanegine{} + adDataMaps := map[string]entity.AdvertisementOceanegine{} + model := dao.AdvertisementOceanegine.Ctx(ctx) + idList := [][]int64{} + ids := []int64{} + deleteCount := 50000 + + limit := 1000000 + if req.Limit > 0 { + limit = req.Limit + } + log.Printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&& RefreshAdvertisementOceanegine start %s &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", req.AD) + if req.AD == "idfa" { + _ = model.Where("idfa <> '' ").Where("os=?", 1).Limit(limit).Offset(req.Page).Scan(&adDatas) + + if len(adDatas) > 0 { + for _, v := range adDatas { + if v.Os == 0 { + continue + } + if v.Idfa == "00000000-0000-0000-0000-000000000000" || v.Idfa == "__IDFA__" { + ids = append(ids, v.Id) + } else if adDataMaps[v.Idfa].Id == 0 { + adDataMaps[v.Idfa] = v + } else if v.LastTouchTime > adDataMaps[v.Idfa].LastTouchTime || + (v.LastTouchTime == adDataMaps[v.Idfa].LastTouchTime && v.CDate.Unix() > adDataMaps[v.Idfa].CDate.Unix()) { + ids = append(ids, adDataMaps[v.Idfa].Id) + adDataMaps[v.Idfa] = v + } + if len(ids) > deleteCount { + idList = append(idList, ids) + ids = []int64{} + } + } + } + } else if req.AD == "caid" { + _ = model.Where("caid <> ''").Where("os=?", 1).Limit(limit).Offset(req.Page).Scan(&adDatas) + + if len(adDatas) > 0 { + for _, v := range adDatas { + if v.Os == 0 { + continue + } + if v.Caid == "00000000-0000-0000-0000-000000000000" || v.Caid == "" { + ids = append(ids, v.Id) + } else if adDataMaps[v.Caid].Id == 0 { + adDataMaps[v.Caid] = v + } else if v.LastTouchTime > adDataMaps[v.Caid].LastTouchTime || + (v.LastTouchTime == adDataMaps[v.Caid].LastTouchTime && v.CDate.Unix() > adDataMaps[v.Caid].CDate.Unix()) { + ids = append(ids, adDataMaps[v.Caid].Id) + adDataMaps[v.Caid] = v + } + if len(ids) > deleteCount { + idList = append(idList, ids) + ids = []int64{} + } + } + } + } else if req.AD == "advAndroidId" { + _ = model.Where("adv_android_id <> ''").Where("os=?", 0).Limit(limit).Offset(req.Page).Scan(&adDatas) + + if len(adDatas) > 0 { + for _, v := range adDatas { + if v.Os == 1 { + continue + } + if v.AdvAndroidId == "00000000-0000-0000-0000-000000000000" || v.AdvAndroidId == "__ANDROIDID__" { + ids = append(ids, v.Id) + } else if adDataMaps[v.AdvAndroidId].Id == 0 { + adDataMaps[v.AdvAndroidId] = v + } else if v.LastTouchTime > adDataMaps[v.AdvAndroidId].LastTouchTime || + (v.LastTouchTime == adDataMaps[v.AdvAndroidId].LastTouchTime && v.CDate.Unix() > adDataMaps[v.AdvAndroidId].CDate.Unix()) { + ids = append(ids, adDataMaps[v.AdvAndroidId].Id) + adDataMaps[v.AdvAndroidId] = v + } + if len(ids) > deleteCount { + idList = append(idList, ids) + ids = []int64{} + } + } + } + } else if req.AD == "advIdfv" { + _ = model.Where("adv_idfv <> ''").Where("os=?", 1).Limit(limit).Offset(req.Page).Scan(&adDatas) + + if len(adDatas) > 0 { + for _, v := range adDatas { + if v.Os == 0 { + continue + } + if adDataMaps[v.AdvIdfv].Id == 0 { + adDataMaps[v.AdvIdfv] = v + } else if v.LastTouchTime > adDataMaps[v.AdvIdfv].LastTouchTime || + (v.LastTouchTime == adDataMaps[v.AdvIdfv].LastTouchTime && v.CDate.Unix() > adDataMaps[v.AdvIdfv].CDate.Unix()) { + ids = append(ids, adDataMaps[v.AdvIdfv].Id) + adDataMaps[v.AdvIdfv] = v + } + if len(ids) > deleteCount { + idList = append(idList, ids) + ids = []int64{} + } + } + } + } + if len(ids) > 0 { + idList = append(idList, ids) + } + if len(idList) > 0 { + for _, v := range idList { + _, _ = model.Where("id in (?)", v).Delete() + } + } + log.Printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&& RefreshAdvertisementOceanegine over %s ids: %d idList: %d count: %f &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&", req.AD, len(ids), len(idList), math.Max(0, float64(len(idList)-1))*float64(deleteCount)+float64(len(ids))) + return +} diff --git a/internal/serviceGame/cron.go b/internal/serviceGame/cron.go index 2d078f6..13bccb4 100644 --- a/internal/serviceGame/cron.go +++ b/internal/serviceGame/cron.go @@ -21,12 +21,12 @@ var ( ) func init() { + ctx := context.TODO() //加载游戏相关配置 + ticker := time.NewTicker(1 * time.Second) notices = []entity.GameNoticeLog{} mails = []entity.Mail{} - //count := 1 - ctx := context.TODO() model := dao.GameNoticeLog.Ctx(ctx) model = model.Where("send_time > ", gtime.TimestampMilli()) _ = model.Scan(¬ices) @@ -37,14 +37,23 @@ func init() { for { //从定时器中获取数据 t := <-ticker.C - gameCronService.Cron(t.UnixMilli()) - gameCronService.MailCron(t.UnixMilli()) - gameCronService.CronAdvertisement(ctx, t.Unix()) - gameCronService.CronDay(ctx, t.Unix()) + if internal.SwitchState.Mail == 1 { + gameCronService.Cron(t.UnixMilli()) + gameCronService.MailCron(t.UnixMilli()) + } + //adv, err := g.Cfg().Get(ctx, "game.state.adv") + //if err == nil && adv.Int() == 1 { + // gameCronService.CronAdvertisement(ctx, t.Unix()) + //} + if internal.SwitchState.Online == 1 { + gameCronService.CronDay(ctx, t.Unix()) + } } }() - internal.LogInit() + if internal.SwitchState.Online == 1 { + internal.LogInit() + } } type IGameCron interface { diff --git a/internal/serviceGame/game_role.go b/internal/serviceGame/game_role.go index 9514f11..1ff1887 100644 --- a/internal/serviceGame/game_role.go +++ b/internal/serviceGame/game_role.go @@ -25,6 +25,7 @@ type IGameRole interface { GameUserDel(ctx context.Context, req *game.UserDelReq) (res *game.UserDelRes, err error) GetLoginOutGm(ctx context.Context, req *game.GetLoginOutGmReq) (res *game.GetLoginOutGmRes, err error) GameChangeName(ctx context.Context, req *game.GameChangeNameReq) (res *game.GameChangeNameRes, err error) + HarmonyChangeEvent(ctx context.Context, req *game.HarmonyChangeEventReq) (res *game.HarmonyChangeEventRes, err error) } type gameRoleImpl struct { @@ -149,3 +150,8 @@ func (s *gameRoleImpl) GameChangeName(ctx context.Context, req *game.GameChangeN res, err = internal.GameChangeName(ctx, req) return } + +func (s *gameRoleImpl) HarmonyChangeEvent(ctx context.Context, req *game.HarmonyChangeEventReq) (res *game.HarmonyChangeEventRes, err error) { + res, err = internal.HarmonyChangeEvent(ctx, req) + return +} diff --git a/internal/serviceGame/internal/advertisement.go b/internal/serviceGame/internal/advertisement.go index ccb9847..549f4f2 100644 --- a/internal/serviceGame/internal/advertisement.go +++ b/internal/serviceGame/internal/advertisement.go @@ -115,13 +115,13 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT "package_name": req.PackageName, "customer_active_time": fmt.Sprint(time.Now().UnixMilli()), // 毫秒时间戳,客户激活归因时间点 } - var adData []entity.AdvertisementOceanegine - model := dao.AdvertisementOceanegine.Ctx(ctx).Order("last_touch_time desc") + var adDatas []entity.AdvertisementOceanegine1 + model := dao.AdvertisementOceanegine1.Ctx(ctx) if req.Platform == "android" { - if req.AndroidId != "" && req.AndroidId != "00000000-0000-0000-0000-000000000000" { - _ = model.Where("adv_android_id=?", req.AndroidId).Page(1, 1).Scan(&adData) + if req.AndroidId != "" && req.AndroidId != "__ANDROIDID__" && req.AndroidId != "00000000-0000-0000-0000-000000000000" { + _ = model.Where("adv_android_id=?", req.AndroidId).Where("os=?", 0).Scan(&adDatas) } - if len(adData) == 0 { + if len(adDatas) == 0 { log.Printf("AttributionHugeAmount: adData is nil %s", gjson.MustEncodeString(req)) err = errors.New("account is nil") return @@ -129,20 +129,20 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT data["android_id"] = req.AndroidId } else if req.Platform == "ios" { if req.Idfa != "" && req.Idfa != "00000000-0000-0000-0000-000000000000" { - _ = model.Where("idfa=?", req.Idfa).Page(1, 1).Scan(&adData) + _ = model.Where("idfa=?", req.Idfa).Where("os=?", 1).Scan(&adDatas) } - if len(adData) == 0 { + if len(adDatas) == 0 { if req.Caid != "" { var list []map[string]string _ = json.Unmarshal([]byte(req.Caid), &list) for _, v := range list { - _ = model.Where("caid=?", v["caid"]).Page(1, 1).Scan(&adData) - if len(adData) > 0 { + _ = model.Where("caid=?", v["caid"]).Where("os=?", 1).Scan(&adDatas) + if len(adDatas) > 0 { break } } } - if len(adData) == 0 { + if len(adDatas) == 0 { log.Printf("AttributionHugeAmount: adData is nil %s", gjson.MustEncodeString(req)) err = errors.New("account is nil") return @@ -153,7 +153,17 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT err = errors.New("platform is error " + req.Platform) return } - if len(adData) == 0 || adData[0].CallbackParam == "" { + if len(adDatas) == 0 { + err = errors.New("无广告!") + return + } + var adData entity.AdvertisementOceanegine1 + for _, v := range adDatas { + if adData.Id == 0 || v.LastTouchTime > adData.LastTouchTime || (v.LastTouchTime == adData.LastTouchTime && v.CDate.Unix() > adData.CDate.Unix()) { + adData = v + } + } + if adData.CallbackParam == "" { err = errors.New("无广告!") return } @@ -188,11 +198,11 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT // advIdfv = req.Idfv //} lastTouchTime := resJson.Get("last_touch_time").Int64() * 1000 - if adData[0].LastTouchTime == lastTouchTime { + if adData.LastTouchTime > lastTouchTime { err = errors.New("lastTouchTime repeat") return } - advertiseData := do.AdvertisementOceanegine{AdvAndroidId: androidId, Idfa: idfa, AdvIdfv: advIdfv, + advertiseData := do.AdvertisementOceanegine1{AdvAndroidId: androidId, Idfa: idfa, AdvIdfv: advIdfv, CallbackUrl: callbackUrl, CallbackParam: callbackParam, LastTouchTime: lastTouchTime, UnitId: req.UnitId} if req.Platform == "android" { advertiseData.Os = 0 @@ -212,7 +222,7 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT } } - _, err = dao.AdvertisementOceanegine.Ctx(ctx).Insert(advertiseData) + _, err = dao.AdvertisementOceanegine1.Ctx(ctx).WherePri(adData.Id).Update(advertiseData) } else { err = errors.New("获取失败") return @@ -223,63 +233,66 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT func ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSHARes, err error) { //log.Printf("ConversionHugeAmount: %s", gjson.MustEncodeString(req)) - var adData []entity.AdvertisementOceanegine + var adDatas []entity.AdvertisementOceanegine1 device := map[string]interface{}{ "platform": req.Platform, } - model := dao.AdvertisementOceanegine.Ctx(ctx).Order("last_touch_time desc") + model := dao.AdvertisementOceanegine1.Ctx(ctx) if req.Platform == "android" { if req.Id != "" && req.Id != "00000000-0000-0000-0000-000000000000" { - _ = model.Where("adv_android_id=?", req.Id).Page(1, 1).Scan(&adData) - } - if len(adData) == 0 { - log.Printf("ConversionHugeAmount: adData is nil %s", gjson.MustEncodeString(req)) - err = errors.New("account is nil") - return + _ = model.Where("adv_android_id=?", req.Id).Where("os=?", 0).Scan(&adDatas) } + device["android_id"] = req.Id } else if req.Platform == "ios" { if req.Idfa != "" && req.Idfa != "00000000-0000-0000-0000-000000000000" { - _ = model.Where("idfa=?", req.Idfa).Page(1, 1).Scan(&adData) + _ = model.Where("idfa=?", req.Idfa).Where("os=?", 1).Scan(&adDatas) } - if len(adData) == 0 { + if len(adDatas) == 0 { if req.Caid != "" { var list []map[string]string _ = json.Unmarshal([]byte(req.Caid), &list) for _, v := range list { - _ = model.Where("caid=?", v["caid"]).Page(1, 1).Scan(&adData) - if len(adData) > 0 { + _ = model.Where("caid=?", v["caid"]).Where("os=?", 1).Scan(&adDatas) + if len(adDatas) > 0 { break } } } - if len(adData) == 0 { - log.Printf("ConversionHugeAmount: adData is nil %s", gjson.MustEncodeString(req)) - err = errors.New("account is nil") - return - } } device["idfv"] = req.Id } else { err = errors.New("platform is error " + req.Platform) return } - if adData[0].CallbackParam == "" { + + if len(adDatas) == 0 { + log.Printf("ConversionHugeAmount: adData is nil %s", gjson.MustEncodeString(req)) + err = errors.New("account is nil") + return + } + var adData entity.AdvertisementOceanegine1 + for _, v := range adDatas { + if adData.Id == 0 || v.LastTouchTime > adData.LastTouchTime || (v.LastTouchTime == adData.LastTouchTime && v.CDate.Unix() > adData.CDate.Unix()) { + adData = v + } + } + if adData.CallbackParam == "" { err = errors.New("callbackParam is nil") return } - if req.EventType == consts.EventType_Active && adData[0].Active == 1 { + if req.EventType == consts.EventType_Active && adData.Active == 1 { err = errors.New("already activated !") return } - if req.EventType == consts.EventType_Register && adData[0].Register == 1 { + if req.EventType == consts.EventType_Register && adData.Register == 1 { err = errors.New("already register!") return } ad := map[string]interface{}{ - "callback": adData[0].CallbackParam, + "callback": adData.CallbackParam, } ct := map[string]interface{}{ "ad": ad, @@ -313,14 +326,14 @@ func ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSH if resJson != nil && resJson.Get("code").Int() != 0 { err = errors.New(resJson.Get("message").String()) } else if resJson.Get("code").Int() == 0 { - saveData := do.AdvertisementOceanegine{} + saveData := do.AdvertisementOceanegine1{} if req.EventType == consts.EventType_Active { saveData.Active = 1 } if req.EventType == consts.EventType_Register { saveData.Register = 1 } - dao.AdvertisementOceanegine.Ctx(ctx).WherePri(adData[0].Id).Update(saveData) + dao.AdvertisementOceanegine1.Ctx(ctx).WherePri(adData.Id).Update(saveData) } return } @@ -372,7 +385,6 @@ func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) { PackageName: req.PackageName, Caid: req.Caid, Idfa: req.Idfa, - //UnitId: req.UnitId, } if req.Platform == "android" { req1.AndroidId = req.Id diff --git a/internal/serviceGame/internal/basicinfo.go b/internal/serviceGame/internal/basicinfo.go index 52b1525..efa44d6 100644 --- a/internal/serviceGame/internal/basicinfo.go +++ b/internal/serviceGame/internal/basicinfo.go @@ -1288,6 +1288,22 @@ func GameChangeName(ctx context.Context, req *game.GameChangeNameReq) (res *game return } +func HarmonyChangeEvent(ctx context.Context, req *game.HarmonyChangeEventReq) (res *game.HarmonyChangeEventRes, err error) { + res = new(game.HarmonyChangeEventRes) + + g.Try(ctx, func(ctx context.Context) { + model := dao.GameUnit.Ctx(ctx) + unitList := []entity.GameUnit{} + err = model.Where("account=?", "000008000000"+req.Account).Scan(&unitList) + + for _, v := range unitList { + sendDeleteAccountToClient(ctx, v.Server, v.Uid) + } + }) + + return +} + func sendMsgToClient(ctx context.Context, serverId int, uid int64, name string) { ip := ServerConfig[fmt.Sprint(serverId)] url := "http://" + ip + "/updateName?unitId=" + fmt.Sprint(uid) + "&name=" + url.QueryEscape(name) @@ -1347,3 +1363,36 @@ func sendMsgToClient(ctx context.Context, serverId int, uid int64, name string) return } + +func sendDeleteAccountToClient(ctx context.Context, serverId int, uid int64) { + ip := ServerConfig[fmt.Sprint(serverId)] + url := "http://" + ip + "/deleteAccount?unitId=" + fmt.Sprint(uid) + bytes := g.Client().GetBytes(ctx, url) + src := string(bytes) + if g.IsEmpty(src) { + g.Log().Printf(ctx, "%d updateName: 空回调,发送失败", serverId) + return + } + + srcCharset := "UTF-8" + tmp, _ := gcharset.ToUTF8(srcCharset, src) + json, err := gjson.DecodeToJson(tmp) + if err != nil { + g.Log().Printf(ctx, "%d updateName err: %s", serverId, err) + return + } + fmt.Println("GetOnlineList - json: ", tmp, gjson.MustEncodeString(json)) + if json.Get("Error").Int() == 200 { + filter := bson.M{"_id": uid} + mongo, ok := MongoDatabaseList[fmt.Sprint(serverId)] + if !ok { + return + } + + err = mongo.Collection("Account").Remove(ctx, filter) + g.Log().Printf(ctx, "%d updateName success err: %s", serverId, err) + return + } + g.Log().Printf(ctx, "%d updateName err: 获取失败", serverId) + return +} diff --git a/internal/serviceGame/internal/dbinit.go b/internal/serviceGame/internal/dbinit.go index a2b15dd..44a3408 100644 --- a/internal/serviceGame/internal/dbinit.go +++ b/internal/serviceGame/internal/dbinit.go @@ -27,6 +27,15 @@ type OceanengineMap struct { Secret string `json:"secret"` } +type StateMap struct { + Mail int `json:"mail"` + Online int `json:"online"` + TencentSms int `json:"tencentSms"` + AliYunSms int `json:"aliYunSms"` + Email int `json:"email"` + Adv int `json:"adv"` +} + var ( MongoClientList map[string]*qmgo.QmgoClient MongoDatabaseList map[string]*qmgo.Database @@ -41,6 +50,7 @@ var ( CallbackKey string Webhook string Oceanengine OceanengineMap + SwitchState StateMap ) func init() { @@ -51,6 +61,7 @@ func init() { // return //} MongoInit(ctx) + SwitchStateInit(ctx) InitServer(ctx) InitChannel(ctx) @@ -218,3 +229,37 @@ func OceanengineInit(ctx context.Context) { Oceanengine.Appid = oceanengine["appid"] Oceanengine.Secret = oceanengine["secret"] } + +func SwitchStateInit(ctx context.Context) { + c, err := g.Cfg().Get(ctx, "game.state.mail") + if err != nil { + return + } + SwitchState.Mail = c.Int() + onlineState, err := g.Cfg().Get(ctx, "game.state.online") + if err != nil { + return + } + SwitchState.Online = onlineState.Int() + tencentSms, err := g.Cfg().Get(ctx, "game.state.tencentSms") + if err != nil { + return + } + SwitchState.TencentSms = tencentSms.Int() + aliYunSms, err := g.Cfg().Get(ctx, "game.state.aliYunSms") + if err != nil { + return + } + SwitchState.AliYunSms = aliYunSms.Int() + email, err := g.Cfg().Get(ctx, "game.state.email") + if err != nil { + return + } + SwitchState.Email = email.Int() + adv, err := g.Cfg().Get(ctx, "game.state.adv") + if err != nil { + return + } + SwitchState.Adv = adv.Int() + +} diff --git a/internal/serviceGame/notice.go b/internal/serviceGame/notice.go index 0b1771a..811541a 100644 --- a/internal/serviceGame/notice.go +++ b/internal/serviceGame/notice.go @@ -45,8 +45,12 @@ func (c *gameNoticeImpl) GetNotice(ctx context.Context, req *game.GetNoticeReq) res = new(game.GetNoticeRes) g.Try(ctx, func(ctx context.Context) { model := dao.GameNotice.Ctx(ctx) - model = model.Where("notice_type = ?", req.NoticeType) - model = model.Where("channel=? ", req.Channel) + model = model.Where("notice_type=?", req.NoticeType) + if req.NoticeType == 5 { + model = model.OrderDesc("c_date") + } else { + model = model.Where("channel=? ", req.Channel) + } var noticeList []*entity.GameNotice err = model.Scan(¬iceList) @@ -103,7 +107,7 @@ func (c *gameNoticeImpl) GetGameNotice(ctx context.Context, req *game.GetGameNot return } if req.NoticeType == consts.Notice_Type_Pop { - model = model.Where("server=? ", req.ServerId) + model = model.Where("serverId=? ", req.ServerId) } else { model = model.Where("channel=? ", req.Channel) } @@ -114,7 +118,7 @@ func (c *gameNoticeImpl) GetGameNotice(ctx context.Context, req *game.GetGameNot model = dao.GameNotice.Ctx(ctx) model = model.Where("notice_type = ?", req.NoticeType) if req.NoticeType == consts.Notice_Type_Pop { - model = model.Where("server=? ", 0) + model = model.Where("serverId=? ", 0) } else { model = model.Where("channel=? ", "") }