军团活动:排行榜&军功上报
This commit is contained in:
185
game-server/app/servers/guild/handler/gateActivityHandler.ts
Normal file
185
game-server/app/servers/guild/handler/gateActivityHandler.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
import { Application, BackendSession, ChannelService } from "pinus";
|
||||
import { setMedianCe, getMedianCe, getGuildActivityStatus, getRecordScore } from "../../../services/guildActivityService";
|
||||
import { resResult } from "../../../pubUtils/util";
|
||||
import { STATUS, GUILD_ACTIVITY_TYPE } from "../../../consts";
|
||||
import { GameModel } from "../../../db/Game";
|
||||
import { ServerlistModel } from "../../../db/Serverlist";
|
||||
import { UserGuildActivityRecModel, Record } from "../../../db/UserGuildActivityRec";
|
||||
import { UserGuildModel } from "../../../db/UserGuild";
|
||||
import { GUILDACTIVITY } from "../../../pubUtils/dicParam";
|
||||
import { GuildActivityRecordModel } from "../../../db/GuildActivityRec";
|
||||
import { RoleModel, RoleType } from "../../../db/Role";
|
||||
import { GuildModel } from "../../../db/Guild";
|
||||
import { RankParam, GuildRankParam } from "../../../domain/rank";
|
||||
import { setRank, getGuildKeyName, getRankScore, getRank, getUnionRank } from "../../../services/redisService";
|
||||
import { REDIS_KEY } from "../../../consts";
|
||||
|
||||
export default function (app: Application) {
|
||||
return new GateActivityHandler(app);
|
||||
}
|
||||
|
||||
export class GateActivityHandler {
|
||||
channelService: ChannelService;
|
||||
constructor(private app: Application) {
|
||||
this.channelService = app.get('channelService');
|
||||
}
|
||||
|
||||
private gateHp: Map<string, number> = new Map(); // 城门血条,每个军团有一条血条
|
||||
private members: Map<string, Array<string>> = new Map(); // 每个军团参与的成员
|
||||
private aid = GUILD_ACTIVITY_TYPE.GATE_ACTIVITY; // 蛮夷入侵id
|
||||
|
||||
// 进入蛮夷入侵界面
|
||||
async getGateActivity(msg: {}, session: BackendSession) {
|
||||
|
||||
const roleId = session.get('roleId');
|
||||
const roleName = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
const guildCode = session.get('guildCode');
|
||||
|
||||
let statusResult = getGuildActivityStatus(this.aid);
|
||||
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid);
|
||||
if(!guildActivityRec) return resResult(STATUS.INTERNAL_ERR);
|
||||
|
||||
let { code: sourceCode } = guildActivityRec;
|
||||
let myGuildActivityRec = await UserGuildActivityRecModel.getRecord(roleId, roleName, guildCode, serverId, sourceCode, [], this.aid);
|
||||
let { challengeCnt } = myGuildActivityRec;
|
||||
|
||||
// TODO 处理多余字段
|
||||
let {ranks: guildRank, myRank: myGuildRank} = await getUnionRank(REDIS_KEY.GUILD_ACTIVITY, serverId, guildCode, 10);
|
||||
let {ranks: memberRank, myRank: myMemberRank} = await getRank(getGuildKeyName(REDIS_KEY.USER_GUILD_ACTIVITY, guildCode), serverId, roleId);
|
||||
if(!myGuildRank) {
|
||||
let guild = await GuildModel.findByCode(guildCode, serverId, 'name');
|
||||
myGuildRank = {
|
||||
rank: 0,
|
||||
code: guildCode,
|
||||
name: guild.name,
|
||||
num: 0
|
||||
}
|
||||
}
|
||||
if(!myMemberRank) {
|
||||
myMemberRank = {
|
||||
rank: 0,
|
||||
roleId,
|
||||
roleName,
|
||||
num: 0
|
||||
}
|
||||
}
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
...statusResult,
|
||||
challengeCnt: GUILDACTIVITY.GATEACTIVITY_CHALLENGE_TIMES - challengeCnt,
|
||||
guildRank, myGuildRank,
|
||||
memberRank, myMemberRank
|
||||
})
|
||||
}
|
||||
|
||||
// 开启挑战
|
||||
async checkBattle(msg: { heroes: number[] }, session: BackendSession) {
|
||||
let { heroes } = msg;
|
||||
if(!heroes || heroes.length <= 0) return resResult(STATUS.WRONG_PARMS);
|
||||
|
||||
const roleId = session.get('roleId');
|
||||
const roleName = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
const guildCode = session.get('guildCode');
|
||||
if(!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
|
||||
|
||||
let statusResult = getGuildActivityStatus(this.aid);
|
||||
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid);
|
||||
if(!guildActivityRec) return resResult(STATUS.INTERNAL_ERR);
|
||||
|
||||
let { code: sourceCode } = guildActivityRec;
|
||||
let myGuildActivityRec = await UserGuildActivityRecModel.getRecord(roleId, roleName, guildCode, serverId, sourceCode, heroes, this.aid);
|
||||
let { code, challengeCnt } = myGuildActivityRec;
|
||||
|
||||
// 返回当前军团总军功
|
||||
let guildScore = await getRankScore(REDIS_KEY.GUILD_ACTIVITY, serverId, guildCode);
|
||||
|
||||
// 城门血条
|
||||
let gateHp = this.gateHp.get(guildCode)||GUILDACTIVITY.GATEACTIVITY_GATEHP;
|
||||
// 前一天中位数战力
|
||||
let medianCe = await getMedianCe(serverId);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
code,
|
||||
...statusResult,
|
||||
guildScore: guildScore||0,
|
||||
myScore: 0,
|
||||
gateHp,
|
||||
challengeCnt: GUILDACTIVITY.GATEACTIVITY_CHALLENGE_TIMES - challengeCnt,
|
||||
medianCe
|
||||
});
|
||||
}
|
||||
|
||||
// 上报玩家获得军功
|
||||
async action(msg: { code: string, record: { round: number, dataId: number }[] }, session: BackendSession) {
|
||||
let roleId = session.get('roleId');
|
||||
let roleName = session.get('roleName');
|
||||
let guildCode = session.get('guildCode');
|
||||
let serverId = session.get('serverId');
|
||||
|
||||
let { code, record } = msg;
|
||||
|
||||
let statusResult = getGuildActivityStatus(this.aid);
|
||||
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
// 计算record内得分
|
||||
// TODO 防刷分,应加入记录玩家操作
|
||||
let scoreResult = getRecordScore(this.aid, record);
|
||||
if(!scoreResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
let { score, newRecords } = scoreResult;
|
||||
|
||||
// 更新redis数据
|
||||
let role = await RoleModel.findByRoleId(roleId);
|
||||
let { lv, vLv, head, frame, spine, title } = role;
|
||||
let userParam = new RankParam(roleName, lv, vLv, head, frame, spine, title);
|
||||
let myScore = await setRank(getGuildKeyName(REDIS_KEY.USER_GUILD_ACTIVITY, guildCode), serverId, guildCode, score, Date.now(), userParam);
|
||||
|
||||
let guild = await GuildModel.findByCode(guildCode, serverId);
|
||||
let leader = <RoleType>guild.leader;
|
||||
let params = new GuildRankParam(guild.icon, guild.name, guild.lv, leader);
|
||||
let guildScore = await setRank(REDIS_KEY.GUILD_ACTIVITY, serverId, guild.code, 0, Date.now(), params, true);
|
||||
|
||||
// 更新数据库
|
||||
let rec = await UserGuildActivityRecModel.pushRecord(code, newRecords);
|
||||
let gateHp = this.gateHp.get(guildCode)||GUILDACTIVITY.GATEACTIVITY_GATEHP;
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
code: rec.code,
|
||||
...statusResult,
|
||||
guildScore: guildScore||0,
|
||||
myScore: myScore||0,
|
||||
gateHp
|
||||
});
|
||||
}
|
||||
|
||||
// 上报敌军攻打城门情况
|
||||
async hitGate(msg: {}, session: BackendSession) {
|
||||
|
||||
}
|
||||
|
||||
// 结束挑战
|
||||
async battleEnd(msg: { count: number }, session: BackendSession) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO debug接口,可以不用
|
||||
async newServer() {
|
||||
let serverlist = await GameModel.getAllServerList();
|
||||
for(let server of serverlist) {
|
||||
|
||||
await ServerlistModel.newServer(server.id, server.serverType, {...server});
|
||||
}
|
||||
}
|
||||
|
||||
async test() {
|
||||
|
||||
let result = await setMedianCe();
|
||||
return resResult(STATUS.SUCCESS, {result});
|
||||
}
|
||||
}
|
||||
106
game-server/app/services/guildActivityService.ts
Normal file
106
game-server/app/services/guildActivityService.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { ServerlistModel } from "../db/Serverlist";
|
||||
import { RoleModel } from "../db/Role";
|
||||
import { reduceCe } from "../pubUtils/util";
|
||||
import { GUILDACTIVITY } from "../pubUtils/dicParam";
|
||||
import { gameData } from "../pubUtils/data";
|
||||
import { getCurHourPoint, getCutDay, nowSeconds } from "../pubUtils/timeUtil";
|
||||
import { GUILD_ACTIVITY_STATUS } from "../consts";
|
||||
import { Record } from "../db/UserGuildActivityRec";
|
||||
|
||||
/**
|
||||
* 定时任务,获得前一天的活跃玩家中位数武将战力
|
||||
*/
|
||||
export async function setMedianCe() {
|
||||
let servers = await ServerlistModel.getAllServerList();
|
||||
|
||||
for(let server of servers) {
|
||||
if(server.serverType == 'official') {
|
||||
let medianRole = await RoleModel.getMedianRole(server.id);
|
||||
if(!medianRole) {
|
||||
await ServerlistModel.updateByServerId(server.id, { medianCe: GUILDACTIVITY.GATEACTIVITY_ENEMYCE });
|
||||
} else {
|
||||
let { topLineup } = medianRole;
|
||||
let topHero = topLineup.sort((a, b) => b.ce - a.ce);
|
||||
let medianCe = reduceCe(topHero[0].ce);
|
||||
await ServerlistModel.updateByServerId(server.id, { medianCe });
|
||||
}
|
||||
}
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得本服前一天活跃玩家中位数玩家的最强武将战力
|
||||
* @param serverId
|
||||
*/
|
||||
export async function getMedianCe(serverId: number) {
|
||||
let server = await ServerlistModel.findByServerId(serverId);
|
||||
if(server) {
|
||||
return server.medianCe;
|
||||
}
|
||||
return GUILDACTIVITY.GATEACTIVITY_ENEMYCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前时间判断军团活动倒计时
|
||||
* @param id 军团活动id
|
||||
*/
|
||||
export function getGuildActivityStatus(id: number) {
|
||||
let dicGuildActivity = gameData.guildActivity.get(id);
|
||||
if(!dicGuildActivity) return false;
|
||||
|
||||
let startTime = getCurHourPoint(dicGuildActivity.startTime);
|
||||
let countdownTime = getCurHourPoint(dicGuildActivity.countDown);
|
||||
let { duringTime, openDay } = dicGuildActivity;
|
||||
let endTime = startTime + duringTime;
|
||||
|
||||
let status = 0, time = 0;
|
||||
let now = nowSeconds();
|
||||
if(now >= countdownTime && now < startTime) {
|
||||
status = GUILD_ACTIVITY_STATUS.WAITING;
|
||||
time = startTime - now;
|
||||
} else if (now >= startTime && now < endTime) {
|
||||
status = GUILD_ACTIVITY_STATUS.START;
|
||||
time = endTime - now;
|
||||
} else {
|
||||
status = GUILD_ACTIVITY_STATUS.END;
|
||||
}
|
||||
|
||||
let day = getCutDay();
|
||||
let isOpen = openDay.includes(day);
|
||||
|
||||
return {
|
||||
status, time, isOpen
|
||||
}
|
||||
}
|
||||
|
||||
export function getRecordScore(aid: number, record: { round: number, dataId: number }[]) {
|
||||
let dicGuildActivity = gameData.guildActivity.get(aid);
|
||||
console.log('xxxx', dicGuildActivity.warid)
|
||||
if(!dicGuildActivity) return false;
|
||||
|
||||
let dicWarJson = gameData.warJson.get(dicGuildActivity.warid);
|
||||
if(!dicWarJson) return false;
|
||||
|
||||
let curRound = record[0]?.round;
|
||||
let sum = 0, newRecords = new Array<Record>()
|
||||
for(let {round, dataId} of record) {
|
||||
let enemy = dicWarJson.find(cur => cur.dataId == dataId);
|
||||
console.log('yyyy', enemy.enemyType);
|
||||
let enemyType = enemy.enemyType;
|
||||
let score = gameData.gateActivityPoint.get(enemyType);
|
||||
newRecords.push({ round, dataId, score});
|
||||
sum += score;
|
||||
console.log('***%*****', sum, score)
|
||||
if(round != curRound) { // 每回合开始得10分
|
||||
sum += gameData.gateActivityPoint.get(1);
|
||||
console.log('***%%*****', sum)
|
||||
curRound = round;
|
||||
}
|
||||
}
|
||||
console.log('***&**', sum)
|
||||
|
||||
|
||||
return { score: sum, newRecords }
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import { SystemConfigModel } from '../db/SystemConfig';
|
||||
import { GuildRankParam, GuildLeader, RankParam } from '../domain/rank';
|
||||
import { GuildModel } from '../db/Guild';
|
||||
import { comBtlRanges } from '../pubUtils/gamedata';
|
||||
import { stringify } from 'querystring';
|
||||
import { getNextHourPoint } from '../pubUtils/timeUtil';
|
||||
/**
|
||||
* 在服务重新启动时,将信息存入redis
|
||||
*/
|
||||
@@ -103,14 +103,28 @@ export async function existsRank(key: string, serverId: number) {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getKeyName(key: string, serverId?: number) {
|
||||
|
||||
/**
|
||||
* 获得redis key的名字
|
||||
* @param key REDIS_KEY中配置的key
|
||||
* @param serverId 服务器id
|
||||
* @param plus 后面再加
|
||||
*/
|
||||
export function getKeyName(key: string, serverId?: number, plus: string = '') {
|
||||
let newKey = '';
|
||||
if(serverId) {
|
||||
return `${key}:${serverId}`;
|
||||
newKey = `${key}:${serverId}`;
|
||||
} else {
|
||||
return key;
|
||||
newKey = key;
|
||||
}
|
||||
|
||||
if(plus) {
|
||||
newKey += `:${plus}`;
|
||||
}
|
||||
return newKey;
|
||||
}
|
||||
|
||||
|
||||
// 更新玩家信息
|
||||
export async function redisUserInfoUpdate(key: string, roleId: string, arr: Array<{field: string, value:(string|number|GuildLeader)}>) {
|
||||
let params = await redisClient().hgetAsync(key, roleId);
|
||||
@@ -129,16 +143,31 @@ export async function redisUserInfoAdd(key: string, roleId: string, params: Rank
|
||||
return await redisClient().hsetAsync(key, roleId, value);
|
||||
}
|
||||
|
||||
// 更新排行榜, 如pvp这样跨服的,serverId传0
|
||||
export async function setRank(key: string, serverId: number, myId: string, score: number, timestamp: number, params: RankParam|GuildRankParam, limit = 100) {
|
||||
/**
|
||||
* 更新排行榜
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id 如pvp这样跨服的,serverId传0
|
||||
* @param myId 玩家roleId或军团code
|
||||
* @param score 得分
|
||||
* @param timestamp 时间 13位时间戳
|
||||
* @param params 玩家数据
|
||||
* @param isAtom 是否是原子性的更新
|
||||
* @param limit
|
||||
*/
|
||||
export async function setRank(key: string, serverId: number, myId: string, score: number, timestamp: number, params: RankParam|GuildRankParam, isAtom = false, limit = 100) {
|
||||
|
||||
// 更新分数
|
||||
const _score = encodeScoreWithTime(score, timestamp);
|
||||
await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId);
|
||||
let newScore = score;
|
||||
if(isAtom) {
|
||||
newScore = await updateRankAtom(key, serverId, myId, score, timestamp);
|
||||
} else {
|
||||
const _score = encodeScoreWithTime(score, timestamp);
|
||||
await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId);
|
||||
}
|
||||
// 移除100名以外
|
||||
await redisClient().zremrangebyrankAsync(getKeyName(key, serverId), limit, 10000);
|
||||
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key);
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
|
||||
// 如果没有信息,更新玩家信息
|
||||
const hasCurUser = await redisClient().hexistsAsync(infoKey, myId);
|
||||
if(!hasCurUser) {
|
||||
@@ -148,12 +177,12 @@ export async function setRank(key: string, serverId: number, myId: string, score
|
||||
}
|
||||
|
||||
// 获取排行榜
|
||||
export async function getRank(key: string, serverId: number, roleId: string) {
|
||||
export async function getRank(key: string, serverId: number, roleId: string, limit = 100) {
|
||||
|
||||
let ranks = [], myRank = null;
|
||||
const rankFromDb = await redisClient().zrevrangebyscoreAsync(getKeyName(key, serverId), '+inf', '-inf', "WITHSCORES", "LIMIT", 0, 100);
|
||||
const rankFromDb = await redisClient().zrevrangebyscoreAsync(getKeyName(key, serverId), '+inf', '-inf', "WITHSCORES", "LIMIT", 0, limit);
|
||||
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key);
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
|
||||
|
||||
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
|
||||
const _roleId = rankFromDb[ii];
|
||||
@@ -496,6 +525,20 @@ async function setServerList() {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllServers() {
|
||||
let servers = await redisClient().hgetallAsync(REDIS_KEY.DB_GAME);
|
||||
let serverlist = new Array<number>();
|
||||
for(let serverStr in servers) {
|
||||
let arr = serverStr.split('_');
|
||||
let serverId = parseInt(arr[1]);
|
||||
|
||||
if(!isNaN(serverId) && !serverlist.includes(serverId)) {
|
||||
serverlist.push(serverId);
|
||||
}
|
||||
}
|
||||
return serverlist;
|
||||
}
|
||||
|
||||
export async function getServerName(serverType: string, serverId: number) {
|
||||
let name = await redisClient().hgetAsync(REDIS_KEY.DB_GAME, `${serverType}_${serverId}`);
|
||||
return name
|
||||
@@ -506,4 +549,96 @@ function redisClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**************** 数据库表end */
|
||||
/**************** 数据库表end */
|
||||
|
||||
/**************** 军团活动排行 */
|
||||
|
||||
/**
|
||||
* 更新排行榜(将得分和时间拆分开)
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id
|
||||
* @param field 玩家id/军团id
|
||||
* @param score 得分
|
||||
* @param time 事件
|
||||
*/
|
||||
async function updateRankAtom(key: string, serverId: number, field: string, score: number, timestamp: number) {
|
||||
let originKey = getKeyName(key, serverId);
|
||||
let timeKey = getKeyName(key, serverId, 'time');
|
||||
await redisClient().expireatAsync(originKey, getNextHourPoint(5));
|
||||
await redisClient().expireatAsync(timeKey, getNextHourPoint(5));
|
||||
|
||||
let timelen = 10;
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
|
||||
let newScore = await redisClient().zincrbyAsync(originKey, score, field);
|
||||
await redisClient().zaddAsync(timeKey, pow - 1 - Math.floor(timestamp/1000), field);
|
||||
return newScore;
|
||||
}
|
||||
|
||||
async function generateUnionRank(key: string, serverId: number) {
|
||||
let unionKey = getKeyName(key, serverId, 'union'); // 联合的key
|
||||
let existsKey = await redisClient().existsAsync(unionKey);
|
||||
if(!existsKey) {
|
||||
await redisClient().expireatAsync(unionKey, 10); // 10秒更新一次
|
||||
let originKey = getKeyName(key, serverId);
|
||||
let timeKey = getKeyName(key, serverId, 'time');
|
||||
|
||||
let timelen = 10;
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
await redisClient().zunionstoreAsync(unionKey, 2, originKey, timeKey, 'WEIGHTS', pow, 1);
|
||||
}
|
||||
return unionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用updateRankAtom更新的排行榜,使用这个方法获取列表
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id
|
||||
* @param roleId 自己的id
|
||||
*/
|
||||
export async function getUnionRank(key: string, serverId: number, roleId: string, limit = 100) {
|
||||
|
||||
let ranks = [], myRank = null;
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
const rankFromDb = await redisClient().zrevrangebyscoreAsync(unionKey, '+inf', '-inf', "WITHSCORES", "LIMIT", 0, limit);
|
||||
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
|
||||
|
||||
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
|
||||
const _roleId = rankFromDb[ii];
|
||||
const _score = decodeScoreWithTime(rankFromDb[ii + 1]);
|
||||
const info = await redisClient().hgetAsync(infoKey, _roleId);
|
||||
const _userInfo = JSON.parse(info);
|
||||
const tmp = {..._userInfo, num: _score, rank: Math.floor(ii/2)+1};
|
||||
if(infoKey == REDIS_KEY.USER_INFO) {
|
||||
tmp["roleId"] = _roleId;
|
||||
} else if(infoKey == REDIS_KEY.GUILD_INFO) {
|
||||
tmp["code"] = _roleId;
|
||||
}
|
||||
ranks.push(tmp);
|
||||
if(roleId == _roleId) myRank = tmp;
|
||||
}
|
||||
return {ranks, myRank}
|
||||
}
|
||||
|
||||
// 获取我的排名
|
||||
export async function getMyUnionRank(key: string, serverId: number, roleId: string) {
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
let myRank = await redisClient().zrevrankAsync(unionKey, roleId);
|
||||
return myRank + 1;
|
||||
}
|
||||
|
||||
export async function getRankScore(key: string, serverId: number, field: string) {
|
||||
let score = await redisClient().zscoreAsync(getKeyName(key, serverId), field);
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按军团名拼接key
|
||||
* @param key
|
||||
* @param guildCode 军团编号
|
||||
*/
|
||||
export function getGuildKeyName(key: string, guildCode: string) {
|
||||
return `${key}:${guildCode}`;
|
||||
}
|
||||
/**************** 军团活动排行end */
|
||||
@@ -42,6 +42,35 @@ export function battle(session: Session, msg: any, app: Application, cb: (err: E
|
||||
cb(null, res.id);
|
||||
}
|
||||
|
||||
|
||||
export function guild(session: Session, msg: any, app: Application, cb: (err: Error , serverId ?: string) => void) {
|
||||
let guildServers = app.getServersByType('guild');
|
||||
|
||||
if(!guildServers || guildServers.length === 0) {
|
||||
cb(new Error('can not find guild servers.'));
|
||||
return;
|
||||
}
|
||||
|
||||
let rid = session.get('roleId');
|
||||
|
||||
if (msg.args && msg.args.length > 0) {
|
||||
for (let arg of msg.args) {
|
||||
if (!arg.route) continue;
|
||||
|
||||
if (['guild.gateActivityHandler.checkBattle', // 军团活动蛮夷入侵路由,按军团路由
|
||||
'guild.gateActivityHandler.action',
|
||||
'guild.gateActivityHandler.hitGate',
|
||||
'guild.gateActivityHandler.battleEnd'
|
||||
].indexOf(arg.route) !== -1) {
|
||||
rid = session.get('guildCode');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let res = dispatch(rid, guildServers);
|
||||
cb(null, res.id);
|
||||
}
|
||||
|
||||
export function gm(session: Session, msg: any, app: Application, cb: (err: Error , serverId ?: string) => void) {
|
||||
let gmServers = app.getServersByType('gm');
|
||||
|
||||
|
||||
@@ -19,4 +19,7 @@ module.exports = [{
|
||||
}, {
|
||||
'type': 'systimer',
|
||||
'token': 'agarxhqb98rpajloaxn34ga8xrunpagkjwlaw3ruxnpaagl29w4rxn'
|
||||
}, {
|
||||
'type': 'guild',
|
||||
'token': 'agarxhqb98rpajloaxn34ga8xrunpagkjwlaw3ruxnpaagl29w4rxn'
|
||||
}];
|
||||
@@ -10,6 +10,8 @@ declare module 'redis' {
|
||||
delAsync(key: string): Promise<number>;
|
||||
// 设置过期时间
|
||||
expireAsync(key: string, time: number): Promise<number>;
|
||||
// 按时间戳设置过期时间
|
||||
expireatAsync(key: string, time: number): Promise<number>;
|
||||
// string类型存储
|
||||
setexAsync(key: string, time: number, value: string): Promise<number>;
|
||||
// 获取存储string类型value
|
||||
@@ -52,6 +54,12 @@ declare module 'redis' {
|
||||
zrevrankAsync(key: string, field: string): Promise<number>;
|
||||
// 命令返回有序集中,指定区间内的成员,从大到小
|
||||
zrevrangeAsync(key: string, start: number, end: number): Promise<string[]>;
|
||||
// 对有序集合中指定成员的分数加上增量 increment
|
||||
zincrbyAsync(key: string, increment: number, member: string): Promise<number>;
|
||||
// 对有序集合中指定成员的分数加上增量 increment
|
||||
zunionstoreAsync(destination: string, numkeys: number, ...args: any): Promise<number>;
|
||||
// 返回有序集中,成员的分数值
|
||||
zscoreAsync(key: string, member: string): Promise<number>;
|
||||
// 显示集合成员
|
||||
smembersAsync(key: string): Promise<string[]>;
|
||||
// 增加集合成员
|
||||
|
||||
@@ -43,6 +43,10 @@ module.exports = {
|
||||
],
|
||||
'systimer': [
|
||||
{'id': 'systimer-server-1', 'host': '127.0.0.1', 'port': 6056, "args": " --inspect=9233"}
|
||||
],
|
||||
'guild': [
|
||||
{'id': 'guild-server-1', 'host': '127.0.0.1', 'port': 6057, "args": " --inspect=9238"},
|
||||
{'id': 'guild-server-2', 'host': '127.0.0.1', 'port': 6058, "args": " --inspect=9238"}
|
||||
]
|
||||
},
|
||||
'production': {
|
||||
@@ -75,6 +79,10 @@ module.exports = {
|
||||
],
|
||||
'systimer': [
|
||||
{'id': 'systimer-server-1', 'host': '127.0.0.1', 'port': 6056}
|
||||
],
|
||||
'guild': [
|
||||
{'id': 'guild-server-1', 'host': '127.0.0.1', 'port': 6057, "args": " --inspect=9238"},
|
||||
{'id': 'guild-server-2', 'host': '127.0.0.1', 'port': 6058, "args": " --inspect=9238"}
|
||||
]
|
||||
},
|
||||
'alpha': {
|
||||
@@ -109,6 +117,10 @@ module.exports = {
|
||||
],
|
||||
'systimer': [
|
||||
{'id': 'systimer-server-1', 'host': '127.0.0.1', 'port': 6056}
|
||||
],
|
||||
'guild': [
|
||||
{'id': 'guild-server-1', 'host': '127.0.0.1', 'port': 6057, "args": " --inspect=9238"},
|
||||
{'id': 'guild-server-2', 'host': '127.0.0.1', 'port': 6058, "args": " --inspect=9238"}
|
||||
]
|
||||
},
|
||||
'dev': {
|
||||
@@ -144,6 +156,10 @@ module.exports = {
|
||||
],
|
||||
'systimer': [
|
||||
{'id': 'systimer-server-1', 'host': '127.0.0.1', 'port': 6056, "args": " --inspect=9233"}
|
||||
],
|
||||
'guild': [
|
||||
{'id': 'guild-server-1', 'host': '127.0.0.1', 'port': 6057, "args": " --inspect=9238"},
|
||||
{'id': 'guild-server-2', 'host': '127.0.0.1', 'port': 6058, "args": " --inspect=9238"}
|
||||
]
|
||||
},
|
||||
'isbn': {
|
||||
@@ -176,6 +192,10 @@ module.exports = {
|
||||
],
|
||||
'systimer': [
|
||||
{'id': 'systimer-server-1', 'host': '127.0.0.1', 'port': 6056}
|
||||
],
|
||||
'guild': [
|
||||
{'id': 'guild-server-1', 'host': '127.0.0.1', 'port': 6057, "args": " --inspect=9238"},
|
||||
{'id': 'guild-server-2', 'host': '127.0.0.1', 'port': 6058, "args": " --inspect=9238"}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -134,4 +134,18 @@ export enum GUILD_POINT_WAYS {
|
||||
TRAIN = 2, // 训练场
|
||||
BOSS_WAR = 3, // 演武台
|
||||
ACTIVITY = 4, // 军团活动
|
||||
}
|
||||
|
||||
// 军团活动id
|
||||
export enum GUILD_ACTIVITY_TYPE {
|
||||
GATE_ACTIVITY = 1, // 蛮夷入侵
|
||||
CITY_ACTIVITY = 2, // 诸侯混战
|
||||
RACE_ACTIVITY = 3 // 粮草先行
|
||||
}
|
||||
|
||||
// 军团活动状态
|
||||
export enum GUILD_ACTIVITY_STATUS {
|
||||
WAITING = 0,
|
||||
START = 1,
|
||||
END = 2
|
||||
}
|
||||
@@ -231,14 +231,18 @@ export const REDIS_KEY = {
|
||||
GUILD_ACTIVE_RANK: "guildActiveRank", // 公会周活跃排行榜
|
||||
DB_GAME: 'db_game', // 服务器列表
|
||||
ONLINE_USERS: 'onlineUsers', // 在线用户情况
|
||||
CHANNEL_SERVERS: 'chat:channelServers', // 渠道对应的 chat 服务器 Id
|
||||
CHANNEL_SERVERS: 'chat:channelServers', // 渠道对应的 chat 服务器 Id,
|
||||
USER_GUILD_ACTIVITY: 'usrGuildAct',
|
||||
GUILD_ACTIVITY: 'guildAct',
|
||||
}
|
||||
|
||||
// 各排行榜对应hash的key
|
||||
export const REDIS_RANK_TO_INFO = new Map([
|
||||
[REDIS_KEY.TOWER_RANK, REDIS_KEY.USER_INFO],
|
||||
[REDIS_KEY.PVP_RANK, REDIS_KEY.USER_INFO],
|
||||
[REDIS_KEY.GUILD_ACTIVE_RANK, REDIS_KEY.GUILD_INFO]
|
||||
[REDIS_KEY.GUILD_ACTIVE_RANK, REDIS_KEY.GUILD_INFO],
|
||||
[REDIS_KEY.GUILD_ACTIVITY, REDIS_KEY.GUILD_INFO],
|
||||
[REDIS_KEY.USER_GUILD_ACTIVITY, REDIS_KEY.USER_INFO]
|
||||
]);
|
||||
|
||||
export const FUNC_OPT_TYPE = {
|
||||
@@ -335,7 +339,9 @@ export const FILENAME = {
|
||||
DIC_ARMY_BOSS_RANK_REWARD: 'dic_army_bossrankReward',
|
||||
DIC_ARMY_DONATE_BOX_REWARD: 'dic_army_donateBoxReward',
|
||||
DIC_ROLE_FRIEND: 'dic_zyz_friends',
|
||||
DIC_ROLE_FRIEND_LEVEL: 'dic_zyz_closelevel'
|
||||
DIC_ROLE_FRIEND_LEVEL: 'dic_zyz_closelevel',
|
||||
DIC_GUILD_ACTIVITY: 'dic_zyz_guildActivity',
|
||||
DIC_GATE_ACTIVITY_POINT: 'dic_zyz_gateActivityPoint'
|
||||
}
|
||||
|
||||
export const WAR_RELATE_TABLES = [
|
||||
|
||||
@@ -192,9 +192,12 @@ export const STATUS = {
|
||||
GUILD_TRAIN_BOX_INDEX_IS_GOT:{ code: 20972, simStr: '该位置试炼宝箱已经领取过,请重新选择' },
|
||||
GUILD_TRAIN_BOX_IS_GOT: { code: 20973, simStr: '玩家已经领取该试炼宝箱' },
|
||||
|
||||
// 军团拍卖
|
||||
GUILD_LOT_NOT_FOUND: { code: 21001, simStr: '拍品未找到' },
|
||||
LOT_OFFER_SERIAL: { code: 21002, simStr: '不能连续出价' },
|
||||
|
||||
// 军团活动 21100-21199
|
||||
GUILD_ACTIVITY_NOT_OPEN: { code: 21100, simStr: '活动未开放' },
|
||||
|
||||
// 通用 30000 - 30099
|
||||
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },
|
||||
ROLE_MATERIAL_NOT_ENOUGH: { code: 30001, simStr: '材料数量不足' },
|
||||
|
||||
80
shared/db/GuildActivityRec.ts
Normal file
80
shared/db/GuildActivityRec.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
|
||||
import { ItemReward } from '../domain/dbGeneral';
|
||||
import { getTodayZeroDate } from '../pubUtils/timeUtil';
|
||||
import { genCode } from '../pubUtils/util';
|
||||
|
||||
|
||||
@index({ code: 1 })
|
||||
export default class GuildActivityRecord extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
code: string; // 本次记录唯一值
|
||||
|
||||
@prop({ required: true })
|
||||
guildCode: string; // 军团code
|
||||
|
||||
@prop({ required: true })
|
||||
serverId: number; // 分服
|
||||
|
||||
@prop({ required: true })
|
||||
aid: number; // 军团活动id
|
||||
|
||||
@prop({ required: true, default: false })
|
||||
isSuccess: boolean; // 是否胜利
|
||||
|
||||
@prop({ required: true, default: false })
|
||||
isCompleted: boolean; // 是否胜利
|
||||
|
||||
@prop({ required: true })
|
||||
rank: number; // 最终排名
|
||||
|
||||
@prop({ required: true, type: String, default: [] })
|
||||
members: string[]; // 参与活动的团员的roleId列表
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
memberCnt: number; // 参加的团员的数量
|
||||
|
||||
@prop({ required: true, type: ()=> ItemReward, default: [] })
|
||||
rewards: ItemReward[]; // 转到拍卖行的道具
|
||||
|
||||
@prop({ required: true })
|
||||
score: number; // 蛮夷入侵总军功
|
||||
|
||||
@prop({ required: true })
|
||||
cityId: number; // 诸侯混战占领了的城池
|
||||
|
||||
@prop({ required: true })
|
||||
damage: number; // 对城门造成的伤害
|
||||
|
||||
@prop({ required: true })
|
||||
raceTime: number; // 粮草先行比赛时间(s)
|
||||
|
||||
@prop({ required: true })
|
||||
distance: number; // 粮草先行最后的距离
|
||||
|
||||
@prop({ required: true })
|
||||
speed: number; // 粮草先行最后的速度(m/s)
|
||||
|
||||
@prop({ required: true })
|
||||
durability: number; // 粮草先行最后的耐久度
|
||||
|
||||
// 每天一条记录
|
||||
public static async getRecord(guildCode: string, serverId: number, aid: number) {
|
||||
let today = getTodayZeroDate();
|
||||
let docs = new GuildActivityRecordModel();
|
||||
let code = genCode(10);
|
||||
let update = Object.assign(docs, { code, guildCode, serverId, aid, createdAt: new Date() })
|
||||
let rec: GuildActivityRecordType = await GuildActivityRecordModel.findOneAndUpdate(
|
||||
{ guildCode, createdAt: { $gte: today }},
|
||||
{ $setOnInsert: update },
|
||||
{new: true, upsert: true}).lean();
|
||||
return rec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const GuildActivityRecordModel = getModelForClass(GuildActivityRecord);
|
||||
|
||||
export interface GuildActivityRecordType extends Pick<DocumentType<GuildActivityRecord>, keyof GuildActivityRecord> { };
|
||||
export type GuildActivityRecordUpdateParam = Partial<GuildActivityRecordType>; // 将所有字段变成可选项
|
||||
@@ -4,7 +4,7 @@ import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typ
|
||||
import User from './User';
|
||||
import { shouldRefresh, reduceCe } from '../pubUtils/util';
|
||||
import { initRoleAtrr } from '../pubUtils/playerCe';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
import { nowSeconds, getBeforeDayDate } from '../pubUtils/timeUtil';
|
||||
import { Figure } from '../domain/dbGeneral';
|
||||
import { EXTERIOR } from '../pubUtils/dicParam';
|
||||
import Hero from './Hero';
|
||||
@@ -483,7 +483,7 @@ export default class Role extends BaseModel {
|
||||
* @param invitedMembers 当天已邀请过的人
|
||||
*/
|
||||
public static async getInviteList(time: number, serverId: number) {
|
||||
const result = await RoleModel.find({ loginTime: { $gt: time }, hasGuild: false, serverId })
|
||||
const result: RoleType[] = await RoleModel.find({ loginTime: { $gt: time }, hasGuild: false, serverId })
|
||||
.select({roleId: 1, roleName: 1,ce: 1, head: 1, frame: 1, lv: 1,title: 1,job: 1,quitTime: 1, _id: 0})
|
||||
.sort({quitTime: -1, lv: -1, ce: -1})
|
||||
.limit(100).lean({getters: true, virtuals: true});
|
||||
@@ -492,7 +492,7 @@ export default class Role extends BaseModel {
|
||||
|
||||
// 获取好友推荐列表
|
||||
public static async getRecommedList(minLv: number, maxLv: number, time: number) {
|
||||
const result = await RoleModel.find({ loginTime: { $gt: time }, lv: { $gte: minLv, $lte: maxLv } }, { _id: 0 })
|
||||
const result: RoleType[] = await RoleModel.find({ loginTime: { $gt: time }, lv: { $gte: minLv, $lte: maxLv } }, { _id: 0 })
|
||||
.select(ROLE_SELECT.SHOW_FRIEND_APPLY_LIST)
|
||||
.sort({quitTime: -1, lv: -1, ce: -1})
|
||||
.limit(200).lean({ getters: true, virtuals: true });
|
||||
@@ -501,7 +501,7 @@ export default class Role extends BaseModel {
|
||||
|
||||
// 查询玩家
|
||||
public static async searchByNameOrId(value: string) {
|
||||
const result = await RoleModel.find({
|
||||
const result: RoleType[] = await RoleModel.find({
|
||||
$or: [
|
||||
{ roleName: { $regex: new RegExp(value.toString(), 'i') } },
|
||||
{ roleId: value }
|
||||
@@ -521,7 +521,7 @@ export default class Role extends BaseModel {
|
||||
|
||||
// 退出公会
|
||||
public static async quitGuild(roleId: string, now: number) {
|
||||
const result = await RoleModel.findOneAndUpdate({ roleId, hasGuild: true }, { hasGuild: false, guildCode: "", guildName: "", quitGuildTime: now }, { new: true }).lean();
|
||||
const result: RoleType = await RoleModel.findOneAndUpdate({ roleId, hasGuild: true }, { hasGuild: false, guildCode: "", guildName: "", quitGuildTime: now }, { new: true }).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -531,35 +531,44 @@ export default class Role extends BaseModel {
|
||||
if(max) {
|
||||
condition['friendCnt'] = {$lte: max - inc};
|
||||
}
|
||||
const result = await RoleModel.findOneAndUpdate(condition, {$inc: { friendCnt: inc }}, {new: true}).lean();
|
||||
const result: RoleType = await RoleModel.findOneAndUpdate(condition, {$inc: { friendCnt: inc }}, {new: true}).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
// 增加好友申请数量
|
||||
public static async increaseFriendApplyCnt(roleId: string, inc: number, max: number) {
|
||||
const result = await RoleModel.findOneAndUpdate({ roleId, recFrdApplyCnt: {$lte: max - inc}}, {$inc: { recFrdApplyCnt: inc }}, {new: true}).lean();
|
||||
const result: RoleType = await RoleModel.findOneAndUpdate({ roleId, recFrdApplyCnt: {$lte: max - inc}}, {$inc: { recFrdApplyCnt: inc }}, {new: true}).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
// 增加黑名单数量
|
||||
public static async increaseBlockCnt(roleId: string, blockCnt: number, friendCnt: number, maxBlockCnt: number) {
|
||||
const result = await RoleModel.findOneAndUpdate({ roleId, blockCnt: {$lte: maxBlockCnt - blockCnt}}, {$inc: { blockCnt, friendCnt }}, {new: true}).lean();
|
||||
const result: RoleType = await RoleModel.findOneAndUpdate({ roleId, blockCnt: {$lte: maxBlockCnt - blockCnt}}, {$inc: { blockCnt, friendCnt }}, {new: true}).lean();
|
||||
return result;
|
||||
}
|
||||
public static async updatedRoleMailAt(roleId: string, updatedMailAt: number, lean = true) {
|
||||
const result = await RoleModel.findOneAndUpdate({ roleId }, {$set: { updatedMailAt }}, {new: true}).lean(lean);
|
||||
const result: RoleType = await RoleModel.findOneAndUpdate({ roleId }, {$set: { updatedMailAt }}, {new: true}).lean(lean);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async addFigure(roleId: string, id: number, figure: Figure) {
|
||||
const result = await RoleModel.findOneAndUpdate({roleId}, { $pull: { heads: { id: id }, $push: { heads: figure } }}, {new: true}).lean();
|
||||
const result: RoleType = await RoleModel.findOneAndUpdate({roleId}, { $pull: { heads: { id: id }, $push: { heads: figure } }}, {new: true}).lean();
|
||||
return result
|
||||
}
|
||||
|
||||
public static async checkName(roleName: string, serverId: number) {
|
||||
const role = await RoleModel.findOne({ roleName, serverId }).lean();
|
||||
const role: RoleType = await RoleModel.findOne({ roleName, serverId }).lean();
|
||||
return !!role;
|
||||
}
|
||||
|
||||
// 获取战力在中位数的玩家
|
||||
public static async getMedianRole(serverId: number) {
|
||||
let yesterday = getBeforeDayDate(1);
|
||||
const roles: RoleType[] = await RoleModel.find({ serverId, updatedAt: { $gte: new Date(yesterday) } })
|
||||
.select('topLineup')
|
||||
.sort({ ce: -1 }).lean();
|
||||
return roles[Math.floor(roles.length/2)]
|
||||
}
|
||||
}
|
||||
|
||||
export const RoleModel = getModelForClass(Role);
|
||||
|
||||
87
shared/db/Serverlist.ts
Normal file
87
shared/db/Serverlist.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { APP_ID } from './../consts';
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||||
|
||||
// 暂时服务器列表是从game表取的,之后会转移到使用这张表,目前用作查询该服战力中位数
|
||||
|
||||
/**
|
||||
* 游戏字段接口
|
||||
*/
|
||||
@index({ id: 1 })
|
||||
@modelOptions({schemaOptions: {id: false}})
|
||||
export default class Serverlist extends BaseModel {
|
||||
|
||||
@prop({ required: true, default: 1 })
|
||||
gameId: number; // 游戏id Game表的id
|
||||
|
||||
@prop({ required: true })
|
||||
id: number; // 小区id
|
||||
|
||||
@prop({ required: true })
|
||||
name: string; // 小区区名
|
||||
|
||||
@prop({ required: true })
|
||||
groupId: number; // 大区id
|
||||
|
||||
@prop({ required: true })
|
||||
groupName: string; // 大区区名
|
||||
|
||||
@prop({ required: true })
|
||||
host: string; // pinus连接地址
|
||||
|
||||
@prop({ required: false })
|
||||
port: number; // pinus端口
|
||||
|
||||
@prop({ required: true })
|
||||
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;
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
medianCe: number; // 中位数武将战力、缩小10000倍后的结果
|
||||
|
||||
public static async getAllServerList() {
|
||||
let servers: ServerlistType[] = await ServerlistModel.find().lean({ getters: true, virtuals: true });
|
||||
return servers;
|
||||
}
|
||||
|
||||
public static async findByServerId(serverId: number) {
|
||||
let server: ServerlistType = await ServerlistModel.findOne({ id: serverId }).select('medianCe').lean({ getters: true, virtuals: true });
|
||||
return server;
|
||||
}
|
||||
|
||||
public static async updateByServerId(serverId: number, update: ServerlistUpdate) {
|
||||
let server: ServerlistType = await ServerlistModel.findOneAndUpdate({id: serverId}, {$set: update}).lean({ getters: true, virtuals: true });
|
||||
return server;
|
||||
}
|
||||
|
||||
public static async newServer(serverId: number, serverType: string, params: ServerlistUpdate) {
|
||||
const doc = new ServerlistModel();
|
||||
const update = Object.assign(doc.toJSON(), { id: serverId, serverType }, params);
|
||||
let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id: serverId, serverType }, {$setOnInsert: update }, {new: true, upsert: true}).lean({ getters: true, virtuals: true });
|
||||
return server;
|
||||
}
|
||||
}
|
||||
|
||||
export const ServerlistModel = getModelForClass(Serverlist);
|
||||
|
||||
export interface ServerlistType extends Pick<DocumentType<Serverlist>, keyof Serverlist>{
|
||||
id: number;
|
||||
};
|
||||
export type ServerlistUpdate = Partial<ServerlistType>; // 将所有字段变成可选项
|
||||
97
shared/db/UserGuildActivityRec.ts
Normal file
97
shared/db/UserGuildActivityRec.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
|
||||
import { getTodayZeroDate } from '../pubUtils/timeUtil';
|
||||
import { genCode } from '../pubUtils/util';
|
||||
|
||||
export class Record {
|
||||
@prop({ required: true })
|
||||
round: number; // 第几回合
|
||||
|
||||
@prop({ required: true })
|
||||
dataId: number; // 出兵表上的dataId
|
||||
|
||||
@prop({ required: true })
|
||||
score: number; // 得分
|
||||
}
|
||||
|
||||
@index({ code: 1 })
|
||||
export default class UserGuildActivityRec extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
code: string; // 本次记录唯一值
|
||||
|
||||
@prop({ required: true })
|
||||
sourceCode: string; // 军团记录的code
|
||||
|
||||
@prop({ required: true })
|
||||
roleId: string; // 玩家id
|
||||
|
||||
@prop({ required: true })
|
||||
roleName: string; // 军团唯一记录
|
||||
|
||||
@prop({ required: true })
|
||||
guildCode: string; // 军团code
|
||||
|
||||
@prop({ required: true })
|
||||
serverId: number; // 分服
|
||||
|
||||
@prop({ required: true })
|
||||
aid: number; // 军团活动id
|
||||
|
||||
@prop({ required: true, default: false })
|
||||
isSuccess: boolean; // 是否胜利
|
||||
|
||||
@prop({ required: true, default: false })
|
||||
isCompleted: boolean; // 是否完成结算了
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
rank: number; // 最终排名
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
challengeCnt: number; // 向上累加的挑战次数
|
||||
|
||||
// 南蛮入侵字段
|
||||
|
||||
@prop({ required: true, type: Number })
|
||||
heroes: number[]; // 使用的武将
|
||||
|
||||
@prop({ required: true })
|
||||
round: number; // 坚持回合数
|
||||
|
||||
@prop({ required: true })
|
||||
score: number; // 个人总军功
|
||||
|
||||
@prop({ required: true, type: Record })
|
||||
record: Record[]; // 个人总军功
|
||||
|
||||
// 每天一条记录
|
||||
public static async getRecord(roleId: string, roleName: string, guildCode: string, serverId: number, sourceCode: string, heroes: number[], aid: number) {
|
||||
let today = getTodayZeroDate();
|
||||
let docs = new UserGuildActivityRecModel();
|
||||
let code = genCode(10);
|
||||
let update = Object.assign(docs, { code, roleId, roleName, guildCode, serverId, aid });
|
||||
delete update.heroes;
|
||||
let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate(
|
||||
{ roleId, sourceCode, createdAt: { $gte: today }},
|
||||
{ $setOnInsert: update },
|
||||
{new: true, upsert: true}).lean();
|
||||
if(heroes.length > 0 && rec) {
|
||||
rec = await UserGuildActivityRecModel.findOneAndUpdate( { code: rec.code}, { $push: { heroes: { $each: heroes}}}, {new: true}).lean();
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
public static async pushRecord(code: string, records: Record[]) {
|
||||
let rec: UserGuildActivityRec = await UserGuildActivityRecModel.findOneAndUpdate(
|
||||
{ code },
|
||||
{ $push: { record: { $each: records } } },
|
||||
{ new: true }
|
||||
).lean();
|
||||
return rec;
|
||||
}
|
||||
}
|
||||
|
||||
export const UserGuildActivityRecModel = getModelForClass(UserGuildActivityRec);
|
||||
|
||||
export interface UserGuildActivityRecType extends Pick<DocumentType<UserGuildActivityRec>, keyof UserGuildActivityRec> { };
|
||||
export type UserGuildActivityRecUpdateParam = Partial<UserGuildActivityRecType>; // 将所有字段变成可选项
|
||||
@@ -58,6 +58,8 @@ import { dicArmyDonate } from '../pubUtils/dictionary/DicArmyDonateBoxReward';
|
||||
import { dicRoleFriend, DicRoleFriend } from "./dictionary/DicRoleFriend";
|
||||
import { dicRoleFriendLv } from "./dictionary/DicRoleFriendLv";
|
||||
import { Attribute } from "../domain/roleField/attribute";
|
||||
import { dicGuildActivity } from './dictionary/DicGuildActivity';
|
||||
import { dicGateActivityPoint } from './dictionary/DicGateActivityPoint';
|
||||
|
||||
export const gameData = {
|
||||
blurprtCompose: dicBlueprtCompose,
|
||||
@@ -139,7 +141,9 @@ export const gameData = {
|
||||
armyDonateBox: dicArmyDonate,
|
||||
roleFriend: dicRoleFriend,
|
||||
roleFriendLv: dicRoleFriendLv,
|
||||
figureCondition: figureCondition
|
||||
figureCondition: figureCondition,
|
||||
guildActivity: dicGuildActivity,
|
||||
gateActivityPoint: dicGateActivityPoint
|
||||
};
|
||||
|
||||
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
||||
|
||||
@@ -34,6 +34,7 @@ export const PVP = {
|
||||
PVP_SEASON_DAYS: 30, // PVP一个赛季的时间
|
||||
PVP_OPPONENT_FREEREFRESH: 3, // pvp挑战对手每日免费刷新次数
|
||||
PVP_WINREWARD_UPLIMIT: 10, // 连胜奖励军功加成上限
|
||||
PVP_LINEUP_HEROS: 6, // pvp最多上阵人数
|
||||
};
|
||||
export const ARMY = {
|
||||
ARMY_CREAT_COST: 188, // 创建军团需要的元宝
|
||||
@@ -75,3 +76,27 @@ export const EXTERIOR = {
|
||||
EXTERIOR_FACECASE: 11301, // 默认头像框id
|
||||
EXTERIOR_APPEARANCE: 11419, // 默认形象id
|
||||
};
|
||||
export const HTTPMANAGE = {
|
||||
ADDRESSTYPE: 1, // 1:开发服,2:审核服,3:版号服
|
||||
SERVERTYPE: 1, // ADDRESSTYPE下服务器的筛选:1:开发服,2:玩家服
|
||||
};
|
||||
export const SYSTEAM = {
|
||||
RECENT_GROUP_MSGS_CNT: 10, // 群消息获取条数
|
||||
RECENT_PRIVATE_CHATS_CNT: 20, // 最近私聊个数
|
||||
MSG_TYPE: 0, // 0:纯文本,1:副文本,2:表情
|
||||
};
|
||||
export const GUILDACTIVITY = {
|
||||
GATEACTIVITY_CHALLENGE_TIMES: 1, // 蛮夷入侵每天可以挑战次的次数
|
||||
GATEACTIVITY_HONOUR_RATIO: 0.5, // 功勋/积分的系数
|
||||
GATEACTIVITY_ENEMYCE: 2000, // 蛮夷入侵敌军2000战力模板
|
||||
GATEACTIVITY_ROUNDSTANDARD: 20, // 蛮夷入侵和基准战力相当的回合
|
||||
CITYACTIVITY_CHALLENGE_CD: 300, // 诸侯混战每次战斗之后的cd间隔
|
||||
CITYACTIVITY_CD_COST: 100, // 诸侯混战取消cd需要消耗的元宝数
|
||||
CITYACTIVITY_ROUND_COUNT: 40, // 诸侯混战的总回合数量
|
||||
RACEACTIVITY_LENGTH: 1000, // 粮草先行赛道的总米数
|
||||
RACEACTIVITY_ENCOUNTER: '100&1|200&2|300&2|400&1|500&2|600&2|700&1|800&2|900&2', // 触发道具和事件的米数(1:道具;2:事件)
|
||||
RACEACTIVITY_EVENT_RATIO: 0.5, // 触发事件好坏的比例
|
||||
GATEACTIVITY_GATEHP: 10000, // 城门血量
|
||||
GATEACTIVITY_BOSS_DIFFICULT: '1&1.2|2&1.5', // boss类型&难度系数|boss类型&难度系数(1:小boss,2:大boss)
|
||||
RACEACTIVITY_DURABILITY_REWARD: 2, // 每剩余1%耐久度给予X点功勋
|
||||
};
|
||||
|
||||
15
shared/pubUtils/dictionary/DicGateActivityPoint.ts
Normal file
15
shared/pubUtils/dictionary/DicGateActivityPoint.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { readJsonFile } from '../util'
|
||||
import { FILENAME } from '../../consts'
|
||||
|
||||
export interface DicGkPvp {
|
||||
readonly id: number;
|
||||
readonly point: number;
|
||||
}
|
||||
|
||||
const str = readJsonFile(FILENAME.DIC_GATE_ACTIVITY_POINT);
|
||||
let arr = JSON.parse(str);
|
||||
|
||||
export const dicGateActivityPoint = new Map<number, number>();
|
||||
arr.forEach(o => {
|
||||
dicGateActivityPoint.set(o.id, o.point);
|
||||
});
|
||||
33
shared/pubUtils/dictionary/DicGuildActivity.ts
Normal file
33
shared/pubUtils/dictionary/DicGuildActivity.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// 军团活动
|
||||
import { readJsonFile, parseNumberList } from '../util'
|
||||
import { FILENAME } from '../../consts'
|
||||
|
||||
export interface DicGuildActivity {
|
||||
|
||||
// id
|
||||
readonly id: number;
|
||||
// 开启日期 星期几
|
||||
readonly openDay: number[];
|
||||
// 持续时间 秒
|
||||
readonly duringTime: number;
|
||||
// 开启时间 几点
|
||||
readonly startTime: number;
|
||||
// 开始倒计时 几点
|
||||
readonly countDown: number;
|
||||
// 对应关卡id
|
||||
readonly warid: number;
|
||||
// 基础功勋值
|
||||
readonly honour: number;
|
||||
|
||||
}
|
||||
|
||||
const str = readJsonFile(FILENAME.DIC_GUILD_ACTIVITY);
|
||||
let arr = JSON.parse(str);
|
||||
|
||||
export const dicGuildActivity = new Map<number, DicGuildActivity>();
|
||||
|
||||
arr.forEach(o => {
|
||||
o.openDay = parseNumberList(o.openDay)
|
||||
dicGuildActivity.set( o.id, o );
|
||||
});
|
||||
arr = undefined;
|
||||
@@ -41,6 +41,8 @@ export interface DicWarJson {
|
||||
readonly spine: string;
|
||||
// boss阶段
|
||||
readonly bossStage: number;
|
||||
// 敌人是小boss还是大boss,和gateActivityPoint的id相对应
|
||||
readonly enemyType: number;
|
||||
// 召唤技能的召唤物
|
||||
readonly callSkillData: string;
|
||||
|
||||
|
||||
@@ -88,6 +88,22 @@ export function getCurHourPoint(hour: number) {
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第2天凌晨几点的时间戳
|
||||
* @param hour
|
||||
*/
|
||||
export function getNextHourPoint(hour: number) {
|
||||
var date = new Date();
|
||||
date.setHours(hour);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
var time = Math.floor(date.getTime() / PER_SECOND);
|
||||
if (nowSeconds() > time) {
|
||||
return time + PER_DAY;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
export function getTodayZeroDate() {
|
||||
var date = new Date();
|
||||
date.setHours(0);
|
||||
@@ -145,3 +161,14 @@ export function getNextTime(date: Date, h: number, m = 0, s = 0): Date {
|
||||
const timeToday = new Date(milliseconds).setHours(h, m, s);
|
||||
return timeToday > milliseconds ? new Date(timeToday) : new Date(timeToday + PER_DAY * PER_SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得某个时间是星期几
|
||||
* @param {Date} time
|
||||
*/
|
||||
export function getCutDay(time?: Date) {
|
||||
if(!time) time = new Date();
|
||||
let d = time.getDay();
|
||||
if(d == 0) d = 7;
|
||||
return d;
|
||||
}
|
||||
|
||||
82
shared/resource/jsons/dic_zyz_cityActivity.json
Normal file
82
shared/resource/jsons/dic_zyz_cityActivity.json
Normal file
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "汉中",
|
||||
"type": 1,
|
||||
"nextCity": 7,
|
||||
"difficult": 90,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "南中",
|
||||
"type": 1,
|
||||
"nextCity": 7,
|
||||
"difficult": 90,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "柴桑",
|
||||
"type": 1,
|
||||
"nextCity": 8,
|
||||
"difficult": 90,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "会稽",
|
||||
"type": 1,
|
||||
"nextCity": 8,
|
||||
"difficult": 90,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "太原",
|
||||
"type": 1,
|
||||
"nextCity": 9,
|
||||
"difficult": 90,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "巨鹿",
|
||||
"type": 1,
|
||||
"nextCity": 9,
|
||||
"difficult": 90,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "成都",
|
||||
"type": 2,
|
||||
"nextCity": 10,
|
||||
"difficult": 100,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "建业",
|
||||
"type": 2,
|
||||
"nextCity": 10,
|
||||
"difficult": 100,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "邺城",
|
||||
"type": 2,
|
||||
"nextCity": 10,
|
||||
"difficult": 100,
|
||||
"warid": 0
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "洛阳",
|
||||
"type": 3,
|
||||
"nextCity": 0,
|
||||
"difficult": 110,
|
||||
"warid": 0
|
||||
}
|
||||
]
|
||||
218
shared/resource/jsons/dic_zyz_cityActivityReward.json
Normal file
218
shared/resource/jsons/dic_zyz_cityActivityReward.json
Normal file
@@ -0,0 +1,218 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"type": 1,
|
||||
"guildRank": 1,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 2000
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": 1,
|
||||
"guildRank": 1,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 1200
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type": 1,
|
||||
"guildRank": 1,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 800
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type": 1,
|
||||
"guildRank": 2,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 1200
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"type": 1,
|
||||
"guildRank": 2,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 720
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": 1,
|
||||
"guildRank": 2,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 480
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"type": 1,
|
||||
"guildRank": 3,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 800
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": 1,
|
||||
"guildRank": 3,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 480
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": 1,
|
||||
"guildRank": 3,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 240
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"type": 2,
|
||||
"guildRank": 1,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 4000
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"type": 2,
|
||||
"guildRank": 1,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 2400
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"type": 2,
|
||||
"guildRank": 1,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 1600
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"type": 2,
|
||||
"guildRank": 2,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 2400
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"type": 2,
|
||||
"guildRank": 2,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 1440
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"type": 2,
|
||||
"guildRank": 2,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 960
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"type": 2,
|
||||
"guildRank": 3,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 1600
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"type": 2,
|
||||
"guildRank": 3,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 960
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"type": 2,
|
||||
"guildRank": 3,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 480
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"type": 3,
|
||||
"guildRank": 1,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 12000
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"type": 3,
|
||||
"guildRank": 1,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 7200
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"type": 3,
|
||||
"guildRank": 1,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 4800
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"type": 3,
|
||||
"guildRank": 2,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 7200
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"type": 3,
|
||||
"guildRank": 2,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 4320
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"type": 3,
|
||||
"guildRank": 2,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 2880
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"type": 3,
|
||||
"guildRank": 3,
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"honour": 4800
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"type": 3,
|
||||
"guildRank": 3,
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"honour": 2880
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"type": 3,
|
||||
"guildRank": 3,
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"honour": 1440
|
||||
}
|
||||
]
|
||||
27
shared/resource/jsons/dic_zyz_gateActivityPoint.json
Normal file
27
shared/resource/jsons/dic_zyz_gateActivityPoint.json
Normal file
@@ -0,0 +1,27 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"getPointWays": "每回合开始时获得",
|
||||
"point": 10
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"getPointWays": "击杀小兵",
|
||||
"point": 3
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"getPointWays": "击杀小boss",
|
||||
"point": 30
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"getPointWays": "击杀大boss",
|
||||
"point": 90
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"getPointWays": "防守成功",
|
||||
"point": 100
|
||||
}
|
||||
]
|
||||
32
shared/resource/jsons/dic_zyz_guildActivity.json
Normal file
32
shared/resource/jsons/dic_zyz_guildActivity.json
Normal file
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "蛮夷入侵",
|
||||
"openDay": "3&0",
|
||||
"duringTime": 900,
|
||||
"startTime": 20,
|
||||
"countDown": 5,
|
||||
"warid": 7001,
|
||||
"honour": 500
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "诸侯混战",
|
||||
"openDay": "2&4&6",
|
||||
"duringTime": 900,
|
||||
"startTime": 20,
|
||||
"countDown": 5,
|
||||
"warid": 7002,
|
||||
"honour": 500
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "粮草先行",
|
||||
"openDay": "1&5",
|
||||
"duringTime": 600,
|
||||
"startTime": 20,
|
||||
"countDown": 5,
|
||||
"warid": 0,
|
||||
"honour": 200
|
||||
}
|
||||
]
|
||||
65
shared/resource/jsons/dic_zyz_guildAuction.json
Normal file
65
shared/resource/jsons/dic_zyz_guildAuction.json
Normal file
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "蛮夷入侵",
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"rewards": "20001&60&2|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "蛮夷入侵",
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"rewards": "20001&60&1|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "蛮夷入侵",
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"rewards": "20002&60&1|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "诸侯混战",
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"rewards": "20001&60&2|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "诸侯混战",
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"rewards": "20001&60&1|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "诸侯混战",
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"rewards": "20002&60&1|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "粮草先行",
|
||||
"min": 1,
|
||||
"max": 1,
|
||||
"rewards": "20001&60&2|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "粮草先行",
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"rewards": "20001&60&1|21008&40&1|42008&20&2|42115&20&3"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "粮草先行",
|
||||
"min": 11,
|
||||
"max": 0,
|
||||
"rewards": "20002&60&1|21008&40&1|42008&20&2|42115&20&3"
|
||||
}
|
||||
]
|
||||
347
shared/resource/warJsons/7001.json
Normal file
347
shared/resource/warJsons/7001.json
Normal file
@@ -0,0 +1,347 @@
|
||||
[
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 0,
|
||||
"relation": 0,
|
||||
"outIndex": 0,
|
||||
"dirction": 2,
|
||||
"x": 6,
|
||||
"y": 5,
|
||||
"var": 0,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 1,
|
||||
"relation": 0,
|
||||
"outIndex": 1,
|
||||
"dirction": 2,
|
||||
"x": 8,
|
||||
"y": 5,
|
||||
"var": 1,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 2,
|
||||
"relation": 0,
|
||||
"outIndex": 2,
|
||||
"dirction": 2,
|
||||
"x": 10,
|
||||
"y": 5,
|
||||
"var": 2,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 3,
|
||||
"relation": 0,
|
||||
"outIndex": 3,
|
||||
"dirction": 2,
|
||||
"x": 12,
|
||||
"y": 5,
|
||||
"var": 3,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 4,
|
||||
"relation": 0,
|
||||
"outIndex": 4,
|
||||
"dirction": 2,
|
||||
"x": 14,
|
||||
"y": 5,
|
||||
"var": 4,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 5,
|
||||
"relation": 0,
|
||||
"outIndex": 5,
|
||||
"dirction": 2,
|
||||
"x": 9,
|
||||
"y": 5,
|
||||
"var": 5,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "城门",
|
||||
"actorId": 1083,
|
||||
"dataId": 1001,
|
||||
"relation": 1,
|
||||
"outIndex": 6,
|
||||
"dirction": 2,
|
||||
"x": 10,
|
||||
"y": 11,
|
||||
"var": 1001,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 2,
|
||||
"attribute": "1&10000",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 0
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "步兵",
|
||||
"actorId": 1001,
|
||||
"dataId": 2001,
|
||||
"relation": 2,
|
||||
"outIndex": 0,
|
||||
"dirction": 1,
|
||||
"x": 8,
|
||||
"y": 9,
|
||||
"var": 2001,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 2,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "步兵",
|
||||
"actorId": 1001,
|
||||
"dataId": 2002,
|
||||
"relation": 2,
|
||||
"outIndex": 1,
|
||||
"dirction": 1,
|
||||
"x": 9,
|
||||
"y": 9,
|
||||
"var": 2002,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 0,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "步兵",
|
||||
"actorId": 1001,
|
||||
"dataId": 2003,
|
||||
"relation": 2,
|
||||
"outIndex": 2,
|
||||
"dirction": 1,
|
||||
"x": 10,
|
||||
"y": 9,
|
||||
"var": 2003,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 2,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "枪兵",
|
||||
"actorId": 1002,
|
||||
"dataId": 2004,
|
||||
"relation": 2,
|
||||
"outIndex": 3,
|
||||
"dirction": 1,
|
||||
"x": 11,
|
||||
"y": 9,
|
||||
"var": 2004,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 2,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "枪兵",
|
||||
"actorId": 1002,
|
||||
"dataId": 2005,
|
||||
"relation": 2,
|
||||
"outIndex": 4,
|
||||
"dirction": 1,
|
||||
"x": 9,
|
||||
"y": 10,
|
||||
"var": 2005,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 2,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "枪兵",
|
||||
"actorId": 1002,
|
||||
"dataId": 2006,
|
||||
"relation": 2,
|
||||
"outIndex": 5,
|
||||
"dirction": 1,
|
||||
"x": 10,
|
||||
"y": 10,
|
||||
"var": 2006,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0,
|
||||
"enemyType": 2,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "狼",
|
||||
"actorId": 1014,
|
||||
"dataId": 2007,
|
||||
"relation": 2,
|
||||
"outIndex": 6,
|
||||
"dirction": 1,
|
||||
"x": 10,
|
||||
"y": 11,
|
||||
"var": 2007,
|
||||
"lv": 0,
|
||||
"hide": 1,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "8001&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 1,
|
||||
"enemyType": 3,
|
||||
"dest_oppo": 1001
|
||||
},
|
||||
{
|
||||
"warId": 7001,
|
||||
"actorName": "怒狼王",
|
||||
"actorId": 1035,
|
||||
"dataId": 2008,
|
||||
"relation": 2,
|
||||
"outIndex": 7,
|
||||
"dirction": 1,
|
||||
"x": 11,
|
||||
"y": 11,
|
||||
"var": 2008,
|
||||
"lv": 0,
|
||||
"hide": 1,
|
||||
"initial_ai": 4,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "8001&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 1,
|
||||
"enemyType": 3,
|
||||
"dest_oppo": 1001
|
||||
}
|
||||
]
|
||||
275
shared/resource/warJsons/7002.json
Normal file
275
shared/resource/warJsons/7002.json
Normal file
@@ -0,0 +1,275 @@
|
||||
[
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 0,
|
||||
"relation": 0,
|
||||
"outIndex": 0,
|
||||
"dirction": 2,
|
||||
"x": 6,
|
||||
"y": 5,
|
||||
"var": 0,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 1,
|
||||
"relation": 0,
|
||||
"outIndex": 1,
|
||||
"dirction": 2,
|
||||
"x": 8,
|
||||
"y": 5,
|
||||
"var": 1,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 2,
|
||||
"relation": 0,
|
||||
"outIndex": 2,
|
||||
"dirction": 2,
|
||||
"x": 10,
|
||||
"y": 5,
|
||||
"var": 2,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 3,
|
||||
"relation": 0,
|
||||
"outIndex": 3,
|
||||
"dirction": 2,
|
||||
"x": 12,
|
||||
"y": 5,
|
||||
"var": 3,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 4,
|
||||
"relation": 0,
|
||||
"outIndex": 4,
|
||||
"dirction": 2,
|
||||
"x": 14,
|
||||
"y": 5,
|
||||
"var": 4,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "我军",
|
||||
"actorId": 0,
|
||||
"dataId": 5,
|
||||
"relation": 0,
|
||||
"outIndex": 5,
|
||||
"dirction": 2,
|
||||
"x": 9,
|
||||
"y": 5,
|
||||
"var": 5,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "&",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "步兵",
|
||||
"actorId": 1001,
|
||||
"dataId": 2001,
|
||||
"relation": 2,
|
||||
"outIndex": 0,
|
||||
"dirction": 1,
|
||||
"x": 8,
|
||||
"y": 9,
|
||||
"var": 2001,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "步兵",
|
||||
"actorId": 1001,
|
||||
"dataId": 2002,
|
||||
"relation": 2,
|
||||
"outIndex": 1,
|
||||
"dirction": 1,
|
||||
"x": 9,
|
||||
"y": 9,
|
||||
"var": 2002,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "步兵",
|
||||
"actorId": 1001,
|
||||
"dataId": 2003,
|
||||
"relation": 2,
|
||||
"outIndex": 2,
|
||||
"dirction": 1,
|
||||
"x": 10,
|
||||
"y": 9,
|
||||
"var": 2003,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "枪兵",
|
||||
"actorId": 1002,
|
||||
"dataId": 2004,
|
||||
"relation": 2,
|
||||
"outIndex": 3,
|
||||
"dirction": 1,
|
||||
"x": 11,
|
||||
"y": 9,
|
||||
"var": 2004,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "枪兵",
|
||||
"actorId": 1002,
|
||||
"dataId": 2005,
|
||||
"relation": 2,
|
||||
"outIndex": 4,
|
||||
"dirction": 1,
|
||||
"x": 9,
|
||||
"y": 10,
|
||||
"var": 2005,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "枪兵",
|
||||
"actorId": 1002,
|
||||
"dataId": 2006,
|
||||
"relation": 2,
|
||||
"outIndex": 5,
|
||||
"dirction": 1,
|
||||
"x": 10,
|
||||
"y": 10,
|
||||
"var": 2006,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 1,
|
||||
"attribute": "1&1400|2&1000|4&600|5&600|9&0|10&25000|11&20000|12&0|13&10000|14&10000|18&0",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 0
|
||||
},
|
||||
{
|
||||
"warId": 7002,
|
||||
"actorName": "城门",
|
||||
"actorId": 1083,
|
||||
"dataId": 2007,
|
||||
"relation": 2,
|
||||
"outIndex": 6,
|
||||
"dirction": 1,
|
||||
"x": 10,
|
||||
"y": 11,
|
||||
"var": 2007,
|
||||
"lv": 0,
|
||||
"hide": 0,
|
||||
"initial_ai": 2,
|
||||
"attribute": "1&10000",
|
||||
"skill": 0,
|
||||
"seid": "&",
|
||||
"star": 0,
|
||||
"spine": 0,
|
||||
"bossStage": 1
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user