HJ_Server/src/extends.ts
2024-01-03 14:44:50 +08:00

343 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 });
};