diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index 618053a6c..beb8e7e77 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -22,6 +22,8 @@ import { reportCreateRoleEventToTa, reportTAEvent, reportTAUserSet } from '../.. import { saveLoginAndOutLog } from '../../../pubUtils/logUtil'; import { sendMessageToAllWithSuc, sendMessageToUserWithSuc } from '../../../services/pushService'; import { getIpLocation } from '../../../services/roleService'; +import { dispatch } from '../../../pubUtils/dispatcher'; +import { leaveRaceActivityToRemote } from '../../../services/guildActivity/guildActivityService'; export default function (app: Application) { new HandlerService(app, {}); @@ -192,6 +194,7 @@ export class EntryHandler { savePlayTime(roleInfo.userCode); } }); + leaveRaceActivityToRemote(serverId, guildCode, roleId); reportTAUserSet(TA_USERSET_TYPE.ADD, roleId, { total_play_time: nowSeconds() - loginTime }); rmRoleFromQueue(roleId, sid); // 删除redis中寻宝的匹配记录 let channelService = this.app.get('channelService'); diff --git a/game-server/app/servers/guild/handler/guildHandler.ts b/game-server/app/servers/guild/handler/guildHandler.ts index d48526837..dc8695b53 100644 --- a/game-server/app/servers/guild/handler/guildHandler.ts +++ b/game-server/app/servers/guild/handler/guildHandler.ts @@ -29,6 +29,7 @@ import { reportTAEvent } from '../../../services/sdkService'; import { changeGuildActivity, guildDismisActivity } from '../../../services/activity/guildPayService'; import { sendMessageToUserWithSuc } from '../../../services/pushService'; import { GuildActiveModel } from '../../../db/GuildActive'; +import { leaveRaceActivityToRemote, leaveRaceWhenDismissToRemote, leaveRaceWhenQuitGuildToRemote } from '../../../services/guildActivity/guildActivityService'; export default function (app: Application) { @@ -576,6 +577,7 @@ export class GuildHandler { reportTAEvent(roleId, TA_EVENT.GUILD_QUIT, { name: guild.name, way: GUILD_QUIT_WAY.DISMISS }, ip); updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'guildName', value: '' }]); } + leaveRaceWhenDismissToRemote(serverId, code); return resResult(STATUS.SUCCESS, { code, status: guild.status }); } @@ -586,6 +588,7 @@ export class GuildHandler { const roleId = session.get('roleId'); const roleName = session.get('roleName'); const serverId = session.get('serverId'); + const guildCode = session.get('guildCode'); const sid = session.get('sid'); const ip = session.get('ip'); const { code } = msg; @@ -611,6 +614,7 @@ export class GuildHandler { setUserGuildSession(session, null); reportTAEvent(roleId, TA_EVENT.GUILD_QUIT, { name: guild.name, way: GUILD_QUIT_WAY.QUIT }, ip); changeGuildActivity('', serverId, roleId, sid); + leaveRaceWhenQuitGuildToRemote(serverId, guildCode, roleId); return resResult(STATUS.SUCCESS, { hasGuild: role.hasGuild }); } @@ -650,6 +654,7 @@ export class GuildHandler { await sendMailByContent(MAIL_TYPE.GUILD_BE_KICK, memberRoleId, { sendName: roleName, params: [guild.name] }); reportTAEvent(memberRoleId, TA_EVENT.GUILD_QUIT, { name: guild.name, way: GUILD_QUIT_WAY.KICK }); + leaveRaceWhenQuitGuildToRemote(serverId, code, memberRoleId); return resResult(STATUS.SUCCESS, { memberCnt: guild.memberCnt }); } diff --git a/game-server/app/servers/guild/handler/raceActivityHandler.ts b/game-server/app/servers/guild/handler/raceActivityHandler.ts index 551b248f7..0f00e40a7 100644 --- a/game-server/app/servers/guild/handler/raceActivityHandler.ts +++ b/game-server/app/servers/guild/handler/raceActivityHandler.ts @@ -1,7 +1,7 @@ import { Application, ChannelService, BackendSession, HandlerService, pinus, } from "pinus"; import { GUILD_ACTIVITY_TYPE, STATUS, GUILD_ACTIVITY_STATUS, REDIS_KEY, TASK_TYPE, PUSH_ROUTE, DEBUG_MAGIC_WORD } from "../../../consts"; import { genCode, resResult } from "../../../pubUtils/util"; -import { getGuildActivityStatus, getRaceActivityObj, getWoodenHorseList, getGAIndexInPinus, getJoinIndex } from "../../../services/guildActivity/guildActivityService"; +import { getGuildActivityStatus, getRaceActivityObj, getWoodenHorseList, getGAIndexInPinus, getJoinIndex, leaveRaceActivity } from "../../../services/guildActivity/guildActivityService"; import { UserGuildModel } from "../../../db/UserGuild"; import { GuildActivityRecordModel } from "../../../db/GuildActivityRec"; import { UserGuildActivityRecModel } from "../../../db/UserGuildActivityRec"; @@ -73,6 +73,18 @@ export class RaceActivityHandler { }); } + // 离开粮草先行界面 + async leavePage(msg: {}, session: BackendSession) { + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const guildCode = session.get('guildCode'); + + await leaveRaceActivity(serverId, guildCode, roleId); + + return resResult(STATUS.SUCCESS); + } + // 加入木马 async join(msg: {}, session: BackendSession) { diff --git a/game-server/app/servers/guild/remote/guildActivityRemote.ts b/game-server/app/servers/guild/remote/guildActivityRemote.ts index 7d7722a90..794323b3c 100644 --- a/game-server/app/servers/guild/remote/guildActivityRemote.ts +++ b/game-server/app/servers/guild/remote/guildActivityRemote.ts @@ -1,5 +1,5 @@ import { Application, ChannelService, HandlerService, } from 'pinus'; -import { sendAllGuildRanks, calWoodenHorseAndSend, sendRaceStartMsg, setDicGuildActivity, setDicAuctionTime, settleGuildActivityReward, clearActivityObj, setGuildActivityIndexInPinus, guildActivityStart, debugSendGateHp, debugAddHorse } from '../../../services/guildActivity/guildActivityService'; +import { sendAllGuildRanks, calWoodenHorseAndSend, sendRaceStartMsg, setDicGuildActivity, setDicAuctionTime, settleGuildActivityReward, clearActivityObj, setGuildActivityIndexInPinus, guildActivityStart, debugSendGateHp, debugAddHorse, leaveRaceActivity, leaveRaceWhenQuitGuild, leaveRaceWhenDismiss } from '../../../services/guildActivity/guildActivityService'; import { gameData } from '../../../pubUtils/data'; import { setWeek } from '../../../pubUtils/timeUtil'; import { sendUngotDividend } from '../../../services/auctionService'; @@ -213,4 +213,28 @@ export class GuildActivityRemote { errlogger.error(`remote ${__filename} \n ${e.stack}`); } } + + public leaveRaceActivity(serverId: number, guildCode: string, roleId: string) { + try { + return leaveRaceActivity(serverId, guildCode, roleId); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } + + public leaveRaceWhenQuitGuild(serverId: number, guildCode: string, roleId: string) { + try { + return leaveRaceWhenQuitGuild(serverId, guildCode, roleId); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } + + public leaveRaceWhenDismiss(guildCode: string) { + try { + return leaveRaceWhenDismiss(guildCode); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } } \ No newline at end of file diff --git a/game-server/app/services/guildActivity/guildActivityService.ts b/game-server/app/services/guildActivity/guildActivityService.ts index d9121bad7..d975e469e 100644 --- a/game-server/app/services/guildActivity/guildActivityService.ts +++ b/game-server/app/services/guildActivity/guildActivityService.ts @@ -315,7 +315,7 @@ export async function settleGuildActivityReward(aid: number) { let obj = getRaceActivityObj(); obj.stopRace(); - for (let { guildCode, serverId } of obj.guildList) { + for (let { guildCode, serverId } of obj.getGuilds()) { let woodenHorse = await obj.getWoodenHorse(guildCode, serverId); if (woodenHorse && woodenHorse.status != 0 && !obj.hasSend(guildCode)) { await raceActivitySettleReward(guildCode, woodenHorse); @@ -661,6 +661,8 @@ export async function raceActivitySettleReward(guildCode: string, woodenHorse: W let { serverId, durability, distance, isRobot } = woodenHorse; if(isRobot) return; let obj = getRaceActivityObj(); + // 已发送 + obj.send(guildCode); // 计算排名,计算耐久,发送奖励 let { guildRank, myGuildRank } = await obj.getRanks(serverId, guildCode); let rank = myGuildRank?.rank||0; @@ -700,8 +702,6 @@ export async function raceActivitySettleReward(guildCode: string, woodenHorse: W } } - // 删除数据 - obj.deleteFromList(guildCode); } /** @@ -930,4 +930,46 @@ export async function debugAddHorse(serverId: number, guildCode: string, memberC clearInterval(timer); }, 10 * 60 * 1000); } +} + +export async function leaveRaceActivity(serverId: number, guildCode: string, roleId: string ) { + if(!guildCode) return; + let obj = getRaceActivityObj(); + await obj.memberLeave(guildCode, serverId, roleId); +} + +export async function leaveRaceActivityToRemote(serverId: number, guildCode: string, roleId: string) { + let guildServers = pinus.app.getServersByType('guild')||[]; + let server = dispatch(`${serverId}`, guildServers); + if(server) { + await pinus.app.rpc.guild.guildActivityRemote.leaveRaceActivity.toServer(server.id, serverId, guildCode, roleId); + } +} + +export async function leaveRaceWhenQuitGuild(serverId: number, guildCode: string, roleId: string) { + if(!guildCode) return; + let obj = getRaceActivityObj(); + await obj.memberQuit(guildCode, serverId, roleId); +} + +export async function leaveRaceWhenQuitGuildToRemote(serverId: number, guildCode: string, roleId: string) { + let guildServers = pinus.app.getServersByType('guild')||[]; + let server = dispatch(`${serverId}`, guildServers); + if(server) { + await pinus.app.rpc.guild.guildActivityRemote.leaveRaceWhenQuitGuild.toServer(server.id, serverId, guildCode, roleId); + } +} + +export async function leaveRaceWhenDismiss(guildCode: string) { + if(!guildCode) return; + let obj = getRaceActivityObj(); + obj.dismiss(guildCode); +} + +export async function leaveRaceWhenDismissToRemote(serverId: number, guildCode: string) { + let guildServers = pinus.app.getServersByType('guild')||[]; + let server = dispatch(`${serverId}`, guildServers); + if(server) { + await pinus.app.rpc.guild.guildActivityRemote.leaveRaceWhenDismiss.toServer(server.id, guildCode); + } } \ No newline at end of file diff --git a/game-server/app/services/guildActivity/raceActivityObj.ts b/game-server/app/services/guildActivity/raceActivityObj.ts index e1e4a18a4..088c154e5 100644 --- a/game-server/app/services/guildActivity/raceActivityObj.ts +++ b/game-server/app/services/guildActivity/raceActivityObj.ts @@ -10,12 +10,42 @@ import { REDIS_KEY, RACE_EVENT_TYPE, RACE_EVENT_EFFECT_TYPE, RACE_EVENT, STATUS, import { getRandEelm, sortArrRandom, resResult, getRandResultByMember } from "../../pubUtils/util"; import { sendMessageToGuildWithSuc, sendMessageToServerWithSuc, sendMessageToUserWithSuc } from "../pushService"; +class MemberInfo extends Member { + isQuit: boolean = false; + + constructor(roleId: string, job: number, code: string) { + super(); + this.roleId = roleId; + this.job = job; + this.code = code; + } + + public quit() { + this.isQuit = true; + } +} + +class GuildInfo { + serverId: number; + guildCode: string; + isDissmiss: boolean = false; + + constructor(serverId: number, guildCode: string) { + this.serverId = serverId; + this.guildCode = guildCode; + } + + dismiss() { + this.isDissmiss = true; + } +} + // 粮草先行 export class RaceActivityObject { public status = GUILD_ACTIVITY_STATUS.WAITING; // 活动状态 0-未开始 1-已开始 2-已结束 private allStartTime = 0; // 开启时间,每天晚上8点 - public guildList: Array<{ serverId: number, guildCode: string }> = []; // 所有军团 - private members: Map> = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}] + private guildList: GuildInfo[] = []; // 所有军团 + private members: Map = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}] private woodenHorses: Map = new Map(); // 每个军团的木牛流马 guildCode => WoodenHorse private events: Map = new Map(); // 每个军团遇到的事件 private items: Map = new Map(); // 每个玩家的道具 roleId => [{id, count}] @@ -32,11 +62,35 @@ export class RaceActivityObject { } public async updateMemberSid(guildCode: string, serverId: number, roleId: string, sid: string) { - let hasJoin = this.getMember(guildCode, roleId); - if(!hasJoin) return hasJoin; + let member = this.getMember(guildCode, roleId); + if(!member) return member; let wh = await this.getWoodenHorse(guildCode, serverId); wh.updateMemberSid(roleId, sid); - return hasJoin + return member + } + + public async memberLeave(guildCode: string, serverId: number, roleId: string) { + let member = this.getMember(guildCode, roleId); + if(!member) return member; + let wh = await this.getWoodenHorse(guildCode, serverId); + wh.leaveMemberSid(roleId); + + return member + } + + public async memberQuit(guildCode: string, serverId: number, roleId: string) { + let member = this.getMember(guildCode, roleId); + if(!member) return; + member.quit(); + let wh = await this.getWoodenHorse(guildCode, serverId); + wh.leaveMemberSid(roleId, true); + } + + public dismiss(guildCode: string) { + let guild = this.guildList.find(guild => guild.guildCode == guildCode); + if(!guild) return; + guild.dismiss(); + this.woodenHorses.delete(guildCode); } // 加入member @@ -44,11 +98,16 @@ export class RaceActivityObject { if(!this.members.has(guildCode)) { this.members.set(guildCode, []); } - this.members.get(guildCode).push({roleId, job, code}); + this.members.get(guildCode).push(new MemberInfo(roleId, job, code)); + } + + public getGuilds() { + return this.guildList.filter(cur => !cur.isDissmiss); } public getMembersOfGuild(guildCode: string) { - return this.members.get(guildCode)||[]; + let members = this.members.get(guildCode)||[]; + return members.filter(cur => !cur.isQuit); } public getAllWoodenHorses() { @@ -93,11 +152,11 @@ export class RaceActivityObject { public async joinWoodenHorse(guildCode: string, roleId: string, roleName: string, serverId: number, sid: string, job: number, code: string, isDebug = false) { let woodenHorse = await this.getWoodenHorse(guildCode, serverId, isDebug); if(!woodenHorse) return false; - let member = woodenHorse.joinMember(roleId, roleName, sid, code) + woodenHorse.joinMember(roleId, roleName, sid, code) this.pushMember(guildCode, roleId, job, code); if(this.status == GUILD_ACTIVITY_STATUS.START) { - this.sendRandItemsToMembers([member], woodenHorse, woodenHorse.remainItems); + // this.sendRandItemsToMembers([member], woodenHorse, woodenHorse.remainItems); this.woodenHorseStartRace(woodenHorse); } return await this.getWoodenHorse(guildCode, serverId); @@ -109,13 +168,13 @@ export class RaceActivityObject { this.initEvents(guildCode); if(isDebug) { this.woodenHorses.set(guildCode, new WoodenHorse(guildCode, guildCode, 0, serverId, this.allStartTime, false)); - this.guildList.push({guildCode, serverId}); + this.guildList.push(new GuildInfo(serverId, guildCode)); } else { let guild = await GuildModel.findByCode(guildCode, serverId); if(!guild) return undefined; let { name: guildName, guildCe } = guild; this.woodenHorses.set(guildCode, new WoodenHorse(guildCode, guildName, guildCe, serverId, this.allStartTime, false)); - this.guildList.push({guildCode, serverId}); + this.guildList.push(new GuildInfo(serverId, guildCode)); } } let woodenHorse = this.woodenHorses.get(guildCode); @@ -187,8 +246,9 @@ export class RaceActivityObject { } private sendRandItemsToMembers(members: WoodenHorseMember[], woodenHorse: WoodenHorse, items: Map) { - let notReceiveMembers = members.filter(member => !member.isReceived()); + let notReceiveMembers = members.filter(member => !member.isReceived() && member.isOnline); let memberCnt = notReceiveMembers.length; + console.log('##### SEND_START', memberCnt, notReceiveMembers) let addItems: Map = new Map(); for(let [id, {total, max}] of items) { let randResult = getRandResultByMember(total, max, memberCnt); @@ -282,7 +342,7 @@ export class RaceActivityObject { return items; } - public deleteFromList(guildCode: string) { + public send(guildCode: string) { this.hasSentGuild.push(guildCode); } diff --git a/shared/domain/battleField/guildActivity.ts b/shared/domain/battleField/guildActivity.ts index cb10750e0..0a008b50f 100644 --- a/shared/domain/battleField/guildActivity.ts +++ b/shared/domain/battleField/guildActivity.ts @@ -22,12 +22,14 @@ export class WoodenHorseMember { items: RewardInter[] = []; code?: string; hasReceiveInitItems: boolean = false; + isOnline: boolean = false; constructor(roleId: string, roleName: string, sid: string, code: string) { this.roleId = roleId; this.roleName = roleName; this.sid = sid; this.code = code; + if(sid) this.isOnline = true; } addTempItem(item: RewardInter) { @@ -58,6 +60,11 @@ export class WoodenHorseMember { updateSid(sid: string) { this.sid = sid; + this.isOnline = true; + } + + leave() { + this.isOnline = false; } } @@ -236,19 +243,24 @@ export class WoodenHorse { if(this.durability < 0) this.durability = 0; break; case RACE_EVENT.ITEM: - let ranMember: WoodenHorseMember[] = getRandEelm(this.members, GUILDACTIVITY.RACEACTIVITY_EVENT_MEMBERCNT); - if(ranMember.length <= 0) ranMember = this.members; + let onlineMembers = this.members.filter(member => member.isOnline); + let memberCnt = onlineMembers.length; + console.log('##### HANDLE_ITEM', memberCnt, onlineMembers) + + let ranMember: WoodenHorseMember[] = getRandEelm(onlineMembers, GUILDACTIVITY.RACEACTIVITY_EVENT_MEMBERCNT); + if(ranMember.length <= 0) ranMember = onlineMembers; for(let member of ranMember) { let item = gameData.raceEventItems; member.addTempItems(item); } let normalItems = getRaceEventItems(); + for(let [id, {total, max}] of normalItems) { - let randResult = getRandResultByMember(total, max, this.members.length); - for(let i = 0; i < this.members.length; i++) { + let randResult = getRandResultByMember(total, max, memberCnt); + for(let i = 0; i < onlineMembers.length; i++) { let count = randResult.arr[i]||0; if(count > 0) { - this.members[i].addTempItem({ id, count }); + onlineMembers[i].addTempItem({ id, count }); normalItems.get(id).total -= count; } } @@ -278,6 +290,15 @@ export class WoodenHorse { } } + public leaveMemberSid(roleId: string, isQuit = false) { + let index = this.members.findIndex(cur => cur.roleId == roleId); + if(index != -1) { + this.members[index].leave(); + } + if(isQuit) this.memberCnt--; + if(this.memberCnt < 0) this.memberCnt = 0; + } + public setRemainItem(id: number, remain: number, max: number) { this.remainItems.set(id, { total: remain, max }); }