diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index 5f76233be..a1fa5292f 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -76,6 +76,7 @@ export class EntryHandler { session.push('funcs', () => {}); session.push('updatedMailAt', () => {}); session.push('guildCode', () => {}); + console.log(role.guildCode) // session.push('rid', function (err) { // if (err) { // console.error('set rid for session service failed! error is : %j', err.stack); diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index bdc337fce..edd5f24fa 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -580,7 +580,7 @@ export class HeroHandler { if (!result) { return resResult(STATUS.HERO_SKIN_NOT_FIND); } - await calPlayerCeAndSave(HERO_SYSTEM_TYPE.SKIN, sid, roleId, hero, { skins: heroSkins }, [id, lastSkinId]); + hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.SKIN, sid, roleId, hero, { skins: heroSkins }, [id, lastSkinId]); return resResult(STATUS.SUCCESS, {curHero: {hid : hero.hid, skins : hero.skins} }); } } diff --git a/game-server/app/servers/role/handler/rankHandler.ts b/game-server/app/servers/role/handler/rankHandler.ts new file mode 100644 index 000000000..72343a1d1 --- /dev/null +++ b/game-server/app/servers/role/handler/rankHandler.ts @@ -0,0 +1,111 @@ +import { Application, BackendSession } from "pinus"; +import { resResult } from "../../../pubUtils/util"; +import { STATUS, REDIS_KEY } from "../../../consts"; +import { RoleModel, RoleType } from "../../../db/Role"; +import { UserGuildModel } from "../../../db/UserGuild"; +import { existsRank, initSingleRankWithServer, getRank } from "../../../services/redisService"; +import { GuildModel } from "../../../db/Guild"; +import { GuildRankParam } from "../../../domain/rank"; + +export default function(app: Application) { + return new RoleHandler(app); +} + +export class RoleHandler { + constructor(private app: Application) { + } + + async getGeneralRank(msg: { }, session: BackendSession) { + let roleId = session.get('roleId'); + let roleName = session.get('roleName'); + let serverId = session.get('serverId'); + + + return resResult(STATUS.SUCCESS, { + role: [ + { type: 1, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 464262, received: [],}, + { type: 2, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 64262, received: [],}, + { type: 3, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 100, received: [],}, + { type: 4, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 99, received: [],}, + ], + battle: [ // 右边列 + {type: 5, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 464262, received: [],}, + {type: 6, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 99, received: [],}, + {type: 7, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 5060, received: [],}, + {type: 8, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 323, received: [],}, + {type: 9, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 9224, received: [],}, + ] + }); + } + + async getRank(msg: { type: number }, session: BackendSession) { + let roleId = session.get('roleId'); + let roleName = session.get('roleName'); + let serverId = session.get('serverId'); + + let { type } = msg; + + let role = await RoleModel.findByRoleId(roleId, null, true); + let { lv, vLv, head, frame, spine, guildName, ce } = role; + + let lineup = [ + { hid: 27, star: 6, colorStar: 6, lv: 96, quality: 3 }, + { hid: 32, star: 6, colorStar: 6, lv: 96, quality: 3 }, + { hid: 19, star: 6, colorStar: 6, lv: 96, quality: 3 }, + { hid: 11, star: 6, colorStar: 6, lv: 96, quality: 3 }, + { hid: 12, star: 6, colorStar: 6, lv: 96, quality: 3 }, + { hid: 8, star: 6, colorStar: 6, lv: 96, quality: 3 } + ] + + let ranks = await RoleModel.getRank('tower', serverId, ["lv", "roleName", "vLv", "head", "frame", "spine", "guildName", "ce"]); + + return resResult(STATUS.SUCCESS, { + type, + ranks: ranks.map((cur, i) => { + let { roleId, roleName, head, frame, spine, lv, vLv, ce } = cur; + return { + rank: i+1, num: 323-i, roleId, roleName, head, frame, spine, lv, vLv, guildName: `军团${i + 1}`, ce, lineup + } + }), + myRank: { + rank: 0, num: 104, roleId, roleName, head, frame, spine, lv, vLv,guildName, ce, lineup + } + }); + } + + // 查看活跃排行榜 + async getGuildRank(msg: { type: number }, session: BackendSession) { + + let roleId = session.get('roleId'); + let serverId = session.get('serverId') + + let { type } = msg; + + const myUserGuild = await UserGuildModel.getMyGuild(roleId, 'auth guildCode'); + if(!myUserGuild) return resResult(STATUS.GUILD_NOT_FOUND); + + const hasRank = await existsRank(REDIS_KEY.GUILD_ACTIVE_RANK, serverId); + if(!hasRank) await initSingleRankWithServer(REDIS_KEY.GUILD_ACTIVE_RANK, serverId); + + let {ranks, myRank} = await getRank(REDIS_KEY.GUILD_ACTIVE_RANK, serverId, myUserGuild.guildCode); + if(!myRank) { + let guild = await GuildModel.findByCode(myUserGuild.guildCode, serverId, 'code icon name lv leader activeWeekly memberCnt'); + let {icon, name, lv, leader, activeWeekly, memberCnt} = guild; + let _leader = leader; + let param = new GuildRankParam(icon, name, lv, _leader, memberCnt); + myRank = {...param, num: activeWeekly, rank: 0}; + } + + return resResult(STATUS.SUCCESS, { type, ranks, myRank }); + } + + async receiveReward(msg: { type: number, id: number }, session: BackendSession) { + let { type } = msg; + + return resResult(STATUS.SUCCESS, { + type: type, + received: [], + goods: [] + }) + } +} \ No newline at end of file diff --git a/game-server/app/servers/role/handler/shopHandler.ts b/game-server/app/servers/role/handler/shopHandler.ts index a77b69503..1c4895f92 100644 --- a/game-server/app/servers/role/handler/shopHandler.ts +++ b/game-server/app/servers/role/handler/shopHandler.ts @@ -1,7 +1,7 @@ import { Application, BackendSession } from "pinus"; import { gameData } from "../../../pubUtils/data"; import { resResult } from "../../../pubUtils/util"; -import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE } from "../../../consts"; +import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GROW_MAX } from "../../../consts"; import { DicShopListModel } from "../../../db/DicShopList"; import { ShopItem } from "../../../domain/dbGeneral"; import { ShopItemListParam } from '../../../domain/roleField/shop'; @@ -161,6 +161,10 @@ export class ShopHandler { return resResult(STATUS.ITEM_NOT_SOUL); } + let hero = await HeroModel.findByHidAndRole(dicGoods.hid, roleId); + if(!hero) return resResult(STATUS.HERO_NOT_MAX); + if(hero.colorStar != HERO_GROW_MAX.COLORSTAR) return resResult(STATUS.HERO_NOT_MAX); + // 检查自己的数量 let cost = [{ id: goodsId, count diff --git a/game-server/app/services/guildActivityService.ts b/game-server/app/services/guildActivityService.ts index 28e480c05..82724e606 100644 --- a/game-server/app/services/guildActivityService.ts +++ b/game-server/app/services/guildActivityService.ts @@ -169,23 +169,19 @@ export async function getCityActivityRank(guildCode: string, serverId: number, c export async function getRaceActivityRank(guildCode: string, serverId: number) { let guildKey = REDIS_KEY.RACE_ACTIVITY; - let obj = getRaceActivityObj(); - let guildRankResult = await getUnionRank(guildKey, serverId, guildCode); + let guildRankResult = await getUnionRank(guildKey, serverId, guildCode, 6); let guildRank = new Array(); - for(let { rank, code, name, num } of guildRankResult.ranks) { - let _obj = await obj.getWoodenHorse(code, serverId); - let param = new SimpleGuildRankWithTimeParam(rank, code, name, _obj); + for(let { rank, code, name, num, time } of guildRankResult.ranks) { + let param = new SimpleGuildRankWithTimeParam(rank, code, name, { distance: num/1000, time: time * 1000, startTime: 0, durability: 0 }); guildRank.push(param); } let myGuildRank: SimpleGuildRankWithTimeParam; if(guildRankResult.myRank) { - let { rank, code, name, num } = guildRankResult.myRank; - let _obj = await obj.getWoodenHorse(code, serverId); - myGuildRank = new SimpleGuildRankWithTimeParam(rank, code, name, _obj); + let { rank, code, name, num, time } = guildRankResult.myRank; + myGuildRank = new SimpleGuildRankWithTimeParam(rank, code, name, { distance: num/1000, time: time * 1000, startTime: 0, durability: 0 }); } else { let guild = await GuildModel.findByCode(guildCode, serverId, 'name'); - let _obj = await obj.getWoodenHorse(guildCode, serverId); - myGuildRank = new SimpleGuildRankWithTimeParam(0, guildCode, guild?.name, _obj); + myGuildRank = new SimpleGuildRankWithTimeParam(0, guildCode, guild?.name, { distance: 0, time: 0, startTime: 0, durability: 0 }); } return { guildRank, myGuildRank } } @@ -581,7 +577,7 @@ export async function calWoodenHorseAndSend(serverId: number) { console.log('calWoodenHorseAndSend'); let guildKey = REDIS_KEY.RACE_ACTIVITY; let obj = getRaceActivityObj(); - let { ranks } = await getUnionRank(guildKey, serverId, ''); + let { ranks } = await getUnionRank(guildKey, serverId, '', 6); let map = new Map(); let guildRank = new Array(); diff --git a/game-server/app/services/redisService.ts b/game-server/app/services/redisService.ts index 5724194a7..5b03fba24 100644 --- a/game-server/app/services/redisService.ts +++ b/game-server/app/services/redisService.ts @@ -155,12 +155,12 @@ export async function redisUserInfoAdd(key: string, roleId: string, params: Rank * @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) { +export async function setRank(key: string, serverId: number, myId: string, score: number, timestamp: number, params: RankParam|GuildRankParam, isAtom = false, timelen = 10, limit = 100) { // 更新分数 let newScore = score; if(isAtom) { - newScore = await updateRankAtom(key, serverId, myId, score, timestamp); + newScore = await updateRankAtom(key, serverId, myId, score, timestamp, true, timelen); } else { const _score = encodeScoreWithTime(score, timestamp); await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId); @@ -177,11 +177,23 @@ export async function setRank(key: string, serverId: number, myId: string, score return parseInt(newScore.toString()); } -export async function setRankWithoutUserInfo(key: string, serverId: number, myId: string, score: number, timestamp: number, isAtom = false, isInc = true, limit = 100) { +export async function setRankWithoutUserInfo(key: string, serverId: number, myId: string, score: number, timestamp: number, isAtom = false, isInc = true, timelen=10, limit = 100) { + + let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO; + // 如果没有信息,更新玩家信息 + const hasCurUser = await redisClient().hexistsAsync(infoKey, myId); + if(!hasCurUser) { + let guild = await GuildModel.findByCode(myId, serverId); + + let leader = guild.leader; + let guildRankParam = new GuildRankParam(guild.icon, guild.name, guild.lv, leader); + await redisUserInfoAdd(infoKey, myId, guildRankParam); + } + // 更新分数 let newScore = score; if(isAtom) { - newScore = await updateRankAtom(key, serverId, myId, score, timestamp, isInc); + newScore = await updateRankAtom(key, serverId, myId, score, timestamp, isInc, timelen); } else { const _score = encodeScoreWithTime(score, timestamp); await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId); @@ -238,13 +250,20 @@ function encodeScoreWithTime(score: number, timestamp: number): number { return score * pow + pow - 1 - Math.floor(timestamp/1000) } -function decodeScoreWithTime(num: string): number { - let timelen = 10; +function decodeScoreWithTime(num: string, timelen: number = 10): number { let pow = Math.pow(10, timelen + 1); let _num = parseInt(num); return Math.floor(_num/pow); } +function decodeTime(num: string, timelen: number = 10): number { + let pow = Math.pow(10, timelen + 1); + let _num = parseInt(num); + let time = _num % pow; + console.log(pow, time, _num); + return pow - time; +} + // 从排行榜中移除 export async function removeFromRank(key: string, serverId: number, myId: string) { await redisClient().zremAsync(getKeyName(key, serverId), myId); @@ -578,13 +597,13 @@ function redisClient() { * @param score 得分 * @param time 事件 */ -async function updateRankAtom(key: string, serverId: number, field: string, score: number, timestamp: number, isInc = true) { +async function updateRankAtom(key: string, serverId: number, field: string, score: number, timestamp: number, isInc = true, timelen = 10) { let originKey = getKeyName(key, serverId); let timeKey = getKeyName(key, serverId, 'time'); - let timelen = 10; let pow = Math.pow(10, timelen + 1); let newScore = 0; + console.log('********', isInc, field, score, pow - 1 - Math.floor(timestamp/1000)); if(isInc) { newScore = await redisClient().zincrbyAsync(originKey, score, field); } else { @@ -634,10 +653,11 @@ export async function getUnionRank(key: string, serverId: number, roleId: string for(let ii = 0; ii < rankFromDb.length; ii+=2) { const _roleId = rankFromDb[ii]; - const _score = decodeScoreWithTime(rankFromDb[ii + 1]); + const _score = decodeScoreWithTime(rankFromDb[ii + 1], timelen); + const _time = decodeTime(rankFromDb[ii + 1], timelen); const info = await redisClient().hgetAsync(infoKey, _roleId); const _userInfo = JSON.parse(info); - const tmp = {..._userInfo, num: _score, rank: Math.floor(ii/2)+1}; + const tmp = {..._userInfo, num: _score, time: _time, rank: Math.floor(ii/2)+1}; if(infoKey == REDIS_KEY.USER_INFO) { tmp["roleId"] = _roleId; } else if(infoKey == REDIS_KEY.GUILD_INFO) { diff --git a/game-server/config.json b/game-server/config.json index 1062903b2..e45862794 100644 --- a/game-server/config.json +++ b/game-server/config.json @@ -1 +1 @@ -{"env":"dev"} \ No newline at end of file +{"env":"alpha"} \ No newline at end of file diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 509ae0355..62d64dc1d 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -308,6 +308,7 @@ export const STATUS = { GUILD_LV_LIMIT: { code: 30901, simStr: '军团等级不足' }, ITEM_NOT_SOUL: { code: 30902, simStr: '该物品不是将魂' }, SKIN_HAS_NOT_HERO: { code: 30903, simStr: '未拥有该武将不可获得皮肤' }, + HERO_NOT_MAX: { code: 30904, simStr: '该武将未升满星' }, // 社交相关状态 40000 - 49999 SYS_CHANNEL_AUTH_NOT_ENOUGH: {code: 40000, simStr: '无法在系统频道发送消息'}, diff --git a/shared/domain/battleField/guildActivity.ts b/shared/domain/battleField/guildActivity.ts index 8db0043c7..f5cba4195 100644 --- a/shared/domain/battleField/guildActivity.ts +++ b/shared/domain/battleField/guildActivity.ts @@ -267,9 +267,6 @@ export class RaceActivityObject { this.initEvents(guildCode); let guild = await GuildModel.findByCode(guildCode, serverId); if(!guild) return false; - let leader = guild.leader; - let guildRankParam = new GuildRankParam(guild.icon, guild.name, guild.lv, leader); - await setRank(REDIS_KEY.RACE_ACTIVITY, serverId, guild.code, 0, Math.pow(10, 11) - guild.guildCe, guildRankParam, true); let { name: guildName, guildCe } = guild; this.woodenHorses.set(guildCode, new WoodenHorse(guildCode, guildName, guildCe, serverId)); this.guildList.push({guildCode, serverId}); @@ -281,7 +278,7 @@ export class RaceActivityObject { let events = this.events.get(guildCode)||[]; let needSendEnd = woodenHorse.calCurWoodenHorse(events); if(woodenHorse.status == 1 || woodenHorse.status == 2) { // 更新距离 // TODO 写进const表 - await setRankWithoutUserInfo(REDIS_KEY.RACE_ACTIVITY, serverId, guildCode, woodenHorse.distance, Math.floor((woodenHorse.time - woodenHorse.startTime)/1000), true, false); + await setRankWithoutUserInfo(REDIS_KEY.RACE_ACTIVITY, serverId, guildCode, Math.floor(woodenHorse.distance * 1000), woodenHorse.time - woodenHorse.startTime, true, false, 6); if (needSendEnd) { // 抵达后发送奖励,发送消息,结算 await sendSingleRaceActEndMsg(guildCode, woodenHorse); } @@ -462,7 +459,7 @@ export class WoodenHorse { * @returns {boolean} needSendEnd 是否跑到终点发送结束新号 */ public calCurWoodenHorse(events: Event[]): boolean { - console.log('**', JSON.stringify(events)) + console.log('**', this.guildName, this.status, this.distance, Date.now(), this.speed, JSON.stringify(events)) if(this.status == 2) return false; // TODO 写进const表 if(this.status == 0 && this.stopContinueTime && Date.now() > this.stopContinueTime) { this.status = 1; this.stopContinueTime = 0; @@ -474,7 +471,6 @@ export class WoodenHorse { this.status = 2; return true; } - console.log('*********', this.distance, Date.now(), this.speed) this.distance = Math.floor((this.distance + (Date.now() - this.time)/1000 * this.speed ) * 1000)/1000; // 1位小数点 this.time = Date.now(); @@ -511,6 +507,7 @@ export class WoodenHorse { for(let { id, count, endTime } of effectiveEvents) { this.calEvent(id, count, endTime); } + console.log('**effect', this.speed, JSON.stringify(effectiveEvents)); return false; } @@ -534,6 +531,8 @@ export class WoodenHorse { if (this.shieldTime < Date.now()) { this.stopContinueTime = endTime; this.status = 0; // TODO 写进const表 + this.time = endTime; + this.speed = 0; } break; case RACE_EVENT.FENGCHE: diff --git a/shared/domain/rank.ts b/shared/domain/rank.ts index 90758781d..9b159c26f 100644 --- a/shared/domain/rank.ts +++ b/shared/domain/rank.ts @@ -28,6 +28,7 @@ export class GuildRankParam { icon: number; name: string; lv: number; + memberCnt: number; leader: { roleName: string; title: number; @@ -38,12 +39,13 @@ export class GuildRankParam { } - constructor(icon: number, name: string, lv: number, leader: {roleName: string, title: number, lv: number, head: number, frame: number, spine: number}) { + constructor(icon: number, name: string, lv: number, leader: {roleName: string, title: number, lv: number, head: number, frame: number, spine: number}, memberCnt: number) { this.icon = icon; this.name = name; this.lv = lv; let _leader = new GuildLeader(leader); this.leader = _leader; + this.memberCnt = memberCnt; } } @@ -83,8 +85,9 @@ export class SimpleGuildRankWithTimeParam extends SimpleGuildRankParam { time: number = 0; durability: number = 0; - constructor(rank: number, code: string, name: string, obj: WoodenHorse|false) { + constructor(rank: number, code: string, name: string, obj: WoodenHorse|{distance: number, time: number, startTime: number, durability: number}|false) { super(rank, code, name, obj?obj.distance:0); + console.log(JSON.stringify(obj)); if(obj) { this.num = obj.distance; this.time = Math.floor((obj.time - obj.startTime)/1000);