Compare commits

..

No commits in common. "d8bee4bd7318ec6279ceb97f0bc46d9d9233f2c7" and "defdc4b8292189c6f87dcf52ee96906d4ade5b6a" have entirely different histories.

114 changed files with 10240 additions and 4356 deletions

4
.gitignore vendored
View File

@ -46,6 +46,4 @@ tools/xlsx2binary/agc.go
/robot/robot /robot/robot
/ranksrv/ranksrv /ranksrv/ranksrv
/schedulesrv/schedulesrv /schedulesrv/schedulesrv
/machine/machine /machine/machine
/statistics/statistics
/statistics/task/task*

View File

@ -1,12 +1,12 @@
stages: stages:
- lock - lock
- build - build
- save
- sync
- unlock - unlock
variables: variables:
GOPROXY: "https://goproxy.cn,direct" ProjectPath: "mongo.games.com/game" # 项目相对于GOPATH的路径
GOPATH: "/home/gopath"
GoServerSrcPath: "mongo.games.com/goserver" # 项目相对于GOPATH/src的路径
BetaBinPath: "/home/game/" # beta环境部署路径 BetaBinPath: "/home/game/" # beta环境部署路径
DevelopBinPath: "/home/game/" # develop环境部署路径 DevelopBinPath: "/home/game/" # develop环境部署路径
@ -25,12 +25,12 @@ lock_job:
stage: lock stage: lock
script: script:
- | - |
if [ -f /tmp/ci_lock_$CI_COMMIT_REF_NAME ]; then if [ -f /tmp/ci_lock ]; then
echo "流水线($CI_COMMIT_REF_NAME)已在运行,等待..." echo "流水线已在运行,等待..."
exit 1 exit 1
else else
touch /tmp/ci_lock_$CI_COMMIT_REF_NAME touch /tmp/ci_lock
echo "获得锁定,开始流水线($CI_COMMIT_REF_NAME)。" echo "获得锁定,开始流水线。"
fi fi
build-job: build-job:
@ -39,21 +39,20 @@ build-job:
- develop - develop
- release - release
script: script:
# 拉取代码
- git checkout $CI_COMMIT_REF_NAME - git checkout $CI_COMMIT_REF_NAME
- git pull origin $CI_COMMIT_REF_NAME - git pull origin $CI_COMMIT_REF_NAME
# 替换 go.mod 中的 ../goserver
- sed -i "s|mongo.games.com/goserver => .*|mongo.games.com/goserver => $GOPATH/src/$GoServerSrcPath|" go.mod
- if [ ! -z "$(git status --porcelain go.mod go.sum)" ]; then - if [ ! -z "$(git status --porcelain go.mod go.sum)" ]; then
GOMODTIDY=1; GOMODTIDY=1;
fi fi
# 拷贝到GOPATH
- echo '拷贝到GOPATH'
- rsync -rvc --no-perms --delete ./* $GOPATH/src/$ProjectPath
# 进入项目目录
- cd $GOPATH/src/$ProjectPath
# 编译 # 编译
- echo '编译' - echo '编译'
- if [ "$GOMODTIDY" == 1 ]; then - if [ "$GOMODTIDY" == 1 ]; then
go mod tidy; go mod tidy;
fi fi
- | - |
while IFS= read -r line || [[ -n $line ]] while IFS= read -r line || [[ -n $line ]]
@ -64,13 +63,19 @@ build-job:
cd .. cd ..
done < ./programs.txt done < ./programs.txt
save-job:
stage: save
only:
- develop
- release
script:
- cd $GOPATH/src/$ProjectPath
# 拷贝文件 # 拷贝文件
- echo '拷贝文件' - echo '拷贝文件'
- rm -rf ./temp - rm -rf ./temp
- mkdir ./temp - mkdir ./temp
- mkdir ./temp/data - mkdir ./temp/data
- cp -rfp ./data/* ./temp/data - cp -rfp ./data/* ./temp/data
# 删除自定义配置 # 删除自定义配置
- echo '删除自定义配置' - echo '删除自定义配置'
- | - |
@ -79,7 +84,6 @@ build-job:
echo "删除 $line 配置" echo "删除 $line 配置"
rm ./temp/data/$line rm ./temp/data/$line
done < ./exclude.txt done < ./exclude.txt
# 拷贝可执行程序 # 拷贝可执行程序
- echo '拷贝可执行程序' - echo '拷贝可执行程序'
- | - |
@ -89,7 +93,13 @@ build-job:
mv ./$line/$line ./temp/$line mv ./$line/$line ./temp/$line
done < ./programs.txt done < ./programs.txt
# 获取部署环境信息 sync_job:
stage: sync
only:
- develop
- release
script:
- cd $GOPATH/src/$ProjectPath
- if [ "$CI_COMMIT_BRANCH" == "develop" ]; then - if [ "$CI_COMMIT_BRANCH" == "develop" ]; then
SSH_PRIVATE_KEY="$SSH_PRIVATE_KEY_DEVELOP"; SSH_PRIVATE_KEY="$SSH_PRIVATE_KEY_DEVELOP";
REMOTE_HOST="$REMOTE_HOST_DEVELOP"; REMOTE_HOST="$REMOTE_HOST_DEVELOP";
@ -118,7 +128,7 @@ build-job:
- echo "同步到服务器" - echo "同步到服务器"
- echo "Deploying to remote server using rsync... $BinPath" - echo "Deploying to remote server using rsync... $BinPath"
- rsync -rvz --delete ./temp/ $REMOTE_USER@$REMOTE_HOST:$BinPath - rsync -rvz --delete ./temp/ $REMOTE_USER@$REMOTE_HOST:$BinPath
# 触发部署 # 触发部署
- "curl -X POST --fail -F token=$SERVER_CI_TOKEN -F ref=release -F variables[ServerName]=$ServerName https://git.pogorockgames.com/api/v4/projects/31/trigger/pipeline" - "curl -X POST --fail -F token=$SERVER_CI_TOKEN -F ref=release -F variables[ServerName]=$ServerName https://git.pogorockgames.com/api/v4/projects/31/trigger/pipeline"
@ -126,6 +136,6 @@ build-job:
unlock_job: unlock_job:
stage: unlock stage: unlock
script: script:
- rm -f /tmp/ci_lock_$CI_COMMIT_REF_NAME - rm -f /tmp/ci_lock
- echo "释放锁定,流水线结束(/$CI_COMMIT_REF_NAME)。" - echo "释放锁定,流水线结束。"
when: always when: always

View File

@ -1,8 +1,8 @@
@echo off @echo off
xcopy ..\data\* .\data\ /s /e /y /exclude:..\exclude.txt xcopy ..\data\* .\data\ /s /e /y /exclude:..\shell\exclude.txt
for /f %%i in (../programs.txt) do ( for /f %%i in (../shell/programs.txt) do (
echo go build %%i echo go build %%i
go build -o ./%%i/%%i.exe ../%%i/ go build -o ./%%i/%%i.exe ../%%i/
) )

View File

@ -250,7 +250,6 @@ func RegisterClockFunc(fs *ClockFunc) {
if fs == nil { if fs == nil {
return return
} }
if fs.OnSecTimerFunc != nil { if fs.OnSecTimerFunc != nil {
fs.event = fs.event | 1<<ClockEventSecond fs.event = fs.event | 1<<ClockEventSecond
} }
@ -273,9 +272,5 @@ func RegisterClockFunc(fs *ClockFunc) {
fs.event = fs.event | 1<<ClockEventShutdown fs.event = fs.event | 1<<ClockEventShutdown
} }
if fs.event == 0 {
return
}
ClockMgrSingleton.RegisterSinker(fs) ClockMgrSingleton.RegisterSinker(fs)
} }

View File

@ -898,7 +898,3 @@ var GuideIdToGainWay = map[int]int{
GuideIdNewPlayer: GainWayGuide, GuideIdNewPlayer: GainWayGuide,
GuideIdCustom: GainWayGuide2, GuideIdCustom: GainWayGuide2,
} }
func GetKeyGameDif(gamedif string) string {
return fmt.Sprintf("gamedif-%v", gamedif)
}

View File

@ -2,15 +2,13 @@ package common
import ( import (
"fmt" "fmt"
rawproto "google.golang.org/protobuf/proto" rawproto "google.golang.org/protobuf/proto"
"mongo.games.com/game/proto"
"mongo.games.com/game/protocol/server"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/core/profile" "mongo.games.com/goserver/core/profile"
"mongo.games.com/goserver/core/utils" "mongo.games.com/goserver/core/utils"
"mongo.games.com/game/proto"
"mongo.games.com/game/protocol/server"
) )
var ( var (

7
common/sysmsg.go Normal file
View File

@ -0,0 +1,7 @@
package common
// 系统消息编号
const (
SYSMSG_BEGIN int = iota
SYSMSG_PASSHU //因过胡规则,此牌不能胡
)

30
common/temp.txt Normal file
View File

@ -0,0 +1,30 @@
GainWay_NewPlayer int32 = iota //0.新建角色 新建账号,系统赠送房卡%s张|新建账号,系统赠送金币%s个 remark:无
GainWay_Pay //1.后台增加(主要是充值) %s获得d%张房卡剩余d%张 remark:充值X元
GainWay_Transfer_In //2.俱乐部转移(转入) s%赠送您房卡d%张剩余d%张 remark:玩家名称
GainWay_AgentReturn //3.代创房间返还 -
GainWay_DrawPrize //4.领取奖励 领取奖励房卡d%张,剩余%d张 remark:无
GainWay_Share //5.每日分享 每日分享活动奖励d%房卡剩余d%房卡 remark:无
GainWay_Activty //6.活动获得 s%活动奖励d%金币剩余d%金币 remark:活动名称
GainWay_Game //7.玩游戏消耗 开房间房卡-d%张剩余d%张 remark:无
GainWay_Task //8.任务 完成%s任务奖励房卡d%张剩余d%张 remark:任务名称
GainWay_ByPMCmd //9.pm命令 -
GainWay_MatchSignup //10.比赛报名 -
GainWay_MatchPlay //11.比赛回兑 -
GainWay_MatchAdd //12.比赛补充 -
GainWay_MatchBreakBack //13.退赛退还 -
GainWay_MatchSystemSupply //14.系统补给 -
GainWay_Exchange //15.兑换 兑换%s红包%d分剩余红包%d分 remark:房卡x张
GainWay_Contribute //16.贡献 -
GainWay_ClubMoneySceneFee //17.俱乐部钻石场房费 -
GainWay_Transfer_Out //18.俱乐部转移(转出) 赠送给s%房卡d%张剩余d%张 remark:玩家名称
GainWay_ServiceFee //19.桌费 扣除桌费d%金币剩余d%金币 remark:无
GainWay_CoinSceneWin //20.金豆场赢取 参与游戏赢取d%金币剩余d%金币 remark:无
GainWay_CoinSceneLost //21.金豆场输 参与游戏输掉d%金币剩余d%金币 remark:无
GainWay_BindTel //22.绑定手机 绑定手机,获得房卡%d张剩余%d张 remark:无
GainWay_PlayerShare //23.隶属玩家每日分享 每日分享活动,领取房卡%d张剩余%d张 remark:无
GainWay_Invite //24.邀请玩家 邀请玩家,获得红包%d分剩余%d分 remark:无
GainWay_LoginSign //25.签到奖励
GainWay_OnlineGift //26.签到奖励
GainWay_CoinSceneEnter //27.进入金币场预扣
GainWay_ShopBuy //28.商城购买或者兑换 使用%s购买金币%d剩余%d remark:房卡x张
GainWay_CoinSceneLeave //29.离开金币场回兑

View File

@ -28,7 +28,6 @@ func InSameDay(tNow, tPre time.Time) bool {
} }
return false return false
} }
func InSameDayNoZero(tNow, tPre time.Time) bool { func InSameDayNoZero(tNow, tPre time.Time) bool {
if tNow.Day() != tPre.Day() { if tNow.Day() != tPre.Day() {
@ -111,7 +110,7 @@ func DiffMonth(tNow, tPre time.Time) int {
return int(diffMonth) return int(diffMonth)
} }
func DelayInvoke(method func(), ud interface{}, delay time.Duration, times int) (timer.TimerHandle, bool) { func DelayInvake(method func(), ud interface{}, delay time.Duration, times int) (timer.TimerHandle, bool) {
return timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool { return timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
if method != nil { if method != nil {
method() method()
@ -127,7 +126,6 @@ func StrTimeToTs(strTime string) int64 {
} }
return rTime.Unix() return rTime.Unix()
} }
func TsToStrTime(tc int64) string { func TsToStrTime(tc int64) string {
//return time.Now().Format("2018-07-02 19:14:00") //return time.Now().Format("2018-07-02 19:14:00")
return time.Unix(tc, 0).Format("2006-01-02 15:04:05") return time.Unix(tc, 0).Format("2006-01-02 15:04:05")

View File

@ -1,23 +0,0 @@
Tienlen207 Àš
 欢ä¹<C3A4>æ<EFBFBD>•é±¼401 Àš
 高棉象棋521 Àš
 å<><C3A5>三水211 Àš
愤æ€çš„大å<C2A7>606 Àš
 å°<C3A5>ç<EFBFBD>«ç®­607 Àš
 è´¢è¿<C3A8>神301 à§
å¤<C3A5>仇者è<E280A6>”çŸ302 à§
  å¤<C3A5>æ´»èŠå²303 à§

 冰河世纪304 à§
  百战æˆ<C3A6>神305 à§
  水果拉霸306 à§
  多ç¦<C3A7>多财307 à§
 FortuneTiger308 à§
 FortuneDragon309 à§
 FortuneRabbit310 à§
 FortuneOx311 à§
 FortuneMouse312 à§
 CashMania313 à§
GatesOfOlympus314 à§
 娃娃机608

View File

@ -1,129 +0,0 @@
{
"Arr": [
{
"Id": 1,
"GameName": "Tienlen",
"GameDif": "207",
"LimitNum": 200000
},
{
"Id": 2,
"GameName": "欢乐捕鱼",
"GameDif": "401",
"LimitNum": 200000
},
{
"Id": 3,
"GameName": "高棉象棋",
"GameDif": "521",
"LimitNum": 200000
},
{
"Id": 4,
"GameName": "十三水",
"GameDif": "211",
"LimitNum": 200000
},
{
"Id": 5,
"GameName": "愤怒的大叔",
"GameDif": "606",
"LimitNum": 200000
},
{
"Id": 6,
"GameName": "小火箭",
"GameDif": "607",
"LimitNum": 200000
},
{
"Id": 7,
"GameName": "财运神",
"GameDif": "301",
"LimitNum": 300000
},
{
"Id": 8,
"GameName": "复仇者联盟",
"GameDif": "302",
"LimitNum": 300000
},
{
"Id": 9,
"GameName": "复活节岛",
"GameDif": "303",
"LimitNum": 300000
},
{
"Id": 10,
"GameName": "冰河世纪",
"GameDif": "304",
"LimitNum": 300000
},
{
"Id": 11,
"GameName": "百战成神",
"GameDif": "305",
"LimitNum": 300000
},
{
"Id": 12,
"GameName": "水果拉霸",
"GameDif": "306",
"LimitNum": 300000
},
{
"Id": 13,
"GameName": "多福多财",
"GameDif": "307",
"LimitNum": 300000
},
{
"Id": 14,
"GameName": "FortuneTiger",
"GameDif": "308",
"LimitNum": 300000
},
{
"Id": 15,
"GameName": "FortuneDragon",
"GameDif": "309",
"LimitNum": 300000
},
{
"Id": 16,
"GameName": "FortuneRabbit",
"GameDif": "310",
"LimitNum": 300000
},
{
"Id": 17,
"GameName": "FortuneOx",
"GameDif": "311",
"LimitNum": 300000
},
{
"Id": 18,
"GameName": "FortuneMouse",
"GameDif": "312",
"LimitNum": 300000
},
{
"Id": 19,
"GameName": "CashMania",
"GameDif": "313",
"LimitNum": 300000
},
{
"Id": 20,
"GameName": "GatesOfOlympus",
"GameDif": "314",
"LimitNum": 300000
},
{
"Id": 21,
"GameName": "娃娃机",
"GameDif": "608"
}
]
}

Binary file not shown.

View File

@ -7154,78 +7154,6 @@
"Compound": { "Compound": {
"71002": 10 "71002": 10
} }
},
{
"Id": 40005,
"Name": "金币赛门票",
"ShowLocation": [
1,
1,
0
],
"Classify": [
1,
1,
0
],
"Type": 4,
"Effect0": [
0,
0,
0,
0,
0,
0
],
"Effect": [
0,
0,
0,
0,
0,
0
],
"SaleGold": 100000,
"Composition": 1,
"CompositionMax": 1,
"Location": "0",
"Describe": "作用:用于报名特殊钻石赛事;\n产出途径存钱罐"
},
{
"Id": 40006,
"Name": "钻石赛门票",
"ShowLocation": [
1,
1,
0
],
"Classify": [
1,
1,
0
],
"Type": 4,
"Effect0": [
0,
0,
0,
0,
0,
0
],
"Effect": [
0,
0,
0,
0,
0,
0
],
"SaleGold": 100000,
"Composition": 1,
"CompositionMax": 1,
"Location": "0",
"Describe": "作用:用于报名特殊钻石赛事;\n产出途径存钱罐"
} }
] ]
} }

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,16 @@
{
"Id":5,
"Name":"51活动",
"Desc":"对局领福袋",
"StartTime":"2018-04-20 00:00:00",
"EndTime":"2018-05-02 23:59:59",
"TaskIds":[],
"IsDelTaskWhenEnd":true,
"IsDelActIdWhenEnd":true,
"Data":[
{"Name":"PerDayLimit", "IntVal":3 },
{"Name":"CostTimes", "IntArr":[5,3] },
{"Name":"Prize1", "IntArr":[1,1500,60,1,2000,20,1,3000,10,4,100,6,4,200,3,4,500,1] },
{"Name":"Prize2", "IntArr":[1,200,40,1,300,25,1,500,15,1,800,10,1,1000,5,4,100,5] }
]
}

View File

@ -0,0 +1,20 @@
{
"Id":3,
"Name":"元宵猜灯谜",
"Desc":"元宵猜灯谜",
"StartTime":"2018-03-02 00:00:00",
"EndTime":"2018-03-02 23:59:59",
"TaskIds":[],
"IsDelTaskWhenEnd":true,
"IsDelActIdWhenEnd":true,
"Data":[
{"Name":"Count", "IntVal":6 },
{"Name":"Prize", "IntArr":[1,2000,50,1,3000,30,3,20,15,3,50,5] },
{"Name":"1", "StrArr":["2018-03-02 00:00:00","1","弟兄五六个,围着圆柱坐,大家一分手,衣服都扯破。","A:花生","B:大蒜","C:向日葵","D:糖葫芦"] },
{"Name":"2", "StrArr":["2018-03-02 04:00:00","2","红公鸡,绿尾巴,身体钻到地底下,又甜又脆营养大。","A:番茄","B:红薯","C:红萝卜","D:花生"] },
{"Name":"3", "StrArr":["2018-03-02 08:00:00","3","纸老虎(打一成语)","A:狐假虎威","B:狗仗人势","C:仗势欺人","D:外强中干"] },
{"Name":"4", "StrArr":["2018-03-02 12:00:00","0","笑死人(打一成语)","A:乐极生悲","B:笑里藏刀","C:哭笑不得","D:强颜欢笑"] },
{"Name":"5", "StrArr":["2018-03-02 16:00:00","3","兔子请老虎(打一成语)","A:狐假虎威","B:为虎作伥","C:与虎谋皮","D:寅吃卯粮"] },
{"Name":"6", "StrArr":["2018-03-02 20:00:00","1", "白又方,嫩又香,能做菜,能煮汤,豆子是它爹和妈,它和爹妈不一样。","A:土豆","B:豆腐","C:大米","D:萝卜"] }
]
}

View File

@ -0,0 +1,11 @@
{
"Id":4,
"Name":"邀请新人",
"Desc":"邀请新人",
"StartTime":"2018-03-23 00:00:00",
"EndTime":"2018-05-31 23:59:59",
"TaskIds":[],
"IsDelTaskWhenEnd":true,
"IsDelActIdWhenEnd":true,
"Data":[]
}

View File

@ -0,0 +1,14 @@
{
"Id":1,
"Name":"新人注册领红包",
"Desc":"新人注册领红包",
"StartTime":"2018-02-05 12:00:00",
"EndTime":"2020-05-30 12:00:00",
"TaskIds":[1,2,3,4,5,6,7,8,9,10],
"IsDelTaskWhenEnd":false,
"IsDelActIdWhenEnd":false,
"Data":[
{"Name":"MaxNum", "IntVal":2000 },
{"Name":"AcceptRate", "IntArr":[1001,100,2001,20] }
]
}

View File

@ -0,0 +1,11 @@
{
"Id":6,
"Name":"投资返利",
"Desc":"投资返利",
"StartTime":"2018-04-20 00:00:00",
"EndTime":"2025-05-02 23:59:59",
"TaskIds":[],
"IsDelTaskWhenEnd":true,
"IsDelActIdWhenEnd":true,
"Data":[]
}

View File

@ -0,0 +1,21 @@
{
"Id":2,
"Name":"对暗号拿红包",
"Desc":"对暗号拿红包",
"StartTime":"2018-02-16 00:00:00",
"EndTime":"2018-02-23 00:00:00",
"TaskIds":[],
"IsDelTaskWhenEnd":false,
"IsDelActIdWhenEnd":false,
"Data":[
{"Name":"Count", "IntVal":7 },
{"Name":"UnOpenTip", "StrVal":"0" },
{"Name":"1", "StrVal":"2018-02-16 19:00:00|1" },
{"Name":"2", "StrVal":"2018-02-17 19:00:00|2" },
{"Name":"3", "StrVal":"2018-02-18 19:00:00|3" },
{"Name":"4", "StrVal":"2018-02-19 19:00:00|4" },
{"Name":"5", "StrVal":"2018-02-20 19:00:00|5" },
{"Name":"6", "StrVal":"2018-02-21 19:00:00|6" },
{"Name":"7", "StrVal":"2018-02-22 19:00:00|7" }
]
}

1173
data/botai/dvtfollowwin.json Normal file

File diff suppressed because it is too large Load Diff

1284
data/botai/dvtinvertwin.json Normal file

File diff suppressed because it is too large Load Diff

1059
data/botai/dvtrandom.json Normal file

File diff suppressed because it is too large Load Diff

1174
data/botai/rvbfollowwin.json Normal file

File diff suppressed because it is too large Load Diff

1285
data/botai/rvbinvertwin.json Normal file

File diff suppressed because it is too large Load Diff

1026
data/botai/rvbrandom.json Normal file

File diff suppressed because it is too large Load Diff

1
data/fishpath/path.json Normal file
View File

@ -0,0 +1 @@
{"count":3,"pools":[{"id":-1,"type":2,"scatter":0,"s_obj":{"helix":0,"h_obj":{"offset":0},"custom":0,"c_obj":{"start":0,"offset":0}},"move":0,"m_obj":{"sx":0,"sy":0,"ex":0,"ey":0,"sp":0},"points":[{"x":-464,"y":-77,"stay":0},{"x":354,"y":1175,"stay":100},{"x":1352,"y":1038,"stay":50},{"x":897,"y":-374,"stay":50}],"stay":200,"length":3986}],"maxId":3,"lastEdit":1}

View File

@ -64,10 +64,10 @@ func (svc *DbShopLogSvc) UpdateDbShopState(args *model.DbShopLogArgs, ret *bool)
logger.Logger.Error("UpdateDbShopState == nil") logger.Logger.Error("UpdateDbShopState == nil")
return nil return nil
} }
logger.Logger.Info("DbShopLogSvc.UpdateDbShopState", args.Log.LogId) logger.Logger.Trace("DbShopLogSvc.UpdateDbShopState")
err = clog.UpdateId(args.Log.LogId, bson.M{"$set": bson.M{"state": args.Log.State}}) err = clog.UpdateId(args.Log.LogId, bson.M{"$set": bson.M{"state": args.Log.State}})
if err != nil { if err != nil {
logger.Logger.Error("DbShopLogSvc.UpdateDbShopState error:", err, "LogId = ", args.Log.LogId) logger.Logger.Error("DbShopLogSvc.UpdateDbShopState error:", err)
return nil return nil
} }
*ret = true *ret = true

View File

@ -33,7 +33,6 @@ func GameDetailedLogsCollection(plt string) *mongo.Collection {
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true}) c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true})
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"time", "cycleid"}, Background: true, Sparse: true}) c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"time", "cycleid"}, Background: true, Sparse: true})
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"-time", "cycleid"}, Background: true, Sparse: true}) c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"-time", "cycleid"}, Background: true, Sparse: true})
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"gamedif"}, Background: true, Sparse: true})
} }
return c_gamedetailed return c_gamedetailed
} }

View File

@ -44,7 +44,6 @@ func GamePlayerListLogsCollection(plt string) *mongo.Collection {
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"-ts", "cycleid"}, Background: true, Sparse: true}) c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"-ts", "cycleid"}, Background: true, Sparse: true})
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"cycleid"}, Background: true, Sparse: true}) c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"cycleid"}, Background: true, Sparse: true})
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true}) c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true})
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"gamedif"}, Background: true, Sparse: true})
} }
return c_gameplayerlistlog return c_gameplayerlistlog
} }

View File

@ -30,7 +30,6 @@ func ItemLogsCollection(plt string) *mongo.Collection {
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"typeid", "roomconfigid"}, Background: true, Sparse: true}) c_itemlog.EnsureIndex(mgo.Index{Key: []string{"typeid", "roomconfigid"}, Background: true, Sparse: true})
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"ts"}, Background: true, Sparse: true}) c_itemlog.EnsureIndex(mgo.Index{Key: []string{"ts"}, Background: true, Sparse: true})
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"-ts"}, Background: true, Sparse: true}) c_itemlog.EnsureIndex(mgo.Index{Key: []string{"-ts"}, Background: true, Sparse: true})
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"gamedif"}, Background: true, Sparse: true})
} }
return c_itemlog return c_itemlog
} }

View File

@ -42,8 +42,8 @@ const (
ETCDKEY_MACHINE = "/game/machine_config" //娃娃机配置 ETCDKEY_MACHINE = "/game/machine_config" //娃娃机配置
ETCDKEY_MatchAudience = "/game/match_audience" //比赛观众 ETCDKEY_MatchAudience = "/game/match_audience" //比赛观众
ETCDKEY_Spirit = "/game/spirit" // 小精灵配置 ETCDKEY_Spirit = "/game/spirit" // 小精灵配置
ETCDKEY_RoomType = "/game/room_type/" // 房间类型配置 ETCDKEY_RoomType = "/game/room_type" // 房间类型配置
ETCDKEY_RoomConfig = "/game/room_config/" // 房间配置 ETCDKEY_RoomConfig = "/game/room_config" // 房间配置
ETCDKEY_RoomConfigSystem = "/game/room_system" // 系统房间配置 ETCDKEY_RoomConfigSystem = "/game/room_system" // 系统房间配置
ETCDKEY_ClientUpgrade = "/game/client_upgrade" // 客户端升级奖励配置 ETCDKEY_ClientUpgrade = "/game/client_upgrade" // 客户端升级奖励配置
ETCDKEY_PopUpWindow = "/game/PopUpWindowConfig" //弹窗配置 ETCDKEY_PopUpWindow = "/game/PopUpWindowConfig" //弹窗配置

View File

@ -35,7 +35,6 @@ const (
ThirteenWaterPlayerOpReset = 4 // 重新选牌 ThirteenWaterPlayerOpReset = 4 // 重新选牌
ThirteenWaterPlayerJoin = 5 // 加入游戏 ThirteenWaterPlayerJoin = 5 // 加入游戏
ThirteenWaterPlayerOpSelect = 6 // 预选牌 ThirteenWaterPlayerOpSelect = 6 // 预选牌
ThirteenWaterPlayerOpAuto = 7 // 自动摆牌 1自动 2手动
) )
const ( const (
ThirteenWaterSceneWaitTimeout = time.Second * 2 //等待倒计时 ThirteenWaterSceneWaitTimeout = time.Second * 2 //等待倒计时

View File

@ -945,6 +945,8 @@ func AvengersCheckAndSaveLog(sceneEx *AvengersSceneData, playerEx *AvengersPlaye
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -44,16 +44,13 @@ func (this *Scene) SaveGameDetailedLog(param *SaveGameDetailedParam) *SaveGameDe
f := func(plt string) { f := func(plt string) {
log := &model.GameDetailedLog{ log := &model.GameDetailedLog{
Id: bson.NewObjectId(), Id: bson.NewObjectId(),
Platform: plt,
LogId: param.LogId, LogId: param.LogId,
GameDif: this.GetDBGameFree().GetGameDif(), GameId: this.GameId,
GameId: this.GetDBGameFree().GetGameId(), Platform: plt,
GameClass: this.GetDBGameFree().GetGameClass(),
GameMode: this.GetDBGameFree().GetGameMode(),
GameType: this.GetDBGameFree().GetGameType(),
GameFreeId: this.GetDBGameFree().GetId(),
MatchId: this.GetMatch().GetMatchSortId(), MatchId: this.GetMatch().GetMatchSortId(),
SceneId: this.SceneId, SceneId: this.SceneId,
GameMode: this.GameMode,
GameFreeid: this.GetGameFreeId(),
PlayerCount: int32(len(this.Players)), PlayerCount: int32(len(this.Players)),
GameTiming: int32(param.GameTime), GameTiming: int32(param.GameTime),
GameBaseBet: this.GetBaseScore(), GameBaseBet: this.GetBaseScore(),
@ -101,6 +98,8 @@ type SaveGamePlayerListLogParam struct {
Platform string // 平台 Platform string // 平台
Snid int32 // 玩家id Snid int32 // 玩家id
PlayerName string // 玩家名字 PlayerName string // 玩家名字
Channel string // 渠道
ChannelId string // 推广渠道
TotalIn int64 // 总投入 TotalIn int64 // 总投入
TotalOut int64 // 总产出(税前) TotalOut int64 // 总产出(税前)
TaxCoin int64 // 总税收 TaxCoin int64 // 总税收
@ -156,35 +155,33 @@ func (this *Scene) SaveGamePlayerListLog(param *SaveGamePlayerListLogParam) *Sav
now := time.Now() now := time.Now()
log := &model.GamePlayerListLog{ log := &model.GamePlayerListLog{
LogId: bson.NewObjectId(), LogId: bson.NewObjectId(),
Platform: param.Platform,
GameDif: this.GetDBGameFree().GetGameDif(),
GameId: this.GetDBGameFree().GetGameId(),
GameClass: this.GetDBGameFree().GetGameClass(),
GameMode: this.GetDBGameFree().GetGameMode(),
GameType: this.GetDBGameFree().GetGameType(),
GameFreeId: this.GetGameFreeId(),
BaseScore: baseScore,
GameDetailedLogId: param.LogId,
Channel: p.Channel,
ChannelId: p.ChannelId,
RoomType: this.SceneMode,
Ts: now.Unix(),
Time: now,
CycleId: this.CycleID,
SnId: p.SnId, SnId: p.SnId,
Name: param.PlayerName, Name: param.PlayerName,
SceneId: this.SceneId, GameId: this.GameId,
MatchId: this.GetMatch().GetMatchSortId(), BaseScore: baseScore,
MatchType: int64(this.GetMatch().GetMatchType()),
WinAmountNoAnyTax: param.WinAmountNoAnyTax,
TaxCoin: param.TaxCoin, TaxCoin: param.TaxCoin,
BetAmount: param.BetAmount, Platform: param.Platform,
Channel: param.Channel,
SceneId: this.SceneId,
GameMode: this.GameMode,
GameFreeid: this.GetGameFreeId(),
GameDetailedLogId: param.LogId,
IsFirstGame: param.IsFirstGame, IsFirstGame: param.IsFirstGame,
BetAmount: param.BetAmount,
WinAmountNoAnyTax: param.WinAmountNoAnyTax,
TotalIn: param.TotalIn, TotalIn: param.TotalIn,
TotalOut: param.TotalOut, TotalOut: param.TotalOut,
Time: now,
RoomType: this.SceneMode,
GameDif: this.GetDBGameFree().GetGameDif(),
GameClass: this.GetDBGameFree().GetGameClass(),
MatchId: this.GetMatch().GetMatchSortId(),
MatchType: int64(this.GetMatch().GetMatchType()),
Ts: now.Unix(),
IsFree: param.IsFree, IsFree: param.IsFree,
WinSmallGame: param.WinSmallGame, WinSmallGame: param.WinSmallGame,
WinTotal: param.WinTotal, WinTotal: param.WinTotal,
CycleId: this.CycleID,
} }
if param.OnlyLog { if param.OnlyLog {
ret.Log = append(ret.Log, log) ret.Log = append(ret.Log, log)
@ -226,12 +223,10 @@ func (s *SaveGameDetailedCopy) Save() {
} }
} }
// LabaLog 拉霸缓存游戏记录,为了统计游戏时长 // LabaLog 拉霸缓存游戏记录
type LabaLog struct { type LabaLog struct {
PlayerListLog *SaveGamePlayerListLogCopy PlayerListLog *SaveGamePlayerListLogCopy
GameDetailLog *SaveGameDetailedCopy GameDetailLog *SaveGameDetailedCopy
CacheTime time.Time // 缓存时间
noEmpty bool
} }
// Cache 临时缓存 // Cache 临时缓存
@ -239,55 +234,22 @@ func (l *LabaLog) Cache(s *Scene, detailLog *SaveGameDetailedParam, playerListLo
if s == nil { if s == nil {
return return
} }
l.Save(2) // 如果没有收到结束消息算2秒游戏时长
detailLog.OnlyLog = true detailLog.OnlyLog = true
playerListLog.OnlyLog = true playerListLog.OnlyLog = true
l.GameDetailLog = s.SaveGameDetailedLog(detailLog) l.GameDetailLog = s.SaveGameDetailedLog(detailLog)
l.PlayerListLog = s.SaveGamePlayerListLog(playerListLog) l.PlayerListLog = s.SaveGamePlayerListLog(playerListLog)
l.CacheTime = time.Now()
l.noEmpty = true
} }
// Save 保存 // Save 保存
// second 为0时自动计算时间,从开始转动计时 func (l *LabaLog) Save(f func(log *LabaLog)) {
func (l *LabaLog) Save(second int32) { f(l)
if !l.noEmpty { l.PlayerListLog.Save()
return l.GameDetailLog.Save()
}
if second <= 0 {
sub := time.Now().Sub(l.CacheTime).Milliseconds()
if sub <= 1000 {
second = 1
} else {
second = int32(sub / 1000)
}
}
if l.PlayerListLog != nil {
if l.PlayerListLog.UpLog != nil {
for _, v := range l.PlayerListLog.UpLog.Log {
v.GamingTime = second
}
}
l.PlayerListLog.Save()
}
if l.GameDetailLog != nil {
for _, v := range l.GameDetailLog.Log {
v.GameTiming = second
}
l.GameDetailLog.Save()
}
l.Clear() l.Clear()
} }
// Clear 清空 // Clear 清空
func (l *LabaLog) Clear() { func (l *LabaLog) Clear() {
l.noEmpty = false
l.PlayerListLog = nil l.PlayerListLog = nil
l.GameDetailLog = nil l.GameDetailLog = nil
l.CacheTime = time.Time{}
} }

View File

@ -7,7 +7,6 @@ import (
"math/rand" "math/rand"
"time" "time"
"go.mongodb.org/mongo-driver/bson/primitive"
rawproto "google.golang.org/protobuf/proto" rawproto "google.golang.org/protobuf/proto"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/netlib"
@ -638,25 +637,19 @@ type ReportGameEventOnly struct {
func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEventOnly { func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEventOnly {
// 记录玩家 首次参与该场次的游戏时间 游戏次数 // 记录玩家 首次参与该场次的游戏时间 游戏次数
var gameFirstTime, gameFreeFirstTime, gamedifFirstTime time.Time var gameFirstTime, gameFreeFirstTime time.Time
var gameTimes, gameFreeTimes, gamedifTimes int64 var gameTimes, gameFreeTimes int64
data, ok := this.GDatas[this.scene.KeyGamefreeId] data, ok := this.GDatas[this.scene.KeyGamefreeId]
if ok { if ok {
gameFreeFirstTime = data.FirstTime gameFirstTime = data.FirstTime
gameFreeTimes = data.Statics.GameTimes gameTimes = data.Statics.GameTimes
} }
// 记录玩家 首次参与该游戏时间 游戏次数(不区分场次) // 记录玩家 首次参与该游戏时间 游戏次数(不区分场次)
dataGame, ok := this.GDatas[this.scene.KeyGameId] dataGame, ok := this.GDatas[this.scene.KeyGameId]
if ok { if ok {
gameFirstTime = dataGame.FirstTime gameFreeFirstTime = dataGame.FirstTime
gameTimes = dataGame.Statics.GameTimes gameFreeTimes = dataGame.Statics.GameTimes
}
dataGameDif, ok := this.GDatas[common.GetKeyGameDif(this.scene.GetDBGameFree().GetGameDif())]
if ok {
gamedifFirstTime = dataGameDif.FirstTime
gamedifTimes = dataGameDif.Statics.GameTimes
} }
isNew := int32(0) isNew := int32(0)
@ -675,32 +668,30 @@ func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEven
var ret ReportGameEventOnly var ret ReportGameEventOnly
ret.Param = param ret.Param = param
log := &model.PlayerGameRecEvent{ log := &model.PlayerGameRecEvent{
Id: primitive.NewObjectID().Hex(), Platform: this.Platform,
RecordId: this.scene.GetRecordId(), RecordId: this.scene.GetRecordId(),
SnId: this.GetSnId(), SnId: this.GetSnId(),
Channel: this.Channel, Channel: this.Channel,
Platform: this.Platform, ChannelId: this.ChannelId,
OS: this.DeviceOS, City: this.City,
GameId: this.scene.GameId, OS: this.DeviceOS,
ModeId: this.scene.GameMode, GameId: this.scene.GameId,
Tax: param.Tax, ModeId: this.scene.GameMode,
Amount: param.Change, Tax: param.Tax,
CreateTime: time.Now().Unix(), Amount: param.Change,
CreateDayTime: tCreateDay.Unix(), CreateTime: time.Now().Unix(),
Out: param.Out, CreateDayTime: tCreateDay.Unix(),
In: param.In, Out: param.Out,
IsNew: isNew, In: param.In,
GameFreeID: this.scene.GetGameFreeId(), IsNew: isNew,
GamingTime: int32(param.GameTime), GameFreeID: this.scene.GetGameFreeId(),
GameDif: this.scene.GetDBGameFree().GetGameDif(), GamingTime: int32(param.GameTime),
FirstGameDifTime: gamedifFirstTime.Unix(), FirstTime: gameFirstTime.Unix(),
GameDifTimes: gamedifTimes, PlayTimes: gameTimes,
FirstTime: gameFreeFirstTime.Unix(), FirstGameTime: gameFreeFirstTime.Unix(),
PlayTimes: gameFreeTimes, PlayGameTimes: gameFreeTimes,
FirstGameTime: gameFirstTime.Unix(), LastLoginTime: this.LastLoginTime.Unix(),
PlayGameTimes: gameTimes, DeviceId: this.DeviceId,
LastLoginTime: this.LastLoginTime.Unix(),
ChannelId: this.ChannelId,
} }
if param.OnlyLog { if param.OnlyLog {
ret.Log = append(ret.Log, log) ret.Log = append(ret.Log, log)

View File

@ -2057,7 +2057,6 @@ func (this *Scene) IsControl(hasRobotGaming bool) bool {
// Statistics 玩家游戏数据统计 // Statistics 玩家游戏数据统计
// 包含水池统计,黑白名单统计,新手调控统计,个人水池统计 // 包含水池统计,黑白名单统计,新手调控统计,个人水池统计
// 拉霸游戏数据统计,一次下注记录一次 StaticsLaba
func (this *Scene) Statistics(param *StaticParam) { func (this *Scene) Statistics(param *StaticParam) {
if param == nil { if param == nil {
return return
@ -2111,7 +2110,6 @@ func (this *Scene) Statistics(param *StaticParam) {
var statics []*model.PlayerGameStatics var statics []*model.PlayerGameStatics
keyGameId := strconv.Itoa(this.GetGameId()) keyGameId := strconv.Itoa(this.GetGameId())
keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId())) keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId()))
keyGameDif := common.GetKeyGameDif(this.GetDBGameFree().GetGameDif())
// 当天数据统计 // 当天数据统计
// 按场次分 // 按场次分
if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok { if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok {
@ -2129,14 +2127,6 @@ func (this *Scene) Statistics(param *StaticParam) {
p.TodayGameData.CtrlData[keyGameId] = data p.TodayGameData.CtrlData[keyGameId] = data
statics = append(statics, data) statics = append(statics, data)
} }
// 按游戏组分
if data, ok := p.TodayGameData.CtrlData[keyGameDif]; ok {
statics = append(statics, data)
} else {
data = model.NewPlayerGameStatics()
p.TodayGameData.CtrlData[keyGameDif] = data
statics = append(statics, data)
}
// 按场次分 // 按场次分
if data, ok := p.GDatas[keyGameFreeId]; ok { if data, ok := p.GDatas[keyGameFreeId]; ok {
if data.FirstTime.IsZero() { if data.FirstTime.IsZero() {
@ -2159,27 +2149,6 @@ func (this *Scene) Statistics(param *StaticParam) {
p.GDatas[keyGameId] = data p.GDatas[keyGameId] = data
statics = append(statics, &data.Statics) statics = append(statics, &data.Statics)
} }
//按游戏组分
getMinTime := func() time.Time {
var minTime = time.Now()
for _, v := range srvdata.GameFreeMgr.GetGameId(this.GetDBGameFree().GetGameDif()) {
vv := p.GDatas[strconv.Itoa(int(v))]
if vv != nil && vv.FirstTime.Before(minTime) {
minTime = vv.FirstTime
}
}
return minTime
}
if data, ok := p.GDatas[keyGameDif]; ok {
if data.FirstTime.IsZero() {
data.FirstTime = getMinTime()
}
statics = append(statics, &data.Statics)
} else {
data = &model.PlayerGameInfo{FirstTime: getMinTime()}
p.GDatas[keyGameDif] = data
statics = append(statics, &data.Statics)
}
// 新手输赢统计 // 新手输赢统计
if !model.GameParamData.CloseNovice && !common.InSliceInt(model.GameParamData.CloseNoviceGame, int(this.GameId)) && isControl && wbLevel == 0 && isNovice { if !model.GameParamData.CloseNovice && !common.InSliceInt(model.GameParamData.CloseNoviceGame, int(this.GameId)) && isControl && wbLevel == 0 && isNovice {
@ -2350,7 +2319,6 @@ func (this *Scene) StaticsLaba(param *StaticLabaParam) {
var statics []*model.PlayerGameStatics var statics []*model.PlayerGameStatics
keyGameId := strconv.Itoa(this.GetGameId()) keyGameId := strconv.Itoa(this.GetGameId())
keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId())) keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId()))
keyGameDif := common.GetKeyGameDif(this.GetDBGameFree().GetGameDif())
// 当天数据统计 // 当天数据统计
// 按场次分 // 按场次分
if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok { if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok {
@ -2368,14 +2336,6 @@ func (this *Scene) StaticsLaba(param *StaticLabaParam) {
p.TodayGameData.CtrlData[keyGameId] = data p.TodayGameData.CtrlData[keyGameId] = data
statics = append(statics, data) statics = append(statics, data)
} }
// 按游戏组
if data, ok := p.TodayGameData.CtrlData[keyGameDif]; ok {
statics = append(statics, data)
} else {
data = model.NewPlayerGameStatics()
p.TodayGameData.CtrlData[keyGameDif] = data
statics = append(statics, data)
}
// 按场次分 // 按场次分
if data, ok := p.GDatas[keyGameFreeId]; ok { if data, ok := p.GDatas[keyGameFreeId]; ok {
if data.FirstTime.IsZero() { if data.FirstTime.IsZero() {
@ -2398,27 +2358,6 @@ func (this *Scene) StaticsLaba(param *StaticLabaParam) {
p.GDatas[keyGameId] = data p.GDatas[keyGameId] = data
statics = append(statics, &data.Statics) statics = append(statics, &data.Statics)
} }
// 按游戏组
getMinTime := func() time.Time {
var minTime = time.Now()
for _, v := range srvdata.GameFreeMgr.GetGameId(this.GetDBGameFree().GetGameDif()) {
vv := p.GDatas[strconv.Itoa(int(v))]
if vv != nil && vv.FirstTime.Before(minTime) {
minTime = vv.FirstTime
}
}
return minTime
}
if data, ok := p.GDatas[keyGameDif]; ok {
if data.FirstTime.IsZero() {
data.FirstTime = getMinTime()
}
statics = append(statics, &data.Statics)
} else {
data = &model.PlayerGameInfo{FirstTime: getMinTime()}
p.GDatas[keyGameDif] = data
statics = append(statics, &data.Statics)
}
for _, data := range statics { for _, data := range statics {
if data != nil { if data != nil {

View File

@ -1035,6 +1035,8 @@ func CaiShenCheckAndSaveLog(sceneEx *CaiShenSceneData, playerEx *CaiShenPlayerDa
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -1315,6 +1315,8 @@ func (this *SceneStateBilled) OnEnter(s *base.Scene) {
Platform: o_player.Platform, Platform: o_player.Platform,
Snid: o_player.UserId, Snid: o_player.UserId,
PlayerName: "", PlayerName: "",
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: o_player.GainTaxCoin, TaxCoin: o_player.GainTaxCoin,

View File

@ -795,6 +795,8 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -904,6 +904,8 @@ func EasterIslandCheckAndSaveLog(sceneEx *EasterIslandSceneData, playerEx *Easte
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -267,6 +267,8 @@ func (this *FishingPlayerData) SaveDetailedLog(s *base.Scene) {
Platform: this.Platform, Platform: this.Platform,
Snid: this.SnId, Snid: this.SnId,
PlayerName: this.Name, PlayerName: this.Name,
Channel: this.Channel,
ChannelId: this.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: int64(this.sTaxCoin), TaxCoin: int64(this.sTaxCoin),

View File

@ -281,7 +281,7 @@ func (this *SceneBaseStateFishing) OnPlayerOp(s *base.Scene, p *base.Player, opc
// start 检测当前房间是否处于基本的关闭状态 // start 检测当前房间是否处于基本的关闭状态
if s.CheckNeedDestroy() { if s.CheckNeedDestroy() {
if sceneEx.hDestroy == timer.InvalidTimerHandle { if sceneEx.hDestroy == timer.InvalidTimerHandle {
if hNext, ok := common.DelayInvoke(func() { if hNext, ok := common.DelayInvake(func() {
sceneEx.hDestroy = timer.InvalidTimerHandle sceneEx.hDestroy = timer.InvalidTimerHandle
sceneEx.SceneDestroy(true) sceneEx.SceneDestroy(true)
}, nil, time.Second*10, 1); ok { }, nil, time.Second*10, 1); ok {

View File

@ -8,7 +8,6 @@ import (
type FortuneDragonPlayerData struct { type FortuneDragonPlayerData struct {
*base.Player *base.Player
base.LabaLog
leaveTime int32 //离开时间 leaveTime int32 //离开时间
SlotsSession *base.SlotsSession SlotsSession *base.SlotsSession
@ -32,7 +31,6 @@ func (p *FortuneDragonPlayerData) Clear() {
p.taxCoin = 0 p.taxCoin = 0
p.winCoin = 0 p.winCoin = 0
p.currentLogId = "" p.currentLogId = ""
p.LabaLog.Clear()
} }
// 需要带到world上进行数据处理 // 需要带到world上进行数据处理

View File

@ -112,7 +112,6 @@ func (this *ScenePolicyFortuneDragon) OnPlayerLeave(s *base.Scene, p *base.Playe
} }
logger.Logger.Trace("(this *ScenePolicyFortuneDragon) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) logger.Logger.Trace("(this *ScenePolicyFortuneDragon) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId)
if playerEx, ok := p.ExtraData.(*FortuneDragonPlayerData); ok { if playerEx, ok := p.ExtraData.(*FortuneDragonPlayerData); ok {
playerEx.Save(2)
m := playerEx.PushPlayer() m := playerEx.PushPlayer()
if m != nil && len(m) > 0 { if m != nil && len(m) > 0 {
b, err := json.Marshal(m) b, err := json.Marshal(m)
@ -477,8 +476,6 @@ func (this *SceneStateStartFortuneDragon) OnPlayerOp(s *base.Scene, p *base.Play
// 记录本次操作 // 记录本次操作
FortuneDragonAndSaveLog(sceneEx, playerEx, data) FortuneDragonAndSaveLog(sceneEx, playerEx, data)
case 1000:
playerEx.Save(0)
} }
} }
} }
@ -523,6 +520,11 @@ func FortuneDragonAndSaveLog(sceneEx *FortuneDragonSceneData, playerEx *FortuneD
if err == nil { if err == nil {
logid, _ := model.AutoIncGameLogId() logid, _ := model.AutoIncGameLogId()
playerEx.currentLogId = logid playerEx.currentLogId = logid
sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{
LogId: logid,
Detail: info,
GameTime: 2,
})
var totalin, totalout int64 var totalin, totalout int64
if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 { if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 {
totalin = playerEx.totalBet totalin = playerEx.totalBet
@ -530,14 +532,13 @@ func FortuneDragonAndSaveLog(sceneEx *FortuneDragonSceneData, playerEx *FortuneD
if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 { if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 {
totalout = int64(data.RoundReward) + playerEx.taxCoin totalout = int64(data.RoundReward) + playerEx.taxCoin
} }
playerEx.Cache(sceneEx.Scene, &base.SaveGameDetailedParam{ sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{
LogId: logid,
Detail: info,
}, &base.SaveGamePlayerListLogParam{
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -545,6 +546,7 @@ func FortuneDragonAndSaveLog(sceneEx *FortuneDragonSceneData, playerEx *FortuneD
WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin, WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin,
IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player), IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player),
IsFree: playerEx.isFree, IsFree: playerEx.isFree,
GameTime: 2,
}) })
} }
} }

View File

@ -8,7 +8,6 @@ import (
type FortuneMousePlayerData struct { type FortuneMousePlayerData struct {
*base.Player *base.Player
base.LabaLog
leaveTime int32 //离开时间 leaveTime int32 //离开时间
SlotsSession *base.SlotsSession SlotsSession *base.SlotsSession
@ -38,7 +37,6 @@ func (p *FortuneMousePlayerData) Clear() {
p.taxCoin = 0 p.taxCoin = 0
p.winCoin = 0 p.winCoin = 0
p.currentLogId = "" p.currentLogId = ""
p.LabaLog.Clear()
} }
// 需要带到world上进行数据处理 // 需要带到world上进行数据处理

View File

@ -111,7 +111,6 @@ func (this *ScenePolicyFortuneMouse) OnPlayerLeave(s *base.Scene, p *base.Player
} }
logger.Logger.Trace("(this *ScenePolicyFortuneMouse) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) logger.Logger.Trace("(this *ScenePolicyFortuneMouse) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId)
if playerEx, ok := p.ExtraData.(*FortuneMousePlayerData); ok { if playerEx, ok := p.ExtraData.(*FortuneMousePlayerData); ok {
playerEx.Save(2)
m := playerEx.PushPlayer() m := playerEx.PushPlayer()
if m != nil && len(m) > 0 { if m != nil && len(m) > 0 {
b, err := json.Marshal(m) b, err := json.Marshal(m)
@ -481,8 +480,6 @@ func (this *SceneStateStartFortuneMouse) OnPlayerOp(s *base.Scene, p *base.Playe
// 记录本次操作 // 记录本次操作
FortuneMouseAndSaveLog(sceneEx, playerEx, data) FortuneMouseAndSaveLog(sceneEx, playerEx, data)
case 1000:
playerEx.Save(0)
} }
} }
} }
@ -527,13 +524,18 @@ func FortuneMouseAndSaveLog(sceneEx *FortuneMouseSceneData, playerEx *FortuneMou
json.Unmarshal(sp, &spinLock) json.Unmarshal(sp, &spinLock)
respinStatus = spinLock.ReSpinStatus respinStatus = spinLock.ReSpinStatus
} }
if respinStatus != 0 && respinStatus != 1 { if respinStatus == 0 || respinStatus == 1 {
data.TotalBet = 0 data.TotalBet = 0
} }
info, err := model.MarshalGameNoteByROLL(data) info, err := model.MarshalGameNoteByROLL(data)
if err == nil { if err == nil {
logid, _ := model.AutoIncGameLogId() logid, _ := model.AutoIncGameLogId()
playerEx.currentLogId = logid playerEx.currentLogId = logid
sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{
LogId: logid,
Detail: info,
GameTime: 2,
})
var totalin, totalout int64 var totalin, totalout int64
if respinStatus == 0 || respinStatus == 1 { if respinStatus == 0 || respinStatus == 1 {
totalin = playerEx.totalBet totalin = playerEx.totalBet
@ -541,21 +543,21 @@ func FortuneMouseAndSaveLog(sceneEx *FortuneMouseSceneData, playerEx *FortuneMou
if respinStatus == 0 || respinStatus == 3 { if respinStatus == 0 || respinStatus == 3 {
totalout = int64(data.RoundReward) + playerEx.taxCoin totalout = int64(data.RoundReward) + playerEx.taxCoin
} }
playerEx.Cache(sceneEx.Scene, &base.SaveGameDetailedParam{ sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{
LogId: logid,
Detail: info,
}, &base.SaveGamePlayerListLogParam{
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
BetAmount: totalin, BetAmount: playerEx.totalBet,
WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin, WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin,
IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player), IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player),
IsFree: totalin == 0, IsFree: totalin == 0,
GameTime: 2,
}) })
} }
} }

View File

@ -8,7 +8,6 @@ import (
type FortuneOxPlayerData struct { type FortuneOxPlayerData struct {
*base.Player *base.Player
base.LabaLog
leaveTime int32 //离开时间 leaveTime int32 //离开时间
SlotsSession *base.SlotsSession SlotsSession *base.SlotsSession
@ -38,7 +37,6 @@ func (p *FortuneOxPlayerData) Clear() {
p.taxCoin = 0 p.taxCoin = 0
p.winCoin = 0 p.winCoin = 0
p.currentLogId = "" p.currentLogId = ""
p.LabaLog.Clear()
} }
// 需要带到world上进行数据处理 // 需要带到world上进行数据处理

View File

@ -111,7 +111,6 @@ func (this *ScenePolicyFortuneOx) OnPlayerLeave(s *base.Scene, p *base.Player, r
} }
logger.Logger.Trace("(this *ScenePolicyFortuneOx) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) logger.Logger.Trace("(this *ScenePolicyFortuneOx) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId)
if playerEx, ok := p.ExtraData.(*FortuneOxPlayerData); ok { if playerEx, ok := p.ExtraData.(*FortuneOxPlayerData); ok {
playerEx.Save(2)
m := playerEx.PushPlayer() m := playerEx.PushPlayer()
if m != nil && len(m) > 0 { if m != nil && len(m) > 0 {
b, err := json.Marshal(m) b, err := json.Marshal(m)
@ -481,8 +480,6 @@ func (this *SceneStateStartFortuneOx) OnPlayerOp(s *base.Scene, p *base.Player,
// 记录本次操作 // 记录本次操作
FortuneOxAndSaveLog(sceneEx, playerEx, data) FortuneOxAndSaveLog(sceneEx, playerEx, data)
case 1000:
playerEx.Save(0)
} }
} }
} }
@ -530,10 +527,16 @@ func FortuneOxAndSaveLog(sceneEx *FortuneOxSceneData, playerEx *FortuneOxPlayerD
if respinStatus != 0 && respinStatus != 1 { if respinStatus != 0 && respinStatus != 1 {
data.TotalBet = 0 data.TotalBet = 0
} }
info, err := model.MarshalGameNoteByROLL(data) info, err := model.MarshalGameNoteByROLL(data)
if err == nil { if err == nil {
logid, _ := model.AutoIncGameLogId() logid, _ := model.AutoIncGameLogId()
playerEx.currentLogId = logid playerEx.currentLogId = logid
sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{
LogId: logid,
Detail: info,
GameTime: 2,
})
var totalin, totalout int64 var totalin, totalout int64
if respinStatus == 0 || respinStatus == 1 { if respinStatus == 0 || respinStatus == 1 {
totalin = playerEx.totalBet totalin = playerEx.totalBet
@ -541,14 +544,13 @@ func FortuneOxAndSaveLog(sceneEx *FortuneOxSceneData, playerEx *FortuneOxPlayerD
if respinStatus == 0 || respinStatus == 3 { if respinStatus == 0 || respinStatus == 3 {
totalout = int64(data.RoundReward) + playerEx.taxCoin totalout = int64(data.RoundReward) + playerEx.taxCoin
} }
playerEx.Cache(sceneEx.Scene, &base.SaveGameDetailedParam{ sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{
LogId: logid,
Detail: info,
}, &base.SaveGamePlayerListLogParam{
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -556,6 +558,7 @@ func FortuneOxAndSaveLog(sceneEx *FortuneOxSceneData, playerEx *FortuneOxPlayerD
WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin, WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin,
IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player), IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player),
IsFree: totalin == 0, IsFree: totalin == 0,
GameTime: 2,
}) })
} }
} }

View File

@ -8,7 +8,6 @@ import (
type FortuneRabbitPlayerData struct { type FortuneRabbitPlayerData struct {
*base.Player *base.Player
base.LabaLog
leaveTime int32 //离开时间 leaveTime int32 //离开时间
SlotsSession *base.SlotsSession SlotsSession *base.SlotsSession
@ -32,7 +31,6 @@ func (p *FortuneRabbitPlayerData) Clear() {
p.taxCoin = 0 p.taxCoin = 0
p.winCoin = 0 p.winCoin = 0
p.currentLogId = "" p.currentLogId = ""
p.LabaLog.Clear()
} }
// 需要带到world上进行数据处理 // 需要带到world上进行数据处理

View File

@ -111,7 +111,6 @@ func (this *ScenePolicyFortuneRabbit) OnPlayerLeave(s *base.Scene, p *base.Playe
} }
logger.Logger.Trace("(this *ScenePolicyFortuneRabbit) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) logger.Logger.Trace("(this *ScenePolicyFortuneRabbit) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId)
if playerEx, ok := p.ExtraData.(*FortuneRabbitPlayerData); ok { if playerEx, ok := p.ExtraData.(*FortuneRabbitPlayerData); ok {
playerEx.LabaLog.Save(2) // 没有收到结束消息算2秒游戏时长
m := playerEx.PushPlayer() m := playerEx.PushPlayer()
if m != nil && len(m) > 0 { if m != nil && len(m) > 0 {
b, err := json.Marshal(m) b, err := json.Marshal(m)
@ -475,9 +474,6 @@ func (this *SceneStateStartFortuneRabbit) OnPlayerOp(s *base.Scene, p *base.Play
// 记录本次操作 // 记录本次操作
FortuneRabbitAndSaveLog(sceneEx, playerEx, data) FortuneRabbitAndSaveLog(sceneEx, playerEx, data)
case 1000:
playerEx.Save(0)
} }
} }
} }
@ -522,6 +518,11 @@ func FortuneRabbitAndSaveLog(sceneEx *FortuneRabbitSceneData, playerEx *FortuneR
if err == nil { if err == nil {
logid, _ := model.AutoIncGameLogId() logid, _ := model.AutoIncGameLogId()
playerEx.currentLogId = logid playerEx.currentLogId = logid
sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{
LogId: logid,
Detail: info,
GameTime: 2,
})
var totalin, totalout int64 var totalin, totalout int64
if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 { if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 {
totalin = playerEx.totalBet totalin = playerEx.totalBet
@ -529,14 +530,13 @@ func FortuneRabbitAndSaveLog(sceneEx *FortuneRabbitSceneData, playerEx *FortuneR
if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 { if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 {
totalout = int64(data.RoundReward) + playerEx.taxCoin totalout = int64(data.RoundReward) + playerEx.taxCoin
} }
playerEx.Cache(sceneEx.Scene, &base.SaveGameDetailedParam{ sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{
LogId: logid,
Detail: info,
}, &base.SaveGamePlayerListLogParam{
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -544,6 +544,7 @@ func FortuneRabbitAndSaveLog(sceneEx *FortuneRabbitSceneData, playerEx *FortuneR
WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin, WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin,
IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player), IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player),
IsFree: playerEx.isFree, IsFree: playerEx.isFree,
GameTime: 2,
}) })
} }
} }

View File

@ -8,7 +8,6 @@ import (
type FortuneTigerPlayerData struct { type FortuneTigerPlayerData struct {
*base.Player *base.Player
base.LabaLog
leaveTime int32 //离开时间 leaveTime int32 //离开时间
SlotsSession *base.SlotsSession SlotsSession *base.SlotsSession
@ -41,7 +40,6 @@ func (p *FortuneTigerPlayerData) Clear() {
p.taxCoin = 0 p.taxCoin = 0
p.winCoin = 0 p.winCoin = 0
p.currentLogId = "" p.currentLogId = ""
p.LabaLog.Clear()
} }
// 需要带到world上进行数据处理 // 需要带到world上进行数据处理

View File

@ -111,7 +111,6 @@ func (this *ScenePolicyFortuneTiger) OnPlayerLeave(s *base.Scene, p *base.Player
} }
logger.Logger.Trace("(this *ScenePolicyFortuneTiger) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) logger.Logger.Trace("(this *ScenePolicyFortuneTiger) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId)
if playerEx, ok := p.ExtraData.(*FortuneTigerPlayerData); ok { if playerEx, ok := p.ExtraData.(*FortuneTigerPlayerData); ok {
playerEx.LabaLog.Save(2) // 没有收到结束消息算2秒游戏时长
m := playerEx.PushPlayer() m := playerEx.PushPlayer()
if m != nil && len(m) > 0 { if m != nil && len(m) > 0 {
b, err := json.Marshal(m) b, err := json.Marshal(m)
@ -481,9 +480,6 @@ func (this *SceneStateStartFortuneTiger) OnPlayerOp(s *base.Scene, p *base.Playe
// 记录本次操作 // 记录本次操作
FortuneTigerAndSaveLog(sceneEx, playerEx, data) FortuneTigerAndSaveLog(sceneEx, playerEx, data)
case 1000:
playerEx.Save(0)
} }
} }
} }
@ -521,20 +517,18 @@ func (this *ScenePolicyFortuneTiger) GetSceneState(s *base.Scene, stateid int) b
func FortuneTigerAndSaveLog(sceneEx *FortuneTigerSceneData, playerEx *FortuneTigerPlayerData, data assemble.GameEnd) { func FortuneTigerAndSaveLog(sceneEx *FortuneTigerSceneData, playerEx *FortuneTigerPlayerData, data assemble.GameEnd) {
if !playerEx.IsRob { if !playerEx.IsRob {
data.SnId = playerEx.SnId data.SnId = playerEx.SnId
var respinStatus int if data.Results[0].FreeStatus != 1 && data.Results[0].FreeNumMax != 0 {
if data.Results[0].ArrSpins[0].Special != nil {
sp, _ := json.Marshal(data.Results[0].ArrSpins[0].Special)
var spinLock SpinLock
json.Unmarshal(sp, &spinLock)
respinStatus = spinLock.ReSpinStatus
}
if respinStatus != 0 && respinStatus != 1 {
data.TotalBet = 0 data.TotalBet = 0
} }
info, err := model.MarshalGameNoteByROLL(data) info, err := model.MarshalGameNoteByROLL(data)
if err == nil { if err == nil {
logid, _ := model.AutoIncGameLogId() logid, _ := model.AutoIncGameLogId()
playerEx.currentLogId = logid playerEx.currentLogId = logid
sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{
LogId: logid,
Detail: info,
GameTime: 2,
})
var totalin, totalout int64 var totalin, totalout int64
if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 { if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 {
totalin = playerEx.totalBet totalin = playerEx.totalBet
@ -542,14 +536,13 @@ func FortuneTigerAndSaveLog(sceneEx *FortuneTigerSceneData, playerEx *FortuneTig
if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 { if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 {
totalout = int64(data.RoundReward) + playerEx.taxCoin totalout = int64(data.RoundReward) + playerEx.taxCoin
} }
playerEx.Cache(sceneEx.Scene, &base.SaveGameDetailedParam{ sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{
LogId: logid,
Detail: info,
}, &base.SaveGamePlayerListLogParam{
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -557,6 +550,7 @@ func FortuneTigerAndSaveLog(sceneEx *FortuneTigerSceneData, playerEx *FortuneTig
WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin, WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin,
IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player), IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player),
IsFree: totalin == 0, IsFree: totalin == 0,
GameTime: 2,
}) })
} }
} }

View File

@ -345,6 +345,8 @@ func (s *FruitsSceneData) SaveLog(p *FruitsPlayerData, isOffline int) {
Platform: p.Platform, Platform: p.Platform,
Snid: p.SnId, Snid: p.SnId,
PlayerName: p.Name, PlayerName: p.Name,
Channel: p.Channel,
ChannelId: p.ChannelId,
TotalIn: totalIn, TotalIn: totalIn,
TotalOut: totalOut, TotalOut: totalOut,
TaxCoin: p.taxCoin, TaxCoin: p.taxCoin,

View File

@ -954,6 +954,8 @@ func IceAgeCheckAndSaveLog(sceneEx *IceAgeSceneData, playerEx *IceAgePlayerData)
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -367,6 +367,8 @@ func (s *RichBlessedSceneData) SaveLog(p *RichBlessedPlayerData, isOffline int)
Platform: p.Platform, Platform: p.Platform,
Snid: p.SnId, Snid: p.SnId,
PlayerName: p.Name, PlayerName: p.Name,
Channel: p.Channel,
ChannelId: p.ChannelId,
TotalIn: totalIn, TotalIn: totalIn,
TotalOut: totalOut, TotalOut: totalOut,
TaxCoin: p.taxCoin, TaxCoin: p.taxCoin,

View File

@ -1179,6 +1179,8 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -1256,6 +1258,8 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -790,6 +790,8 @@ func TamQuocCheckAndSaveLog(sceneEx *TamQuocSceneData, playerEx *TamQuocPlayerDa
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -1,8 +1,6 @@
package thirteen package thirteen
import ( import (
"time"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
"mongo.games.com/game/gamerule/thirteen" "mongo.games.com/game/gamerule/thirteen"
@ -27,10 +25,7 @@ type PlayerEx struct {
odds int32 odds int32
totalScore int64 totalScore int64
defGroup *thirteen.Group defGroup *thirteen.Group
playerPool int // 个人水池分 playerPool int // 个人水池分
AutoState int // 是否自动模式
AutoMill time.Duration // 自动时长
HandMill time.Duration // 手动时长
} }
func (this *PlayerEx) Clear() { func (this *PlayerEx) Clear() {
@ -47,9 +42,6 @@ func (this *PlayerEx) Clear() {
this.gainCoin = 0 this.gainCoin = 0
this.taxCoin = 0 this.taxCoin = 0
this.deterMine = false this.deterMine = false
this.AutoState = 0
this.AutoMill = time.Duration(0)
this.HandMill = time.Duration(0)
this.score = [7]int64{0, 0, 0, 0, 0, 0, 0} this.score = [7]int64{0, 0, 0, 0, 0, 0, 0}
this.tableScore = [6]int64{} this.tableScore = [6]int64{}
this.winThreePos = make(map[int]int64) this.winThreePos = make(map[int]int64)

View File

@ -86,7 +86,6 @@ type SceneEx struct {
ctrlType int // 1控赢 2控输 0不控 ctrlType int // 1控赢 2控输 0不控
cardsArr [][13]int cardsArr [][13]int
cardsGroup []map[int]*rule.Group cardsGroup []map[int]*rule.Group
timestamp time.Time
} }
func NewThirteenWaterSceneData(s *base.Scene) *SceneEx { func NewThirteenWaterSceneData(s *base.Scene) *SceneEx {

View File

@ -4,7 +4,6 @@ import (
"strconv" "strconv"
"time" "time"
"go.mongodb.org/mongo-driver/bson/primitive"
"mongo.games.com/goserver/core" "mongo.games.com/goserver/core"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
@ -12,7 +11,6 @@ import (
rule "mongo.games.com/game/gamerule/thirteen" rule "mongo.games.com/game/gamerule/thirteen"
"mongo.games.com/game/gamesrv/base" "mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/model" "mongo.games.com/game/model"
"mongo.games.com/game/mq"
"mongo.games.com/game/proto" "mongo.games.com/game/proto"
"mongo.games.com/game/protocol/thirteen" "mongo.games.com/game/protocol/thirteen"
) )
@ -190,6 +188,8 @@ func (this *PolicyThirteen) OnPlayerLeave(s *base.Scene, p *base.Player, reason
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -810,11 +810,6 @@ func (this *StateOp) OnEnter(s *base.Scene) {
logger.Logger.Tracef("(this *StateOp) OnEnter, sceneid=%v", s.GetSceneId()) logger.Logger.Tracef("(this *StateOp) OnEnter, sceneid=%v", s.GetSceneId())
this.BaseState.OnEnter(s) this.BaseState.OnEnter(s)
ThirteenWaterBroadcastRoomState(s) ThirteenWaterBroadcastRoomState(s)
sceneEx, ok := s.ExtraData.(*SceneEx)
if !ok {
return
}
sceneEx.timestamp = time.Now()
} }
// 玩家操作 // 玩家操作
@ -833,34 +828,38 @@ func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, param
return false return false
} }
returnFunc := func(code thirteen.OpResultCode, broadcast bool) { returnFunc := func(code thirteen.OpResultCode) {
pack := &thirteen.SCThirteenPlayerOp{ pack := &thirteen.SCThirteenPlayerOp{
OpRetCode: code, OpRetCode: code,
OpCode: int32(opcode), OpCode: int32(opcode),
OpParam: params, OpParam: params,
Pos: int32(playerEx.GetPos()), Pos: int32(playerEx.GetPos()),
} }
if broadcast { if code == thirteen.OpResultCode_OPRC_Error {
playerEx.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack, 0) proto.SetDefaults(pack)
} else { logger.Logger.Trace("SCThirteenPlayerOp:", pack)
playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack) playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack)
return
} }
logger.Logger.Trace("SCThirteenPlayerOp:", pack)
} }
if !playerEx.IsGameing() { if !playerEx.IsGameing() {
returnFunc(thirteen.OpResultCode_OPRC_Error, false) returnFunc(thirteen.OpResultCode_OPRC_Error)
return true return true
} }
switch opcode { switch opcode {
case rule.ThirteenWaterPlayerOpMS: //确定牌 case rule.ThirteenWaterPlayerOpMS: //确定牌
//if playerEx.deterMine { // 确认牌型
// returnFunc(thirteen.OpResultCode_OPRC_Error)
// return false
//}
if len(params) == 13 { if len(params) == 13 {
//校验牌 //校验牌
a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params)) a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params))
if len(a) != 0 { if len(a) != 0 {
logger.Logger.Error("the cards is error.") logger.Logger.Error("the cards is error.")
returnFunc(thirteen.OpResultCode_OPRC_Error, false) returnFunc(thirteen.OpResultCode_OPRC_Error)
return true return true
} }
//牌赋值 //牌赋值
@ -876,7 +875,6 @@ func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, param
playerEx.Trusteeship = 0 playerEx.Trusteeship = 0
playerEx.UnmarkFlag(base.PlayerState_Auto) playerEx.UnmarkFlag(base.PlayerState_Auto)
playerEx.deterMine = true playerEx.deterMine = true
playerEx.AutoState = 0
//如果所有玩家都确认牌之后 可以直接开始下一阶段 //如果所有玩家都确认牌之后 可以直接开始下一阶段
a := true a := true
for _, v := range sceneEx.players { for _, v := range sceneEx.players {
@ -896,70 +894,38 @@ func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, param
playerEx.cardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1} playerEx.cardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1}
playerEx.Trusteeship = 0 playerEx.Trusteeship = 0
playerEx.UnmarkFlag(base.PlayerState_Auto) playerEx.UnmarkFlag(base.PlayerState_Auto)
pack := &thirteen.SCThirteenPlayerOp{
OpRetCode: thirteen.OpResultCode_OPRC_Sucess,
OpCode: int32(opcode),
OpParam: params,
Pos: int32(playerEx.GetPos()),
}
if len(params) == 13 { if len(params) == 13 {
//校验牌 //校验牌
remain := len(playerEx.cards) a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params))
remainCards := make([]int, remain) if len(a) != 0 {
copy(remainCards, playerEx.cards[:]) logger.Logger.Error("the cards is error.")
for _, v := range params { returnFunc(thirteen.OpResultCode_OPRC_Error)
if v >= 0 { return true
a := rule.DelCards(remainCards, []int{int(v)})
if len(a) == remain {
logger.Logger.Error("the cards is error.")
returnFunc(thirteen.OpResultCode_OPRC_Error, false)
return true
}
remain = len(a)
remainCards = a
}
} }
//牌赋值 //牌赋值
copy(playerEx.preCardsO.Head[:], common.Int64Toint(params[:3])) copy(playerEx.preCardsO.Head[:], common.Int64Toint(params[:3]))
copy(playerEx.preCardsO.Mid[:], common.Int64Toint(params[3:8])) copy(playerEx.preCardsO.Mid[:], common.Int64Toint(params[3:8]))
copy(playerEx.preCardsO.End[:], common.Int64Toint(params[8:])) copy(playerEx.preCardsO.End[:], common.Int64Toint(params[8:]))
playerEx.preCardsO.PokerType = 0 playerEx.preCardsO.PokerType = 0
for k, v := range playerEx.preCardsO.Head {
if v < 0 {
playerEx.preCardsO.Head[k] = remainCards[0]
remainCards = remainCards[1:]
}
}
for k, v := range playerEx.preCardsO.Mid {
if v < 0 {
playerEx.preCardsO.Mid[k] = remainCards[0]
remainCards = remainCards[1:]
}
}
for k, v := range playerEx.preCardsO.End {
if v < 0 {
playerEx.preCardsO.End[k] = remainCards[0]
remainCards = remainCards[1:]
}
}
} }
playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack)
if len(params) == 1 {
sceneEx.SelectCards(playerEx, int(params[0]))
}
if len(params) == 0 {
playerEx.preCardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1}
}
returnFunc(thirteen.OpResultCode_OPRC_Sucess, true)
case rule.ThirteenWaterPlayerOpReset: case rule.ThirteenWaterPlayerOpReset:
// 取消确认 // 取消确认
playerEx.deterMine = false playerEx.deterMine = false
returnFunc(thirteen.OpResultCode_OPRC_Sucess, true) pack := &thirteen.SCThirteenPlayerOp{
OpRetCode: thirteen.OpResultCode_OPRC_Sucess,
case rule.ThirteenWaterPlayerOpAuto: OpCode: int32(opcode),
if len(params) == 0 { OpParam: params,
return true Pos: int32(playerEx.GetPos()),
} }
playerEx.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack, 0)
playerEx.AutoState = int(params[0])
default: default:
return false return false
@ -977,19 +943,6 @@ func (this *StateOp) OnLeave(s *base.Scene) {
for _, player := range sceneEx.players { for _, player := range sceneEx.players {
if player != nil && player.IsGameing() { if player != nil && player.IsGameing() {
if !player.IsRobot() {
mq.Write(model.ThirteenAutoLog{
Id: primitive.NewObjectID().Hex(),
Platform: player.Platform,
LogId: sceneEx.logid,
SnId: player.SnId,
AutoTime: player.AutoMill.Milliseconds(),
HandTime: player.HandMill.Milliseconds(),
Ts: time.Now().Unix(),
}, mq.BackThirteenAutoLog)
}
// 使用预选牌 // 使用预选牌
if player.preCardsO != nil && player.preCardsO.PokerType != -1 && (player.cardsO == nil || player.cardsO.PokerType == -1) { if player.preCardsO != nil && player.preCardsO.PokerType != -1 && (player.cardsO == nil || player.cardsO.PokerType == -1) {
player.cardsO = player.preCardsO player.cardsO = player.preCardsO
@ -1169,23 +1122,7 @@ func (this *StateOp) OnLeave(s *base.Scene) {
func (this *StateOp) OnTick(s *base.Scene) { func (this *StateOp) OnTick(s *base.Scene) {
this.BaseState.OnTick(s) this.BaseState.OnTick(s)
if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
now := time.Now() if time.Now().Sub(sceneEx.StateStartTime) > sceneEx.GetBaiPai() {
addTime := now.Sub(sceneEx.timestamp)
for _, v := range sceneEx.seats {
if v != nil && v.IsGameing() {
switch v.AutoState {
case 2:
v.AutoMill += addTime
case 1:
v.HandMill += addTime
default:
}
}
}
sceneEx.timestamp = now
if now.Sub(sceneEx.StateStartTime) > sceneEx.GetBaiPai() {
s.ChangeSceneState(rule.ThirteenWaterSceneStateShowCards) s.ChangeSceneState(rule.ThirteenWaterSceneStateShowCards)
} }
} }
@ -1501,6 +1438,8 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: o_player.Platform, Platform: o_player.Platform,
Snid: o_player.SnId, Snid: o_player.SnId,
PlayerName: o_player.Name, PlayerName: o_player.Name,
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: o_player.taxCoin, TaxCoin: o_player.taxCoin,

View File

@ -1302,20 +1302,24 @@ func (this *TienLenSceneData) SendHandCardOdds() {
allcs[i], allcs[j] = allcs[j], allcs[i] allcs[i], allcs[j] = allcs[j], allcs[i]
}) })
allcs = common.DelSliceIn32s(allcs, this.testPokers[1:]) if len(this.testPokers) > 14 {
this.testPokers = append(this.testPokers, allcs...) this.testPokers = this.testPokers[:14]
for _, seat := range this.seats {
if seat != nil && seat.IsGameing() && seat.SnId == this.testPokers[0] {
f1(seat, this.testPokers[1:14])
this.testPokers = this.testPokers[14:]
break
}
} }
if len(this.testPokers) < 14 {
allcs = common.DelSliceIn32s(allcs, this.testPokers[1:])
this.testPokers = append(this.testPokers, allcs[:14-len(this.testPokers)]...)
allcs = allcs[14-len(this.testPokers):]
}
allcs = common.DelSliceIn32s(allcs, this.testPokers[1:])
for _, seat := range this.seats { for _, seat := range this.seats {
if seat != nil && seat.IsGameing() && seat.cards[0] == rule.InvalideCard { if seat != nil && seat.IsGameing() {
f1(seat, this.testPokers[:13]) if seat.SnId == this.testPokers[0] {
this.testPokers = this.testPokers[13:] f1(seat, this.testPokers[1:])
} else {
f1(seat, allcs[:13])
allcs = allcs[13:]
}
} }
} }
this.testPokers = nil this.testPokers = nil

View File

@ -1383,7 +1383,7 @@ func (this *ScenePlayerOpStateTienLen) OnPlayerOp(s *base.Scene, p *base.Player,
case rule.TienLenPlayerOpPass: //过牌 case rule.TienLenPlayerOpPass: //过牌
//当前操作者和上一个操作者是同一个人,必出牌,不能过牌 //当前操作者和上一个操作者是同一个人,必出牌,不能过牌
if int32(playerEx.GetPos()) == sceneEx.lastOpPos || sceneEx.lastOpPos == rule.InvalidePos { if int32(playerEx.GetPos()) == sceneEx.lastOpPos || sceneEx.lastOpPos != rule.InvalidePos {
finishFunc() finishFunc()
return true return true
} }
@ -2789,6 +2789,8 @@ func (this *SceneBilledStateTienLen) OnEnter(s *base.Scene) {
LogId: sceneEx.recordId, LogId: sceneEx.recordId,
Platform: o_player.Platform, Platform: o_player.Platform,
Snid: o_player.UserId, Snid: o_player.UserId,
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: o_player.BillTaxCoin, TaxCoin: o_player.BillTaxCoin,

13
go.mod
View File

@ -19,7 +19,6 @@ require (
github.com/jinzhu/now v1.1.5 github.com/jinzhu/now v1.1.5
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/mojocn/base64Captcha v1.3.6 github.com/mojocn/base64Captcha v1.3.6
github.com/mozillazg/go-pinyin v0.20.0
github.com/spf13/cast v1.7.0 github.com/spf13/cast v1.7.0
github.com/spf13/viper v1.19.0 github.com/spf13/viper v1.19.0
github.com/tealeg/xlsx v1.0.5 github.com/tealeg/xlsx v1.0.5
@ -92,7 +91,7 @@ require (
github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/xtaci/kcp-go v5.4.20+incompatible // indirect github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6 // indirect github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.etcd.io/etcd/api/v3 v3.5.16 // indirect go.etcd.io/etcd/api/v3 v3.5.16 // indirect
@ -103,12 +102,12 @@ require (
go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.31.0 // indirect golang.org/x/crypto v0.28.0 // indirect
golang.org/x/image v0.18.0 // indirect golang.org/x/image v0.18.0 // indirect
golang.org/x/net v0.33.0 // indirect golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.10.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.28.0 // indirect golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.7.0 // indirect golang.org/x/time v0.7.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect

13
go.sum
View File

@ -226,8 +226,6 @@ github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew0
github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E= github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@ -388,8 +386,6 @@ github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2
github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk= github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6 h1:8m6DWBG+dlFNbx5ynvrE7NgI+Y7OlZVMVTpayoW+rCc=
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE= github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE=
github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE= github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A= github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
@ -443,8 +439,6 @@ golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
@ -481,8 +475,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -495,7 +487,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -525,8 +516,6 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -539,8 +528,6 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=

View File

@ -8,11 +8,9 @@ type BankruptLog struct {
LogId bson.ObjectId `bson:"_id"` LogId bson.ObjectId `bson:"_id"`
SnId int32 //玩家id SnId int32 //玩家id
Channel string // 渠道 Channel string // 渠道
ChannelId string // 推广渠道
Platform string //平台名称 Platform string //平台名称
GameId int //游戏id GameId int //游戏id
GameFreeID int32 //房间id GameFreeID int32 //房间id
GameDif string // 游戏分组
CreateTime int64 // 注册时间 CreateTime int64 // 注册时间
UseCoin int64 // 消耗金币 UseCoin int64 // 消耗金币
@ -24,14 +22,12 @@ func NewBankruptLog() *BankruptLog {
return log return log
} }
func NewBankruptLogEx(snid int32, gamefreeid int32, createtime, usecoin int64, platform, channel, channelId, gamedif string, gameId int) *BankruptLog { func NewBankruptLogEx(snid int32, gamefreeid int32, createtime, usecoin int64, platform, channel string, gameId int) *BankruptLog {
cl := NewBankruptLog() cl := NewBankruptLog()
cl.SnId = snid cl.SnId = snid
cl.Platform = platform cl.Platform = platform
cl.Channel = channel cl.Channel = channel
cl.ChannelId = channelId
cl.GameId = gameId cl.GameId = gameId
cl.GameDif = gamedif
cl.GameFreeID = gamefreeid cl.GameFreeID = gamefreeid
cl.CreateTime = createtime cl.CreateTime = createtime

View File

@ -245,36 +245,34 @@ func CreatePlayerLoginEvent(snid int32, channel, promoter, platform, city, os, i
// 玩家游戏记录 // 玩家游戏记录
type PlayerGameRecEvent struct { type PlayerGameRecEvent struct {
Id string //id RecordId string //游戏记录ID
RecordId string //游戏记录ID SnId int32 //用户ID
SnId int32 //用户ID Channel string //包类型
Channel string //包类型 Promoter string //推广
Platform string //平台 Platform string //平台
OS string //操作系统 City string //城市
GameId int32 //游戏id OS string //操作系统
ModeId int32 //游戏模式 TelephonePromoter int32 //电销标记
Tax int64 //税收 GameId int32 //游戏id
Amount int64 //金币变化,税后(正值为赢;负值为输) ModeId int32 //游戏模式
CreateTime int64 //创建时间 Tax int64 //税收
CreateDayTime int64 //账号创建时间0点 Amount int64 //金币变化(正值为赢;负值为输)
Out int64 //产出 CreateTime int64 //创建时间
In int64 //投入 CreateDayTime int64 //账号创建时间0点
IsNew int32 //是否是新人 ValidBet int64 //有效下注数量
GameFreeID int32 //游戏freeid ValidFlow int64 //有效流水数量
GamingTime int32 //游戏开始到玩家结算的时长 单位:秒 Out int64 //产出
In int64 //投入
GameDif string // 游戏分组 IsNew int32 //是否是新人
FirstGameDifTime int64 // 首次游戏分组时间 GameFreeID int32 //游戏freeid
GameDifTimes int64 // 游戏分组游戏次数 GamingTime int32 //游戏开始到玩家结算的时长 单位:秒
FirstTime int64 //首次玩该场次游戏时间
FirstTime int64 //首次玩该场次游戏时间 PlayTimes int64 //该场次游戏次数
PlayTimes int64 //该场次游戏次数 FirstGameTime int64 //首次玩游戏时间
PlayGameTimes int64 //该游戏总次数
FirstGameTime int64 //首次玩游戏时间 LastLoginTime int64 //最后登录时间
PlayGameTimes int64 //该游戏总次数 DeviceId string //设备id
ChannelId string //推广渠道id
LastLoginTime int64 //最后登录时间
ChannelId string //推广渠道id
} }
// 玩家游戏记录 // 玩家游戏记录

View File

@ -23,33 +23,9 @@ type CoinPoolCtx struct {
Controlled bool //被水池控制了 Controlled bool //被水池控制了
} }
type GameDetailedLog struct { type GameDetailedLogRet struct {
Id bson.ObjectId `bson:"_id"` Gplt GameDetailedLogType
Platform string // 平台
LogId string // 记录ID每局游戏唯一
GameDif string // 游戏组
GameId int32 // 游戏id
GameClass int32 // 游戏类型
GameMode int32 // 游戏模式,弃用
GameType int32 // 游戏类型
GameFreeId int32 // 场次id
CycleId string // 房卡场id多轮有相同的id
MatchId int64 // 比赛ID应该用字符串的
SceneId int32 // 房间id会重复
PlayerCount int32 // 玩家数量
GameTiming int32 // 游戏用时,秒
GameBaseBet int32 // 游戏底分
Ts int64 // 时间戳
Time time.Time // 记录时间
GameDetailedNote string // 游戏详情
GameDetailVer int32 // 游戏详情版本
CpCtx CoinPoolCtx // 水池上下文信息
Trend20Lately string // 最近游戏走势
CtrlType int // 1控赢 2控输 0不控
PlayerPool map[int]int // 个人水池分 玩家id:分
} }
type GameDetailedLogType struct { type GameDetailedLogType struct {
PageNo int //当前页码 PageNo int //当前页码
PageSize int //每页数量 PageSize int //每页数量
@ -57,8 +33,64 @@ type GameDetailedLogType struct {
Data []*GameDetailedLog //当页数据 Data []*GameDetailedLog //当页数据
} }
type GameDetailedLogRet struct { type GameDetailedLog struct {
Gplt GameDetailedLogType Id bson.ObjectId `bson:"_id"` //记录ID
LogId string //记录ID每局游戏唯一
GameId int32 //游戏id
ClubId int32 //俱乐部Id
ClubRoom string //俱乐部包间
Platform string //平台id
Channel string //渠道
Promoter string //推广员
MatchId int64 //比赛ID应该用字符串的
SceneId int32 //房间id会重复
GameMode int32 //游戏类型
GameFreeid int32 //游戏类型房间号
PlayerCount int32 //玩家数量
GameTiming int32 //本局游戏用时(mm)
GameBaseBet int32 //游戏单位低分
GameDetailedNote string //游戏详情
GameDetailVer int32 //游戏详情版本
CpCtx CoinPoolCtx //水池上下文信息
Time time.Time //记录时间
Trend20Lately string //最近游戏走势
Ts int64 //时间戳
CtrlType int // 1控赢 2控输 0不控
PlayerPool map[int]int // 个人水池分
CycleId string // 本轮id打一轮有多局
}
func NewGameDetailedLog() *GameDetailedLog {
log := &GameDetailedLog{Id: bson.NewObjectId()}
return log
}
func NewGameDetailedLogEx(logid string, gameid, sceneid, gamemode, gamefreeid, playercount, gametiming, gamebasebet int32,
gamedetailednote string, platform string, clubId int32, clubRoom string, cpCtx CoinPoolCtx, ver int32,
trend20Lately string, ctrlType int, playerPool map[int]int, cycleId string) *GameDetailedLog {
cl := NewGameDetailedLog()
cl.LogId = logid
cl.GameId = gameid
cl.ClubId = clubId
cl.ClubRoom = clubRoom
cl.SceneId = sceneid
cl.GameMode = gamemode
cl.GameFreeid = gamefreeid
cl.PlayerCount = playercount
cl.GameTiming = gametiming
cl.GameBaseBet = gamebasebet
cl.GameDetailedNote = gamedetailednote
cl.Platform = platform
tNow := time.Now()
cl.Time = tNow
cl.CpCtx = cpCtx
cl.GameDetailVer = ver
cl.Trend20Lately = trend20Lately
cl.Ts = time.Now().Unix()
cl.CtrlType = ctrlType
cl.PlayerPool = playerPool
cl.CycleId = cycleId
return cl
} }
func InsertGameDetailedLog(log *GameDetailedLog) (err error) { func InsertGameDetailedLog(log *GameDetailedLog) (err error) {

View File

@ -21,36 +21,86 @@ type GameTotalRecord struct {
type GamePlayerListLog struct { type GamePlayerListLog struct {
LogId bson.ObjectId `bson:"_id"` //记录ID LogId bson.ObjectId `bson:"_id"` //记录ID
Platform string // 平台 SnId int32 //用户Id
GameDif string // 游戏组 Name string //名称
GameId int32 // 游戏id GameId int32 //游戏id
GameClass int32 // 游戏类型 BaseScore int32 //游戏底注
GameMode int32 // 游戏模式,弃用 ClubId int32 //俱乐部Id
GameType int32 // 游戏类型 ClubRoom string //俱乐部包间
GameFreeId int32 // 场次id TaxCoin int64 //税收
BaseScore int32 // 游戏底注 ClubPumpCoin int64 //俱乐部额外抽水
GameDetailedLogId string // 游戏记录Id Platform string //平台id
Channel string // 包类型 Channel string //渠道
ChannelId string // 推广渠道 Promoter string //推广员
RoomType int32 // 房间类型 PackageTag string //包标识
Ts int64 // 记录时间 SceneId int32 //场景ID
Time time.Time // 记录时间 GameMode int32 //游戏类型
CycleId string // 本轮id打一轮有多局 GameFreeid int32 //游戏类型房间号
GameDetailedLogId string //游戏记录Id
IsFirstGame bool //是否第一次游戏
//对于拉霸类BetAmount=100 WinAmountNoAnyTax=0 (表示投入多少、收益多少,值>=0
//拉霸类小游戏会是BetAmount=0 WinAmountNoAnyTax=100 投入0、收益多少值>=0
//对战场BetAmount=0 WinAmountNoAnyTax=100 投入会有是0、收益有正负WinAmountNoAnyTax=100则盈利WinAmountNoAnyTax=-100则输100
BetAmount int64 //下注金额
WinAmountNoAnyTax int64 //盈利金额,不包含任何税
TotalIn int64 //本局投入
TotalOut int64 //本局产出
Time time.Time //记录时间
RoomType int32 //房间类型
GameDif string //游戏标识
GameClass int32 //游戏类型 1棋牌 2电子 3百人 4捕鱼 5视讯 6彩票 7体育
MatchId int64
MatchType int64 //0.普通场 1.锦标赛 2.冠军赛 3.vip专属
Ts int64
IsFree bool //拉霸专用 是否免费
WinSmallGame int64 //拉霸专用 小游戏奖励
WinTotal int64 //拉霸专用 输赢
CycleId string // 本轮id打一轮有多局
}
SnId int32 // 用户Id func NewGamePlayerListLog() *GamePlayerListLog {
Name string // 名称 log := &GamePlayerListLog{LogId: bson.NewObjectId()}
SceneId int32 // 房间id会重复 return log
MatchId int64 // 比赛ID应该用字符串的 }
MatchType int64 // 0.普通场 1.锦标赛 2.冠军赛 3.vip专属 func NewGamePlayerListLogEx(snid int32, gamedetailedlogid string, platform, channel, promoter, packageTag string, gameid, baseScore,
WinAmountNoAnyTax int64 // 盈利金额,不包含任何税 sceneid, gamemode, gamefreeid int32, totalin, totalout int64, clubId int32, clubRoom string, taxCoin, pumpCoin int64, roomType int32,
TaxCoin int64 // 税收 betAmount, winAmountNoAnyTax int64, key, name string, gameClass int32, isFirst bool, matchid, matchType int64,
BetAmount int64 // 下注金额 isFree bool, winSmallGame, winTotal int64, cycleId string) *GamePlayerListLog {
IsFirstGame bool // 是否第一次游戏 cl := NewGamePlayerListLog()
TotalIn int64 // 本局投入 cl.SnId = snid
TotalOut int64 // 本局产出 cl.GameDetailedLogId = gamedetailedlogid
IsFree bool // 拉霸专用 是否免费 cl.Platform = platform
WinSmallGame int64 // 拉霸专用 小游戏奖励 cl.Name = name
WinTotal int64 // 拉霸专用 输赢 cl.Channel = channel
cl.Promoter = promoter
cl.PackageTag = packageTag
cl.GameFreeid = gamefreeid
cl.GameId = gameid
cl.BaseScore = baseScore
cl.ClubId = clubId
cl.GameMode = gamemode
cl.SceneId = sceneid
cl.TotalIn = totalin
cl.TotalOut = totalout
cl.ClubRoom = clubRoom
cl.TaxCoin = taxCoin
cl.IsFirstGame = isFirst
cl.ClubPumpCoin = pumpCoin
cl.RoomType = roomType
cl.BetAmount = betAmount
cl.WinAmountNoAnyTax = winAmountNoAnyTax
cl.GameDif = key
cl.GameClass = gameClass
cl.IsFree = isFree
cl.WinSmallGame = winSmallGame
cl.WinTotal = winTotal
tNow := time.Now()
cl.Ts = tNow.Unix()
cl.Time = tNow
cl.MatchId = matchid
cl.MatchType = matchType
cl.CycleId = cycleId
return cl
} }
type GamePlayerListRet struct { type GamePlayerListRet struct {

View File

@ -28,7 +28,6 @@ type ItemLog struct {
TypeId int32 // 变化类型 TypeId int32 // 变化类型
GameId int64 // 游戏id,游戏中获得时有值 GameId int64 // 游戏id,游戏中获得时有值
GameFreeId int64 // 场次id,游戏中获得时有值 GameFreeId int64 // 场次id,游戏中获得时有值
GameDif string // 游戏分组
Cost []*Item // 消耗的道具 Cost []*Item // 消耗的道具
Id string // 撤销的id兑换失败 Id string // 撤销的id兑换失败
RoomConfigId int32 // 房间配置id RoomConfigId int32 // 房间配置id
@ -51,7 +50,6 @@ type ItemParam struct {
TypeId int32 // 变化类型 TypeId int32 // 变化类型
GameId int64 // 游戏id,游戏中获得时有值 GameId int64 // 游戏id,游戏中获得时有值
GameFreeId int64 // 场次id,游戏中获得时有值 GameFreeId int64 // 场次id,游戏中获得时有值
GameDif string // 游戏分组
Cost []*Item // 消耗的道具 Cost []*Item // 消耗的道具
LogId string // 撤销的id兑换失败 LogId string // 撤销的id兑换失败
RoomConfigId int32 // 房间配置id RoomConfigId int32 // 房间配置id
@ -73,7 +71,6 @@ func NewItemLogEx(param ItemParam) *ItemLog {
itemLog.TypeId = param.TypeId itemLog.TypeId = param.TypeId
itemLog.GameId = param.GameId itemLog.GameId = param.GameId
itemLog.GameFreeId = param.GameFreeId itemLog.GameFreeId = param.GameFreeId
itemLog.GameDif = param.GameDif
itemLog.Cost = param.Cost itemLog.Cost = param.Cost
itemLog.Id = param.LogId itemLog.Id = param.LogId
itemLog.RoomConfigId = param.RoomConfigId itemLog.RoomConfigId = param.RoomConfigId
@ -249,7 +246,7 @@ type InsertItemLogReq struct {
Logs []*ItemLog Logs []*ItemLog
} }
func InsertItemLog(configItems map[int32]*server.DB_GameItem, param *AddItemParam, gamedif string, isOffline bool) error { func InsertItemLog(configItems map[int32]*server.DB_GameItem, param *AddItemParam, isOffline bool) error {
if rpcCli == nil { if rpcCli == nil {
logger.Logger.Warnf("rpcCli is nil") logger.Logger.Warnf("rpcCli is nil")
return errors.New("rpcCli is nil") return errors.New("rpcCli is nil")
@ -283,7 +280,6 @@ func InsertItemLog(configItems map[int32]*server.DB_GameItem, param *AddItemPara
TypeId: param.GainWay, TypeId: param.GainWay,
GameId: param.GameId, GameId: param.GameId,
GameFreeId: param.GameFreeId, GameFreeId: param.GameFreeId,
GameDif: gamedif,
Cost: param.Cost, Cost: param.Cost,
LogId: param.LogId, LogId: param.LogId,
RoomConfigId: param.RoomConfigId, RoomConfigId: param.RoomConfigId,

View File

@ -1262,11 +1262,9 @@ func SavePlayerData(pd *PlayerData) bool {
} }
if pd != nil { if pd != nil {
var ret bool var ret bool
t1 := time.Now()
err := rpcCli.CallWithTimeout("PlayerDataSvc.SavePlayerData", pd, &ret, time.Second*30) err := rpcCli.CallWithTimeout("PlayerDataSvc.SavePlayerData", pd, &ret, time.Second*30)
if err != nil { if err != nil {
logger.Logger.Errorf("SavePlayerData %v cost:%v fail err:%v PlayerData:%+v", logger.Logger.Errorf("SavePlayerData %v err:%v", pd.SnId, err)
pd.SnId, time.Now().Sub(t1), err, *pd)
return false return false
} }
return ret return ret

View File

@ -15,13 +15,6 @@ func GenerateOnline(online map[string]map[string]int) *mq.RabbitMQData {
return NewRabbitMQData(mq.BackOnline, params) return NewRabbitMQData(mq.BackOnline, params)
} }
func GenerateOnlineGame(online map[string]map[string]map[string]map[int]map[int]int) *mq.RabbitMQData {
params := make(map[string]interface{})
params["Online"] = online
params["Time"] = time.Now().Unix()
return NewRabbitMQData(mq.BackOnlineGame, params)
}
// GenerateLogin 玩家登陆事件 // GenerateLogin 玩家登陆事件
func GenerateLogin(o *PlayerLoginEvent) *mq.RabbitMQData { func GenerateLogin(o *PlayerLoginEvent) *mq.RabbitMQData {
return NewRabbitMQData(mq.BackLogin, o) return NewRabbitMQData(mq.BackLogin, o)

View File

@ -1,11 +0,0 @@
package model
type ThirteenAutoLog struct {
Id string `gorm:"primaryKey"`
Platform string `gorm:"-"`
LogId string `gorm:"index;column:logid"`
SnId int32 `gorm:"index;column:snid"`
AutoTime int64 // 自动时长,毫秒
HandTime int64 // 手动时长,毫秒
Ts int64
}

View File

@ -55,18 +55,18 @@ type RabbitMQData struct {
Data interface{} Data interface{}
} }
func (c *MessageMgr) Send(data interface{}, name string, options ...broker.PublishOption) error { func (c *MessageMgr) Send(data interface{}, name ...string) error {
if msg, ok := data.(*RabbitMQData); ok { if msg, ok := data.(*RabbitMQData); ok {
return Send(msg.MQName, msg.Data, options...) return Send(msg.MQName, msg.Data)
} }
if len(name) > 0 { if len(name) > 0 && name[0] != "" {
return Send(name, data, options...) return Send(name[0], data)
} }
key := c.getName(data) key := c.getName(data)
if key == "" { if key == "" {
key = "_null_" key = "_null_"
} }
return Send(key, data, options...) return Send(key, data)
} }
type RegisterHandlerParam struct { type RegisterHandlerParam struct {
@ -132,14 +132,7 @@ func RegisterMessage(param *RegisterMessageParam) {
// Write 发送消息 // Write 发送消息
// 默认队列名称规则队列前缀_消息结构体名称 // 默认队列名称规则队列前缀_消息结构体名称
func Write(data interface{}, name ...string) error { func Write(data interface{}, name ...string) error {
if len(name) > 0 && name[0] != "" { return MessageMgrSingle.Send(data, name...)
return MessageMgrSingle.Send(data, name[0])
}
return MessageMgrSingle.Send(data, "")
}
func WriteWithOptions(data interface{}, name string, opts ...broker.PublishOption) error {
return MessageMgrSingle.Send(data, name, opts...)
} }
// RegisterHandler 注册消息处理函数 // RegisterHandler 注册消息处理函数

View File

@ -18,14 +18,11 @@ const (
BackSystemPermitTask = "back_permittask" BackSystemPermitTask = "back_permittask"
BackSystemJyb = "back_jyblog" BackSystemJyb = "back_jyblog"
BackActivityLog = "back_activitylog" BackActivityLog = "back_activitylog"
BackOnlineGame = "back_onlinegame"
) )
// go后端 // mgrsrv
const ( const ()
BackThirteenAutoLog = "b_thirteenautolog"
)
// worldsrv 消息 // worldsrv 消息

File diff suppressed because it is too large Load Diff

View File

@ -659,22 +659,6 @@ message DB_GamMatchLVArray {
repeated DB_GamMatchLV Arr = 1; repeated DB_GamMatchLV Arr = 1;
} }
message DB_GameBankruptcy {
int32 Id = 1;
string GameName = 2;
string GameDif = 3;
int32 LimitNum = 4;
}
message DB_GameBankruptcyArray {
repeated DB_GameBankruptcy Arr = 1;
}
message DB_GameCoinPool { message DB_GameCoinPool {
int32 Id = 1; int32 Id = 1;

View File

@ -386,7 +386,7 @@ type CSThirteenPlayerOp struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
OpCode int32 `protobuf:"varint,1,opt,name=OpCode,proto3" json:"OpCode,omitempty"` // 1:确定牌 2站起状态 3test 4重新选牌 5加入游戏 6预选 7自动手动切换(1自动2手动) OpCode int32 `protobuf:"varint,1,opt,name=OpCode,proto3" json:"OpCode,omitempty"` // 1:确定牌 2站起状态 3test 4重新选牌 5加入游戏 6预选
// 确定牌时,两种参数规则,都可以 // 确定牌时,两种参数规则,都可以
// 第一种玩家从推荐牌型中选择一个把Poker.IndexType发过来减少数据传输 // 第一种玩家从推荐牌型中选择一个把Poker.IndexType发过来减少数据传输
// 第二种:按头墩中墩尾墩顺序把牌发过来 // 第二种:按头墩中墩尾墩顺序把牌发过来

View File

@ -73,7 +73,7 @@ message SCThirteenPlayerCards {
// //
//PACKET_CSThirteenPlayerOp //PACKET_CSThirteenPlayerOp
message CSThirteenPlayerOp { message CSThirteenPlayerOp {
int32 OpCode = 1; // 1: 2 3test 4 5 6 7(12) int32 OpCode = 1; // 1: 2 3test 4 5 6
// , // ,
// Poker.IndexType发过来 // Poker.IndexType发过来

File diff suppressed because it is too large Load Diff

View File

@ -513,8 +513,6 @@ message ASQueryOnlineReportList{
int32 OrderType = 6;// 0, 1 int32 OrderType = 6;// 0, 1
int32 GameFreeId = 7; int32 GameFreeId = 7;
string Channel = 8; string Channel = 8;
string GameDif = 9; //
string ChannelId = 10; // 广ID
} }
message SAQueryOnlineReportList{ message SAQueryOnlineReportList{
TagCode Tag = 1; // TagCode Tag = 1; //

View File

@ -1,77 +0,0 @@
// Code generated by xlsx2proto.
// DO NOT EDIT!
package srvdata
import (
"google.golang.org/protobuf/proto"
"mongo.games.com/game/protocol/server"
)
var PBDB_GameBankruptcyMgr = &DB_GameBankruptcyMgr{
Datas: &server.DB_GameBankruptcyArray{},
pool: make(map[int32]*server.DB_GameBankruptcy),
}
type DB_GameBankruptcyMgr struct {
Datas *server.DB_GameBankruptcyArray
pool map[int32]*server.DB_GameBankruptcy
}
func (this *DB_GameBankruptcyMgr) unmarshal(data []byte) error {
err := proto.Unmarshal(data, this.Datas)
if err == nil {
this.arrangeData()
}
return err
}
func (this *DB_GameBankruptcyMgr) reunmarshal(data []byte) error {
newDatas := &server.DB_GameBankruptcyArray{}
err := proto.Unmarshal(data, newDatas)
if err == nil {
for _, item := range newDatas.Arr {
existItem := this.GetData(item.GetId())
if existItem == nil {
this.pool[item.GetId()] = item
this.Datas.Arr = append(this.Datas.Arr, item)
} else {
*existItem = *item
}
}
}
return err
}
func (this *DB_GameBankruptcyMgr) arrangeData() {
if this.Datas == nil {
return
}
dataArr := this.Datas.GetArr()
if dataArr == nil {
return
}
for _, data := range dataArr {
this.pool[data.GetId()] = data
}
}
func (this *DB_GameBankruptcyMgr) GetData(id int32) *server.DB_GameBankruptcy {
if data, ok := this.pool[id]; ok {
return data
}
return nil
}
func init() {
DataMgr.register("DB_GameBankruptcy.dat", &ProtobufDataLoader{dh: PBDB_GameBankruptcyMgr})
}

View File

@ -24,9 +24,4 @@ update_invite_num: 30
# 几秒读取一次道具日志 # 几秒读取一次道具日志
update_second_item: 10 update_second_item: 10
# 一次最多读取多少道具日志 # 一次最多读取多少道具日志
update_item_num: 100 update_item_num: 100
# rabbitmq配置
rabbitmq:
url: amqp://win88:123456@127.0.0.1:5672/win99
exchange: win99

View File

@ -15,10 +15,9 @@ import (
"mongo.games.com/goserver/core/utils" "mongo.games.com/goserver/core/utils"
"mongo.games.com/goserver/core/viperx" "mongo.games.com/goserver/core/viperx"
"mongo.games.com/game/mq"
mongomodel "mongo.games.com/game/statistics/modelmongo" mongomodel "mongo.games.com/game/statistics/modelmongo"
mysqlmodel "mongo.games.com/game/statistics/modelmysql" mysqlmodel "mongo.games.com/game/statistics/modelmysql"
_ "mongo.games.com/game/statistics/mq" "mongo.games.com/game/statistics/static"
"mongo.games.com/game/statistics/syn" "mongo.games.com/game/statistics/syn"
) )
@ -69,9 +68,9 @@ func DoTickPlatform(ctx context.Context, wg *sync.WaitGroup, duration time.Durat
} }
func main() { func main() {
VP = viperx.GetViper("config.yaml") VP = viperx.GetViper("config", "yaml")
// mongo // mongo
vp := viperx.GetViper("mongo.yaml") vp := viperx.GetViper("mongo", "yaml")
// mongo初始化 // mongo初始化
conf := &mongox.Config{} conf := &mongox.Config{}
err := vp.Unmarshal(conf) err := vp.Unmarshal(conf)
@ -82,7 +81,7 @@ func main() {
defer mongox.Close() defer mongox.Close()
// mysql // mysql
vp = viperx.GetViper("mysql.yaml") vp = viperx.GetViper("mysql", "yaml")
myConf := &mysqlx.Config{} myConf := &mysqlx.Config{}
err = vp.Unmarshal(myConf) err = vp.Unmarshal(myConf)
if err != nil { if err != nil {
@ -93,32 +92,26 @@ func main() {
mysqlx.SetAutoMigrateTables(mysqlmodel.Tables) mysqlx.SetAutoMigrateTables(mysqlmodel.Tables)
// mq
mq.StartConsumer(VP.GetString("rabbitmq.url"), VP.GetString("rabbitmq.exchange"), true)
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
// 同步注册和登录日志
DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second"))*time.Second, SyncSnId) DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second"))*time.Second, SyncSnId)
//DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_snid"))*time.Second, func(ctx context.Context) { DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_snid"))*time.Second, func(ctx context.Context) {
// wg := new(sync.WaitGroup) wg := new(sync.WaitGroup)
// for _, v := range VP.GetStringSlice("platforms") { for _, v := range VP.GetStringSlice("platforms") {
// platform := v platform := v
// wg.Add(1) wg.Add(1)
// go func() { go func() {
// defer wg.Done() defer wg.Done()
// Static(platform) Static(platform)
// }() }()
// } }
// wg.Wait() wg.Wait()
//}) })
// 同步邀请数据
DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_invite"))*time.Second, SyncInvite) DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_invite"))*time.Second, SyncInvite)
// 同步道具日志数据
DoTickPlatform(ctx, wg, time.Duration(VP.GetInt64("update_second_item"))*time.Second, VP.GetInt("update_item_num"), DoTickPlatform(ctx, wg, time.Duration(VP.GetInt64("update_second_item"))*time.Second, VP.GetInt("update_item_num"),
func(ctx context.Context, platform string, batchSize int) { func(ctx context.Context, platform string, batchSize int) {
err := syn.ItemGainDone(&syn.Data[mongomodel.ItemLog]{ err := syn.ItemGainDone(&syn.Data[mongomodel.ItemLog]{
@ -130,7 +123,7 @@ func main() {
} }
}) })
logger.Logger.Info("start success") logger.Logger.Info("start")
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill) signal.Notify(c, os.Interrupt, os.Kill)
@ -169,36 +162,36 @@ func SyncSnId(ctx context.Context) {
} }
// Static 玩家id触发数据统计 // Static 玩家id触发数据统计
//func Static(platform string) { func Static(platform string) {
// // 查询需要更新的玩家id // 查询需要更新的玩家id
// var ids []*mysqlmodel.UserID var ids []*mysqlmodel.UserID
// db, err := mysqlx.GetDatabase(platform) db, err := mysqlx.GetDatabase(platform)
// if err != nil { if err != nil {
// logger.Logger.Errorf("GetDatabase error: %v", err) logger.Logger.Errorf("GetDatabase error: %v", err)
// return return
// } }
// if err := db.Limit(VP.GetInt("update_snid_num")).Find(&ids).Error; err != nil { if err := db.Limit(VP.GetInt("update_snid_num")).Find(&ids).Error; err != nil {
// logger.Logger.Warnf("Get UserID error: %v", err) logger.Logger.Warnf("Get UserID error: %v", err)
// return return
// } }
//
// if len(ids) == 0 { if len(ids) == 0 {
// logger.Logger.Tracef("Static: no need to update") logger.Logger.Tracef("Static: no need to update")
// return return
// } }
//
// // 统计玩家跳出记录 // 统计玩家跳出记录
// //if err := static.UserLogin(platform, ids); err != nil { if err := static.UserLogin(platform, ids); err != nil {
// // logger.Logger.Errorf("StaticUserLogin error: %v", err) logger.Logger.Errorf("StaticUserLogin error: %v", err)
// // return return
// //} }
//
// // 删除更新过的玩家id // 删除更新过的玩家id
// if err := db.Delete(ids).Error; err != nil { if err := db.Delete(ids).Error; err != nil {
// logger.Logger.Errorf("Delete error: %v", err) logger.Logger.Errorf("Delete error: %v", err)
// return return
// } }
//} }
// SyncInvite 同步邀请数据 // SyncInvite 同步邀请数据
func SyncInvite(ctx context.Context) { func SyncInvite(ctx context.Context) {

View File

@ -9,13 +9,13 @@ const (
) )
type LogLogin struct { type LogLogin struct {
ID uint `gorm:"primaryKey"` ID uint `gorm:"primaryKey"`
Snid int `gorm:"index"` Snid int `gorm:"index"`
OnlineType int `gorm:"index"` OnlineType int `gorm:"index"`
OnlineTs int64 `gorm:"index"` //OnlineTs int `gorm:"index"`
OnlineTime time.Time `gorm:"index"` OnlineTime time.Time `gorm:"index"`
OfflineType int `gorm:"index"` OfflineType int `gorm:"index"`
OfflineTs int64 `gorm:"index"` //OfflineTs int `gorm:"index"`
OfflineTime time.Time `gorm:"index"` OfflineTime time.Time `gorm:"index"`
ChannelId string `gorm:"index"` // 推广渠道 ChannelId string `gorm:"index"` // 推广渠道

View File

@ -1,20 +1,17 @@
package modelmysql package modelmysql
import "mongo.games.com/game/model"
// 需要自动迁移的表添加在这里 Tables // 需要自动迁移的表添加在这里 Tables
var Tables = []interface{}{ var Tables = []interface{}{
&LogLogin{}, &LogLogin{},
&LogLoginMid{}, &LogLoginMid{},
&UserAccount{}, &UserAccount{},
//&UserLogin{}, &UserLogin{},
//&UserID{}, &UserID{},
&LogInviteScoreMid{}, &LogInviteScoreMid{},
&LogInviteScore{}, &LogInviteScore{},
&LogInviteUser{}, &LogInviteUser{},
&LogMid{}, &LogMid{},
&ItemGain{}, &ItemGain{},
&ItemTotalGain{}, &ItemTotalGain{},
&model.ThirteenAutoLog{},
} }

View File

@ -8,7 +8,6 @@ type UserAccount struct {
Snid int `gorm:"index"` Snid int `gorm:"index"`
//RegisterTs int `gorm:"index"` //RegisterTs int `gorm:"index"`
RegisterTime time.Time `gorm:"index"` RegisterTime time.Time `gorm:"index"`
RegisterTs int64 `gorm:"index"`
ChannelId string `gorm:"index"` // 推广渠道 ChannelId string `gorm:"index"` // 推广渠道
DeviceName string `gorm:"index"` DeviceName string `gorm:"index"`

View File

@ -1,35 +1 @@
package mq package mq
import (
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/mysqlx"
"mongo.games.com/game/model"
"mongo.games.com/game/mq"
)
func init() {
mq.RegisterHandler(&mq.RegisterHandlerParam{
Name: mq.BackThirteenAutoLog,
Data: &model.ThirteenAutoLog{},
Handler: func(data interface{}) (err error) {
d, ok := data.(*model.ThirteenAutoLog)
if !ok {
return nil
}
db, err := mysqlx.GetDatabase(d.Platform)
if err != nil {
logger.Logger.Errorf("mysql: SyncThirteenAutoLog failed to get database: %v", err)
return err
}
if err = db.Create(d).Error; err != nil {
logger.Logger.Errorf("mysql: SyncThirteenAutoLog failed to create thirteen_auto_log: %v", err)
return err
}
return nil
},
})
}

View File

@ -1,355 +1,371 @@
package static package static
//func getAccountTel(platform string, id int) (string, error) { import (
// acc := &mongomodel.Account{} "context"
// cc, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount) "errors"
// if err != nil {
// logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err) "go.mongodb.org/mongo-driver/bson"
// return "", err "go.mongodb.org/mongo-driver/mongo"
// } "go.mongodb.org/mongo-driver/mongo/options"
// dd := cc.FindOne(context.TODO(), bson.M{"snid": id}, options.FindOne().SetProjection(bson.M{"tel": 1})) "mongo.games.com/goserver/core/logger"
// err = dd.Err()
// if err != nil { mymongo "mongo.games.com/goserver/core/mongox"
// if errors.Is(err, mongo.ErrNoDocuments) { mymysql "mongo.games.com/goserver/core/mysqlx"
// logger.Logger.Tracef("getAccountTel %v not found in user_account", id)
// return "", nil mongomodel "mongo.games.com/game/statistics/modelmongo"
// } mysqlmodel "mongo.games.com/game/statistics/modelmysql"
// logger.Logger.Errorf("getAccountTel %v get user_account err: %v", id, err) )
// return "", err
// } func getAccountTel(platform string, id int) (string, error) {
// if err := dd.Decode(acc); err != nil { acc := &mongomodel.Account{}
// logger.Logger.Errorf("getAccountTel %v decode user_account err: %v", id, err) cc, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount)
// return "", err if err != nil {
// } logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err)
// return acc.Tel, nil return "", err
//} }
// dd := cc.FindOne(context.TODO(), bson.M{"snid": id}, options.FindOne().SetProjection(bson.M{"tel": 1}))
//// 游戏结束离开 err = dd.Err()
//func checkGameOver(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { if err != nil {
// // 最早的一条掉线记录并且是游戏结束离开 if errors.Is(err, mongo.ErrNoDocuments) {
// a := &mongomodel.LoginLog{} logger.Logger.Tracef("getAccountTel %v not found in user_account", id)
// c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin) return "", nil
// if err != nil { }
// logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err) logger.Logger.Errorf("getAccountTel %v get user_account err: %v", id, err)
// return false, err return "", err
// } }
// d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": 0, "lastgameid": bson.D{{"$gt", 0}}}, if err := dd.Decode(acc); err != nil {
// options.FindOne().SetSort(bson.D{{"time", 1}})) logger.Logger.Errorf("getAccountTel %v decode user_account err: %v", id, err)
// err = d.Err() return "", err
// if err != nil { }
// if errors.Is(err, mongo.ErrNoDocuments) { return acc.Tel, nil
// logger.Logger.Tracef("checkGameOver %v not found in log_login", id) }
// return false, nil
// } // 游戏结束离开
// logger.Logger.Errorf("checkGameOver %v get log_login err: %v", id, err) func checkGameOver(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
// return false, err // 最早的一条掉线记录并且是游戏结束离开
// } a := &mongomodel.LoginLog{}
// if err := d.Decode(a); err != nil { c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin)
// logger.Logger.Errorf("checkGameOver %v decode log_login err: %v", id, err) if err != nil {
// return false, err logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err)
// } return false, err
// }
// // account tel d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": 0, "lastgameid": bson.D{{"$gt", 0}}},
// tel, err := getAccountTel(platform, id) options.FindOne().SetSort(bson.D{{"time", 1}}))
// if err != nil { err = d.Err()
// logger.Logger.Warnf("get account tel %v err: %v", id, err) if err != nil {
// } if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Tracef("checkGameOver %v not found in log_login", id)
// update := &mysqlmodel.UserLogin{ return false, nil
// //OfflineTs: int(a.Ts), }
// OfflineTime: a.Time, logger.Logger.Errorf("checkGameOver %v get log_login err: %v", id, err)
// OutType: mysqlmodel.OutTypeGameOver, return false, err
// GameID: a.LastGameID, }
// Tel: tel, if err := d.Decode(a); err != nil {
// DeviceName: a.DeviceName, logger.Logger.Errorf("checkGameOver %v decode log_login err: %v", id, err)
// AppVersion: a.AppVersion, return false, err
// BuildVersion: a.BuildVersion, }
// AppChannel: a.AppChannel,
// ChannelId: a.ChannelId, // account tel
// } tel, err := getAccountTel(platform, id)
// if err != nil {
// if err := db.Model(login).Select( logger.Logger.Warnf("get account tel %v err: %v", id, err)
// "OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel", }
// ).Updates(update).Error; err != nil {
// logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err) update := &mysqlmodel.UserLogin{
// return false, err //OfflineTs: int(a.Ts),
// } OfflineTime: a.Time,
// OutType: mysqlmodel.OutTypeGameOver,
// return true, nil GameID: a.LastGameID,
//} Tel: tel,
// DeviceName: a.DeviceName,
//// 游戏中离开 AppVersion: a.AppVersion,
//func checkGaming(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { BuildVersion: a.BuildVersion,
// // 最早的一条掉线记录并且是游戏中掉线 AppChannel: a.AppChannel,
// a := &mongomodel.LoginLog{} ChannelId: a.ChannelId,
// c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin) }
// if err != nil {
// logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err) if err := db.Model(login).Select(
// return false, err "OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel",
// } ).Updates(update).Error; err != nil {
// d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": bson.D{{"$gt", 0}}}, logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
// options.FindOne().SetSort(bson.D{{"time", 1}})) return false, err
// err = d.Err() }
// if err != nil {
// if errors.Is(err, mongo.ErrNoDocuments) { return true, nil
// logger.Logger.Tracef("checkGaming %v not found in log_login", id) }
// return false, nil
// } // 游戏中离开
// logger.Logger.Errorf("checkGaming %v get log_login err: %v", id, err) func checkGaming(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
// return false, err // 最早的一条掉线记录并且是游戏中掉线
// } a := &mongomodel.LoginLog{}
// if err := d.Decode(a); err != nil { c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin)
// logger.Logger.Errorf("checkGaming %v decode log_login err: %v", id, err) if err != nil {
// return false, err logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err)
// } return false, err
// }
// // account tel d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": bson.D{{"$gt", 0}}},
// tel, err := getAccountTel(platform, id) options.FindOne().SetSort(bson.D{{"time", 1}}))
// if err != nil { err = d.Err()
// logger.Logger.Warnf("get account tel %v err: %v", id, err) if err != nil {
// } if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Tracef("checkGaming %v not found in log_login", id)
// update := &mysqlmodel.UserLogin{ return false, nil
// //OfflineTs: int(a.Ts), }
// OfflineTime: a.Time, logger.Logger.Errorf("checkGaming %v get log_login err: %v", id, err)
// OutType: mysqlmodel.OutTypeGaming, return false, err
// GameID: a.GameId, }
// Tel: tel, if err := d.Decode(a); err != nil {
// DeviceName: a.DeviceName, logger.Logger.Errorf("checkGaming %v decode log_login err: %v", id, err)
// AppVersion: a.AppVersion, return false, err
// BuildVersion: a.BuildVersion, }
// AppChannel: a.AppChannel,
// ChannelId: a.ChannelId, // account tel
// } tel, err := getAccountTel(platform, id)
// if err != nil {
// if err := db.Model(login).Select( logger.Logger.Warnf("get account tel %v err: %v", id, err)
// "OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel", }
// ).Updates(update).Error; err != nil {
// logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err) update := &mysqlmodel.UserLogin{
// return false, err //OfflineTs: int(a.Ts),
// } OfflineTime: a.Time,
// OutType: mysqlmodel.OutTypeGaming,
// return true, nil GameID: a.GameId,
//} Tel: tel,
// DeviceName: a.DeviceName,
//// 登录后离开 AppVersion: a.AppVersion,
//func checkLogin(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { BuildVersion: a.BuildVersion,
// // 最早的一条掉线记录 AppChannel: a.AppChannel,
// a := &mongomodel.LoginLog{} ChannelId: a.ChannelId,
// c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin) }
// if err != nil {
// logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err) if err := db.Model(login).Select(
// return false, err "OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel",
// } ).Updates(update).Error; err != nil {
// d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop}, options.FindOne().SetSort(bson.D{{"time", 1}})) logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
// err = d.Err() return false, err
// if err != nil { }
// if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Tracef("checkLogin %v not found in log_login", id) return true, nil
// return false, nil }
// }
// logger.Logger.Errorf("checkLogin %v get log_login err: %v", id, err) // 登录后离开
// return false, err func checkLogin(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
// } // 最早的一条掉线记录
// if err := d.Decode(a); err != nil { a := &mongomodel.LoginLog{}
// logger.Logger.Errorf("checkLogin %v decode log_login err: %v", id, err) c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin)
// return false, err if err != nil {
// } logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err)
// return false, err
// // account tel }
// tel, err := getAccountTel(platform, id) d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop}, options.FindOne().SetSort(bson.D{{"time", 1}}))
// if err != nil { err = d.Err()
// logger.Logger.Warnf("get account tel %v err: %v", id, err) if err != nil {
// } if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Tracef("checkLogin %v not found in log_login", id)
// update := &mysqlmodel.UserLogin{ return false, nil
// //OfflineTs: int(a.Ts), }
// OfflineTime: a.Time, logger.Logger.Errorf("checkLogin %v get log_login err: %v", id, err)
// OutType: mysqlmodel.OutTypeLogin, return false, err
// Tel: tel, }
// DeviceName: a.DeviceName, if err := d.Decode(a); err != nil {
// AppVersion: a.AppVersion, logger.Logger.Errorf("checkLogin %v decode log_login err: %v", id, err)
// BuildVersion: a.BuildVersion, return false, err
// AppChannel: a.AppChannel, }
// ChannelId: a.ChannelId,
// } // account tel
// tel, err := getAccountTel(platform, id)
// if err := db.Model(login).Select( if err != nil {
// "OfflineTime", "OutType", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel", logger.Logger.Warnf("get account tel %v err: %v", id, err)
// ).Updates(update).Error; err != nil { }
// logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
// return false, err update := &mysqlmodel.UserLogin{
// } //OfflineTs: int(a.Ts),
// OfflineTime: a.Time,
// return true, nil OutType: mysqlmodel.OutTypeLogin,
//} Tel: tel,
// DeviceName: a.DeviceName,
//// 注册后离开 AppVersion: a.AppVersion,
//func checkRegister(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { BuildVersion: a.BuildVersion,
// a := &mongomodel.Account{} AppChannel: a.AppChannel,
// c, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount) ChannelId: a.ChannelId,
// if err != nil { }
// logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err)
// return false, err if err := db.Model(login).Select(
// } "OfflineTime", "OutType", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel",
// d := c.FindOne(context.TODO(), bson.M{"snid": id}) ).Updates(update).Error; err != nil {
// err = d.Err() logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
// if err != nil { return false, err
// if errors.Is(err, mongo.ErrNoDocuments) { }
// logger.Logger.Warnf("checkRegister %v not found in user_account", id)
// return false, nil return true, nil
// } }
// logger.Logger.Errorf("checkRegister %v get user_account err: %v", id, err)
// return false, err // 注册后离开
// } func checkRegister(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
// if err := d.Decode(a); err != nil { a := &mongomodel.Account{}
// logger.Logger.Errorf("checkRegister %v decode user_account err: %v", id, err) c, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount)
// return false, err if err != nil {
// } logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err)
// return false, err
// // account tel }
// tel, err := getAccountTel(platform, id) d := c.FindOne(context.TODO(), bson.M{"snid": id})
// if err != nil { err = d.Err()
// logger.Logger.Warnf("get account tel %v err: %v", id, err) if err != nil {
// } if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Warnf("checkRegister %v not found in user_account", id)
// login.Snid = id return false, nil
// //login.OnlineTs = int(a.RegisterTs) }
// login.OnlineTime = a.RegisteTime logger.Logger.Errorf("checkRegister %v get user_account err: %v", id, err)
// //login.OfflineTs = int(a.RegisterTs) return false, err
// login.OfflineTime = a.RegisteTime }
// login.OutType = mysqlmodel.OutTypRegister if err := d.Decode(a); err != nil {
// login.Tel = tel logger.Logger.Errorf("checkRegister %v decode user_account err: %v", id, err)
// login.DeviceName = a.DeviceName return false, err
// login.AppVersion = a.AppVersion }
// login.BuildVersion = a.BuildVersion
// login.AppChannel = a.AppChannel // account tel
// login.ChannelId = a.ChannelId tel, err := getAccountTel(platform, id)
// if err != nil {
// if err := db.Create(login).Error; err != nil { logger.Logger.Warnf("get account tel %v err: %v", id, err)
// logger.Logger.Errorf("checkRegister create err: %v", err) }
// return false, err
// } login.Snid = id
// return true, nil //login.OnlineTs = int(a.RegisterTs)
//} login.OnlineTime = a.RegisteTime
//login.OfflineTs = int(a.RegisterTs)
login.OfflineTime = a.RegisteTime
login.OutType = mysqlmodel.OutTypRegister
login.Tel = tel
login.DeviceName = a.DeviceName
login.AppVersion = a.AppVersion
login.BuildVersion = a.BuildVersion
login.AppChannel = a.AppChannel
login.ChannelId = a.ChannelId
if err := db.Create(login).Error; err != nil {
logger.Logger.Errorf("checkRegister create err: %v", err)
return false, err
}
return true, nil
}
// UserLogin 玩家跳出统计 // UserLogin 玩家跳出统计
//func UserLogin(platform string, ids []*mysqlmodel.UserID) error { func UserLogin(platform string, ids []*mysqlmodel.UserID) error {
// f := func(id int) error { f := func(id int) error {
// // 玩家是否已经统计结束,已经是游戏结束状态 // 玩家是否已经统计结束,已经是游戏结束状态
// login := &mysqlmodel.UserLogin{} login := &mysqlmodel.UserLogin{}
// db, err := mymysql.GetDatabase(platform) db, err := mymysql.GetDatabase(platform)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin get db err: %v", err) logger.Logger.Errorf("UserLogin get db err: %v", err)
// return err return err
// } }
// if err = db.Where("snid = ?", id).Find(login).Error; err != nil { if err = db.Where("snid = ?", id).Find(login).Error; err != nil {
// logger.Logger.Errorf("UserLogin find %v err: %v", id, err) logger.Logger.Errorf("UserLogin find %v err: %v", id, err)
// return err return err
// } }
//
// switch login.OutType { switch login.OutType {
// case mysqlmodel.OutTypeGameOver: case mysqlmodel.OutTypeGameOver:
// return nil return nil
//
// case mysqlmodel.OutTypeGaming: case mysqlmodel.OutTypeGaming:
// _, err := checkGameOver(db, login, platform, id) _, err := checkGameOver(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
// return err return err
// } }
// return nil return nil
//
// case mysqlmodel.OutTypeLogin: case mysqlmodel.OutTypeLogin:
// ret, err := checkGameOver(db, login, platform, id) ret, err := checkGameOver(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
// ret, err = checkGaming(db, login, platform, id) ret, err = checkGaming(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
//
// case mysqlmodel.OutTypRegister: case mysqlmodel.OutTypRegister:
// ret, err := checkGameOver(db, login, platform, id) ret, err := checkGameOver(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
// ret, err = checkGaming(db, login, platform, id) ret, err = checkGaming(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
// ret, err = checkLogin(db, login, platform, id) ret, err = checkLogin(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
//
// default: default:
// ret, err := checkRegister(db, login, platform, id) ret, err := checkRegister(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkRegister %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkRegister %v err: %v", id, err)
// return err return err
// } }
// if !ret { if !ret {
// logger.Logger.Warnf("UserLogin not found user_account checkRegister %v err: %v", id, err) logger.Logger.Warnf("UserLogin not found user_account checkRegister %v err: %v", id, err)
// return nil return nil
// } }
//
// ret, err = checkGameOver(db, login, platform, id) ret, err = checkGameOver(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
// ret, err = checkGaming(db, login, platform, id) ret, err = checkGaming(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
// ret, err = checkLogin(db, login, platform, id) ret, err = checkLogin(db, login, platform, id)
// if err != nil { if err != nil {
// logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err) logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err)
// return err return err
// } }
// if ret { if ret {
// return nil return nil
// } }
// return nil return nil
// } }
//
// return nil return nil
// } }
//
// for _, v := range ids { for _, v := range ids {
// if err := f(v.Snid); err != nil { if err := f(v.Snid); err != nil {
// return err return err
// } }
// } }
//
// return nil return nil
//} }

View File

@ -9,12 +9,12 @@ import (
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
"gorm.io/gorm" "gorm.io/gorm"
"mongo.games.com/goserver/core/logger"
mymongo "mongo.games.com/goserver/core/mongox"
mymysql "mongo.games.com/goserver/core/mysqlx"
mongomodel "mongo.games.com/game/statistics/modelmongo" mongomodel "mongo.games.com/game/statistics/modelmongo"
mysqlmodel "mongo.games.com/game/statistics/modelmysql" mysqlmodel "mongo.games.com/game/statistics/modelmysql"
"mongo.games.com/goserver/core/logger"
mymongo "mongo.games.com/goserver/core/mongox"
mymysql "mongo.games.com/goserver/core/mysqlx"
) )
/* /*
@ -91,12 +91,12 @@ func LogLogin(platform string, batchSize int) ([]*mysqlmodel.LogLogin, error) {
if n == 0 { if n == 0 {
e = &mysqlmodel.LogLogin{ e = &mysqlmodel.LogLogin{
Snid: int(v.SnId), Snid: int(v.SnId),
OnlineType: onlineType, OnlineType: onlineType,
OnlineTs: v.Time.Unix(), //OnlineTs: int(v.Ts),
OnlineTime: v.Time, OnlineTime: v.Time,
OfflineType: 0, OfflineType: 0,
OfflineTs: 0, //OfflineTs: 0,
OfflineTime: v.Time, OfflineTime: v.Time,
DeviceName: v.DeviceName, DeviceName: v.DeviceName,
AppVersion: v.AppVersion, AppVersion: v.AppVersion,
@ -132,7 +132,7 @@ func LogLogin(platform string, batchSize int) ([]*mysqlmodel.LogLogin, error) {
} }
e.OfflineType = mysqlmodel.LogTypeOffline e.OfflineType = mysqlmodel.LogTypeOffline
e.OfflineTs = v.Time.Unix() //e.OfflineTs = int(v.Ts)
e.OfflineTime = v.Time e.OfflineTime = v.Time
if err = db.Model(e).Select("OfflineType", "OfflineTime").Updates(e).Error; err != nil { if err = db.Model(e).Select("OfflineType", "OfflineTime").Updates(e).Error; err != nil {
logger.Logger.Errorf("mysql: SyncLogLogin failed to update log_login: %v", err) logger.Logger.Errorf("mysql: SyncLogLogin failed to update log_login: %v", err)
@ -155,19 +155,19 @@ func LogLogin(platform string, batchSize int) ([]*mysqlmodel.LogLogin, error) {
return err return err
} }
//for _, v := range ls { for _, v := range ls {
// if err = tx.First(&mysqlmodel.UserID{}, "snid = ?", v.Snid).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { if err = tx.First(&mysqlmodel.UserID{}, "snid = ?", v.Snid).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
// logger.Logger.Errorf("mysql: SyncLogLogin failed to find user_id: %v", err) logger.Logger.Errorf("mysql: SyncLogLogin failed to find user_id: %v", err)
// return err return err
// } }
//
// if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
// if err = tx.Create(&mysqlmodel.UserID{Snid: v.Snid}).Error; err != nil { if err = tx.Create(&mysqlmodel.UserID{Snid: v.Snid}).Error; err != nil {
// logger.Logger.Errorf("mysql: SyncLogLogin failed to create user_id: %v", err) logger.Logger.Errorf("mysql: SyncLogLogin failed to create user_id: %v", err)
// return err return err
// } }
// } }
//} }
return nil return nil
}) })

View File

@ -1,3 +1 @@
游戏服mongodb同步到mysql 游戏服mongodb同步到mysql
datasync.go 同步模型

View File

@ -68,9 +68,9 @@ func UserAccount(platform string, batchSize int) ([]*mysqlmodel.UserAccount, err
for _, v := range accounts { for _, v := range accounts {
logger.Logger.Tracef("mongo account: %+v", *v) logger.Logger.Tracef("mongo account: %+v", *v)
a := &mysqlmodel.UserAccount{ a := &mysqlmodel.UserAccount{
MID: v.AccountId.Hex(), MID: v.AccountId.Hex(),
Snid: int(v.SnId), Snid: int(v.SnId),
RegisterTs: v.RegisteTime.Unix(), //RegisterTs: int(v.RegisterTs),
RegisterTime: v.RegisteTime, RegisterTime: v.RegisteTime,
Tel: v.Tel, Tel: v.Tel,
ChannelId: v.ChannelId, ChannelId: v.ChannelId,
@ -81,17 +81,17 @@ func UserAccount(platform string, batchSize int) ([]*mysqlmodel.UserAccount, err
return err return err
} }
//if err = tx.First(&mysqlmodel.UserID{}, "snid = ?", v.SnId).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { if err = tx.First(&mysqlmodel.UserID{}, "snid = ?", v.SnId).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
// logger.Logger.Errorf("mysql: UserAccount failed to find user_id: %v", err) logger.Logger.Errorf("mysql: UserAccount failed to find user_id: %v", err)
// return err return err
//} }
//
//if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
// if err = tx.Create(&mysqlmodel.UserID{Snid: int(v.SnId)}).Error; err != nil { if err = tx.Create(&mysqlmodel.UserID{Snid: int(v.SnId)}).Error; err != nil {
// logger.Logger.Errorf("mysql: UserAccount failed to create user_id: %v", err) logger.Logger.Errorf("mysql: UserAccount failed to create user_id: %v", err)
// return err return err
// } }
//} }
as = append(as, a) as = append(as, a)
} }

View File

@ -1,21 +1,17 @@
StartTime: "2024-12-25T00:00:00+08:00" StartTime: "2024-11-26T00:00:00+08:00"
EndTime: "2024-12-26T00:00:00+08:00" EndTime: "2024-11-27T00:00:00+08:00"
IsDatabaseMode: true
ListenPort: 8888
Switch: # 1: open, 0: close Switch: # 1: open, 0: close
- 1 # 新用户游戏破产率 - 0 # 新用户游戏破产率
- 1 # 新用户平均游戏时长 - 0 # 新用户平均游戏时长
- 1 # 用户平均游戏时长 - 0 # 新用户平均局数
- 1 # 新用户平均局数 - 0 # 平均倍数
- 1 # 平均倍数
- 1 # 活跃破产率 - 1 # 活跃破产率
- 0 # 控输赢胜率 - 1 # 控输赢胜率
- 0 # 机器人胜率 - 1 # 机器人胜率
- 0 # 人均获得金币 - 1 # 人均获得金币
- 0 # 破产后离线 - 1 # 破产后离线
- 0 # 充值玩家金币余额 - 1 # 充值玩家金币余额
Gamefreeids: Gamefreeids:
- 2070001 - 2070001

View File

@ -2,14 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"golang.org/x/exp/maps"
"strings"
"github.com/mozillazg/go-pinyin"
"github.com/xuri/excelize/v2" "github.com/xuri/excelize/v2"
"gorm.io/gorm"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/mysqlx"
) )
type ExcelData struct { type ExcelData struct {
@ -17,10 +10,6 @@ type ExcelData struct {
Head []string Head []string
Index int Index int
IndexCell int IndexCell int
TableName string
TableHead []string
DataName string
} }
func (e *ExcelData) SetHead(head []string) *ExcelData { func (e *ExcelData) SetHead(head []string) *ExcelData {
@ -70,26 +59,13 @@ func NewExcelMgr() *ExcelMgr {
} }
} }
func (e *ExcelMgr) Register(id int, head []string, filename string) *ExcelData { func (e *ExcelMgr) Register(id int, head []string) *ExcelData {
e.List[id] = &ExcelData{ e.List[id] = &ExcelData{
File: excelize.NewFile(), File: excelize.NewFile(),
Head: head, Head: head,
Index: 0, Index: 0,
} }
name := ChineseToPinYin([]string{filename})
if len(name) == 0 {
return nil
}
tableName := fmt.Sprintf("task_%s", name[0])
e.List[id].TableName = tableName
for _, v := range head {
cl := ChineseToPinYin([]string{v})[0]
e.List[id].TableHead = append(e.List[id].TableHead, cl)
}
e.List[id].DataName = filename
e.List[id].NewSheet("Sheet1") e.List[id].NewSheet("Sheet1")
if len(head) > 0 { if len(head) > 0 {
@ -103,180 +79,10 @@ func (e *ExcelMgr) Get(id int) *ExcelData {
return e.List[id] return e.List[id]
} }
func (e *ExcelMgr) Save(id int, startTime, endTime string) error { func (e *ExcelMgr) Save(id int, fileName string) error {
d := e.List[id] d := e.List[id]
if d == nil { if d == nil {
return nil return nil
} }
return d.SaveAs(fileName)
filename := fmt.Sprintf("%s_%s_%s.xlsx", d.DataName, startTime, endTime)
if VP.GetBool("IsDatabaseMode") {
rows, err := d.GetRows("Sheet1")
if err != nil {
return err
}
db, err := mysqlx.GetDatabase("1")
if err != nil {
logger.Logger.Errorf("GetDatabase error: %v", err)
return err
}
files := make(map[string]string)
index := make(map[string]string)
for _, v := range d.Head {
cl := ChineseToPinYin([]string{v})[0]
d.TableHead = append(d.TableHead, cl)
files[cl] = v
if strings.Contains(v, "*") {
index[cl] = "INDEX"
}
}
createSQL := buildCreateTableSQLWithIndices(d.TableName, d.DataName, files, index)
if err = db.Exec(createSQL).Error; err != nil {
logger.Logger.Errorf("createTable error: %v", err)
return err
}
if err = insertData(db.DB, d.TableName, maps.Keys(files), rows); err != nil {
logger.Logger.Errorf("insertData error: %v", err)
return err
}
return nil
}
return d.SaveAs(filename)
}
func (e *ExcelMgr) Pull(id int, startTime, endTime string) (*excelize.File, string, error) {
d := e.List[id]
if d == nil {
return nil, "", nil
}
db, err := mysqlx.GetDatabase("1")
if err != nil {
logger.Logger.Errorf("GetDatabase error: %v", err)
return nil, "", err
}
rows, err := db.Table(d.TableName).Where("ri_qi between ? and ?", startTime, endTime).Select(d.TableHead).Rows()
if err != nil {
logger.Logger.Errorf("Pull error: %v", err)
return nil, "", err
}
defer rows.Close()
f := excelize.NewFile()
f.NewSheet("Sheet1")
f.SetSheetRow("Sheet1", "A1", &d.Head)
index := 2
for rows.Next() {
data := make([]interface{}, len(d.TableHead))
scanArgs := make([]interface{}, len(d.TableHead))
for i := range data {
scanArgs[i] = &data[i]
}
err = rows.Scan(scanArgs...)
if err != nil {
logger.Logger.Errorf("Pull error: %v", err)
return nil, "", err
}
f.SetSheetRow("Sheet1", "A"+fmt.Sprintf("%d", index), &data)
index++
}
return f, fmt.Sprintf("%s_%s_%s", d.DataName, startTime, endTime), nil
}
// 构建创建表的 SQL 语句,支持中文描述和索引
func buildCreateTableSQLWithIndices(tableName string, comment string, fields map[string]string, indices map[string]string) string {
var columns []string
var indexDefs []string
// 遍历字段定义
for field, comment := range fields {
column := fmt.Sprintf("`%s` VARCHAR(255) COMMENT '%s'", field, comment)
columns = append(columns, column)
// 根据索引类型添加索引定义
if indexType, ok := indices[field]; ok {
switch strings.ToUpper(indexType) {
case "PRIMARY":
indexDefs = append(indexDefs, fmt.Sprintf("PRIMARY KEY (`%s`)", field))
case "UNIQUE":
indexDefs = append(indexDefs, fmt.Sprintf("UNIQUE KEY `idx_%s` (`%s`)", field, field))
case "INDEX":
indexDefs = append(indexDefs, fmt.Sprintf("KEY `idx_%s` (`%s`)", field, field))
}
}
}
// 拼接字段和索引部分
allDefs := append(columns, indexDefs...)
ret := fmt.Sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n%s\n) COMMENT='%s';",
tableName,
strings.Join(allDefs, ",\n"), comment)
logger.Logger.Tracef("createTableSQL: %s", ret)
// 拼接最终的 SQL
return ret
}
func insertData(db *gorm.DB, tableName string, header []string, rows [][]string) error {
placeholders := strings.Repeat("?,", len(header))
placeholders = placeholders[:len(placeholders)-1] // 移除多余的逗号
insertSQL := fmt.Sprintf("INSERT INTO `%s` (%s) VALUES (%s)", tableName, "`"+strings.Join(header, "`,`")+"`", placeholders)
for _, row := range rows {
// 确保每行数据长度和表头一致
if len(row) < len(header) {
for len(row) < len(header) {
row = append(row, "") // 填充缺失列
}
}
err := db.Exec(insertSQL, interfaceSlice(row)...).Error
if err != nil {
return err
}
}
return nil
}
func interfaceSlice(slice []string) []interface{} {
result := make([]interface{}, len(slice))
for i, v := range slice {
result[i] = v
}
return result
}
var args = pinyin.NewArgs()
func init() {
args.Style = pinyin.Normal
}
func joinPinyin(py [][]string) string {
var result []string
for _, word := range py {
if len(word) > 0 {
result = append(result, word[0]) // 每个字的拼音取第一个候选
}
}
return strings.Join(result, "_")
}
func ChineseToPinYin(param []string) []string {
var ret []string
for _, v := range param {
ret = append(ret, joinPinyin(pinyin.Pinyin(v, args)))
}
return ret
} }

View File

@ -1,51 +0,0 @@
package main
import (
"net/http"
"strconv"
)
/*
下载
GET http://127.0.0.1:8888/statistics/task?data_type=0&start_time=2024-12-26&end_time=2024-12-26
请求参数
data_type 数据类型
0新用户游戏破产率
1新用户平均游戏时长
2用户平均游戏时长
3新用户平均局数
4平均倍数
5活跃破产率
start_time 开始时间
end_time 结束时间
*/
// Download 下载
func Download(w http.ResponseWriter, r *http.Request) {
// 请求参数
// data_type 数据类型
// start_time 开始时间
// end_time 结束时间
// Request parameters
dataType, err := strconv.Atoi(r.URL.Query().Get("data_type"))
if err != nil {
http.Error(w, "Invalid data_type", http.StatusBadRequest)
return
}
startTime := r.URL.Query().Get("start_time")
endTime := r.URL.Query().Get("end_time")
f, name, err := ExcelMgrSingle.Pull(dataType, startTime, endTime)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer f.Close()
w.Header().Set("Content-Type", "application/octet-stream;charset=UTF-8")
w.Header().Set("Content-Disposition", "attachment; filename=\""+name+".xlsx\"")
f.Write(w)
}

