邮件,异地登录bug
This commit is contained in:
@@ -111,7 +111,6 @@ export class PvpHandler {
|
||||
let checkHeroes = await checkBattleHeroesByHid(roleId, heroes);
|
||||
if(!checkHeroes) return resResult(STATUS.BATTLE_HERO_NOT_FOUND);
|
||||
|
||||
|
||||
const pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
|
||||
if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
|
||||
// 检查挑战次数
|
||||
@@ -196,7 +195,7 @@ export class PvpHandler {
|
||||
$set: { status: isSuccess?1:2 }
|
||||
}, true);
|
||||
|
||||
// 增加挑战次数
|
||||
// 减少挑战次数
|
||||
let { challengeCnt, challengeRefTime } = comsumeChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, pvpDefense.seasonEndTime);
|
||||
if ( hisScore < score) {
|
||||
hisScore = score;
|
||||
@@ -371,16 +370,13 @@ export class PvpHandler {
|
||||
}
|
||||
receivedBox.push(id);
|
||||
let { challengeCnt, challengeRefTime } = refresh(lastChallengeCnt, lastChallengeRefTime, seasonEndTime);
|
||||
|
||||
await PvpDefenseModel.updateInfo(roleId, {receivedBox, challengeCnt, challengeRefTime});
|
||||
|
||||
let result = await addItems(roleId, roleName, sid, pvpBox.reward );
|
||||
return resResult(STATUS.SUCCESS,{goods: result, receivedBox, challengeCnt, challengeRefTime});
|
||||
}
|
||||
|
||||
async getRec(msg: {}, session: BackendSession ) {
|
||||
let roleId = session.get('roleId');
|
||||
let roleName = session.get('roleName');
|
||||
let pvpRecords = await PvpRecordModel.getRecByRoleId(roleId);
|
||||
return resResult(STATUS.SUCCESS, {list: pvpRecords});
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { getAp } from '../../../services/actionPointService';
|
||||
import { ItemModel } from '../../../db/Item';
|
||||
import { chackFunOpenWhenLogin } from '../../../services/funcSwitchService';
|
||||
import { loginRefresh } from '../../../services/playerEventService';
|
||||
import { getRedis, setRedis } from '../../../services/redisService';
|
||||
export default function (app: Application) {
|
||||
return new EntryHandler(app);
|
||||
}
|
||||
@@ -29,7 +30,6 @@ export class EntryHandler {
|
||||
async enter(msg: { token: string, serverId: number }, session: FrontendSession) {
|
||||
let self = this;
|
||||
let serverId = msg.serverId;
|
||||
let sessionService = self.app.get('sessionService');
|
||||
|
||||
let user = await UserModel.findUserByToken(msg.token);
|
||||
if (!user) {
|
||||
@@ -41,8 +41,13 @@ export class EntryHandler {
|
||||
if (!role) {
|
||||
return resResult(STATUS.ROLE_NOT_FOUND);
|
||||
}
|
||||
self.remoteLogin(role.roleId);
|
||||
await sessionService.akick(role.roleId);//
|
||||
let key = 'login_roleId_' + role.roleId;
|
||||
let connect = await getRedis(key);
|
||||
if (!!connect) {
|
||||
self.app.rpc.connector.connectorRemote.remoteLogin.toServer(connect, role.roleId);
|
||||
}
|
||||
let serverName = this.app.getServerId();
|
||||
setRedis(key, serverName);
|
||||
await session.abind(role.roleId);
|
||||
session.set('uid', role.roleId);
|
||||
session.set('roleId', role.roleId);
|
||||
@@ -88,21 +93,10 @@ export class EntryHandler {
|
||||
role['apJson'] = apJson;
|
||||
role['ce'] = reduceCe(role.ce);
|
||||
role['topFiveCe'] = reduceCe(role.topFiveCe);
|
||||
|
||||
return resResult(STATUS.SUCCESS, { role });
|
||||
}
|
||||
|
||||
remoteLogin(uid: string) {
|
||||
let sessionService = this.app.get('sessionService');
|
||||
let sessions = sessionService.getByUid(uid);
|
||||
if (!!sessions) {
|
||||
sessions.forEach(session=>{
|
||||
let roleId = session.get('roleId');
|
||||
let sid = session.get('sid');
|
||||
let uids = [{uid: roleId, sid}];
|
||||
this.app.get('channelService').pushMessageByUids('onRemoteLogin', resResult(STATUS.LOGIN_ERR ), uids);
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* User log out handler
|
||||
*
|
||||
|
||||
29
game-server/app/servers/connector/remote/connectorRemote.ts
Normal file
29
game-server/app/servers/connector/remote/connectorRemote.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Application, ChannelService, FrontendSession, RemoterClass } from 'pinus';
|
||||
import { STATUS } from '../../../consts/statusCode';
|
||||
import { resResult } from '../../../pubUtils/util';
|
||||
export default function (app: Application) {
|
||||
return new ConnectorRemote(app);
|
||||
}
|
||||
|
||||
export class ConnectorRemote {
|
||||
|
||||
constructor(private app: Application) {
|
||||
this.app = app;
|
||||
this.channelService = app.get('channelService');
|
||||
}
|
||||
private channelService: ChannelService;
|
||||
|
||||
public async remoteLogin(uid: string) {
|
||||
let sessionService = this.app.get('sessionService');
|
||||
let sessions = sessionService.getByUid(uid);
|
||||
if (!!sessions) {
|
||||
sessions.forEach(session=>{
|
||||
let roleId = session.get('roleId');
|
||||
let sid = session.get('sid');
|
||||
let uids = [{uid: roleId, sid}];
|
||||
this.channelService.pushMessageByUids('onRemoteLogin', resResult(STATUS.LOGIN_ERR ), uids);
|
||||
});
|
||||
}
|
||||
await sessionService.akick(uid);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Application, ChannelService, FrontendSession, RemoterClass } from 'pinus';
|
||||
|
||||
import { STATUS } from '../../../consts/statusCode';
|
||||
import { resResult } from '../../../pubUtils/util';
|
||||
export default function (app: Application) {
|
||||
return new RoleRemote(app);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { FrontendSession, RemoterClass } from 'pinus';
|
||||
import { ChatRemote } from './chat/remote/chatRemote';
|
||||
import { ComBattleRemote } from './battle/remote/comBattleRemote';
|
||||
import { BattleRemote } from './battle/remote/battleRemote';
|
||||
import { ConnectorRemote } from './connector/remote/connectorRemote';
|
||||
|
||||
declare global {
|
||||
interface UserRpc {
|
||||
@@ -16,5 +17,8 @@ declare global {
|
||||
comBattleRemote: RemoterClass<FrontendSession, ComBattleRemote>;
|
||||
battleRemote: RemoterClass<FrontendSession, BattleRemote>;
|
||||
};
|
||||
connector: {
|
||||
connectorRemote: RemoterClass<FrontendSession, ConnectorRemote>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
/**
|
||||
* 体力系统
|
||||
*/
|
||||
|
||||
import { fromCallback } from 'bluebird';
|
||||
import { checkPvp, findPvpDefByRoleId } from '../services/pvpService'
|
||||
import { getFuncsSwitch } from '../pubUtils/data';
|
||||
|
||||
@@ -224,4 +224,14 @@ export async function clearComBtlQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
export function setRedis(key: string, data: string) {
|
||||
const client: Redis.RedisClient = pinus.app.get('redis');
|
||||
client.setAsync(key, data);
|
||||
}
|
||||
|
||||
export async function getRedis(key: string) {
|
||||
const client: Redis.RedisClient = pinus.app.get('redis');
|
||||
const str = await client.getAsync(key);
|
||||
return str;
|
||||
}
|
||||
/**************** 寻宝相关 end */
|
||||
|
||||
@@ -10,8 +10,11 @@ import { nowSeconds, getTodayZeroPoint } from '../pubUtils/timeUtil';
|
||||
import { getPvpGkWarIds, getPvpRankRewards, getPvpHeroRewards } from '../pubUtils/data';
|
||||
import { getRandomArr } from '../pubUtils/util';
|
||||
import { getLvByScore } from './pvpService';
|
||||
import { getMyRank } from './redisService';
|
||||
import { getMyRank, setRank } from './redisService';
|
||||
import { REDIS_KEY } from '../consts';
|
||||
import { RankParam } from '../pubUtils/interface';
|
||||
import { RoleModel } from '../db/Role';
|
||||
import { MailModel, MailType } from '../db/Mail';
|
||||
const _ = require('underscore');
|
||||
const PER_SECOND = 1 * 1000;
|
||||
const PER_DAY = 24 * 60 * 60;
|
||||
@@ -42,15 +45,36 @@ export async function init() {
|
||||
export async function setPvpSeasonResult(obj:{ name:string }) {
|
||||
console.log('exce setPvpSeasonResult'+ obj.name);
|
||||
let { seasonNum, seasonEndTime } = await setNextPvpTime();
|
||||
let pvpDefenses = await PvpDefenseModel.getPvpDef(LIMIT_NUM);
|
||||
for (let pvpDefense of pvpDefenses) {
|
||||
if (pvpDefense.seasonNum !== seasonNum) {
|
||||
await setPvpDefResult(pvpDefense, seasonNum, seasonEndTime);
|
||||
for (let page = 0; page < 3; page++) {
|
||||
let pvpDefenses = await PvpDefenseModel.getPvpDef(500, page);
|
||||
let addMails = new Array<MailType>();
|
||||
for (let pvpDefense of pvpDefenses) {
|
||||
if (pvpDefense.seasonNum !== seasonNum) {
|
||||
await setPvpDefResultOnTime(pvpDefense, seasonNum, seasonEndTime, addMails);
|
||||
}
|
||||
}
|
||||
await MailModel.addMails(addMails);
|
||||
}
|
||||
}
|
||||
|
||||
export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime:number) {
|
||||
export async function setPvpDefResultOnTime(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime:number, addMails: Array<MailType>) {
|
||||
let role = await RoleModel.findByRoleId(pvpDefense.roleId);
|
||||
if (!role) {
|
||||
return;
|
||||
}
|
||||
let {score, pLv, heroScores, winStreakNum, challengeCnt, challengeRefTime, goods } = await checkResult(pvpDefense, seasonNum, seasonEndTime);
|
||||
pvpDefense = await PvpDefenseModel.updateInfo(pvpDefense.roleId, {score:score, pLv, heroScores, winStreakNum, seasonNum, challengeCnt, challengeRefTime, seasonEndTime});
|
||||
let { roleName, lv, vLv, headHid, sHid, title } = role;
|
||||
let params = new RankParam(roleName, lv, vLv, headHid, sHid, title);
|
||||
setRank(REDIS_KEY.PVP_RANK, 0, pvpDefense.roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), params);
|
||||
//下发邮件
|
||||
const doc = new MailModel();
|
||||
const mail = Object.assign(doc.toJSON(), { goods, sendName: '系统', mailId: 1, sendTime: nowSeconds()});
|
||||
addMails.push(mail);
|
||||
return pvpDefense;
|
||||
}
|
||||
|
||||
export async function checkResult(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime:number) {
|
||||
let pvpRankRewards = getPvpRankRewards();
|
||||
let pvpHeroRewards = getPvpHeroRewards();
|
||||
let goods = [];
|
||||
@@ -70,8 +94,22 @@ export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: num
|
||||
score += heroScore.score;
|
||||
}
|
||||
let pLv = getLvByScore(pvpDefense.heroScores);
|
||||
pvpDefense = await PvpDefenseModel.updateInfo(pvpDefense.roleId, {score:score, pLv, heroScores: pvpDefense.heroScores, winStreakNum:0, seasonNum, challengeCnt:PVP.PVP_CHALLENGE_COUNTS, challengeRefTime:0, seasonEndTime});
|
||||
//TODO 下发邮件
|
||||
return {score, pLv, heroScores: pvpDefense.heroScores, winStreakNum:0, seasonNum, challengeCnt:PVP.PVP_CHALLENGE_COUNTS, challengeRefTime:0, seasonEndTime, goods};
|
||||
}
|
||||
|
||||
export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime:number) {
|
||||
let role = await RoleModel.findByRoleId(pvpDefense.roleId);
|
||||
if (!role) {
|
||||
return;
|
||||
}
|
||||
let {score, pLv, heroScores, winStreakNum, challengeCnt, challengeRefTime, goods } = await checkResult(pvpDefense, seasonNum, seasonEndTime);
|
||||
pvpDefense = await PvpDefenseModel.updateInfo(pvpDefense.roleId, {score:score, pLv, heroScores, winStreakNum, seasonNum, challengeCnt, challengeRefTime, seasonEndTime});
|
||||
let { roleName, lv, vLv, headHid, sHid, title } = role;
|
||||
let params = new RankParam(roleName, lv, vLv, headHid, sHid, title);
|
||||
setRank(REDIS_KEY.PVP_RANK, 0, pvpDefense.roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), params);
|
||||
//下发邮件
|
||||
let sendTime = seasonEndTime - PVP.PVP_SEASON_DAYS * PER_DAY + SETTLE_DIFF;
|
||||
await MailModel.addMail({ goods, sendName: '系统', mailId: 1, sendTime: sendTime});
|
||||
return pvpDefense;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,12 @@ declare module 'redis' {
|
||||
delAsync(key: string): Promise<number>;
|
||||
// 设置过期时间
|
||||
expireAsync(key: string, time: number): Promise<number>;
|
||||
|
||||
// string类型存储
|
||||
setexAsync(key: string, time: number, value: string): Promise<number>;
|
||||
// 获取存储string类型value
|
||||
getAsync(key: string): Promise<string>;
|
||||
// 获取存储string类型value
|
||||
setAsync(key: string, value: string): Promise<number>;
|
||||
// 删除哈希表 key 中的一个或多个指定字段
|
||||
hdelAsync(key: string, field: string): Promise<number>;
|
||||
// 将哈希表 key 中的字段 field 的值设为 value
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||||
const _ = require('underscore');
|
||||
// const Transaction = require('mongoose-transactions');
|
||||
// const Transaction = require("mongoose-transactions");
|
||||
@index({ roleId: 1, id: 1 })
|
||||
@index({ seqId: 1 })
|
||||
@modelOptions({ schemaOptions: { id: false } })
|
||||
@@ -86,14 +86,8 @@ export default class Item extends BaseModel {
|
||||
// let hasError: boolean = false, result = new Array();
|
||||
// try {
|
||||
// for (let { id, count, ratio } of items) {
|
||||
// if (ratio) ratio = -1;
|
||||
// await transaction.update({ roleId, id, count: { $gte: count } }, { $inc: { count: ratio * count } }, { new: true});
|
||||
// const rec: ItemType = await transaction.findOneAndUpdate({ roleId, id, count: { $gte: count } }, { $inc: { count: ratio * count } }, { new: true}).lean(lean);
|
||||
// if (!!rec) {
|
||||
// result.push({ id: rec.id, count: rec.count });
|
||||
// } else {
|
||||
// hasError = true; break;
|
||||
// }
|
||||
// if (!ratio) ratio = -1;
|
||||
// await transaction.update("Item", { roleId, id, count: { $gte: count } }, { $inc: { count: ratio * count } }, { new: true});
|
||||
// }
|
||||
// await transaction.run();
|
||||
// return {hasError, result};
|
||||
|
||||
41
shared/db/Mail.ts
Normal file
41
shared/db/Mail.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { RewardInter } from '../pubUtils/interface';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
|
||||
@index({ roleId: 1 })
|
||||
|
||||
export default class Mail extends BaseModel {
|
||||
@prop({ required: true })
|
||||
roleId: number;
|
||||
|
||||
@prop({ required: true })
|
||||
seqId: number;
|
||||
|
||||
@prop({ required: true })
|
||||
mailId: number;
|
||||
|
||||
@prop({ required: true })
|
||||
goods: Array<RewardInter>;
|
||||
|
||||
@prop({ required: true, default: nowSeconds() })
|
||||
sendTime: number;
|
||||
|
||||
@prop({ required: true })
|
||||
sendName: string;
|
||||
|
||||
public static async addMails( mails: Array<MailType>) {
|
||||
await MailModel.insertMany(mails);
|
||||
}
|
||||
|
||||
public static async addMail(params:{ goods: Array<RewardInter>, sendName: string, mailId: number, sendTime?: number}) {
|
||||
const doc = new MailModel();
|
||||
const mail = Object.assign(doc.toJSON(), params);
|
||||
const mailInfo: MailType = await MailModel.create(mail);
|
||||
return mailInfo;
|
||||
}
|
||||
}
|
||||
|
||||
export const MailModel = getModelForClass(Mail);
|
||||
|
||||
export interface MailType extends Pick<DocumentType<Mail>, keyof Mail> { };
|
||||
@@ -233,14 +233,14 @@ export default class PvpDefense extends BaseModel {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async getPvpDef(limitNum: number, lean = true) {
|
||||
let result: Array<PvpDefenseType> = await PvpDefenseModel.find().sort({ score: -1 }).limit(limitNum).lean(lean);
|
||||
public static async getPvpDef(limit: number, page: number, lean = true) {
|
||||
let result: Array<PvpDefenseType> = await PvpDefenseModel.find().sort({ score: -1 }).limit(limit).skip((page) * limit).lean(lean);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async getRank(page = 1, limit = 1000, lean = true) {
|
||||
let sortBy = { score: -1, updatedAt: 1 };
|
||||
const ranks: PvpDefenseType[] = await PvpDefenseModel.find().limit(limit).skip(page - 1).select('roleId role score updatedAt')
|
||||
const ranks: PvpDefenseType[] = await PvpDefenseModel.find().select('roleId role score updatedAt')
|
||||
.populate('role', 'roleId roleName headHid sHid title lv vLv')
|
||||
.sort(sortBy).limit(limit).skip((page - 1) * limit).lean(lean);
|
||||
return ranks;
|
||||
|
||||
Reference in New Issue
Block a user