初步加入寻宝匹配,逻辑还不全
This commit is contained in:
@@ -9,6 +9,7 @@ import { resResult, getRandomByLen, calculateNum } from '../../../pubUtils/util'
|
|||||||
import { RoleStatus } from '../../../db/ComBattleTeam';
|
import { RoleStatus } from '../../../db/ComBattleTeam';
|
||||||
import { ItemModel } from '../../../db/Item';
|
import { ItemModel } from '../../../db/Item';
|
||||||
import { handleReward } from '../../../services/rewardService';
|
import { handleReward } from '../../../services/rewardService';
|
||||||
|
import { getTeamSearchByQuality, setTeamSearchReq } from '../../../services/redisService';
|
||||||
|
|
||||||
export default function(app: Application) {
|
export default function(app: Application) {
|
||||||
return new ComBattleHandler(app);
|
return new ComBattleHandler(app);
|
||||||
@@ -35,6 +36,17 @@ class ComTeam {
|
|||||||
bossHp: number;
|
bossHp: number;
|
||||||
// 品质
|
// 品质
|
||||||
quality: number;
|
quality: number;
|
||||||
|
|
||||||
|
constructor(teamCode: string, pub: boolean, blueprtId: number, status: number, capId: string, ceLimit: number, bossHp: number, quality: number) {
|
||||||
|
this.teamCode = teamCode;
|
||||||
|
this.pub = pub;
|
||||||
|
this.blueprtId = blueprtId;
|
||||||
|
this.status = status;
|
||||||
|
this.capId = capId;
|
||||||
|
this.ceLimit = ceLimit;
|
||||||
|
this.bossHp = bossHp;
|
||||||
|
this.quality = quality;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export class ComBattleHandler {
|
export class ComBattleHandler {
|
||||||
constructor(private app: Application) {
|
constructor(private app: Application) {
|
||||||
@@ -54,7 +66,7 @@ export class ComBattleHandler {
|
|||||||
if (!goodData || goodData.itid !== IT_TYPE.BLUEPRT) return resResult(STATUS.COM_BATTLE_BLUEPRT_INVALID);
|
if (!goodData || goodData.itid !== IT_TYPE.BLUEPRT) return resResult(STATUS.COM_BATTLE_BLUEPRT_INVALID);
|
||||||
|
|
||||||
// 检查藏宝图是否足够
|
// 检查藏宝图是否足够
|
||||||
let { lv, headHid, topFiveCe, sHid } = await RoleModel.findByRoleId(roleId);
|
let { lv, headHid = 19, topFiveCe, sHid = 19 } = await RoleModel.findByRoleId(roleId);
|
||||||
if (lv < COM_TEAM_ENABLE_LV) return resResult(STATUS.COM_BATTLE_LV_NOT_ENOUGH);
|
if (lv < COM_TEAM_ENABLE_LV) return resResult(STATUS.COM_BATTLE_LV_NOT_ENOUGH);
|
||||||
|
|
||||||
let blueprt = await ItemModel.findbyRoleAndGidAndCount(roleId, blueprtId, 1);
|
let blueprt = await ItemModel.findbyRoleAndGidAndCount(roleId, blueprtId, 1);
|
||||||
@@ -62,48 +74,68 @@ export class ComBattleHandler {
|
|||||||
// 检查是否有已创建未结束的寻宝,预先占用一张藏宝图
|
// 检查是否有已创建未结束的寻宝,预先占用一张藏宝图
|
||||||
let teams = await ComBattleTeamModel.getTeamByCapAndStatus(roleId, COM_TEAM_STATUS.FIGHTING);
|
let teams = await ComBattleTeamModel.getTeamByCapAndStatus(roleId, COM_TEAM_STATUS.FIGHTING);
|
||||||
if (teams && blueprt.count <= teams.length) return resResult(STATUS.COM_BATTLE_BLUEPRT_NOT_ENOUGH);
|
if (teams && blueprt.count <= teams.length) return resResult(STATUS.COM_BATTLE_BLUEPRT_NOT_ENOUGH);
|
||||||
// TODO: 检查武将是否拥有
|
|
||||||
|
|
||||||
|
let roleStatus = [];
|
||||||
|
let roleIds = [];
|
||||||
|
roleIds.push(roleId);
|
||||||
|
let capStatus = new RoleStatus(roleId, roleName, true, false, headHid, sHid, topFiveCe, lv);
|
||||||
|
roleStatus.push(capStatus);
|
||||||
|
let teammates = await getTeamSearchByQuality(goodData.quality);
|
||||||
|
console.log('teammates: ', teammates);
|
||||||
|
if (teammates) {
|
||||||
|
for (let teammate of teammates) {
|
||||||
|
let roleInfo = await RoleModel.findByRoleId(teammate.roleId);
|
||||||
|
if (!roleInfo) continue;
|
||||||
|
// TODO: 没处理情谊助战
|
||||||
|
roleStatus.push(new RoleStatus(roleInfo.roleId, roleInfo.roleName, false, false, roleInfo.headHid, roleInfo.sHid, roleInfo.topFiveCe, roleInfo.lv));
|
||||||
|
roleIds.push(roleInfo.roleId);
|
||||||
|
}
|
||||||
|
}
|
||||||
// 创建队伍数据结构
|
// 创建队伍数据结构
|
||||||
let comTeam = new ComTeam();
|
let comTeam = new ComTeam(teamCode, pub, blueprtId, 0, roleId, ceLimit, getBossHpByBlueprtId(blueprtId) || 10000, goodData.quality);
|
||||||
comTeam.blueprtId = blueprtId;
|
comTeam.roleStatus = roleStatus;
|
||||||
comTeam.quality = goodData.quality;
|
comTeam.roleIds = roleIds;
|
||||||
comTeam.capId = roleId;
|
|
||||||
comTeam.pub = pub;
|
|
||||||
comTeam.teamCode = teamCode;
|
|
||||||
comTeam.roleIds = [roleId];
|
|
||||||
comTeam.status = COM_TEAM_STATUS.DEFAULT;
|
|
||||||
comTeam.ceLimit = ceLimit;
|
|
||||||
comTeam.bossHp = getBossHpByBlueprtId(blueprtId) || 10000;
|
|
||||||
|
|
||||||
let roleStatus = new RoleStatus();
|
|
||||||
roleStatus.heroes = heroes;
|
|
||||||
roleStatus.isCap = true;
|
|
||||||
roleStatus.headHid = headHid || 19;
|
|
||||||
roleStatus.topFiveCe = topFiveCe;
|
|
||||||
roleStatus.roleId = roleId;
|
|
||||||
roleStatus.isReady = true;
|
|
||||||
roleStatus.totalDmg = 0;
|
|
||||||
roleStatus.roleName = roleName;
|
|
||||||
roleStatus.lv = lv;
|
|
||||||
roleStatus.sHid = sHid || 19;
|
|
||||||
comTeam.roleStatus = [roleStatus];
|
|
||||||
|
|
||||||
this.teamMap.set(teamCode, comTeam);
|
this.teamMap.set(teamCode, comTeam);
|
||||||
|
|
||||||
|
// TODO: 处理助战回滚
|
||||||
const team = await ComBattleTeamModel.createTeam(comTeam);
|
const team = await ComBattleTeamModel.createTeam(comTeam);
|
||||||
if (!team) return resResult(STATUS.COM_BATTLE_CREATE_ERR);
|
if (!team) return resResult(STATUS.COM_BATTLE_CREATE_ERR);
|
||||||
|
|
||||||
let channelService = this.app.get('channelService');
|
let channelService = this.app.get('channelService');
|
||||||
let channel = channelService.getChannel(teamCode, true);
|
let channel = channelService.getChannel(teamCode, true);
|
||||||
let users = channel.getMembers();
|
let users = channel.getMembers();
|
||||||
if (users.indexOf(roleId) === -1) {
|
for (let roleId of roleIds) {
|
||||||
channel.add(roleId, sid);
|
if (users.indexOf(roleId) === -1) {
|
||||||
|
channel.add(roleId, sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (teammates) {
|
||||||
|
let uids = [];
|
||||||
|
for (let teammate of teammates) {
|
||||||
|
let { roleId, sid } = teammate;
|
||||||
|
uids.push({uid: roleId, sid});
|
||||||
|
}
|
||||||
|
// TODO: 处理助战 timer
|
||||||
|
channelService.pushMessageByUids('onTeamJoin', {teamInfo: comTeam}, uids);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resResult(STATUS.SUCCESS, { teamCode, roleStatus });
|
return resResult(STATUS.SUCCESS, { teamCode, roleStatus });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async searchTeam(msg: {qualityArr: [number]}, session: BackendSession) {
|
||||||
|
let roleId = session.get('roleId');
|
||||||
|
let sid = session.get('sid');
|
||||||
|
const { qualityArr } = msg;
|
||||||
|
let { lv, headHid = 19, topFiveCe, sHid = 19 } = await RoleModel.findByRoleId(roleId);
|
||||||
|
|
||||||
|
await setTeamSearchReq(roleId, sid, qualityArr);
|
||||||
|
setTimeout(() => {
|
||||||
|
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
async joinTeam(msg: {teamCode: string, isFrd: boolean}, session: BackendSession) {
|
async joinTeam(msg: {teamCode: string, isFrd: boolean}, session: BackendSession) {
|
||||||
let roleId = session.get('roleId');
|
let roleId = session.get('roleId');
|
||||||
let roleName = session.get('roleName');
|
let roleName = session.get('roleName');
|
||||||
@@ -113,7 +145,7 @@ export class ComBattleHandler {
|
|||||||
let teamStatus = this.teamMap.get(teamCode);
|
let teamStatus = this.teamMap.get(teamCode);
|
||||||
if (!teamStatus || teamStatus.status !== 0 || teamStatus.roleIds.length === 3) return resResult(STATUS.COM_BATTLE_MEMBER_LIMIT);
|
if (!teamStatus || teamStatus.status !== 0 || teamStatus.roleIds.length === 3) return resResult(STATUS.COM_BATTLE_MEMBER_LIMIT);
|
||||||
if (teamStatus.roleIds.indexOf(roleId) !== -1) return resResult(STATUS.COM_BATTLE_DUP_ENTER);
|
if (teamStatus.roleIds.indexOf(roleId) !== -1) return resResult(STATUS.COM_BATTLE_DUP_ENTER);
|
||||||
let { lv, headHid, topFiveCe, sHid } = await Role.findByRoleId(roleId);
|
let { lv, headHid = 19, topFiveCe = 0, sHid = 19 } = await Role.findByRoleId(roleId);
|
||||||
let { quality } = getGoodById(teamStatus.blueprtId);
|
let { quality } = getGoodById(teamStatus.blueprtId);
|
||||||
let { assistanceLevel, assistanceTime } = getComBtlSetByQuality(quality);
|
let { assistanceLevel, assistanceTime } = getComBtlSetByQuality(quality);
|
||||||
if (lv < COM_TEAM_ENABLE_LV) {
|
if (lv < COM_TEAM_ENABLE_LV) {
|
||||||
@@ -127,18 +159,7 @@ export class ComBattleHandler {
|
|||||||
let teams = await ComBattleTeamModel.getTeamByRoleAndTime(roleId, teamStatus.quality, new Date(new Date().setHours(0, 0, 0, 0)), true);
|
let teams = await ComBattleTeamModel.getTeamByRoleAndTime(roleId, teamStatus.quality, new Date(new Date().setHours(0, 0, 0, 0)), true);
|
||||||
if (teams.length >= assistanceTime) resResult(STATUS.COM_BATTLE_ASSIST_NOT_ENOUGH);
|
if (teams.length >= assistanceTime) resResult(STATUS.COM_BATTLE_ASSIST_NOT_ENOUGH);
|
||||||
|
|
||||||
let roleStatus = new RoleStatus();
|
let roleStatus = new RoleStatus(roleId, roleName, false, isFrd, headHid, sHid, topFiveCe, lv);
|
||||||
roleStatus.heroes = [];
|
|
||||||
roleStatus.isCap = false;
|
|
||||||
roleStatus.headHid = headHid || 19; // 默认给赵云
|
|
||||||
roleStatus.topFiveCe = topFiveCe || 0;
|
|
||||||
roleStatus.roleId = roleId;
|
|
||||||
roleStatus.roleName = roleName;
|
|
||||||
roleStatus.isFrd = isFrd;
|
|
||||||
roleStatus.isReady = false;
|
|
||||||
roleStatus.totalDmg = 0;
|
|
||||||
roleStatus.lv = lv;
|
|
||||||
roleStatus.sHid = sHid || 19;
|
|
||||||
const team = await ComBattleTeamModel.addRole(teamCode, roleStatus);
|
const team = await ComBattleTeamModel.addRole(teamCode, roleStatus);
|
||||||
if (!team) {
|
if (!team) {
|
||||||
return resResult(STATUS.COM_BATTLE_CREATE_ERR);
|
return resResult(STATUS.COM_BATTLE_CREATE_ERR);
|
||||||
|
|||||||
@@ -1,23 +1,40 @@
|
|||||||
|
import { GOOD_QUALITY } from './../consts/consts';
|
||||||
import { RoleModel } from "../db/Role";
|
import { RoleModel } from "../db/Role";
|
||||||
import * as redis from 'redis';
|
import * as Redis from 'redis';
|
||||||
import {REDIS_KEY} from '../consts/consts'
|
import {REDIS_KEY} from '../consts/consts'
|
||||||
import { GameModel } from "../db/Game";
|
import { GameModel } from "../db/Game";
|
||||||
import { exists } from "fs";
|
import { promisifyAll } from 'bluebird';
|
||||||
|
|
||||||
|
// 映射 redis 接口
|
||||||
|
declare module 'redis' {
|
||||||
|
export interface RedisClient extends NodeJS.EventEmitter {
|
||||||
|
hdelAsync(...args: any[]): Promise<any>;
|
||||||
|
spopAsync(...args: any[]): Promise<any>;
|
||||||
|
sremAsync(...args: any[]): Promise<any>;
|
||||||
|
srandmemberAsync(...args: any[]): Promise<any>;
|
||||||
|
}
|
||||||
|
export interface Multi extends Commands<Multi> {
|
||||||
|
execAsync(...args: any[]): Promise<any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let redisArr = 'r-8vb4i2kgl91886fkxd.redis.zhangbei.rds.aliyuncs.com';
|
let redisArr = 'r-8vb4i2kgl91886fkxd.redis.zhangbei.rds.aliyuncs.com';
|
||||||
if(process.env.NODE_ENV == 'local') {
|
if(process.env.NODE_ENV == 'local') {
|
||||||
redisArr = '127.0.0.1';
|
redisArr = '127.0.0.1';
|
||||||
}
|
}
|
||||||
// 创建 redis 连接
|
// 创建 redis 连接
|
||||||
const client = redis.createClient(6379, redisArr, {detect_buffers: true});
|
const oldRedisClient = Redis.createClient(6379, redisArr, {detect_buffers: true});
|
||||||
client.auth('zyz_2020', (err, reply) => {
|
oldRedisClient.auth('zyz_2020', (err, reply) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('redis err', err);
|
console.log('redis err', err);
|
||||||
} else {
|
} else {
|
||||||
console.log('redis suc');
|
console.log('redis suc');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
client.set('hello', 'redis', redis.print);
|
|
||||||
|
// 转 promise
|
||||||
|
const client = promisifyAll(oldRedisClient) as Redis.RedisClient;
|
||||||
|
client.set('hello', 'redis', Redis.print);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在服务重新启动时,将信息存入redis
|
* 在服务重新启动时,将信息存入redis
|
||||||
@@ -118,6 +135,49 @@ function decodeScoreWithTime(num: string): number {
|
|||||||
return Math.floor(_num/pow);
|
return Math.floor(_num/pow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************** 寻宝相关 start */
|
||||||
|
|
||||||
|
// 把寻宝的玩家信息存入 redis
|
||||||
|
export async function setTeamSearchReq(roleId: string, sid: string, qualityArr: Array<number>) {
|
||||||
|
let cmds = [];
|
||||||
|
qualityArr.forEach(quality => {
|
||||||
|
if (quality) {
|
||||||
|
cmds.push(['sadd', `${REDIS_KEY.COM_TEAM_SEARCH_PRE}${quality}`, `${roleId}:${sid}`]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const multiClient = client.multi(cmds) as Redis.Multi;
|
||||||
|
const newMulti = promisifyAll(multiClient) as Redis.Multi;
|
||||||
|
const res = await newMulti.execAsync();
|
||||||
|
console.log('setTeamSearchReq: ', res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取出 0 - 2 个某品质的匹配中玩家,并在其它品质中删除此玩家信息
|
||||||
|
export async function getTeamSearchByQuality(quality: number) {
|
||||||
|
// TODO: 操作不具有原子性
|
||||||
|
const userInfos = await client.srandmemberAsync(`${REDIS_KEY.COM_TEAM_SEARCH_PRE}${quality}`, 2);
|
||||||
|
console.log('getTeamSearchByQuality: ' + userInfos);
|
||||||
|
if (!userInfos || !userInfos.length) return null;
|
||||||
|
|
||||||
|
let cmds = [];
|
||||||
|
let res = [];
|
||||||
|
for (let userInfo of userInfos) {
|
||||||
|
const decodeData = `${userInfo}`.split(':');
|
||||||
|
if (decodeData.length !== 2) return null;
|
||||||
|
|
||||||
|
res.push({roleId: decodeData[0], sid: decodeData[1]});
|
||||||
|
GOOD_QUALITY.forEach((q) => {
|
||||||
|
cmds.push(['srem', `${REDIS_KEY.COM_TEAM_SEARCH_PRE}${q}`, userInfo]);
|
||||||
|
})
|
||||||
|
const multiClient = client.multi(cmds) as Redis.Multi;
|
||||||
|
const newMulti = promisifyAll(multiClient) as Redis.Multi;
|
||||||
|
await newMulti.execAsync();
|
||||||
|
}
|
||||||
|
console.log('getTeamSearchByQuality res: ', res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************** 寻宝相关 end */
|
||||||
|
|
||||||
////// redis方法
|
////// redis方法
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export const IT_TYPE = {
|
|||||||
BLUEPRT: 28
|
BLUEPRT: 28
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const GOOD_QUALITY = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
// 大类型,区分存到哪张表里
|
// 大类型,区分存到哪张表里
|
||||||
export const GOOD_TYPE = {
|
export const GOOD_TYPE = {
|
||||||
EQUIP: 1,
|
EQUIP: 1,
|
||||||
@@ -284,13 +286,14 @@ export const COM_BATTLE_ROBOT_HURT_RATE = 0.4;
|
|||||||
// 每个机器人消耗 boss 血量百分比浮动范围
|
// 每个机器人消耗 boss 血量百分比浮动范围
|
||||||
export const COM_BATTLE_ROBOT_HURT_RAND_RATE = 0.05;
|
export const COM_BATTLE_ROBOT_HURT_RAND_RATE = 0.05;
|
||||||
// 每日情谊点上限
|
// 每日情谊点上限
|
||||||
export const COM_BATTLE_FRDCNT_MAX = 100;
|
export const COM_BATTLE_FRDCNT_MAX = 150;
|
||||||
// 情谊点掉落数量
|
// 情谊点掉落数量
|
||||||
export const COM_BATTLE_FRDCNT_DROP = 10;
|
export const COM_BATTLE_FRDCNT_DROP = 10;
|
||||||
|
|
||||||
export const REDIS_KEY = {
|
export const REDIS_KEY = {
|
||||||
USER_INFO: "userInfo", // 玩家缓存信息
|
USER_INFO: "userInfo", // 玩家缓存信息
|
||||||
TOWER_RANK: "towerRank" // 天梯排行榜
|
TOWER_RANK: "towerRank", // 天梯排行榜
|
||||||
|
COM_TEAM_SEARCH_PRE: 'comTeamSerQ', // 匹配中的玩家,按品质分
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FUNC_OPT_TYPE = {
|
export const FUNC_OPT_TYPE = {
|
||||||
|
|||||||
@@ -40,6 +40,20 @@ export class RoleStatus {
|
|||||||
// 主公等级
|
// 主公等级
|
||||||
@prop({ required: true, default: 1 })
|
@prop({ required: true, default: 1 })
|
||||||
lv: number;
|
lv: number;
|
||||||
|
|
||||||
|
constructor(roleId: string, roleName: string, isCap: boolean, isFrd: boolean, headHid: number, sHid: number, topFiveCe: number, lv: number) {
|
||||||
|
this.roleId = roleId;
|
||||||
|
this.roleName = roleName;
|
||||||
|
this.isCap = isCap;
|
||||||
|
this.totalDmg = 0;
|
||||||
|
this.isFrd = isFrd;
|
||||||
|
this.headHid = headHid;
|
||||||
|
this.sHid = sHid;
|
||||||
|
this.topFiveCe = topFiveCe;
|
||||||
|
this.lv = lv;
|
||||||
|
this.heroes = [];
|
||||||
|
this.killed = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@index({ teamCode: 1 })
|
@index({ teamCode: 1 })
|
||||||
|
|||||||
Reference in New Issue
Block a user