修改:协议和配置表
This commit is contained in:
@@ -28,7 +28,9 @@ import LanguageUtils, { LanguageType } from "../../Main/Common/LanguageUtils";
|
||||
import { DataManager, DataId } from "../../chat18x/data/DataManager";
|
||||
import { LoginData } from "../../chat18x/data/LoginData";
|
||||
import { PlayerData } from "../../chat18x/data/PlayerData";
|
||||
import { AccountData } from "../../chat18x/data/AccountData";
|
||||
import { WalletData } from "../../chat18x/data/WalletData";
|
||||
import { EnvData } from "../../chat18x/data/EnvData";
|
||||
import { ConfigManager } from "../../chat18x/manager/ConfigManager";
|
||||
import { AppConfig } from "db://assets/Scripts/chat18x/config/env/appConfig";
|
||||
import DeviceIdService from "db://assets/Scripts/chat18x/foundation/identity/DeviceIdService";
|
||||
@@ -277,7 +279,11 @@ export class PreloadUI extends Component {
|
||||
loginData.expire = resData.expire;
|
||||
const playerData = DataManager.I.getDataById<PlayerData>(DataId.Player);
|
||||
playerData.name = resData.name;
|
||||
|
||||
const accountData = DataManager.I.getDataById<AccountData>(DataId.Account);
|
||||
accountData.accId = resData.accId;
|
||||
const envData = DataManager.I.getDataById<EnvData>(DataId.Env);
|
||||
envData.cdn = resData.cdn;
|
||||
|
||||
this.loginFinish = true;
|
||||
|
||||
// this.reqMyInfo();
|
||||
@@ -296,7 +302,7 @@ export class PreloadUI extends Component {
|
||||
const resData = res.data;
|
||||
// 保存数据
|
||||
const walletData = DataManager.I.getDataById<WalletData>(DataId.Wallet);
|
||||
walletData.diamond = resData.diamond;
|
||||
walletData.balance = resData.balance;
|
||||
walletData.vipExpire = resData.vipExpire;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,20 @@ export class AiCharacterConfig extends BaseConfig {
|
||||
return ConfigManager.tables.TbAiCharacters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有配置 id,如果存在
|
||||
*/
|
||||
public getAllId(): any | null {
|
||||
let allData = this.getAllConfig();
|
||||
if (!allData) return null;
|
||||
const dataArr = allData.getDataList();
|
||||
let allId = [];
|
||||
for (let oneData of dataArr) {
|
||||
allId.push(oneData.id);
|
||||
}
|
||||
return allId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置,根据 id
|
||||
*/
|
||||
|
||||
@@ -82,6 +82,20 @@ export class GirlConfig extends BaseConfig {
|
||||
if (!oneData) return null;
|
||||
return oneData.priceType;
|
||||
}
|
||||
|
||||
/** 根据 id 获取购买价格 */
|
||||
public getPriceById(id: number): number | null {
|
||||
let oneData = this.getConfigById(id);
|
||||
if (!oneData) return null;
|
||||
return oneData.price;
|
||||
}
|
||||
|
||||
/** 根据 id 获取VIP能否解锁 */
|
||||
public getVipUnlockById(id: number): number | null {
|
||||
let oneData = this.getConfigById(id);
|
||||
if (!oneData) return null;
|
||||
return oneData.vipUnlock;
|
||||
}
|
||||
|
||||
/** 根据 id 获取头像路径 */
|
||||
public getAvatarPathById(id: number): string | null {
|
||||
|
||||
@@ -53,30 +53,59 @@ export class GirlDetailConfig extends BaseConfig {
|
||||
let oneData = this.getCommercialImagesById(id);
|
||||
if (!oneData) return null;
|
||||
return oneData.length;
|
||||
}
|
||||
|
||||
/** 根据 id 和 index 获取图片类型 */
|
||||
public getImageTypeById(id: number, index: number): number | null {
|
||||
}
|
||||
|
||||
/** 根据 id 获取 commercialImages的id数组 */
|
||||
public getCommercialImagesIds(id: number): number[] {
|
||||
let oneData = this.getCommercialImagesById(id);
|
||||
if (!oneData) return [];
|
||||
// 获取所有 id
|
||||
let allId = [];
|
||||
for (let one of oneData) {
|
||||
allId.push(one.id);
|
||||
}
|
||||
return allId;
|
||||
}
|
||||
|
||||
/** 根据 id 获取 某一个commercialImage */
|
||||
private getOneCommercialImageById(id: number, resId: number): any | null {
|
||||
let oneData = this.getCommercialImagesById(id);
|
||||
if (!oneData) return null;
|
||||
if (index < 0 || index >= oneData.length) return null;
|
||||
return oneData[index].imageType;
|
||||
// 遍历数组找到匹配的资源
|
||||
for (let one of oneData) {
|
||||
if (one.id === resId) {
|
||||
return one;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 根据 id 获取图片类型 */
|
||||
public getImageTypeById(id: number, resId: number): number | null {
|
||||
let oneData = this.getOneCommercialImageById(id, resId);
|
||||
if (!oneData) return null;
|
||||
return oneData.imageType;
|
||||
}
|
||||
|
||||
/** 根据 id 和 index 获取图片价格 */
|
||||
public getImagePriceById(id: number, index: number): number | null {
|
||||
let oneData = this.getCommercialImagesById(id);
|
||||
/** 根据 id 获取聊天触发次数 */
|
||||
public getImageUnlockCountsById(id: number, resId: number): number | null {
|
||||
let oneData = this.getOneCommercialImageById(id, resId);
|
||||
if (!oneData) return null;
|
||||
if (index < 0 || index >= oneData.length) return null;
|
||||
return oneData[index].imagePrice;
|
||||
return oneData.unlockCounts;
|
||||
}
|
||||
|
||||
/** 根据 id 获取图片价格 */
|
||||
public getImagePriceById(id: number, resId: number): number | null {
|
||||
let oneData = this.getOneCommercialImageById(id, resId);
|
||||
if (!oneData) return null;
|
||||
return oneData.imagePrice;
|
||||
}
|
||||
|
||||
/** 根据 id 和 index 获取图片路径 */
|
||||
public getImagePathById(id: number, index: number): string | null {
|
||||
let oneData = this.getCommercialImagesById(id);
|
||||
/** 根据 id 获取图片路径 */
|
||||
public getImagePathById(id: number, resId: number): string | null {
|
||||
let oneData = this.getOneCommercialImageById(id, resId);
|
||||
if (!oneData) return null;
|
||||
if (index < 0 || index >= oneData.length) return null;
|
||||
return oneData[index].path;
|
||||
return oneData.path;
|
||||
}
|
||||
|
||||
/** 根据 id 获取 commercialVideos */
|
||||
@@ -93,27 +122,49 @@ export class GirlDetailConfig extends BaseConfig {
|
||||
return oneData.length;
|
||||
}
|
||||
|
||||
/** 根据 id 和 index 获取视频路径 */
|
||||
public getVideoPathById(id: number, index: number): string | null {
|
||||
/** 根据 id 获取 commercialVideo的id数组 */
|
||||
public getCommercialVideosIds(id: number): number[] {
|
||||
let oneData = this.getCommercialVideosById(id);
|
||||
if (!oneData) return null;
|
||||
if (index < 0 || index >= oneData.length) return null;
|
||||
return oneData[index].path;
|
||||
if (!oneData) return [];
|
||||
// 获取所有 id
|
||||
let allId = [];
|
||||
for (let one of oneData) {
|
||||
allId.push(one.id);
|
||||
}
|
||||
return allId;
|
||||
}
|
||||
|
||||
/** 根据 id 和 index 获取关联情绪 */
|
||||
public getVideoEmotionById(id: number, index: number): number | null {
|
||||
/** 根据 id 获取 某一个commercialVideo */
|
||||
private getOneCommercialVideoById(id: number, resId: number): any | null {
|
||||
let oneData = this.getCommercialVideosById(id);
|
||||
if (!oneData) return null;
|
||||
if (index < 0 || index >= oneData.length) return null;
|
||||
return oneData[index].emotion;
|
||||
// 遍历数组找到匹配的资源
|
||||
for (let one of oneData) {
|
||||
if (one.id === resId) {
|
||||
return one;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 根据 id 获取视频路径 */
|
||||
public getVideoPathById(id: number, resId: number): string | null {
|
||||
let oneData = this.getOneCommercialVideoById(id, resId);
|
||||
if (!oneData) return null;
|
||||
return oneData.path;
|
||||
}
|
||||
|
||||
/** 根据 id 和 index 获取视频价格 */
|
||||
public getVideoPriceById(id: number, index: number): number | null {
|
||||
let oneData = this.getCommercialVideosById(id);
|
||||
/** 根据 id 获取关联情绪 */
|
||||
public getVideoEmotionById(id: number, resId: number): number | null {
|
||||
let oneData = this.getOneCommercialVideoById(id, resId);
|
||||
if (!oneData) return null;
|
||||
if (index < 0 || index >= oneData.length) return null;
|
||||
return oneData[index].videoPrice;
|
||||
return oneData.emotion;
|
||||
}
|
||||
|
||||
/** 根据 id 获取视频价格 */
|
||||
public getVideoPriceById(id: number, resId: number): number | null {
|
||||
let oneData = this.getOneCommercialVideoById(id, resId);
|
||||
if (!oneData) return null;
|
||||
return oneData.videoPrice;
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,20 @@ export class GlobalConfig extends BaseConfig {
|
||||
return oneData.FreeChatTimes;
|
||||
}
|
||||
|
||||
/** 单次对话增长好感度 */
|
||||
public getOnceChatAddScore(): number | null {
|
||||
let oneData = this.getAllConfig();
|
||||
if (!oneData) return null;
|
||||
return oneData.OnceChatAddScore;
|
||||
}
|
||||
|
||||
/** 好感度等级兑换比例 */
|
||||
public getScoreExchangeStarLevel(): number | null {
|
||||
let oneData = this.getAllConfig();
|
||||
if (!oneData) return null;
|
||||
return oneData.ScoreExchangeStarLevel;
|
||||
}
|
||||
|
||||
/** 游戏名 */
|
||||
public getGameName(): string | null {
|
||||
let oneData = this.getAllConfig();
|
||||
|
||||
@@ -25,6 +25,65 @@ export class PurchaseConfig extends BaseConfig {
|
||||
return ConfigManager.tables.TbPurchaseConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有配置 id,如果存在
|
||||
*/
|
||||
public getAllId(): any | null {
|
||||
let allData = this.getAllConfig();
|
||||
if (!allData) return null;
|
||||
const dataArr = allData.getDataList();
|
||||
let allId = [];
|
||||
for (let oneData of dataArr) {
|
||||
allId.push(oneData.id);
|
||||
}
|
||||
return allId;
|
||||
}
|
||||
|
||||
/** 获取 充值商品的id数组,首位数字为 1 */
|
||||
public getRechargeIds(): number[] {
|
||||
let allId = this.getAllId();
|
||||
if (!allId) return [];
|
||||
// 获取所有 id
|
||||
let resultId = [];
|
||||
for (let one of allId) {
|
||||
const firstDigit = one.toString()[0]; // 取首位字符
|
||||
if (firstDigit === "1") {
|
||||
resultId.push(one);
|
||||
}
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
/** 获取 会员商品的id数组,首位数字为 2 */
|
||||
public getMemberIds(): number[] {
|
||||
let allId = this.getAllId();
|
||||
if (!allId) return [];
|
||||
// 获取所有 id
|
||||
let resultId = [];
|
||||
for (let one of allId) {
|
||||
const firstDigit = one.toString()[0];
|
||||
if (firstDigit === "2") {
|
||||
resultId.push(one);
|
||||
}
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
/** 获取 聊天商品的id数组,首位数字为 3 */
|
||||
public getChatIds(): number[] {
|
||||
let allId = this.getAllId();
|
||||
if (!allId) return [];
|
||||
// 获取所有 id
|
||||
let resultId = [];
|
||||
for (let one of allId) {
|
||||
const firstDigit = one.toString()[0];
|
||||
if (firstDigit === "3") {
|
||||
resultId.push(one);
|
||||
}
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置,根据 id
|
||||
*/
|
||||
@@ -47,4 +106,11 @@ export class PurchaseConfig extends BaseConfig {
|
||||
if (!oneData) return null;
|
||||
return oneData.count;
|
||||
}
|
||||
|
||||
/** 根据商品 id 获取商品价格 */
|
||||
public getPriceById(id: number): number | null {
|
||||
let oneData = this.getConfigById(id);
|
||||
if (!oneData) return null;
|
||||
return oneData.price;
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ export class AccountData extends BaseData {
|
||||
private _identifier = "";
|
||||
// 身份类型,1:游客;2:微信;3:googleplay
|
||||
private _identityType = 1;
|
||||
// 玩家Uid
|
||||
private _uid = "";
|
||||
// 用户id
|
||||
private _accId = 0;
|
||||
// 是否新手
|
||||
private _isNewGuide = true;
|
||||
// 是否刚注册
|
||||
@@ -18,7 +18,7 @@ export class AccountData extends BaseData {
|
||||
public reset(): void {
|
||||
this._identifier = "";
|
||||
this._identityType = 1;
|
||||
this._uid = "";
|
||||
this._accId = 0;
|
||||
this._isNewGuide = true;
|
||||
this._isNewRegist = true;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export class AccountData extends BaseData {
|
||||
public clear(): void {
|
||||
this._identifier = "";
|
||||
this._identityType = 1;
|
||||
this._uid = "";
|
||||
this._accId = 0;
|
||||
this._isNewGuide = true;
|
||||
this._isNewRegist = true;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ export class AccountData extends BaseData {
|
||||
super.destroy();
|
||||
this._identifier = null;
|
||||
this._identityType = null;
|
||||
this._uid = null;
|
||||
this._accId = null;
|
||||
this._isNewGuide = null;
|
||||
this._isNewRegist = null;
|
||||
}
|
||||
@@ -60,14 +60,14 @@ export class AccountData extends BaseData {
|
||||
return this._identityType;
|
||||
}
|
||||
|
||||
/** 设置玩家Uid */
|
||||
public set uid(value: string) {
|
||||
this._uid = value;
|
||||
/** 设置用户id */
|
||||
public set accId(value: number) {
|
||||
this._accId = value;
|
||||
}
|
||||
|
||||
/** 获取玩家Uid */
|
||||
public get uid(): string {
|
||||
return this._uid;
|
||||
/** 获取用户id */
|
||||
public get accId(): number {
|
||||
return this._accId;
|
||||
}
|
||||
|
||||
/** 设置是否新手 */
|
||||
|
||||
@@ -13,6 +13,13 @@ export class BaseData {
|
||||
/** 数据ID */
|
||||
protected _dataId: string = '';
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*/
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
* @param dataId 数据ID
|
||||
|
||||
@@ -13,6 +13,7 @@ import { WalletData } from "./WalletData";
|
||||
import { ShopData } from "./ShopData";
|
||||
import { OrderData } from "./OrderData";
|
||||
import { GirlData } from "./GirlData";
|
||||
import { EnvData } from "./EnvData";
|
||||
|
||||
/**
|
||||
* 集中定义数据ID,避免写错字符串
|
||||
@@ -28,6 +29,12 @@ export enum DataId {
|
||||
Shop = "shop", // 商城数据
|
||||
Order = "order", // 订单数据
|
||||
Girl = "girl", // 技师数据
|
||||
GirlBrief = "girlBrief", // 技师的简要数据
|
||||
GirlDetail = "girlDetail", // 技师的详细数据
|
||||
GirlUnlock = "girlUnlock", // 技师的解锁数据
|
||||
GirlChat = "girlChat", // 技师的聊天数据
|
||||
GirlFavorability = "girlFavorability", // 技师的好感度数据
|
||||
Env = "env", // 环境数据
|
||||
}
|
||||
|
||||
/** 构造器类型 */
|
||||
@@ -70,6 +77,7 @@ export class DataManager {
|
||||
this.register(DataId.Shop, ShopData);
|
||||
this.register(DataId.Order, OrderData);
|
||||
this.register(DataId.Girl, GirlData);
|
||||
this.register(DataId.Env, EnvData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 环境数据
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
|
||||
export class EnvData extends BaseData {
|
||||
// cdn地址
|
||||
private _cdn: string = '';
|
||||
|
||||
public reset(): void {
|
||||
this._cdn = '';
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._cdn = '';
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this._cdn = null;
|
||||
}
|
||||
|
||||
/** 设置cdn地址 */
|
||||
public set cdn(value: string) {
|
||||
this._cdn = value;
|
||||
}
|
||||
|
||||
/** 获取cdn地址 */
|
||||
public get cdn(): string {
|
||||
return this._cdn;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "cf8c891f-8726-42be-918b-4f101118dae3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* 技师的简要数据
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
export class GirlBriefData extends BaseData {
|
||||
// id
|
||||
private id: number;
|
||||
// 名字键
|
||||
private nameKey: string;
|
||||
// 年龄
|
||||
private age: string;
|
||||
// 主题枚举
|
||||
private category: number;
|
||||
// 标签键
|
||||
private tagKey: string;
|
||||
// 付费类型
|
||||
private priceType: number;
|
||||
// 购买价格
|
||||
private price: number;
|
||||
// VIP能否解锁
|
||||
private vipUnlock: number;
|
||||
// 头像路径
|
||||
private avatarPath: string;
|
||||
// list头像路径
|
||||
private listAvatarPath: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.id = 0;
|
||||
this.nameKey = "";
|
||||
this.age = "";
|
||||
this.category = 0;
|
||||
this.tagKey = "";
|
||||
this.priceType = 0;
|
||||
this.price = 0;
|
||||
this.vipUnlock = 0;
|
||||
this.avatarPath = "";
|
||||
this.listAvatarPath = "";
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.id = 0;
|
||||
this.nameKey = "";
|
||||
this.age = "";
|
||||
this.category = 0;
|
||||
this.tagKey = "";
|
||||
this.priceType = 0;
|
||||
this.price = 0;
|
||||
this.vipUnlock = 0;
|
||||
this.avatarPath = "";
|
||||
this.listAvatarPath = "";
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.id = 0;
|
||||
this.nameKey = "";
|
||||
this.age = "";
|
||||
this.category = 0;
|
||||
this.tagKey = "";
|
||||
this.priceType = 0;
|
||||
this.price = 0;
|
||||
this.vipUnlock = 0;
|
||||
this.avatarPath = "";
|
||||
this.listAvatarPath = "";
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this.id = null;
|
||||
this.nameKey = null;
|
||||
this.age = null;
|
||||
this.category = null;
|
||||
this.tagKey = null;
|
||||
this.priceType = null;
|
||||
this.price = null;
|
||||
this.vipUnlock = null;
|
||||
this.avatarPath = null;
|
||||
this.listAvatarPath = null;
|
||||
}
|
||||
|
||||
/** 保存数据 */
|
||||
public setData(data: proto.cs.IGirls): void {
|
||||
if (!data) return;
|
||||
this.id = data.id;
|
||||
this.nameKey = data.nameKey;
|
||||
this.age = data.age;
|
||||
this.category = data.category;
|
||||
this.tagKey = data.tagKey;
|
||||
this.priceType = data.priceType;
|
||||
this.price = data.price;
|
||||
this.vipUnlock = data.vipUnlock;
|
||||
this.avatarPath = data.avatarPath;
|
||||
this.listAvatarPath = data.listAvatarPath;
|
||||
console.log("保存了技师的简要数据,id:", this.id);
|
||||
}
|
||||
|
||||
/** 获取 id */
|
||||
public getId(): number {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/** 获取名字键 */
|
||||
public getGrilName(): string {
|
||||
return this.nameKey;
|
||||
}
|
||||
|
||||
/** 获取年龄 */
|
||||
public getGrilAge(): string {
|
||||
return this.age;
|
||||
}
|
||||
|
||||
/** 获取主题枚举 */
|
||||
public getGrilCategory(): number {
|
||||
return this.category;
|
||||
}
|
||||
|
||||
/** 获取标签键 */
|
||||
public getGrilTagKey(): string {
|
||||
return this.tagKey;
|
||||
}
|
||||
|
||||
/** 获取付费类型 */
|
||||
public getGrilPriceType(): number {
|
||||
return this.priceType;
|
||||
}
|
||||
|
||||
/** 获取价格 */
|
||||
public getGrilPrice(): number {
|
||||
return this.price;
|
||||
}
|
||||
|
||||
/** 获取VIP能否解锁 */
|
||||
public getGrilVipUnlock(): number {
|
||||
return this.vipUnlock;
|
||||
}
|
||||
|
||||
/** 获取头像路径 */
|
||||
public getGrilAvatar(): string {
|
||||
return this.avatarPath;
|
||||
}
|
||||
|
||||
/** 获取list头像路径 */
|
||||
public getGrilListAvatar(): string {
|
||||
return this.listAvatarPath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "35c42c32-997a-40f3-b689-6de7e53cdf3b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 技师的聊天数据
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
export class GirlChatData extends BaseData {
|
||||
// id
|
||||
private id: number;
|
||||
// 总聊天次数
|
||||
private chatTotalCount: number;
|
||||
// 剩余聊天次数, < 0: 不限制; = 0 聊天次数已经用完; > 0 还剩余多少次聊天次数
|
||||
private chatRemainCount: number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.id = 0;
|
||||
this.chatTotalCount = 0;
|
||||
this.chatRemainCount = 0;
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.id = 0;
|
||||
this.chatTotalCount = 0;
|
||||
this.chatRemainCount = 0;
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.id = 0;
|
||||
this.chatTotalCount = 0;
|
||||
this.chatRemainCount = 0;
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this.id = null;
|
||||
this.chatTotalCount = null;
|
||||
this.chatRemainCount = null;
|
||||
}
|
||||
|
||||
/** 获取 id */
|
||||
public getId(): number {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/** 保存 id */
|
||||
public setId(value: number): void {
|
||||
this.id = value;
|
||||
}
|
||||
|
||||
/** 获取总聊天次数 */
|
||||
public getChatTotalCount(): number {
|
||||
return this.chatTotalCount;
|
||||
}
|
||||
|
||||
/** 保存总聊天次数 */
|
||||
public setChatTotalCount(value: number): void {
|
||||
this.chatTotalCount = value;
|
||||
console.log("当前总聊天次数:", this.chatTotalCount);
|
||||
}
|
||||
|
||||
/** 获取剩余聊天次数 */
|
||||
public getChatRemainCount(): number {
|
||||
return this.chatRemainCount;
|
||||
}
|
||||
|
||||
/** 保存剩余聊天次数 */
|
||||
public setChatRemainCount(value: number): void {
|
||||
this.chatRemainCount = value;
|
||||
console.log("当前剩余聊天次数:", this.chatRemainCount);
|
||||
}
|
||||
|
||||
/** 更新剩余聊天次数 */
|
||||
public useChat(times: number = 1) {
|
||||
if (this.chatRemainCount > 0) {
|
||||
this.setChatRemainCount(Math.max(0, this.chatRemainCount - times));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "40a2e0a1-fce2-4812-97b5-f96153800c52",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -1,15 +1,27 @@
|
||||
/**
|
||||
* 技师数据
|
||||
* 技师数据,统一访问入口
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
import { GirlBriefData } from "./GirlBriefData";
|
||||
import { GirlDetailData } from "./GirlDetailData";
|
||||
import { GirlUnlockData } from "./GirlUnlockData";
|
||||
import { GirlChatData } from "./GirlChatData";
|
||||
import { GirlFavorabilityData } from "./GirlFavorabilityData";
|
||||
import { DataId } from "./DataManager";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
// 分类的数据结构
|
||||
interface CategoryBucket {
|
||||
// 技师的简要数据
|
||||
briefs: Map<number, proto.cs.IGirlBrief>;
|
||||
briefs: Map<number, GirlBriefData>;
|
||||
// 技师的详细数据
|
||||
details: Map<number, proto.cs.IGirlDetail>;
|
||||
details: Map<number, GirlDetailData>;
|
||||
// 技师的解锁数据
|
||||
unlocks: Map<number, GirlUnlockData>;
|
||||
// 技师的聊天数据
|
||||
chats: Map<number, GirlChatData>;
|
||||
// 技师的好感度数据
|
||||
favorability: Map<number, GirlFavorabilityData>;
|
||||
// 技师的id
|
||||
girlIds: number[];
|
||||
}
|
||||
@@ -20,8 +32,6 @@ const DAILY_BUCKET = "__daily__";
|
||||
export class GirlData extends BaseData {
|
||||
// 大分类
|
||||
private _categories = new Map<string, CategoryBucket>();
|
||||
// 每日推荐(存放在 DAILY_BUCKET 中,同时保留 id 索引便于 UI 使用)
|
||||
private _dailyRecommendIds: number[] = [];
|
||||
|
||||
public reset(): void {
|
||||
this._categories.clear();
|
||||
@@ -50,271 +60,208 @@ export class GirlData extends BaseData {
|
||||
let bucket = cats.get(categoryId);
|
||||
if (!bucket) {
|
||||
bucket = {
|
||||
briefs: new Map<number, proto.cs.IGirlBrief>(),
|
||||
details: new Map<number, proto.cs.IGirlDetail>(),
|
||||
briefs: new Map<number, GirlBriefData>(),
|
||||
details: new Map<number, GirlDetailData>(),
|
||||
unlocks: new Map<number, GirlUnlockData>(),
|
||||
chats: new Map<number, GirlChatData>(),
|
||||
favorability: new Map<number, GirlFavorabilityData>(),
|
||||
girlIds: [],
|
||||
};
|
||||
cats.set(categoryId, bucket);
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并一批简要信息到指定分类;并维护 girlIds 顺序(去重追加)
|
||||
*/
|
||||
public mergeBriefs(categoryId: string, respOrList: proto.cs.IGirlBrief[]): void {
|
||||
if (!respOrList) return;
|
||||
let allData = this.parseAllGirlBrief(respOrList);
|
||||
if (!allData) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
// 用一个临时 Set 保存已有的 id,加速去重
|
||||
const existed = new Set<number>(bucket.girlIds);
|
||||
for (const g of allData) {
|
||||
const id = g.id;
|
||||
bucket.briefs.set(id, g);
|
||||
// 去重
|
||||
if (!existed.has(id)) {
|
||||
bucket.girlIds.push(id);
|
||||
existed.add(id);
|
||||
}
|
||||
}
|
||||
console.log("保存技师的简要数据: ", bucket);
|
||||
}
|
||||
|
||||
/** 取分类下的全部 girlIds(若分类不存在返回空数组) */
|
||||
public getGirlIds(categoryId: string): number[] {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
return b ? b.girlIds : [];
|
||||
}
|
||||
|
||||
/** 保存技师列表 */
|
||||
public setGirlList(categoryId: string, data: proto.cs.ICSGetGirlListRes): void {
|
||||
if (!data) return;
|
||||
this.setGirlBrief(categoryId, data.girls);
|
||||
this.setGirlUnlock(categoryId, data.girls);
|
||||
this.setGirlFavorability(categoryId, data.girls);
|
||||
}
|
||||
|
||||
/** 保存技师详细数据 */
|
||||
public setGirlDetailData(categoryId: string, data: proto.cs.ICSGetGirlDetailRes): void {
|
||||
if (!data) return;
|
||||
let details = []
|
||||
details.push(data.girl);
|
||||
this.setGirlBrief(categoryId, details);
|
||||
this.setGirlDetail(categoryId, details);
|
||||
this.setGirlUnlock(categoryId, details);
|
||||
this.setGirlChat(categoryId, details);
|
||||
this.setGirlFavorability(categoryId, details);
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 技师的简要数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师简要数据,一个
|
||||
private parseOneGirlBrief(data: proto.cs.IGirlBrief): proto.cs.IGirlBrief | null {
|
||||
/**
|
||||
* 合并一个简要数据到指定分类;并维护 girlIds 顺序(去重追加)
|
||||
*/
|
||||
private mergeOneBrief(categoryId: string, data: proto.cs.IGirls): void {
|
||||
if (!data) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
// 用一个临时 Set 保存已有的 id,加速去重
|
||||
const existed = new Set<number>(bucket.girlIds);
|
||||
let id = data.id;
|
||||
const one = this.parseOneGirlBrief(data);
|
||||
if (!one) return;
|
||||
bucket.briefs.set(id, one);
|
||||
if (!existed.has(id)) {
|
||||
bucket.girlIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并一批简要数据到指定分类;并维护 girlIds 顺序(去重追加)
|
||||
*/
|
||||
private mergeBriefs(categoryId: string, respOrList: proto.cs.IGirlData[]): void {
|
||||
if (!respOrList) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
// 用一个临时 Set 保存已有的 id,加速去重
|
||||
const existed = new Set<number>(bucket.girlIds);
|
||||
|
||||
for (const g of respOrList) {
|
||||
const one = this.parseOneGirlBrief(g.girl);
|
||||
if (!one) continue;
|
||||
bucket.briefs.set(g.id, one);
|
||||
|
||||
if (!existed.has(g.id)) {
|
||||
bucket.girlIds.push(g.id);
|
||||
existed.add(g.id);
|
||||
}
|
||||
}
|
||||
console.log("保存技师的简要数据: ", bucket);
|
||||
}
|
||||
|
||||
private parseOneGirlBrief(data: proto.cs.IGirls): GirlBriefData | null {
|
||||
if (!data) return null;
|
||||
const oneData: proto.cs.IGirlBrief = {
|
||||
id: data.id, // id
|
||||
name: data.name, // 名字
|
||||
age: data.age, // 年龄
|
||||
tagKey: data.tagKey, // 标签
|
||||
priceType: data.priceType, // 付费类型
|
||||
price: data.price, // 价格
|
||||
avatar: data.avatar, // 头像
|
||||
star: data.star, // 星级
|
||||
category: data.category, // 主题枚举
|
||||
listAvatarPath: data.listAvatarPath, // list头像路径
|
||||
};
|
||||
let oneData = new GirlBriefData();
|
||||
oneData.init?.(DataId.GirlBrief);
|
||||
oneData.setData(data);
|
||||
return oneData;
|
||||
}
|
||||
|
||||
// 解析技师简要数据,多个
|
||||
private parseAllGirlBrief(data: proto.cs.IGirlBrief[]): proto.cs.IGirlBrief[] | null {
|
||||
if (!data) return null;
|
||||
let allData = [];
|
||||
for (const value of data) {
|
||||
const oneData: proto.cs.IGirlBrief = this.parseOneGirlBrief(value);
|
||||
if (oneData) {
|
||||
allData.push(oneData);
|
||||
}
|
||||
}
|
||||
return allData;
|
||||
}
|
||||
|
||||
/** 保存技师的简要数据 */
|
||||
public setGirlBriefs(categoryId: string, data: proto.cs.ICSGetGirlListRes): void {
|
||||
this.mergeBriefs(categoryId, data.girls);
|
||||
private setGirlBrief(categoryId: string, data: proto.cs.IGirlData[]): void {
|
||||
this.mergeBriefs(categoryId, data);
|
||||
}
|
||||
|
||||
/** 取某分类 + girlId 的简要信息 */
|
||||
private getGrilBrief(categoryId: string, girlId: number): proto.cs.IGirlBrief | null {
|
||||
/** 取某分类 + girlId 的简要数据 */
|
||||
private getGrilBrief(categoryId: string, girlId: number): GirlBriefData | null {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
if (!b) return null;
|
||||
return b.briefs.get(girlId) ?? null;
|
||||
}
|
||||
|
||||
/** 获取名字 */
|
||||
/** 获取名字键 */
|
||||
public getGrilName(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.name;
|
||||
return oneData.getGrilName();
|
||||
}
|
||||
|
||||
/** 获取年龄 */
|
||||
public getGrilAge(categoryId: string, girlId: number): number {
|
||||
public getGrilAge(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return "0";
|
||||
return oneData.getGrilAge();
|
||||
}
|
||||
|
||||
/** 获取主题枚举 */
|
||||
public getGrilCategory(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.age;
|
||||
}
|
||||
return oneData.getGrilCategory();
|
||||
}
|
||||
|
||||
/** 获取标签 */
|
||||
/** 获取标签键 */
|
||||
public getGrilTagKey(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.tagKey;
|
||||
return oneData.getGrilTagKey();
|
||||
}
|
||||
|
||||
/** 获取付费类型 */
|
||||
public getGrilPriceType(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.priceType;
|
||||
return oneData.getGrilPriceType();
|
||||
}
|
||||
|
||||
/** 获取价格 */
|
||||
public getGrilPrice(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.price;
|
||||
return oneData.getGrilPrice();
|
||||
}
|
||||
|
||||
/** 获取VIP能否解锁 */
|
||||
public getGrilVipUnlock(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getGrilVipUnlock();
|
||||
}
|
||||
|
||||
/** 获取头像 */
|
||||
/** 获取头像路径 */
|
||||
public getGrilAvatar(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.avatar;
|
||||
}
|
||||
|
||||
/** 获取星级 */
|
||||
public getGrilStar(categoryId: string, girlId: number): number {
|
||||
return oneData.getGrilAvatar();
|
||||
}
|
||||
|
||||
/** 获取list头像路径 */
|
||||
public getGrilListAvatar(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.star;
|
||||
}
|
||||
|
||||
/** 获取主题枚举 */
|
||||
public getGrilCategory(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.category;
|
||||
if (!oneData) return "";
|
||||
return oneData.getGrilListAvatar();
|
||||
}
|
||||
|
||||
/** 获取主题枚举,根据 id */
|
||||
public getGrilCategoryById(girlId: number): number {
|
||||
const cats = this.ensureCategories();
|
||||
|
||||
// 遍历
|
||||
for (const bucket of cats.values()) {
|
||||
// 先查简要信息
|
||||
const brief = bucket.briefs.get(girlId);
|
||||
if (brief && brief.category) {
|
||||
return brief.category;
|
||||
}
|
||||
// 兜底:若只缓存了详情,也从详情里的 brief 取
|
||||
const detail = bucket.details.get(girlId);
|
||||
if (detail?.brief && typeof detail.brief.category) {
|
||||
return detail.brief.category;
|
||||
if (brief) {
|
||||
return brief.getGrilCategory();
|
||||
}
|
||||
}
|
||||
|
||||
// 未找到
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 获取list头像路径 */
|
||||
public getGrilListAvatar(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilBrief(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.listAvatarPath;
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 技师的详细数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师图片数据,一个
|
||||
private parseOneGirlPhoto(data: proto.cs.IPurchaseCommercialImage): proto.cs.IPurchaseCommercialImage | null {
|
||||
if (!data) return null;
|
||||
const oneData: proto.cs.IPurchaseCommercialImage = {
|
||||
imageType: data.imageType, // 图片类型
|
||||
imagePrice: data.imagePrice, // 图片价格
|
||||
path: data.path, // 图片资源路径
|
||||
isRelease: data.isRelease, // 是否解锁
|
||||
};
|
||||
return oneData;
|
||||
}
|
||||
|
||||
// 解析技师图片数据,多个
|
||||
private parseAllGirlPhoto(data: proto.cs.IPurchaseCommercialImage[]): proto.cs.IPurchaseCommercialImage[] | null {
|
||||
if (!data) return null;
|
||||
let allData = [];
|
||||
for (const value of data) {
|
||||
const oneData: proto.cs.IPurchaseCommercialImage = this.parseOneGirlPhoto(value);
|
||||
if (oneData) {
|
||||
allData.push(oneData);
|
||||
}
|
||||
}
|
||||
return allData;
|
||||
}
|
||||
|
||||
// 解析技师视频数据,一个
|
||||
private parseOneGirlVideo(data: proto.cs.IPurchaseCommercialVideo): proto.cs.IPurchaseCommercialVideo | null {
|
||||
if (!data) return null;
|
||||
const oneData: proto.cs.IPurchaseCommercialVideo = {
|
||||
path: data.path, // 视频资源路径
|
||||
emotion: data.emotion, // 关联情绪
|
||||
videoPrice: data.videoPrice, // 价格
|
||||
isRelease: data.isRelease, // 是否解锁
|
||||
};
|
||||
return oneData;
|
||||
}
|
||||
|
||||
// 解析技师视频数据,多个
|
||||
private parseAllGirlVideo(data: proto.cs.IPurchaseCommercialVideo[]): proto.cs.IPurchaseCommercialVideo[] | null {
|
||||
if (!data) return null;
|
||||
let allData = [];
|
||||
for (const value of data) {
|
||||
const oneData: proto.cs.IPurchaseCommercialVideo = this.parseOneGirlVideo(value);
|
||||
if (oneData) {
|
||||
allData.push(oneData);
|
||||
}
|
||||
}
|
||||
return allData;
|
||||
}
|
||||
|
||||
// 解析技师详细数据,一个
|
||||
private parseOneGirlDetail(data: proto.cs.IGirlDetail): proto.cs.IGirlDetail | null {
|
||||
private parseOneGirlDetail(data: proto.cs.IGirlsDetail): GirlDetailData | null {
|
||||
if (!data) return null;
|
||||
const photoData = this.parseAllGirlPhoto(data.images);
|
||||
const videoData = this.parseAllGirlVideo(data.videos);
|
||||
const briefData = this.parseOneGirlBrief(data.brief);
|
||||
const oneData: proto.cs.IGirlDetail = {
|
||||
brief: briefData, // 技师简要数据
|
||||
desc: data.desc, // 技师描述
|
||||
isRelease: data.isRelease, // 技师是否解锁
|
||||
chatCount: data.chatCount, // 剩余聊天次数
|
||||
images: photoData, // 技师图片列表
|
||||
videos: videoData, // 技师视频列表
|
||||
};
|
||||
let oneData = new GirlDetailData();
|
||||
oneData.init?.(DataId.GirlDetail);
|
||||
oneData.setData(data);
|
||||
return oneData;
|
||||
}
|
||||
|
||||
// 解析技师详细数据,多个
|
||||
private parseAllGirlDetail(data: proto.cs.IGirlDetail[]): proto.cs.IGirlDetail[] | null {
|
||||
if (!data) return null;
|
||||
let allData = [];
|
||||
for (const value of data) {
|
||||
const oneData: proto.cs.IGirlDetail = this.parseOneGirlDetail(value);
|
||||
if (oneData) {
|
||||
allData.push(oneData);
|
||||
}
|
||||
}
|
||||
return allData;
|
||||
}
|
||||
|
||||
/** 保存技师的详细数据 */
|
||||
public setGirlDetails(categoryId: string, data: proto.cs.ICSGetGirlDetailRes): void {
|
||||
const d = data?.detail;
|
||||
if (!d) return;
|
||||
// 合并简要信息
|
||||
if (d.brief) this.mergeBriefs(categoryId, [d.brief]);
|
||||
const oneDetail = this.parseOneGirlDetail(d);
|
||||
private setGirlDetail(categoryId: string, data: proto.cs.IGirlData[]): void {
|
||||
if (!data) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
// id
|
||||
const id = d.brief?.id ?? 0;
|
||||
// 写入详情
|
||||
bucket.details.set(id, oneDetail);
|
||||
for (const g of data) {
|
||||
const one = this.parseOneGirlDetail(g.detail);
|
||||
if (!one) continue;
|
||||
bucket.details.set(g.id, one);
|
||||
}
|
||||
console.log("保存技师的详细数据: ", bucket);
|
||||
}
|
||||
|
||||
/** 取某分类 + girlId 的详细信息 */
|
||||
public getGrilDetail(categoryId: string, girlId: number): proto.cs.IGirlDetail | null {
|
||||
/** 取某分类 + girlId 的详细数据 */
|
||||
public getGrilDetail(categoryId: string, girlId: number): GirlDetailData | null {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
if (!b) return null;
|
||||
return b.details.get(girlId) ?? null;
|
||||
@@ -324,163 +271,321 @@ export class GirlData extends BaseData {
|
||||
public getGrilDesc(categoryId: string, girlId: number): string {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.desc;
|
||||
}
|
||||
|
||||
/** 获取技师是否解锁 */
|
||||
public getGrilIsRelease(categoryId: string, girlId: number): boolean {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return false;
|
||||
return oneData.isRelease;
|
||||
}
|
||||
|
||||
/** 获取技师剩余聊天次数 */
|
||||
public getGrilChatCount(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.chatCount;
|
||||
}
|
||||
|
||||
/** 获取所有技师图片数据 */
|
||||
private getAllGrilPhotoData(categoryId: string, girlId: number): proto.cs.IPurchaseCommercialImage[] | null {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData || !oneData.images) return null;
|
||||
return oneData.images;
|
||||
}
|
||||
return oneData.getGirlDesc();
|
||||
}
|
||||
|
||||
/** 获取所有技师图片数据的数量 */
|
||||
public getAllGrilPhotoDataCount(categoryId: string, girlId: number): number {
|
||||
let allData = this.getAllGrilPhotoData(categoryId, girlId);
|
||||
if (!allData) return 0;
|
||||
return allData.length;
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getAllGrilPhotoDataCount();
|
||||
}
|
||||
|
||||
/** 获取技师图片数据,通过 index */
|
||||
private getGrilPhotoData(categoryId: string, girlId: number, index: number): proto.cs.IPurchaseCommercialImage | null {
|
||||
let allData = this.getAllGrilPhotoData(categoryId, girlId);
|
||||
if (!allData) return null;
|
||||
// 下标越界保护
|
||||
if (index < 0 || index >= allData.length) return null;
|
||||
|
||||
return allData[index] ?? null;
|
||||
}
|
||||
/** 获取所有技师图片数据的id */
|
||||
public getAllGrilPhotoDataId(categoryId: string, girlId: number): number[] {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return [];
|
||||
return oneData.getAllGrilPhotoDataId();
|
||||
}
|
||||
|
||||
/** 获取技师图片的类型 */
|
||||
public getGrilPhotoType(categoryId: string, girlId: number, index: number): number {
|
||||
let oneData = this.getGrilPhotoData(categoryId, girlId, index);
|
||||
public getGrilPhotoType(categoryId: string, girlId: number, id: number): number {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.imageType;
|
||||
return oneData.getGrilPhotoType(id);
|
||||
}
|
||||
|
||||
/** 获取技师图片的聊天触发次数 */
|
||||
public getGrilPhotoUnlockCounts(categoryId: string, girlId: number, id: number): number {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getGrilPhotoUnlockCounts(id);
|
||||
}
|
||||
|
||||
/** 获取技师图片的价格 */
|
||||
public getGrilPhotoPrice(categoryId: string, girlId: number, index: number): number {
|
||||
let oneData = this.getGrilPhotoData(categoryId, girlId, index);
|
||||
if (!oneData) return 0;
|
||||
return oneData.imagePrice;
|
||||
}
|
||||
|
||||
/** 获取技师图片的路径 */
|
||||
public getGrilPhotoPic(categoryId: string, girlId: number, index: number): string {
|
||||
let oneData = this.getGrilPhotoData(categoryId, girlId, index);
|
||||
if (!oneData) return "";
|
||||
return oneData.path;
|
||||
}
|
||||
|
||||
/** 获取技师图片是否解锁 */
|
||||
public getGrilPhotoIsRelease(categoryId: string, girlId: number, index: number): boolean {
|
||||
let oneData = this.getGrilPhotoData(categoryId, girlId, index);
|
||||
if (!oneData) return false;
|
||||
return oneData.isRelease;
|
||||
}
|
||||
|
||||
/** 获取所有技师视频数据 */
|
||||
private getAllGrilVideoData(categoryId: string, girlId: number): proto.cs.IPurchaseCommercialVideo[] | null {
|
||||
public getGrilPhotoPrice(categoryId: string, girlId: number, id: number): number {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData || !oneData.videos) return null;
|
||||
|
||||
return oneData.videos ?? null;
|
||||
if (!oneData) return 0;
|
||||
return oneData.getGrilPhotoPrice(id);
|
||||
}
|
||||
|
||||
/** 获取技师图片的资源路径 */
|
||||
public getGrilPhotoPic(categoryId: string, girlId: number, id: number): string {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.getGrilPhotoPath(id);
|
||||
}
|
||||
|
||||
/** 获取所有技师视频数据的数量 */
|
||||
public getAllGrilVideoDataCount(categoryId: string, girlId: number): number {
|
||||
let allData = this.getAllGrilVideoData(categoryId, girlId);
|
||||
if (!allData) return 0;
|
||||
return allData.length;
|
||||
}
|
||||
|
||||
/** 获取技师视频数据,通过 index */
|
||||
private getGrilVideoData(categoryId: string, girlId: number, index: number): proto.cs.IPurchaseCommercialVideo | null {
|
||||
let allData = this.getAllGrilVideoData(categoryId, girlId);
|
||||
if (!allData) return null;
|
||||
// 下标越界保护
|
||||
if (index < 0 || index >= allData.length) return null;
|
||||
|
||||
return allData[index] ?? null;
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getAllGrilVideoDataCount();
|
||||
}
|
||||
|
||||
/** 获取技师视频的路径 */
|
||||
public getGrilVideoPath(categoryId: string, girlId: number, index: number): string {
|
||||
let oneData = this.getGrilVideoData(categoryId, girlId, index);
|
||||
/** 获取所有技师视频数据的id */
|
||||
public getAllGrilVideoDataId(categoryId: string, girlId: number): number[] {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return [];
|
||||
return oneData.getAllGrilVideoDataId();
|
||||
}
|
||||
|
||||
/** 获取技师视频的资源路径 */
|
||||
public getGrilVideoPath(categoryId: string, girlId: number, id: number): string {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return "";
|
||||
return oneData.path;
|
||||
return oneData.getGrilVideoPath(id);
|
||||
}
|
||||
|
||||
/** 获取技师视频的关联情绪 */
|
||||
public getGrilVideoEmotion(categoryId: string, girlId: number, index: number): number {
|
||||
let oneData = this.getGrilVideoData(categoryId, girlId, index);
|
||||
public getGrilVideoEmotion(categoryId: string, girlId: number, id: number): number {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.emotion;
|
||||
return oneData.getGrilVideoEmotion(id);
|
||||
}
|
||||
|
||||
/** 获取技师视频的价格 */
|
||||
public getGrilVideoPrice(categoryId: string, girlId: number, index: number): number {
|
||||
let oneData = this.getGrilVideoData(categoryId, girlId, index);
|
||||
public getGrilVideoPrice(categoryId: string, girlId: number, id: number): number {
|
||||
let oneData = this.getGrilDetail(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.videoPrice;
|
||||
return oneData.getGrilVideoPrice(id);
|
||||
}
|
||||
|
||||
/** 获取技师视频是否解锁 */
|
||||
public getGrilVideoIsRelease(categoryId: string, girlId: number, index: number): boolean {
|
||||
let oneData = this.getGrilVideoData(categoryId, girlId, index);
|
||||
/** --------------------------------------------------------- 技师的解锁数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师解锁数据,一个
|
||||
private parseOneGirlUnlock(data: proto.cs.IGirlData): GirlUnlockData | null {
|
||||
if (!data) return null;
|
||||
let oneData = new GirlUnlockData();
|
||||
oneData.init?.(DataId.GirlUnlock);
|
||||
oneData.setId(data.id);
|
||||
oneData.setIsRelease(data.isRelease);
|
||||
if (data.images) {
|
||||
let ids = [];
|
||||
for (let one of data.images) {
|
||||
ids.push(one.resId);
|
||||
}
|
||||
oneData.setUnlockedImageIds(ids);
|
||||
}
|
||||
if (data.videos) {
|
||||
let ids = [];
|
||||
for (let one of data.videos) {
|
||||
ids.push(one.resId);
|
||||
}
|
||||
oneData.setUnlockedVideoIds(ids);
|
||||
}
|
||||
return oneData;
|
||||
}
|
||||
|
||||
/** 保存技师的解锁数据 */
|
||||
private setGirlUnlock(categoryId: string, data: proto.cs.IGirlData[]): void {
|
||||
if (!data) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
for (const g of data) {
|
||||
const one = this.parseOneGirlUnlock(g);
|
||||
if (!one) continue;
|
||||
bucket.unlocks.set(g.id, one);
|
||||
}
|
||||
console.log("保存技师的解锁数据: ", bucket);
|
||||
}
|
||||
|
||||
/** 取某分类 + girlId 的解锁数据 */
|
||||
private getGrilUnlock(categoryId: string, girlId: number): GirlUnlockData | null {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
if (!b) return null;
|
||||
return b.unlocks.get(girlId) ?? null;
|
||||
}
|
||||
|
||||
/** 获取 付费技师是否已经解锁 */
|
||||
public getIsRelease(categoryId: string, girlId: number): boolean {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return false;
|
||||
return oneData.isRelease;
|
||||
return oneData.getIsRelease();
|
||||
}
|
||||
|
||||
/** 判断图片是否解锁 */
|
||||
public isImageUnlock(categoryId: string, girlId: number, id: number): boolean {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return false;
|
||||
return oneData.isImageUnlock(id);
|
||||
}
|
||||
|
||||
/** 解锁图片 */
|
||||
public unlockImage(categoryId: string, girlId: number, id: number): void {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return;
|
||||
return oneData.unlockImage(id);
|
||||
}
|
||||
|
||||
/** 获取所有解锁图片的 id */
|
||||
public getUnlockedImageIds(categoryId: string, girlId: number): number[] {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return [];
|
||||
return oneData.getUnlockedImageIds();
|
||||
}
|
||||
|
||||
/** 判断视频是否解锁 */
|
||||
public isVideoUnlock(categoryId: string, girlId: number, id: number): boolean {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return false;
|
||||
return oneData.isVideoUnlock(id);
|
||||
}
|
||||
|
||||
/** 解锁视频 */
|
||||
public unlockVideo(categoryId: string, girlId: number, id: number): void {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return;
|
||||
return oneData.unlockVideo(id);
|
||||
}
|
||||
|
||||
/** 获取所有解锁视频的 id */
|
||||
public getUnlockedVideoIds(categoryId: string, girlId: number): number[] {
|
||||
let oneData = this.getGrilUnlock(categoryId, girlId);
|
||||
if (!oneData) return [];
|
||||
return oneData.getUnlockedVideoIds();
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 技师的聊天数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师聊天数据,一个
|
||||
private parseOneGirlChat(data: proto.cs.IGirlData): GirlChatData | null {
|
||||
if (!data) return null;
|
||||
let oneData = new GirlChatData();
|
||||
oneData.init?.(DataId.GirlChat);
|
||||
oneData.setChatTotalCount(data.chatTotalCount);
|
||||
oneData.setChatRemainCount(data.chatRemainCount);
|
||||
return oneData;
|
||||
}
|
||||
|
||||
/** 保存技师的聊天数据 */
|
||||
private setGirlChat(categoryId: string, data: proto.cs.IGirlData[]): void {
|
||||
if (!data) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
for (const g of data) {
|
||||
const one = this.parseOneGirlChat(g);
|
||||
if (!one) continue;
|
||||
bucket.chats.set(g.id, one);
|
||||
}
|
||||
console.log("保存技师的聊天数据: ", bucket);
|
||||
}
|
||||
|
||||
/** 取某分类 + girlId 的聊天数据 */
|
||||
private getGrilChat(categoryId: string, girlId: number): GirlChatData | null {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
if (!b) return null;
|
||||
return b.chats.get(girlId) ?? null;
|
||||
}
|
||||
|
||||
/** 获取总聊天次数 */
|
||||
public getChatTotalCount(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilChat(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getChatTotalCount();
|
||||
}
|
||||
|
||||
/** 保存总聊天次数 */
|
||||
public setChatTotalCount(categoryId: string, girlId: number, value: number): void {
|
||||
let oneData = this.getGrilChat(categoryId, girlId);
|
||||
if (!oneData) return;
|
||||
return oneData.setChatTotalCount(value);
|
||||
}
|
||||
|
||||
/** 获取剩余聊天次数 */
|
||||
public getChatRemainCount(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilChat(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getChatRemainCount();
|
||||
}
|
||||
|
||||
/** 保存剩余聊天次数 */
|
||||
public setChatRemainCount(categoryId: string, girlId: number, value: number): void {
|
||||
let oneData = this.getGrilChat(categoryId, girlId);
|
||||
if (!oneData) return;
|
||||
return oneData.setChatRemainCount(value);
|
||||
}
|
||||
|
||||
/** 更新剩余聊天次数 */
|
||||
public useChat(categoryId: string, girlId: number, times: number = 1): void {
|
||||
let oneData = this.getGrilChat(categoryId, girlId);
|
||||
if (!oneData) return;
|
||||
return oneData.useChat(times);
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 技师的好感度数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师好感度数据,一个
|
||||
private parseOneGirlFavorability(data: proto.cs.IGirlData): GirlFavorabilityData | null {
|
||||
if (!data) return null;
|
||||
let oneData = new GirlFavorabilityData();
|
||||
oneData.init?.(DataId.GirlFavorability);
|
||||
oneData.setStar(data.star);
|
||||
return oneData;
|
||||
}
|
||||
|
||||
/** 保存技师的好感度数据 */
|
||||
private setGirlFavorability(categoryId: string, data: proto.cs.IGirlData[]): void {
|
||||
if (!data) return;
|
||||
const bucket = this.ensureBucket(categoryId);
|
||||
for (const g of data) {
|
||||
const one = this.parseOneGirlFavorability(g);
|
||||
if (!one) continue;
|
||||
bucket.favorability.set(g.id, one);
|
||||
}
|
||||
console.log("保存技师的好感度数据: ", bucket);
|
||||
}
|
||||
|
||||
/** 取某分类 + girlId 的好感度数据 */
|
||||
private getGrilFavorability(categoryId: string, girlId: number): GirlFavorabilityData | null {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
if (!b) return null;
|
||||
return b.favorability.get(girlId) ?? null;
|
||||
}
|
||||
|
||||
/** 获取星级 */
|
||||
public getStar(categoryId: string, girlId: number): number {
|
||||
let oneData = this.getGrilFavorability(categoryId, girlId);
|
||||
if (!oneData) return 0;
|
||||
return oneData.getStar();
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 每日推荐 --------------------------------------------------------- */
|
||||
|
||||
/** 保存每日推荐:放入特殊分类 DAILY_BUCKET,并维护 id 索引 */
|
||||
public setDailyRecommend(res: proto.cs.ICSDailyRecommendRes): void {
|
||||
this.mergeBriefs(DAILY_BUCKET, res.girls);
|
||||
this._dailyRecommendIds = res.girls.map(g => g.id ?? 0);
|
||||
console.log("保存每日推荐: ", this._dailyRecommendIds);
|
||||
public setDailyRecommend(data: proto.cs.ICSDailyRecommendRes): void {
|
||||
if (!data) return;
|
||||
this.mergeOneBrief(DAILY_BUCKET, data.girl);
|
||||
const bucket = this.ensureBucket(DAILY_BUCKET);
|
||||
console.log("保存每日推荐: ", bucket);
|
||||
}
|
||||
|
||||
/** 获取每日推荐的简要信息 */
|
||||
private getRecommendGrilBrief(categoryId: string, index: number): proto.cs.IGirlBrief | null {
|
||||
const b = this.ensureCategories().get(categoryId);
|
||||
if (!b) return null;
|
||||
if (index < 0 || index >= b.girlIds.length) return null;
|
||||
return b.briefs.get(b.girlIds[index]) ?? null;
|
||||
/** 获取推荐id */
|
||||
public getRecommendGirlId(): number {
|
||||
const bucket = this.ensureBucket(DAILY_BUCKET);
|
||||
const girlIds = bucket.girlIds;
|
||||
const length = girlIds.length;
|
||||
if (length <= 0) return 0;
|
||||
return girlIds[length-1];
|
||||
}
|
||||
|
||||
/** 获取每日推荐的简要数据 */
|
||||
private getRecommendGrilBrief(): GirlBriefData | null {
|
||||
const recId = this.getRecommendGirlId();
|
||||
if (recId <= 0) return null;
|
||||
const data = this.getGrilBrief(DAILY_BUCKET, recId);
|
||||
return data;
|
||||
}
|
||||
|
||||
/** 获取 id */
|
||||
public getRecommendGrilId(index: number): number {
|
||||
let oneData = this.getRecommendGrilBrief(DAILY_BUCKET, index);
|
||||
if (!oneData) return 0;
|
||||
return oneData.id;
|
||||
}
|
||||
|
||||
/** 获取名字 */
|
||||
public getRecommendGrilName(index: number): string {
|
||||
let oneData = this.getRecommendGrilBrief(DAILY_BUCKET, index);
|
||||
public getRecommendGrilName(): string {
|
||||
let oneData = this.getRecommendGrilBrief();
|
||||
if (!oneData) return "";
|
||||
return oneData.name;
|
||||
return oneData.getGrilName();
|
||||
}
|
||||
|
||||
/** 获取头像 */
|
||||
public getRecommendGrilAvatar(index: number): string {
|
||||
let oneData = this.getRecommendGrilBrief(DAILY_BUCKET, index);
|
||||
/** 获取头像路径 */
|
||||
public getRecommendGrilAvatar(): string {
|
||||
let oneData = this.getRecommendGrilBrief();
|
||||
if (!oneData) return "";
|
||||
return oneData.avatar;
|
||||
return oneData.getGrilAvatar();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* 技师的详细数据
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
export class GirlDetailData extends BaseData {
|
||||
// id
|
||||
private id: number;
|
||||
// 自我介绍
|
||||
private detailDesc: string;
|
||||
// 图片数据
|
||||
private photoData: proto.cs.IPurchaseCommercialImage[];
|
||||
// 视频数据
|
||||
private videoData: proto.cs.IPurchaseCommercialVideo[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.id = 0;
|
||||
this.detailDesc = "";
|
||||
this.photoData = [];
|
||||
this.videoData = [];
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.id = 0;
|
||||
this.detailDesc = "";
|
||||
this.photoData = [];
|
||||
this.videoData = [];
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.id = 0;
|
||||
this.detailDesc = "";
|
||||
this.photoData = [];
|
||||
this.videoData = [];
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this.id = null;
|
||||
this.detailDesc = null;
|
||||
this.photoData = null;
|
||||
this.videoData = null;
|
||||
}
|
||||
|
||||
/** 保存数据 */
|
||||
public setData(data: proto.cs.IGirlsDetail): void {
|
||||
if (!data) return;
|
||||
this.id = data.id;
|
||||
this.detailDesc = data.detailDesc;
|
||||
this.photoData = this.parseAllGirlPhoto(data.commercialImages);
|
||||
this.videoData = this.parseAllGirlVideo(data.commercialVideos);
|
||||
console.log("保存了技师的详细数据,id:", this.id);
|
||||
}
|
||||
|
||||
/** 获取 id */
|
||||
public getId(): number {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/** 获取自我介绍 */
|
||||
public getGirlDesc(): string {
|
||||
return this.detailDesc;
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 图片数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师图片数据,一个
|
||||
private parseOneGirlPhoto(data: proto.cs.IPurchaseCommercialImage): proto.cs.IPurchaseCommercialImage | null {
|
||||
if (!data) return null;
|
||||
const oneData: proto.cs.IPurchaseCommercialImage = {
|
||||
id: data.id, // 图片 id
|
||||
imageType: data.imageType, // 图片类型
|
||||
unlockCounts: data.unlockCounts, // 聊天触发次数
|
||||
imagePrice: data.imagePrice, // 图片价格
|
||||
path: data.path, // 图片资源路径
|
||||
};
|
||||
return oneData;
|
||||
}
|
||||
|
||||
// 解析技师图片数据,多个
|
||||
private parseAllGirlPhoto(data: proto.cs.IPurchaseCommercialImage[]): proto.cs.IPurchaseCommercialImage[] {
|
||||
if (!data) return [];
|
||||
let allData = [];
|
||||
for (const value of data) {
|
||||
const oneData: proto.cs.IPurchaseCommercialImage = this.parseOneGirlPhoto(value);
|
||||
if (oneData) {
|
||||
allData.push(oneData);
|
||||
}
|
||||
}
|
||||
return allData;
|
||||
}
|
||||
|
||||
/** 获取所有技师图片数据的数量 */
|
||||
public getAllGrilPhotoDataCount(): number {
|
||||
if (!this.photoData) return 0;
|
||||
return this.photoData.length;
|
||||
}
|
||||
|
||||
/** 获取所有技师图片数据的id */
|
||||
public getAllGrilPhotoDataId(): number[] {
|
||||
if (!this.photoData) return [];
|
||||
// 获取所有 id
|
||||
let allId = [];
|
||||
for (let one of this.photoData) {
|
||||
allId.push(one.id);
|
||||
}
|
||||
return allId;
|
||||
}
|
||||
|
||||
/** 获取技师图片数据,通过 id */
|
||||
private getGrilPhotoData(id: number): proto.cs.IPurchaseCommercialImage | null {
|
||||
if (!this.photoData) return null;
|
||||
// 遍历数组找到匹配的资源
|
||||
for (let oneData of this.photoData) {
|
||||
if (oneData.id === id) {
|
||||
return oneData;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 获取技师图片的类型 */
|
||||
public getGrilPhotoType(id: number): number {
|
||||
let oneData = this.getGrilPhotoData(id);
|
||||
if (!oneData) return 0;
|
||||
return oneData.imageType;
|
||||
}
|
||||
|
||||
/** 获取技师图片的聊天触发次数 */
|
||||
public getGrilPhotoUnlockCounts(id: number): number {
|
||||
let oneData = this.getGrilPhotoData(id);
|
||||
if (!oneData) return 0;
|
||||
return oneData.unlockCounts;
|
||||
}
|
||||
|
||||
/** 获取技师图片的价格 */
|
||||
public getGrilPhotoPrice(id: number): number {
|
||||
let oneData = this.getGrilPhotoData(id);
|
||||
if (!oneData) return 0;
|
||||
return oneData.imagePrice;
|
||||
}
|
||||
|
||||
/** 获取技师图片的资源路径 */
|
||||
public getGrilPhotoPath(id: number): string {
|
||||
let oneData = this.getGrilPhotoData(id);
|
||||
if (!oneData) return "";
|
||||
return oneData.path;
|
||||
}
|
||||
|
||||
/** --------------------------------------------------------- 视频数据 --------------------------------------------------------- */
|
||||
|
||||
// 解析技师视频数据,一个
|
||||
private parseOneGirlVideo(data: proto.cs.IPurchaseCommercialVideo): proto.cs.IPurchaseCommercialVideo | null {
|
||||
if (!data) return null;
|
||||
const oneData: proto.cs.IPurchaseCommercialVideo = {
|
||||
id: data.id, // 视频 id
|
||||
path: data.path, // 视频资源路径
|
||||
emotion: data.emotion, // 关联情绪
|
||||
videoPrice: data.videoPrice, // 价格
|
||||
};
|
||||
return oneData;
|
||||
}
|
||||
|
||||
// 解析技师视频数据,多个
|
||||
private parseAllGirlVideo(data: proto.cs.IPurchaseCommercialVideo[]): proto.cs.IPurchaseCommercialVideo[] {
|
||||
if (!data) return [];
|
||||
let allData = [];
|
||||
for (const value of data) {
|
||||
const oneData: proto.cs.IPurchaseCommercialVideo = this.parseOneGirlVideo(value);
|
||||
if (oneData) {
|
||||
allData.push(oneData);
|
||||
}
|
||||
}
|
||||
return allData;
|
||||
}
|
||||
|
||||
/** 获取所有技师视频数据的数量 */
|
||||
public getAllGrilVideoDataCount(): number {
|
||||
if (!this.videoData) return 0;
|
||||
return this.videoData.length;
|
||||
}
|
||||
|
||||
/** 获取所有技师视频数据的id */
|
||||
public getAllGrilVideoDataId(): number[] {
|
||||
if (!this.videoData) return [];
|
||||
// 获取所有 id
|
||||
let allId = [];
|
||||
for (let one of this.videoData) {
|
||||
allId.push(one.id);
|
||||
}
|
||||
return allId;
|
||||
}
|
||||
|
||||
/** 获取技师视频数据,通过 id */
|
||||
private getGrilVideoData(id: number): proto.cs.IPurchaseCommercialVideo | null {
|
||||
if (!this.videoData) return null;
|
||||
// 遍历数组找到匹配的资源
|
||||
for (let oneData of this.videoData) {
|
||||
if (oneData.id === id) {
|
||||
return oneData;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 获取技师视频的资源路径 */
|
||||
public getGrilVideoPath(id: number): string {
|
||||
let oneData = this.getGrilVideoData(id);
|
||||
if (!oneData) return "";
|
||||
return oneData.path;
|
||||
}
|
||||
|
||||
/** 获取技师视频的关联情绪 */
|
||||
public getGrilVideoEmotion(id: number): number {
|
||||
let oneData = this.getGrilVideoData(id);
|
||||
if (!oneData) return 0;
|
||||
return oneData.emotion;
|
||||
}
|
||||
|
||||
/** 获取技师视频的价格 */
|
||||
public getGrilVideoPrice(id: number): number {
|
||||
let oneData = this.getGrilVideoData(id);
|
||||
if (!oneData) return 0;
|
||||
return oneData.videoPrice;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f10268c6-f575-4249-9175-499a07aeb2d8",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 技师的好感度数据
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
export class GirlFavorabilityData extends BaseData {
|
||||
// id
|
||||
private id: number;
|
||||
// 星级
|
||||
private star: number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.id = 0;
|
||||
this.star = 0;
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.id = 0;
|
||||
this.star = 0;
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.id = 0;
|
||||
this.star = 0;
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this.id = null;
|
||||
this.star = null;
|
||||
}
|
||||
|
||||
/** 获取 id */
|
||||
public getId(): number {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/** 保存 id */
|
||||
public setId(value: number): void {
|
||||
this.id = value;
|
||||
}
|
||||
|
||||
/** 获取星级 */
|
||||
public getStar(): number {
|
||||
return this.star;
|
||||
}
|
||||
|
||||
/** 保存星级 */
|
||||
public setStar(value: number): void {
|
||||
this.star = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "fc838010-523c-4f4a-bff4-8c83d0ce5618",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* 技师的解锁数据
|
||||
*/
|
||||
import { BaseData } from "./BaseData";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
export class GirlUnlockData extends BaseData {
|
||||
// id
|
||||
private id: number;
|
||||
// 付费技师是否已经解锁
|
||||
private isRelease: boolean;
|
||||
// 解锁图片 id
|
||||
private unlockedImageIds: number[];
|
||||
// 解锁视频 id
|
||||
private unlockedVideoIds: number[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.id = 0;
|
||||
this.isRelease = false;
|
||||
this.unlockedImageIds = [];
|
||||
this.unlockedVideoIds = [];
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.id = 0;
|
||||
this.isRelease = false;
|
||||
this.unlockedImageIds = [];
|
||||
this.unlockedVideoIds = [];
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.id = 0;
|
||||
this.isRelease = false;
|
||||
this.unlockedImageIds = [];
|
||||
this.unlockedVideoIds = [];
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this.id = null;
|
||||
this.isRelease = null;
|
||||
this.unlockedImageIds = null;
|
||||
this.unlockedVideoIds = null;
|
||||
}
|
||||
|
||||
/** 获取 id */
|
||||
public getId(): number {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/** 保存 id */
|
||||
public setId(value: number): void {
|
||||
this.id = value;
|
||||
}
|
||||
|
||||
/** 获取 付费技师是否已经解锁 */
|
||||
public getIsRelease(): boolean {
|
||||
return this.isRelease;
|
||||
}
|
||||
|
||||
/** 保存 付费技师是否已经解锁 */
|
||||
public setIsRelease(value: boolean): void {
|
||||
this.isRelease = value;
|
||||
}
|
||||
|
||||
/** 判断图片是否解锁,根据 id */
|
||||
public isImageUnlock(id: number): boolean {
|
||||
for (let i = 0; i < this.unlockedImageIds.length; i++) {
|
||||
if (this.unlockedImageIds[i] === id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 解锁图片 */
|
||||
public unlockImage(id: number) {
|
||||
// 去重
|
||||
let exists = this.isImageUnlock(id);
|
||||
if (!exists) {
|
||||
this.unlockedImageIds.push(id);
|
||||
}
|
||||
console.log("当前解锁图片的所有id:", this.unlockedImageIds);
|
||||
}
|
||||
|
||||
/** 获取所有解锁图片的 id */
|
||||
public getUnlockedImageIds(): number[] {
|
||||
return this.unlockedImageIds;
|
||||
}
|
||||
|
||||
/** 保存解锁图片 id */
|
||||
public setUnlockedImageIds(value: number[]): void {
|
||||
for(let one of value) {
|
||||
this.unlockImage(one);
|
||||
}
|
||||
}
|
||||
|
||||
/** 判断视频是否解锁,根据 id */
|
||||
public isVideoUnlock(id: number): boolean {
|
||||
for (let i = 0; i < this.unlockedVideoIds.length; i++) {
|
||||
if (this.unlockedVideoIds[i] === id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 解锁视频 */
|
||||
public unlockVideo(id: number) {
|
||||
// 去重
|
||||
let exists = this.isVideoUnlock(id);;
|
||||
if (!exists) {
|
||||
this.unlockedVideoIds.push(id);
|
||||
}
|
||||
console.log("当前解锁视频的所有id:", this.unlockedVideoIds);
|
||||
}
|
||||
|
||||
/** 获取所有解锁视频的 id */
|
||||
public getUnlockedVideoIds(): number[] {
|
||||
return this.unlockedVideoIds;
|
||||
}
|
||||
|
||||
/** 保存解锁视频 id */
|
||||
public setUnlockedVideoIds(value: number[]): void {
|
||||
for(let one of value) {
|
||||
this.unlockVideo(one);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9ae023d4-bad5-4afc-9418-34c70cc4cb08",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
|
||||
export class ThemeData extends BaseData {
|
||||
// 主题数据
|
||||
private _themes = new Map<number, proto.cs.IHallTheme>();
|
||||
private _themes = new Map<number, proto.cs.IThemes>();
|
||||
// 主题 id
|
||||
private _themeIds: number[] = [];
|
||||
|
||||
@@ -32,7 +32,7 @@ export class ThemeData extends BaseData {
|
||||
this._themes.clear();
|
||||
this._themeIds = [];
|
||||
for (const t of list) {
|
||||
const vo: proto.cs.IHallTheme = {
|
||||
const vo: proto.cs.IThemes = {
|
||||
id: t.id || 0, // 主题 id
|
||||
key: t.key || "", // 多语言键
|
||||
name: t.name || "", // 主题名称
|
||||
@@ -47,7 +47,7 @@ export class ThemeData extends BaseData {
|
||||
}
|
||||
|
||||
/** 获取所有主题数据 */
|
||||
public get themes(): Map<number, proto.cs.IHallTheme> { return this._themes; }
|
||||
public get themes(): Map<number, proto.cs.IThemes> { return this._themes; }
|
||||
|
||||
/** 获取所有主题数据的数量 */
|
||||
public get themesCount(): number { return this._themes ? this._themes.size : 0; }
|
||||
@@ -56,7 +56,7 @@ export class ThemeData extends BaseData {
|
||||
public get themeIds(): number[] { return this._themeIds; }
|
||||
|
||||
/** 根据主题 id 获取主题数据 */
|
||||
private getThemeDataById(id: number): proto.cs.IHallTheme | null {
|
||||
private getThemeDataById(id: number): proto.cs.IThemes | null {
|
||||
if (!this._themes) return null;
|
||||
return this._themes.get(id) ?? null;
|
||||
}
|
||||
|
||||
@@ -4,35 +4,35 @@
|
||||
import { BaseData } from "./BaseData";
|
||||
|
||||
export class WalletData extends BaseData {
|
||||
// 钻石数
|
||||
private _diamond = 0;
|
||||
// 余额
|
||||
private _balance = 0;
|
||||
// vip失效时间戳
|
||||
private _vipExpire = 0;
|
||||
|
||||
public reset(): void {
|
||||
this._diamond = 0;
|
||||
this._balance = 0;
|
||||
this._vipExpire = 0;
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._diamond = 0;
|
||||
this._balance = 0;
|
||||
this._vipExpire = 0;
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this._diamond = null;
|
||||
this._balance = null;
|
||||
this._vipExpire = null;
|
||||
}
|
||||
|
||||
/** 设置钻石数 */
|
||||
public set diamond(value: number) {
|
||||
this._diamond = value;
|
||||
/** 设置余额 */
|
||||
public set balance(value: number) {
|
||||
this._balance = value;
|
||||
}
|
||||
|
||||
/** 获取钻石数 */
|
||||
public get diamond(): number {
|
||||
return this._diamond;
|
||||
/** 获取余额 */
|
||||
public get balance(): number {
|
||||
return this._balance;
|
||||
}
|
||||
|
||||
/** 设置vip失效时间戳 */
|
||||
|
||||
@@ -4,10 +4,8 @@ import type { IAuthService } from "./IAuthService";
|
||||
|
||||
export class MockAuthService implements IAuthService {
|
||||
private delay(ms = 180) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
|
||||
// 项目里 ApiResponse 结构若固定(code/message 等),把 ok()/err() 调整为你的真实结构即可
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
return ({ code: proto.cs.EnmRetCode.SUCCESS, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
// private err<T = unknown>(message = "mock login error"): ApiResponse<T> {
|
||||
// return ({ ok: false, error: { message } } as unknown) as ApiResponse<T>;
|
||||
@@ -15,18 +13,29 @@ export class MockAuthService implements IAuthService {
|
||||
|
||||
// 登录
|
||||
async login(req: proto.cs.ICSLoginReq): Promise<ApiResponse<proto.cs.ICSLoginRes>> {
|
||||
// 延时
|
||||
await this.delay(150);
|
||||
|
||||
const name = req?.platType === "guest" ? `guest_${(req?.userId ?? "uid").toString().slice(-6)}` : "tester";
|
||||
// 注意:protobufjs 会把 int64 表达为 number/Long。这里用「秒」级时间戳更常见
|
||||
const isGuest = req?.platType === "guest";
|
||||
const userId = req?.userId ?? "uid";
|
||||
const name = isGuest ? `guest_${userId.toString().slice(-6)}` : "tester";
|
||||
|
||||
// 过期时间(秒级时间戳,7天后过期)
|
||||
const expireSeconds = Math.floor(Date.now() / 1000) + 7 * 24 * 3600;
|
||||
|
||||
// 你的生成器通常会把 refresh_token 转成 refreshToken(camelCase)
|
||||
// 模拟用户ID
|
||||
const accId = Math.floor(Math.random() * 1000000);
|
||||
|
||||
// 模拟 CDN 前缀
|
||||
const cdn = "https://cdn.mockserver.com/";
|
||||
|
||||
const res: proto.cs.ICSLoginRes = {
|
||||
name,
|
||||
token: `mock_token_${Date.now()}`,
|
||||
refreshToken: `mock_refresh_${Date.now()}`,
|
||||
expire: expireSeconds,
|
||||
accId,
|
||||
cdn,
|
||||
};
|
||||
|
||||
return this.ok(res);
|
||||
|
||||
@@ -15,50 +15,66 @@ export class MockGirlService implements IGirlService {
|
||||
return ({ code: 100, error: { message } } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
|
||||
private genBrief(id: number, name: string, age: number, tagKey: string, priceType: number, price: number, avatar: string, star: number, category: number, listAvatarPath: string): proto.cs.IGirlBrief {
|
||||
private genBrief(id: number, nameKey: string, age: string, category: number, tagKey: string, priceType: number, price: number, vipUnlock: number, avatarPath: string, listAvatarPath: string): proto.cs.IGirls {
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
nameKey,
|
||||
age,
|
||||
category,
|
||||
tagKey,
|
||||
priceType,
|
||||
price,
|
||||
avatar,
|
||||
star,
|
||||
category,
|
||||
vipUnlock,
|
||||
avatarPath,
|
||||
listAvatarPath,
|
||||
};
|
||||
}
|
||||
|
||||
private genPhoto(imageType: number, imagePrice: number, path: string, isRelease: boolean, ): proto.cs.IPurchaseCommercialImage {
|
||||
private genPhoto(id: number, imageType: number, unlockCounts: number, imagePrice: number, path: string): proto.cs.IPurchaseCommercialImage {
|
||||
return {
|
||||
id,
|
||||
imageType,
|
||||
unlockCounts,
|
||||
imagePrice,
|
||||
path,
|
||||
isRelease,
|
||||
};
|
||||
}
|
||||
|
||||
private genVideo(path: string, emotion: number, videoPrice: number, isRelease: boolean): proto.cs.IPurchaseCommercialVideo {
|
||||
return {
|
||||
private genVideo(id: number, path: string, emotion: number, videoPrice: number): proto.cs.IPurchaseCommercialVideo {
|
||||
return {
|
||||
id,
|
||||
path,
|
||||
emotion,
|
||||
videoPrice,
|
||||
isRelease,
|
||||
};
|
||||
}
|
||||
|
||||
private genDetail(brief: proto.cs.IGirlBrief, desc: string, images: proto.cs.IPurchaseCommercialImage[], videos: proto.cs.IPurchaseCommercialVideo[], isRelease: boolean, chatCount: number): proto.cs.IGirlDetail {
|
||||
private genDetail(id: number, detailDesc: string, commercialImages: proto.cs.IPurchaseCommercialImage[], commercialVideos: proto.cs.IPurchaseCommercialVideo[]): proto.cs.IGirlsDetail {
|
||||
return {
|
||||
brief,
|
||||
desc,
|
||||
images,
|
||||
videos,
|
||||
isRelease,
|
||||
chatCount,
|
||||
id,
|
||||
detailDesc,
|
||||
commercialImages,
|
||||
commercialVideos,
|
||||
};
|
||||
}
|
||||
|
||||
private genGirlData(
|
||||
id: number, girl: proto.cs.IGirls, isRelease: boolean, star: number,
|
||||
detail: proto.cs.IGirlsDetail, images: proto.cs.IResourceUnlock[], videos: proto.cs.IResourceUnlock[],
|
||||
chatTotalCount: number, chatRemainCount: number): proto.cs.IGirlData {
|
||||
return {
|
||||
id,
|
||||
girl,
|
||||
isRelease,
|
||||
star,
|
||||
detail,
|
||||
images,
|
||||
videos,
|
||||
chatTotalCount,
|
||||
chatRemainCount,
|
||||
};
|
||||
}
|
||||
|
||||
// 每日推荐
|
||||
async reqDailyRecommend(_req: proto.cs.ICSDailyRecommendReq): Promise<ApiResponse<proto.cs.ICSDailyRecommendRes>> {
|
||||
// 延时
|
||||
@@ -67,19 +83,19 @@ export class MockGirlService implements IGirlService {
|
||||
const configData = ConfigManager.I.getDataById<GirlConfig>(ConfigId.Girl);
|
||||
const allId = configData.getAllId();
|
||||
const recId = allId[0];
|
||||
let name = configData.getNameById(recId);
|
||||
let age = Number(configData.getAgeById(recId));
|
||||
let nameKey = configData.getNameById(recId);
|
||||
let age = configData.getAgeById(recId);
|
||||
let tagKey = configData.getTagKeyById(recId);
|
||||
let priceType = configData.getPriceTypeById(recId);
|
||||
let price = 9.9;
|
||||
let avatar = configData.getAvatarPathById(recId);
|
||||
let star = 3;
|
||||
let price = configData.getPriceById(recId);
|
||||
let vipUnlock = configData.getVipUnlockById(recId);
|
||||
let avatarPath = configData.getAvatarPathById(recId);
|
||||
let category = configData.getCategoryById(recId);
|
||||
let listAvatarPath = configData.getListAvatarPathPathById(recId);
|
||||
let oneData = this.genBrief(recId, name, age, tagKey, priceType, price, avatar, star, category, listAvatarPath);
|
||||
let oneData = this.genBrief(recId, nameKey, age, category, tagKey, priceType, price, vipUnlock, avatarPath, listAvatarPath);
|
||||
// 返回数据
|
||||
const girls = [oneData];
|
||||
return this.ok({ girls });
|
||||
const res: proto.cs.ICSDailyRecommendRes = {girl: oneData};
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
// 获取技师列表
|
||||
@@ -105,29 +121,35 @@ export class MockGirlService implements IGirlService {
|
||||
const start = (page - 1) * limit;
|
||||
const pageIds = filteredIds.slice(start, start + limit);
|
||||
|
||||
// 映射为 IGirlBrief
|
||||
const girls: proto.cs.IGirlBrief[] = pageIds.map((id: number) => {
|
||||
const name = configData.getNameById(id);
|
||||
const age = Number(configData.getAgeById(id));
|
||||
// 映射数据
|
||||
const girls: proto.cs.IGirlData[] = pageIds.map((id: number) => {
|
||||
// 简要数据
|
||||
const nameKey = configData.getNameById(id);
|
||||
const age = configData.getAgeById(id);
|
||||
const tagKey = configData.getTagKeyById(id);
|
||||
const priceType = Number(configData.getPriceTypeById(id));
|
||||
const avatar = configData.getAvatarPathById(id);
|
||||
|
||||
// 如果有价格配置,就用配置里的,否则给个兜底值
|
||||
const price = typeof (configData as any).getPriceById === "function"
|
||||
? Number((configData as any).getPriceById(id) ?? 9.9)
|
||||
: 9.9;
|
||||
|
||||
// 星级兜底:1~5
|
||||
const star = (id % 5) + 1;
|
||||
|
||||
const priceType = configData.getPriceTypeById(id);
|
||||
const price = configData.getPriceById(id);
|
||||
const vipUnlock = configData.getVipUnlockById(id);
|
||||
const avatarPath = configData.getAvatarPathById(id);
|
||||
const category = configData.getCategoryById(id);
|
||||
const listAvatarPath = configData.getListAvatarPathPathById(id);
|
||||
|
||||
return this.genBrief(id, name, age, tagKey, priceType, price, avatar, star, category, listAvatarPath);
|
||||
const listAvatarPath = configData.getListAvatarPathPathById(id);
|
||||
const briefData = this.genBrief(id, nameKey, age, category, tagKey, priceType, price, vipUnlock, avatarPath, listAvatarPath);
|
||||
|
||||
const isRelease = true;
|
||||
const star = 3;
|
||||
// 详细数据
|
||||
const detail = null;
|
||||
const images = [];
|
||||
const videos = [];
|
||||
const chatTotalCount = 0;
|
||||
const chatRemainCount = 0;
|
||||
const girlData = this.genGirlData(id, briefData, isRelease, star, detail, images, videos, chatTotalCount, chatRemainCount);
|
||||
|
||||
return girlData;
|
||||
});
|
||||
// 返回数据
|
||||
return this.ok({ girls });
|
||||
const res: proto.cs.ICSGetGirlListRes = {girls};
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
// 获取技师详细信息
|
||||
@@ -140,45 +162,76 @@ export class MockGirlService implements IGirlService {
|
||||
// id
|
||||
const girlId = req.id;
|
||||
// 简要数据
|
||||
let name = girlConfig.getNameById(girlId);
|
||||
let age = Number(girlConfig.getAgeById(girlId));
|
||||
let nameKey = girlConfig.getNameById(girlId);
|
||||
let age = girlConfig.getAgeById(girlId);
|
||||
let tagKey = girlConfig.getTagKeyById(girlId);
|
||||
let priceType = girlConfig.getPriceTypeById(girlId);
|
||||
let price = 9.9;
|
||||
let avatar = girlConfig.getAvatarPathById(girlId);
|
||||
let star = 3;
|
||||
let price = girlConfig.getPriceById(girlId);
|
||||
let vipUnlock = girlConfig.getVipUnlockById(girlId);
|
||||
let avatarPath = girlConfig.getAvatarPathById(girlId);
|
||||
let category = girlConfig.getCategoryById(girlId);
|
||||
let listAvatarPath = girlConfig.getListAvatarPathPathById(girlId);
|
||||
let briefData = this.genBrief(girlId, name, age, tagKey, priceType, price, avatar, star, category, listAvatarPath);
|
||||
let briefData = this.genBrief(girlId, nameKey, age, category, tagKey, priceType, price, vipUnlock, avatarPath, listAvatarPath);
|
||||
|
||||
let desc = girlDetailConfig.getDetailDescById(girlId);
|
||||
let isRelease = Math.random() < 0.4;
|
||||
let chatCount = 10;
|
||||
let detailDesc = girlDetailConfig.getDetailDescById(girlId);
|
||||
// 图片
|
||||
let photoData = [];
|
||||
let photoCount = girlDetailConfig.getCommercialImagesCount(girlId);
|
||||
for (let i = 0; i < photoCount; i++) {
|
||||
let imageType = girlDetailConfig.getImageTypeById(girlId, i);
|
||||
let imagePath = girlDetailConfig.getImagePathById(girlId, i);
|
||||
let isRelease = Math.random() < 0.4;
|
||||
let imagePrice = girlDetailConfig.getImagePriceById(girlId, i);
|
||||
let oneData = this.genPhoto(imageType, imagePrice, imagePath, isRelease);
|
||||
let photoIds = girlDetailConfig.getCommercialImagesIds(girlId);
|
||||
for (let id of photoIds) {
|
||||
let imageType = girlDetailConfig.getImageTypeById(girlId, id);
|
||||
let unlockCounts = girlDetailConfig.getImageUnlockCountsById(girlId, id);
|
||||
let imagePrice = girlDetailConfig.getImagePriceById(girlId, id);
|
||||
let imagePath = girlDetailConfig.getImagePathById(girlId, id);
|
||||
let oneData = this.genPhoto(id, imageType, unlockCounts, imagePrice, imagePath);
|
||||
photoData.push(oneData);
|
||||
}
|
||||
// 视频
|
||||
let videoData = [];
|
||||
let videoCount = girlDetailConfig.getCommercialVideosCount(girlId);
|
||||
for (let i = 0; i < videoCount; i++) {
|
||||
let videoPath = girlDetailConfig.getVideoPathById(girlId, i);
|
||||
let videoEmotion = girlDetailConfig.getVideoEmotionById(girlId, i);
|
||||
let videoPrice = girlDetailConfig.getVideoPriceById(girlId, i);
|
||||
let isRelease = Math.random() < 0.4;
|
||||
let oneData = this.genVideo(videoPath, videoEmotion, videoPrice, isRelease);
|
||||
let videoIds = girlDetailConfig.getCommercialVideosIds(girlId);
|
||||
for (let id of videoIds) {
|
||||
let videoPath = girlDetailConfig.getVideoPathById(girlId, id);
|
||||
let videoEmotion = girlDetailConfig.getVideoEmotionById(girlId, id);
|
||||
let videoPrice = girlDetailConfig.getVideoPriceById(girlId, id);
|
||||
let oneData = this.genVideo(id, videoPath, videoEmotion, videoPrice);
|
||||
videoData.push(oneData);
|
||||
}
|
||||
// 详细数据
|
||||
let detail = this.genDetail(briefData, desc, photoData, videoData, isRelease, chatCount);
|
||||
let detail = this.genDetail(girlId, detailDesc, photoData, videoData);
|
||||
// 图片解锁数据
|
||||
let unlockImageData: proto.cs.IResourceUnlock[] = [];
|
||||
for (let id of photoIds) {
|
||||
// 偶数才解锁
|
||||
let isUnlock = (id % 2 === 0);
|
||||
if (isUnlock) {
|
||||
let oneData = {
|
||||
girlId: girlId,
|
||||
resId: id,
|
||||
};
|
||||
unlockImageData.push(oneData);
|
||||
}
|
||||
}
|
||||
// 视频解锁数据
|
||||
let unlockVideoData: proto.cs.IResourceUnlock[] = [];
|
||||
for (let id of videoIds) {
|
||||
// 偶数才解锁
|
||||
let isUnlock = (id % 2 === 0);
|
||||
if (isUnlock) {
|
||||
let oneData = {
|
||||
girlId: girlId,
|
||||
resId: id,
|
||||
};
|
||||
unlockVideoData.push(oneData);
|
||||
}
|
||||
}
|
||||
|
||||
const star = 3;
|
||||
const chatTotalCount = 10;
|
||||
const chatRemainCount = 10;
|
||||
|
||||
const girlData = this.genGirlData(girlId, briefData, isRelease, star, detail, unlockImageData, unlockVideoData, chatTotalCount, chatRemainCount);
|
||||
// 返回数据
|
||||
return this.ok({ detail });
|
||||
const res: proto.cs.ICSGetGirlDetailRes = {girl: girlData};
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,26 +3,26 @@ import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IPlayerDataService } from "./IPlayerDataService";
|
||||
|
||||
export class MockPlayerDataService implements IPlayerDataService {
|
||||
private delay(ms = 160) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
private delay(ms = 160) {
|
||||
return new Promise<void>(r => setTimeout(r, ms));
|
||||
}
|
||||
|
||||
// 按你项目的 ApiResponse 真实结构调整这里
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
return ({ code: proto.cs.EnmRetCode.SUCCESS, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
// 如需模拟失败
|
||||
// private err<T = unknown>(message = "mock myInfo error"): ApiResponse<T> {
|
||||
// return ({ ok: false, error: { message } } as unknown) as ApiResponse<T>;
|
||||
// }
|
||||
|
||||
// 获取个人信息
|
||||
async reqMyInfo(_req: proto.cs.ICSMyInfoReq): Promise<ApiResponse<proto.cs.ICSMyInfoRes>> {
|
||||
// 延时
|
||||
await this.delay();
|
||||
|
||||
// 由于我们并不知道 ICSMyInfoRes 的具体字段,这里提供一个“最安全”的空对象返回;
|
||||
// 如果你有明确字段(例如 name/diamond/vipExpire 等),可在此构造并 as-cast:
|
||||
// const res = { name: "Player-001", diamond: 123, vipExpire: Math.floor(Date.now()/1000) } as unknown as proto.cs.ICSMyInfoRes;
|
||||
const nowSeconds = Math.floor(Date.now() / 1000);
|
||||
|
||||
const res = ({} as unknown) as proto.cs.ICSMyInfoRes;
|
||||
const res: proto.cs.ICSMyInfoRes = {
|
||||
balance: Math.floor(Math.random() * 100000), // 随机余额
|
||||
vipExpire: nowSeconds + 30 * 24 * 3600, // vip 30天后过期
|
||||
};
|
||||
// 返回数据
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export class MockThemeService implements IThemeService {
|
||||
return ({ code: proto.cs.EnmRetCode.SUCCESS, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
|
||||
private makeTheme(id: number, key: string, name: string, category: number, isRelease: boolean, path: string): proto.cs.IHallTheme {
|
||||
private makeTheme(id: number, key: string, name: string, category: number, isRelease: boolean, path: string): proto.cs.IThemes {
|
||||
return {
|
||||
id,
|
||||
key,
|
||||
@@ -28,7 +28,7 @@ export class MockThemeService implements IThemeService {
|
||||
|
||||
const configData = ConfigManager.I.getDataById<ThemeConfig>(ConfigId.Theme);
|
||||
const allId = configData.getAllId();
|
||||
let themes: proto.cs.IHallTheme[] = [];
|
||||
let themes: proto.cs.IThemes[] = [];
|
||||
for (let oneId of allId) {
|
||||
let key = configData.getLanKeyById(oneId);
|
||||
let name = configData.getNameById(oneId);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { HttpPlayerDataService } from "./HttpPlayerDataService";
|
||||
import { MockPlayerDataService } from "./MockPlayerDataService";
|
||||
|
||||
// 模拟开关
|
||||
const USE_MOCK = true;
|
||||
const USE_MOCK = false;
|
||||
|
||||
export class PlayerDataService implements IPlayerDataService {
|
||||
private static _I: PlayerDataService | null = null;
|
||||
|
||||
@@ -145,7 +145,7 @@ export class GirlDetailPanel extends li_BaseView {
|
||||
let res = await GirlService.I.reqGetGirlDetail(reqData);
|
||||
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
|
||||
// 保存数据
|
||||
girlData.setGirlDetails(this.category.toString(), res.data);
|
||||
girlData.setGirlDetailData(this.category.toString(), res.data);
|
||||
// 根据数据,刷新界面
|
||||
this.nameKey = girlData.getGrilName(this.category.toString(), this.id);
|
||||
this.girlName.string = LanguageUtils.getText(this.nameKey);
|
||||
@@ -173,39 +173,41 @@ export class GirlDetailPanel extends li_BaseView {
|
||||
"Chat18x"
|
||||
);
|
||||
|
||||
let allPhotoDataCount = girlData.getAllGrilPhotoDataCount(this.category.toString(), this.id);
|
||||
let resIds = girlData.getAllGrilPhotoDataId(this.category.toString(), this.id);
|
||||
// 也立即尝试调整(以防已经加载完成)
|
||||
this.adjustVideoScale();
|
||||
this.refreshImgs(1, this.category, this.id, allPhotoDataCount);
|
||||
this.refreshImgs(1, this.category, this.id, resIds);
|
||||
}
|
||||
}
|
||||
|
||||
bindImgToggle() {
|
||||
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||
let allPhotoDataCount = girlData.getAllGrilPhotoDataCount(this.category.toString(), this.id);
|
||||
this.refreshImgs(1, this.category, this.id, allPhotoDataCount);
|
||||
let resIds = girlData.getAllGrilPhotoDataId(this.category.toString(), this.id);
|
||||
this.refreshImgs(1, this.category, this.id, resIds);
|
||||
}
|
||||
|
||||
bindVideoToggle() {
|
||||
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||
let allVideoDataCount = girlData.getAllGrilVideoDataCount(this.category.toString(), this.id);
|
||||
this.refreshImgs(2, this.category, this.id, allVideoDataCount);
|
||||
let resIds = girlData.getAllGrilVideoDataId(this.category.toString(), this.id);
|
||||
this.refreshImgs(2, this.category, this.id, resIds);
|
||||
}
|
||||
|
||||
refreshImgs(
|
||||
type: number,
|
||||
category: number,
|
||||
id: number,
|
||||
count: number
|
||||
resIds: number[]
|
||||
) {
|
||||
for (let i = this.imgsLayout.children.length - 1; i >= 0; i--) {
|
||||
this.imgsLayout.children[i].destroy();
|
||||
}
|
||||
|
||||
let count = resIds.length;
|
||||
for (let i = 0; i < count; i++) {
|
||||
let newNode = instantiate(this.imgItemInst.node);
|
||||
let item = newNode.getComponent(DetailImageItem);
|
||||
item.refresh(this, type, category, id, i);
|
||||
let resId = resIds[i];
|
||||
item.refresh(this, type, category, id, resId);
|
||||
newNode.active = true;
|
||||
this.imgsLayout.addChild(newNode);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ export class GirlListPanel extends li_BaseView {
|
||||
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
|
||||
// 保存数据
|
||||
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||
girlData.setGirlBriefs(category.toString(), res.data);
|
||||
girlData.setGirlList(category.toString(), res.data);
|
||||
// 根据数据,刷新界面
|
||||
const allId = girlData.getGirlIds(category.toString());
|
||||
for (let id of allId) {
|
||||
|
||||
@@ -95,9 +95,9 @@ export class ThemePanel extends li_BaseView {
|
||||
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||
girlData.setDailyRecommend(res2.data);
|
||||
// 根据数据,刷新界面
|
||||
this.recId = girlData.getRecommendGrilId(0);
|
||||
this.rectNameKey = girlData.getRecommendGrilName(0);
|
||||
let avatarPath = girlData.getRecommendGrilAvatar(0);
|
||||
this.recId = girlData.getRecommendGirlId();
|
||||
this.rectNameKey = girlData.getRecommendGrilName();
|
||||
let avatarPath = girlData.getRecommendGrilAvatar();
|
||||
//this.recName.string = LanguageUtils.getText(this.rectNameKey);
|
||||
ResManager.I.changeBundleSpriteFrame(
|
||||
this.recSprite,
|
||||
|
||||
@@ -26,7 +26,7 @@ export class DetailImageItem extends Component {
|
||||
uitransform: UITransform;
|
||||
category: number;
|
||||
id: number;
|
||||
index: number;
|
||||
resId: number;
|
||||
type : number;
|
||||
|
||||
onLoad() {
|
||||
@@ -92,13 +92,13 @@ export class DetailImageItem extends Component {
|
||||
type: number,
|
||||
category: number,
|
||||
id: number,
|
||||
index: number
|
||||
resId: number
|
||||
) {
|
||||
this.base = base;
|
||||
this.type = type;
|
||||
this.category = category;
|
||||
this.id = id;
|
||||
this.index = index;
|
||||
this.resId = resId;
|
||||
this.lock.active = false;
|
||||
this.question.active = true; // 显示问号,表示加载中
|
||||
|
||||
@@ -106,14 +106,14 @@ export class DetailImageItem extends Component {
|
||||
let imgPath = "";
|
||||
if (type === 1) {
|
||||
// 图片
|
||||
this.url = girlData.getGrilPhotoPic(this.category.toString(), this.id, this.index);
|
||||
this.url = girlData.getGrilPhotoPic(this.category.toString(), this.id, this.resId);
|
||||
imgPath = this.url;
|
||||
this.isImage = true;
|
||||
} else if (type === 2) {
|
||||
// 视频
|
||||
this.isImage = false;
|
||||
this.url = girlData.getGrilVideoPath(this.category.toString(), this.id, this.index);
|
||||
let videoPrice = girlData.getGrilVideoPrice(this.category.toString(), this.id, this.index);
|
||||
this.url = girlData.getGrilVideoPath(this.category.toString(), this.id, this.resId);
|
||||
let videoPrice = girlData.getGrilVideoPrice(this.category.toString(), this.id, this.resId);
|
||||
if (videoPrice > 0) {
|
||||
imgPath = this.url + "_thumbnail_blur";
|
||||
} else {
|
||||
|
||||
Vendored
+3222
-1015
File diff suppressed because it is too large
Load Diff
+7994
-2605
File diff suppressed because it is too large
Load Diff
@@ -15,29 +15,29 @@ export enum Category {
|
||||
/**
|
||||
* 熟女
|
||||
*/
|
||||
shunv = 0,
|
||||
mature = 0,
|
||||
/**
|
||||
* 20s
|
||||
* 18s
|
||||
*/
|
||||
twenty = 1,
|
||||
eighteen = 1,
|
||||
/**
|
||||
* 辣妈
|
||||
* qinfan
|
||||
*/
|
||||
lama = 2,
|
||||
qinfan = 2,
|
||||
/**
|
||||
* 捆绑
|
||||
* luanlun
|
||||
*/
|
||||
kunbang = 3,
|
||||
luanlun = 3,
|
||||
/**
|
||||
* 公众野战
|
||||
* bdsm
|
||||
*/
|
||||
publicfight = 4,
|
||||
bdsm = 4,
|
||||
/**
|
||||
* 卡通
|
||||
* loli
|
||||
*/
|
||||
cartoon = 5,
|
||||
loli = 5,
|
||||
/**
|
||||
* 未完成
|
||||
* upcomming
|
||||
*/
|
||||
upcomming = 6,
|
||||
}
|
||||
@@ -92,7 +92,7 @@ export class AiCharacters {
|
||||
*/
|
||||
readonly basePrompt: string
|
||||
/**
|
||||
* 额外信息prompt(聊天&评分都需要)
|
||||
* 额外信息prompt(聊天需要)
|
||||
*/
|
||||
readonly additionPrompt: string
|
||||
|
||||
@@ -199,11 +199,11 @@ export class GirlsDetail {
|
||||
*/
|
||||
readonly detailDesc: string
|
||||
/**
|
||||
* 类型
|
||||
* 资源ID
|
||||
*/
|
||||
readonly commercialImages: purchase.CommercialImage[]
|
||||
/**
|
||||
* 视频资源列表
|
||||
* 资源ID
|
||||
*/
|
||||
readonly commercialVideos: purchase.CommercialVideo[]
|
||||
|
||||
@@ -229,10 +229,11 @@ export class GlobalConfig {
|
||||
this.MaxTokens = _buf_.readInt()
|
||||
this.Timeout = _buf_.readInt()
|
||||
this.FreeChatTimes = _buf_.readInt()
|
||||
this.OnceChatAddScore = _buf_.readInt()
|
||||
this.ScoreExchangeStarLevel = _buf_.readInt()
|
||||
this.GameName = _buf_.readString()
|
||||
this.EmotionRating = _buf_.readString()
|
||||
this.girlBasePrompt = _buf_.readString()
|
||||
this.dailyRecommendGirl = _buf_.readInt()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,6 +261,14 @@ export class GlobalConfig {
|
||||
* 单个角色免费聊天次数
|
||||
*/
|
||||
readonly FreeChatTimes: number
|
||||
/**
|
||||
* 单次对话增长好感度
|
||||
*/
|
||||
readonly OnceChatAddScore: number
|
||||
/**
|
||||
* 好感度等级兑换比例
|
||||
*/
|
||||
readonly ScoreExchangeStarLevel: number
|
||||
/**
|
||||
* 游戏名
|
||||
*/
|
||||
@@ -272,10 +281,6 @@ export class GlobalConfig {
|
||||
* ai机器人基础规则
|
||||
*/
|
||||
readonly girlBasePrompt: string
|
||||
/**
|
||||
* 每日推荐技师ID,参见:girls.id
|
||||
*/
|
||||
readonly dailyRecommendGirl: number
|
||||
|
||||
resolve(tables:Tables) {
|
||||
|
||||
@@ -289,6 +294,7 @@ export class GlobalConfig {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,15 +349,25 @@ export namespace purchase {
|
||||
export class CommercialImage {
|
||||
|
||||
constructor(_buf_: ByteBuf) {
|
||||
this.id = _buf_.readInt()
|
||||
this.imageType = _buf_.readInt()
|
||||
this.imagePrice = _buf_.readFloat()
|
||||
this.unlockCounts = _buf_.readInt()
|
||||
this.imagePrice = _buf_.readInt()
|
||||
this.path = _buf_.readString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片资源ID
|
||||
*/
|
||||
readonly id: number
|
||||
/**
|
||||
* 1=详情页展示<br/>2=聊天触发
|
||||
*/
|
||||
readonly imageType: number
|
||||
/**
|
||||
* 聊天触发次数
|
||||
*/
|
||||
readonly unlockCounts: number
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
@@ -365,6 +381,8 @@ export class CommercialImage {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,11 +393,16 @@ export namespace purchase {
|
||||
export class CommercialVideo {
|
||||
|
||||
constructor(_buf_: ByteBuf) {
|
||||
this.id = _buf_.readInt()
|
||||
this.path = _buf_.readString()
|
||||
this.emotion = _buf_.readInt()
|
||||
this.videoPrice = _buf_.readFloat()
|
||||
this.videoPrice = _buf_.readInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频资源ID
|
||||
*/
|
||||
readonly id: number
|
||||
/**
|
||||
* 资源路径
|
||||
*/
|
||||
@@ -397,6 +420,7 @@ export class CommercialVideo {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,8 +433,8 @@ export class PurchaseConfig {
|
||||
constructor(_buf_: ByteBuf) {
|
||||
this.id = _buf_.readInt()
|
||||
this.name = _buf_.readString()
|
||||
this.desc = _buf_.readString()
|
||||
this.count = _buf_.readInt()
|
||||
this.price = _buf_.readInt()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,11 +448,11 @@ export class PurchaseConfig {
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
readonly desc: string
|
||||
/**
|
||||
* 计费点ID
|
||||
*/
|
||||
readonly count: number
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
readonly price: number
|
||||
|
||||
resolve(tables:Tables) {
|
||||
|
||||
@@ -762,6 +786,14 @@ export class TbGlobalConfig {
|
||||
* 单个角色免费聊天次数
|
||||
*/
|
||||
get FreeChatTimes(): number { return this._data.FreeChatTimes; }
|
||||
/**
|
||||
* 单次对话增长好感度
|
||||
*/
|
||||
get OnceChatAddScore(): number { return this._data.OnceChatAddScore; }
|
||||
/**
|
||||
* 好感度等级兑换比例
|
||||
*/
|
||||
get ScoreExchangeStarLevel(): number { return this._data.ScoreExchangeStarLevel; }
|
||||
/**
|
||||
* 游戏名
|
||||
*/
|
||||
@@ -774,10 +806,6 @@ export class TbGlobalConfig {
|
||||
* ai机器人基础规则
|
||||
*/
|
||||
get girlBasePrompt(): string { return this._data.girlBasePrompt; }
|
||||
/**
|
||||
* 每日推荐技师ID,参见:girls.id
|
||||
*/
|
||||
get dailyRecommendGirl(): number { return this._data.dailyRecommendGirl; }
|
||||
|
||||
resolve(tables:Tables) {
|
||||
this._data.resolve(tables)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1,2 @@
|
||||
ƒιι’»η�³11000ΟF)ƒκι’»η�³23000ΟF*ƒλι’»η�³35000ΟF+ƒμι’»η�³410000ΟF,ƒνι’»η�³520000ΟF-ƒξι’»η�³630000ΟF.‡Ρ η‰Ήζ�ƒε�΅168ΟJ
|
||||
ƒé␍充值挡ä½�1ƒçƒçƒê␍充值挡ä½�2§§ƒë␍充值挡ä½�3ÀNÀNƒì␍充值挡ä½�4Àu/Àu/ƒí␍充值挡ä½�5ÁoÁoƒî␍充值挡ä½�6Á†ŸÁ†Ÿ‡Ñ
|
||||
7天会员€¨ƒç‡Ò30天会员‚Їϋ¹å¢žåŠ è�Šå¤©æ¬¡æ•°€Ç
|
||||
Binary file not shown.
+1
-1
Submodule proto_cs updated: f055100cf0...9a53ebc7f9
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"__version__": "3.0.7",
|
||||
"game": {
|
||||
"name": "UNKNOW GAME",
|
||||
"name": "未知游戏",
|
||||
"app_id": "UNKNOW",
|
||||
"c_id": "0"
|
||||
},
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
"customSplash": {
|
||||
"id": "customSplash",
|
||||
"label": "customSplash",
|
||||
"enable": false,
|
||||
"enable": true,
|
||||
"customSplash": {
|
||||
"complete": false,
|
||||
"form": "https://creator-api.cocos.com/api/form/show?"
|
||||
"complete": true,
|
||||
"form": "https://creator-api.cocos.com/api/form/show?sid=800ccf353f6eb54dc483510ce462e944"
|
||||
}
|
||||
},
|
||||
"removeSplash": {
|
||||
"id": "removeSplash",
|
||||
"label": "removeSplash",
|
||||
"enable": false,
|
||||
"enable": true,
|
||||
"removeSplash": {
|
||||
"complete": false,
|
||||
"form": "https://creator-api.cocos.com/api/form/show?"
|
||||
"complete": true,
|
||||
"form": "https://creator-api.cocos.com/api/form/show?sid=800ccf353f6eb54dc483510ce462e944"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
Submodule xchat_cfg updated: f0e8993d1e...151531a5c7
Reference in New Issue
Block a user