活动优化

This commit is contained in:
hahwu 2026-03-23 14:57:32 +08:00
commit f3ce3249cc
16 changed files with 222 additions and 197 deletions

View File

@ -1,24 +1,52 @@
package backend
func Start() {
// addr := net.JoinHostPort("localhost", "9090")
// handler := NewGameServiceHandler()
import (
"context"
"net"
"server/conf"
"server/game"
"server/msg"
"server/pkg/github.com/name5566/leaf/log"
// //创建处理器
// processor := backend.NewGameAdminServiceProcessor(handler)
"google.golang.org/grpc"
)
// transportFactory := thrift.NewTBufferedTransportFactory(8192)
// protocolFactory := thrift.NewTBinaryProtocolFactoryConf(&thrift.TConfiguration{})
// tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
// if err != nil {
// fmt.Printf("Failed to resolve address %s: %v\n", addr, err)
// return
// }
// serverTransport := thrift.NewTServerSocketFromAddrTimeout(tcpAddr, 0)
// server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory)
// fmt.Printf("Starting the server on %s...\n", addr)
// if err := server.Serve(); err != nil {
// fmt.Printf("Error starting the server: %v\n", err)
// }
type backendServer struct {
msg.UnimplementedBackendServer
}
func (s *backendServer) ReloadActivity(ctx context.Context, req *msg.ReqActivityCfgReload) (*msg.ResActivityCfgReload, error) {
log.Debug("Received ReloadActivity request: %v", req)
game.AcitivityCfgReload()
return nil, nil
}
func (s *backendServer) OrderShipping(ctx context.Context, req *msg.ReqOrderShipping) (*msg.ResOrderShipping, error) {
log.Debug("Received OrderShipping request: %v", req)
res, err := game.AdminShipping(req)
if err != nil {
log.Error("OrderShipping error: %v", err)
return nil, err
}
return res, nil
}
func Start() {
if conf.Server.RPCAddr == "" {
log.Debug("RPC server address not configured, skipping gRPC server startup")
return
}
lis, err := net.Listen("tcp", conf.Server.RPCAddr)
if err != nil {
log.Error("failed to listen: %v", err)
return
}
s := grpc.NewServer()
msg.RegisterBackendServer(s, &backendServer{})
log.Debug("gRPC server listening on %s", conf.Server.RPCAddr)
if err := s.Serve(lis); err != nil {
log.Error("server exited with error: %v", err)
}
}

View File

@ -1,135 +0,0 @@
package backend
// type GameServiceHandler struct{}
// func NewGameServiceHandler() *GameServiceHandler {
// return &GameServiceHandler{}
// }
// func (h *GameServiceHandler) ReqPlayerInfo(ctx context.Context, id int64) (*backend.ResAdminInfo, error) {
// player := game.G_GameLogicPtr.GetPlayer(int64(id))
// online := true
// if player == nil {
// player = new(game.Player)
// player.M_DwUin = int64(id)
// player.InitPlayerOnly()
// player.ZeroUpdate(nil)
// online = false
// }
// res := &backend.ResAdminInfo{}
// res.Name = player.GetBaseMod().NickName
// res.UID = player.M_DwUin
// res.AreaId = int32(player.GetDecorateMod().GetAreaId())
// res.Face = int32(player.GetFaceMod().SetId)
// res.Charge = player.GetChargeMod().Charge
// res.MaxCharge = player.GetChargeMod().MaxCharge
// res.Level = int32(player.GetPlayerBaseMod().GetLevel())
// res.Diamond = int32(player.GetPlayerBaseMod().GetDiamond())
// res.Star = int32(player.GetPlayerBaseMod().GetStar())
// res.Energy = int32(player.GetPlayerBaseMod().GetEnergy())
// res.UserName = player.GetPlayerBaseMod().GetName()
// res.LoginTime = player.GetBaseMod().LoginTime
// res.Cumulative = int32(player.GetBaseMod().Cumulative)
// res.RegisterTime = int32(player.GetPlayerBaseMod().GetRegisterTime())
// res.TodayCumulative = int32(player.GetBaseMod().TodayCumulative)
// res.Ban = int8(db.GetPlayerBan(player.GetBaseMod().Account))
// if online {
// res.Cumulative = int32(int64(player.GetBaseMod().Cumulative) + GoUtil.Now() - int64(player.GetBaseMod().LoginTime))
// res.TodayCumulative = int32(int64(player.GetBaseMod().TodayCumulative) + GoUtil.Now() - int64(player.GetBaseMod().LoginTime))
// }
// res.Code = player.GetBaseMod().AddCode
// res.ChessMap = player.GetChessMod().ChessMap
// resActLog := make([]*backend.Actlog, 0, len(player.GetFriendMod().ActivityLog))
// for _, log := range player.GetFriendMod().ActivityLog {
// resActLog = append(resActLog, &backend.Actlog{
// Type: int8(log.Type),
// Time: log.Time,
// Param: log.Param,
// })
// }
// res.ActLog = resActLog
// friendList := player.GetFriendMod().NewFriendList
// type friendInfo struct {
// Uid int64
// NickName string
// Avatar int
// Level int
// LogoutTime int64
// LoginTime int64
// }
// resFriendList := make([]*backend.FriendInfo, 0, len(friendList))
// for v := range friendList {
// ps := game.G_GameLogicPtr.GetSimplePlayerByUid(v)
// if ps == nil {
// continue
// }
// resFriendList = append(resFriendList, &backend.FriendInfo{
// UID: int64(v),
// NickName: ps.Name,
// Face: int32(ps.Face),
// Level: int32(ps.Level),
// LogoutTime: ps.Loginout,
// LoginTime: ps.Login,
// })
// }
// res.FriendList = resFriendList
// OrderMap := make(map[int32]*backend.OrderInfo)
// Index := 0
// for k, v := range player.GetOrderMod().OrderList {
// OrderMap[int32(Index)] = &backend.OrderInfo{
// ID: int32(k),
// Type: int32(v.Type),
// Time: v.Timestamp,
// ChessId: GoUtil.IntSliceToString(v.MergeId),
// Diff: int8(v.Diff),
// }
// Index++
// }
// res.OrderList = OrderMap
// return res, nil
// }
// func (h *GameServiceHandler) ReqReloadServerMail(ctx context.Context) (*backend.ResMessage, error) {
// game.G_GameLogicPtr.MailMgrCall(&msg.Msg{Type: msg.HANDLE_TYPE_MAIL_RELOAD})
// game.G_GameLogicPtr.NotifyAll(&msg.Msg{Type: msg.HANDLE_TYPE_MAIL})
// log.Debug("ReqReloadServerMail success")
// return &backend.ResMessage{
// Code: 0,
// }, nil
// }
// func (h *GameServiceHandler) ReqConfigReload(ctx context.Context) (*backend.ResMessage, error) {
// gamedata.Reload()
// return &backend.ResMessage{
// Code: 0,
// }, nil
// }
// func (h *GameServiceHandler) ReqAdminGm(ctx context.Context, uid int64, command string) (*backend.ResMessage, error) {
// player := game.G_GameLogicPtr.GetPlayer(uid)
// if player == nil {
// return &backend.ResMessage{
// Code: 1,
// Msg: "player not online",
// }, nil
// }
// player.Lock()
// defer player.UnLock()
// err := game.ReqGmCommand_(player, command)
// if err != nil {
// return &backend.ResMessage{
// Code: 1,
// Msg: err.Error(),
// }, nil
// }
// return &backend.ResMessage{
// Code: 0,
// }, nil
// }
// func (h *GameServiceHandler) ReqAdminBan(ctx context.Context, uid int64, banTime int64) (*backend.ResMessage, error) {
// db.UpdatePlayerBan(uid, banTime)
// return &backend.ResMessage{
// Code: 0,
// }, nil
// }

View File

@ -1,11 +1,9 @@
package activityCfg
import (
languageCfg "server/conf/language"
"server/game/mod/item"
GoUtil "server/game_util"
"server/gamedata"
"server/msg"
"server/pkg/github.com/name5566/leaf/log"
"strconv"
)
@ -136,16 +134,6 @@ func GetActivityRewardItems(ActId int) []*item.Item {
return nil
}
func GetActivityTitle(ActId int) (string, string) {
data, err := gamedata.GetDataByIntKey(CFG_ACTIVITY, ActId)
if err != nil {
log.Debug("GetActivityTitle err:%v", err)
return "", ""
}
title := gamedata.GetStringValue(data, "Title")
return languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, title), languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, title)
}
func GetActivityRecycleMail(ActId int) (string, string, string) {
data, err := gamedata.GetDataByIntKey(CFG_ACTIVITY, ActId)
if err != nil {

View File

@ -14,6 +14,7 @@ var Server struct {
LogLevel string
LogPath string
WSAddr string
RPCAddr string
CertFile string
KeyFile string
TCPAddr string

View File

@ -4,6 +4,7 @@
"LogPath": "./log",
"TCPAddr": ":3602",
"WSAddr": ":3567",
"RPCAddr": ":50051",
"MySqlAddr": "127.0.0.1",
"MySqlPort": "3306",
"MySqlUsr": "root",

View File

@ -413,6 +413,12 @@ func GetServerMailData(data *[]*SqlServerMailStruct) error {
return err
}
func GetActivityData(data *[]*SqlActivityCfgStruct) error {
sql := "select `id`, `type`, `title`, `mail_title`, `mail_content`, `level_limit`, `start_time`, `end_time`, `cfg_buf`, `extra` from t_activity_mod"
err := SqlDb.Select(data, sql)
return err
}
func CreateOrderSn(Uid, ChargeId int, OrderSn, Platform, Channel string, Price float64, Currency, Extra string) error {
sql := "insert into t_player_charge (`Uid`,`OrderId`, `ProductId`, `Price`,`Currency`, `CreateTime`, `PayPlatform`, `PayChannel`, `PayChannelExtra`) Values (?,?,?,?,?,?,?,?,?)"
Now := GoUtil.Now()

View File

@ -497,6 +497,19 @@ type SqlServerMailStruct struct {
CreateTime int64 `db:"create_time"`
}
type SqlActivityCfgStruct struct {
Id int `db:"id"`
Type int `db:"type"`
Title string `db:"title"`
MailTitle string `db:"mail_title"`
MailContent string `db:"mail_content"`
Level int `db:"level_limit"`
Start_time int64 `db:"start_time"`
End_time int64 `db:"end_time"`
Cfg []byte `db:"cfg_buf"`
Extra string `db:"extra"`
}
type SqlChargeOrderStruct struct {
Id int `db:"id"`
Uid int `db:"Uid"`

View File

@ -84,6 +84,7 @@ type GameLogic struct {
VarMgr *VarMgr // 变量管理器
StartTime int64 // 服务器启动时间
MessageMgr *MessageMgr // 消息管理器
ActivityMgr *ActivityMgr // 活动管理器
}
type ServerInfo struct {
@ -293,6 +294,12 @@ func (ad *GameLogic) CreateMailMgr() {
ad.MailMgr.Init()
}
// 活动管理器
func (ad *GameLogic) CreateActivityMgr() {
ad.ActivityMgr = &ActivityMgr{}
ad.ActivityMgr.Init()
}
func (ad *GameLogic) CreateMessageMgr() {
ad.MessageMgr = &MessageMgr{
ServerMod: new(ServerMod),
@ -478,6 +485,8 @@ func G_getGameLogic() *GameLogic {
// G_GameLogicPtr.CreateFriendMgr() //创建好友管理器
G_GameLogicPtr.CreateChampshipMgr() // 创建竞标赛管理器
G_GameLogicPtr.CreateVarMgr() // 创建变量管理器
} else {
G_GameLogicPtr.CreateActivityMgr() //创建活动管理器
}
G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器
G_GameLogicPtr.CreateMailMgr() //创建邮件管理器

View File

@ -468,7 +468,7 @@ func (p *Player) CatnipBackData() {
func (p *Player) GetChampshipActivityId() (int, int) {
var todayActivityId int
var yesterdayActivityId int
activiyCfgList := activityCfg.GetActivityListOrigin()
activiyCfgList := G_GameLogicPtr.ActivityMgr.GetActivityList()
Now := GoUtil.Now()
YesterDay := GoUtil.ZeroTimestamp() - 1
level := p.GetBaseMod().GetLevel()
@ -480,10 +480,10 @@ func (p *Player) GetChampshipActivityId() (int, int) {
if v.Level > level {
continue
}
if v.StartTime <= Now && v.EndTime >= Now {
if v.Startime <= Now && v.Endtime >= Now {
todayActivityId = v.Id
}
if v.StartTime <= YesterDay && v.EndTime >= YesterDay {
if v.Startime <= YesterDay && v.Endtime >= YesterDay {
yesterdayActivityId = v.Id
}
}
@ -492,7 +492,7 @@ func (p *Player) GetChampshipActivityId() (int, int) {
func (p *Player) GetDailyTaskActivityId() int {
var activityId int
activiyCfgList := activityCfg.GetActivityListOrigin()
activiyCfgList := G_GameLogicPtr.ActivityMgr.GetActivityList()
Now := GoUtil.Now()
level := p.GetBaseMod().GetLevel()
activityIds := dailyTaskCfg.GetActivityIds()
@ -503,7 +503,7 @@ func (p *Player) GetDailyTaskActivityId() int {
if v.Level > level {
continue
}
if v.StartTime <= Now && v.EndTime >= Now {
if v.Startime <= Now && v.Endtime >= Now {
activityId = v.Id
break
}

View File

@ -1,12 +1,18 @@
package game
import (
"fmt"
"server/db"
"server/game/mod/msg"
protoMsg "server/msg"
"server/pkg/github.com/name5566/leaf/log"
"sync"
"google.golang.org/protobuf/proto"
)
type ActivityMgr struct {
*ServerMod
data *ActivityData
}
type ActivityData struct {
@ -17,29 +23,32 @@ type ActivityData struct {
type ActivityCfg struct {
Id int
Type int
Strartime int64
Startime int64
Endtime int64
Level int
Title string
MailTitle string
MailContent string
RewardItem map[string]interface{}
cfg interface{}
Extra map[string]interface{}
}
func (ac *ActivityCfg) String() string {
return fmt.Sprintf("Id: %d, Type: %d, StartTime: %d, EndTime: %d, Level: %d, Title: %s, MailTitle: %s, MailContent: %s, cfg: %v, Extra: %v",
ac.Id, ac.Type, ac.Startime, ac.Endtime, ac.Level, ac.Title, ac.MailTitle, ac.MailContent, ac.cfg, ac.Extra)
}
const ()
func (r *ActivityMgr) Init() {
r.key = RANK_MGR_KEY
r.data = &ActivityData{
List: make(map[int]*ActivityCfg, 0),
}
// 注册处理函数
r.init()
r.Reload()
}
func (r *ActivityMgr) getData() *ActivityData {
return r.data.(*ActivityData)
return r.data
}
// 零点更新 重置榜单
@ -47,7 +56,19 @@ func (r *ActivityMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
return nil, nil
}
func (r ActivityMgr) GetActivityCfg(Id int) ActivityCfg {
func (r *ActivityMgr) GetActivityList() []ActivityCfg {
// 获取活动列表
data := r.getData()
data.mu.Lock()
defer data.mu.Unlock()
list := make([]ActivityCfg, 0, len(data.List))
for _, v := range data.List {
list = append(list, *v)
}
return list
}
func (r *ActivityMgr) GetActivityCfg(Id int) ActivityCfg {
// 获取活动配置
data := r.getData()
data.mu.Lock()
@ -58,3 +79,56 @@ func (r ActivityMgr) GetActivityCfg(Id int) ActivityCfg {
}
return *cfg
}
func (r *ActivityMgr) Reload() error {
// 重新加载活动配置
// 从数据库加载邮件
log.Debug("reload activity data")
data := r.getData()
data.mu.Lock()
defer data.mu.Unlock()
cfgList := make([]*db.SqlActivityCfgStruct, 0)
err := db.GetActivityData(&cfgList)
if err != nil {
log.Error("LoadActivityData error: %v", err)
return err
}
data.List = make(map[int]*ActivityCfg, 0)
for _, v := range cfgList {
activityCfg, err := unmarshalActivityCfg(v.Type, []byte(v.Cfg))
if err != nil {
log.Error("Unmarshal activity cfg error: %v", err)
continue
}
cfg := &ActivityCfg{
Id: v.Id,
Type: v.Type,
Startime: v.Start_time,
Endtime: v.End_time,
Level: v.Level,
Title: v.Title,
MailTitle: v.MailTitle,
MailContent: v.MailContent,
cfg: activityCfg,
}
log.Debug("load activity cfg: %v", cfg)
data.List[v.Id] = cfg
}
return nil
}
func unmarshalActivityCfg(atype int, buf []byte) (interface{}, error) {
if len(buf) == 0 {
return nil, nil
}
switch atype {
case 1:
cfg := &protoMsg.MiningCfg{}
err := proto.Unmarshal(buf, cfg)
if err != nil {
return nil, err
}
return cfg, nil
}
return nil, nil
}

View File

@ -322,3 +322,29 @@ func ReqAdminBan(args []interface{}) error {
AdminPlayerBack(a, res)
return nil
}
func AcitivityCfgReload() {
G_GameLogicPtr.ActivityMgr.Reload()
}
func AdminShipping(req *msg.ReqOrderShipping) (*msg.ResOrderShipping, error) {
res := &msg.ResOrderShipping{}
res.Code = 0
OrderInfo, err := db.GetPlayerChargeData(req.OrderSn)
if err != nil {
res.Code = 1
res.Msg = "order not found"
}
if OrderInfo.PayStatus == MergeConst.ORDER_STATUS_SHIP {
res.Msg = "order already shipped"
}
// 玩家在线,通知发货
Player := G_GameLogicPtr.GetPlayer(int64(OrderInfo.Uid))
if Player != nil {
go Player.TriggerShippingOrderOrigin(&msg.ReqShippingOrder{
OrderSn: req.OrderSn,
})
res.Msg = "player online,triggered sync"
}
return res, nil
}

View File

@ -7,7 +7,6 @@ import (
"errors"
"math"
"server/conf"
activityCfg "server/conf/activity"
cardCfg "server/conf/card"
chargeCfg "server/conf/charge"
fur_cfg "server/conf/fur"
@ -70,6 +69,7 @@ type Player struct {
stopOnce sync.Once
msgChanOnce sync.Once
func_time int
config_list map[string]interface{}
}
type PlayerBackUp struct {
@ -1222,9 +1222,8 @@ func (p *Player) TeLog(Type string, Param map[string]interface{}) {
// 初始化活动
func (p *Player) InitActivity() {
p.activity = make(map[int]*ActivityInfo)
ActivityList := activityCfg.GetActivityList()
ActivityList := G_GameLogicPtr.ActivityMgr.GetActivityList()
Level := p.GetPlayerBaseMod().GetLevel()
ActivityMod := p.PlayMod.getActivityMod()
now := GoUtil.Now()
var startduration int64
var minduration int64
@ -1233,24 +1232,21 @@ func (p *Player) InitActivity() {
if v.Level > Level {
continue
}
Status := ActivityMod.GetActivityStatus(v)
if Status == 0 {
continue
}
startduration = v.StartTime - now
endduration = v.EndTime - now + 1
Status := 1
startduration = v.Startime - now
endduration = v.Endtime - now + 1
if startduration > 0 && (minduration == 0 || minduration > startduration) {
minduration = startduration
}
if endduration > 0 && (minduration == 0 || minduration > endduration) {
minduration = endduration
}
if v.StartTime > now || v.EndTime < now {
if v.Startime > now || v.Endtime < now {
continue
}
p.activity[v.Id] = &ActivityInfo{
StartT: v.StartTime,
EndT: v.EndTime,
StartT: v.Startime,
EndT: v.Endtime,
Id: v.Id,
Type: v.Type,
Status: Status,
@ -1260,7 +1256,7 @@ func (p *Player) InitActivity() {
if minduration > 0 {
p.CallEvent(time.Duration(minduration)*time.Second, p.TickActivity, "init_activity")
}
ActivityMod = p.PlayMod.getActivityMod()
ActivityMod := p.PlayMod.getActivityMod()
if ActivityMod.AddEnd > now && !ActivityMod.AddReward {
p.CallEvent(time.Duration(ActivityMod.AddEnd-now)*time.Second, p.TickActivityAddGift, "init_activity_add_gift")
}

View File

@ -2896,8 +2896,6 @@ func ReqSetPetName(player *Player, buf []byte) error {
})
player.PlayMod.save()
player.BackUserInfo()
PlayroomMod := player.PlayMod.getPlayroomMod()
PlayroomMod.UnLock(BaseMod.GetLevel())
player.LimitedTimePlayroomTrigger()
player.UpdateUserInfo()
player.TeLog("petname_set", map[string]interface{}{

View File

@ -3,6 +3,7 @@ package leaf
import (
"os"
"os/signal"
"server/backend"
mergeCluster "server/cluster"
sconf "server/conf"
"server/game"
@ -32,7 +33,7 @@ func Run(mods ...module.Module) {
}
log.Release("服务器版本: %s", "1.0.02")
log.Release("%s 启动, 节点类型: %s, 区服id: %d", sconf.Server.GameName, sconf.Server.ServerType, sconf.Server.ServerID)
go backend.Start()
// module
for i := 0; i < len(mods); i++ {
module.Register(mods[i])

View File

@ -141,7 +141,7 @@ CREATE TABLE IF NOT EXISTS `system_mail_info` (
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '系统邮件';
/*==============================================================*/
/* Table: t_player_data 系统模块表 */
/* Table: t_server_mod 系统模块表 */
/*==============================================================*/
CREATE TABLE IF NOT EXISTS t_server_mod (
`id` int NOT NULL AUTO_INCREMENT primary key,
@ -149,3 +149,21 @@ CREATE TABLE IF NOT EXISTS t_server_mod (
`mData` mediumblob DEFAULT NULL COMMENT '数据',
`updateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE utf8mb4_general_ci COMMENT = '系统模块表';
/*==============================================================*/
/* Table: t_activity_mod 系统活动表 */
/*==============================================================*/
CREATE TABLE IF NOT EXISTS t_activity_mod (
`id` int NOT NULL AUTO_INCREMENT primary key,
`type` int DEFAULT 0 COMMENT '活动类型',
`title` varchar(128) DEFAULT '' COMMENT '活动标题',
`mail_title` varchar(128) DEFAULT '' COMMENT '活动邮件标题',
`mail_content` varchar(2048) DEFAULT '' COMMENT '活动邮件内容',
`start_time` int unsigned NOT NULL DEFAULT '0' COMMENT '活动开始时间',
`end_time` int unsigned NOT NULL DEFAULT '0' COMMENT '活动结束时间',
`level_limit` int unsigned NOT NULL DEFAULT '0' COMMENT '等级限制',
`cfg` TEXT DEFAULT '' COMMENT '活动配置',
`cfg_buf` BLOB DEFAULT NULL COMMENT '活动配置buf',
`extra` TEXT DEFAULT '' COMMENT '活动额外数据',
`updateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE utf8mb4_general_ci COMMENT = '系统活动表';

View File

@ -3,6 +3,7 @@
"LogLevel": "debug",
"LogPath": "./log",
"TCPAddr": ":3601",
"RPCAddr": ":50051",
"WSAddr": ":3566",
"MySqlAddr": "127.0.0.1",
"MySqlPort": "3306",