343 lines
12 KiB
TypeScript
343 lines
12 KiB
TypeScript
import 'tsrpc';
|
||
import { ApiCall, BaseConnection, ConnectionStatus, WsServer } from 'tsrpc';
|
||
import { Wjjl } from './module/collection_wjjl';
|
||
import { GH } from './public/gonghui/gh';
|
||
import { GHManage } from './public/gonghui/manage';
|
||
import { HeroFun } from './public/hero';
|
||
import { Rank } from './public/rank/rank';
|
||
import { UserFun } from './public/user';
|
||
import { joinFightData, roleDataType } from './shared/fightControl/fightType';
|
||
import { ResGetList } from './shared/protocols/item/PtlGetList';
|
||
import { ServiceType } from './shared/protocols/serviceProto';
|
||
import { ResLogin } from './shared/protocols/user/PtlLogin';
|
||
import { HeroShared, otherBuff } from './shared/public/hero';
|
||
import { PlayerShared } from './shared/public/player';
|
||
import { PublicShared } from './shared/public/public';
|
||
import {RankKfjs} from "./public/rank/rank_kfjs";
|
||
import { setGud } from './public/gud';
|
||
|
||
export function extendType() {
|
||
|
||
}
|
||
|
||
type msg = ServiceType['msg'];
|
||
type s2cMsg = Omit<msg, 'msg_c2s/BindUid'>;
|
||
type omitMsg = Pick<s2cMsg, 'msg_s2c/EquipChange' | 'msg_s2c/HeroChange' | 'msg_s2c/ItemChange' | 'msg_s2c/ShiwuChange' | 'msg_s2c/PeijianChange'>;
|
||
|
||
declare module 'tsrpc' {
|
||
export interface BaseConnection {
|
||
/**玩家上阵英雄 */
|
||
get heroPos(): k_v<string>;
|
||
/**有些功能会对英雄有属性加成 */
|
||
get otherBuff(): otherBuff;
|
||
/**获取当前公会 */
|
||
get gonghui(): GH;
|
||
/**玩家唯一uid 玩家登录时赋值*/
|
||
uid: string;
|
||
/**玩家登录账号 玩家登录时赋值*/
|
||
bindUid: string;
|
||
/**玩家数据 玩家登录时赋值*/
|
||
gud: ResLogin['gud'];
|
||
/**玩家道具 玩家拉取道具列表时赋值*/
|
||
//item: ResGetList['list'];
|
||
/**历史获得 */
|
||
lshd: Partial<{
|
||
hero: k_v<number>;
|
||
equip: k_v<number>;
|
||
peijian: k_v<number>;
|
||
}>;
|
||
/**玩家调用api的时间 */
|
||
requstApiTime: k_v<number>;
|
||
/**API 锁 */
|
||
apiLock: k_v<number>;
|
||
/**获取默认上阵战斗数据 */
|
||
getDefaultFightData(def?: k_v<string>): Promise<joinFightData>;
|
||
/**刷新上阵英雄战力 */
|
||
refreshPower(): Promise<any>;
|
||
/**玩家计算在线时长时间戳 */
|
||
onlineTime: number;
|
||
}
|
||
|
||
export interface WsServer {
|
||
/**玩家uid对应的socket连接 */
|
||
uid_connections: k_v<BaseConnection<ServiceType>>;
|
||
/**向单个玩家推送消息 */
|
||
sendMsgByUid<msgType extends `msg_s2c${string}` & keyof msg>(uid: string, type: msgType, val: msg[msgType], pid?: string): void;
|
||
|
||
broadcastClusterMsg<T extends string & keyof ServiceType['msg']>(msgName: T, msg: ServiceType['msg'][T], filter?: any): Promise<{
|
||
isSucc: true;
|
||
} | {
|
||
isSucc: false;
|
||
errMsg: string;
|
||
}>;
|
||
}
|
||
|
||
export interface ApiCall {
|
||
/**玩家唯一uid 玩家登录时赋值 */
|
||
get uid(): string;
|
||
/**有些功能会对英雄有属性加成 */
|
||
get otherBuff(): otherBuff;
|
||
/**接口回调之前自动推送的消息 */
|
||
eventMsg: k_v<k_v<any>>;
|
||
/**消息推送 */
|
||
sendMsg<T extends string & keyof ServiceType['msg']>(msgName: T, msg: ServiceType['msg'][T]): ReturnType<BaseConnection['sendData']>;
|
||
/**添加推送消息 */
|
||
addEventMsg<T extends string & keyof omitMsg>(msgName: T, msgKey: string, msg: omitMsg[T]['']): void;
|
||
addEventMsg<T extends 'msg_s2c/PlayerChange'>(msgName: T, msg: Partial<ResLogin['gud']>): void;
|
||
addEventMsg<T extends 'msg_s2c/LshdChange'>(msgName: T, msgKey: 'equip' | 'hero' | 'peijian', msg: k_v<number>): void;
|
||
/**返回错误码 */
|
||
errorCode(code: number): Promise<void>;
|
||
}
|
||
|
||
export interface ApiServiceDef {
|
||
/**
|
||
* <br />
|
||
*
|
||
* timeIntervalLimit?: number; ---> api调用间隔 默认500毫秒 <br />
|
||
*
|
||
* needGudKey?: string[]; ---> 需要玩家gud里面存在的字段 并且conn.gud[key]为true
|
||
*/
|
||
conf?: {
|
||
[k: string]: any;
|
||
};
|
||
}
|
||
}
|
||
|
||
//BaseConnection
|
||
Object.defineProperties(BaseConnection.prototype, {
|
||
'heroPos': {
|
||
get(this: BaseConnection) {
|
||
return this.gud.heroPos;
|
||
},
|
||
},
|
||
'otherBuff': {
|
||
get(this: BaseConnection): otherBuff {
|
||
return UserFun.getOtherBuff(this.gud);
|
||
},
|
||
},
|
||
'gonghui': {
|
||
// 涉及call.conn.gonghui,对应引用变量处需增加await
|
||
async get(this: BaseConnection): Promise<GH> {
|
||
// return GHManage.list[this.gud.ghId];
|
||
return await GHManage.getGH(this.gud.ghId);
|
||
}
|
||
},
|
||
});
|
||
|
||
BaseConnection.prototype.getDefaultFightData = async function (this: BaseConnection, def?: k_v<string>) {
|
||
let posObj = def || this.heroPos;
|
||
let roles: k_v<roleDataType> = {};
|
||
|
||
if (!def && this.gud.selectMatrix && this.gud.matrixPos) {
|
||
posObj = this.gud.matrixPos[this.gud.selectMatrix];
|
||
}
|
||
|
||
let heros = await HeroFun.getHeros(this, Object.values(posObj).filter(_id => _id != '') as string[]);
|
||
|
||
Object.entries(posObj).forEach(obj => {
|
||
let pos = obj[0];
|
||
let _id = obj[1];
|
||
let hero = heros.filter(h => h._id == _id)[0];
|
||
|
||
if (hero) {
|
||
roles[pos] = {
|
||
...hero,
|
||
attr: {
|
||
...HeroShared.getHeroBasicAttr(hero, { ...this.otherBuff, allBuff: HeroShared.getAllBuff(heros) }, Number(pos))
|
||
}
|
||
};
|
||
}
|
||
});
|
||
|
||
return {
|
||
player: { ...this.gud, buff: PlayerShared.getBuff(this.gud) },
|
||
roles: roles
|
||
};
|
||
|
||
};
|
||
|
||
// 战力刷新
|
||
BaseConnection.prototype.refreshPower = async function (this: BaseConnection<ServiceType>) {
|
||
let power: number;
|
||
|
||
const heroIds = Object.values(this.heroPos).filter(id => id != '');
|
||
|
||
if (heroIds.length < 1) return power = 0;
|
||
|
||
const heros = (await HeroFun.getHeros(this, heroIds)).filter(hero => hero != null);
|
||
|
||
if (heros.length < 1) return power = 0;
|
||
|
||
let jiban = 0;
|
||
let powerObj = {
|
||
hero: 0,
|
||
zj: 0
|
||
}
|
||
// 英雄战力
|
||
powerObj.hero = heros.map((h, index) => {
|
||
let buff = HeroShared.getHeroBasicAttr(h, { ...this.otherBuff, allBuff: HeroShared.getAllBuff(heros) }, index + 1);
|
||
jiban += buff.jiban || 0;
|
||
return HeroShared.computeHeroZhanLi(buff);
|
||
}).reduce((a, b) => a + b);
|
||
Wjjl.setVal(this.uid, 'hero_jiban', jiban);
|
||
// 主角属性变量设置
|
||
let zjBuff: k_v<number> = {
|
||
zj_atk: 0,
|
||
zj_def: 0,
|
||
zj_liliang: 0,
|
||
zj_zhishi: 0
|
||
}
|
||
// 主角等级属性获取
|
||
|
||
zjBuff.zj_atk += PublicShared.eval(G.gc.com.zjcz_atk.value as any as string, { lv: this.gud.lv })
|
||
zjBuff.zj_def += PublicShared.eval(G.gc.com.zjcz_def.value as any as string, { lv: this.gud.lv })
|
||
zjBuff.zj_liliang += PublicShared.eval(G.gc.com.zjcz_liliang.value as any as string, { lv: this.gud.lv })
|
||
zjBuff.zj_zhishi += PublicShared.eval(G.gc.com.zjcz_zhishi.value as any as string, { lv: this.gud.lv })
|
||
// 图鉴属性获取
|
||
for(let i = 1; i <= this.gud.tujianLv; i++) {
|
||
let item = G.gc.tujian_jc[i]
|
||
if(item) {
|
||
// 各等级累加
|
||
for(let k in item.buff) {
|
||
zjBuff[k] += item.buff[k]
|
||
}
|
||
}
|
||
}
|
||
// 名望属性加成
|
||
if(this.gud.renown > 0) {
|
||
let mwConf = G.gc.mw_dj
|
||
// 各等级累加
|
||
for(let i = 1; i <= this.gud.renown; i++) {
|
||
let mwData = mwConf[i]
|
||
for(let k in mwData.buff) {
|
||
zjBuff[k] += mwData.buff[k]
|
||
}
|
||
}
|
||
}
|
||
// 训练计划加成
|
||
let skillConf = G.gc.xunlianjihua
|
||
if(this.gud.skills) {
|
||
for(let i in this.gud.skills) {
|
||
let item = skillConf[i]
|
||
for(let j in zjBuff) {
|
||
if((j + 'pro') == item.skill) {
|
||
zjBuff[j] += Math.floor(zjBuff[j] * PublicShared.eval(item.v, { slv: this.gud.skills[i]}))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 属性战力计算
|
||
powerObj.zj = Object.values(zjBuff).reduce((a, b) => a + b) * 5
|
||
// 总战力计算
|
||
power = Math.floor(Object.values(powerObj).reduce((a, b) => a + b));
|
||
// console.log(__filename)
|
||
// console.log(await Wjjl.setVal(this.uid, 'hero_jiban', jiban))
|
||
// console.log(power)
|
||
// console.log(powerObj)
|
||
// console.log(tujianBuff)
|
||
// console.log(zjBuff)
|
||
if (power != this.gud.power) {
|
||
let dbUpdate = { power: power };
|
||
if(power > this.gud?.maxpower){
|
||
//记录历史最大战力
|
||
//this.gud.maxpower = power;
|
||
dbUpdate['maxpower'] = power;
|
||
}
|
||
|
||
//this.gud.power = power;
|
||
setGud(this.uid,dbUpdate);
|
||
|
||
G.mongodb.collection('user').updateOne({ uid: this.uid }, { $set: dbUpdate });
|
||
this.sendMsg('msg_s2c/PlayerChange', dbUpdate);
|
||
|
||
let rankKfjs = RankKfjs(7)
|
||
rankKfjs?.setDataAndCheck({
|
||
player: this.gud,
|
||
valArr: [power]
|
||
});
|
||
|
||
Rank.list['zhanli'].addNew({
|
||
valArr: [power],
|
||
... await this.getDefaultFightData()
|
||
});
|
||
|
||
Wjjl.setVal(this.uid, 'power', power);
|
||
}
|
||
};
|
||
|
||
|
||
// ApiCall --------------
|
||
Object.defineProperties(ApiCall.prototype, {
|
||
'uid': {
|
||
get(this: ApiCall) {
|
||
return this.conn.uid;
|
||
},
|
||
},
|
||
'otherBuff': {
|
||
get(this: ApiCall): otherBuff {
|
||
return this.conn.otherBuff;
|
||
},
|
||
}
|
||
});
|
||
|
||
const succ = ApiCall.prototype.succ;
|
||
ApiCall.prototype.succ = async function (this: ApiCall, res: any) {
|
||
this.eventMsg && await this.sendMsg('msg_s2c/Collection', this.eventMsg);
|
||
return succ.call(this, res);
|
||
};
|
||
|
||
ApiCall.prototype.sendMsg = function (this: ApiCall, msgName: string, msg: any) {
|
||
return this.conn.sendMsg(msgName, {
|
||
fromApi: this.service.name,
|
||
msg: msg
|
||
});
|
||
};
|
||
|
||
const doubleApi = [
|
||
'peijiancangku/Deal',
|
||
'xstask/Get'
|
||
]
|
||
|
||
ApiCall.prototype.addEventMsg = function (this: ApiCall) {
|
||
if (!this.conn.id) return;
|
||
let msgName: keyof s2cMsg = arguments[0];
|
||
let msgKey = arguments[1];
|
||
let msg = arguments.length == 3 ? arguments[2] : arguments[1];
|
||
|
||
if (!this.eventMsg) this.eventMsg = {};
|
||
if (!this.eventMsg[msgName]) this.eventMsg[msgName] = {};
|
||
if (arguments.length == 3) {
|
||
if (!this.eventMsg[msgName][msgKey]) this.eventMsg[msgName][msgKey] = {};
|
||
PublicShared.mergeProperty(this.eventMsg[msgName][msgKey], msg);
|
||
} else {
|
||
if(doubleApi.includes(this.service?.name) && this.service?.type=='api'&& Object.keys(this.eventMsg[msgName])[0]==Object.keys(msgKey)[0]){
|
||
this.eventMsg[msgName] = msgKey
|
||
}else {
|
||
PublicShared.mergeProperty(this.eventMsg[msgName], msgKey);
|
||
}
|
||
}
|
||
|
||
switch (msgName) {
|
||
case 'msg_s2c/ItemChange':
|
||
// if (this.conn.item[msgKey]) {
|
||
// if (msg.num == 0) {
|
||
// this.conn.item[msgKey] = null;
|
||
// delete this.conn.item[msgKey];
|
||
// } else Object.assign(this.conn.item[msgKey], msg);
|
||
// } else {
|
||
// this.conn.item[msgKey] = msg;
|
||
// }
|
||
break;
|
||
case 'msg_s2c/PlayerChange':
|
||
Object.assign(this.conn.gud, msg);
|
||
if (Object.keys(this.otherBuff).intersection(Object.keys(msg)).length > 0) this.conn.refreshPower();
|
||
break;
|
||
case 'msg_s2c/LshdChange':
|
||
this.conn?.lshd?.[msgKey] && PublicShared.mergeProperty(this.conn.lshd[msgKey], msg);
|
||
break;
|
||
}
|
||
};
|
||
|
||
ApiCall.prototype.errorCode = function (this: ApiCall, code: number) {
|
||
return this.error('', { code: code });
|
||
}; |