Merge branch 'feature/login'
Conflicts: game-server/app/servers/role/handler/heroHandler.ts game-server/app/services/redisService.ts shared/consts/index.ts shared/resource/jsons/dic_zyz_gk_main.json
This commit is contained in:
@@ -4,9 +4,6 @@
|
||||
* 属性 id
|
||||
*/
|
||||
|
||||
|
||||
import { JOB_TYPE } from "..";
|
||||
|
||||
export enum ABI_TYPE{
|
||||
/**生命 */
|
||||
ABI_HP = 1,
|
||||
@@ -41,12 +38,33 @@ export enum ABI_TYPE{
|
||||
ABI_DEF_IGNORE = 15,
|
||||
/**吸血等级 */
|
||||
ABI_BLOOD_SUCK = 16,
|
||||
/**怒气 */
|
||||
/**怒气恢复效果 */
|
||||
ABI_AP = 17,
|
||||
/**暴击伤害 */
|
||||
ABI_DAMAGE_CRI = 18,
|
||||
|
||||
ABI_MAX,
|
||||
}
|
||||
|
||||
// 主属性
|
||||
export const ABI_TYPE_MAIN = [
|
||||
ABI_TYPE.ABI_HP,
|
||||
ABI_TYPE.ABI_ATK,
|
||||
ABI_TYPE.ABI_DEF,
|
||||
ABI_TYPE.ABI_MDEF
|
||||
];
|
||||
|
||||
// 次级属性
|
||||
export const ABI_TYPE_SUB = [
|
||||
ABI_TYPE.ABI_HIT,
|
||||
ABI_TYPE.ABI_CRI,
|
||||
ABI_TYPE.ABI_FLEE,
|
||||
ABI_TYPE.ABI_ANT_CRI,
|
||||
ABI_TYPE.ABI_DAMAGE_INCREASE,
|
||||
ABI_TYPE.ABI_DAMAGE_DECREASE,
|
||||
ABI_TYPE.ABI_DEF_IGNORE,
|
||||
ABI_TYPE.ABI_DAMAGE_CRI
|
||||
];
|
||||
|
||||
export enum SEID_TYPE {
|
||||
/**属性固定值加成(数值) */
|
||||
@@ -63,39 +81,10 @@ export enum ABI_STAGE {
|
||||
ATK = 2,
|
||||
DEF = 3,
|
||||
MDEF = 4,
|
||||
AGI = 5,
|
||||
LUK = 6,
|
||||
END = 6
|
||||
END = 4
|
||||
}
|
||||
|
||||
export const ATTR = {}
|
||||
//武将训练等级
|
||||
export const HEROTARIN = {
|
||||
1: "hp",
|
||||
2: "atk",
|
||||
3: "def",
|
||||
4: "mdef",
|
||||
5: "agi",
|
||||
6: "luk"
|
||||
};
|
||||
//战力系数
|
||||
export const CE_RATIO = {
|
||||
"hp" : 1,
|
||||
"atk" : 2,
|
||||
"matk": 2,
|
||||
"def": 2,
|
||||
"mdef": 2,
|
||||
"agi": 2,
|
||||
"luk": 0,
|
||||
"hit": 0,
|
||||
"cri": 0,
|
||||
"flee": 0,
|
||||
"antCri": 0,
|
||||
"damageIncrease": 0,
|
||||
"damageDecrease": 0,
|
||||
"defIngnore": 0,
|
||||
"bloodSuck": 0,
|
||||
};
|
||||
|
||||
export const HERO_ATTR = {
|
||||
1: "hp", // 生命
|
||||
@@ -114,44 +103,30 @@ export const HERO_ATTR = {
|
||||
14: "damageDecrease", // 伤害减免等级
|
||||
15: "defIngnore", // 忽视防御等级
|
||||
16: "bloodSuck", // 吸血等级
|
||||
17: "ap" // 怒气
|
||||
17: "damageCri", // 暴击伤害
|
||||
18: "ap" // 暴击伤害
|
||||
};
|
||||
|
||||
export const JEWEL_ATTR = {
|
||||
1: "hp",
|
||||
2: "atk",
|
||||
3: "def",
|
||||
4: "mdef",
|
||||
5: "agi",
|
||||
6: "luk"
|
||||
}
|
||||
const BASE_ATTR = {
|
||||
'hp' : 1 ,
|
||||
'atk' : 2,
|
||||
'def' : 3,
|
||||
'mdef' : 4
|
||||
}
|
||||
export const ABI_TYPE_TO_STAGE = new Map<number, number | ((jobType: number) => number)>([
|
||||
export const ABI_TYPE_TO_STAGE = new Map<number, number>([
|
||||
[ABI_STAGE.HP, ABI_TYPE.ABI_HP],
|
||||
[ABI_STAGE.ATK, (jobType:number) => { return jobType == JOB_TYPE.PHYSIC?ABI_TYPE.ABI_ATK: ABI_TYPE.ABI_MATK}],
|
||||
[ABI_STAGE.ATK, ABI_TYPE.ABI_ATK],
|
||||
[ABI_STAGE.DEF, ABI_TYPE.ABI_DEF],
|
||||
[ABI_STAGE.MDEF, ABI_TYPE.ABI_MDEF],
|
||||
[ABI_STAGE.AGI, ABI_TYPE.ABI_AGI],
|
||||
[ABI_STAGE.LUK, ABI_TYPE.ABI_LUK]
|
||||
[ABI_STAGE.MDEF, ABI_TYPE.ABI_MDEF]
|
||||
]);
|
||||
|
||||
export function getAtrrNameById(attrId: number):string {
|
||||
return HERO_ATTR[attrId];
|
||||
};
|
||||
|
||||
export function getAttrCeRatio(attr: string):number {
|
||||
return CE_RATIO[attr];
|
||||
};
|
||||
|
||||
export function getAttrNameByJobStage(jobStage: number) {
|
||||
return HEROTARIN[jobStage];
|
||||
};
|
||||
|
||||
export function getTeraphAttr() {
|
||||
return BASE_ATTR;
|
||||
};
|
||||
export enum CE_CONST {
|
||||
FLEE_VALUE = 0.3, // 格挡价值
|
||||
PUT_HIT = 50000, // 投放总命中
|
||||
HIT_RATE_BASE = 0.75, // 命中率基础
|
||||
HIT_RATE_MAX = 1, // 命中率上限
|
||||
HIT_RATE_MIN = 0, // 命中率下限
|
||||
PUT_ANT_CRI = 50000, // 投放总抗暴
|
||||
CRI_RATE_BASE = 0.05, // 暴击率基础
|
||||
CRI_RATE_MAX = 0.75, // 暴击率上限
|
||||
CRI_RATE_MIN = 0.05, // 暴击率下限
|
||||
CRI_VALUE_BASE = 1.5, // 暴击价值基础
|
||||
}
|
||||
@@ -14,7 +14,3 @@ export const GOLD_COST_RATIO = {
|
||||
"DAILY_REF_NUM": { "A": 50, "B": 0 }, // 每日购买次数花费
|
||||
"DUNGRON_BUY_NUM": { "A": 0, "B": 50 } // 秘境购买次数花费
|
||||
}
|
||||
|
||||
export const EXPRESSION = {
|
||||
"CE": "1*hp+2*atk+2*matk+2*def+2*mdef+2*agi+2*luk+0*hit+0*cri+0*flee+0*antCri+0*damageIncrease+0*damageDecrease+0*defIngnore+0*bloodSuck"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ export const HERO_SYSTEM_TYPE = {
|
||||
ADD_SKIN: 15,
|
||||
SCHOOL: 16,
|
||||
SCROLL: 17,
|
||||
TITLE:18,
|
||||
TITLE: 18,
|
||||
TERAPH: 19,
|
||||
TERAPH_UP: 20
|
||||
};
|
||||
|
||||
// 武将上限
|
||||
@@ -36,4 +38,6 @@ export const JOB_TYPE = {
|
||||
}
|
||||
|
||||
// 武将战力放大系数
|
||||
export const HERO_CE_RATIO = 100;
|
||||
export const HERO_CE_RATIO = 100;
|
||||
// 次级属性放大系数
|
||||
export const HERO_SUB_ATTR_RATIO = 1000;
|
||||
6
shared/consts/constModules/httpConst.ts
Normal file
6
shared/consts/constModules/httpConst.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export enum BANTU_VID_ADDR {
|
||||
HOST = 'https://sdks.trgame.cn',
|
||||
IDCARD = '/vid/idcard', // 实名认证
|
||||
REPORT_ONLINE = '/addiction_prevention/report_online'
|
||||
}
|
||||
export const BANTU_VID_APP_KEY = '05c1c495369769e3c5d98426e9c8c2c0';
|
||||
@@ -7,7 +7,7 @@ export enum ROLE_SELECT {
|
||||
// 显示申请需要的信息
|
||||
SHOW_FRIEND_APPLY_LIST = 'roleId roleName ce headHid sHid lv title job quitTime vLv guildName friendCnt recFrdApplyCnt serverId userInfo.serverType',
|
||||
HANDLE_APPLY = 'roleId friendCnt lv',
|
||||
ATTR = 'globalCeAttr',
|
||||
ATTR = 'attr',
|
||||
GET_LV = 'lv',
|
||||
GET_ROLE_ID = 'roleId',
|
||||
GET_MY_SERVER = 'lv serverId userInfo.serverType',
|
||||
@@ -15,8 +15,8 @@ export enum ROLE_SELECT {
|
||||
};
|
||||
|
||||
export enum HERO_SELECT {
|
||||
ENTRY = '-ceAttr',
|
||||
HERO_DETAIL = 'roleId roleName hid hName ce lv star colorStar quality job skins ceAttr'
|
||||
ENTRY = '-attr',
|
||||
HERO_DETAIL = 'roleId roleName hid hName ce lv star colorStar quality job skins attr'
|
||||
}
|
||||
|
||||
export enum EQUIP_SELECT {
|
||||
|
||||
@@ -7,6 +7,10 @@ export const ENCRYPT_KEY = 'fiqaxijabbantusmprc234fj';
|
||||
|
||||
export const AUTH_SMS_CNT_PER_DAY = 8;
|
||||
|
||||
export const ADULT_AGE = 18;
|
||||
export const GUEST_MAX_TIME = 60 * 60 * 100; // 游客体验时间
|
||||
export const GUEST_DAY = 15; // 同一设备15天内不得重复体验游客模式
|
||||
|
||||
export const COUNTER = {
|
||||
UID: { name: 'uid', def: 1 },
|
||||
GMUID: { name: 'gmuid', def: 1 },
|
||||
@@ -392,4 +396,17 @@ export enum BLOCK_OPEATE {
|
||||
REMOVE_BLACK = 2,
|
||||
REMOVE_AND_APPLY = 3,
|
||||
REMOVE_FRIEND = 4
|
||||
}
|
||||
|
||||
export enum TIME_FORMAT {
|
||||
TYPE_SLASH = 1
|
||||
}
|
||||
|
||||
export enum ADDICTION_PREVENTION_CODE {
|
||||
FAIL = -1,
|
||||
SUCCESS = 1, // 接口的返回
|
||||
GUEST = 1, // 返回给客户端时,游客时间超时
|
||||
CURFEW = 2, // 每日22时至次日8时,未成年禁止游戏
|
||||
HOLIDAY = 3, // 法定节假日每日累计不得超过3小时
|
||||
WORKDAY = 4, // 非法定节假日每日累计不得超过1.5小时
|
||||
}
|
||||
@@ -7,5 +7,6 @@ export * from './constModules/sysConst';
|
||||
export * from './constModules/guildConst';
|
||||
export * from './constModules/selectConst';
|
||||
export * from './constModules/chatConst';
|
||||
export * from './constModules/httpConst';
|
||||
export * from './statusCode';
|
||||
export * from './dataName';
|
||||
@@ -17,6 +17,12 @@ export const STATUS = {
|
||||
DUP_LOGIN: { code: 10006, simStr: '重复登录' },
|
||||
NEW_SERVER_ERR: { code: 10007, simStr: '添加新服务器失败' },
|
||||
SERVER_EXISTS: { code: 10008, simStr: '服务器已存在' },
|
||||
PASSWORD_ERR: { code: 10009, simStr: '密码错误' },
|
||||
PASSWORD_ILLEGEL: { code: 10010, simStr: '请输入密码' },
|
||||
TEL_HAS_USED: { code: 10011, simStr: '该手机号已被使用' },
|
||||
ACCOUNT_NOT_GUEST: { code: 10012, simStr: '该账号已绑定过' },
|
||||
AUTHEN_FAIL: { code: 10013, simStr: '实名失败' },
|
||||
TEL_LEN_ERR: { code: 10014, simStr: '手机长度错误' },
|
||||
// 战斗相关状态 20000 - 29999
|
||||
// 战斗通用 20000 - 20099
|
||||
BATTLE_MISS_INFO: { code: 20001, simStr: '缺少关卡信息' },
|
||||
|
||||
@@ -94,7 +94,7 @@ export default class Equip extends BaseModel {
|
||||
return equip;
|
||||
}
|
||||
|
||||
public static async putOn(hid: number, equipId: string, lean = true) {
|
||||
public static async putOnOrOff(equipId: string, hid: number, lean = true) {
|
||||
const equip: EquipType = await EquipModel.findOneAndUpdate({ _id: equipId }, { hid }, { new: true }).lean(lean);
|
||||
return equip;
|
||||
}
|
||||
|
||||
@@ -2,27 +2,58 @@ import { APP_ID } from './../consts';
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||||
|
||||
class ServerInfo {
|
||||
export class ServerInfo {
|
||||
@prop({ required: true })
|
||||
id: number;
|
||||
id: number; // 小区id
|
||||
|
||||
@prop({ required: true })
|
||||
name: string;
|
||||
name: string; // 小区区名
|
||||
|
||||
@prop({ required: true })
|
||||
host: string;
|
||||
groupId: number; // 大区id
|
||||
|
||||
@prop({ required: true })
|
||||
groupName: string; // 大区区名
|
||||
|
||||
@prop({ required: true })
|
||||
host: string; // pinus连接地址
|
||||
|
||||
@prop({ required: false })
|
||||
port: number;
|
||||
port: number; // pinus端口
|
||||
|
||||
@prop({ required: true })
|
||||
status: number;
|
||||
serverStatus: number; // 服务器状态
|
||||
|
||||
public get status() {
|
||||
let now = new Date();
|
||||
if( now > this.openTime) {
|
||||
return this.serverStatus;
|
||||
} else {
|
||||
return 3; // 未开服
|
||||
}
|
||||
}
|
||||
|
||||
@prop({ required: true })
|
||||
openTime: Date;
|
||||
|
||||
@prop({ required: true })
|
||||
createTime: Date;
|
||||
|
||||
@prop({ required: true })
|
||||
serverType: string;
|
||||
|
||||
constructor(id: number, name: string, groupId: number, groupName: string, host: string, port: number, serverStatus: number, serverType: string, openTime?: Date) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.groupId = groupId;
|
||||
this.groupName = groupName;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.serverStatus = serverStatus;
|
||||
this.serverType = serverType;
|
||||
this.openTime = openTime||new Date();
|
||||
this.createTime = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,26 +96,23 @@ export default class Game extends BaseModel {
|
||||
}
|
||||
}
|
||||
|
||||
public static async getServerListByType(serverType: string) {
|
||||
let game: GameType = await GameModel.findOne().lean();
|
||||
public static async getServerList() {
|
||||
let game: GameType = await GameModel.findOne().lean({ getter: true, virtuals: true });
|
||||
if (!game) {
|
||||
const serverInfo: ServerInfo = { id: 1, name: '常山少年', host: 'pinus_test.trgame.cn', port: 3014, status: 1, createTime: new Date(), serverType: 'official' };
|
||||
const serverInfo = new ServerInfo(1, '常山少年', 1, '逍遥津', 'pinus_test.trgame.cn', 3014, 1, 'official');
|
||||
const iconUrl = `https://download.tgamebox.cn/avatar/${APP_ID}/1.png`;
|
||||
game = await GameModel.findOneAndUpdate(
|
||||
{},
|
||||
{ id: 1, name: '赵云传', nameEn: 'zyz', des: '牛逼的战棋', iconUrl, version: '0.0.1', versionCode: 1, $push: { serverList: serverInfo } },
|
||||
{ upsert: true, new: true },
|
||||
).lean();
|
||||
).lean({ getter: true, virtuals: true });
|
||||
}
|
||||
console.log(serverType, game);
|
||||
let serverList: Array<ServerInfo> = game ? game.serverList : [];
|
||||
serverList = serverList.filter(item => { return item.serverType === serverType; });
|
||||
console.log(serverType, serverList);
|
||||
return serverList;
|
||||
}
|
||||
|
||||
public static async newServer(serverId: number, serverType: string, name: string, host: string, port: number, status: number, lean = true) {
|
||||
let serverInfo: ServerInfo = {id: serverId, name, host, port, status, createTime: new Date(), serverType};
|
||||
let serverInfo = new ServerInfo(serverId, name, 1, '逍遥津', host, port, status, serverType);
|
||||
let game: GameType = await GameModel.findOneAndUpdate({}, {$push: {serverList: serverInfo}}, {new: true}).lean(lean);
|
||||
return game;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, mongoose, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
import { MAIL_STATUS, MAIL_TYPE } from '../consts/constModules/mailConst';
|
||||
import { findWhere } from 'underscore';
|
||||
const { ObjectId } = mongoose.Types;
|
||||
|
||||
class RewardInter {
|
||||
@prop({ required: true })
|
||||
id: number;
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { CeAttr } from '../domain/roleField/attribute';
|
||||
import { index, getModelForClass, prop, Ref, mongoose, DocumentType } from '@typegoose/typegoose';
|
||||
import Equip, { } from './Equip';
|
||||
import { CounterModel } from './Counter';
|
||||
import { COUNTER, EQUIP_TYPE } from '../consts';
|
||||
import { reduceCe } from '../pubUtils/util';
|
||||
|
||||
class CeAttrData {
|
||||
@prop({ required: true })
|
||||
id: number = 0;
|
||||
@prop({ required: true })
|
||||
base: number = 0;
|
||||
@prop({ required: true })
|
||||
ratioUp: number = 0;
|
||||
@prop({ required: true })
|
||||
fixUp: number = 0;
|
||||
@prop({ required: true })
|
||||
equipUp: number = 0;
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 英雄表
|
||||
*/
|
||||
|
||||
class Connect {
|
||||
export class Connect {
|
||||
@prop({ required: true })
|
||||
shipId: number;
|
||||
@prop({ required: true })
|
||||
@@ -51,31 +66,6 @@ function getInitialEplace() {
|
||||
return ePlace;
|
||||
}
|
||||
|
||||
interface heroUpdate {
|
||||
exp?: number;
|
||||
lv?: number;
|
||||
ce?: number;
|
||||
star?: number;
|
||||
starStage?: number;
|
||||
colorStar?: number;
|
||||
colorStarStage?: number;
|
||||
quality?: number;
|
||||
job?:number;
|
||||
jobStage?:number;
|
||||
favour?:number;
|
||||
favourLv?:number;
|
||||
skins?: Skin[];
|
||||
connections?: Connect[];
|
||||
ePlace?:EPlace[];
|
||||
_id?:number;
|
||||
scrollActive?: boolean;
|
||||
scrollId?: number;
|
||||
scrollStar?: number;
|
||||
scrollColorStar?: number;
|
||||
scrollQuality?: number;
|
||||
historyCe?: number;
|
||||
}
|
||||
|
||||
@index({ roleId: 1, hid: 1 })
|
||||
@index({ roleId: 1, seqId: 1 })
|
||||
export default class Hero extends BaseModel {
|
||||
@@ -102,8 +92,8 @@ export default class Hero extends BaseModel {
|
||||
ce: number; // 武将战力
|
||||
@prop({ required: true, default: 0 })
|
||||
historyCe: number; // 武将历史最高战力
|
||||
@prop({required: true, default: new CeAttr(), _id: false })
|
||||
ceAttr: CeAttr; // 影响战力的属性
|
||||
@prop({required: true, type: CeAttrData, default: [], _id: false })
|
||||
attr: CeAttrData[]; // 影响战力的属性
|
||||
|
||||
@prop({ required: true, default: 1 })
|
||||
star: number; // 星级
|
||||
@@ -181,10 +171,21 @@ export default class Hero extends BaseModel {
|
||||
public static async addEquip(roleId: string, hid: number, ePlaceId: number, equipId: string, lean = true) {
|
||||
const hero: HeroType = await HeroModel.findOneAndUpdate(
|
||||
{ roleId, hid, 'ePlace.id': ePlaceId },
|
||||
{$set: {'ePlace.$.equip': equipId, 'ePlace.$.hid':hid, 'ePlace.$.ePlaceId':ePlaceId}},
|
||||
{$set: { 'ePlace.$.equip': equipId }},
|
||||
{new: true}).populate('ePlace.equip').lean(lean);
|
||||
if (hero) {
|
||||
await Equip.putOn(hero.hid, equipId);
|
||||
await Equip.putOnOrOff( equipId, hero.hid );
|
||||
}
|
||||
return hero;
|
||||
}
|
||||
|
||||
public static async removeEquip(roleId: string, hid: number, ePlaceId: number, equipId: string, lean = true) {
|
||||
const hero: HeroType = await HeroModel.findOneAndUpdate(
|
||||
{ roleId, hid, 'ePlace.id': ePlaceId },
|
||||
{$set: {'ePlace.$.equip': null}},
|
||||
{new: true}).populate('ePlace.equip').lean(lean);
|
||||
if (hero) {
|
||||
await Equip.putOnOrOff( equipId, 0 );
|
||||
}
|
||||
return hero;
|
||||
}
|
||||
@@ -238,7 +239,7 @@ export default class Hero extends BaseModel {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async updateHeroInfo(roleId: string, hid:number, heroUpdate:heroUpdate, select?: string, lean = true) {
|
||||
public static async updateHeroInfo(roleId: string, hid:number, heroUpdate:HeroUpdate, select?: string, lean = true) {
|
||||
delete heroUpdate._id;
|
||||
let result: HeroType = await HeroModel.findOneAndUpdate({roleId, hid}, {$set:heroUpdate}, {new: true}).select(select).lean(lean);
|
||||
return result;
|
||||
@@ -270,3 +271,4 @@ export default class Hero extends BaseModel {
|
||||
export const HeroModel = getModelForClass(Hero);
|
||||
|
||||
export interface HeroType extends Pick<DocumentType<Hero>, keyof Hero>{};
|
||||
export type HeroUpdate = Partial<HeroType>; // 将所有字段变成可选项
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, mongoose } from '@typegoose/typegoose';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
import { MAIL_STATUS, MAIL_TYPE } from '../consts/constModules/mailConst';
|
||||
const { ObjectId } = mongoose.Types;
|
||||
|
||||
class RewardInter {
|
||||
@prop({ required: true })
|
||||
id: number;
|
||||
|
||||
63
shared/db/Notice.ts
Normal file
63
shared/db/Notice.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||||
import { formatTime } from '../pubUtils/timeUtil';
|
||||
import { TIME_FORMAT } from '../consts'
|
||||
|
||||
/**
|
||||
* 游戏字段接口
|
||||
*/
|
||||
@index({ id: 1 })
|
||||
@modelOptions({schemaOptions: {id: false}})
|
||||
export default class Notice extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
id: number; // 公告id
|
||||
@prop({ required: true })
|
||||
title: string; // 公告标题
|
||||
@prop({ required: true })
|
||||
tag: number; // 公告显示标签,在系统参数表中配了
|
||||
@prop({ required: true })
|
||||
type: number; // 类型 1-公告 2-活动
|
||||
@prop({ required: true })
|
||||
content: number; // 公告内容
|
||||
|
||||
@prop({ required: true })
|
||||
timeStr: string; // 时间显示
|
||||
@prop({ required: true })
|
||||
startTime: Date; // 活动开始时间
|
||||
@prop({ required: true })
|
||||
endTime: Date; // 活动结束时间
|
||||
public get time() {
|
||||
let startTime = formatTime(this.startTime, TIME_FORMAT.TYPE_SLASH);
|
||||
let endTime = formatTime(this.endTime, TIME_FORMAT.TYPE_SLASH);
|
||||
|
||||
return this.timeStr.replace(/%startTime/g, startTime).replace(/%endTime/g, endTime);
|
||||
}
|
||||
|
||||
@prop({ required: true, select: false })
|
||||
sort: number;
|
||||
|
||||
@prop({ required: true, select: false })
|
||||
showStartTime: Date;
|
||||
@prop({ required: true, select: false })
|
||||
showEndTime: Date;
|
||||
@prop({ required: true, select: false })
|
||||
serverType: string; // 服务器类型
|
||||
@prop({ required: true, select: false })
|
||||
isEnable: boolean;
|
||||
|
||||
|
||||
public static async getAllNotice(serverType: string) {
|
||||
let curTime = new Date();
|
||||
let notices: NoticeType[] = await NoticeModel.find({ showStartTime: { $lte: curTime }, showEndTime: { $gte: curTime }, isEnable: true, serverType })
|
||||
.sort({ sort: -1, createTime: -1 })
|
||||
.lean({ virtuals: true });
|
||||
return notices;
|
||||
}
|
||||
}
|
||||
|
||||
export const NoticeModel = getModelForClass(Notice);
|
||||
|
||||
export interface NoticeType extends Pick<DocumentType<Notice>, keyof Notice>{
|
||||
id: number;
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
import { HANG_UP_CONSTS, ROLE_TERAPH, ROLE_SELECT } from './../consts';
|
||||
import { HANG_UP_CONSTS, ROLE_TERAPH, ROLE_SELECT, ABI_TYPE } from './../consts';
|
||||
import BaseModel from './BaseModel';
|
||||
import { CeAttrRole } from '../domain/roleField/attribute';
|
||||
import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose';
|
||||
import User from './User';
|
||||
import { shouldRefresh, reduceCe } from '../pubUtils/util';
|
||||
@@ -8,6 +7,20 @@ import { initRoleAtrr } from '../pubUtils/playerCe';
|
||||
import Hero,{} from '../db/Hero';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
|
||||
// role表属性格式
|
||||
export class CeAttrDataRole {
|
||||
@prop({ required: true })
|
||||
id: number = 0;
|
||||
@prop({ required: true })
|
||||
ratioUp: number = 0;
|
||||
@prop({ required: true })
|
||||
fixUp: number = 0;
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
class TopHero {
|
||||
@prop({ required: true })
|
||||
hid: number; // 武将id
|
||||
@@ -41,37 +54,47 @@ export class WarStar {
|
||||
star: number; // 星级
|
||||
}
|
||||
|
||||
class Teraph{
|
||||
export class Teraph{
|
||||
@prop({ required: true, default: 1 })
|
||||
id: number; // 神像的id
|
||||
@prop({ required: true, default: 1 })
|
||||
grade: number; // 等级
|
||||
grade: number = 1; // 等级
|
||||
@prop({ required: true, default: 0 })
|
||||
hp: number;
|
||||
hp: number = 0;
|
||||
@prop({ required: true, default: 0 })
|
||||
atk: number;
|
||||
atk: number = 0;
|
||||
@prop({ required: true, default: 0 })
|
||||
def: number;
|
||||
def: number = 0;
|
||||
@prop({ required: true, default: 0 })
|
||||
mdef: number;
|
||||
@prop({ required: true, default: 0 })
|
||||
agi: number;
|
||||
@prop({ required: true, default: 0 })
|
||||
luk: number;
|
||||
mdef: number = 0;
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public get attr() {
|
||||
let map = new Map<number, number>();
|
||||
map.set(ABI_TYPE.ABI_HP, this.hp);
|
||||
map.set(ABI_TYPE.ABI_ATK, this.atk);
|
||||
map.set(ABI_TYPE.ABI_DEF, this.def);
|
||||
map.set(ABI_TYPE.ABI_MDEF, this.mdef);
|
||||
return map
|
||||
}
|
||||
|
||||
public set attr(value: Map<number, number>) {
|
||||
value.forEach((val, id) => {
|
||||
if(id == ABI_TYPE.ABI_HP) this.hp = val;
|
||||
if(id == ABI_TYPE.ABI_ATK) this.atk = val;
|
||||
if(id == ABI_TYPE.ABI_DEF) this.def = val;
|
||||
if(id == ABI_TYPE.ABI_MDEF) this.mdef = val;
|
||||
});
|
||||
}
|
||||
}
|
||||
// 初始化
|
||||
function getInitialTeraph() {
|
||||
let teraphs = new Array<Teraph>();
|
||||
for(let i = ROLE_TERAPH.START; i <= ROLE_TERAPH.END; i++) {
|
||||
let p = new Teraph();
|
||||
p.id = i;
|
||||
p.grade = 1;
|
||||
p.hp = 0;
|
||||
p.atk = 0;
|
||||
p.def = 0;
|
||||
p.mdef = 0;
|
||||
p.agi = 0;
|
||||
p.luk = 0;
|
||||
let p = new Teraph(i);
|
||||
teraphs.push(p);
|
||||
}
|
||||
return teraphs;
|
||||
@@ -114,8 +137,8 @@ export default class Role extends BaseModel {
|
||||
lv: number; // 主公等级
|
||||
@prop({ required: true, default: 0, set: (val: number) => val, get: (val: number) => reduceCe(val) })
|
||||
ce: number; // 总战力
|
||||
@prop({ required: true, default: new CeAttrRole(), _id: false })
|
||||
globalCeAttr: CeAttrRole; // 总战力
|
||||
@prop({ required: true, type: CeAttrDataRole, default: [], _id: false })
|
||||
attr: CeAttrDataRole[]; // 总战力
|
||||
@prop({ required: true, default: 0, set: (val: number) => val, get: (val: number) => reduceCe(val) })
|
||||
topLineupCe: number; // 最强x人战力
|
||||
@prop({ required: true, type: TopHero, default: [], _id: false })
|
||||
@@ -227,7 +250,7 @@ export default class Role extends BaseModel {
|
||||
@prop({ required: true, default: 0 })
|
||||
updatedMailAt: number;
|
||||
public static async findAllByUid(uid: number, lean = true) {
|
||||
const role: RoleType[] = await RoleModel.find({ 'userInfo.uid': uid }).select('roleId roleName serverId').lean(lean);
|
||||
const role: RoleType[] = await RoleModel.find({ 'userInfo.uid': uid }).select('roleId roleName serverId headHid sHid lv updatedAt').lean(lean);
|
||||
return role;
|
||||
}
|
||||
|
||||
@@ -242,8 +265,8 @@ export default class Role extends BaseModel {
|
||||
* @param select 选取字段,来自 selectConst/ROLE
|
||||
* @param getters 是否使用get方法,如ce使用了自动缩小1w倍
|
||||
*/
|
||||
public static async findByRoleId(roleId: string, select?: string, getters = false) {
|
||||
const role: RoleType = await RoleModel.findOne({ roleId }).select(select).lean({getters});
|
||||
public static async findByRoleId(roleId: string, select?: string, getters = false, virtuals = true) {
|
||||
const role: RoleType = await RoleModel.findOne({ roleId }).select(select).lean({getters, virtuals});
|
||||
return role;
|
||||
}
|
||||
|
||||
@@ -252,9 +275,8 @@ export default class Role extends BaseModel {
|
||||
if (!user) return null;
|
||||
const doc = new RoleModel();
|
||||
const update = Object.assign(doc.toJSON(), roleInfo, { userInfo: user, serverType: user.serverType, serverId });
|
||||
initRoleAtrr(update);
|
||||
const role: RoleType = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, update, { upsert: true, new: true }).lean(lean);
|
||||
|
||||
initRoleAtrr(role);
|
||||
return role;
|
||||
}
|
||||
|
||||
@@ -427,7 +449,7 @@ export default class Role extends BaseModel {
|
||||
return recs
|
||||
}
|
||||
|
||||
public static async updateRoleInfo(roleId: string, roleUpdate:roleUpdate, lean = true) {
|
||||
public static async updateRoleInfo(roleId: string, roleUpdate:RoleUpdate, lean = true) {
|
||||
delete roleUpdate._id;
|
||||
let result: RoleType = await RoleModel.findOneAndUpdate({roleId}, {$set:roleUpdate}, {new: true}).lean(lean);
|
||||
return result;
|
||||
@@ -519,4 +541,4 @@ export default class Role extends BaseModel {
|
||||
export const RoleModel = getModelForClass(Role);
|
||||
|
||||
export interface RoleType extends Pick<DocumentType<Role>, keyof Role>{};
|
||||
type roleUpdate = Partial<RoleType>; // 将所有字段变成可选项
|
||||
export type RoleUpdate = Partial<RoleType>; // 将所有字段变成可选项
|
||||
|
||||
@@ -3,6 +3,8 @@ import { CounterModel } from './Counter';
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { genCode } from '../pubUtils/util';
|
||||
const bcrypt = require('bcrypt');
|
||||
const SALT_WORK_FACTOR = 5
|
||||
|
||||
/**
|
||||
* 用户字段接口
|
||||
@@ -24,16 +26,42 @@ export default class User extends BaseModel {
|
||||
token: string;
|
||||
|
||||
@prop({ required: true })
|
||||
tel: string;
|
||||
tel: string; // 账号
|
||||
|
||||
@prop({ required: true, default: '' })
|
||||
telHash: string;
|
||||
|
||||
@prop({ required: true })
|
||||
password: string;
|
||||
|
||||
@prop({ required: true })
|
||||
salt: string;
|
||||
|
||||
@prop({ required: true, default: '' })
|
||||
channelId: string;
|
||||
|
||||
// 游客相关
|
||||
@prop({ required: false, default: false })
|
||||
isGuest: boolean; // 是否是游客
|
||||
@prop({ required: false })
|
||||
guestId: string;
|
||||
guestId: string; // 游客id
|
||||
@prop({ required: false, default: 0 })
|
||||
guestTime: number; // 游客体验时间
|
||||
|
||||
// 防沉迷相关
|
||||
@prop({ required: false, default: false })
|
||||
hasAuthenticated: boolean; // 是否是已认证
|
||||
@prop({ required: false })
|
||||
birthday: string; // 生日年月
|
||||
@prop({ required: false })
|
||||
pi: string; // 已通过实名认证用户唯一标识
|
||||
@prop({ required: false, default: 0 })
|
||||
todayPlayTime: number; // 今日游戏时间
|
||||
@prop({ required: false })
|
||||
reportTime: Date; // 汇报时间
|
||||
|
||||
@prop({ required: false, default: false })
|
||||
hasSetPw: boolean; // 是否设置过密码
|
||||
|
||||
// 最后登录 IP
|
||||
@prop({ required: false })
|
||||
@@ -52,6 +80,9 @@ export default class User extends BaseModel {
|
||||
unionId: string; // 用户标识
|
||||
}];
|
||||
|
||||
@prop({ required: true, type: String, default: [], _id: false })
|
||||
device: string[];
|
||||
|
||||
@prop({ required: true, default: 'com.bantu.zyz' })
|
||||
pkgName: string;
|
||||
|
||||
@@ -67,23 +98,77 @@ export default class User extends BaseModel {
|
||||
@prop({ required: true, default: 0 })
|
||||
auth: number;
|
||||
|
||||
public static async updateToken(tel: string, token: string, platform: string, pkgName: string, serverType: string, lean = true) {
|
||||
let user: UserType = await UserModel.findOne({ tel }).lean();
|
||||
public static async createUser(isGuest: boolean, tel: string, token: string, platform: string, pkgName: string, serverType: string, deviceId: string, guestTime?: number) {
|
||||
const curTime: Date = new Date();
|
||||
|
||||
const uid = await CounterModel.getNewCounter(COUNTER.UID);
|
||||
const userCode = genCode(8);
|
||||
const doc = new UserModel();
|
||||
let update = {};
|
||||
if (!user) {
|
||||
const uid = await CounterModel.getNewCounter(COUNTER.UID);
|
||||
const userCode = genCode(8);
|
||||
const doc = new UserModel();
|
||||
update = Object.assign(update, { platform, pkgName, serverType, createTime: curTime, uid, userCode, username: `用户${uid}` }, doc.toJSON());
|
||||
}
|
||||
update = Object.assign(update, { token, lastLoginTime: curTime });
|
||||
user = await UserModel.findOneAndUpdate({ tel }, update, { upsert: true, new: true }).lean(lean);
|
||||
update = Object.assign(update, doc.toJSON(), { platform, pkgName, serverType, createTime: curTime, uid, userCode, username: `用户${uid}`, isGuest, token, lastLoginTime: curTime, guestTime });
|
||||
if(isGuest) update["guestId"] = tel;
|
||||
delete update["device"];
|
||||
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ tel }, { $set: update, $addToSet: {device: deviceId}}, { upsert: true, new: true }).lean();
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async getLastDeviceGuest(deviceId: string) {
|
||||
const user: UserType = await UserModel.findOne({ device: { $elemMatch: { $eq: deviceId } }, isGuest: true }).sort({createTime: -1}).lean();
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async updateToken(tel: string, token: string, deviceId: string, lean = true) {
|
||||
const curTime: Date = new Date();
|
||||
|
||||
let user = await UserModel.findOneAndUpdate({ tel }, { $set: { token, lastLoginTime: curTime }, $addToSet: {device: deviceId}}, { new: true }).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async createOrUpdate(isGuest: boolean, tel: string, token: string, platform: string, pkgName: string, serverType: string, deviceId: string) {
|
||||
let user: UserType = await UserModel.findOne({ tel }).lean();
|
||||
if (!user) {
|
||||
user = await UserModel.createUser(isGuest, tel, token, platform, pkgName, serverType, deviceId);
|
||||
} else {
|
||||
user = await UserModel.updateToken(tel, token, deviceId);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private static async encryptPass(password: string, salt?: string) {
|
||||
if (!salt) {
|
||||
salt = await bcrypt.genSalt(SALT_WORK_FACTOR);
|
||||
}
|
||||
let npassword = await bcrypt.hash(password, salt);
|
||||
return { npassword, salt };
|
||||
}
|
||||
|
||||
public static async setPass(uid: number, password: string, lean = true) {
|
||||
let r = await this.encryptPass(password);
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ uid }, { $set: { password: r.npassword, salt: r.salt, hasSetPw: true }}, {new: true}).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async bindTel(uid: number, tel: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ uid, isGuest: true }, { $set: { tel, isGuest: false }}, {new: true}).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async checkPass(tel: string, password: string, token: string, deviceId: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOne({ tel }).select('salt').lean();
|
||||
if (user) {
|
||||
const curTime: Date = new Date();
|
||||
let { salt } = user;
|
||||
let { npassword } = await this.encryptPass(password, salt);
|
||||
const checkUser: UserType = await UserModel.findOneAndUpdate({ tel, password: npassword }, { $set: { token, lastLoginTime: curTime }, $addToSet: {device: deviceId}}, { new: true }).lean(lean);
|
||||
return checkUser;
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
public static async findUserByToken(token: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOne({ token }).select('uid token serverType auth userCode').lean(lean);
|
||||
const user: UserType = await UserModel.findOne({ token }).select('uid token serverType auth tel userCode pkgName').lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -93,7 +178,7 @@ export default class User extends BaseModel {
|
||||
}
|
||||
|
||||
public static async findUserByTel(tel: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOne({ tel }).select('uid tel').lean(lean);
|
||||
const user: UserType = await UserModel.findOne({ tel }).select('uid tel hasSetPw').lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -102,8 +187,18 @@ export default class User extends BaseModel {
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async findUserByUserCode(userCode: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOne({ userCode }).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async addAuth(uid: number, auth: number, lean = true) {
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ uid }, { auth }).select('uid tel').lean(lean);
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ uid }, { auth }, {new: true}).select('uid tel').lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static async authentication(uid: number, birthday: string, pi: string, lean = true) {
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ uid }, { hasAuthenticated: true, birthday, pi }, {new: true}).lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -117,8 +212,15 @@ export default class User extends BaseModel {
|
||||
const user: UserType[] = await UserModel.find(searchObj).select('uid tel username serverType auth').lean(lean);
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
public static async updatePlayTime(userCode: string, guestTimeInc: number, todayPlayTime: number, lean = true) {
|
||||
const user: UserType = await UserModel.findOneAndUpdate({ userCode }, { $inc: { guestTime: guestTimeInc }, $set: { todayPlayTime, reportTime: new Date() }}, { new: true }).lean(lean);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const UserModel = getModelForClass(User);
|
||||
|
||||
export interface UserType extends Pick<DocumentType<User>, keyof User>{};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { prop } from '@typegoose/typegoose';
|
||||
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
|
||||
import { HeroType } from '../db/Hero';
|
||||
import { CeAttrNumber } from './roleField/attribute';
|
||||
import { Attribute } from './roleField/attribute';
|
||||
|
||||
// 从玩家数据中覆盖warjson的部分字段
|
||||
export class PvpHeroInfo {
|
||||
@@ -27,7 +27,7 @@ export class PvpHeroInfo {
|
||||
quality?: number = 0; // 品质
|
||||
|
||||
@prop({ required: true, _id: false })
|
||||
attribute?: CeAttrNumber; // 属性
|
||||
attribute?: Attribute; // 属性
|
||||
|
||||
setHeroInfo(hero: HeroType) {
|
||||
this.actorId = hero.hid;
|
||||
@@ -46,7 +46,7 @@ export class PvpHeroInfo {
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
setAttribute(attribute: CeAttrNumber) {
|
||||
setAttribute(attribute: Attribute) {
|
||||
this.attribute = attribute;
|
||||
}
|
||||
|
||||
|
||||
69
shared/domain/gameField/serverlist.ts
Normal file
69
shared/domain/gameField/serverlist.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { ServerInfo } from '../../db/Game';
|
||||
import { RoleType } from '../../db/Role';
|
||||
import { getSeconds } from '../../pubUtils/timeUtil';
|
||||
|
||||
export class ServerParam {
|
||||
id: number; // 区号
|
||||
serverStr: string; // 显示的区号 S1
|
||||
name: string; // 区名
|
||||
host: string; // pinus地址
|
||||
port: number; // pinus端口
|
||||
status: number; // 状态
|
||||
openTime: number; // 开服时间
|
||||
serverType: string; // 分区类型 官服 测试服 开发服
|
||||
|
||||
constructor(server: ServerInfo) {
|
||||
this.id = server.id;
|
||||
this.serverStr = `S${this.id}`;
|
||||
this.name = server.name;
|
||||
this.host = server.host;
|
||||
this.port = server.port;
|
||||
this.status = server.status;
|
||||
this.openTime = getSeconds(server.openTime);
|
||||
this.serverType = server.serverType;
|
||||
}
|
||||
}
|
||||
|
||||
export class GroupParam {
|
||||
groupId: number; // 大区号
|
||||
groupName: string; // 大区名
|
||||
groupStr: string; // 大区内小区编号 S1-S10
|
||||
servers: ServerParam[]; // 区
|
||||
|
||||
constructor(server: ServerInfo) {
|
||||
this.groupId = server.groupId;
|
||||
this.groupName = server.groupName;
|
||||
this.groupStr = `S${server.id}-S${server.id + 9}`;
|
||||
this.servers = new Array<ServerParam>();
|
||||
}
|
||||
|
||||
public pushServer(server: ServerInfo) {
|
||||
let srv = new ServerParam(server);
|
||||
this.servers.push(srv);
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerParamWithRole extends ServerParam {
|
||||
groupId: number; // 大区号
|
||||
groupName: string; // 大区名
|
||||
|
||||
roleId: string; // 玩家账号
|
||||
roleName: string; // 玩家名
|
||||
headHid: number; // 头像
|
||||
sHid: number; // 形象
|
||||
lv: number; // 等级
|
||||
updatedAt: Date;
|
||||
|
||||
constructor(role: RoleType, server: ServerInfo) {
|
||||
super(server);
|
||||
this.groupId = server.groupId;
|
||||
this.groupName = server.groupName;
|
||||
|
||||
this.roleId = role.roleId;
|
||||
this.roleName = role.roleName;
|
||||
this.headHid = role.headHid;
|
||||
this.sHid = role.sHid;
|
||||
this.lv = role.lv;
|
||||
this.updatedAt = role.updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
import { prop } from '@typegoose/typegoose';
|
||||
import { HERO_CE_RATIO, getAtrrNameById, CE_CONST, HERO_SUB_ATTR_RATIO } from '../../consts';
|
||||
import { reduceCe } from '../../pubUtils/util';
|
||||
|
||||
// hero表内属性基础格式
|
||||
export class CeAttrData {
|
||||
@prop({ required: true })
|
||||
id: number = 0;
|
||||
@prop({ required: true })
|
||||
base: number = 0;
|
||||
@prop({ required: true })
|
||||
@@ -10,134 +14,175 @@ export class CeAttrData {
|
||||
fixUp: number = 0;
|
||||
@prop({ required: true })
|
||||
equipUp: number = 0;
|
||||
}
|
||||
|
||||
// hero表全属性
|
||||
export class CeAttr {
|
||||
@prop({ required: false, _id: false })
|
||||
hp?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
atk?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
matk?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
def?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
mdef?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
agi?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
luk?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
hit?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
cri?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
flee?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
antCri?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
damageIncrease?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
damageDecrease?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
defIngnore?: CeAttrData = new CeAttrData();
|
||||
@prop({ required: false, _id: false })
|
||||
bloodSuck?: CeAttrData = new CeAttrData();
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
// role表属性格式
|
||||
export class CeAttrDataRole {
|
||||
@prop({ required: true })
|
||||
id: number = 0;
|
||||
@prop({ required: true })
|
||||
ratioUp: number = 0;
|
||||
@prop({ required: true })
|
||||
fixUp: number = 0;
|
||||
}
|
||||
|
||||
// role表全属性
|
||||
export class CeAttrRole {
|
||||
@prop({ required: false, _id: false })
|
||||
hp?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
atk?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
matk?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
def?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
mdef?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
agi?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
luk?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
hit?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
cri?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
flee?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
antCri?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
damageIncrease?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
damageDecrease?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
defIngnore?: CeAttrDataRole = new CeAttrDataRole();
|
||||
@prop({ required: false, _id: false })
|
||||
bloodSuck?: CeAttrDataRole = new CeAttrDataRole();
|
||||
}
|
||||
|
||||
// 所有属性使用数字格式
|
||||
export class CeAttrNumber {
|
||||
@prop({ required: false })
|
||||
hp?: number = 0;
|
||||
@prop({ required: false })
|
||||
atk?: number = 0;
|
||||
@prop({ required: false })
|
||||
matk?: number = 0;
|
||||
@prop({ required: false })
|
||||
def?: number = 0;
|
||||
@prop({ required: false })
|
||||
mdef?: number = 0;
|
||||
@prop({ required: false })
|
||||
agi?: number = 0;
|
||||
@prop({ required: false })
|
||||
luk?: number = 0;
|
||||
@prop({ required: false })
|
||||
hit?: number = 0;
|
||||
@prop({ required: false })
|
||||
cri?: number = 0;
|
||||
@prop({ required: false })
|
||||
flee?: number = 0;
|
||||
@prop({ required: false })
|
||||
antCri?: number = 0;
|
||||
@prop({ required: false })
|
||||
damageIncrease?: number = 0;
|
||||
@prop({ required: false })
|
||||
damageDecrease?: number = 0;
|
||||
@prop({ required: false })
|
||||
defIngnore?: number = 0;
|
||||
@prop({ required: false })
|
||||
bloodSuck?: number = 0;
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
// 主属性
|
||||
export class MainAttrNumber {
|
||||
hp: number = 0;
|
||||
atk: number = 0;
|
||||
matk: number = 0;
|
||||
def: number = 0;
|
||||
mdef: number = 0;
|
||||
agi: number = 0;
|
||||
luk: number = 0;
|
||||
|
||||
constructor(attr: CeAttrNumber) {
|
||||
constructor(attr: Attribute) {
|
||||
if(attr.hp) this.hp = attr.hp;
|
||||
if(attr.atk) this.atk = attr.atk;
|
||||
if(attr.def) this.def = attr.def;
|
||||
if(attr.mdef) this.mdef = attr.mdef;
|
||||
if(attr.agi) this.agi = attr.agi;
|
||||
if(attr.luk) this.luk = attr.luk;
|
||||
}
|
||||
}
|
||||
|
||||
export class Attribute {
|
||||
@prop({ required: false })
|
||||
hp: number = 0;
|
||||
@prop({ required: false })
|
||||
atk: number = 0;
|
||||
@prop({ required: false })
|
||||
def: number = 0;
|
||||
@prop({ required: false })
|
||||
mdef: number = 0;
|
||||
@prop({ required: false })
|
||||
speed: number = 0;
|
||||
@prop({ required: false })
|
||||
hit: number = 0;
|
||||
@prop({ required: false })
|
||||
cri: number = 0;
|
||||
@prop({ required: false })
|
||||
flee: number = 0;
|
||||
@prop({ required: false })
|
||||
antCri: number = 0;
|
||||
@prop({ required: false })
|
||||
damageIncrease: number = 0;
|
||||
@prop({ required: false })
|
||||
damageDecrease: number = 0;
|
||||
@prop({ required: false })
|
||||
defIngnore: number = 0;
|
||||
@prop({ required: false })
|
||||
bloodSuck: number = 0;
|
||||
@prop({ required: false })
|
||||
ap: number = 0;
|
||||
@prop({ required: false })
|
||||
damageCri: number = 0;
|
||||
|
||||
setByDbData(roleAttrs: CeAttrDataRole[], heroAttrs: CeAttrData[]) {
|
||||
for(let { id, fixUp: roleFix, ratioUp: roleRatio } of roleAttrs) {
|
||||
let attrName = getAtrrNameById(id);
|
||||
let heroAttr = heroAttrs.find(heroAttr => heroAttr.id == id);
|
||||
if(heroAttr) {
|
||||
let { fixUp: heroFix, base: heroBase, ratioUp: heroRatio, equipUp: heroEquip } = heroAttr;
|
||||
let value = this.calAttrValue(roleFix, roleRatio, heroBase, heroFix, heroRatio, heroEquip);
|
||||
if(attrName in this) this[attrName] = value;
|
||||
} else {
|
||||
let value = this.calAttrValue(roleFix, roleRatio, 0, 0, 0, 0);
|
||||
if(attrName in this) this[attrName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
for(let { id, base: heroBase, fixUp: heroFix, ratioUp: heroRatio, equipUp: heroEquip } of heroAttrs) {
|
||||
let attrName = getAtrrNameById(id);
|
||||
let roleAttr = roleAttrs.find(roleAttr => roleAttr.id == id);
|
||||
if(!roleAttr) {
|
||||
let value = this.calAttrValue(0, 0, heroBase, heroFix, heroRatio, heroEquip);
|
||||
if(attrName in this) this[attrName] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setByWarJson( attributes: {id: number, val: number}[], ratio: number = 1) {
|
||||
for(let {id, val} of attributes) {
|
||||
let attrName = getAtrrNameById(id);
|
||||
if(attrName in this) this[attrName] = Math.floor(val * ratio * HERO_CE_RATIO * HERO_CE_RATIO);
|
||||
}
|
||||
}
|
||||
|
||||
private calAttrValue(roleFix: number = 0, roleRatio: number = 0, heroBase: number = 0, heroFix: number = 0, heroRatio: number = 0, heroEquip: number = 0) {
|
||||
return (heroFix + heroEquip + roleFix) * HERO_CE_RATIO + heroBase * ( HERO_CE_RATIO + heroRatio + roleRatio );
|
||||
}
|
||||
|
||||
private getRealSubAttr() {
|
||||
return {
|
||||
hit: this.hit / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
cri: this.cri / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
flee: this.flee / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
antCri: this.antCri / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
damageIncrease: this.damageIncrease / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
damageDecrease: this.damageDecrease / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
defIngnore: this.defIngnore / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
damageCri: this.damageCri / HERO_SUB_ATTR_RATIO / HERO_CE_RATIO / HERO_CE_RATIO
|
||||
}
|
||||
}
|
||||
|
||||
private getRealMainAttr() {
|
||||
return {
|
||||
hp: this.hp / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
atk: this.atk / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
def: this.def / HERO_CE_RATIO / HERO_CE_RATIO,
|
||||
mdef: this.mdef / HERO_CE_RATIO / HERO_CE_RATIO
|
||||
}
|
||||
}
|
||||
|
||||
public getReduceAttributes() {
|
||||
let newAttr = new Attribute();
|
||||
newAttr.hp = reduceCe(this.hp);
|
||||
newAttr.atk = reduceCe(this.atk);
|
||||
newAttr.def = reduceCe(this.def);
|
||||
newAttr.mdef = reduceCe(this.mdef);
|
||||
newAttr.speed = reduceCe(this.speed);
|
||||
newAttr.hit = reduceCe(this.hit);
|
||||
newAttr.cri = reduceCe(this.cri);
|
||||
newAttr.flee = reduceCe(this.flee);
|
||||
newAttr.antCri = reduceCe(this.antCri);
|
||||
newAttr.damageIncrease = reduceCe(this.damageIncrease);
|
||||
newAttr.damageDecrease = reduceCe(this.damageDecrease);
|
||||
newAttr.defIngnore = reduceCe(this.defIngnore);
|
||||
newAttr.bloodSuck = reduceCe(this.bloodSuck);
|
||||
newAttr.ap = reduceCe(this.ap);
|
||||
newAttr.damageCri = reduceCe(this.damageCri);
|
||||
return newAttr;
|
||||
}
|
||||
|
||||
// 战力计算
|
||||
public calCe() {
|
||||
let { hp, atk, def, mdef } = this.getRealMainAttr();
|
||||
let { cri, flee, damageIncrease, damageDecrease, damageCri } = this.getRealSubAttr();
|
||||
let putHit = CE_CONST.PUT_HIT / HERO_SUB_ATTR_RATIO;
|
||||
let putAntCri = CE_CONST.PUT_ANT_CRI / HERO_SUB_ATTR_RATIO;
|
||||
|
||||
let hitRate = CE_CONST.HIT_RATE_BASE + putHit/2 - flee; // 命中率
|
||||
if(hitRate > CE_CONST.HIT_RATE_MAX) hitRate = CE_CONST.HIT_RATE_MAX;
|
||||
if(hitRate < CE_CONST.HIT_RATE_MIN) hitRate = CE_CONST.HIT_RATE_MIN;
|
||||
let fleeRate = 1 - hitRate; // 格挡率
|
||||
|
||||
let criRate = CE_CONST.CRI_RATE_BASE + cri - putAntCri/2;
|
||||
if(criRate > CE_CONST.CRI_RATE_MAX) criRate = CE_CONST.CRI_RATE_MAX;
|
||||
if(criRate < CE_CONST.CRI_RATE_MIN) criRate = CE_CONST.CRI_RATE_MIN;
|
||||
|
||||
let criValue = CE_CONST.CRI_VALUE_BASE + damageCri;
|
||||
|
||||
let validHp = hp + (def + mdef) * 0.5 / ((1 - fleeRate * CE_CONST.FLEE_VALUE) * (1 - damageDecrease)); // 有效生命
|
||||
let validAtk = atk * hitRate * ( 1 + criRate * criValue) * ( 1 + damageIncrease); // 有效输出
|
||||
let ce = Math.floor(validHp * validAtk * HERO_CE_RATIO * HERO_CE_RATIO);
|
||||
return ce > 0? ce: 1;
|
||||
}
|
||||
|
||||
public calCelAndReduce() {
|
||||
return Math.floor(this.calCe() / HERO_CE_RATIO / HERO_CE_RATIO);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,6 @@ import { dicTeraph } from './dictionary/DicTeraph';
|
||||
import { dicSchool } from './dictionary/DicSchool';
|
||||
import { dicSchoolRate } from './dictionary/DicSchoolRate';
|
||||
import { dicHeroScroll, preHeroScroll } from './dictionary/DicHeroScroll';
|
||||
import { ABI_TYPE_TO_STAGE } from "../consts";
|
||||
import { dicPvpOpponent } from './dictionary/DicPvpOpponent';
|
||||
import { dicPvpTeamLevel } from './dictionary/DicPvpTeamLevel';
|
||||
import { dicPvpRefreshConsume, maxPvpRefreshCnt } from './dictionary/DicPvpRefreshConsume';
|
||||
@@ -58,6 +57,7 @@ import { dicArmyBossRank } from '../pubUtils/dictionary/DicArmyBossRank';
|
||||
import { dicArmyDonate } from '../pubUtils/dictionary/DicArmyDonateBoxReward';
|
||||
import { dicRoleFriend } from "./dictionary/DicRoleFriend";
|
||||
import { dicRoleFriendLv } from "./dictionary/DicRoleFriendLv";
|
||||
import { Attribute } from "../domain/roleField/attribute";
|
||||
|
||||
export const gameData = {
|
||||
blurprtCompose: dicBlueprtCompose,
|
||||
@@ -213,7 +213,11 @@ export function getBossHpByWarId(warId: number) {
|
||||
warInfo.forEach(hero => {
|
||||
let { attribute, dataId, relation, actorId } = hero;
|
||||
if (relation === 2) {
|
||||
const hp = attribute.hp||0;
|
||||
let newAttr = new Attribute();
|
||||
newAttr.setByWarJson(attribute, 1);
|
||||
let attrJson = newAttr.getReduceAttributes();
|
||||
|
||||
const hp = attrJson.hp||0;
|
||||
if (hp > 0) {
|
||||
bossHpArr.push({dataId, hp, actorId});
|
||||
bossHpSum += hp;
|
||||
@@ -300,17 +304,6 @@ export function getScollByStar(quality: number, star: number, curQuality: number
|
||||
return heroScroll;
|
||||
}
|
||||
|
||||
// 根据存在升星表等的stage字段的id对应17维id
|
||||
export function getFieldByStage(stage: number, jobid: number) {
|
||||
let targetAttrId = ABI_TYPE_TO_STAGE.get(stage);
|
||||
if(typeof targetAttrId === 'number') {
|
||||
return targetAttrId
|
||||
} else {
|
||||
const dicJob = gameData.job.get(jobid);
|
||||
return targetAttrId(dicJob.type);
|
||||
}
|
||||
}
|
||||
|
||||
export function getSuit(id: number) {
|
||||
const suitInfo = gameData.suit.get(id);
|
||||
return suitInfo;
|
||||
@@ -420,7 +413,7 @@ export function getArmyWishPoolBaseByLv(lv: number) {
|
||||
|
||||
export function getFriendLvByExp(exp: number) {
|
||||
let resultLv = 1;
|
||||
for(let [lv, {sum}] of gameData.roleFriendLv) {
|
||||
for(let [lv, {sum}] of gameData.roleFriendLv.entries()) {
|
||||
resultLv = lv;
|
||||
if(exp < sum) break;
|
||||
}
|
||||
|
||||
@@ -152,12 +152,10 @@ function parseAbility(json) {
|
||||
let map = new Map<number, number>();
|
||||
map.set(ABI_TYPE.ABI_HP, json.hp||0);
|
||||
map.set(ABI_TYPE.ABI_ATK, json.atk||0);
|
||||
map.set(ABI_TYPE.ABI_MATK, json.matk||0);
|
||||
map.set(ABI_TYPE.ABI_DEF, json.def||0);
|
||||
map.set(ABI_TYPE.ABI_MDEF, json.mdef||0);
|
||||
map.set(ABI_TYPE.ABI_AGI, json.agi||0);
|
||||
map.set(ABI_TYPE.ABI_LUK, json.luk||0);
|
||||
map.set(ABI_TYPE.ABI_SPEED, json.speed||0);
|
||||
map.set(ABI_TYPE.ABI_DAMAGE_INCREASE, json.damageIncrease||0);
|
||||
map.set(ABI_TYPE.ABI_DAMAGE_DECREASE, json.damageDecrease||0);
|
||||
return map
|
||||
}
|
||||
|
||||
@@ -165,12 +163,10 @@ function parseAbilityUp(json) {
|
||||
let map = new Map<number, number>();
|
||||
map.set(ABI_TYPE.ABI_HP, json.hp_up||0);
|
||||
map.set(ABI_TYPE.ABI_ATK, json.atk_up||0);
|
||||
map.set(ABI_TYPE.ABI_MATK, json.matk_up||0);
|
||||
map.set(ABI_TYPE.ABI_DEF, json.def_up||0);
|
||||
map.set(ABI_TYPE.ABI_MDEF, json.mdef_up||0);
|
||||
map.set(ABI_TYPE.ABI_AGI, json.agi_up||0);
|
||||
map.set(ABI_TYPE.ABI_LUK, json.luk_up||0);
|
||||
map.set(ABI_TYPE.ABI_SPEED, json.speed_up||0);
|
||||
map.set(ABI_TYPE.ABI_DAMAGE_INCREASE, json.damageIncrease_up||0);
|
||||
map.set(ABI_TYPE.ABI_DAMAGE_DECREASE, json.damageDecrease_up||0);
|
||||
return map
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,8 @@ function parseBaseAbilityArr(json) {
|
||||
let map = new Map<number, number>();
|
||||
map.set(ABI_TYPE.ABI_HP, json.hp||0);
|
||||
map.set(ABI_TYPE.ABI_ATK, json.atk||0);
|
||||
map.set(ABI_TYPE.ABI_MATK, json.matk||0);
|
||||
map.set(ABI_TYPE.ABI_DEF, json.def||0);
|
||||
map.set(ABI_TYPE.ABI_MDEF, json.mdef||0);
|
||||
map.set(ABI_TYPE.ABI_AGI, json.agi||0);
|
||||
map.set(ABI_TYPE.ABI_LUK, json.luk||0);
|
||||
map.set(ABI_TYPE.ABI_SPEED, json.speed||0);
|
||||
return map
|
||||
}
|
||||
|
||||
@@ -59,11 +55,7 @@ function parseBaseAbilityUpArr(json) {
|
||||
let map = new Map<number, number>();
|
||||
map.set(ABI_TYPE.ABI_HP, json.hp_up||0);
|
||||
map.set(ABI_TYPE.ABI_ATK, json.atk_up||0);
|
||||
map.set(ABI_TYPE.ABI_MATK, json.matk_up||0);
|
||||
map.set(ABI_TYPE.ABI_DEF, json.def_up||0);
|
||||
map.set(ABI_TYPE.ABI_MDEF, json.mdef_up||0);
|
||||
map.set(ABI_TYPE.ABI_AGI, json.agi_up||0);
|
||||
map.set(ABI_TYPE.ABI_LUK, json.luk_up||0);
|
||||
map.set(ABI_TYPE.ABI_SPEED, json.speed_up||0);
|
||||
return map
|
||||
}
|
||||
@@ -41,7 +41,5 @@ function parseCeAttr(elem) {
|
||||
ceAttr.set(ABI_STAGE.ATK, elem.atk);
|
||||
ceAttr.set(ABI_STAGE.DEF, elem.def);
|
||||
ceAttr.set(ABI_STAGE.MDEF, elem.mdef);
|
||||
ceAttr.set(ABI_STAGE.AGI, elem.agi);
|
||||
ceAttr.set(ABI_STAGE.LUK, elem.luk);
|
||||
return ceAttr;
|
||||
}
|
||||
@@ -36,7 +36,6 @@ function parseCeAttr(elem) {
|
||||
ceAttr.set(ABI_STAGE.ATK, elem.atk_up);
|
||||
ceAttr.set(ABI_STAGE.DEF, elem.def_up);
|
||||
ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up);
|
||||
ceAttr.set(ABI_STAGE.AGI, elem.agi_up);
|
||||
ceAttr.set(ABI_STAGE.LUK, elem.luk_up);
|
||||
return ceAttr;
|
||||
}
|
||||
}
|
||||
arr = undefined;
|
||||
@@ -40,7 +40,5 @@ function parseCeAttr(elem) {
|
||||
ceAttr.set(ABI_STAGE.ATK, elem.atk_up);
|
||||
ceAttr.set(ABI_STAGE.DEF, elem.def_up);
|
||||
ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up);
|
||||
ceAttr.set(ABI_STAGE.AGI, elem.agi_up);
|
||||
ceAttr.set(ABI_STAGE.LUK, elem.luk_up);
|
||||
return ceAttr;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// 兵种表
|
||||
import {readJsonFile, parseNumberList, parseGoodStr} from '../util'
|
||||
import { FILENAME } from '../../consts'
|
||||
import { FILENAME, ABI_STAGE } from '../../consts'
|
||||
import { RewardInter } from '../interface';
|
||||
const _ = require('lodash');
|
||||
|
||||
@@ -23,18 +23,8 @@ export interface DicJob {
|
||||
readonly trainingConsume: Array<RewardInter>;
|
||||
// 升阶消耗
|
||||
readonly upGradeConsume: Array<RewardInter>;
|
||||
// 生命训练提升
|
||||
readonly hp: number;
|
||||
// 攻击力训练提升
|
||||
readonly atk: number;
|
||||
// 防御力训练提升
|
||||
readonly def: number;
|
||||
// 策防训练提升
|
||||
readonly mdef: number;
|
||||
// 敏捷训练提升
|
||||
readonly agi: number;
|
||||
// 幸运训练提升
|
||||
readonly luk: number;
|
||||
// 每阶升级属性
|
||||
readonly ceAttr: Map<number, number>
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +32,7 @@ const str = readJsonFile(FILENAME.DIC_JOB);
|
||||
let arr = JSON.parse(str);
|
||||
|
||||
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||
const DicJobKeys: KeysEnum<DicJob> = {jobid: true, name: true, grade: true, unlockLevel: true, job_class: true, type: true, seid: true,trainingConsume: true, upGradeConsume: true, hp: true, atk: true, def: true, mdef: true, agi: true, luk: true};
|
||||
const DicJobKeys: KeysEnum<DicJob> = {jobid: true, name: true, grade: true, unlockLevel: true, job_class: true, type: true, seid: true,trainingConsume: true, upGradeConsume: true, ceAttr: true};
|
||||
|
||||
export const dicJob = new Map<number, DicJob>();
|
||||
export const jobClassMaxGrades = new Map<number, {grade:number, jobid:number}>();
|
||||
@@ -52,6 +42,7 @@ arr.forEach(o => {
|
||||
o.seid = parseNumberList(o.seid);
|
||||
o.trainingConsume = parseGoodStr(o.trainingConsume);
|
||||
o.upGradeConsume = parseGoodStr(o.upGradeConsume);
|
||||
o.ceAttr = parseCeAttr(o);
|
||||
dicJob.set(o.jobid, _.pick(o, Object.keys(DicJobKeys)));
|
||||
let jobClass = jobClassMaxGrades.get(o.job_class);
|
||||
if (!!jobClass && jobClass.grade < o.grade) {
|
||||
@@ -61,4 +52,13 @@ arr.forEach(o => {
|
||||
|
||||
});
|
||||
|
||||
function parseCeAttr(elem) {
|
||||
let ceAttr = new Map<number, number>();
|
||||
ceAttr.set(ABI_STAGE.HP, elem.hp);
|
||||
ceAttr.set(ABI_STAGE.ATK, elem.atk);
|
||||
ceAttr.set(ABI_STAGE.DEF, elem.def);
|
||||
ceAttr.set(ABI_STAGE.MDEF, elem.mdef);
|
||||
return ceAttr;
|
||||
}
|
||||
|
||||
arr = undefined;
|
||||
@@ -1,6 +1,7 @@
|
||||
// 物品表
|
||||
import { decodeArrayListStr, readJsonFile, parseGoodStr } from '../util'
|
||||
import { FILENAME} from '../../consts'
|
||||
import { FILENAME, ABI_TYPE} from '../../consts'
|
||||
import { RewardInter } from '../interface';
|
||||
const _ = require('lodash');
|
||||
|
||||
export interface SpecialMaterial {
|
||||
@@ -13,25 +14,16 @@ export interface DicTeraph {
|
||||
readonly id: number;
|
||||
readonly index: number;
|
||||
readonly grade: number;
|
||||
readonly hpMax: number;
|
||||
readonly atkMax: number;
|
||||
readonly defMax: number;
|
||||
readonly mdefMax: number;
|
||||
readonly agiMax: number;
|
||||
readonly lukMax: number;
|
||||
|
||||
readonly hp;
|
||||
readonly atk;
|
||||
readonly def;
|
||||
readonly mdef;
|
||||
readonly agi;
|
||||
readonly luk;
|
||||
readonly criRate;
|
||||
readonly criEffect;
|
||||
readonly upMaterial:Array<{id: number, number: number}>;
|
||||
readonly mainAttrMax: Map<number, number>; // 最大强化加成 id => value 18围内的id
|
||||
readonly mainAttrUp: Map<number, number>; // 每次强化加成 id => value 18围内的id
|
||||
|
||||
readonly criRate: number;
|
||||
readonly criEffect: number;
|
||||
readonly upMaterial:Array<RewardInter>;
|
||||
|
||||
readonly assiAttrValue:Array<{id: number, number: number}>;
|
||||
readonly upGradeMaterial:Array<{id: number, number: number}>;
|
||||
readonly assiAttrValue:Map<number, number>; // 次级属性
|
||||
readonly upGradeMaterial:Array<RewardInter>;
|
||||
}
|
||||
|
||||
const str = readJsonFile(FILENAME.DIC_TERAPH);
|
||||
@@ -42,18 +34,8 @@ const DicTeraphKeys: KeysEnum<DicTeraph> = {
|
||||
id: true,
|
||||
index: true,
|
||||
grade: true,
|
||||
hpMax: true,
|
||||
atkMax: true,
|
||||
defMax: true,
|
||||
mdefMax: true,
|
||||
agiMax: true,
|
||||
lukMax: true,
|
||||
hp: true,
|
||||
atk: true,
|
||||
def: true,
|
||||
mdef: true,
|
||||
agi: true,
|
||||
luk: true,
|
||||
mainAttrMax: true,
|
||||
mainAttrUp: true,
|
||||
criRate: true,
|
||||
criEffect: true,
|
||||
upMaterial: true,
|
||||
@@ -65,26 +47,40 @@ arr.forEach(o => {
|
||||
o.assiAttrValue = parseAttr(o.assiAttrValue);
|
||||
o.upGradeMaterial = parseGoodStr(o.upGradeMaterial);
|
||||
o.upMaterial = parseGoodStr(o.upMaterial);
|
||||
o.hp = o.hpUp;
|
||||
o.atk = o.atkUp;
|
||||
o.def = o.defUp;
|
||||
o.mdef = o.mdefUp;
|
||||
o.agi = o.agiUp;
|
||||
o.luk = o.lukUp;
|
||||
o.mainAttrMax = parseMainAttrMax(o);
|
||||
o.mainAttrUp = parseMainAttrUp(o);
|
||||
dicTeraph.set(o.index + '_' + o.grade, _.pick(o, Object.keys(DicTeraphKeys)));
|
||||
});
|
||||
|
||||
arr = undefined;
|
||||
|
||||
function parseAttr(str: string) {
|
||||
let result = new Array<{id: number, number: number}>();
|
||||
let result = new Map<number, number>();
|
||||
if(!str) return result;
|
||||
let decodeArr = decodeArrayListStr(str);
|
||||
for(let [id, number] of decodeArr) {
|
||||
if(isNaN(parseInt(id)) || isNaN(parseInt(number))) {
|
||||
throw new Error('data table format wrong');
|
||||
}
|
||||
result.push({id: parseInt(id), number: parseInt(number)});
|
||||
result.set(parseInt(id), parseInt(number));
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function parseMainAttrMax(elem) {
|
||||
let result = new Map<number, number>();
|
||||
result.set(ABI_TYPE.ABI_HP, elem.hpMax);
|
||||
result.set(ABI_TYPE.ABI_ATK, elem.atkMax);
|
||||
result.set(ABI_TYPE.ABI_DEF, elem.defMax);
|
||||
result.set(ABI_TYPE.ABI_MDEF, elem.mdefMax);
|
||||
return result
|
||||
}
|
||||
|
||||
function parseMainAttrUp(elem) {
|
||||
let result = new Map<number, number>();
|
||||
result.set(ABI_TYPE.ABI_HP, elem.hpUp);
|
||||
result.set(ABI_TYPE.ABI_ATK, elem.atkUp);
|
||||
result.set(ABI_TYPE.ABI_DEF, elem.defUp);
|
||||
result.set(ABI_TYPE.ABI_MDEF, elem.mdefUp);
|
||||
return result
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// 物品表
|
||||
import { decodeArrayListStr, readJsonFile, parseGoodStr } from '../util'
|
||||
import { FILENAME} from '../../consts'
|
||||
import { FILENAME, ABI_TYPE} from '../../consts'
|
||||
const _ = require('lodash');
|
||||
|
||||
export interface SpecialMaterial {
|
||||
@@ -9,15 +9,10 @@ export interface SpecialMaterial {
|
||||
}
|
||||
|
||||
export interface DicTitle {
|
||||
// 等级
|
||||
readonly id: number;
|
||||
readonly hp: number;
|
||||
readonly atk: number;
|
||||
readonly def: number;
|
||||
readonly mdef: number;
|
||||
readonly agi: number;
|
||||
readonly luk: number;
|
||||
readonly assiAttrValue: Array<{id: number, number: number}>;
|
||||
// 等级
|
||||
readonly mainAttrValue: Map<number, number>; // id => value 这里的值是上一级的基础上增加的值
|
||||
readonly assiAttrValue: Map<number, number>; // id => value
|
||||
// 等级现在
|
||||
readonly lvLimited: number;
|
||||
// 升级消耗
|
||||
@@ -30,18 +25,14 @@ let arr = JSON.parse(str);
|
||||
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||
const DicTitleKeys: KeysEnum<DicTitle> = {
|
||||
id: true,
|
||||
hp: true,
|
||||
atk: true,
|
||||
def: true,
|
||||
mdef: true,
|
||||
agi: true,
|
||||
luk: true,
|
||||
mainAttrValue: true,
|
||||
assiAttrValue: true,
|
||||
lvLimited: true,
|
||||
material: true
|
||||
}
|
||||
export const dicTitle = new Map<number, DicTitle>();
|
||||
arr.forEach(o => {
|
||||
o.mainAttrValue = parseMainAttr(o);
|
||||
o.assiAttrValue = parseAttr(o.assiAttrValue);
|
||||
o.material = parseGoodStr(o.material);
|
||||
dicTitle.set(o.id, _.pick(o, Object.keys(DicTitleKeys)));
|
||||
@@ -50,14 +41,23 @@ arr.forEach(o => {
|
||||
arr = undefined;
|
||||
|
||||
function parseAttr(str: string) {
|
||||
let result = new Array<{id: number, number: number}>();
|
||||
let result = new Map<number, number>();
|
||||
if(!str) return result;
|
||||
let decodeArr = decodeArrayListStr(str);
|
||||
for(let [id, number] of decodeArr) {
|
||||
if(isNaN(parseInt(id)) || isNaN(parseInt(number))) {
|
||||
for(let [id, value] of decodeArr) {
|
||||
if(isNaN(parseInt(id)) || isNaN(parseInt(value))) {
|
||||
throw new Error('data table format wrong');
|
||||
}
|
||||
result.push({id: parseInt(id), number: parseInt(number)});
|
||||
result.set(parseInt(id), parseInt(value));
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function parseMainAttr(elem) {
|
||||
let result = new Map<number, number>();
|
||||
result.set(ABI_TYPE.ABI_HP, elem.hp);
|
||||
result.set(ABI_TYPE.ABI_ATK, elem.atk);
|
||||
result.set(ABI_TYPE.ABI_DEF, elem.def);
|
||||
result.set(ABI_TYPE.ABI_MDEF, elem.mdef);
|
||||
return result;
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
// 关卡表
|
||||
import {decodeArrayListStr, readWarJsonFileList} from '../util'
|
||||
import { ABI_TYPE } from '../../consts';
|
||||
import { Attributes } from '../interface';
|
||||
|
||||
|
||||
export interface DicWarJson {
|
||||
|
||||
@@ -33,7 +30,7 @@ export interface DicWarJson {
|
||||
// 角色使用的AI类型
|
||||
readonly initial_ai: number;
|
||||
// 属性
|
||||
readonly attribute: Attributes;
|
||||
readonly attribute: {id: number, val: number}[];
|
||||
// 武将技能
|
||||
readonly skill: string;
|
||||
// 武将被动技能
|
||||
@@ -63,55 +60,15 @@ readWarJsonFileList().forEach(str => {
|
||||
dicWarJson.set(warid, warjson);
|
||||
})
|
||||
|
||||
function parseAttribute(str: string) {
|
||||
|
||||
let attribute: Attributes = {};
|
||||
if(!str) return attribute;
|
||||
|
||||
let arr = decodeArrayListStr(str);
|
||||
for(let [id, value] of arr) {
|
||||
if(isNaN(parseInt(id)) || isNaN(parseInt(value))) {
|
||||
export function parseAttribute(str: string) {
|
||||
let result = new Array<{ id: number, val: number }>();
|
||||
if (!str) return result;
|
||||
let decodeArr = decodeArrayListStr(str);
|
||||
for (let [id, val] of decodeArr) {
|
||||
if (isNaN(parseInt(id)) || isNaN(parseInt(val))) {
|
||||
throw new Error('data table format wrong');
|
||||
}
|
||||
let _id = parseInt(id), _value = parseInt(value);
|
||||
switch(_id) {
|
||||
case ABI_TYPE.ABI_HP:
|
||||
attribute.hp = _value; break;
|
||||
case ABI_TYPE.ABI_ATK:
|
||||
attribute.atk = _value; break;
|
||||
case ABI_TYPE.ABI_MATK:
|
||||
attribute.matk = _value; break;
|
||||
case ABI_TYPE.ABI_DEF:
|
||||
attribute.def = _value; break;
|
||||
case ABI_TYPE.ABI_MDEF:
|
||||
attribute.mdef = _value; break;
|
||||
case ABI_TYPE.ABI_AGI:
|
||||
attribute.agi = _value; break;
|
||||
case ABI_TYPE.ABI_LUK:
|
||||
attribute.luk = _value; break;
|
||||
case ABI_TYPE.ABI_SPEED:
|
||||
attribute.speed = _value; break;
|
||||
case ABI_TYPE.ABI_HIT:
|
||||
attribute.hit = _value; break;
|
||||
case ABI_TYPE.ABI_CRI:
|
||||
attribute.cri = _value; break;
|
||||
case ABI_TYPE.ABI_FLEE:
|
||||
attribute.flee = _value; break;
|
||||
case ABI_TYPE.ABI_ANT_CRI:
|
||||
attribute.antCri = _value; break;
|
||||
case ABI_TYPE.ABI_DAMAGE_INCREASE:
|
||||
attribute.damageIncrease = _value; break;
|
||||
case ABI_TYPE.ABI_DAMAGE_DECREASE:
|
||||
attribute.damageDecrease = _value; break;
|
||||
case ABI_TYPE.ABI_DEF_IGNORE:
|
||||
attribute.defIngnore = _value; break;
|
||||
case ABI_TYPE.ABI_BLOOD_SUCK:
|
||||
attribute.bloodSuck = _value; break;
|
||||
case ABI_TYPE.ABI_AP:
|
||||
attribute.ap = _value; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
result.push({ id: parseInt(id), val: parseInt(val) });
|
||||
}
|
||||
return attribute
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -373,8 +373,6 @@ function parseHeroStar() {
|
||||
ceAttr.set(ABI_STAGE.ATK, elem.atk_up);
|
||||
ceAttr.set(ABI_STAGE.DEF, elem.def_up);
|
||||
ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up);
|
||||
ceAttr.set(ABI_STAGE.AGI, elem.agi_up);
|
||||
ceAttr.set(ABI_STAGE.LUK, elem.luk_up);
|
||||
|
||||
heroStarList.set(`${elem.quality}_${elem.star}`,{ceAttr, ...elem});
|
||||
}
|
||||
@@ -392,8 +390,6 @@ function parseHeroWake() {
|
||||
ceAttr.set(ABI_STAGE.ATK, elem.atk_up);
|
||||
ceAttr.set(ABI_STAGE.DEF, elem.def_up);
|
||||
ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up);
|
||||
ceAttr.set(ABI_STAGE.AGI, elem.agi_up);
|
||||
ceAttr.set(ABI_STAGE.LUK, elem.luk_up);
|
||||
|
||||
heroWakeList.set(`${elem.quality}_${elem.star}`,{ceAttr, ...elem});
|
||||
}
|
||||
|
||||
103
shared/pubUtils/httpUtil.ts
Normal file
103
shared/pubUtils/httpUtil.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import * as request from "request-promise";
|
||||
import * as crypto from 'crypto'
|
||||
import { BANTU_VID_ADDR, BANTU_VID_APP_KEY } from '../consts';
|
||||
|
||||
/**
|
||||
* 在线报告
|
||||
* @param userCode 账号
|
||||
* @param packageName 包名
|
||||
*/
|
||||
export async function reportOnline ( userCode: string, packageName: string) {
|
||||
if(!packageName || packageName==''){
|
||||
packageName = 'com.bantu.nfsg'
|
||||
}
|
||||
|
||||
let result = await vidHttpRequest(BANTU_VID_ADDR.REPORT_ONLINE, {
|
||||
account: userCode,
|
||||
package: packageName
|
||||
});
|
||||
if(result && result.code !== 1) {
|
||||
console.error(result.msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实名认证
|
||||
* @param name 真实姓名
|
||||
* @param idNum 身份证号
|
||||
* @param userCode 账号
|
||||
* @param packageName 包名
|
||||
*/
|
||||
export async function authenticate (name: string, idNum: string, userCode: string, packageName: string) {
|
||||
if(!packageName || packageName==''){
|
||||
packageName = 'com.bantu.nfsg'
|
||||
}
|
||||
|
||||
let result = await vidHttpRequest(BANTU_VID_ADDR.IDCARD, {
|
||||
account: userCode,
|
||||
cardno: idNum,
|
||||
name,
|
||||
appkey: BANTU_VID_APP_KEY,
|
||||
package: packageName
|
||||
});
|
||||
if(result && result.code !== 1) {
|
||||
console.error(result.msg);
|
||||
}
|
||||
|
||||
return result && result.code == 1;
|
||||
}
|
||||
|
||||
export async function vidHttpRequest(addr: string, body: any) {
|
||||
body['sign'] = getObjSign(body);
|
||||
console.log('body: ', JSON.stringify(body))
|
||||
|
||||
let options = {
|
||||
url: BANTU_VID_ADDR.HOST + addr,
|
||||
method: 'POST',
|
||||
body:body,
|
||||
json: true
|
||||
}
|
||||
|
||||
try {
|
||||
let res = await request(options);
|
||||
let check = checkSign(res);
|
||||
if(!check) return false;
|
||||
console.log('*****request result*****');
|
||||
console.log(JSON.stringify(res));
|
||||
return res;
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function md5Vid (str: string) {
|
||||
str = 'vId' + str;
|
||||
return crypto.createHash('md5').update(str, 'utf8').digest("hex");
|
||||
};
|
||||
|
||||
export function getObjSign (obj: any) {
|
||||
const str = [];
|
||||
Object.keys(obj).sort().forEach((key) => {
|
||||
if (key == 'sign') {
|
||||
|
||||
} else {
|
||||
str.push(key + '=' + obj[key]);
|
||||
}
|
||||
});
|
||||
if (str.length == 0) {
|
||||
console.error('check obj', obj);
|
||||
}
|
||||
var strs = str.join('');
|
||||
return md5Vid(strs);
|
||||
}
|
||||
|
||||
export async function checkSign (obj: any) {
|
||||
if (getObjSign(obj) === obj.sign) {
|
||||
return true;
|
||||
}
|
||||
console.warn('correct sign:', getObjSign(obj), obj.sign);
|
||||
return false;
|
||||
}
|
||||
@@ -1,31 +1,12 @@
|
||||
// 一些通用的interface定义
|
||||
|
||||
import { Attribute } from "../domain/roleField/attribute";
|
||||
|
||||
export interface RewardInter {
|
||||
id: number;
|
||||
count: number;
|
||||
}
|
||||
|
||||
|
||||
export interface Attributes {
|
||||
hp?: number;
|
||||
atk?: number;
|
||||
matk?: number;
|
||||
def?: number;
|
||||
mdef?: number;
|
||||
agi?: number;
|
||||
luk?: number;
|
||||
speed?: number;
|
||||
hit?: number;
|
||||
cri?: number;
|
||||
flee?: number;
|
||||
antCri?: number;
|
||||
damageIncrease?: number;
|
||||
damageDecrease?: number;
|
||||
defIngnore?: number;
|
||||
bloodSuck?: number;
|
||||
ap?: number;
|
||||
}
|
||||
|
||||
export interface EquipInter {
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -82,7 +63,7 @@ export interface oppHeroesDefenseInter {
|
||||
lv: number; // 等级
|
||||
hide: number; // 是否隐藏
|
||||
initial_ai: number; // ai类型
|
||||
attribute: Attributes;
|
||||
attribute: Attribute;
|
||||
star: number; // 星级
|
||||
skill: string|number; // 技能
|
||||
seid: string; // 技能
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
import { TIME_FORMAT } from '@consts';
|
||||
|
||||
const PER_SECOND = 1 * 1000;
|
||||
const PER_DAY = 24 * 60 * 60;
|
||||
@@ -93,4 +94,39 @@ export function getTodayZeroDate() {
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
return date;
|
||||
}
|
||||
|
||||
export function getAge(birthday: string) {
|
||||
let d = new Date(birthday + ' 00:00:00');
|
||||
let _year = d.getFullYear();
|
||||
let _month = d.getMonth() + 1;
|
||||
let _day = d.getDate();
|
||||
|
||||
let age = 0;
|
||||
let now = new Date();
|
||||
let year = now.getFullYear();
|
||||
let month = now.getMonth() + 1;
|
||||
let day = now.getDate();
|
||||
|
||||
if (year >= _year && month >= _month && day >= _day) {
|
||||
age = year - _year;
|
||||
}else{
|
||||
age = year - _year - 1;
|
||||
}
|
||||
return age
|
||||
}
|
||||
|
||||
export function formatTime(d: Date, type: number) {
|
||||
let year = d.getFullYear();
|
||||
let month = d.getMonth() + 1;
|
||||
let day = d.getDate();
|
||||
let yearStr = year.toString();
|
||||
let monthStr = month.toString();
|
||||
let dayStr = day.toString();
|
||||
|
||||
if(type == TIME_FORMAT.TYPE_SLASH) {
|
||||
if(day < 10) dayStr = '0' + dayStr;
|
||||
if(month < 10) monthStr = '0' + monthStr;
|
||||
return `${yearStr}/${monthStr}/${dayStr}`;
|
||||
}
|
||||
}
|
||||
@@ -751,7 +751,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_1",
|
||||
"recommendedPower": 10031,
|
||||
"previousGk": 129,
|
||||
"previousGk": 201,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 95
|
||||
},
|
||||
@@ -779,7 +779,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_1",
|
||||
"recommendedPower": 10032,
|
||||
"previousGk": 130,
|
||||
"previousGk": 202,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 97
|
||||
},
|
||||
@@ -807,7 +807,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "2_1",
|
||||
"recommendedPower": 10033,
|
||||
"previousGk": 0,
|
||||
"previousGk": 203,
|
||||
"relatedEliteGk": 9204,
|
||||
"movePoint": 100
|
||||
},
|
||||
@@ -835,7 +835,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_2",
|
||||
"recommendedPower": 10034,
|
||||
"previousGk": 0,
|
||||
"previousGk": 204,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 103
|
||||
},
|
||||
@@ -863,7 +863,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_2",
|
||||
"recommendedPower": 10035,
|
||||
"previousGk": 0,
|
||||
"previousGk": 205,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 109
|
||||
},
|
||||
@@ -891,7 +891,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_2",
|
||||
"recommendedPower": 10036,
|
||||
"previousGk": 0,
|
||||
"previousGk": 206,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 112
|
||||
},
|
||||
@@ -919,7 +919,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "2_2",
|
||||
"recommendedPower": 10037,
|
||||
"previousGk": 0,
|
||||
"previousGk": 207,
|
||||
"relatedEliteGk": 9208,
|
||||
"movePoint": 116
|
||||
},
|
||||
@@ -947,7 +947,7 @@
|
||||
"heroInUI": "1&1001",
|
||||
"detailUIBg": "2_3",
|
||||
"recommendedPower": 10038,
|
||||
"previousGk": 0,
|
||||
"previousGk": 208,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 118
|
||||
},
|
||||
@@ -975,7 +975,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_3",
|
||||
"recommendedPower": 10039,
|
||||
"previousGk": 0,
|
||||
"previousGk": 209,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 120
|
||||
},
|
||||
@@ -1003,7 +1003,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_3",
|
||||
"recommendedPower": 10040,
|
||||
"previousGk": 0,
|
||||
"previousGk": 210,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 122
|
||||
},
|
||||
@@ -1031,7 +1031,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "2_3",
|
||||
"recommendedPower": 10041,
|
||||
"previousGk": 0,
|
||||
"previousGk": 211,
|
||||
"relatedEliteGk": 9212,
|
||||
"movePoint": 124
|
||||
},
|
||||
@@ -1059,7 +1059,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_4",
|
||||
"recommendedPower": 10042,
|
||||
"previousGk": 0,
|
||||
"previousGk": 212,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 126
|
||||
},
|
||||
@@ -1087,7 +1087,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_4",
|
||||
"recommendedPower": 10043,
|
||||
"previousGk": 0,
|
||||
"previousGk": 213,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 128
|
||||
},
|
||||
@@ -1115,7 +1115,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_4",
|
||||
"recommendedPower": 10044,
|
||||
"previousGk": 0,
|
||||
"previousGk": 214,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 130
|
||||
},
|
||||
@@ -1143,7 +1143,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "2_4",
|
||||
"recommendedPower": 10045,
|
||||
"previousGk": 0,
|
||||
"previousGk": 215,
|
||||
"relatedEliteGk": 9216,
|
||||
"movePoint": 133
|
||||
},
|
||||
@@ -1171,7 +1171,7 @@
|
||||
"heroInUI": "1&1001",
|
||||
"detailUIBg": "2_5",
|
||||
"recommendedPower": 10046,
|
||||
"previousGk": 0,
|
||||
"previousGk": 216,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 135
|
||||
},
|
||||
@@ -1199,7 +1199,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_5",
|
||||
"recommendedPower": 10047,
|
||||
"previousGk": 0,
|
||||
"previousGk": 217,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 137
|
||||
},
|
||||
@@ -1227,7 +1227,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_5",
|
||||
"recommendedPower": 10048,
|
||||
"previousGk": 0,
|
||||
"previousGk": 218,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 139
|
||||
},
|
||||
@@ -1255,7 +1255,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "2_5",
|
||||
"recommendedPower": 10049,
|
||||
"previousGk": 0,
|
||||
"previousGk": 219,
|
||||
"relatedEliteGk": 9220,
|
||||
"movePoint": 141
|
||||
},
|
||||
@@ -1283,7 +1283,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_6",
|
||||
"recommendedPower": 10050,
|
||||
"previousGk": 0,
|
||||
"previousGk": 220,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 143
|
||||
},
|
||||
@@ -1311,7 +1311,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_6",
|
||||
"recommendedPower": 10051,
|
||||
"previousGk": 0,
|
||||
"previousGk": 221,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 146
|
||||
},
|
||||
@@ -1339,7 +1339,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "2_6",
|
||||
"recommendedPower": 10052,
|
||||
"previousGk": 0,
|
||||
"previousGk": 222,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 148
|
||||
},
|
||||
@@ -1367,7 +1367,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "2_6",
|
||||
"recommendedPower": 10053,
|
||||
"previousGk": 0,
|
||||
"previousGk": 223,
|
||||
"relatedEliteGk": 9224,
|
||||
"movePoint": 150
|
||||
},
|
||||
@@ -1395,7 +1395,7 @@
|
||||
"heroInUI": "1&1001",
|
||||
"detailUIBg": "3_1",
|
||||
"recommendedPower": 10054,
|
||||
"previousGk": 0,
|
||||
"previousGk": 224,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 155
|
||||
},
|
||||
@@ -1423,7 +1423,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_1",
|
||||
"recommendedPower": 10055,
|
||||
"previousGk": 0,
|
||||
"previousGk": 301,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 159
|
||||
},
|
||||
@@ -1451,7 +1451,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_1",
|
||||
"recommendedPower": 10056,
|
||||
"previousGk": 0,
|
||||
"previousGk": 302,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 162
|
||||
},
|
||||
@@ -1479,7 +1479,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "3_1",
|
||||
"recommendedPower": 10057,
|
||||
"previousGk": 0,
|
||||
"previousGk": 303,
|
||||
"relatedEliteGk": 9304,
|
||||
"movePoint": 166
|
||||
},
|
||||
@@ -1507,7 +1507,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_2",
|
||||
"recommendedPower": 10058,
|
||||
"previousGk": 0,
|
||||
"previousGk": 304,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 169
|
||||
},
|
||||
@@ -1535,7 +1535,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_2",
|
||||
"recommendedPower": 10059,
|
||||
"previousGk": 0,
|
||||
"previousGk": 305,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 173
|
||||
},
|
||||
@@ -1563,7 +1563,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_2",
|
||||
"recommendedPower": 10060,
|
||||
"previousGk": 0,
|
||||
"previousGk": 306,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 176
|
||||
},
|
||||
@@ -1591,7 +1591,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "3_2",
|
||||
"recommendedPower": 10061,
|
||||
"previousGk": 0,
|
||||
"previousGk": 307,
|
||||
"relatedEliteGk": 9308,
|
||||
"movePoint": 180
|
||||
},
|
||||
@@ -1619,7 +1619,7 @@
|
||||
"heroInUI": "1&1001",
|
||||
"detailUIBg": "3_3",
|
||||
"recommendedPower": 10062,
|
||||
"previousGk": 0,
|
||||
"previousGk": 308,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 184
|
||||
},
|
||||
@@ -1647,7 +1647,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_3",
|
||||
"recommendedPower": 10063,
|
||||
"previousGk": 0,
|
||||
"previousGk": 309,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 186
|
||||
},
|
||||
@@ -1675,7 +1675,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_3",
|
||||
"recommendedPower": 10064,
|
||||
"previousGk": 0,
|
||||
"previousGk": 310,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 188
|
||||
},
|
||||
@@ -1703,7 +1703,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "3_3",
|
||||
"recommendedPower": 10065,
|
||||
"previousGk": 0,
|
||||
"previousGk": 311,
|
||||
"relatedEliteGk": 9312,
|
||||
"movePoint": 190
|
||||
},
|
||||
@@ -1731,7 +1731,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_4",
|
||||
"recommendedPower": 10066,
|
||||
"previousGk": 0,
|
||||
"previousGk": 312,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 195
|
||||
},
|
||||
@@ -1759,7 +1759,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_4",
|
||||
"recommendedPower": 10067,
|
||||
"previousGk": 0,
|
||||
"previousGk": 313,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 197
|
||||
},
|
||||
@@ -1787,7 +1787,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_4",
|
||||
"recommendedPower": 10068,
|
||||
"previousGk": 0,
|
||||
"previousGk": 314,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 201
|
||||
},
|
||||
@@ -1815,7 +1815,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "3_4",
|
||||
"recommendedPower": 10069,
|
||||
"previousGk": 0,
|
||||
"previousGk": 315,
|
||||
"relatedEliteGk": 9316,
|
||||
"movePoint": 204
|
||||
},
|
||||
@@ -1843,7 +1843,7 @@
|
||||
"heroInUI": "1&1001",
|
||||
"detailUIBg": "3_5",
|
||||
"recommendedPower": 10070,
|
||||
"previousGk": 0,
|
||||
"previousGk": 316,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 209
|
||||
},
|
||||
@@ -1871,7 +1871,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_5",
|
||||
"recommendedPower": 10071,
|
||||
"previousGk": 0,
|
||||
"previousGk": 317,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 212
|
||||
},
|
||||
@@ -1899,7 +1899,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_5",
|
||||
"recommendedPower": 10072,
|
||||
"previousGk": 0,
|
||||
"previousGk": 318,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 215
|
||||
},
|
||||
@@ -1927,7 +1927,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "3_5",
|
||||
"recommendedPower": 10073,
|
||||
"previousGk": 0,
|
||||
"previousGk": 319,
|
||||
"relatedEliteGk": 9320,
|
||||
"movePoint": 218
|
||||
},
|
||||
@@ -1955,7 +1955,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_6",
|
||||
"recommendedPower": 10074,
|
||||
"previousGk": 0,
|
||||
"previousGk": 320,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 221
|
||||
},
|
||||
@@ -1983,7 +1983,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_6",
|
||||
"recommendedPower": 10075,
|
||||
"previousGk": 0,
|
||||
"previousGk": 321,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 223
|
||||
},
|
||||
@@ -2011,7 +2011,7 @@
|
||||
"heroInUI": "1&1001|1&1004",
|
||||
"detailUIBg": "3_6",
|
||||
"recommendedPower": 10076,
|
||||
"previousGk": 0,
|
||||
"previousGk": 322,
|
||||
"relatedEliteGk": 0,
|
||||
"movePoint": 225
|
||||
},
|
||||
@@ -2039,7 +2039,7 @@
|
||||
"heroInUI": "1&1001|1&1004|2&312",
|
||||
"detailUIBg": "3_6",
|
||||
"recommendedPower": 10077,
|
||||
"previousGk": 0,
|
||||
"previousGk": 323,
|
||||
"relatedEliteGk": 9324,
|
||||
"movePoint": 227
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user