Compare commits
104 Commits
1f3adac088
...
a5da9e1522
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a5da9e1522 | ||
![]() |
d03d8a8399 | ||
![]() |
ca4616e4de | ||
![]() |
35ea01f3aa | ||
![]() |
65417fb8bd | ||
![]() |
6be02bee61 | ||
![]() |
8f3cb3e091 | ||
![]() |
fc426a283b | ||
![]() |
e496b3fefb | ||
![]() |
b9be0901fa | ||
![]() |
ecc116bfa1 | ||
![]() |
d71ecf13f9 | ||
![]() |
000de548c0 | ||
![]() |
d5d5d72bad | ||
![]() |
aa671a332b | ||
![]() |
b56a0c4591 | ||
![]() |
bf39147538 | ||
![]() |
e9a27e135e | ||
![]() |
f9deacd411 | ||
c2b1a6cb0b | |||
![]() |
7676fc3142 | ||
![]() |
2af3bf426b | ||
![]() |
89af066d12 | ||
![]() |
8dfe0b4ce8 | ||
![]() |
55fae245e9 | ||
![]() |
ad9e3cca46 | ||
![]() |
cedce860c5 | ||
![]() |
cc6aad7223 | ||
![]() |
566c3aeb7b | ||
![]() |
8a69a4fc1e | ||
![]() |
63877a2664 | ||
![]() |
1a88ed0784 | ||
![]() |
6a0a158fba | ||
![]() |
9d9c37714b | ||
![]() |
37f2472f5d | ||
![]() |
bf4f22d092 | ||
![]() |
4343d50f7c | ||
![]() |
5512bf3422 | ||
![]() |
847a1d03e9 | ||
![]() |
96729c719a | ||
![]() |
075c60a9f8 | ||
![]() |
1412da00ae | ||
![]() |
4e19dc21a1 | ||
![]() |
27d7a56d10 | ||
![]() |
053ab1ab23 | ||
![]() |
07fa117614 | ||
![]() |
d6e41758f9 | ||
![]() |
4fc0aa8576 | ||
![]() |
ee991be3b9 | ||
![]() |
cae860a087 | ||
![]() |
47b1fe4d22 | ||
![]() |
e098e41885 | ||
![]() |
57c5a8a5e7 | ||
![]() |
7b5c470f52 | ||
![]() |
b9a556ea30 | ||
![]() |
757f1ba4b8 | ||
![]() |
722e92a54b | ||
![]() |
2309ff4a9c | ||
![]() |
d6d8b39afe | ||
![]() |
47f16b583a | ||
![]() |
82d323d5c8 | ||
![]() |
dced990c89 | ||
![]() |
12300703b5 | ||
![]() |
2e84333776 | ||
![]() |
add9c7c562 | ||
![]() |
dbb012675a | ||
![]() |
7af728b68c | ||
![]() |
837e9b58c8 | ||
![]() |
5e476fa5c6 | ||
![]() |
3c034fb296 | ||
![]() |
53a2becac5 | ||
![]() |
7c83a8bbe8 | ||
![]() |
0df09e0f9e | ||
![]() |
bdb83f9da7 | ||
![]() |
b821afc6b0 | ||
![]() |
6089ad5dd2 | ||
![]() |
b578bb0db0 | ||
![]() |
d4bd776b48 | ||
![]() |
c3fa18c9b1 | ||
![]() |
34ace42872 | ||
![]() |
1cf4784d42 | ||
![]() |
4538c0dc16 | ||
![]() |
f9989cf002 | ||
![]() |
944ef41d5d | ||
![]() |
8503a65c1f | ||
![]() |
f50f6de933 | ||
![]() |
a6efa1019e | ||
![]() |
1f92fe7dc3 | ||
![]() |
3e5479760d | ||
![]() |
74c28c787b | ||
![]() |
08d0bed291 | ||
![]() |
78b246f32a | ||
![]() |
21994f214a | ||
![]() |
ae0a5c6882 | ||
![]() |
bfc9ff369c | ||
![]() |
72ff17ba0b | ||
![]() |
1e90b96c6c | ||
![]() |
9b6d29ddf2 | ||
![]() |
fd035faf86 | ||
![]() |
d5ef0b3187 | ||
![]() |
5486c2adf7 | ||
![]() |
1d6143794c | ||
![]() |
cba4f4563d | ||
![]() |
00804fa8c1 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
/node_modules
|
||||
/.idea
|
||||
/.vscode
|
||||
/dist
|
||||
/doc
|
||||
|
||||
|
50
.vscode/launch.json
vendored
Normal file
50
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "消息服",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"${workspaceRoot}/src/index.ts",
|
||||
"-serverType",
|
||||
"msg",
|
||||
"-logModel",
|
||||
"debug"
|
||||
],
|
||||
"runtimeArgs": [
|
||||
"--nolazy",
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
},
|
||||
{
|
||||
"name": "跨服",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"${workspaceRoot}/src/index.ts",
|
||||
"-serverType",
|
||||
"cross",
|
||||
"-logModel",
|
||||
"debug"
|
||||
],
|
||||
"runtimeArgs": [
|
||||
"--nolazy",
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
}
|
||||
]
|
||||
}
|
@ -11,6 +11,6 @@ WORKDIR /app
|
||||
|
||||
RUN npm config set registry http://registry.npm.taobao.org/ && npm install pm2@5.2.2 -g
|
||||
|
||||
RUN rm -rf node_modules/tsbuffer-validator/index.js && cp tsbufferIndex.js node_modules/tsbuffer-validator/index.js
|
||||
#RUN rm -rf node_modules/tsbuffer-validator/index.js && cp tsbufferIndex.js node_modules/tsbuffer-validator/index.js
|
||||
|
||||
CMD cd /app && sh zoeninfo.sh "Asia/Tokyo" && pm2-runtime start js_pm2.config.js -- ${Param}
|
||||
|
4159
package-lock.json
generated
4159
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@
|
||||
"axios": "^1.4.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"express": "^4.18.2",
|
||||
"heapdump": "^0.3.15",
|
||||
"inspector-api": "^1.4.8",
|
||||
"ioredis": "^5.3.2",
|
||||
"json5": "^2.2.3",
|
||||
"mathjs": "^11.4.0",
|
||||
@ -47,7 +47,7 @@
|
||||
"redis": "^4.3.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"sync-request": "^6.1.0",
|
||||
"tsrpc": "^3.4.12",
|
||||
"tsrpc": "^3.4.14",
|
||||
"xlsx": "^0.18.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { ApiCall } from "tsrpc";
|
||||
import { Reqheapdump, Resheapdump } from "../../monopoly/protocols/games/Ptlheapdump";
|
||||
var heapdump = require('heapdump');
|
||||
import Inspector from 'inspector-api'
|
||||
const inspector = new Inspector({ storage: { type: 'fs' } })
|
||||
|
||||
export default async function (call: ApiCall<Reqheapdump, Resheapdump>) {
|
||||
|
||||
@ -20,4 +22,24 @@ export default async function (call: ApiCall<Reqheapdump, Resheapdump>) {
|
||||
data:"gc..."
|
||||
})
|
||||
}
|
||||
|
||||
if(call.req.act == "cpustart"){
|
||||
await inspector.profiler.enable()
|
||||
await inspector.profiler.start()
|
||||
console.log('CPU profile has been start')
|
||||
call.succ({
|
||||
code:200,
|
||||
data:"profiler.start"
|
||||
})
|
||||
}
|
||||
|
||||
if(call.req.act == "cpustop"){
|
||||
await inspector.profiler.stop()
|
||||
await inspector.profiler.disable()
|
||||
console.log('CPU profile has been stop')
|
||||
call.succ({
|
||||
code:200,
|
||||
data:"profiler.cpustop"
|
||||
})
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ import { getGud } from "../../public/gud";
|
||||
|
||||
|
||||
export default async function (call: ApiCall<ReqSend, ResSend>) {
|
||||
let status_chat = await getGud(call.uid)['status_chat'];
|
||||
let status_chat = (await getGud(call.uid))['status_chat'];
|
||||
// 验证是否被禁言
|
||||
if(status_chat == 1) return call.error(lng.chat_4);
|
||||
let data = call.req;
|
||||
|
@ -26,7 +26,7 @@ export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
call.succ({
|
||||
sTime: sTime,
|
||||
recIndex: db?.recIndex || [],
|
||||
payNum: await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.rtime),
|
||||
payNum: (await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.rtime)) * 10,
|
||||
hdinfo: _hdinfo
|
||||
});
|
||||
}
|
@ -20,7 +20,7 @@ export default async function (call: ApiCall<ReqRec, ResRec>) {
|
||||
let db = await G.mongodb.cEvent(_dbType).findOne({ uid: call.uid, type: _dbType });
|
||||
if (db.recIndex.includes(call.req.index)) return call.error('', { code: -2 });
|
||||
|
||||
let payNum = await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.rtime);
|
||||
let payNum = (await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.rtime)) * 10;
|
||||
if (payNum < conf.total) return call.error('', { code: -3 });
|
||||
|
||||
await PlayerFun.sendPrize(call, conf.prize);
|
||||
|
@ -26,10 +26,10 @@ export async function playerCanReceive(call: ApiCall, callError : boolean = true
|
||||
}
|
||||
activityId = activityInfo.hdid;
|
||||
const hasReceivedKey = hasGotKeyPrefix + activityId;
|
||||
const hasReceivedStr = await G.iorediscross.get(hasReceivedKey);
|
||||
const hasReceivedStr = await G.crossioredis.get(hasReceivedKey);
|
||||
const hasReceived = hasReceivedStr? parseInt(hasReceivedStr) : 0;
|
||||
const remaining = activityInfo.data['totalmoney'] - hasReceived;
|
||||
const showOffResult = await G.iorediscross.lrange(showOffListKeyPrefix + activityId, 0, -1);
|
||||
const showOffResult = await G.crossioredis.lrange(showOffListKeyPrefix + activityId, 0, -1);
|
||||
const showOffList = showOffResult.map(result => JSON.parse(result));
|
||||
const zeroTime = PublicShared.getToDayZeroTime();
|
||||
const vipScore = await ActionLog.getDayLog(call.uid, 'pay');
|
||||
|
@ -71,12 +71,12 @@ export default async function (call: ApiCall<ReqReceive, ResReceive>) {
|
||||
}
|
||||
const activityData = canReceiveResult.activityInfo.data;
|
||||
// 更新 redis 领取记录之前先加锁, 防止多领
|
||||
const lockResult = await G.iorediscross.setnx(hasGotLockKey, 1);
|
||||
const lockResult = await G.crossioredis.setnx(hasGotLockKey, 1);
|
||||
if (lockResult) {
|
||||
await G.iorediscross.expire(hasGotLockKey, 1); // 设置 ttl 避免死锁
|
||||
await G.crossioredis.expire(hasGotLockKey, 1); // 设置 ttl 避免死锁
|
||||
const activityId = call.req.activityId;
|
||||
const hasReceivedKey = hasGotKeyPrefix + activityId;
|
||||
const hasReceivedStr = await G.iorediscross.get(hasReceivedKey);
|
||||
const hasReceivedStr = await G.crossioredis.get(hasReceivedKey);
|
||||
const hasReceived = hasReceivedStr? parseInt(hasReceivedStr) : 0;
|
||||
const remaining = activityData['totalmoney'] - hasReceived;
|
||||
if (remaining <= 0) {
|
||||
@ -86,8 +86,8 @@ export default async function (call: ApiCall<ReqReceive, ResReceive>) {
|
||||
} else {
|
||||
const { group, maxAmount } = randomWithWeight(activityData['groupConf']['base']['arr']);
|
||||
const gotAmount = calcDiamondGot(remaining, group, maxAmount);
|
||||
await G.iorediscross.incrby(hasReceivedKey, Math.abs(gotAmount)); // 添加已领取的额度
|
||||
await G.iorediscross.del(hasGotLockKey); // 移除锁
|
||||
await G.crossioredis.incrby(hasReceivedKey, Math.abs(gotAmount)); // 添加已领取的额度
|
||||
await G.crossioredis.del(hasGotLockKey); // 移除锁
|
||||
await PlayerFun.sendPrize(call, [{ 'a': 'attr', 't': 'rmbmoney', 'n': gotAmount }]);
|
||||
const showOff = gotAmount >= activityData['groupConf']['base']['loglimit'];
|
||||
call.succ({ // 领取核心逻辑完成, 请求可以返回了
|
||||
@ -108,8 +108,8 @@ export default async function (call: ApiCall<ReqReceive, ResReceive>) {
|
||||
name: call.conn.gud.name, gotAmount, serverID: call.conn.gud.sid
|
||||
});
|
||||
const showOffListKey = showOffListKeyPrefix + activityId;
|
||||
await G.iorediscross.lpush(showOffListKey, msg);
|
||||
await G.iorediscross.ltrim(showOffListKey, 0, 49); // 限制列表保存 50 条消息, 避免无限增长
|
||||
await G.crossioredis.lpush(showOffListKey, msg);
|
||||
await G.crossioredis.ltrim(showOffListKey, 0, 49); // 限制列表保存 50 条消息, 避免无限增长
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -4,13 +4,13 @@ import {HuoDongFun} from "../../../public/huodongfun";
|
||||
|
||||
/**
|
||||
* 消费竞赛
|
||||
* redis缓存120秒
|
||||
* redis缓存60秒
|
||||
* 返回活动日期内的
|
||||
* @param call
|
||||
*/
|
||||
export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
|
||||
let ioList = await G.ioredis.get(`rank:xiaofeijingsai`);
|
||||
let ioList = await G.crossioredis.get(`rank:xiaofeijingsai`);
|
||||
if (ioList) {
|
||||
let myData = await getMyData(call, JSON.parse(ioList))
|
||||
return call.succ({list: JSON.parse(ioList), myData})
|
||||
@ -21,28 +21,27 @@ export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
|
||||
let limit = _hd.data?.rank?.slice(-1)?.[0]?.rank?.slice(-1)?.[0] || call.req.limit || 100
|
||||
|
||||
let rmbuse = await G.mongodb.collection('rmbuse').aggregate([
|
||||
{$match: {isAdd: false, cTime: {$gte: _hd.stime, $lte: _hd.etime}}},
|
||||
{$group: {_id: "$uid", total: {$sum: "$change"}}},
|
||||
{$sort: {total: 1}},
|
||||
{$limit: limit}
|
||||
]).toArray()
|
||||
|
||||
let list: any = rmbuse.map(i => ({...i, total: R.negate(i.total)}))
|
||||
let rmbuse = await G.crossmongodb.collection('rmbuse').find({
|
||||
time: {
|
||||
$gte: _hd.stime,
|
||||
$lte: _hd.etime + 10
|
||||
}
|
||||
}).sort({change: 1}).limit(limit).toArray()
|
||||
|
||||
let list: any = rmbuse.map(i => ({...i, total: R.negate(i.change)}))
|
||||
|
||||
let rankList = sortRankList(_hd.data.rank, list)
|
||||
|
||||
let users = await G.mongodb.collection('user').find({uid: {$in: rankList.map(i => i._id).filter(i => i._id != 'system')}}).toArray()
|
||||
let users = await G.crossmongodb.collection('huodong_user').find({uid: {$in: rankList.map(i => i._id).filter(i => i._id != 'system')}}).toArray()
|
||||
|
||||
rankList = rankList.map(i => ({...i, player: users.find(v => v.uid == i._id) || {}}))
|
||||
rankList = rankList.map(i => ({...i, player: users.find(v => v.uid == i.uid) || {}}))
|
||||
|
||||
// 活动结束前半小时,缓存过期时间改为10秒
|
||||
let exTime = (G.time + 1800) > _hd.etime ? 10 : 120
|
||||
let exTime = (G.time + 1800) > _hd.etime ? 10 : 60
|
||||
|
||||
G.ioredis.setex(`rank:xiaofeijingsai`, exTime, JSON.stringify(rankList));
|
||||
G.crossioredis.setex(`rank:xiaofeijingsai`, exTime, JSON.stringify(rankList));
|
||||
|
||||
let myData = await getMyData(call, rankList, _hd)
|
||||
let myData = await getMyData(call, rankList)
|
||||
|
||||
call.succ({list: rankList, myData})
|
||||
}
|
||||
@ -58,7 +57,7 @@ export function sortRankList(rank, list) {
|
||||
rank.map(i => {
|
||||
for (let k = i.rank[0] - 1; k < i.rank[1]; k++) {
|
||||
if (list[k]?.total >= i.need[0].n) {
|
||||
rankList.push({...list[k - ccc], rank: k})
|
||||
rankList.push({...list[k - ccc], rank: k, _id: list[k - ccc].uid})
|
||||
} else {
|
||||
rankList.push({_id: 'system', total: i.need[0].n, rank: k, player: {}})
|
||||
ccc += 1
|
||||
@ -69,23 +68,18 @@ export function sortRankList(rank, list) {
|
||||
}
|
||||
|
||||
// 获取自己的信息
|
||||
async function getMyData(call, rankList, _hd?) {
|
||||
async function getMyData(call, rankList) {
|
||||
let myData = rankList.find(i => i._id == call.uid)
|
||||
if (myData) return myData
|
||||
|
||||
if (!_hd) {
|
||||
_hd = (await HuoDongFun.gethdList(call, 11))[0]
|
||||
}
|
||||
let myCut = (await G.mongodb.collection('rmbuse').aggregate([
|
||||
{$match: {uid: call.uid, isAdd: false, cTime: {$gte: _hd.stime, $lte: _hd.etime}}},
|
||||
{$group: {_id: "$uid", total: {$sum: "$change"}}}
|
||||
]).toArray())[0]
|
||||
let myCut: any = await G.crossmongodb.collection('rmbuse').findOne({uid: call.uid})
|
||||
|
||||
let myUser = await G.mongodb.collection('user').findOne({uid: call.uid})
|
||||
G.crossmongodb.collection('huodong_user').updateOne({uid: call.uid}, {$set: myUser}, {upsert: true})
|
||||
|
||||
if (!myCut) {
|
||||
myCut = {_id: myUser.uid, total: 0}
|
||||
}
|
||||
|
||||
return {player: myUser, ...myCut, total: R.negate(myCut.total), rank: -1}
|
||||
return {player: myUser, ...myCut, total: R.negate(myCut.total), rank: -1, _id: myUser.uid}
|
||||
}
|
35
src/api_s2c/event/yuandan/ApiDMRec.ts
Normal file
35
src/api_s2c/event/yuandan/ApiDMRec.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import {ApiCall} from "tsrpc";
|
||||
import {ReqDMRec, ResDMRec} from "../../../shared/protocols/event/yuandan/PtlDMRec";
|
||||
import {HuoDongFun} from "../../../public/huodongfun";
|
||||
import {PlayerFun} from "../../../public/player";
|
||||
import {HongDianChange} from "../../hongdian/fun";
|
||||
import {PublicShared} from "../../../shared/public/public";
|
||||
|
||||
export default async function (call: ApiCall<ReqDMRec, ResDMRec>) {
|
||||
// 查询活动是否存在
|
||||
let _hd = (await HuoDongFun.gethdList(call, 14))[0]
|
||||
if (!_hd) return call.errorCode(-1)
|
||||
|
||||
// 扣除免费次数或相应货币
|
||||
let data = await G.mongodb.cEvent(`yuandan${_hd.hdid}`).findOne({uid: call.uid, type: `yuandan${_hd.hdid}`})
|
||||
let rec = data?.gameNum
|
||||
|
||||
if (rec && rec >= _hd.data?.gamefree) {
|
||||
await PlayerFun.checkNeedIsMeet(call, _hd.data.gameneed);
|
||||
await PlayerFun.cutNeed(call, _hd.data.gameneed);
|
||||
}
|
||||
|
||||
let prize = []
|
||||
if (call.req.id) {
|
||||
prize = PublicShared.randomDropGroup('1', 1, {'1': _hd.data.game});
|
||||
await PlayerFun.sendPrize(call, prize);
|
||||
}
|
||||
|
||||
await G.mongodb.cEvent(`yuandan${_hd.hdid}`).updateOne({uid: call.uid, type: `yuandan${_hd.hdid}`}, {
|
||||
$inc: {[`gameNum`]: 1},
|
||||
}, {upsert: true})
|
||||
|
||||
call.succ({prize})
|
||||
|
||||
HongDianChange.sendChangeKey(call.uid, ['huodonghd']);
|
||||
}
|
36
src/api_s2c/event/yuandan/ApiDZRec.ts
Normal file
36
src/api_s2c/event/yuandan/ApiDZRec.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import {ApiCall} from "tsrpc";
|
||||
import {ReqDZRec, ResDZRec} from "../../../shared/protocols/event/yuandan/PtlDZRec";
|
||||
import {HuoDongFun} from "../../../public/huodongfun";
|
||||
import {PlayerFun} from "../../../public/player";
|
||||
import {HongDianChange} from "../../hongdian/fun";
|
||||
|
||||
export default async function (call: ApiCall<ReqDZRec, ResDZRec>) {
|
||||
// 查询活动是否有当前领奖的免费选项
|
||||
let _hd = (await HuoDongFun.gethdList(call, 14))[0]
|
||||
let gift = _hd?.data?.gift?.find(i => i.free && i.id == call.req.id)
|
||||
if (!gift) return call.errorCode(-1)
|
||||
|
||||
// 超出限购次数
|
||||
let data = await G.mongodb.cEvent(`yuandan${_hd.hdid}`).findOne({uid: call.uid, type: `yuandan${_hd.hdid}`})
|
||||
let rec = data?.gift?.[call.req.id]
|
||||
if (rec && rec >= gift.buynum) return call.errorCode(-2)
|
||||
|
||||
// 奖励不符合,严格判断
|
||||
let dlzList = R.flatten(gift.dlz.map(i => R.values(i)))
|
||||
call.req.dlz.map(i => {
|
||||
let item = dlzList.find(v => i.a == v.a && i.t == v.t && i.n == v.n)
|
||||
if (!item) call.errorCode(-4)
|
||||
})
|
||||
|
||||
let prize = [...gift.prize, ...call.req.dlz]
|
||||
|
||||
await PlayerFun.sendPrize(call, prize);
|
||||
|
||||
await G.mongodb.cEvent(`yuandan${_hd.hdid}`).updateOne({uid: call.uid, type: `yuandan${_hd.hdid}`}, {
|
||||
$set: {[`gift.${gift.id}`]: prize},
|
||||
}, {upsert: true})
|
||||
|
||||
call.succ({[gift.id]: prize})
|
||||
|
||||
HongDianChange.sendChangeKey(call.uid, ['huodonghd']);
|
||||
}
|
29
src/api_s2c/event/yuandan/ApiExchange.ts
Normal file
29
src/api_s2c/event/yuandan/ApiExchange.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import {ApiCall} from "tsrpc";
|
||||
import {ReqExchange, ResExchange} from "../../../shared/protocols/event/yuandan/PtlExchange";
|
||||
import {HuoDongFun} from "../../../public/huodongfun";
|
||||
import {PlayerFun} from "../../../public/player";
|
||||
import {HongDianChange} from "../../hongdian/fun";
|
||||
|
||||
export default async function (call: ApiCall<ReqExchange, ResExchange>) {
|
||||
// 礼包不存在
|
||||
let _hd = (await HuoDongFun.gethdList(call, 14))[0]
|
||||
let gift = _hd?.data?.duihuan?.find(i => i.id == call.req.id)
|
||||
if (!gift) return call.errorCode(-1)
|
||||
|
||||
// 超出限购次数
|
||||
let data = await G.mongodb.cEvent(`yuandan${_hd.hdid}`).findOne({uid: call.uid, type: `yuandan${_hd.hdid}`})
|
||||
let rec = data?.exchange?.[call.req.id]
|
||||
if (rec && rec >= gift?.buyNum) return call.errorCode(-2)
|
||||
|
||||
await PlayerFun.checkNeedIsMeet(call, gift.need);
|
||||
await PlayerFun.cutNeed(call, gift.need)
|
||||
await PlayerFun.sendPrize(call, gift.prize);
|
||||
|
||||
await G.mongodb.cEvent(`yuandan${_hd.hdid}`).updateOne({uid: call.uid, type: `yuandan${_hd.hdid}`}, {
|
||||
$inc: {[`exchange.${gift.id}`]: 1},
|
||||
}, {upsert: true})
|
||||
|
||||
call.succ({})
|
||||
|
||||
HongDianChange.sendChangeKey(call.uid, ['huodonghd']);
|
||||
}
|
20
src/api_s2c/event/yuandan/ApiOpen.ts
Normal file
20
src/api_s2c/event/yuandan/ApiOpen.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import {ApiCall} from "tsrpc";
|
||||
import {ReqOpen, ResOpen} from "../../../shared/protocols/event/yuandan/PtlOpen";
|
||||
import {HuoDongFun} from "../../../public/huodongfun";
|
||||
import {PayFun} from "../../../public/pay";
|
||||
import {Yuandanfun} from "./fun";
|
||||
import {PublicShared} from "../../../shared/public/public";
|
||||
|
||||
export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
let _hd = await Yuandanfun.getCon(call)
|
||||
if (!_hd) return call.errorCode(-1)
|
||||
|
||||
let payIds = _hd.data.gift.filter(i => i.payid).map(i => i.payid)
|
||||
|
||||
let data = await Yuandanfun.getData(call, _hd.hdid)
|
||||
|
||||
call.succ({
|
||||
data: {...data, isSameDay: PublicShared.chkSameDate(data.qiandaoTime, G.time)},
|
||||
payLog: await PayFun.getPayLogs(call.uid, payIds),
|
||||
})
|
||||
}
|
37
src/api_s2c/event/yuandan/ApiTaskRec.ts
Normal file
37
src/api_s2c/event/yuandan/ApiTaskRec.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { ApiCall } from "tsrpc";
|
||||
import { ReqTaskRec, ResTaskRec } from "../../../shared/protocols/event/yuandan/PtlTaskRec";
|
||||
import {Yuandanfun, Yuandanfun as Christmasfun} from "./fun";
|
||||
import {HongDianChange} from "../../hongdian/fun";
|
||||
import {PlayerFun} from "../../../public/player";
|
||||
|
||||
export default async function (call: ApiCall<ReqTaskRec, ResTaskRec>) {
|
||||
let _hd = await Christmasfun.getCon(call)
|
||||
let taskid = call.req.taskid;
|
||||
let _con = _hd.data.task[taskid];
|
||||
if (!_con) {
|
||||
// 任务id 不存在
|
||||
return call.error('', { code: -1, message: globalThis.lng.yangchengmubiao_2 })
|
||||
}
|
||||
let _mydata = await Yuandanfun.getData(call, _hd.hdid)
|
||||
if (_mydata.taskval[taskid] < _con.pval) {
|
||||
// 任务未完成
|
||||
return call.error('', { code: -2, message: globalThis.lng.yangchengmubiao_3 })
|
||||
}
|
||||
if (_mydata.taskfinish.includes(taskid)) {
|
||||
// 任务已领取
|
||||
return call.error('', { code: -3, message: globalThis.lng.yangchengmubiao_4 })
|
||||
}
|
||||
_mydata.taskfinish.push(taskid)
|
||||
let _setData = {}
|
||||
_setData["taskfinish"] = _mydata.taskfinish
|
||||
await Yuandanfun.setData(call.uid, _hd.hdid, { $set: _setData })
|
||||
let _prize = _con.prize
|
||||
|
||||
await PlayerFun.sendPrize(call, _prize);
|
||||
let changedata = { data: _mydata, prize: _prize}
|
||||
|
||||
call.succ(changedata);
|
||||
|
||||
// 推送红点
|
||||
HongDianChange.sendChangeKey(call.uid, ['huodonghd']);
|
||||
}
|
44
src/api_s2c/event/yuandan/ApiZLRec.ts
Normal file
44
src/api_s2c/event/yuandan/ApiZLRec.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import {ApiCall} from "tsrpc";
|
||||
import {ReqZLRec, ResZLRec} from "../../../shared/protocols/event/yuandan/PtlZLRec";
|
||||
import {HuoDongFun} from "../../../public/huodongfun";
|
||||
import {PlayerFun} from "../../../public/player";
|
||||
import {HongDianChange} from "../../hongdian/fun";
|
||||
import {Yuandanfun} from "./fun";
|
||||
import {PublicShared} from "../../../shared/public/public";
|
||||
|
||||
export default async function (call: ApiCall<ReqZLRec, ResZLRec>) {
|
||||
let _hd = await Yuandanfun.getCon(call)
|
||||
if (!_hd) return call.errorCode(-1)
|
||||
|
||||
// 查询是否存在当前传入id的礼品
|
||||
let gift = _hd?.data?.qiandao?.[call.req.id]
|
||||
if (!gift) return call.errorCode(-2)
|
||||
|
||||
// 奖励已领取
|
||||
let data = await G.mongodb.cEvent(`yuandan${_hd.hdid}`).findOne({uid: call.uid, type: `yuandan${_hd.hdid}`})
|
||||
let rec = data?.qiandao?.[call.req.id]
|
||||
if (rec) return call.errorCode(-3)
|
||||
|
||||
if (data && data.qiandaoTime && PublicShared.chkSameDate(data.qiandaoTime, G.time)) {
|
||||
return call.errorCode(-4)
|
||||
}
|
||||
|
||||
// 奖励不符合,严格判断
|
||||
let dlzList = R.flatten(gift.dlz.map(i => R.values(i)))
|
||||
call.req.dlz.map(i => {
|
||||
let item = dlzList.find(v => i.a == v.a && i.t == v.t && i.n == v.n)
|
||||
if (!item) call.errorCode(-5)
|
||||
})
|
||||
|
||||
let prize = [...gift.prize, ...call.req.dlz]
|
||||
|
||||
await PlayerFun.sendPrize(call, prize);
|
||||
|
||||
await G.mongodb.cEvent(`yuandan${_hd.hdid}`).updateOne({uid: call.uid, type: `yuandan${_hd.hdid}`}, {
|
||||
$set: {[`qiandao.${call.req.id}`]: prize, qiandaoTime: G.time},
|
||||
}, {upsert: true})
|
||||
|
||||
call.succ({[call.req.id]: prize})
|
||||
|
||||
HongDianChange.sendChangeKey(call.uid, ['huodonghd']);
|
||||
}
|
116
src/api_s2c/event/yuandan/fun.ts
Normal file
116
src/api_s2c/event/yuandan/fun.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import {ApiCall} from 'tsrpc';
|
||||
import {HuoDongFun} from '../../../public/huodongfun';
|
||||
import {christmas} from '../../../shared/protocols/event/christmas/PtlOpen';
|
||||
import {PublicShared} from '../../../shared/public/public';
|
||||
import {PayFun} from "../../../public/pay";
|
||||
|
||||
export class Yuandanfun {
|
||||
/**配置 */
|
||||
static async getCon(call: ApiCall) {
|
||||
return (await HuoDongFun.gethdList(call, 14))[0]
|
||||
}
|
||||
|
||||
/**获取我的数据 */
|
||||
static async getData(call: ApiCall, hdid: number) {
|
||||
|
||||
let data = await G.mongodb.cEvent(`yuandan${hdid}`).findOne({uid: call.uid, type: `yuandan${hdid}`})
|
||||
|
||||
if (!data || !data.refreshTime || !PublicShared.chkSameDate(data.refreshTime, G.time)) {
|
||||
// 刷新每日任务
|
||||
data = (await G.mongodb.cEvent(`yuandan${hdid}`).findOneAndUpdate({uid: call.uid, type: `yuandan${hdid}`}, {
|
||||
$set: {
|
||||
gameNum: 0,
|
||||
gift: {},
|
||||
exchange: {},
|
||||
taskfinish: [],
|
||||
taskval: await this.getTaskVal(call),
|
||||
qiandaoTime: data?.qiandaoTime || 1,
|
||||
refreshTime: G.time
|
||||
},
|
||||
}, {upsert: true, returnDocument: 'after'})).value
|
||||
this.refreshPayLog(call)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
static async refreshPayLog(call: ApiCall) {
|
||||
let _hd = await this.getCon(call)
|
||||
let payIds = _hd?.data?.gift?.filter(i => i.payId).map(i => i.payId)
|
||||
PayFun.delPayLog(call.uid, ...payIds.map(i => {
|
||||
return {payId: i, val: []}
|
||||
}))
|
||||
}
|
||||
|
||||
/**获取所有taskid 及对应的值 */
|
||||
static async getTaskVal(call: ApiCall) {
|
||||
let _initCon = await this.getCon(call)
|
||||
let _tasks = _initCon.data.task
|
||||
let _res = {}
|
||||
for (let index = 0; index < Object.keys(_tasks).length; index++) {
|
||||
const element = Object.keys(_tasks)[index];
|
||||
let _tmp = _tasks[element]
|
||||
_tmp["id"] = element
|
||||
// 每日登录直接完成
|
||||
if (_tmp.stype == "128") {
|
||||
_res[element] = 1
|
||||
} else {
|
||||
_res[element] = 0
|
||||
}
|
||||
}
|
||||
return _res
|
||||
}
|
||||
|
||||
/**设置数据 */
|
||||
static async setData(uid: string, hdid: number, set: {}) {
|
||||
await G.mongodb.cEvent(`yuandan${hdid}`).updateOne(
|
||||
{uid: uid, type: `yuandan${hdid}`},
|
||||
set
|
||||
)
|
||||
}
|
||||
|
||||
/**设置任务 */
|
||||
static async setTaskVal(call: ApiCall, stype: number, val: number, chkCall: Function, chkval: number = 0, isinc: number = 0, alchangeVal: Function, arg) {
|
||||
// 活动过期,不计数
|
||||
let _hd = await this.getCon(call)
|
||||
if (!_hd) return
|
||||
|
||||
await this.getData(call, _hd.hdid)
|
||||
|
||||
let _tasks = _hd.data.task
|
||||
|
||||
let _setData = {
|
||||
$inc: {},
|
||||
$set: {}
|
||||
}
|
||||
let isset = 0
|
||||
for (let indextask = 0; indextask < Object.keys(_tasks).length; indextask++) {
|
||||
const ele = Object.keys(_tasks)[indextask];
|
||||
// 具体任务配置
|
||||
let _taskCon = _tasks[ele]
|
||||
if (_taskCon.stype != stype) continue
|
||||
|
||||
// 不符合任务要求
|
||||
if (!(await chkCall(_taskCon["cond"], chkval, arg))) continue
|
||||
|
||||
// 根据需求改写
|
||||
val = await alchangeVal(call, _taskCon, val, arg)
|
||||
|
||||
isset = 1
|
||||
if (isinc == 1) { // 累加
|
||||
_setData["$inc"][`taskval.${ele}`] = val
|
||||
} else {
|
||||
_setData["$set"][`taskval.${ele}`] = val
|
||||
}
|
||||
}
|
||||
|
||||
// 设置任务
|
||||
if (isset == 1) {
|
||||
await G.mongodb.collection('event').updateOne({
|
||||
uid: call.uid,
|
||||
type: `yuandan${_hd.hdid}`
|
||||
}, _setData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -15,10 +15,21 @@ export default async function (call: ApiCall<ReqBuy, ResBuy>) {
|
||||
let conf = _hdinfo.data.gift[call.req.index];
|
||||
if (!conf || conf.payId) return call.errorCode(-1);
|
||||
|
||||
let selectPrize = conf.prize.map((v, i) => v[call.req.prizeIndex[i]]).filter(p => !!p);
|
||||
if (selectPrize.length < conf.prize.length) return call.errorCode(-2);
|
||||
let data = await G.mongodb.cEvent(_dbType).findOne({uid: call.uid, type: _dbType})
|
||||
let rec = data?.rec?.[call.req.index]
|
||||
if (rec) return call.errorCode(-3)
|
||||
|
||||
// 奖励不符合,严格判断
|
||||
let dlzList = R.flatten(conf.dlz.map(i => R.values(i)))
|
||||
call.req.dlz.map(i => {
|
||||
let item = dlzList.find(v => i.a == v.a && i.t == v.t && i.n == v.n)
|
||||
if (!item) call.errorCode(-4)
|
||||
})
|
||||
|
||||
let event = (await G.mongodb.cEvent(_dbType).findOne({ uid: call.uid, type: _dbType }));
|
||||
|
||||
let buyNum = R.values(event?.rec)?.length || 0
|
||||
|
||||
let buyNum = (await G.mongodb.cEvent(_dbType).findOne({ uid: call.uid, type: _dbType }))?.record?.[call.req.index] || 0;
|
||||
if (buyNum >= conf.buyNum) return call.errorCode(-3);
|
||||
|
||||
if (conf.need.length > 0) {
|
||||
@ -26,15 +37,15 @@ export default async function (call: ApiCall<ReqBuy, ResBuy>) {
|
||||
await PlayerFun.cutNeed(call, conf.need);
|
||||
}
|
||||
|
||||
await PlayerFun.sendPrize(call, selectPrize);
|
||||
let prize = [...conf.prize,...call.req.dlz]
|
||||
|
||||
G.mongodb.cEvent(_dbType).updateOne(
|
||||
{ uid: call.uid, type: _dbType },
|
||||
{ $inc: G.mongodb.createTreeObj({ key: `record.${call.req.index}`, val: 1 }) },
|
||||
{ upsert: true }
|
||||
);
|
||||
await PlayerFun.sendPrize(call, prize);
|
||||
|
||||
await G.mongodb.cEvent(_dbType).updateOne({uid: call.uid, type: _dbType}, {
|
||||
$set: {[`rec.${call.req.index}`]: prize},
|
||||
}, {upsert: true})
|
||||
|
||||
call.succ({
|
||||
prize: selectPrize
|
||||
prize: prize
|
||||
});
|
||||
}
|
@ -13,7 +13,7 @@ export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
let db = await G.mongodb.cEvent(_dbType).findOne({ uid: call.uid, type: _dbType });
|
||||
|
||||
call.succ({
|
||||
record: db?.record || {},
|
||||
rec: db?.rec || {},
|
||||
hdinfo: _hdinfo
|
||||
});
|
||||
}
|
@ -8,4 +8,11 @@ export default async function (call: ApiCall<ReqhdGetList, ReshdGetList>) {
|
||||
let _hdList = await HuoDongFun.gethdList(call)
|
||||
|
||||
call.succ({hdlist: _hdList});
|
||||
|
||||
// 消费竞赛是跨服活动,活动开启时,同步当前用户信息到跨服数据库
|
||||
G.huodong.xfjs = !!_hdList.find(i => i.htype == 11);
|
||||
if (G.huodong.xfjs) {
|
||||
let myUser = await G.mongodb.collection('user').findOne({uid: call.uid})
|
||||
G.crossmongodb.collection('huodong_user').updateOne({uid: call.uid}, {$set: myUser}, {upsert: true})
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ export default async function (call: ApiCall<ReqRepair, ResRepair>) {
|
||||
} else {
|
||||
cutItem = R.find(R.whereEq({a: "item", t: "21"}))(need)
|
||||
}
|
||||
let rankKfjs = new RankKfjs(6)
|
||||
let rankKfjs = RankKfjs(6)
|
||||
rankKfjs.setDataAndCheck({
|
||||
player: call.conn.gud,
|
||||
valArr: [await rankKfjs.getRankScore(call.uid) + cutItem.n]
|
||||
|
@ -269,7 +269,7 @@ export class HongDianFun {
|
||||
for (let i = 1; i <= 7; i++) {
|
||||
let prize = kfjsFun.getStatus(i)
|
||||
if (PublicShared.getOpenServerDay() <= prize.conf.showDay[1]) continue
|
||||
let rankKfjs = new RankKfjs(i)
|
||||
let rankKfjs = RankKfjs(i)
|
||||
let myRank = await rankKfjs.getRankSortByOne(call.uid)
|
||||
if (prize.type > 0 && !data?.record?.[i] && myRank >= 0) {
|
||||
canGet[i] = true
|
||||
@ -348,6 +348,10 @@ export class HuoDongHongDianFun {
|
||||
// 检测 htype 10 破冰活动红点
|
||||
ishd = await this.pobinglibao(call, element)
|
||||
}
|
||||
if (element.htype == 14) {
|
||||
// 检测 htype 10 元旦活动红点
|
||||
ishd = await this.yuandan(call, element)
|
||||
}
|
||||
|
||||
// 此活动有红点
|
||||
if (ishd.show) {
|
||||
@ -362,7 +366,7 @@ export class HuoDongHongDianFun {
|
||||
|
||||
/**破冰礼包红点 */
|
||||
static async pobinglibao(call: ApiCall, _hd: ReqAddHuoDong): Promise<hongdianVal> {
|
||||
let gift = _hd?.data?.gift?.find(i => i.id == call.req.id)
|
||||
let gift = _hd?.data?.gift?.find(i => i.free == true && !i.payId)
|
||||
if (!gift) return {show: false}
|
||||
|
||||
let payLog = await PayFun.getPayLog(call.uid, gift.payId)
|
||||
@ -376,6 +380,30 @@ export class HuoDongHongDianFun {
|
||||
return {show: true}
|
||||
}
|
||||
|
||||
/**元旦活动红点 */
|
||||
static async yuandan(call: ApiCall, _hd: ReqAddHuoDong): Promise<hongdianVal> {
|
||||
|
||||
let gift = _hd?.data?.gift?.find(i => i.free && !i.payId)
|
||||
|
||||
// 取奖励列表,判断是否有可领取奖励
|
||||
let data = await G.mongodb.cEvent(`yuandan${_hd.hdid}`).findOne({uid: call.uid, type: `yuandan${_hd.hdid}`})
|
||||
|
||||
if (gift && !data?.gift?.[gift.id]) return {show: true}
|
||||
|
||||
if (data?.gameNum < _hd.data.gamefree) return {show: true}
|
||||
|
||||
if (!PublicShared.chkSameDate(data?.qiandaoTime || 1, G.time)) {
|
||||
return {show: true}
|
||||
}
|
||||
|
||||
for (const i in data.taskval) {
|
||||
if (data?.taskval[i] >= _hd?.data?.task?.[i]?.pval && !data?.taskfinish.find(v => v == i)) {
|
||||
return {show: true}
|
||||
}
|
||||
}
|
||||
return {show: false}
|
||||
}
|
||||
|
||||
/**开服狂欢红点 */
|
||||
static async kfkhHongDian(call: ApiCall) {
|
||||
let _res: hongdianVal = {
|
||||
@ -829,7 +857,7 @@ export class HuoDongHongDianFun {
|
||||
static async zixuanlibaoHongDian(call: ApiCall, hdCon: ReqAddHuoDong): Promise<hongdianVal> {
|
||||
let _dbType: `zixuanlibao${number}` = `zixuanlibao${hdCon.hdid}`
|
||||
let db = await G.mongodb.cEvent(_dbType).findOne({uid: call.uid, type: _dbType});
|
||||
if (!db?.record?.[0]) {
|
||||
if (!db?.rec) {
|
||||
return {show: true}
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ export default async function (call: ApiCall<ReqLottery, ResLottery>) {
|
||||
changeData: changeData
|
||||
});
|
||||
|
||||
let rankKfjs = new RankKfjs(1)
|
||||
let rankKfjs = RankKfjs(1)
|
||||
rankKfjs.setDataAndCheck({
|
||||
player: call.conn.gud,
|
||||
valArr: [await rankKfjs.getRankScore(call.uid) + call.req.type]
|
||||
|
@ -27,4 +27,7 @@ export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
...data,
|
||||
...enemy
|
||||
});
|
||||
|
||||
JJCFun.checkUpdatePlayer()
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ export default async function (call: ApiCall<ReqOpen, ResOpen>) {
|
||||
|
||||
const {min, max} = Rank.pageToMin(call.req.page, call.req.offset)
|
||||
|
||||
let rankKfjs = new RankKfjs(status.type)
|
||||
let rankKfjs = RankKfjs(status.type)
|
||||
|
||||
let endTime = PublicShared.getToDayZeroTime(PublicShared.getToDayZeroTime(G.openTime) + status.conf.showDay[1] * 86400)
|
||||
|
||||
|
@ -15,7 +15,7 @@ export default async function (call: ApiCall<ReqReceive, ResReceive>) {
|
||||
if (data?.record?.[call.req.type]) return call.errorCode(-2)
|
||||
|
||||
// 查询自己排名,发奖
|
||||
let rankKfjs = new RankKfjs(call.req.type)
|
||||
let rankKfjs = RankKfjs(call.req.type)
|
||||
let myRank = await rankKfjs.getRankSortByOne(call.uid)
|
||||
|
||||
let conf = R.find(i => i.rank[0] <= myRank + 1 && i.rank[1] >= myRank + 1)(prize)
|
||||
|
@ -43,7 +43,7 @@ export default async function (call: ApiCall<ReqFight, ResFight>) {
|
||||
valArr: [changeInfo.lv]
|
||||
});
|
||||
|
||||
let rankKfjs = new RankKfjs(5)
|
||||
let rankKfjs = RankKfjs(5)
|
||||
rankKfjs.setDataAndCheck({
|
||||
player: call.conn.gud,
|
||||
valArr: [changeInfo.lv-1]
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { ApiCall } from "tsrpc";
|
||||
import { ReqGetList, ResGetList } from "../../shared/protocols/peijian/PtlGetList";
|
||||
import {ApiCall} from "tsrpc";
|
||||
import {ReqGetList, ResGetList} from "../../shared/protocols/peijian/PtlGetList";
|
||||
|
||||
export default async function (call: ApiCall<ReqGetList, ResGetList>) {
|
||||
let _maxLv = 0
|
||||
let color = {}
|
||||
let peijianCon = G.gc.peijian
|
||||
|
||||
let dbList = (await G.mongodb.collection('peijian').find({ uid: call.uid }).toArray()).map(p => {
|
||||
let dbList = (await G.mongodb.collection('peijian').find({uid: call.uid}).toArray()).map(p => {
|
||||
let np = G.mongodb.conversionIdObj(p);
|
||||
let { uid, ...ops } = np;
|
||||
let {uid, ...ops} = np;
|
||||
|
||||
if (np.lv > _maxLv) _maxLv = np.lv
|
||||
if (!color[peijianCon[np.peijianId].colour]) color[peijianCon[np.peijianId].colour] = 0
|
||||
@ -16,15 +16,25 @@ export default async function (call: ApiCall<ReqGetList, ResGetList>) {
|
||||
return ops;
|
||||
});
|
||||
|
||||
// 修复配件穿戴在不存在的英雄身上
|
||||
let heroIds = R.values(call.conn.gud.heroPos)
|
||||
let fixIds = dbList.filter(i => i.wearId && !heroIds.includes(i.wearId)).map(i => G.mongodb.conversionId(i._id))
|
||||
if (fixIds.length) {
|
||||
await G.mongodb.collection('peijian').updateMany({_id: {$in: fixIds}}, {$set: {wearId: ''}})
|
||||
}
|
||||
|
||||
// 记录玩家最大等级,颜色相关数据 注册任务用
|
||||
await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({ uid: call.conn.uid, type: 'usertasklog' },
|
||||
{ $set: { maxpeijianlv: _maxLv, peijiancolor: color } }, { upsert: true })
|
||||
await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({uid: call.conn.uid, type: 'usertasklog'},
|
||||
{$set: {maxpeijianlv: _maxLv, peijiancolor: color}}, {upsert: true})
|
||||
|
||||
let list = Object.fromEntries(dbList.map(p => [G.formatRedisKey(p._id), p]));
|
||||
G.redis.set('peijian', call.uid, list);
|
||||
|
||||
let recLshd = await G.mongodb.collection('playerInfo', 'lshd_peijian').findOne({ uid: call.conn.uid, type: 'lshd_peijian' });
|
||||
let { uid, _id, type, ...peijians } = (recLshd || {});
|
||||
let recLshd = await G.mongodb.collection('playerInfo', 'lshd_peijian').findOne({
|
||||
uid: call.conn.uid,
|
||||
type: 'lshd_peijian'
|
||||
});
|
||||
let {uid, _id, type, ...peijians} = (recLshd || {});
|
||||
|
||||
call.conn.lshd.peijian = peijians || {};
|
||||
call.succ({
|
||||
|
@ -38,7 +38,7 @@ export default async function (call: ApiCall<ReqFight, ResFight>) {
|
||||
|
||||
// (await call.conn.gonghui)?.addExp(20, call.uid);
|
||||
|
||||
let rankKfjs = new RankKfjs(4)
|
||||
let rankKfjs = RankKfjs(4)
|
||||
rankKfjs.setDataAndCheck({
|
||||
player: call.conn.gud,
|
||||
valArr: [call.conn.gud.mapId]
|
||||
|
@ -20,4 +20,10 @@ export default async function (call: ApiCall<ReqPing, ResPing>) {
|
||||
onlineTime: onlineTime,
|
||||
openDay: PublicShared.getOpenServerDay()
|
||||
});
|
||||
|
||||
let gud = call.conn?.gud
|
||||
G.server.sendMsgByUid(call.uid, 'msg_s2c/PlayerChange', {
|
||||
jinbi: gud?.jinbi,
|
||||
rmbmoney: gud?.rmbmoney
|
||||
});
|
||||
}
|
@ -38,9 +38,7 @@ export default async function (call: ApiCall<ReqAllGet, ResAllGet>) {
|
||||
}
|
||||
// XstaskFun.delTask(call.uid, task._id);
|
||||
XstaskFun.changeInfo(call.uid, change);
|
||||
await PlayerFun.sendPrize(call, taskConf.prize);
|
||||
HongDianChange.sendChangeKey(call.uid, ['xstaskhd', 'huodonghd']);
|
||||
|
||||
if (!tequan) {
|
||||
prizeArr.push(...taskConf.prize)
|
||||
} else {
|
||||
@ -48,8 +46,9 @@ export default async function (call: ApiCall<ReqAllGet, ResAllGet>) {
|
||||
prizeArr.push(...taskConf.prize)
|
||||
}
|
||||
}
|
||||
prizeArr.push(...taskConf.prize)
|
||||
// prizeArr.push(...taskConf.prize)
|
||||
}
|
||||
if (prizeArr.length > 0) await PlayerFun.sendPrize(call, prizeArr);
|
||||
call.succ({
|
||||
taskList: await XstaskFun.getAllTask(call.uid),
|
||||
prize: PublicShared.mergePrize(prizeArr)
|
||||
|
@ -44,10 +44,10 @@ export function clusterPublish(key: string, data: any) {
|
||||
* 在集群的N个进程中,只运行一次,在业务逻辑中也可使用
|
||||
*/
|
||||
export function clusterRunOnce(fun) {
|
||||
console.log(`${process.pid}环境变量pm_id===>${process.env.pm_id}`);
|
||||
// console.log(`${process.pid}环境变量pm_id===>${process.env.pm_id}`);
|
||||
if (process.env.pm_id == null || process.env.pm_id === '0') {
|
||||
//非pm2启动的,或是pm2下启动的第一个进程
|
||||
console.log("run clusterRunOnce1 ===>", process.pid)
|
||||
// console.log("run clusterRunOnce1 ===>", process.pid)
|
||||
fun();
|
||||
return;
|
||||
}
|
||||
@ -56,7 +56,7 @@ export function clusterRunOnce(fun) {
|
||||
|
||||
if (firstPid == process.pid) {
|
||||
//pm2的其中一个进程
|
||||
console.log("run clusterRunOnce2 ===>", process.pid)
|
||||
// console.log("run clusterRunOnce2 ===>", process.pid)
|
||||
fun();
|
||||
return;
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ BaseConnection.prototype.refreshPower = async function (this: BaseConnection<Ser
|
||||
G.mongodb.collection('user').updateOne({ uid: this.uid }, { $set: dbUpdate });
|
||||
this.sendMsg('msg_s2c/PlayerChange', dbUpdate);
|
||||
|
||||
let rankKfjs = new RankKfjs(7)
|
||||
let rankKfjs = RankKfjs(7)
|
||||
rankKfjs.setDataAndCheck({
|
||||
player: this.gud,
|
||||
valArr: [power]
|
||||
|
82
src/fix_patch/patch_hdinfo_20231228.ts
Normal file
82
src/fix_patch/patch_hdinfo_20231228.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import {patchFun, patchInit} from "../patch";
|
||||
|
||||
class Path {
|
||||
@patchFun
|
||||
async fun1(a: any) {
|
||||
//这里执行脚本的内容,加了patchFun的函数,不允许重复执行
|
||||
console.log("这是第1个脚本里内容");
|
||||
|
||||
let _hd = G.gc.huodong.find(i => i.hdid == 4000)
|
||||
|
||||
if (!_hd) {
|
||||
console.log('htype4没查到活动')
|
||||
return
|
||||
}
|
||||
|
||||
await G.mongodb.collection('hdinfo').findOneAndUpdate({hdid: 4000}, {$set: {data: _hd.data}})
|
||||
|
||||
console.log('这是第1个脚本执行完成')
|
||||
|
||||
return _hd
|
||||
}
|
||||
|
||||
@patchFun
|
||||
async fun2(a: any) {
|
||||
//这里执行脚本的内容,加了patchFun的函数,不允许重复执行
|
||||
console.log("这是第2个脚本里内容");
|
||||
|
||||
let _hd = G.gc.huodong.find(i => i.htype == 2)
|
||||
|
||||
if (!_hd) {
|
||||
console.log('htype2没查到活动')
|
||||
return
|
||||
}
|
||||
|
||||
await G.mongodb.collection('hdinfo').updateMany({htype: 2}, {$set: {data: _hd.data}})
|
||||
|
||||
console.log('这是第2个脚本执行完成')
|
||||
|
||||
return _hd
|
||||
}
|
||||
|
||||
@patchFun
|
||||
async fun3(a: any) {
|
||||
//这里执行脚本的内容,加了patchFun的函数,不允许重复执行
|
||||
console.log("这是第3个脚本里内容");
|
||||
let _hd = G.gc.huodong.filter(i => i.htype == 5)
|
||||
|
||||
if (!_hd.length) {
|
||||
console.log('htype5没查到活动')
|
||||
return
|
||||
}
|
||||
|
||||
_hd.map(i => {
|
||||
// @ts-ignore
|
||||
G.mongodb.collection('hdinfo').updateOne({hdid: i.hdid}, {$set: {...i}}, {upsert: true})
|
||||
})
|
||||
|
||||
console.log('这是第3个脚本执行完成')
|
||||
|
||||
return _hd
|
||||
}
|
||||
|
||||
|
||||
async run() {
|
||||
await this.fun1(1);
|
||||
await this.fun2(2);
|
||||
await this.fun3(3);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await patchInit()
|
||||
let patch = new Path();
|
||||
await patch.run();
|
||||
console.log("逻辑执行完成,等待退出");
|
||||
setTimeout(function() {
|
||||
console.log('结束程序');
|
||||
process.exit();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
main();
|
45
src/fix_patch/patch_rank_delData.ts
Normal file
45
src/fix_patch/patch_rank_delData.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { patchFun, patchInit } from "../patch";
|
||||
|
||||
class Path{
|
||||
@patchFun
|
||||
async fun1(a:any) {
|
||||
//这里执行脚本的内容,加了patchFun的函数,不允许重复执行
|
||||
console.log("这是第1个脚本里内容");
|
||||
G.ioredis.del(`rank:kfjs1:data`);
|
||||
G.ioredis.del(`rank:kfjs2:data`);
|
||||
G.ioredis.del(`rank:kfjs3:data`);
|
||||
G.ioredis.del(`rank:kfjs4:data`);
|
||||
G.ioredis.del(`rank:kfjs5:data`);
|
||||
G.ioredis.del(`rank:kfjs6:data`);
|
||||
G.ioredis.del(`rank:kfjs7:data`);
|
||||
G.ioredis.del(`rank:slzd1:data`);
|
||||
G.ioredis.del(`rank:slzd2:data`);
|
||||
G.ioredis.del(`rank:slzd3:data`);
|
||||
G.ioredis.del(`rank:slzd4:data`);
|
||||
G.ioredis.del(`rank:slzd5:data`);
|
||||
G.ioredis.del(`rank:slzd6:data`);
|
||||
G.ioredis.del(`rank:qjzzd:data`);
|
||||
G.ioredis.del(`rank:tanxian:data`);
|
||||
G.ioredis.del(`rank:tujian:data`);
|
||||
G.ioredis.del(`rank:zccg:data`);
|
||||
G.ioredis.del(`rank:zhanli:data`);
|
||||
console.log("这是第1个脚本执行完成");
|
||||
return 12
|
||||
}
|
||||
|
||||
async run(){
|
||||
await this.fun1(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function main(){
|
||||
await patchInit()
|
||||
let patch = new Path();
|
||||
await patch.run();
|
||||
console.log("逻辑执行完成,等待退出");
|
||||
setTimeout(function() {
|
||||
console.log('结束程序');
|
||||
process.exit();
|
||||
}, 3000);
|
||||
}
|
||||
main();
|
@ -25,9 +25,10 @@ async function main(){
|
||||
await patchInit()
|
||||
let patch = new Path();
|
||||
await patch.run();
|
||||
setInterval(() => {
|
||||
console.log(new Date().format("MM-dd hh:mm:ss"));
|
||||
}, 1000);
|
||||
console.log("逻辑执行完成,等待退出");
|
||||
setTimeout(function() {
|
||||
console.log('结束程序');
|
||||
process.exit();
|
||||
}, 3000);
|
||||
}
|
||||
main();
|
||||
|
@ -1,22 +1,22 @@
|
||||
import EventEmitter from 'events';
|
||||
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { parse } from 'json5';
|
||||
import {existsSync, readdirSync, readFileSync, writeFileSync} from 'fs';
|
||||
import {parse} from 'json5';
|
||||
import * as mathjs from 'mathjs';
|
||||
import { join, resolve } from 'path';
|
||||
import { argv, env } from 'process';
|
||||
import { HttpServer, WsClient, WsServer } from 'tsrpc';
|
||||
import { ServiceType as ServiceTypeCross } from './cross/protocols/serviceProto';
|
||||
import { MyEvent } from './event';
|
||||
import { addListener, gEventType } from './globalListener';
|
||||
import {join, resolve} from 'path';
|
||||
import {argv, env} from 'process';
|
||||
import {HttpServer, WsClient, WsServer} from 'tsrpc';
|
||||
import {ServiceType as ServiceTypeCross} from './cross/protocols/serviceProto';
|
||||
import {MyEvent} from './event';
|
||||
import {addListener, gEventType} from './globalListener';
|
||||
import localConfig from './localConfig';
|
||||
import { ServiceType as ServiceTypeHttp } from './monopoly/protocols/serviceProto';
|
||||
import { SchedulerManage } from './public/scheduler/scheduler';
|
||||
import { _mongodb } from './setMongodb';
|
||||
import { redisJsonFun } from './setRedis';
|
||||
import { ResGetList } from './shared/protocols/pay/PtlGetList';
|
||||
import { ServiceType as ServiceTypeWs } from './shared/protocols/serviceProto';
|
||||
import { PublicShared } from './shared/public/public';
|
||||
import { clusterRunOnce } from './clusterUtils';
|
||||
import {ServiceType as ServiceTypeHttp} from './monopoly/protocols/serviceProto';
|
||||
import {SchedulerManage} from './public/scheduler/scheduler';
|
||||
import {_mongodb} from './setMongodb';
|
||||
import {redisJsonFun} from './setRedis';
|
||||
import {ResGetList} from './shared/protocols/pay/PtlGetList';
|
||||
import {ServiceType as ServiceTypeWs} from './shared/protocols/serviceProto';
|
||||
import {PublicShared} from './shared/public/public';
|
||||
import {clusterRunOnce} from './clusterUtils';
|
||||
import * as ramda from 'ramda'
|
||||
import Redis from 'ioredis';
|
||||
|
||||
@ -33,22 +33,24 @@ declare global {
|
||||
type atn = { a: string, t: string | number | any, n: number; colour?: number; shiwuBuff?: any; };
|
||||
|
||||
/**类型过滤 */
|
||||
type FilterConditionally<Source, Condition> = Pick<
|
||||
Source,
|
||||
type FilterConditionally<Source, Condition> = Pick<Source,
|
||||
{
|
||||
[K in keyof Source]: Source[K] extends Condition ? K : never
|
||||
}[keyof Source]
|
||||
>;
|
||||
}[keyof Source]>;
|
||||
|
||||
interface Array<T> {
|
||||
/**数组随机取值 */
|
||||
random(): T;
|
||||
|
||||
/**取一个数组在当前数组中的交集 */
|
||||
intersection(other: T[]): T[];
|
||||
|
||||
/**取一个数组在当前数组中的差集 */
|
||||
difference(other: T[]): T[];
|
||||
|
||||
/**数组是否存在重复元素 */
|
||||
isDuplication(): boolean;
|
||||
|
||||
/**打乱数组 */
|
||||
shuffle(): this;
|
||||
}
|
||||
@ -69,9 +71,9 @@ class _G {
|
||||
/**服务器日志模式 error | debug*/
|
||||
logModel: string;
|
||||
} = {
|
||||
serverType: 'msg',
|
||||
logModel: 'error'
|
||||
};
|
||||
serverType: 'msg',
|
||||
logModel: 'error'
|
||||
};
|
||||
/**当前时间对象 */
|
||||
date: Date;
|
||||
/**当前时间戳 */
|
||||
@ -93,7 +95,7 @@ class _G {
|
||||
/**ioredis连接对象 */
|
||||
ioredis: Redis;
|
||||
/** 跨服 ioredis 连接对象 */
|
||||
iorediscross: Redis;
|
||||
crossioredis: Redis;
|
||||
/**mongodb连接对象 */
|
||||
mongodb: _mongodb;
|
||||
/**crossmongodb连接对象 */
|
||||
@ -102,6 +104,11 @@ class _G {
|
||||
/**所有玩家的充值记录 */
|
||||
allPlayerPayLog: k_v<ResGetList['list']> = {};
|
||||
|
||||
/**跨服活动——消费竞赛的开启状态 */
|
||||
huodong = {
|
||||
xfjs: false
|
||||
};
|
||||
|
||||
private event = new EventEmitter();
|
||||
|
||||
/**映射开服时间 */
|
||||
@ -115,7 +122,7 @@ class _G {
|
||||
off(type: any, callback: any, caller?: any): void;
|
||||
emit(type: any, ...args: any[]): void;
|
||||
debug(): any;
|
||||
removeAllListeners(type?:any):void;
|
||||
removeAllListeners(type?: any): void;
|
||||
} {
|
||||
return MyEvent as any;
|
||||
}
|
||||
@ -142,10 +149,10 @@ class _G {
|
||||
}
|
||||
|
||||
on<T extends keyof gEventType>(event: T, callback: gEventType[T]) {
|
||||
return this.event.on(event, (...args)=>{
|
||||
try{
|
||||
return this.event.on(event, (...args) => {
|
||||
try {
|
||||
callback.call(this, ...args);
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
});
|
||||
@ -166,7 +173,7 @@ class _G {
|
||||
if (file.endsWith('.json5')) {
|
||||
let json = parse(readFileSync(join(jsonPath, file), 'utf-8'));
|
||||
this.gc[file.split('.')[0]] = json;
|
||||
} else if(file.endsWith('.json')) {
|
||||
} else if (file.endsWith('.json')) {
|
||||
let json = JSON.parse(readFileSync(join(jsonPath, file), 'utf-8'));
|
||||
this.gc[file.split('.')[0]] = json;
|
||||
}
|
||||
@ -233,7 +240,7 @@ export function ctor() {
|
||||
}
|
||||
|
||||
Array.prototype.random = function (this: Array<any>) {
|
||||
return this[PublicShared.randomNum(0, this.length)];
|
||||
return this[PublicShared.randomNum(0, this.length - 1)];
|
||||
};
|
||||
|
||||
Array.prototype.intersection = function (this: Array<any>, other: Array<any>) {
|
||||
|
@ -149,6 +149,8 @@ export type gEventType = {
|
||||
Class_task_156: (eventname, call, val, chkVal) => void;
|
||||
/**每日获取vip经验 */
|
||||
Class_task_157: (eventname, call, val, chkVal) => void;
|
||||
/**今日参与{1}次抓娃娃小游戏 */
|
||||
Class_task_158: (eventname, call, val, chkVal) => void;
|
||||
};
|
||||
|
||||
export function addListener() {
|
||||
|
@ -16,7 +16,7 @@ export async function initIORedis() {
|
||||
G.ioredis = new Redis(G.argv.serverType == 'cross' ? G.config.crossRedisUrl : G.config.redisUrl,{
|
||||
keyPrefix: preKey,
|
||||
});
|
||||
G.iorediscross = new Redis(G.config.crossRedisUrl,{
|
||||
G.crossioredis = new Redis(G.config.crossRedisUrl,{
|
||||
keyPrefix: "cross_",
|
||||
});
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import {ResOpen as ResOpenKaifujingsai} from '../shared/protocols/kaifujingsai/P
|
||||
import {ResOpen as ResOpenZhoumolibao} from '../shared/protocols/event/zhoumolibao/PtlOpen';
|
||||
import {ResOpen as ResOpenPobinglibao} from '../shared/protocols/event/pobinglibao/PtlOpen';
|
||||
import {ResOpen as ResOpenLeiChongLiBao} from '../shared/protocols/event/leichonglibao/PtlOpen';
|
||||
import {event as ResOpenYuandan} from '../shared/protocols/event/yuandan/PtlOpen';
|
||||
|
||||
export type eventType = {
|
||||
shouchong: {
|
||||
@ -57,6 +58,7 @@ export type eventType = {
|
||||
payForDiamond: {
|
||||
[time: number]: number
|
||||
}
|
||||
|
||||
} & {
|
||||
[k: `${number}jijin`]: ResOpenYuedujijin;
|
||||
[k: `yangchengmubiao${number}`]: yangchengmubiao;
|
||||
@ -67,6 +69,7 @@ export type eventType = {
|
||||
[k: `leijichongzhi${number}`]: Omit<ResOpenLeijichongzhi, 'payNum'>;
|
||||
[k: `qiridenglu${number}`]: Pick<ResOpenQiridenglu, 'recPrize'>;
|
||||
[k: `leichonglibao${number}`]: ResOpenLeiChongLiBao & { opentime: number };
|
||||
[k: `yuandan${number}`]: ResOpenYuandan;
|
||||
};
|
||||
|
||||
export type CollectionEvent<T extends keyof eventType> = {
|
||||
|
@ -133,4 +133,6 @@ export type MongodbCollections = {
|
||||
fightLog: CollectionFightLog
|
||||
shop: CollectionShop
|
||||
pushgift:CollectionPushGift
|
||||
|
||||
huodong_user: CollectionUser;
|
||||
};
|
@ -15,7 +15,7 @@ export function patchFun(target: any, key: string, descriptor: PropertyDescripto
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
let caller = (e.stack.split("\n").slice(2)[0].split("\\").slice(-2));
|
||||
scriptName = caller[1].split(':')[0];
|
||||
scriptName = caller[0].split('(')[1].split(':')[0];
|
||||
}
|
||||
|
||||
if(!scriptName){
|
||||
|
@ -87,6 +87,45 @@ export class JJCFun {
|
||||
return rankList
|
||||
}
|
||||
|
||||
/**
|
||||
* 每10分钟刷新前一千名玩家的用户数据
|
||||
* @param min
|
||||
* @param max
|
||||
* @param uTimeOffset
|
||||
* @param isUpdate 是否更新数据
|
||||
*/
|
||||
static async checkUpdatePlayer(min: number = 0, max: number = 1000, uTimeOffset: number = 600, isUpdate: boolean = true) {
|
||||
// 获取指定排名用户uid
|
||||
let sortInfo = await this.getRankListUid(min, max)
|
||||
if (!sortInfo.length) return []
|
||||
let updateArr = []
|
||||
|
||||
let users = await G.redis.hGetAll('rank:jjc:data')
|
||||
|
||||
for (let i = 0; i < sortInfo.length; i++) {
|
||||
let uid = sortInfo[i]
|
||||
let rankInfo = users[uid]
|
||||
if (!rankInfo?.player) continue
|
||||
// 比对utime,判断是否更新数据
|
||||
if (!rankInfo.player.isNpc) {
|
||||
if (!rankInfo.utime || (rankInfo.utime && rankInfo.utime < (G.time - uTimeOffset))) {
|
||||
updateArr.push(rankInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 更新数据
|
||||
if (isUpdate && updateArr.length > 0) {
|
||||
let playerArrInfo = await G.mongodb.collection("user").find({uid: {$in: updateArr.map(i => i.uid)}}).toArray()
|
||||
for (let i = 0; i < playerArrInfo.length; i++) {
|
||||
let playerInfo = playerArrInfo[i]
|
||||
let index = updateArr.findIndex(x => x.player.uid == playerInfo.uid)
|
||||
updateArr[index].player = playerInfo
|
||||
updateArr[index].utime = G.time
|
||||
this.updatePlayerData(playerInfo.uid, updateArr[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定范围排名的用户,仅返回uid[]
|
||||
* @param min
|
||||
|
@ -27,7 +27,7 @@ async function setHeroLvCount(call) {
|
||||
|
||||
let score = R.sum(arrList.map(i => i.lv))
|
||||
|
||||
let rankKfjs = new RankKfjs(2)
|
||||
let rankKfjs = RankKfjs(2)
|
||||
rankKfjs.setDataAndCheck({
|
||||
player: call.conn.gud,
|
||||
valArr: [score]
|
||||
@ -37,7 +37,7 @@ async function setHeroLvCount(call) {
|
||||
async function setEquipLvCount(call) {
|
||||
let status = getStatus()
|
||||
if (status.type != 3) return
|
||||
let rankKfjs = new RankKfjs(3)
|
||||
let rankKfjs = RankKfjs(3)
|
||||
let equips = await G.mongodb.collection('equip').find({
|
||||
uid: call.uid,
|
||||
wearaId: {$in: R.values(call.conn.gud.heroPos)}
|
||||
|
@ -75,8 +75,8 @@ export class LingZhuLaiXifun {
|
||||
if (_myData && PublicShared.chkSameDate(_myData.time, G.time)) {
|
||||
_res = {
|
||||
num: _myData.num || 0,
|
||||
time: _myData.time,
|
||||
maxdps: _myData.maxdps
|
||||
time: _myData.time || G.time,
|
||||
maxdps: _myData.maxdps || {}
|
||||
}
|
||||
} else {
|
||||
_res = {
|
||||
|
@ -31,6 +31,8 @@ export class PayFun {
|
||||
let obj: payLog = {time: G.time, type: type};
|
||||
if (conf.time != -1) obj.eTime = time + conf.time;
|
||||
|
||||
obj.args = payArgs
|
||||
|
||||
if (payId == 'G123SendGift') {
|
||||
obj.popup_id = payArgs.popup_id
|
||||
obj.template_id = payArgs.template_id
|
||||
@ -206,19 +208,20 @@ export class PayFun {
|
||||
payArgs: payArgs,
|
||||
orderNo: orderNo
|
||||
}
|
||||
if (payId.indexOf('zixuanlibao') != -1) {
|
||||
// 后端唯一标识 htype 4 自选/定制 礼包
|
||||
// @ts-ignore
|
||||
let _hdList = await HuoDongFun.gethdList(call, 4)
|
||||
_hdList.forEach(ele => {
|
||||
let selectPrize = ele.data.gift.find(v => v.payId == payId)?.prize;
|
||||
if (prize) {
|
||||
let index = payArgs instanceof Array ? payArgs : [];
|
||||
let select = selectPrize.map((v, i) => v[index[i]] ? v[index[i]] : v[0]);
|
||||
prize.push(...select);
|
||||
}
|
||||
})
|
||||
}
|
||||
//改为统一方法,此处自选不这样用
|
||||
// if (payId.indexOf('zixuanlibao') != -1) {
|
||||
// // 后端唯一标识 htype 4 自选/定制 礼包
|
||||
// // @ts-ignore
|
||||
// let _hdList = await HuoDongFun.gethdList(call, 4)
|
||||
// _hdList.forEach(ele => {
|
||||
// let selectPrize = ele.data.gift.find(v => v.payId == payId)?.prize;
|
||||
// if (prize) {
|
||||
// let index = payArgs instanceof Array ? payArgs : [];
|
||||
// let select = selectPrize.map((v, i) => v[index[i]] ? v[index[i]] : v[0]);
|
||||
// prize.push(...select);
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
if (payId.indexOf('ycmb') != -1) {
|
||||
// @ts-ignore // 养成活动充值礼包
|
||||
let _hdids = await YangChengMuBiaofun.getCon(call);
|
||||
@ -235,11 +238,30 @@ export class PayFun {
|
||||
let conf = await zmlbGetConf(call, {payId})
|
||||
prize.push(...conf.prize)
|
||||
}
|
||||
|
||||
/**
|
||||
* todo 不要轻易改动这个方法,不允许集成业务逻辑在内部
|
||||
* todo 此方法仅仅是支付成功后的发奖
|
||||
* todo 如果有业务逻辑通过事件驱动,在支付成功后emit事件
|
||||
* todo 下面这个方法不应该这样写
|
||||
*/
|
||||
//圣诞节活动充值
|
||||
try{
|
||||
try {
|
||||
await Christmasfun.payChristmas(payId, call);
|
||||
}catch (e) {
|
||||
console.log("Christmasfun.payChristmas Error",e);
|
||||
} catch (e) {
|
||||
console.log("Christmasfun.payChristmas Error", e);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果是自选奖励,payArgs里传入自选项,直接发奖
|
||||
* 在check里判断拦截自选项的奖励
|
||||
*/
|
||||
if (payArgs && payArgs?.htype && payArgs?.selectList) {
|
||||
let selectPrize = await G.ioredis.get(`pay:${payId}:${player.uid}`);
|
||||
if (selectPrize) {
|
||||
prize.push(...JSON.parse(selectPrize))
|
||||
G.ioredis.del(`pay:${payId}:${player.uid}`)
|
||||
}
|
||||
}
|
||||
|
||||
let isReplaceConf = await this.checkBuysAfterPay(uid, payId, conf, payArgs, player)
|
||||
@ -399,6 +421,33 @@ export class PayFun {
|
||||
if (conf.time != -1 && buyLog.slice(-1)[0]?.eTime > G.time && conf.buys == 0 && payId.indexOf('wkdlibao') == -1) {
|
||||
return G.server.sendMsgByUid(player.uid, 'msg_s2c/PayResult', {code: -2});
|
||||
}
|
||||
|
||||
/**
|
||||
* 活动相关的自选礼包,目前htype 4、14支持此方法
|
||||
* payArgs里传相应参数,selectList选择的奖励列表
|
||||
* 往后所有自选类型,走这个方法,配置格式同4、14
|
||||
*/
|
||||
if (payArgs && payArgs?.htype && payArgs?.selectList) {
|
||||
let call = this.getCall(player)
|
||||
// @ts-ignore
|
||||
let _hdInfo = (await HuoDongFun.gethdList(call, payArgs.htype))[0]
|
||||
// 活动类购买不符合条件返回-5
|
||||
if (!_hdInfo) G.server.sendMsgByUid(player.uid, 'msg_s2c/PayResult', {code: -5})
|
||||
let giftInfo = _hdInfo.data.gift.find(v => v.payId == payId);
|
||||
if (!giftInfo) G.server.sendMsgByUid(player.uid, 'msg_s2c/PayResult', {code: -5})
|
||||
|
||||
let dlzPrize = R.flatten(giftInfo.dlz.map(i => R.values(i)))
|
||||
let selectPrize = payArgs.selectList.map(v => {
|
||||
let sPrize = dlzPrize.find(o => o.a == v.a && o.t == v.t && o.n == v.n)
|
||||
// 严格判断,自选奖励不存在奖励列表,返回-6
|
||||
if (!sPrize) return G.server.sendMsgByUid(player.uid, 'msg_s2c/PayResult', {code: -6});
|
||||
return sPrize
|
||||
})
|
||||
// 自选奖励过判断后,存入redis,6小时内支付有效 todo 6小时可能有些长
|
||||
let prize = [...giftInfo.prize, ...selectPrize]
|
||||
G.ioredis.setex(`pay:${payId}:${player.uid}`, 21600, JSON.stringify(prize));
|
||||
}
|
||||
|
||||
//针对每日礼包的单独处理
|
||||
let zeroTime = PublicShared.getToDayZeroTime(G.time)
|
||||
if (payId.indexOf('136Gift') != -1 && payId != '136GiftAll') {
|
||||
@ -455,6 +504,7 @@ export class PayFun {
|
||||
|
||||
/**
|
||||
* 当玩家购买过有时间期效性的礼包 并且在生效期内每天有邮件奖励时 每天首次登陆时根据时间补发邮件 玩家每天首次登陆会进入检查
|
||||
* @param player
|
||||
* @param lastTime 上一次登陆时间
|
||||
* @param curTime 每日首次登陆时间
|
||||
*/
|
||||
|
@ -214,7 +214,6 @@ export class PlayerFun {
|
||||
}
|
||||
|
||||
static async changeAttrLog(uid: string, change, atn, before) {
|
||||
|
||||
let data = {
|
||||
uid,
|
||||
before,
|
||||
@ -225,6 +224,13 @@ export class PlayerFun {
|
||||
atn
|
||||
}
|
||||
G.mongodb.collection('rmbuse').insertOne(data);
|
||||
// 消费竞赛开启时写入跨服数据库
|
||||
if (G.huodong.xfjs && !data.isAdd) {
|
||||
G.crossmongodb.collection('rmbuse').updateOne({uid: data.uid}, {
|
||||
$set: {time: G.time},
|
||||
$inc: {change: data.change}
|
||||
}, {upsert: true});
|
||||
}
|
||||
}
|
||||
|
||||
static async changeAttr(uid: string, change: Partial<player>) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { rankType, ResOpen } from '../../shared/protocols/rank/PtlOpen';
|
||||
import { rankInfo } from '../../shared/protocols/type';
|
||||
import { player } from '../../shared/protocols/user/type';
|
||||
import { Queue } from '../../shared/public/queue';
|
||||
import { RankClslCross } from './rank_clsl';
|
||||
//import { RankHbzbJfsCross, RankHbzbJfsLocal, RankHbzbZbsCross } from './rank_hbzb_jfs';
|
||||
@ -12,11 +11,11 @@ import { RankTujian } from './rank_tujian';
|
||||
import { RankWzryCross } from './rank_wzry';
|
||||
import { RankXszm } from './rank_xszm';
|
||||
import { RankZccg } from './rank_zccg';
|
||||
import { sortEd } from '../../module/redis'
|
||||
import * as util from 'util'
|
||||
import {RankKfjs} from "./rank_kfjs";
|
||||
|
||||
import { RankKfjs_1 } from "./rank_kfjs";
|
||||
import { clusterRunOnce } from '../../clusterUtils';
|
||||
import { number } from 'mathjs';
|
||||
|
||||
|
||||
|
||||
export abstract class Rank {
|
||||
@ -24,9 +23,6 @@ export abstract class Rank {
|
||||
qjzzd: RankQjzzd;
|
||||
zhanli: RankPower;
|
||||
tanxian: RankTanXian;
|
||||
//hbzbLocal: RankHbzbJfsLocal;
|
||||
// hbzbCross: RankHbzbJfsCross;
|
||||
// hbzbZbsCross: RankHbzbZbsCross;
|
||||
slzd1: RankSlzd1;
|
||||
slzd2: RankSlzd2;
|
||||
slzd3: RankSlzd3;
|
||||
@ -38,20 +34,14 @@ export abstract class Rank {
|
||||
zccg: RankZccg;
|
||||
tujian: RankTujian;
|
||||
wzryCross: RankWzryCross;
|
||||
kfjs: RankKfjs
|
||||
}> = {};
|
||||
}> & k_v<Rank> = {};
|
||||
|
||||
// list: rankInfo[];
|
||||
queue = new Queue();
|
||||
findKey = 'uid';
|
||||
countMaxNum = 50;
|
||||
utimeTTL = 60;
|
||||
|
||||
abstract getType(): rankType;
|
||||
// abstract compare(other: rankInfo, cur: rankInfo): boolean;
|
||||
// abstract compareSort(a: rankInfo, b: rankInfo): number;
|
||||
// abstract getRankList(uid: string, obj?: {gud?:player, min?: number, max?:number}): Promise<ResOpen['']>;
|
||||
// abstract getValArr(info: rankInfo): number|string; // 运算后的积分值,排名依据
|
||||
|
||||
// 获取rank数据, 注:可能重写,具体根据type类型判断
|
||||
async getRankList(uid: string, { min, max }): Promise<{ rankList: rankInfo[]; myRank: rankInfo; }> {
|
||||
@ -65,13 +55,18 @@ export abstract class Rank {
|
||||
myRank: {
|
||||
rank,
|
||||
player: data?.player || conn?.gud || {},
|
||||
valArr: [ score ]
|
||||
valArr: [score]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 积分, 排名依据, ,注:可能重写,具体根据type类型判断
|
||||
getValArr(info: rankInfo):number|string {
|
||||
/**
|
||||
* 根据RankInfo数据,获取用于排名的积分值得
|
||||
* 注:可能重写,具体根据type类型判断
|
||||
* @param info
|
||||
* @returns 积分值
|
||||
*/
|
||||
getValArr(info: rankInfo): number | string {
|
||||
return info?.valArr[0] || 0
|
||||
}
|
||||
|
||||
@ -85,9 +80,13 @@ export abstract class Rank {
|
||||
return b.valArr[0] - a.valArr[0];
|
||||
}
|
||||
|
||||
|
||||
// 页码转换为min,max
|
||||
static pageToMin (page, offset) {
|
||||
/**
|
||||
* 页面转换,根据page和offset转换出min和max
|
||||
* @param page 页面
|
||||
* @param offset 每页数量
|
||||
* @returns
|
||||
*/
|
||||
static pageToMin(page: number, offset: number) {
|
||||
let res = {
|
||||
min: page * offset,
|
||||
max: page * offset + offset
|
||||
@ -95,22 +94,35 @@ export abstract class Rank {
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回排行榜DB连接对象
|
||||
*/
|
||||
get db() {
|
||||
return G.mongodb.collection('rankList');
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回排行榜类型
|
||||
*/
|
||||
get type() {
|
||||
return this.getType();
|
||||
}
|
||||
|
||||
constructor() {
|
||||
Rank.list[this.getType()] = this;
|
||||
Rank.list[this.getType() as string] = this;
|
||||
this.cotr();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据type,获取redis Data的key
|
||||
*/
|
||||
get getRedisKey() {
|
||||
return util.format('rank:%s:data', this.getType())
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据type,获取redis Sort的key
|
||||
*/
|
||||
get getRedisKeySort() {
|
||||
return util.format('rank:%s:sort', this.getType())
|
||||
}
|
||||
@ -119,152 +131,279 @@ export abstract class Rank {
|
||||
async cotr() {
|
||||
clusterRunOnce(async () => {
|
||||
// redis已存在则不初始化
|
||||
if(await this.getRankLen() > 0) return
|
||||
this.db.find({ type: this.type }).toArray().then(listArr => {
|
||||
//if(await this.getRankLen() > 0) return
|
||||
|
||||
//将db里的数据,写入到 rank:xxx:sort里
|
||||
//写入的单条数据为: {uid:score}
|
||||
this.db.find({ type: this.type }, {
|
||||
projection: {
|
||||
"idKey": 1,
|
||||
"type": 1,
|
||||
"data.valArr": 1,
|
||||
"utime": 1
|
||||
}
|
||||
}).toArray().then(listArr => {
|
||||
// 写入初始化数据
|
||||
listArr = listArr || [];
|
||||
listArr.forEach(item => {
|
||||
if(item.idKey && item.data) this.setRankData(item.idKey, item.data)
|
||||
if (item.idKey && item.data) this.setRankData(item.idKey, item.data)
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
this.getRankListRange();
|
||||
}
|
||||
|
||||
// 更新数据与排名
|
||||
async setRankData(idKey: string, data: rankInfo) {
|
||||
let key = this.getRedisKey
|
||||
/**
|
||||
* 更新玩家的积分
|
||||
* @param uid uid,在rank里通常保存于idKey这个字段
|
||||
* @param data 积分数据,主要是需要里面的data.valArr字段
|
||||
* @returns
|
||||
*/
|
||||
async setRankData(uid: string, data: rankInfo) {
|
||||
let keySort = this.getRedisKeySort
|
||||
data.utime = G.time
|
||||
// data
|
||||
G.redis.hSet(key, idKey, data)
|
||||
// sort
|
||||
let valArr = await this.getValArr(data)
|
||||
G.redis.zAdd(keySort, <sortEd>{value: idKey, score: valArr})
|
||||
|
||||
// let key = this.getRedisKey
|
||||
// G.redis.hSet(key, idKey, data)
|
||||
|
||||
/**积分 */
|
||||
let score = await this.getValArr(data)
|
||||
//G.redis.zAdd(keySort, <sortEd>{value: idKey, score: valArr})
|
||||
await G.ioredis.zadd(keySort, score, uid)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取单个用户的数据
|
||||
async getRankData(idKey: string) {
|
||||
let key = this.getRedisKey
|
||||
let data = await G.redis.hGet(key, idKey)
|
||||
if(!data || data.utime < (G.time - this.utimeTTL)) {
|
||||
let type = this.getType()
|
||||
let res = await this.db.findOne({isKey: idKey, type})
|
||||
if(res) {
|
||||
data = G.mongodb.conversionIdObj(res)
|
||||
this.setRankData(idKey, data.data)
|
||||
}
|
||||
/**
|
||||
* 获取单个用户的数据
|
||||
* @param uid uid
|
||||
* @returns
|
||||
*/
|
||||
async getRankData(uid: string) {
|
||||
let data: rankInfo;
|
||||
let res = await this.db.findOne({ "idKey": uid, "type": this.getType() })
|
||||
|
||||
if (res?.data && res.data.utime + 60 > G.time) {
|
||||
data = (G.mongodb.conversionIdObj(res)).data;
|
||||
} else if (res?.data) {
|
||||
let player = await G.mongodb.collection("user").findOne({ uid: uid }, { projection: { _id: 0 } });
|
||||
|
||||
data = Object.assign(res.data, { player: player });
|
||||
this.db.updateOne({ idKey: uid, type: this.getType() }, { $set: { "data.player": data.player, "data.utime": G.time } });
|
||||
}
|
||||
if(data) return data
|
||||
return undefined || {}
|
||||
return data;
|
||||
|
||||
// let key = this.getRedisKey
|
||||
// let data = await G.redis.hGet(key, idKey)
|
||||
// if(!data || data.utime < (G.time - this.utimeTTL)) {
|
||||
// let type = this.getType()
|
||||
// let res = await this.db.findOne({isKey: idKey, type}) //<--isKey??意味着整个rank从来不会更新,res永远是空
|
||||
// if(res) {
|
||||
// data = G.mongodb.conversionIdObj(res)
|
||||
// this.setRankData(idKey, data.data)
|
||||
// }
|
||||
// }
|
||||
// if(data) return data
|
||||
// return undefined || {}
|
||||
}
|
||||
|
||||
// 获取单个用户的分数
|
||||
async getRankScore(idKey:string): Promise<number> {
|
||||
let score = await G.redis.zScore(this.getRedisKeySort, idKey)
|
||||
/**
|
||||
* 获取单个用户的排序分数
|
||||
* @param uid
|
||||
* @returns
|
||||
*/
|
||||
async getRankScore(uid: string): Promise<number> {
|
||||
let score = await G.redis.zScore(this.getRedisKeySort, uid)
|
||||
return score || 0
|
||||
}
|
||||
|
||||
// 获取单个用户的排名 *降序
|
||||
async getRankSortByOne(idKey: string):Promise<number> {
|
||||
let rank = await G.redis.zRevRank(this.getRedisKeySort, idKey)
|
||||
return rank === 0 || rank > 0 ? rank: -1;
|
||||
/**
|
||||
* 从redis中获取单个用户的排名 *降序
|
||||
* @param uid
|
||||
* @returns
|
||||
*/
|
||||
async getRankSortByOne(uid: string): Promise<number> {
|
||||
let rank = await G.redis.zRevRank(this.getRedisKeySort, uid)
|
||||
return rank === 0 || rank > 0 ? rank : -1;
|
||||
}
|
||||
|
||||
// 获取单个指定排名的用户数据 *降序
|
||||
// 从redis中获取单个指定排名的用户数据 *降序
|
||||
async getRankSortDataByOne(rank: number): Promise<rankInfo> {
|
||||
let rankList:rankInfo[] = await this.getRankListRange(rank, rank + 1)
|
||||
let rankList: rankInfo[] = await this.getRankListRange(rank, rank + 1)
|
||||
let rankInfo = rankList && rankList.length > 0 ? rankList[0] : {} as rankInfo
|
||||
return rankInfo
|
||||
}
|
||||
|
||||
// 获取排名长度
|
||||
async getRankLen() {
|
||||
return await G.redis.hLen(this.getRedisKey)
|
||||
// async getRankLen() {
|
||||
// return await G.redis.hLen(this.getRedisKey)
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取指定排名范围的数据 *降序
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns
|
||||
*/
|
||||
async getRankListRange(min: number = 0, max: number = 50): Promise<rankInfo[]> {
|
||||
let uids = await this.getRankListIdKeyRange(min, max)
|
||||
if (uids && uids.length > 0) {
|
||||
let res = await this.db.find({ idKey: { $in: uids }, type: this.getType() }).toArray()
|
||||
|
||||
switch (this.getType()) {
|
||||
case "slzd1":
|
||||
case "slzd2":
|
||||
case "slzd3":
|
||||
case "slzd4":
|
||||
case "slzd5":
|
||||
case "slzd6":
|
||||
let ghid = [];
|
||||
res = res.map(item => {
|
||||
if (!item.data?.player?.ghid || item.data.utime + 60 < G.time) {
|
||||
ghid.push(G.mongodb.conversionId(item.idKey));
|
||||
}
|
||||
return item;
|
||||
})
|
||||
if(ghid.length > 0){
|
||||
let ghinfo = await G.mongodb.collection("gonghui").find(
|
||||
{ _id: { $in: ghid } }, { projection: { name: 1 } }
|
||||
).toArray();
|
||||
ghinfo.forEach(item => {
|
||||
let index = res.findIndex(x => x.idKey == item._id.toHexString());
|
||||
res[index].data.player = {
|
||||
ghName: item.name,
|
||||
ghId: item._id.toHexString(),
|
||||
};
|
||||
this.db.updateOne({ idKey: item._id.toHexString(), type: this.getType() }, { $set: { "data.player": res[index].data.player } });
|
||||
})
|
||||
}
|
||||
break;
|
||||
default: // 排行数据更新逻辑 默认更新playerInfo
|
||||
let updateUids = [];
|
||||
res = res.map(item => {
|
||||
// 没有player 或者 player 过期
|
||||
if (!item.data?.player || item.data.utime + 60 < G.time) {
|
||||
updateUids.push(item.idKey);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
let newUserArr = await G.mongodb.collection('user').find(
|
||||
{ uid: { $in: updateUids } }, { projection: { _id: 0 } }
|
||||
).toArray();
|
||||
|
||||
newUserArr.forEach(item => {
|
||||
// 每次遍历查找?
|
||||
let index = res.findIndex(x => x.idKey == item.uid);
|
||||
|
||||
res[index].data.player = item;
|
||||
this.db.updateOne({ idKey: item.uid, type: this.getType() }, { $set: { "data.player": item } });
|
||||
|
||||
// 跟新redis score
|
||||
// this.setRankData(item.uid, res[index].data as any);
|
||||
})
|
||||
}
|
||||
|
||||
return res.map(ele => ele.data).sort(this.compareSort) as any;
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// 获取指定排名范围的数据 *降序
|
||||
async getRankListRange(min:number = 0, max:number = 50): Promise<rankInfo[]> {
|
||||
let idKeys = await this.getRankListIdKeyRange(min, max)
|
||||
if(idKeys && idKeys.length > 0) {
|
||||
let res = await G.redis.hmGet(this.getRedisKey, idKeys)
|
||||
res = await this.checkData(res)
|
||||
/**
|
||||
* 从redis中获取指定排名范围的uid集合 *降序
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns uid集合数组
|
||||
*/
|
||||
async getRankListIdKeyRange(min: number = 0, max: number = 50): Promise<string[]> {
|
||||
let uids = await G.redis.zRevRange(this.getRedisKeySort, min, max - 1)
|
||||
return uids || []
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定类型的全部rank列表,返回为积分排序后的数组
|
||||
* @returns
|
||||
*/
|
||||
async getRankListAll(): Promise<rankInfo[]> {
|
||||
// let res = await G.redis.hGetAll(this.getRedisKey)
|
||||
let res = (await this.db.find({ type: this.getType() }).toArray()).map(ele => ele.data);
|
||||
if (res) {
|
||||
// 如果是用户数据,则比对utime,更新数据
|
||||
// res = await this.checkData(res)
|
||||
return res.sort(this.compareSort)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// 获取指定排名范围的idKey *降序
|
||||
async getRankListIdKeyRange(min:number = 0, max: number = 50): Promise<string[]> {
|
||||
let idKeys = await G.redis.zRevRange(this.getRedisKeySort, min, max - 1)
|
||||
return idKeys || []
|
||||
}
|
||||
|
||||
// 获取指定类型的全部rank列表,返回为积分排序后的数组
|
||||
async getRankListAll(): Promise<rankInfo[]> {
|
||||
let res = await G.redis.hGetAll(this.getRedisKey)
|
||||
if(res) {
|
||||
// 如果是用户数据,则比对utime,更新数据
|
||||
// res = await this.checkData(res)
|
||||
return Object.values(res).sort(this.compareSort)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// 按排名获取全部的idKey
|
||||
/**
|
||||
* 按排名获取全部的idKey
|
||||
* @returns
|
||||
*/
|
||||
async getRankListIdKeyAll(): Promise<string[]> {
|
||||
let res = this.getRankListIdKeyRange(0, -1)
|
||||
return res
|
||||
}
|
||||
|
||||
// 验证数据的过期时间,更新数据
|
||||
async checkData(rankList: rankInfo[]): Promise<rankInfo[]> {
|
||||
let updateUid = []
|
||||
rankList.forEach((value,key) => {
|
||||
// 仅针对用户表,公会表暂不考虑
|
||||
if(rankList[key].player?.uid && (rankList[key].utime || 0) < (G.time - this.utimeTTL)) {
|
||||
// 更新数据
|
||||
updateUid.push(rankList[key].player.uid)
|
||||
}
|
||||
})
|
||||
if(updateUid.length > 0) {
|
||||
let newUserArr = await G.mongodb.collection('user').find({uid:{$in: updateUid}}).toArray()
|
||||
// let newUserArr = await G.redis.gets('user', ...updateUid.map(uid => [uid] as [string]))
|
||||
// let newUserArr = await G.mongodb.collection('user').find({uid:{$in: updateUid}}).toArray()
|
||||
newUserArr.forEach(item => {
|
||||
let index = rankList.findIndex( x => x.player.uid == item.uid);
|
||||
rankList[index].player = item;
|
||||
this.setRankData(item.uid, rankList[index]);
|
||||
})
|
||||
}
|
||||
return rankList
|
||||
// async checkData(rankList: rankInfo[]): Promise<rankInfo[]> {
|
||||
// let updateUid = []
|
||||
// rankList.forEach((value,key) => {
|
||||
// // 仅针对用户表,公会表暂不考虑
|
||||
// if(rankList[key].player?.uid && (rankList[key].utime || 0) < (G.time - this.utimeTTL)) {
|
||||
// // 更新数据
|
||||
// updateUid.push(rankList[key].player.uid)
|
||||
// }
|
||||
// })
|
||||
// if(updateUid.length > 0) {
|
||||
// let newUserArr = await G.mongodb.collection('user').find({uid:{$in: updateUid}}).toArray()
|
||||
// // let newUserArr = await G.redis.gets('user', ...updateUid.map(uid => [uid] as [string]))
|
||||
// // let newUserArr = await G.mongodb.collection('user').find({uid:{$in: updateUid}}).toArray()
|
||||
// newUserArr.forEach(item => {
|
||||
// let index = rankList.findIndex( x => x.player.uid == item.uid);
|
||||
// rankList[index].player = item;
|
||||
// this.setRankData(item.uid, rankList[index]);
|
||||
// })
|
||||
// }
|
||||
// return rankList
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 删除指定idk的排名数据
|
||||
* @param idKey
|
||||
* @returns
|
||||
*/
|
||||
async delRankData(idKey: string) {
|
||||
// G.redis.hDel(this.getRedisKey, idKey)
|
||||
G.redis.zRem(this.getRedisKeySort, idKey);
|
||||
this.db.updateOne({ idKey: idKey, type: this.getType() }, {
|
||||
$set: { idKey: `del_${idKey}` }
|
||||
});
|
||||
}
|
||||
|
||||
async delRankData(idKey:string) {
|
||||
G.redis.hDel(this.getRedisKey, idKey)
|
||||
G.redis.zRem(this.getRedisKeySort, idKey)
|
||||
}
|
||||
|
||||
// 原逻辑前50(countMaxNum)名才更新数据(上榜),多余的数据会删除。
|
||||
/**
|
||||
* 原逻辑前50(countMaxNum)名才更新数据(上榜),多余的数据会删除。
|
||||
* @param info
|
||||
* @returns
|
||||
*/
|
||||
async addNew(info: rankInfo) {
|
||||
//this.queue.enqueue(async () => {
|
||||
await this.setRankData(info.player[this.findKey], info)
|
||||
await this.db.updateOne({ type: this.type, idKey: info.player[this.findKey] }, { $set: { data: info } }, { upsert: true });
|
||||
// 删除第50名以后的数据,(排名从0开始计算)
|
||||
// let idKeys:string[] = await this.getRankListIdKeyRange(50, -1)
|
||||
// idKeys.forEach(idKey => {
|
||||
// this.db.deleteOne({ type: this.type, idKey: idKey });
|
||||
// this.delRankData(idKey)
|
||||
// })
|
||||
await this.setRankData(info.player[this.findKey], info)
|
||||
await this.db.updateOne({ type: this.type, idKey: info.player[this.findKey] }, { $set: { data: info } }, { upsert: true });
|
||||
// 删除第50名以后的数据,(排名从0开始计算)
|
||||
// let idKeys:string[] = await this.getRankListIdKeyRange(50, -1)
|
||||
// idKeys.forEach(idKey => {
|
||||
// this.db.deleteOne({ type: this.type, idKey: idKey });
|
||||
// this.delRankData(idKey)
|
||||
// })
|
||||
//});
|
||||
}
|
||||
|
||||
|
||||
// 清空相关rank数据
|
||||
async clear() {
|
||||
this.queue.enqueue(async () => {
|
||||
// G.redis.rawDel(this.getRedisKey)
|
||||
G.redis.rawDel(this.getRedisKeySort);
|
||||
await this.db.deleteMany({ type: this.type });
|
||||
G.redis.rawDel(this.getRedisKey)
|
||||
G.redis.rawDel(this.getRedisKeySort)
|
||||
});
|
||||
}
|
||||
}
|
@ -1,23 +1,18 @@
|
||||
import {rankType} from '../../shared/protocols/rank/PtlOpen';
|
||||
import {rankInfo} from '../../shared/protocols/type';
|
||||
import {Rank} from './rank';
|
||||
import { rankType } from '../../shared/protocols/rank/PtlOpen';
|
||||
import { rankInfo } from '../../shared/protocols/type';
|
||||
import { Rank } from './rank';
|
||||
import kfjsFun from "../kaifujingsai";
|
||||
|
||||
|
||||
export class RankKfjs extends Rank {
|
||||
export class RankKfjs_1 extends Rank {
|
||||
ctype: string;
|
||||
|
||||
ortype: string
|
||||
ctype: string
|
||||
|
||||
constructor(ctype) {
|
||||
super();
|
||||
this.ctype = ctype
|
||||
this.ortype = `kfjs${kfjsFun.getStatus().type}`
|
||||
get ortype() {
|
||||
return `kfjs${kfjsFun.getStatus().type}`
|
||||
}
|
||||
|
||||
getType(): rankType {
|
||||
let status = kfjsFun.getStatus(this.ctype)
|
||||
return <rankType>`kfjs${status.type}`;
|
||||
return <rankType>`kfjs1`;
|
||||
}
|
||||
|
||||
async setDataAndCheck(info: rankInfo) {
|
||||
@ -27,3 +22,46 @@ export class RankKfjs extends Rank {
|
||||
this.addNew(info)
|
||||
}
|
||||
}
|
||||
|
||||
export class RankKfjs_2 extends RankKfjs_1 {
|
||||
getType(): rankType {
|
||||
return <rankType>`kfjs2`;
|
||||
}
|
||||
}
|
||||
|
||||
export class RankKfjs_3 extends RankKfjs_1 {
|
||||
getType(): rankType {
|
||||
return <rankType>`kfjs3`;
|
||||
}
|
||||
}
|
||||
|
||||
export class RankKfjs_4 extends RankKfjs_1 {
|
||||
getType(): rankType {
|
||||
return <rankType>`kfjs4`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class RankKfjs_5 extends RankKfjs_1 {
|
||||
getType(): rankType {
|
||||
return <rankType>`kfjs5`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class RankKfjs_6 extends RankKfjs_1 {
|
||||
getType(): rankType {
|
||||
return <rankType>`kfjs6`;
|
||||
}
|
||||
}
|
||||
|
||||
export class RankKfjs_7 extends RankKfjs_1 {
|
||||
getType(): rankType {
|
||||
return <rankType>`kfjs7`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function RankKfjs(type: number) {
|
||||
return <RankKfjs_1>Rank.list[`kfjs${type}`]
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import { Scheduler, schedulerType } from './scheduler';
|
||||
import {PublicShared} from "../../shared/public/public";
|
||||
import {Wjjl} from "../../module/collection_wjjl";
|
||||
import {ZhanLingTasks} from "../zhanling";
|
||||
import { PublicShared } from "../../shared/public/public";
|
||||
import { Wjjl } from "../../module/collection_wjjl";
|
||||
import { ZhanLingTasks } from "../zhanling";
|
||||
import { setGud } from '../gud';
|
||||
import { EmailFun } from '../email';
|
||||
|
||||
|
||||
export class SchedulerNewDayLocalCtor extends Scheduler {
|
||||
@ -23,8 +24,8 @@ export class SchedulerNewDayLocalCtor extends Scheduler {
|
||||
|
||||
async start() {
|
||||
let users = Object.values(G.server.uid_connections)
|
||||
if(users.length) {
|
||||
for (let item of users){
|
||||
if (users.length) {
|
||||
for (let item of users) {
|
||||
let gud = item.gud
|
||||
let add: k_v<any> = {};
|
||||
//每天首次登陆
|
||||
@ -36,23 +37,53 @@ export class SchedulerNewDayLocalCtor extends Scheduler {
|
||||
if (gud.logoutTime && PublicShared.getToWeekMondayZeroTime(gud.logoutTime) < PublicShared.getToWeekMondayZeroTime(G.time)) {
|
||||
ZhanLingTasks.clearLog(gud.uid, 'week');
|
||||
}
|
||||
G.emit('FIRST_LOGIN_EVERY_DAY', gud, G.time - 24 * 3600, G.time);
|
||||
G.emit('FIRST_LOGIN_EVERY_DAY', gud, gud.loginTime, G.time);
|
||||
}
|
||||
gud.loginTime = G.time;
|
||||
add.loginTime = G.time;
|
||||
|
||||
if (Object.keys(add).length > 0) {
|
||||
G.mongodb.collection('user').updateOne({ bindUid: gud.bindUid,sid:gud.sid }, {
|
||||
G.mongodb.collection('user').updateOne({ bindUid: gud.bindUid, sid: gud.sid }, {
|
||||
$set: {
|
||||
...add
|
||||
}
|
||||
});
|
||||
setGud(gud.uid,add);
|
||||
setGud(gud.uid, add);
|
||||
}
|
||||
G.server.sendMsgByUid(gud.uid, 'msg_s2c/PlayerChange', gud)
|
||||
|
||||
}
|
||||
G.server.broadcastClusterMsg('msg_s2c/NewDay', {time: this.zeroTime});
|
||||
G.server.broadcastClusterMsg('msg_s2c/NewDay', { time: this.zeroTime });
|
||||
}
|
||||
|
||||
(async () => {
|
||||
// 每周一,发放终身卡
|
||||
if (PublicShared.getWeek(G.time) != 1) {
|
||||
console.log("不是周一,不发放终身卡", PublicShared.getWeek(G.time));
|
||||
return
|
||||
};
|
||||
|
||||
let logs = await G.mongodb.collection("payLogNew").find(
|
||||
{ key: "zhongshenka", del_time: { $exists: false } }, { projection: { _id: 0, } }
|
||||
).toArray();
|
||||
|
||||
if (logs.length == 0) {
|
||||
console.log("没有终身卡数据,不发放终身卡");
|
||||
}
|
||||
let con = G.gc.payEmail.zhongshenka.filter(e => e.day == 7)[0];
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
console.log("发放终身卡", logs[i].uid);
|
||||
// 发送邮件
|
||||
EmailFun.addEmail({
|
||||
uid: logs[i].uid,
|
||||
type: "system",
|
||||
title: con.title,
|
||||
content: con.content,
|
||||
contentInsertArr: [],
|
||||
createTime: G.time,
|
||||
prize:con.prize,
|
||||
})
|
||||
}
|
||||
})()
|
||||
}
|
||||
}
|
||||
|
@ -38,14 +38,15 @@ export class Scheduler_xfjs_Local_Ctor extends Scheduler {
|
||||
if (!_hd) return
|
||||
|
||||
let limit = _hd.data?.rank?.slice(-1)?.[0]?.rank?.slice(-1)?.[0] || 100
|
||||
let rmbuse = await G.mongodb.collection('rmbuse').aggregate([
|
||||
{$match: {isAdd: false, cTime: {$gte: _hd.stime, $lte: _hd.etime}}},
|
||||
{$group: {_id: "$uid", total: {$sum: "$change"}}},
|
||||
{$sort: {total: 1}},
|
||||
{$limit: limit}
|
||||
]).toArray()
|
||||
|
||||
let list: any = rmbuse.map(i => ({...i, total: R.negate(i.total)}))
|
||||
let rmbuse = await G.crossmongodb.collection('rmbuse').find({
|
||||
time: {
|
||||
$gte: _hd.stime,
|
||||
$lte: _hd.etime + 10
|
||||
}
|
||||
}).sort({change: 1}).limit(limit).toArray()
|
||||
|
||||
let list: any = rmbuse.map(i => ({...i, total: R.negate(i.change)}))
|
||||
|
||||
let ranklist = sortRankList(_hd.data.rank, list)
|
||||
|
||||
@ -53,6 +54,7 @@ export class Scheduler_xfjs_Local_Ctor extends Scheduler {
|
||||
let users = R.slice(i.rank[0] - 1, i.rank[1])(ranklist)
|
||||
users.map(v => {
|
||||
if (v._id == 'system') return
|
||||
if (G.config.serverId != users.sid) return;
|
||||
EmailFun.addEmail({
|
||||
uid: v._id,
|
||||
type: 'system',
|
||||
|
@ -1,32 +1,31 @@
|
||||
import { ApiCall } from 'tsrpc';
|
||||
import { ResOpen } from '../shared/protocols/tanxian/PtlOpen';
|
||||
import { TeQuanFun } from './tequan';
|
||||
import {ApiCall} from 'tsrpc';
|
||||
import {ResOpen} from '../shared/protocols/tanxian/PtlOpen';
|
||||
import {TeQuanFun} from './tequan';
|
||||
|
||||
type dataChange = Partial<ResOpen>;
|
||||
|
||||
export class TanXianFun {
|
||||
/**修改探险数据 */
|
||||
static async changeData(call: ApiCall, change: dataChange) {
|
||||
|
||||
G.mongodb.collection('tanxian').updateOne({ uid: call.uid }, { $set: { ...change } });
|
||||
G.mongodb.collection('tanxian').updateOne({uid: call.uid}, {$set: {...change}});
|
||||
let data = await this.getData(call);
|
||||
Object.assign(data, change);
|
||||
G.ioredis.set(`tanxian:${call.uid}`, JSON.stringify(data));
|
||||
G.ioredis.setex(`tanxian:${call.uid}`, 600, JSON.stringify(data));
|
||||
}
|
||||
|
||||
/**获取探险数据 */
|
||||
static async getData(call: ApiCall, cache = true) {
|
||||
if(cache){
|
||||
let data = await G.ioredis.get(`tanxian:${call.uid}`);
|
||||
if (data) return JSON.parse(data);
|
||||
}
|
||||
let { _id, uid, ...data } = await G.mongodb.collection('tanxian').findOne({ uid: call.uid });
|
||||
let cacheData = await G.ioredis.get(`tanxian:${call.uid}`);
|
||||
if (cacheData && cache) return JSON.parse(cacheData);
|
||||
let {_id, uid, ...data} = await G.mongodb.collection('tanxian').findOne({uid: call.uid});
|
||||
if (!data.eventTime) {
|
||||
data.eventTime = G.time;
|
||||
G.mongodb.collection('tanxian').updateOne({ uid: call.uid }, { $set: { eventTime: G.time } });
|
||||
G.mongodb.collection('tanxian').updateOne({uid: call.uid}, {$set: {eventTime: G.time}});
|
||||
}
|
||||
await G.ioredis.set(`tanxian:${call.uid}`, JSON.stringify(data));
|
||||
G.ioredis.setex(`tanxian:${call.uid}`, 600, JSON.stringify(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
/**获取快速探险次数 */
|
||||
static async getFastGuaJiNum(call: ApiCall) {
|
||||
let num = G.gc.tanxian_com.fastGuaJiNum + await TeQuanFun.getTxFreeNum(call);
|
||||
@ -38,9 +37,10 @@ export class TanXianFun {
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
/**获取最后领取奖励的id与sort后的数组*/
|
||||
static getLastMapId(receivePrizeConfId: string[]) {
|
||||
if(!receivePrizeConfId) receivePrizeConfId = []
|
||||
if (!receivePrizeConfId) receivePrizeConfId = []
|
||||
receivePrizeConfId = receivePrizeConfId.sort((a, b) => ~~a - ~~b);
|
||||
let receiveLastId = receivePrizeConfId.length > 0 ? receivePrizeConfId[receivePrizeConfId.length - 1] : '0';// 获取当前的领取进度
|
||||
return {receiveLastId, receivePrizeConfId}
|
||||
|
@ -838,6 +838,11 @@ export class TaskAllEmitFun {
|
||||
G.emit("Class_task_153", 'Class_task_153', node.call, _val, 0);
|
||||
}
|
||||
|
||||
if (node.call.service.name == 'event/yuandan/DMRec' && node.return.isSucc) {
|
||||
// 今日参与{1}次抓娃娃小游戏
|
||||
G.emit("Class_task_158", 'Class_task_158', node.call, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
if (node.call.eventMsg && node.call.eventMsg["msg_s2c/PeijianChange"] && node.call.eventMsg["msg_s2c/PeijianChange"]) {
|
||||
let _change = node.call.eventMsg["msg_s2c/PeijianChange"];
|
||||
|
@ -13,6 +13,7 @@ import {weixiuchangType} from "../shared/protocols/weixiuchang/type";
|
||||
import {FunWeiXiuChang} from "./weixiuchang";
|
||||
import {JJCFun} from "./jjc";
|
||||
import {getGud} from "./gud";
|
||||
import {Yuandanfun} from "../api_s2c/event/yuandan/fun";
|
||||
|
||||
let _classNameFunc = {}
|
||||
/**
|
||||
@ -76,6 +77,8 @@ export module manager {
|
||||
YangChengMuBiaofun.setTaskVal(call, this.stype, val, this.chkCall, chkval, this.isinc, this.alchangeVal, arg)
|
||||
// 圣诞活动任务计数
|
||||
Christmasfun.setTaskVal(call, this.stype, val, this.chkCall, chkval, this.isinc, this.alchangeVal, arg)
|
||||
// 元旦活动任务计数
|
||||
Yuandanfun.setTaskVal(call, this.stype, val, this.chkCall, chkval, this.isinc, this.alchangeVal, arg)
|
||||
}
|
||||
|
||||
// 任务数值, 和检测值,看情况需要上层复写
|
||||
@ -820,6 +823,16 @@ export module manager {
|
||||
}
|
||||
}
|
||||
|
||||
// 第60个任务 今日参与{1}次抓娃娃小游戏
|
||||
export class Class_task_158 extends BaseClass {
|
||||
stype = 158
|
||||
isinc = 1
|
||||
|
||||
async initVal(call: ApiCall, con) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -438,7 +438,12 @@ const crossIndexs: Partial<{ [k in keyof MongodbCollections]: IndexDescription[]
|
||||
{
|
||||
key: {zkey: 1}
|
||||
},
|
||||
]
|
||||
],
|
||||
huodong_user: [
|
||||
{
|
||||
key: {uid: 1}, unique: true,
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
export async function initMongoDB() {
|
||||
|
@ -28,6 +28,7 @@ import { addListener } from './globalListener';
|
||||
import { SchedulerManage } from './public/scheduler/scheduler';
|
||||
import {CrossEmailPull} from "./public/scheduler/scheduler_cross_email_pull";
|
||||
import {Scheduler_xfjs_Local_Ctor} from "./public/scheduler/scheduler_xiaofeijingsai";
|
||||
import { RankKfjs_1, RankKfjs_2, RankKfjs_3, RankKfjs_4, RankKfjs_5, RankKfjs_6, RankKfjs_7 } from './public/rank/rank_kfjs';
|
||||
export async function startAfter() {
|
||||
|
||||
//事件监听和定时器初始化
|
||||
@ -58,6 +59,14 @@ export async function startAfter() {
|
||||
new RankSlzd5();
|
||||
new RankSlzd6();
|
||||
|
||||
new RankKfjs_1();
|
||||
new RankKfjs_2();
|
||||
new RankKfjs_3();
|
||||
new RankKfjs_4();
|
||||
new RankKfjs_5();
|
||||
new RankKfjs_6();
|
||||
new RankKfjs_7();
|
||||
|
||||
new RankZccg();
|
||||
new RankTujian();
|
||||
|
||||
|
12
src/shared/protocols/event/yuandan/PtlDMRec.ts
Normal file
12
src/shared/protocols/event/yuandan/PtlDMRec.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import {prizeType} from "../../type";
|
||||
|
||||
/**
|
||||
* 元旦达摩领奖
|
||||
*/
|
||||
export type ReqDMRec = {
|
||||
id: 1 | 0
|
||||
}
|
||||
|
||||
export type ResDMRec = {
|
||||
prize: prizeType[]
|
||||
}
|
11
src/shared/protocols/event/yuandan/PtlDZRec.ts
Normal file
11
src/shared/protocols/event/yuandan/PtlDZRec.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* 元旦定制领奖
|
||||
*/
|
||||
export type ReqDZRec = {
|
||||
id: string
|
||||
dlz: { a: string, t: string, n: number }[]
|
||||
}
|
||||
|
||||
export type ResDZRec = {
|
||||
[k: string]: any;
|
||||
}
|
11
src/shared/protocols/event/yuandan/PtlExchange.ts
Normal file
11
src/shared/protocols/event/yuandan/PtlExchange.ts
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
/**
|
||||
* 元旦兑换领奖
|
||||
*/
|
||||
export type ReqExchange = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export type ResExchange = {
|
||||
|
||||
}
|
22
src/shared/protocols/event/yuandan/PtlOpen.ts
Normal file
22
src/shared/protocols/event/yuandan/PtlOpen.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 元旦
|
||||
*/
|
||||
export type ReqOpen = {}
|
||||
|
||||
export type ResOpen = {
|
||||
data: any
|
||||
payLog: any
|
||||
[k: string]: any;
|
||||
}
|
||||
|
||||
export type event = {
|
||||
qiandao: { [k: string]: any };
|
||||
gift: { [k: string]: any };
|
||||
taskfinish: string[];
|
||||
taskval: { [k: string]: any }
|
||||
exchange: { [k: string]: any }
|
||||
gameNum: number
|
||||
refreshTime: number;
|
||||
qiandaoTime: number;
|
||||
[k: string]: any;
|
||||
}
|
10
src/shared/protocols/event/yuandan/PtlTaskRec.ts
Normal file
10
src/shared/protocols/event/yuandan/PtlTaskRec.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* 元旦任务领奖
|
||||
*/
|
||||
export type ReqTaskRec = {
|
||||
taskid: string
|
||||
}
|
||||
|
||||
export type ResTaskRec = {
|
||||
[k: string]: any;
|
||||
}
|
12
src/shared/protocols/event/yuandan/PtlZLRec.ts
Normal file
12
src/shared/protocols/event/yuandan/PtlZLRec.ts
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* 元旦赠礼领奖
|
||||
*/
|
||||
export type ReqZLRec = {
|
||||
id: string,
|
||||
dlz: { a: string, t: string, n: number }[]
|
||||
}
|
||||
|
||||
export type ResZLRec = {
|
||||
[k: string]: any;
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
/**
|
||||
* 周末礼包领奖
|
||||
*/
|
||||
export interface ReqReceive {
|
||||
export type ReqReceive = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface ResReceive {
|
||||
export type ResReceive = {
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { prizeType } from '../../type';
|
||||
import {prizeType} from '../../type';
|
||||
|
||||
/**
|
||||
* 购买自选礼包
|
||||
@ -7,7 +7,7 @@ export type ReqBuy = {
|
||||
/**礼包index */
|
||||
index: number;
|
||||
/**礼包的每个奖励index */
|
||||
prizeIndex: number[];
|
||||
dlz: prizeType[]
|
||||
hdid: number
|
||||
};
|
||||
|
||||
|
@ -10,8 +10,8 @@ export type ReqOpen = {
|
||||
|
||||
export type ResOpen = {
|
||||
/**购买记录 */
|
||||
record: {
|
||||
[k: string]: number;
|
||||
rec: {
|
||||
[k: string]: any;
|
||||
};
|
||||
hdinfo: ReqAddHuoDong
|
||||
};
|
@ -54,7 +54,8 @@ export type hongdianKey =
|
||||
| 'zhoumolibao'
|
||||
| 'pobinglibao'
|
||||
| 'payForDiamond'
|
||||
| 'leichonglibao';
|
||||
| 'leichonglibao'
|
||||
|
||||
export type hongdianVal = {
|
||||
show?: boolean;
|
||||
// 看功能需要
|
||||
|
@ -20,6 +20,11 @@ export type payLog = {
|
||||
* @system 系统赠送
|
||||
*/
|
||||
type: 'user' | 'system' | 'legu';
|
||||
/**
|
||||
* 其他信息
|
||||
*/
|
||||
args?: any;
|
||||
|
||||
|
||||
/** G123 */
|
||||
popup_id?: string
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -141,6 +141,8 @@ export class HeroShared {
|
||||
}
|
||||
});
|
||||
|
||||
let sumLv = R.sum(pjs.map(i => i.lv))
|
||||
|
||||
for (let [suitId, data] of Object.entries(suitObj)) {
|
||||
|
||||
// //计算配件套装属性
|
||||
@ -149,7 +151,7 @@ export class HeroShared {
|
||||
// suitBuff.forEach(b => PublicShared.mergeProperty(buff, b[1]));
|
||||
|
||||
//计算配件大师属性
|
||||
let masterConf = Object.values(G.gc.peijian_master[suitId]).filter(c => c.lv <= data.minLv).sort((a, b) => b.lv - a.lv)[0];
|
||||
let masterConf = Object.values(G.gc.peijian_master[suitId]).filter(c => c.needLv <= sumLv).sort((a, b) => b.lv - a.lv)[0];
|
||||
if (masterConf) {
|
||||
let masterbuff = Object.entries(masterConf.buff).filter(v => Number(v[0]) <= data.num);
|
||||
masterbuff.forEach(b => PublicShared.mergeProperty(buff, b[1]));
|
||||
@ -236,7 +238,9 @@ export class HeroShared {
|
||||
let find = Object.entries(posObj).find(v => v[1] == hero._id);
|
||||
|
||||
if (find) {
|
||||
let __buff = G.gc.fightPlan[select][lv].buff[Number(find[0]) - 1];
|
||||
let maxLv = R.values(G.gc.fightPlan[select]).length - 1
|
||||
let fixLv = lv > maxLv ? maxLv : lv
|
||||
let __buff = G.gc.fightPlan[select][fixLv].buff[Number(find[0]) - 1];
|
||||
__buff && PublicShared.mergeProperty(buff, __buff);
|
||||
}
|
||||
}
|
||||
@ -280,6 +284,7 @@ export class HeroShared {
|
||||
let buffKey = k.replace('pro', '');
|
||||
if (buff[buffKey]) {
|
||||
buff[buffKey] += buff[buffKey] * buff[k];
|
||||
if (buffKey == 'baoshang' && buff[buffKey] > 10) buff[buffKey] = 10
|
||||
// buff[k] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ export class PublicShared {
|
||||
* 随机掉落组
|
||||
* @param id 掉落组id
|
||||
* @param num 随机次数
|
||||
* @param conf
|
||||
*/
|
||||
static randomDropGroup(id: string | number, num = 1, conf = G.gc.diaoluo): prizeType[] {
|
||||
let prize = [];
|
||||
@ -115,7 +116,7 @@ export class PublicShared {
|
||||
* 随机生成区间范围整数
|
||||
*/
|
||||
static randomNum(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
}
|
||||
/**获取道具配置 */
|
||||
static getAtnConf(atn: prizeType) {
|
||||
|
Loading…
Reference in New Issue
Block a user