Files
ZYZ/game-server/app/servers/role/handler/shopHandler.ts
luying f09ebd56b1 feat(将魂出售): 修复将魂回收的问题
4cfbce94e - 2fa8c7a91 by zhangxk
2023-07-19 15:51:04 +08:00

254 lines
11 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 { Application, BackendSession, pinus } from "pinus";
import { gameData, hasShopType } from "../../../pubUtils/data";
import { arrToMap, parseGoodStr, resResult } from "../../../pubUtils/util";
import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GROW_MAX, ITEM_CHANGE_REASON } from "../../../consts";
import { UserShopModel } from "../../../db/UserShop";
import { handleCost, addItems } from "../../../services/role/rewardService";
import { SHOP } from "../../../pubUtils/dicParam";
import { HeroModel, HeroType } from "../../../db/Hero";
import { checkShopInPurchase, getShopDicById, getShopListByType, getShopPrice } from "../../../services/shopService";
import { RewardInter, recycleSoulFastPara } from "../../../pubUtils/interface";
import { UserShopTypeModel } from "../../../db/UserShopType";
import { nowSeconds } from "../../../pubUtils/timeUtil";
import { isGoodsHidden, isHeroHidden } from "../../../services/dataService";
import { RoleModel } from './../../../db/Role';
import { calUpSixColorsResidueFragment } from "../../../services/role/checkMaterial";
import { ItemModel } from "../../../db/Item";
export default function (app: Application) {
return new ShopHandler(app);
}
export class ShopHandler {
constructor(private app: Application) {
}
// 获得商品列表
async getShopList(msg: { shop: number, type: number }, session: BackendSession) {
let roleId = session.get('roleId');
let serverId = session.get('serverId');
let { shop, type } = msg;
if (!hasShopType(shop, type)) {
return resResult(STATUS.WRONG_PARMS);
}
const result = await getShopListByType(shop, type, roleId, serverId);
return resResult(STATUS.SUCCESS, result);
}
// 读取红点
async readShop(msg: { shop: number, type: number }, session: BackendSession) {
let roleId = session.get('roleId');
let { shop, type } = msg;
if (!hasShopType(shop, type)) {
return resResult(STATUS.WRONG_PARMS);
}
await UserShopTypeModel.read(roleId, shop, type);
return resResult(STATUS.SUCCESS);
}
// 购买商品
async purchase(msg: { activityId: number, shopItemId: number, count: number }, session: BackendSession) {
let roleId = session.get('roleId');
let roleName = session.get('roleName');
let sid = session.get('sid');
let serverId = session.get('serverId');
let seasonNum = pinus.app.get('pvpSeasonNum');
let { activityId = 0, shopItemId, count } = msg;
let dicShopItem = await getShopDicById(activityId, shopItemId, roleId, serverId);
if (!dicShopItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if (dicShopItem['productID'] && dicShopItem['productID'] != '&') return resResult(STATUS.CAN_NOT_PURCHASE);
if (dicShopItem['beginTime'] && dicShopItem['beginTime'] > nowSeconds()) return resResult(STATUS.SHOP_CLOSED);
if (dicShopItem['endTime'] && dicShopItem['endTime'] < nowSeconds()) return resResult(STATUS.SHOP_CLOSED);
let userShop = await UserShopModel.findByRoleAndItem(roleId, dicShopItem, seasonNum);
let checkResult = await checkShopInPurchase(session, activityId, count, userShop?.count || 0, dicShopItem);
if (checkResult.code != STATUS.SUCCESS.code) {
return resResult(checkResult);
}
// 总计可买次数(从配置表读取)
const totalCanBuyTimes = dicShopItem.purchaseLimit;
if (!totalCanBuyTimes || totalCanBuyTimes <= 0) {
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
}
// 消耗
let cost = getShopPrice(dicShopItem.money, count, userShop?.count || 0, dicShopItem.price);
let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.SHOP_PURCHASE);
if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
// 次数
userShop = await UserShopModel.purchase(roleId, roleName, activityId, dicShopItem, count, seasonNum);
if (!userShop || (userShop && userShop.count > totalCanBuyTimes)) {
// rollback 消耗
let role = await RoleModel.findByRoleId(roleId);
addItems(roleId, role.roleName, sid, cost, ITEM_CHANGE_REASON.SHOP_PURCHASE);
// rollback 购买次数
await UserShopModel.updateCount(roleId, dicShopItem, -count, seasonNum)
return resResult(STATUS.BUY_COUNT_OVER);
}
// 获得
let reward = [{
id: dicShopItem.goodId,
count: count * (dicShopItem.num || 1)
}];
let goods = await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.SHOP_PURCHASE);
return resResult(STATUS.SUCCESS, {
shopItemId, count,
goods
});
}
// 将魂回收
async recycleSoul(msg: { goodsId: number, count: number }, session: BackendSession) {
let roleId = session.get('roleId');
let roleName = session.get('roleName');
let sid = session.get('sid');
let { goodsId, count } = msg;
if (isGoodsHidden(goodsId)) return resResult(STATUS.ITEM_IS_HIDDEN);
let dicGoods = gameData.goods.get(goodsId);
if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let dicItid = ITID.get(dicGoods.itid);
if (!dicItid) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if (dicItid.type != CONSUME_TYPE.SOUL) {
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) {
let residueFragment = await calUpSixColorsResidueFragment(roleId, hero, dicGoods.hid);
if (!residueFragment || count > residueFragment) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
// return resResult(STATUS.HERO_NOT_MAX);
}
// 检查自己的数量
let cost = [{
id: goodsId, count
}];
let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.RECYCLE_SOUL);
if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
let reward: RewardInter[] = [];
switch (dicGoods.quality) {
case HERO_QUALITY_TYPE.BLUE:
reward = parseGoodStr(SHOP.HERO_SOUL_BULE); break;
case HERO_QUALITY_TYPE.PURPLE:
reward = parseGoodStr(SHOP.HERO_SOUL_PURPLE); break;
case HERO_QUALITY_TYPE.GOLD:
reward = parseGoodStr(SHOP.HERO_SOUL_GOLDEN); break;
case HERO_QUALITY_TYPE.UR:
reward = parseGoodStr(SHOP.HERO_SOUL_UR); break;
}
// 增加货币
let goods = await addItems(roleId, roleName, sid, reward.map(cur => { return { id: cur.id, count: cur.count * count } }), ITEM_CHANGE_REASON.RECYCLE_SOUL);
return resResult(STATUS.SUCCESS, {
goodsId, count,
goods
});
}
/**
* 将魂一键回收
* @param msg
* @param session
* @returns
*/
async recycleSoulFast(msg: { recycleSoulFastPara: recycleSoulFastPara[] }, session: BackendSession) {
let roleId = session.get('roleId');
let roleName = session.get('roleName');
let sid = session.get('sid');
let { recycleSoulFastPara } = msg;
// 检测参数防止hid重复
let checkHid = new Map<number, number>();
for (let { hid, count } of recycleSoulFastPara) {
if (checkHid.get(hid)) return resResult(STATUS.WRONG_PARMS);
checkHid.set(hid, 1);
}
// 从db获取所有武将数据
const dbHeros = await HeroModel.findByHidsAndRole(roleId, recycleSoulFastPara.map(obj => obj.hid)) as HeroType[];
let heroesMap = new Map<number, HeroType>();
let items = []
for (const val of dbHeros) {
let hid = val.hid
heroesMap.set(hid, val);
let dicHero = gameData.hero.get(hid);
if (!dicHero || !dicHero.pieceId) continue;
items.push(dicHero.pieceId);
}
// 从db获取相关碎片道具数据
if (!items || items.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
const dbItems = await ItemModel.findbyRoleAndIds(roleId, items);
if (!dbItems || dbItems.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
const itemsMap = arrToMap(dbItems, obj => obj.id);
let allAddItem = [];
let allCostItem = [];
for (let { hid, count } of recycleSoulFastPara) {
let residueFragment = 0;
let goodsId = gameData.hero.get(hid)?.pieceId || 0;
const curItemCount = itemsMap.get(goodsId)?.count || 0;
if (curItemCount <= 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let hero = heroesMap.get(hid);
if (!hero) return resResult(STATUS.HERO_IS_HIDDEN);
if (hero.colorStar != HERO_GROW_MAX.COLORSTAR) {
residueFragment = await calUpSixColorsResidueFragment(roleId, hero, hid, curItemCount);
if (!residueFragment || count > residueFragment) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
}
allCostItem.push({ id: goodsId, count: count });
let dicGoods = gameData.goods.get(goodsId);
if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND)
let reward: RewardInter[] = [];
switch (dicGoods.quality) {
case HERO_QUALITY_TYPE.BLUE:
reward = parseGoodStr(SHOP.HERO_SOUL_BULE); break;
case HERO_QUALITY_TYPE.PURPLE:
reward = parseGoodStr(SHOP.HERO_SOUL_PURPLE); break;
case HERO_QUALITY_TYPE.GOLD:
reward = parseGoodStr(SHOP.HERO_SOUL_GOLDEN); break;
case HERO_QUALITY_TYPE.UR:
reward = parseGoodStr(SHOP.HERO_SOUL_UR); break;
}
allAddItem.push(...reward.map(cur => { return { id: cur.id, count: cur.count * count } }));
}
let costResult = await handleCost(roleId, sid, allCostItem, ITEM_CHANGE_REASON.RECYCLE_SOUL);
if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
// 增加货币
let goods = await addItems(roleId, roleName, sid, allAddItem, ITEM_CHANGE_REASON.RECYCLE_SOUL);
return resResult(STATUS.SUCCESS, { goods });
}
// !测试接口。 去除限购次数
async debugClearPurchaseLimit(msg: {}, session: BackendSession) {
let roleId = session.get('roleId');
await UserShopModel.deleteAccount(roleId);
return resResult(STATUS.SUCCESS);
}
}