diff --git a/game-server/app/servers/battle/handler/comBattleHandler.ts b/game-server/app/servers/battle/handler/comBattleHandler.ts index eaf414916..6fdc12f84 100644 --- a/game-server/app/servers/battle/handler/comBattleHandler.ts +++ b/game-server/app/servers/battle/handler/comBattleHandler.ts @@ -561,6 +561,7 @@ export class ComBattleHandler { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); + let ip = session.get('ip'); let { teamCode } = msg; let team = await ComBattleTeamModel.getTeamByCode(teamCode); @@ -578,7 +579,7 @@ export class ComBattleHandler { if (!warInfo) return resResult(STATUS.BATTLE_MISS_INFO); let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await setAp(roleId, role.lv, -1 * warInfo.cost, sid); // 扣除体力 + let apJson = await setAp(roleId, ip, role.lv, -1 * warInfo.cost, sid, ITEM_CHANGE_REASON.COM_BATTLE_END); // 扣除体力 if(!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } @@ -592,7 +593,7 @@ export class ComBattleHandler { // } await ComBattleTeamModel.updateRewardSt(teamCode, roleId, true); - const goods = await addItems(roleId, roleName, sid, roleSt.fixReward, ITEM_CHANGE_REASON.COM_BATTLE_REWARD); + const goods = await addItems(roleId, roleName, sid, roleSt.fixReward, ITEM_CHANGE_REASON.COM_BATTLE_END); let actordata = await roleLevelup(KING_EXP_RATIO_TYPE.BATTLE, roleId, warInfo.kingExp, session);// 主公升级经验 // 任务 await checkTaskWithGoods(roleId, sid, TASK_TYPE.COM_BATTLE_DROP, goods); diff --git a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts index d1c5aa0e4..6e17a03bd 100644 --- a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts +++ b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts @@ -122,13 +122,14 @@ export class ExpeditionBattleHandler { const { expeditionCode, expeditionId, battleId, heroes: seqIds = [] } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); + let ip = session.get('ip'); let warInfo = gameData.war.get(battleId); if (!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await getAp(roleId, role.lv); + let apJson = await getAp(roleId, ip, role.lv); let { ap } = apJson; if (ap < warInfo.cost) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); @@ -185,7 +186,7 @@ export class ExpeditionBattleHandler { let roleName = session.get('roleName'); const serverId = session.get('serverId'); let sid = session.get('sid'); - + let ip = session.get('ip'); let warInfo = gameData.war.get(battleId); if (!warInfo) { @@ -207,7 +208,7 @@ export class ExpeditionBattleHandler { } let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await setAp(roleId, role.lv, isSuccess?-1 * warInfo.cost: 0, sid); // 扣除体力 + let apJson = await setAp(roleId, ip, role.lv, isSuccess?-1 * warInfo.cost: 0, sid, ITEM_CHANGE_REASON.EXPEDITION_BATTLE_END); // 扣除体力 if (!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index 3def077ef..c1c788520 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -1,7 +1,7 @@ import { Application, BackendSession, HandlerService, } from 'pinus'; import { BattleRecordModel } from '../../../db/BattleRecord'; import { BattleSweepRecordModel } from '../../../db/BattleSweepRecord'; -import { genCode } from '../../../pubUtils/util'; +import { genCode, getReasonByWarType } from '../../../pubUtils/util'; import { WAR_TYPE, EVENT_STATUS, FUNC_OPT_TYPE, MSG_SOURCE, REDIS_KEY, TASK_TYPE, KING_EXP_RATIO_TYPE } from '../../../consts'; import { checkDaily, checkDailyAndIncrease } from '../../../services/dailyBattleService'; import { checkTowerWar, towerBattleEnd } from '../../../services/battleService'; @@ -39,12 +39,13 @@ export class NormalBattleHandler { const { battleId, heroes: seqIds = [] } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); + let ip = session.get('ip'); let warInfo = gameData.war.get(battleId); if (!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await getAp(roleId, role.lv); + let apJson = await getAp(roleId, ip, role.lv); let { ap } = apJson; if (ap < warInfo.cost) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); @@ -128,7 +129,7 @@ export class NormalBattleHandler { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); - + let ip = session.get('ip'); let serverId = session.get('serverId'); let skipReward = false;//是否跳过奖励结算 @@ -156,7 +157,7 @@ export class NormalBattleHandler { } let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await setAp(roleId, role.lv, isSuccess? -1 * warInfo.cost: 0, sid); // 扣除体力 + let apJson = await setAp(roleId, ip, role.lv, isSuccess? -1 * warInfo.cost: 0, sid, getReasonByWarType(warInfo.warType)); // 扣除体力 if (!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } @@ -281,6 +282,7 @@ export class NormalBattleHandler { let roleName = session.get('roleName'); let sid = session.get('sid'); let serverId = session.get('serverId'); + let ip = session.get('ip'); let warInfo = gameData.war.get(battleId); if (!warInfo) { @@ -295,7 +297,7 @@ export class NormalBattleHandler { // 扣体力 let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await setAp(roleId, role.lv, -1 * warInfo.cost * count, sid); // 扣除体力 + let apJson = await setAp(roleId, ip, role.lv, -1 * warInfo.cost * count, sid, getReasonByWarType(warInfo.warType)); // 扣除体力 if (!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index f4f416311..8a8ec8063 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -7,7 +7,7 @@ import { Application, HandlerService, pinus, } from 'pinus'; import { FrontendSession } from 'pinus'; import { HeroModel } from './../../../db/Hero'; import { genCode, generateStr, resResult } from '../../../pubUtils/util'; -import { COM_BTL_QUALITY, HERO_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY, TASK_TYPE, ENTERY_ROLE_PICK, COUNTER, DEFAULT_LV } from '../../../consts'; +import { COM_BTL_QUALITY, HERO_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY, TASK_TYPE, ENTERY_ROLE_PICK, COUNTER, DEFAULT_LV, TA_USERSET_TYPE } from '../../../consts'; import { getAp } from '../../../services/actionPointService'; import { ItemModel } from '../../../db/Item'; import { SkinModel } from '../../../db/Skin'; @@ -24,6 +24,7 @@ import { pick } from 'lodash'; import { setComBtlOnUserLeave } from '../../../services/comBattleService'; import Counter from '../../../db/Counter'; import { getExpByLv } from '../../../pubUtils/data'; +import { reportTAUserSet } from '../../../services/sdkService'; export default function (app: Application) { new HandlerService(app, {}); @@ -98,7 +99,8 @@ export class EntryHandler { role['equips'] = equips; role['consumeGoods'] = items; role['skins'] = skins; - let apJson = await getAp(role.roleId, role.lv); + let ip = session.remoteAddress.ip.replace('::ffff:', ''); + let apJson = await getAp(role.roleId, ip, role.lv); role['apJson'] = apJson; if (!role.showLineup) role.showLineup = role.topLineup.map(cur => cur.hid); @@ -120,17 +122,21 @@ export class EntryHandler { async addSession(role: RoleType, session: FrontendSession) { const self = this; + let ip = session.remoteAddress.ip.replace('::ffff:', ''); + await session.abind(role.roleId); session.set('userid', role.userInfo.uid); session.set('uid', role.roleId); session.set('roleId', role.roleId); let updatedMailAt = role.updatedMailAt ? role.updatedMailAt : 0; session.set('updatedMailAt', updatedMailAt); + session.set('loginTime', role.loginTime); session.set('roleName', role.roleName); session.set('eventStatus', role.eventStatus); session.set('sid', self.app.get('serverId')); session.set('serverId', role.serverId); session.set('guildCode', role.guildCode); + session.set('ip', ip); session.push('userid', () => { }); session.push('sid', () => { }); session.push('roleId', () => { }); @@ -138,7 +144,9 @@ export class EntryHandler { session.push('eventStatus', () => { }); session.push('serverId', () => { }); session.push('updatedMailAt', () => { }); + session.push('loginTime', () => { }); session.push('guildCode', () => { }); + session.push('ip', () => { }); // console.log(role.guildCode) // session.push('rid', function (err) { // if (err) { @@ -191,6 +199,7 @@ export class EntryHandler { let roleId = session.get('roleId'); let sid = session.get('sid'); let serverId = session.get('serverId'); + let loginTime = session.get('loginTime'); const guildCode = session.get('guildCode'); const teamCode: string = session.get('teamCode'); roleLeave(roleId).then(function (roleInfo) { @@ -198,6 +207,7 @@ export class EntryHandler { savePlayTime(roleInfo.userCode); } }); + reportTAUserSet(TA_USERSET_TYPE.ADD, roleId, nowSeconds() - loginTime); rmRoleFromQueue(roleId, sid, COM_BTL_QUALITY, null); // 删除redis中寻宝的匹配记录 let channelService = this.app.get('channelService'); let channel = channelService.getChannel(roleId, true); diff --git a/game-server/app/servers/guild/handler/auctionHandler.ts b/game-server/app/servers/guild/handler/auctionHandler.ts index 66349c05c..0ed2190cc 100644 --- a/game-server/app/servers/guild/handler/auctionHandler.ts +++ b/game-server/app/servers/guild/handler/auctionHandler.ts @@ -1,6 +1,6 @@ import { DividendModel } from './../../../db/Dividend'; import { Application, BackendSession, ChannelService, HandlerService, pinus, } from "pinus"; -import { AUCTION_STAGE, DEBUG_MAGIC_WORD, STATUS, CURRENCY_BY_TYPE, CURRENCY_TYPE, DATA_NAME, LOT_STATUS, CHANNEL_PREFIX, MAIL_TYPE, ITEM_CHANGE_REASON } from "../../../consts"; +import { AUCTION_STAGE, DEBUG_MAGIC_WORD, STATUS, CURRENCY_BY_TYPE, CURRENCY_TYPE, DATA_NAME, LOT_STATUS, CHANNEL_PREFIX, MAIL_TYPE, ITEM_CHANGE_REASON, TA_EVENT } from "../../../consts"; import { LotModel } from "../../../db/Lot"; import { ItemReward } from "../../../domain/dbGeneral"; import { genCode, resResult } from "../../../pubUtils/util"; @@ -16,11 +16,12 @@ import { unlockTrain } from '../../../services/guildTrainService'; import { UserGuildModel } from '../../../db/UserGuild'; import { UserGuildApplyModel } from '../../../db/UserGuildApply'; import * as dicParam from '../../../pubUtils/dicParam'; -import { getAuctionRewardByPoolId } from '../../../pubUtils/data'; +import { gameData, getAuctionRewardByPoolId } from '../../../pubUtils/data'; import { addRoleToGuildAuctionChannel, addRoleToWorldAuctionChannel, channelServer, groupRoomId, leaveGuildAuctionChannel } from '../../../services/chatService'; import { RewardInter } from '../../../pubUtils/interface'; import { sendMailByContent } from '../../../services/mailService'; import { getGoldObject } from '../../../pubUtils/itemUtils'; +import { reportTAEvent } from '../../../services/sdkService'; export default function (app: Application) { new HandlerService(app, {}); @@ -53,6 +54,7 @@ export class AuctionHandler { const sid = session.get('sid'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); + const ip = session.get('ip'); let res: any = await lockData(serverId, DATA_NAME.AUCTION_LOT, code);// 加锁 try { @@ -95,6 +97,8 @@ export class AuctionHandler { if (maxFlag) { newPrice = maxPrice; await sendMailByContent(MAIL_TYPE.AUTION_REWARD, roleId, { goods: [{ id: gid, count }] }); + let dicGoods = gameData.goods.get(gid); + reportTAEvent(roleId, TA_EVENT.AUCTION_ITEM_GET, { item_name: dicGoods?.name, item_count: count, deel_price: newPrice }, ip); } bidRoles.push({ roleId, price: newPrice, time: new Date() }); const newLot = await LotModel.updateLot({ code, curBuyer: roleId, curPrice: newPrice, bidRoles, status: max ? LOT_STATUS.MAX : (maxFlag ? LOT_STATUS.SOLD : LOT_STATUS.ING), watchingRoles: Array.from(new Set([...watchingRoles, roleId])) }); diff --git a/game-server/app/servers/guild/handler/guildHandler.ts b/game-server/app/servers/guild/handler/guildHandler.ts index ec7f85fcd..d922e5f74 100644 --- a/game-server/app/servers/guild/handler/guildHandler.ts +++ b/game-server/app/servers/guild/handler/guildHandler.ts @@ -1,6 +1,6 @@ import { Application, BackendSession, ChannelService, HandlerService, } from 'pinus'; import { resResult, getRandEelm, shouldRefresh, sortArrRandom } from '../../../pubUtils/util'; -import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB, GUILD_APPLY_TYPE, GUILD_STRUCTURE, GUILD_REC_TYPE, GUILD_STRUCTURE_NAME, MAIL_TYPE, REDIS_KEY, GUILD_SELECT, USER_GUILD_SELECT, TASK_TYPE, DEBUG_MAGIC_WORD, CHANNEL_PREFIX, MSG_TYPE, MSG_SOURCE, ITEM_CHANGE_REASON } from '../../../consts'; +import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB, GUILD_APPLY_TYPE, GUILD_STRUCTURE, GUILD_REC_TYPE, GUILD_STRUCTURE_NAME, MAIL_TYPE, REDIS_KEY, GUILD_SELECT, USER_GUILD_SELECT, TASK_TYPE, DEBUG_MAGIC_WORD, CHANNEL_PREFIX, MSG_TYPE, MSG_SOURCE, ITEM_CHANGE_REASON, TA_EVENT, GUILD_DISMISS_WAY, GUILD_MASTER_CHANGE_WAY } from '../../../consts'; import { UserGuildModel, UserGuildType } from '../../../db/UserGuild'; import { checkAuth, joinGuild, getGuildWithRefActive, getUserGuildWithRefActive, addActive, settleGuildWeekly, getMyGuildInfo, refreshUserGuild, setUserGuildSession } from '../../../services/guildService'; import { GuildModel, GuildType, GuildUpdateParam } from '../../../db/Guild'; @@ -26,6 +26,7 @@ import { Rank } from '../../../services/rankService'; import { checkTask } from '../../../services/taskService'; import { guildInter } from '../../../pubUtils/interface'; import * as dicParam from '../../../pubUtils/dicParam'; +import { reportTAEvent } from '../../../services/sdkService'; export default function (app: Application) { @@ -181,6 +182,7 @@ export class GuildHandler { const sid = session.get('sid'); const roleName = session.get('roleName'); const serverId = session.get('serverId'); + const ip = session.get('ip'); const { roleId: memberRoleId, auth, myUserGuild, hisUserGuild } = msg; const { guildCode: code } = myUserGuild; @@ -240,6 +242,8 @@ export class GuildHandler { this.app.rpc.chat.guildRemote.changeLeader.toServer(chatSid, code, guild.managerCnt, role, roleId); this.app.rpc.chat.guildRemote.addRec.toServer(chatSid, rec); await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_LEADER, memberRoleId, { sendName: roleName, params: [guild.name] }); + + reportTAEvent(roleId, TA_EVENT.GUILD_MASTER_CHANGE, { way: GUILD_MASTER_CHANGE_WAY, change_id_after: memberRoleId }, ip); } else { this.app.rpc.chat.guildRemote.updateInfo.toServer(chatSid, code, { managerCnt: guild.managerCnt }); await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_MEMBER, memberRoleId, { sendName: roleName, params: [guild.name] }); @@ -548,6 +552,8 @@ export class GuildHandler { const serverId = session.get('serverId'); const sid = session.get('sid'); + const roleId = session.get('roleId'); + const ip = session.get('ip'); const { code } = msg; const guild = await GuildModel.dismiss(code, serverId); @@ -569,6 +575,7 @@ export class GuildHandler { await r.removeFromRank({ guildCode: code }); let r2 = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId }); await r2.removeFromRank({ guildCode: code }); + reportTAEvent(roleId, TA_EVENT.GUILD_DISMISS, { name: guild.name, way: GUILD_DISMISS_WAY.GAME }, ip); return resResult(STATUS.SUCCESS, { code, status: guild.status }); } @@ -580,6 +587,7 @@ export class GuildHandler { const roleName = session.get('roleName'); const serverId = session.get('serverId'); const sid = session.get('sid'); + const ip = session.get('ip'); const { code } = msg; const userGuild = await UserGuildModel.quit(code, roleId); @@ -602,6 +610,7 @@ export class GuildHandler { this.app.rpc.chat.guildRemote.memberQuit.toServer(chatSid, code, roleId, guild, sid); setUserGuildSession(session, null); + reportTAEvent(roleId, TA_EVENT.GUILD_QUIT, { name: guild.name }, ip); return resResult(STATUS.SUCCESS, { hasGuild: role.hasGuild }); } @@ -638,6 +647,7 @@ export class GuildHandler { await this.app.rpc.connector.connectorRemote.setOtherUserGuildSession.toServer(sid,[{ roleId: memberRoleId, userGuild }]); await sendMailByContent(MAIL_TYPE.GUILD_BE_KICK, memberRoleId, { sendName: roleName, params: [guild.name] }); + reportTAEvent(memberRoleId, TA_EVENT.GUILD_QUIT, { name: guild.name }); return resResult(STATUS.SUCCESS, { memberCnt: guild.memberCnt }); } @@ -649,6 +659,7 @@ export class GuildHandler { const roleName = session.get('roleName'); const sid = session.get('sid'); const serverId = session.get('serverId'); + const ip = session.get('ip'); const { code, roleId: leaderRoleId } = msg; // 离线72小时 @@ -702,6 +713,7 @@ export class GuildHandler { await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_LEADER, topUser.roleId, { sendName: roleName, params: [guild.name] }); await updateUserInfo(REDIS_KEY.GUILD_INFO, code, [{ field: 'leader', value: new GuildLeader(topUser) }]); + reportTAEvent(roleId, TA_EVENT.GUILD_MASTER_CHANGE, { way: GUILD_MASTER_CHANGE_WAY.IMPEACH, change_id_after: topUser.roleId }, ip) let isOnline = await isRoleOnline(topUser.roleId); const leader = { ...topUser, ce: topUser.ce, isOnline } diff --git a/game-server/app/servers/order/handler/orderHandler.ts b/game-server/app/servers/order/handler/orderHandler.ts index 04f968c16..17238b640 100644 --- a/game-server/app/servers/order/handler/orderHandler.ts +++ b/game-server/app/servers/order/handler/orderHandler.ts @@ -1,6 +1,6 @@ import { Application, BackendSession, HandlerService, } from 'pinus'; import { genCode, resResult } from '../../../pubUtils/util'; -import { ACTIVITY_TYPE, DEBUG_MAGIC_WORD, ORDER_STATE, PAY_TYPE, STATUS, TASK_TYPE } from '../../../consts'; +import { ACTIVITY_TYPE, DEBUG_MAGIC_WORD, ORDER_STATE, PAY_TYPE, STATUS, TASK_TYPE, TA_EVENT } from '../../../consts'; import { dicRMB } from '../../../pubUtils/dictionary/DicRMB'; import { UserOrderModel } from '../../../db/UserOrder'; import _ = require('underscore'); @@ -12,6 +12,7 @@ import { addRechargeMoney } from '../../../services/activity/rechargeMoneyServic import { addVipRechargeMoney } from '../../../services/activity/vipRechargeMoneyService'; import { checkActivityTask } from '../../../services/taskService'; import { getActivityById } from '../../../services/activity/activityService'; +import { reportTAEvent } from '../../../services/sdkService'; export default function (app: Application) { new HandlerService(app, {}); @@ -34,6 +35,7 @@ export class orderHandler { const { productID, payType, activityId, paramStr } = msg; const roleId = session.get('roleId'); const serverId = session.get('serverId'); + const ip = session.get('ip'); //如果有特殊情况,activityId可为0 if (!productID || !_.isString(productID) || !payType || !_.isNumber(payType)) { @@ -99,6 +101,9 @@ export class orderHandler { return resResult(STATUS.NO_PAY_TYPE); } await UserOrderModel.applyOrder(serverId, roleId, productID, localOrderID, orderID, price, payType, activityId, paramStr, message); + reportTAEvent(roleId, TA_EVENT.RECHARGE, { + pay_id: localOrderID, chargeId: productID, pay_name: message, pay_amount: price, pay_channel: payType + }, ip) return resResult(STATUS.SUCCESS, { orderInfo: sdkOrderInfo, productInfo, localOrderID }); } diff --git a/game-server/app/servers/role/handler/itemHandler.ts b/game-server/app/servers/role/handler/itemHandler.ts index da7c6f860..1206d5fbd 100644 --- a/game-server/app/servers/role/handler/itemHandler.ts +++ b/game-server/app/servers/role/handler/itemHandler.ts @@ -65,7 +65,7 @@ export class ItemHandler { let { id, count } = msg; const roleId = session.get('roleId'); const sid = session.get('sid'); - + const ip = session.get('ip'); if (count > 0) { let dicGoods = gameData.goods.get(id); @@ -79,13 +79,13 @@ export class ItemHandler { } let role = await RoleModel.findByRoleId(roleId, 'lv'); - let { isOver } = await getAp(roleId, role.lv); + let { isOver } = await getAp(roleId, ip, role.lv); if (isOver) return resResult(STATUS.AP_IS_FULL); let consumeResult = await handleCost(roleId, sid, [{ id: id, count: count }], ITEM_CHANGE_REASON.USE_MEAT); if (!consumeResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); - let apJson = await setAp(roleId, role.lv, dicGoods.value * count, sid); + let apJson = await setAp(roleId, ip, role.lv, dicGoods.value * count, sid, ITEM_CHANGE_REASON.USE_MEAT); return resResult(STATUS.SUCCESS, { apJson @@ -102,6 +102,7 @@ export class ItemHandler { const roleId: string = session.get('roleId'); const roleName: string = session.get('roleName'); const sid: string = session.get('sid'); + const ip: string = session.get('ip'); if (count <= 0) return resResult(STATUS.WRONG_PARMS); @@ -116,7 +117,7 @@ export class ItemHandler { } let role = await RoleModel.findByRoleId(roleId, 'lv'); - let { buyTimes = 0 } = await getAp(roleId, role.lv); + let { buyTimes = 0 } = await getAp(roleId, ip, role.lv); if (buyTimes + count > gameData.apMaxBuyTimes.max) return resResult(STATUS.AP_BUY_TIMES_LACK); let cost: RewardInter[] = []; @@ -129,7 +130,7 @@ export class ItemHandler { if (!consumeResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let goods = await addItems(roleId, roleName, sid, [{ id, count }], ITEM_CHANGE_REASON.BUY_MEAT); - let apJson = await setApBuyTimes(roleId, role.lv, sid, count); + let apJson = await setApBuyTimes(roleId, ip, role.lv, sid, count); return resResult(STATUS.SUCCESS, { goods, apJson @@ -179,10 +180,10 @@ export class ItemHandler { const roleId = session.get('roleId'); const sid = session.get('sid'); - + const ip = session.get('ip'); let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await setAp(roleId, role.lv, msg.ap, sid); + let apJson = await setAp(roleId, ip, role.lv, msg.ap, sid, ITEM_CHANGE_REASON.DEBUG); if (!apJson) return resResult(STATUS.BATTLE_ACTION_POINT_LACK) return resResult(STATUS.SUCCESS, { apJson }); } @@ -193,9 +194,10 @@ export class ItemHandler { return resResult(STATUS.TOKEN_ERR); } let roleId = session.get('roleId'); + let ip = session.get('ip'); let role = await RoleModel.findByRoleId(roleId, 'lv'); - let apJson = await getAp(roleId, role.lv); + let apJson = await getAp(roleId, ip, role.lv); return resResult(STATUS.SUCCESS, { apJson }); } @@ -205,9 +207,10 @@ export class ItemHandler { return resResult(STATUS.TOKEN_ERR); } let roleId = session.get('roleId'); + let ip = session.get('ip'); let role = await RoleModel.findByRoleId(roleId, 'lv'); await ActionPointModel.resetBuyTimes(roleId); - let apJson = await getAp(roleId, role.lv); + let apJson = await getAp(roleId, ip, role.lv); return resResult(STATUS.SUCCESS, { apJson }); } } \ No newline at end of file diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index f649643e9..ba04d2306 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -601,6 +601,7 @@ export class RoleHandler { public async test(msg: { magicWord: string }, session: BackendSession) { let roleId: string = session.get('roleId'); + let serverId: string = session.get('serverId'); let { magicWord } = msg; if (magicWord !== DEBUG_MAGIC_WORD) { @@ -609,7 +610,7 @@ export class RoleHandler { let role = await RoleModel.findByRoleId(roleId); let user = await UserModel.findUserByUid(role.userInfo.uid); - reportTAEvent(user.userCode, role.serverId, 'test', user.ip); + reportTAEvent(roleId, 'test', { serverId }, user.ip); return resResult(STATUS.SUCCESS); diff --git a/game-server/app/services/actionPointService.ts b/game-server/app/services/actionPointService.ts index 6965b8bcd..afe67309c 100644 --- a/game-server/app/services/actionPointService.ts +++ b/game-server/app/services/actionPointService.ts @@ -3,7 +3,7 @@ */ import { ActionPointModel, ActionPointType } from '../db/ActionPoint'; -import { TASK_TYPE, STATUS } from '../consts'; +import { TASK_TYPE, STATUS, TA_EVENT, ITEM_CHANGE_REASON } from '../consts'; import { checkActivityTask, checkTask } from './taskService'; import { getDicApByLv } from '../pubUtils/data'; import { pinus } from 'pinus'; @@ -11,24 +11,26 @@ import { resResult, shouldRefresh } from '../pubUtils/util'; import { RoleModel } from '../db/Role'; import { pick } from 'underscore'; import { AP } from '../pubUtils/dicParam'; +import { reportTAEvent } from './sdkService'; /** * 获取当前体力 * @param roleId 玩家id * @param lv 玩家等级 */ -export async function getAp(roleId: string, lv: number, fromGetAp = false) { +export async function getAp(roleId: string, ip: string, lv: number, fromGetAp = false) { let dataAp = await ActionPointModel.getAp(roleId); - return getApWithDataAp(lv, dataAp, fromGetAp); + return getApWithDataAp(roleId, ip, lv, dataAp, fromGetAp); } -function getApWithDataAp(lv: number, dataAp: ActionPointType, fromGetAp = false) { +function getApWithDataAp(roleId: string, ip: string, lv: number, dataAp: ActionPointType, fromGetAp = false) { const now = Date.now(); const dicAp = getDicApByLv(lv); const maxAp = dicAp.maxAp; // 最大体力值 const per = AP.PERAPRESTORETIME * 1000; // 恢复时间(ms) let { ap, refTime, buyRefTime = 0, buyTimes = 0 } = dataAp; + let oldAp = ap; if(shouldRefresh(new Date(buyRefTime), new Date())) { buyTimes = 0; @@ -52,6 +54,10 @@ function getApWithDataAp(lv: number, dataAp: ActionPointType, fromGetAp = false) result = { ap, maxAp, refTime, apRemainTime, apMaxRemainTime, isOver: false, buyTimes, buyRefTime }; } } + if(result.ap > oldAp) { + reportTAEvent(roleId, TA_EVENT.AP_GET, { change_count: oldAp - result.ap, change_after: result.ap, change_reason: ITEM_CHANGE_REASON.AP_RECOVERY }) + } + return fromGetAp?result: pick(result, ['ap', 'maxAp', 'apRemainTime', 'apMaxRemainTime', 'buyTimes']); } @@ -62,10 +68,10 @@ function getApWithDataAp(lv: number, dataAp: ActionPointType, fromGetAp = false) * @param changeAp 体力变化,正是加,负是减 * @param sid */ -export async function setAp(roleId: string, lv: number, changeAp: number, sid: string) { +export async function setAp(roleId: string, ip: string, lv: number, changeAp: number, sid: string, reason: ITEM_CHANGE_REASON) { const now = Date.now(); const dicAp = getDicApByLv(lv); - let ApResult = await getAp(roleId, lv, true); + let ApResult = await getAp(roleId, ip, lv, true); let { ap, maxAp, refTime, apRemainTime, apMaxRemainTime, isOver, buyTimes } = ApResult; // 更新ap ap += changeAp; if (ap >= maxAp) { // 溢出 @@ -85,8 +91,11 @@ export async function setAp(roleId: string, lv: number, changeAp: number, sid: s await checkTask(roleId, sid, TASK_TYPE.BATTLE_COST_AP, -1 * changeAp, true, {}); let { serverId } = await RoleModel.findByRoleId(roleId); await checkActivityTask(serverId, sid, roleId, TASK_TYPE.BATTLE_COST_AP, -1 * changeAp,); + reportTAEvent(roleId, TA_EVENT.AP_CONSUME, { change_count: -1 * changeAp, change_after: ap, change_reason: reason }, ip) + } else { + reportTAEvent(roleId, TA_EVENT.AP_GET, { change_count: changeAp, change_after: ap, change_reason: reason }, ip) } - let apJson = await getApWithDataAp(lv, dataAp); + let apJson = await getApWithDataAp(roleId, ip, lv, dataAp); if (changeAp != 0) { let uids = [{ uid: roleId, sid }]; @@ -96,10 +105,10 @@ export async function setAp(roleId: string, lv: number, changeAp: number, sid: s return apJson } -export async function setApBuyTimes(roleId: string, lv: number, sid: string, incTimes: number) { +export async function setApBuyTimes(roleId: string, ip: string, lv: number, sid: string, incTimes: number) { if(incTimes <= 0) return false; - let ApResult = await getAp(roleId, lv, true); + let ApResult = await getAp(roleId, ip, lv, true); let { ap, maxAp, refTime, apRemainTime, apMaxRemainTime, buyTimes, buyRefTime } = ApResult; // 更新ap if(shouldRefresh(new Date(buyRefTime), new Date())) { diff --git a/game-server/app/services/auctionService.ts b/game-server/app/services/auctionService.ts index 309ee72a8..2a61678b4 100644 --- a/game-server/app/services/auctionService.ts +++ b/game-server/app/services/auctionService.ts @@ -1,5 +1,5 @@ import { DividendModel } from './../db/Dividend'; -import { LOT_CODE_LEN, AUCTION_STAGE, AUCTION_TIME, DIVIDEND_CODE_LEN, DIVIDEND_STATUS, LOT_STATUS, MAIL_TYPE, CURRENCY_BY_TYPE, CURRENCY_TYPE, DIVIDENDMAXRATIO, DIVIDENDPOSITIONMAXRATIO, ROLE_RECEIVE_STATUS, AUCTION_BID_STATUS, DEBUG_MAGIC_WORD, AUCTION_SOURCE } from './../consts'; +import { LOT_CODE_LEN, AUCTION_STAGE, AUCTION_TIME, DIVIDEND_CODE_LEN, DIVIDEND_STATUS, LOT_STATUS, MAIL_TYPE, CURRENCY_BY_TYPE, CURRENCY_TYPE, DIVIDENDMAXRATIO, DIVIDENDPOSITIONMAXRATIO, ROLE_RECEIVE_STATUS, AUCTION_BID_STATUS, DEBUG_MAGIC_WORD, AUCTION_SOURCE, TA_EVENT, getAuctionSourceTypeName } from './../consts'; import { DividendRec, ItemReward } from "../domain/dbGeneral"; import { genCode, getRandSingleEelm } from '../pubUtils/util'; import { LotModel, LotParam, LotType } from '../db/Lot'; @@ -13,6 +13,7 @@ import { Member } from '../domain/battleField/guildActivity'; import * as dicParam from '../pubUtils/dicParam'; import { RewardInter } from '../pubUtils/interface'; import { getGuildAuctionChannelSid, getGuildChannelSid, getWorldAuctionChannelSid, pushCurrentTime } from './chatService'; +import { reportTAEvent } from './sdkService'; // ! 获取底价,假数据 export function getBasePrice(gid: number, count: number) { @@ -298,15 +299,19 @@ export async function startGuildAuction() { } export async function sendLotsRewardToMlail(lots: LotType[]) { - let lotByRole = new Map(); + let lotByRole = new Map(); for(let lot of lots) { if(!lotByRole.has(lot.curBuyer)) { lotByRole.set(lot.curBuyer, []); } - lotByRole.get(lot.curBuyer).push({ id: lot.gid, count: lot.count }); + lotByRole.get(lot.curBuyer).push({ id: lot.gid, count: lot.count, price: lot.curPrice }); } for(let [roleId, goods ] of lotByRole) { await sendMailByContent(MAIL_TYPE.AUTION_REWARD, roleId, { goods }); + for(let { id, count, price } of goods) { + let dicGoods = gameData.goods.get(id); + reportTAEvent(roleId, TA_EVENT.AUCTION_ITEM_GET, { item_name: dicGoods?.name, item_count: count, deel_price: price }); + } } } @@ -411,6 +416,7 @@ export async function sendUngotDividend(debug = false) { if (dividendRec.status === ROLE_RECEIVE_STATUS.YES) continue; const sum = rewards.get(dividendRec.roleId) || 0; rewards.set(dividendRec.roleId, sum + dividendRec.total); + reportTAEvent(dividendRec.roleId, TA_EVENT.AUCTION_DIVIDEND, { type: getAuctionSourceTypeName(dividend.sourceType), count: dividendRec.total }) } } diff --git a/game-server/app/services/normalBattleService.ts b/game-server/app/services/normalBattleService.ts index d66476124..384e52917 100644 --- a/game-server/app/services/normalBattleService.ts +++ b/game-server/app/services/normalBattleService.ts @@ -4,7 +4,7 @@ import Role, { RoleModel, RoleType } from '../db/Role' import { getLvByExp, getExpByLv, gameData, getDicApByLv } from '../pubUtils/data'; import { updateUserInfo } from './redisService'; // import { switchOnFunc } from './funcSwitchService'; -import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE } from '../consts'; +import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE, ITEM_CHANGE_REASON } from '../consts'; import { BackendSession, pinus } from 'pinus'; import { REDIS_KEY } from '../consts'; import { Rank } from './rankService'; @@ -20,6 +20,7 @@ import { uniq } from 'underscore'; export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kingExp: number = 0, session: BackendSession) { const serverId = session.get('serverId'); const sid = session.get('sid'); + const ip = session.get('ip'); let role = await RoleModel.findByRoleId(roleId); let { lv = 1, exp = 0 } = role; @@ -67,7 +68,7 @@ export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kin }); if(i != lv) { // 升级加体力 let dicAp = getDicApByLv(i); - await setAp(roleId, i, dicAp.restoreAp, sid); + await setAp(roleId, ip, i, dicAp.restoreAp, sid, ITEM_CHANGE_REASON.LV_UP); } } // 推送 diff --git a/game-server/app/services/orderService.ts b/game-server/app/services/orderService.ts index aca2e9408..16b322ee5 100644 --- a/game-server/app/services/orderService.ts +++ b/game-server/app/services/orderService.ts @@ -1,5 +1,5 @@ import { UserOrderModel, UserOrderModelType } from '../db/UserOrder'; -import { ACTIVITY_TYPE, ORDER_STATE, STATUS, TASK_TYPE } from '../consts'; +import { ACTIVITY_TYPE, ORDER_STATE, STATUS, TASK_TYPE, TA_EVENT, TA_USERSET_TYPE } from '../consts'; import { dicRMB } from '../pubUtils/dictionary/DicRMB'; import { makeYuanbaoShopReward } from './activity/yuanbaoService'; import { RoleModel } from '../db/Role'; @@ -26,6 +26,7 @@ import { checkActivityTask } from './taskService'; import { checkOrderALI } from './pay/aliPay'; import { getRoleOnlineInfo } from './redisService'; import { PayCallback37Data } from '../domain/sdk'; +import { reportTAEvent, reportTAUserSet } from './sdkService'; /** @@ -158,6 +159,7 @@ export async function settleOrder(order: UserOrderModelType, serverId: number, s let result = await makeOrder(order, sid); if (result.code !== 0) {//结算失败 console.log(`支付失败..... ${JSON.stringify(result)}`) + reportTAEvent(order.roleId, TA_EVENT.RECHARGE_FAIL, { pay_id: order.localOrderID, charge_id: order.productID, pay_name: order.message, pay_amount: order.price, pay_channel: order.payType }) return resResult(result); } //推送 @@ -175,6 +177,10 @@ export async function settleOrder(order: UserOrderModelType, serverId: number, s await addVipRechargeMoney(order.roleId, serverId, order.price); //成长任务 await checkActivityTask(serverId, sid, order.roleId, TASK_TYPE.ACTIVITY_RMB, order.price, { activityId: order.activityId }) + reportTAEvent(order.roleId, TA_EVENT.RECHARGE_SUCCESS, { pay_id: order.localOrderID, charge_id: order.productID, pay_name: order.message, pay_amount: order.price, pay_channel: order.payType }) + reportTAUserSet(TA_USERSET_TYPE.SET_ONCE, order.roleId, { first_pay_time: new Date() }); + reportTAUserSet(TA_USERSET_TYPE.SET, order.roleId, { last_pay_time: new Date() }); + reportTAUserSet(TA_USERSET_TYPE.ADD, order.roleId, { total_revenue: order.price }); return result.data; } diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index d84c0c678..e445a9db3 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -2,7 +2,7 @@ import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense'; import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp'; import { RoleType, CeAttrDataRole } from '../db/Role'; -import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE } from '../consts'; +import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE, TA_EVENT } from '../consts'; import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent"; import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util'; import { pvpEndParamInter, RewardInter } from '../pubUtils/interface'; @@ -25,6 +25,7 @@ import { PvpSeasonResultModel, PvpSeasonResultType } from '../db/PvpSeasonResult import { checkTask } from '../services/taskService'; import { sendMailByContent } from './mailService'; import { RoleRankInfo } from '../domain/rank'; +import { reportTAEvent } from './sdkService'; /** * 返回对手三人信息 @@ -330,7 +331,8 @@ export async function sendLastSeasonRewardIfNotSent(pvpDefense: PvpDefenseType) let seasonNum: number = pinus.app.get('pvpSeasonNum'); if(pvpDefense.seasonNum < seasonNum) { let oldPvpCongig = await PVPConfigModel.findPVPConfig(pvpDefense.seasonNum); - pvpDefense = await sendPVPRewardToUser(pvpDefense, pvpDefense.seasonNum, oldPvpCongig.seasonEndTime); + let result = await sendPVPRewardToUser(pvpDefense, pvpDefense.seasonNum, oldPvpCongig.seasonEndTime); + pvpDefense = result.pvpDefense; } return pvpDefense; } @@ -530,7 +532,8 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer, for(let { rank, roleId } of allRank) { console.log('******** pvpSeasonEnd: ', rank, roleId); let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); - await sendPVPRewardToUser(pvpDefense, pvpConfig.seasonNum, pvpConfig.seasonEndTime); + let { pvpSeasonResult } = await sendPVPRewardToUser(pvpDefense, pvpConfig.seasonNum, pvpConfig.seasonEndTime); + reportTAEvent(roleId, TA_EVENT.PVP_SEASON_END, { top_rank: rank, hero_score: pvpSeasonResult.heroScores }) } await PVPConfigModel.setReward(pvpConfig.seasonNum); } @@ -557,7 +560,10 @@ export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum: goods: heroGoods, notPush }); - return await resetPvpScores(pvpDefense, seasonNum + 1, pvpSeasonResult); + return { + pvpSeasonResult, + pvpDefense: await resetPvpScores(pvpDefense, seasonNum + 1, pvpSeasonResult) + } } async function resetPvpScores(pvpDefense: PvpDefenseType, seasonNum: number, pvpSeasonResult: PvpSeasonResultType) { diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index 89b0f6138..46d302bc1 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -1,4 +1,4 @@ -import { ITID, CONSUME_TYPE, ITEM_TABLE, REDIS_KEY, TASK_TYPE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON } from './../consts'; +import { ITID, CONSUME_TYPE, ITEM_TABLE, REDIS_KEY, TASK_TYPE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT } from './../consts'; import { EquipModel, EquipType } from './../db/Equip'; import { getRandSingleEelm, resResult } from '../pubUtils/util'; import { RoleModel, RoleType } from '../db/Role'; @@ -25,6 +25,7 @@ import { CreateHeroes } from '../pubUtils/roleUtil'; import { SkinUpdate } from '../db/Skin'; import { getInitHeroById } from './roleService'; import { getActivities } from './activity/activityService'; +import { reportTAEvent, reportTAUserSet } from './sdkService'; export class CheckMeterial { private roleId: string; @@ -150,11 +151,22 @@ export async function handleCost(roleId: string, sid: string, goods: Array 0 || coin.length > 0) { + let costGold = gold.reduce((pre, cur) => pre + cur.count, 0); let costCoin = coin.reduce((pre, cur) => pre + cur, 0); role = await RoleModel.decreaseGoldAndCoin(roleId, gold, costCoin); pinus.app.get('channelService').pushMessageByUids('onPlayerDataChange', resResult(STATUS.SUCCESS, { gold: role.gold, coin: role.coin, totalCost: role.totalCost }), uids); + + if(costGold > 0) { + reportTAEvent(roleId, TA_EVENT.ITEM_CONSUME, getGoldEventProperties(costGold, role.gold, reason)); + reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_gold: role.gold }); + } + if(costCoin > 0) { + reportTAEvent(roleId, TA_EVENT.ITEM_CONSUME, getCoinEventProperties(costCoin, role.coin, reason)); + reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_coin: role.coin }); + } + } return true; @@ -214,8 +226,9 @@ export async function addItems(roleId: string, roleName: string, sid: string, go // 3. 货币推送 if(gold.length > 0 || coin.length > 0 || ap > 0) { - let { ap: addAp } = await setAp(roleId, role.lv, ap, sid); + let { ap: addAp } = await setAp(roleId, null, role.lv, ap, sid, reason); let incCoin = coin.reduce((pre, cur) => pre + cur, 0); + let incGold = gold.reduce((pre, cur) => pre + cur.count, 0); role = await RoleModel.increaseGoldAndCoin(roleId, gold, incCoin); pinus.app.get('channelService').pushMessageByUids('onPlayerDataChange', resResult(STATUS.SUCCESS, { gold: role.gold, coin: role.coin, ap: addAp @@ -224,11 +237,15 @@ export async function addItems(roleId: string, roleName: string, sid: string, go gold.forEach(({ count }) => { showItems.push(getGoldObject(count)); }); + reportTAEvent(roleId, TA_EVENT.ITEM_GET, getGoldEventProperties(incGold, role.gold, reason)); + reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_gold: role.gold }); } if(coin.length > 0) { coin.forEach(count => { showItems.push(getCoinObject(count)); }); + reportTAEvent(roleId, TA_EVENT.ITEM_GET, getCoinEventProperties(incCoin, role.coin, reason)); + reportTAUserSet(TA_USERSET_TYPE.SET, roleId, { current_coin: role.coin }); } if(ap > 0) { showItems.push(getApObject(ap)); @@ -280,6 +297,18 @@ export async function addItems(roleId: string, roleName: string, sid: string, go return showItems; } +function getGoldEventProperties(inc: number, count: number, reason: ITEM_CHANGE_REASON) { + let id = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD); + let dicGoods = gameData.goods.get(id); + return { item_id: id, item_name: dicGoods.name, item_itid: dicGoods.itid, change_count: inc, change_after: count, change_reason: reason } +} + +function getCoinEventProperties(inc: number, count: number, reason: ITEM_CHANGE_REASON) { + let id = CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN); + let dicGoods = gameData.goods.get(id); + return { item_id: id, item_name: dicGoods.name, item_itid: dicGoods.itid, change_count: inc, change_after: count, change_reason: reason } +} + export function combineItems(items: { id?: number, count?: number }[]) { let result: { id: number, count: number }[] = []; for(let { id, count = 1 } of items) { diff --git a/game-server/app/services/sdkService.ts b/game-server/app/services/sdkService.ts index 3df70fb16..77fc27fb4 100644 --- a/game-server/app/services/sdkService.ts +++ b/game-server/app/services/sdkService.ts @@ -5,7 +5,7 @@ import { Chat37Params, CheckGuild37Params, CheckName37Params, GetWordParam } fro import { sendMailByContent, sendMailToGuildByContent } from './mailService'; import { getGoldObject } from '../pubUtils/itemUtils'; import { NAMEPLATE } from '../pubUtils/dicParam'; -import { CHANNEL_PREFIX, FILENAME, getSdkChannelId, MAIL_TYPE, REDIS_KEY, SDK_37_ADDR, SDK_37_CONST, SDK_TA_CONST, STATUS, THINKING_DATA_MODE, THINKING_DATA_MODE_LIST } from "../consts"; +import { CHANNEL_PREFIX, FILENAME, getSdkChannelId, MAIL_TYPE, REDIS_KEY, SDK_37_ADDR, SDK_37_CONST, SDK_TA_CONST, STATUS, TA_USERSET_TYPE, THINKING_DATA_MODE, THINKING_DATA_MODE_LIST } from "../consts"; import { UserModel } from "../db/User"; import { request37CheckChat, request37GetWord, request37Post } from "../pubUtils/httpUtil"; import { GuildModel } from "../db/Guild"; @@ -167,22 +167,21 @@ export function connectThinkingData(app: Application) { pm2: true }); } - ta.setDynamicSuperProperties(() => { - return { - env: app.get('env'), - server: app.getServerId(), - mode: THINKING_DATA_MODE - }; - }); + // ta.setDynamicSuperProperties(() => { + // return { + // env: app.get('env'), + // server: app.getServerId(), + // mode: THINKING_DATA_MODE + // }; + // }); app.set('ta', ta); } -export function reportTAEvent(userCode: string, serverId: number, eventName: string, ip: string) { - console.log(userCode, serverId) +export function reportTAEvent(roleId: string, eventName: string, properties: any, ip?: string) { let ta = pinus.app.get('ta'); let event = { // 账号 ID (可选) - accountId: `${userCode}`, + accountId: `${roleId}`, // 访客 ID (可选),账号 ID 和访客 ID 不可以都为空 distinctId: "", // 事件名称 (必填) @@ -192,9 +191,7 @@ export function reportTAEvent(userCode: string, serverId: number, eventName: st // 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地 ip: ip, // 事件属性 (可选) - properties: { - serverId - }, + properties, callback(err) { console.log('*****测试接入事件', err) } @@ -203,6 +200,37 @@ export function reportTAEvent(userCode: string, serverId: number, eventName: st ta.track(event); } +export function reportTAUserSet(type: TA_USERSET_TYPE, roleId: string, properties: any) { + let ta = pinus.app.get('ta'); + let userData = { + // 账号 ID (可选) + accountId: `${roleId}`, + // 访客 ID (可选),账号 ID 和访客 ID 不可以都为空 + distinctId: "", + // 用户属性 + properties, + // 出错时回调 (可选) + callback(e) { + if (e) { + console.log(e); + } + } + }; + if(type == TA_USERSET_TYPE.SET) { + ta.userSet(userData); + } else if (type == TA_USERSET_TYPE.SET_ONCE) { + ta.userSetOnce(userData); + } else if (type == TA_USERSET_TYPE.ADD) { + ta.userAdd(userData); + } +} + +export function taflush() { + let ta = pinus.app.get('ta'); + ta.flush(); + ta.close(); +} + export async function fetch37Words() { let params = new GetWordParam(); let result = await request37GetWord(SDK_37_ADDR.GET_WORD, params, SDK_37_CONST.CHAT_KEY); diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 6411ad95e..062d486b2 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -799,7 +799,6 @@ export enum ITEM_CHANGE_REASON { RECYCLE_SOUL = 47, // 将魂回收 TASK_REWARD = 48, // 领取任务奖励 TASK_STAGE_REWARD = 49, // 主线任务阶段性奖励 - COM_BATTLE_REWARD = 50, // 寻宝奖励 EVENT_REWARD = 51, // 奇遇领取奖励 EXPEDITION_POINT_REWARD = 52, // 过关斩将点数宝箱 TOWER_HUNG_UP_REWARD = 53, // 镇念塔挂机奖励 @@ -814,6 +813,7 @@ export enum ITEM_CHANGE_REASON { TASK_ACTIVE_REWARD = 62, // 每日任务活跃奖励 TASK_BOX_REWARD = 63, // 每日任务每周奖励 NORMAL_BATTLE_END = 64, // 主线关卡结算奖励 + COM_BATTLE_END = 50, // 寻宝 PVP_BATTLE_END = 65, // pvp关卡结算奖励 VESTIGE_BATTLE_END = 66, // 遗迹本结算奖励 EVENT_BATTLE_END = 67, // 事件本结算奖励 @@ -884,4 +884,50 @@ export enum ITEM_CHANGE_REASON { MONTHLY_TICKET_FIRST = 132, // 活动 月卡首次奖励 YUANBAO_SHOP_BUY = 133, // 活动 元宝商店购买 GET_HERO_UNLOCK_SKIN = 134, // 获得武将解锁皮肤 + AP_RECOVERY = 135, // 自然恢复体力 + LV_UP = 136, // 升级恢复 +} + +export enum TA_EVENT { + REGISTER = 'register', // 注册 + RECHARGE = 'recharge', // 发起充值 + RECHARGE_SUCCESS = 'recharge_success', // 充值成功 + RECHARGE_FAIL = 'recharge_fail', // 充值失败 + AP_GET = 'ap_get', // 获得体力 + AP_CONSUME = 'ap_consume', // 体力消耗 + PVP_SEASON_END = 'PVP_season_end', // pvp赛季结算 + GUILD_DISMISS = 'guild_dissolute', // 军团解散 + GUILD_QUIT = 'guild_quit', // 军团退出 + GUILD_MASTER_CHANGE = 'guild_master_change', // 军团长改变 + AUCTION_ITEM_GET = 'AH_item_get', // 拍卖行拍品获得 + AUCTION_DIVIDEND = 'AH_bonus_get', // 拍卖行分红领取 + ITEM_GET = 'item_get', // 道具获得 + ITEM_CONSUME = 'item_consume', // 道具消耗 +} + +// 军团解散way字段 +export enum GUILD_DISMISS_WAY { + GAME = "游戏内", + BACKEND = "后台", +} + +export enum GUILD_MASTER_CHANGE_WAY { + SET_AUTH = "转让", + IMPEACH = "弹劾", + BACKEND = "后台", +} + +export function getAuctionSourceTypeName(sourceType: number) { + switch(sourceType) { + case 1: return '军团演武'; + case 2: return '蛮夷入侵'; + case 3: return '诸侯混战'; + case 4: return '粮草先行'; + } +} + +export enum TA_USERSET_TYPE { + SET = 1, + SET_ONCE = 2, + ADD = 3 } \ No newline at end of file diff --git a/shared/db/User.ts b/shared/db/User.ts index 54bc87c94..8e273347d 100644 --- a/shared/db/User.ts +++ b/shared/db/User.ts @@ -193,10 +193,11 @@ export default class User extends BaseModel { let user: UserType = await UserModel.findUserByChannel(channelId); if (!user) { user = await UserModel.createUserWithChannel(channelId, channelType, channelInfo, token, platform, pkgName, serverType, deviceId, ip); + return { isCreate: true, user}; } else { user = await UserModel.updateTokenByChannel(channelId, token, deviceId, ip, channelInfo); + return { isCreate: false, user}; } - return user; } private static async encryptPass(password: string, salt?: string) { diff --git a/web-server/app.ts b/web-server/app.ts index 48c6d8a18..5ee4e7083 100644 --- a/web-server/app.ts +++ b/web-server/app.ts @@ -2,6 +2,8 @@ import 'reflect-metadata' import * as mongoose from 'mongoose'; import { Application, IBoot } from 'egg'; import { connectRedis } from './app/pubUtils/redis'; +import { SDK_TA_CONST, THINKING_DATA_MODE, THINKING_DATA_MODE_LIST } from '@consts'; +const ThinkingAnalytics = require("thinkingdata-node"); export default class FooBoot implements IBoot { private readonly app: Application; @@ -16,7 +18,7 @@ export default class FooBoot implements IBoot { // this is the last chance to modify the config. await this.connectDB(this.app); await this.connectRedis(this.app); - + this.connectThinkingData(this.app); } configDidLoad() { @@ -64,6 +66,28 @@ export default class FooBoot implements IBoot { app.context.redisClient = redisClient; } } + + public connectThinkingData(app: Application) { + let ta; + if(THINKING_DATA_MODE == THINKING_DATA_MODE_LIST.DEBUG) { + ta = ThinkingAnalytics.initWithDebugMode(SDK_TA_CONST.APPID, SDK_TA_CONST.SERVER_URL); + } else if (THINKING_DATA_MODE == THINKING_DATA_MODE_LIST.BATCH) { + ta = ThinkingAnalytics.initWithBatchMode(SDK_TA_CONST.APPID, SDK_TA_CONST.SERVER_URL); + } else if (THINKING_DATA_MODE == THINKING_DATA_MODE_LIST.LOGGING) { + ta = ThinkingAnalytics.initWithLoggingMode(SDK_TA_CONST.LOG_PATH, { + pm2: true + }); + } + // ta.setDynamicSuperProperties(() => { + // return { + // env: app.get('env'), + // server: app.getServerId(), + // mode: THINKING_DATA_MODE + // }; + // }); + app.context.ta = ta; +} + //#endregion } diff --git a/web-server/app/service/Auth.ts b/web-server/app/service/Auth.ts index 399e70ddf..2ce9fef4b 100644 --- a/web-server/app/service/Auth.ts +++ b/web-server/app/service/Auth.ts @@ -1,5 +1,5 @@ -import { COUNTER, DEFAULT_LV, ADULT_AGE, GUEST_MAX_TIME, TASK_TYPE } from '@consts'; +import { COUNTER, DEFAULT_LV, ADULT_AGE, GUEST_MAX_TIME, TASK_TYPE, TA_EVENT } from '@consts'; import { RoleModel } from '@db/Role'; import { UserModel, UserType } from '@db/User'; import { STATUS, GET_SMS_TYPE, ADDICTION_PREVENTION_CODE } from '@consts'; @@ -389,9 +389,9 @@ export default class Auth extends Service { * @returns */ public async channelLogin(params: { - channelType: string, pst: string, clientId: string, deviceId: string, platform: string, platformAppid: string, childGameId: number, pkgName: string, serverType: string, getuiCID: string + channelType: string, pst: string, clientId: string, deviceId: string, platform: string, platformAppid: string, childGameId: number, pkgName: string, serverType: string, getuiCID: string, distinctId: string }) { - const { channelType, pst, clientId, deviceId, platform, platformAppid, childGameId, pkgName, serverType, getuiCID } = params; + const { channelType, pst, clientId, deviceId, platform, platformAppid, childGameId, pkgName, serverType, getuiCID, distinctId } = params; const ctx = this.ctx; const ip = ctx.request.ip; @@ -405,9 +405,13 @@ export default class Auth extends Service { let channelId = getChannelId(channelType, requestResult.data.uid); const token = ctx.service.utils.generateStr(256); - let user = await UserModel.createOrUpdateChannelUser(channelId, channelType, { + let { isCreate, user} = await UserModel.createOrUpdateChannelUser(channelId, channelType, { ...requestResult.data, childGameId, platformAppid }, token, platform, pkgName, serverType, deviceId, ip); + if(isCreate) { + ctx.service.sdk.reportTAEventWithDistinctId(distinctId, TA_EVENT.REGISTER, null, ip); + } + if (getuiCID) {//更新个推cid await UserModel.updateGetuiCIDByChannel(channelId, getuiCID); } diff --git a/web-server/app/service/Sdk.ts b/web-server/app/service/Sdk.ts index fab9f1be6..f9e89be83 100644 --- a/web-server/app/service/Sdk.ts +++ b/web-server/app/service/Sdk.ts @@ -258,4 +258,28 @@ export default class Sdk extends Service { msg: '成功' } } + + public reportTAEventWithDistinctId(distinctId: string, eventName: string, properties: any, ip: string) { + let ta = this.app.context.ta; + let event = { + // 账号 ID (可选) + accountId: "", + // 访客 ID (可选),账号 ID 和访客 ID 不可以都为空 + distinctId: `${distinctId}`, + // 事件名称 (必填) + event: eventName, + // 事件时间 (可选) 如果不填,将以调用接口时的时间作为事件时间 + time: new Date(), + // 事件 IP (可选) 当传入 IP 地址时,后台可以解析所在地 + ip: ip, + // 事件属性 (可选) + properties, + callback(err) { + console.log('*****测试接入事件', err) + } + + }; + ta.track(event); + } + } diff --git a/web-server/package-lock.json b/web-server/package-lock.json index 0d2c415c1..42c573a43 100644 --- a/web-server/package-lock.json +++ b/web-server/package-lock.json @@ -3343,6 +3343,11 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" }, + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==" + }, "debounce": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", @@ -5685,8 +5690,7 @@ "flatted": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" }, "for-in": { "version": "1.0.2", @@ -5743,6 +5747,16 @@ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -5994,8 +6008,7 @@ "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "graceful-process": { "version": "1.2.0", @@ -6871,6 +6884,14 @@ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsonp-body": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/jsonp-body/-/jsonp-body-1.0.0.tgz", @@ -7160,6 +7181,18 @@ "chalk": "^2.0.1" } }, + "log4js": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-5.3.0.tgz", + "integrity": "sha512-PZHXaXJKMKEscvQxSnTjM4UosQalSDlNpMw63eCKW+/DiAFKIZPW1jGyIPXZDjiEYFusMfiI7zzvnxeGozUcAw==", + "requires": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "flatted": "^2.0.1", + "rfdc": "^1.1.4", + "streamroller": "^2.2.2" + } + }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -9894,6 +9927,11 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -10461,6 +10499,16 @@ "resolved": "https://registry.npmjs.org/stream-wormhole/-/stream-wormhole-1.1.0.tgz", "integrity": "sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==" }, + "streamroller": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "requires": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0" + } + }, "streamsearch": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", @@ -10822,6 +10870,14 @@ "thenify": ">= 3.1.0 < 4" } }, + "thinkingdata-node": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/thinkingdata-node/-/thinkingdata-node-1.2.2.tgz", + "integrity": "sha512-U5Nz2/OsFj3oFGboo/OmQcc1bcbibNJm2KVMPy7JpIVdYAH8U/VKzXCHfuVvbGSalLAdvMiBklL49r5uQnVqvw==", + "requires": { + "log4js": "^5.3.0" + } + }, "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", @@ -11157,6 +11213,11 @@ "object-keys": "^1.0.0" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/web-server/package.json b/web-server/package.json index 59afd8fcd..4b3f27655 100644 --- a/web-server/package.json +++ b/web-server/package.json @@ -45,6 +45,7 @@ "reflect-metadata": "^0.1.13", "request": "^2.88.2", "request-promise": "^4.2.6", + "thinkingdata-node": "^1.2.2", "underscore": "^1.13.1" }, "devDependencies": {