View File

@ -2,10 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"mongo.games.com/goserver/core/utils"
"net/http"
"os"
"os/signal"
"sort" "sort"
"time" "time"
@ -15,7 +11,6 @@ import (
"mongo.games.com/goserver/core/mysqlx" "mongo.games.com/goserver/core/mysqlx"
"mongo.games.com/goserver/core/viperx" "mongo.games.com/goserver/core/viperx"
"mongo.games.com/game/common"
"mongo.games.com/game/statistics/task/gamefree" "mongo.games.com/game/statistics/task/gamefree"
"mongo.games.com/game/statistics/task/task" "mongo.games.com/game/statistics/task/task"
) )
@ -23,7 +18,6 @@ import (
const ( const (
ExcelTypeNewPlayerBankrupt = iota // 新用户游戏破产率 ExcelTypeNewPlayerBankrupt = iota // 新用户游戏破产率
ExcelTypeGameTimeAvg // 新用户平均游戏时长 ExcelTypeGameTimeAvg // 新用户平均游戏时长
ExcelTypeGameTimeAllAvg // 用户平均游戏时长
ExcelTypeGameCountAvg // 新用户平均局数 ExcelTypeGameCountAvg // 新用户平均局数
ExcelTypeGameRate // 平均倍数 ExcelTypeGameRate // 平均倍数
ExcelTypeActiveRate // 活跃破产率 ExcelTypeActiveRate // 活跃破产率
@ -35,13 +29,33 @@ const (
) )
var VP *viper.Viper var VP *viper.Viper
var ExcelMgrSingle *ExcelMgr
func run() { func main() {
if VP.GetBool("IsDatabaseMode") { defer func() {
VP.Set("StartTime", common.HMSToTime(0, 0, 0).Format(time.RFC3339)) logger.Logger.Flush()
VP.Set("EndTime", common.HMSToTime(0, 0, 0).AddDate(0, 0, 1).Format(time.RFC3339)) logger.Logger.Close()
}()
VP = viperx.GetViper("config", "yaml")
// mongo
vp := viperx.GetViper("mongo", "yaml")
// mongo初始化
conf := &mongox.Config{}
err := vp.Unmarshal(conf)
if err != nil {
panic(fmt.Errorf("mongo config error: %v", err))
} }
mongox.Init(conf)
defer mongox.Close()
// mysql
vp = viperx.GetViper("mysql", "yaml")
myConf := &mysqlx.Config{}
err = vp.Unmarshal(myConf)
if err != nil {
panic(fmt.Errorf("mysql config error: %v", err))
}
mysqlx.Init(myConf)
defer mysqlx.Close()
startTime, err := time.Parse(time.RFC3339, VP.GetString("StartTime")) startTime, err := time.Parse(time.RFC3339, VP.GetString("StartTime"))
if err != nil { if err != nil {
@ -54,6 +68,18 @@ func run() {
return return
} }
mgr := NewExcelMgr()
mgr.Register(ExcelTypeNewPlayerBankrupt, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeGameTimeAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"})
mgr.Register(ExcelTypeGameCountAvg, []string{"日期", "场次id", "参与人数", "平均局数"})
mgr.Register(ExcelTypeGameRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeActiveRate, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeCtrlWinRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeCtrlWinRate*10, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeRobotWinRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeCoinAvg, []string{"日期", "场次id", "参与人数", "人均获得金币"})
mgr.Register(ExcelTypeBankruptOffline, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeOfflineCoin, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"})
switchArr := VP.GetIntSlice("Switch") switchArr := VP.GetIntSlice("Switch")
for { for {
@ -67,161 +93,83 @@ func run() {
if switchArr[ExcelTypeNewPlayerBankrupt] == 1 { if switchArr[ExcelTypeNewPlayerBankrupt] == 1 {
// 新用户游戏破产率 // 新用户游戏破产率
ExcelMgrSingle.GenNewPlayerBankruptRateExcel("1", startTimeStr, endTimeStr) mgr.GenNewPlayerBankruptRateExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeGameTimeAvg] == 1 { if switchArr[ExcelTypeGameTimeAvg] == 1 {
// 新用户平均游戏时长 // 新用户平均游戏时长
ExcelMgrSingle.GenNewPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr) mgr.GenNewPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
// 用户平均游戏时长
ExcelMgrSingle.GenPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeGameCountAvg] == 1 { if switchArr[ExcelTypeGameCountAvg] == 1 {
// 新用户平均局数 // 新用户平均局数
ExcelMgrSingle.GenGameCountExcel("1", startTimeStr, endTimeStr) mgr.GenGameCountExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeGameRate] == 1 { if switchArr[ExcelTypeGameRate] == 1 {
// 平均倍数 // 平均倍数
ExcelMgrSingle.GenGameRateExcel("1", startTimeStr, endTimeStr) mgr.GenGameRateExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeActiveRate] == 1 { if switchArr[ExcelTypeActiveRate] == 1 {
// 活跃破产率 // 活跃破产率
ExcelMgrSingle.GenActiveBankruptRateExcel("1", startTimeStr, endTimeStr) mgr.GenActiveBankruptRateExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeCtrlWinRate] == 1 { if switchArr[ExcelTypeCtrlWinRate] == 1 {
// 控赢胜率 // 控赢胜率
ExcelMgrSingle.GenCtrlWinRateExcel("1", startTimeStr, endTimeStr) mgr.GenCtrlWinRateExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeRobotWinRate] == 1 { if switchArr[ExcelTypeRobotWinRate] == 1 {
// 机器人胜率 // 机器人胜率
ExcelMgrSingle.GenRobotWinRateExcel("1", startTimeStr, endTimeStr) mgr.GenRobotWinRateExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeCoinAvg] == 1 { if switchArr[ExcelTypeCoinAvg] == 1 {
// 人均获得金币 // 人均获得金币
ExcelMgrSingle.GenCoinAvgExcel("1", startTimeStr, endTimeStr) mgr.GenCoinAvgExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeBankruptOffline] == 1 { if switchArr[ExcelTypeBankruptOffline] == 1 {
// 破产后离线 // 破产后离线
ExcelMgrSingle.GenBankruptOfflineExcel("1", startTimeStr, endTimeStr) mgr.GenBankruptOfflineExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeOfflineCoin] == 1 { if switchArr[ExcelTypeOfflineCoin] == 1 {
// 离线金币 // 离线金币
ExcelMgrSingle.GenOfflineCoinExcel("1", startTimeStr, endTimeStr) mgr.GenOfflineCoinExcel("1", startTimeStr, endTimeStr)
} }
startTime = et startTime = et
} }
ExcelMgrSingle.SaveAll(VP.GetString("StartTime")[:10], endTime.AddDate(0, 0, -1).Format(time.DateOnly)) mgr.SaveAll(VP.GetString("StartTime")[:10], endTime.AddDate(0, 0, -1).Format(time.DateOnly))
}
func main() {
defer func() {
logger.Logger.Flush()
logger.Logger.Close()
}()
VP = viperx.GetViper("config.yaml")
// mongo
vp := viperx.GetViper("mongo.yaml")
// mongo初始化
conf := &mongox.Config{}
err := vp.Unmarshal(conf)
if err != nil {
panic(fmt.Errorf("mongo config error: %v", err))
}
mongox.Init(conf)
defer mongox.Close()
// mysql
vp = viperx.GetViper("mysql.yaml")
myConf := &mysqlx.Config{}
err = vp.Unmarshal(myConf)
if err != nil {
panic(fmt.Errorf("mysql config error: %v", err))
}
mysqlx.Init(myConf)
defer mysqlx.Close()
mgr := NewExcelMgr()
ExcelMgrSingle = mgr
mgr.Register(ExcelTypeNewPlayerBankrupt, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "新用户破产率")
mgr.Register(ExcelTypeGameTimeAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"}, "新用户平均游戏时长")
mgr.Register(ExcelTypeGameTimeAllAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"}, "用户平均游戏时长")
mgr.Register(ExcelTypeGameCountAvg, []string{"日期", "场次id", "参与人数", "平均局数"}, "新用户平均局数")
mgr.Register(ExcelTypeGameRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "平均倍数")
mgr.Register(ExcelTypeActiveRate, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "活跃破产率")
mgr.Register(ExcelTypeCtrlWinRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "控赢胜率")
mgr.Register(ExcelTypeCtrlWinRate*10, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "控数胜率")
mgr.Register(ExcelTypeRobotWinRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}, "机器人输率")
mgr.Register(ExcelTypeCoinAvg, []string{"日期", "场次id", "参与人数", "人均获得金币"}, "人均获得金币")
mgr.Register(ExcelTypeBankruptOffline, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "破产后离线")
mgr.Register(ExcelTypeOfflineCoin, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}, "离线金币")
if VP.GetBool("IsDatabaseMode") {
// 每天凌晨执行一次 run方法
var f func()
f = func() {
nextTime := common.HMSToTime(0, 0, 0).AddDate(0, 0, 1)
time.AfterFunc(nextTime.Sub(time.Now())+time.Second*10, func() {
go utils.RepeatUntilPanicless(run)
f()
})
}
f()
//run()
listenPort := VP.GetString("ListenPort")
http.HandleFunc("/statistics/task", Download)
go http.ListenAndServe(fmt.Sprintf(":%v", listenPort), nil)
logger.Logger.Infof("start server 0.0.0.0:%v", listenPort)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)
sig := <-c
logger.Logger.Infof("closing down (signal: %v)", sig)
} else {
run()
}
} }
func (e *ExcelMgr) SaveAll(startTime, endTime string) { func (e *ExcelMgr) SaveAll(startTime, endTime string) {
switchArr := VP.GetIntSlice("Switch") switchArr := VP.GetIntSlice("Switch")
if switchArr[ExcelTypeNewPlayerBankrupt] == 1 { if switchArr[ExcelTypeNewPlayerBankrupt] == 1 {
e.Save(ExcelTypeNewPlayerBankrupt, startTime, endTime) e.Save(ExcelTypeNewPlayerBankrupt, fmt.Sprintf("新用户破产率_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeGameTimeAvg] == 1 { if switchArr[ExcelTypeGameTimeAvg] == 1 {
e.Save(ExcelTypeGameTimeAvg, startTime, endTime) e.Save(ExcelTypeGameTimeAvg, fmt.Sprintf("新用户平局游戏时长_%s_%s.xlsx", startTime, endTime))
}
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
e.Save(ExcelTypeGameTimeAllAvg, startTime, endTime)
} }
if switchArr[ExcelTypeGameCountAvg] == 1 { if switchArr[ExcelTypeGameCountAvg] == 1 {
e.Save(ExcelTypeGameCountAvg, startTime, endTime) e.Save(ExcelTypeGameCountAvg, fmt.Sprintf("新用户平均局数_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeGameRate] == 1 { if switchArr[ExcelTypeGameRate] == 1 {
e.Save(ExcelTypeGameRate, startTime, endTime) e.Save(ExcelTypeGameRate, fmt.Sprintf("平均倍数_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeActiveRate] == 1 { if switchArr[ExcelTypeActiveRate] == 1 {
e.Save(ExcelTypeActiveRate, startTime, endTime) e.Save(ExcelTypeActiveRate, fmt.Sprintf("活跃破产率_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeCtrlWinRate] == 1 { if switchArr[ExcelTypeCtrlWinRate] == 1 {
e.Save(ExcelTypeCtrlWinRate, startTime, endTime) e.Save(ExcelTypeCtrlWinRate, fmt.Sprintf("控赢胜率_%s_%s.xlsx", startTime, endTime))
e.Save(ExcelTypeCtrlWinRate*10, startTime, endTime) e.Save(ExcelTypeCtrlWinRate*10, fmt.Sprintf("控输胜率_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeRobotWinRate] == 1 { if switchArr[ExcelTypeRobotWinRate] == 1 {
e.Save(ExcelTypeRobotWinRate, startTime, endTime) e.Save(ExcelTypeRobotWinRate, fmt.Sprintf("机器人输率_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeCoinAvg] == 1 { if switchArr[ExcelTypeCoinAvg] == 1 {
e.Save(ExcelTypeCoinAvg, startTime, endTime) e.Save(ExcelTypeCoinAvg, fmt.Sprintf("人均获得金币_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeBankruptOffline] == 1 { if switchArr[ExcelTypeBankruptOffline] == 1 {
e.Save(ExcelTypeBankruptOffline, startTime, endTime) e.Save(ExcelTypeBankruptOffline, fmt.Sprintf("破产后离线_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeOfflineCoin] == 1 { if switchArr[ExcelTypeOfflineCoin] == 1 {
e.Save(ExcelTypeOfflineCoin, startTime, endTime) e.Save(ExcelTypeOfflineCoin, fmt.Sprintf("离线金币_%s_%s.xlsx", startTime, endTime))
} }
} }
@ -275,29 +223,6 @@ func (e *ExcelMgr) GenNewPlayerGameTimeAvgExcel(plt string, startTime, endTime s
} }
} }
func (e *ExcelMgr) GenPlayerGameTimeAvgExcel(plt string, startTime, endTime string) {
for _, v := range VP.GetIntSlice("Gamefreeids") {
a, b, err := task.PlayerGameTimeAvg(plt, startTime, endTime, v)
if err != nil {
logger.Logger.Errorf("PlayerGameTimeAvg get StartTime:%v EndTime:%v GameFreeId:%v err: %v", startTime, endTime, v, err)
continue
}
ex := e.Get(ExcelTypeGameTimeAllAvg)
ex.NewLine()
ex.SetCell(startTime[:10])
ex.SetCell(GetGameFreeName(v))
ex.SetCell(a)
if a > 0 {
avg := float64(b) / float64(a)
show := fmt.Sprintf("%v", time.Second*time.Duration(avg))
ex.SetCell(show)
} else {
ex.SetCell(0)
}
logger.Logger.Tracef("PlayerGameTimeAvg GameFreeId: %v avg: %v", v, float64(b)/float64(a))
}
}
func (e *ExcelMgr) GenGameCountExcel(plt string, startTime, endTime string) { func (e *ExcelMgr) GenGameCountExcel(plt string, startTime, endTime string) {
for _, v := range VP.GetIntSlice("Gamefreeids") { for _, v := range VP.GetIntSlice("Gamefreeids") {
a, b, err := task.NewPlayerGameCountAvg(plt, startTime, endTime, v) a, b, err := task.NewPlayerGameCountAvg(plt, startTime, endTime, v)

View File

@ -45,37 +45,6 @@ func GetNewPayerIds(plt string, startTime, endTime string) ([]int, error) {
return ret, nil return ret, nil
} }
func GetPayerIds(plt string, startTime, endTime string, gamefreeid int) ([]int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
c, err := mymongo.GetLogCollection(plt, mongomodel.LogGamePlayerListLog)
if err != nil {
return nil, err
}
var res []struct{ Snid int }
dd, err := c.Aggregate(context.TODO(), bson.A{
bson.M{"$match": bson.M{"time": bson.M{"$gte": s, "$lt": e}, "gamefreeid": gamefreeid}},
bson.M{"$group": bson.M{"_id": "$snid", "snid": bson.M{"$first": "$snid"}}},
})
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, nil
}
logger.Logger.Errorf("find game player snid get err: %v", err)
return nil, err
}
if err := dd.All(context.TODO(), &res); err != nil {
logger.Logger.Errorf("find game player snid decode err: %v", err)
return nil, err
}
var ret []int
for _, v := range res {
ret = append(ret, v.Snid)
}
logger.Logger.Tracef("find game player snid: %v", ret)
return ret, nil
}
// 场次破产总人数 // 场次破产总人数
func GameFreeIdBankruptPlayerCount(plt string, ids []int, startTime, endTime string, gamefreeid int) (int, error) { func GameFreeIdBankruptPlayerCount(plt string, ids []int, startTime, endTime string, gamefreeid int) (int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime) s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)

View File

@ -36,10 +36,7 @@ func NewPlayerGameTime(plt string, ids []int, startTime, endTime string, gamefre
if gamefreeid > 0 { if gamefreeid > 0 {
where["gamefreeid"] = gamefreeid where["gamefreeid"] = gamefreeid
} }
cur, err := c.Aggregate(context.Background(), bson.A{ cur, err := c.Find(context.TODO(), where, options.Find().SetProjection(bson.M{"gamedetailedlogid": 1}))
bson.M{"$match": where},
bson.M{"$group": bson.M{"_id": "$gamedetailedlogid", "gamedetailedlogid": bson.M{"$first": "$gamedetailedlogid"}}},
})
if err != nil { if err != nil {
logger.Logger.Errorf("find player gamedetailedlogid get err: %v", err) logger.Logger.Errorf("find player gamedetailedlogid get err: %v", err)
return 0, 0, err return 0, 0, err
@ -105,26 +102,3 @@ func NewPlayerGameTimeAvg(plt string, startTime, endTime string, gamefreeid int)
} }
return b, a, err return b, a, err
} }
func PlayerGameTimeAvg(plt string, startTime, endTime string, gamefreeid int) (int, int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
if s.IsZero() || e.IsZero() {
return 0, 0, fmt.Errorf("time format error")
}
ids, err := GetPayerIds(plt, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, err
}
if len(ids) == 0 {
return 0, 0, nil
}
a, _, err := NewPlayerGameTime(plt, ids, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, err
}
if len(ids) == 0 {
return 0, 0, nil
}
return len(ids), a, err
}

5
todo
View File

@ -7,7 +7,4 @@ dbproxy优化:
参考 https://go-zero.dev/ 中的goctl工具 参考 https://go-zero.dev/ 中的goctl工具
消息队列数据恢复发送: 消息队列数据恢复发送:
发送失败的消息会写入本地文件等mq正常后尝试重新发送 发送失败的消息会写入本地文件等mq正常后尝试重新发送
代理业务需要重构支持worldsrv的滚动更新
dbproxy/mq/c_invite.go

Some files were not shown because too many files have changed in this diff Show More