282 lines
12 KiB
TypeScript
282 lines
12 KiB
TypeScript
import xlsx from 'node-xlsx'
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { Utils } from './Utils';
|
|
|
|
|
|
const ROOM_COUNT = 7;
|
|
export type SubpackageConfig = {
|
|
key: string,
|
|
name: string,
|
|
des: string,
|
|
uuids: string[],
|
|
}
|
|
|
|
|
|
|
|
type RoomFishData = { [filePath: string]: { [roomType: number]: boolean } };
|
|
type SubpackageInfoData = { [name: string]: { key: string, name: string, des: string; } };
|
|
type SubpackageContentDataItem = { path: string, type: number }[]
|
|
type SubpackageContentData = { [name: string]: SubpackageContentDataItem };
|
|
export class Config {
|
|
|
|
private readonly assetsDir: string;
|
|
private readonly uuidMap: { db: string, uuid: string, dest: string }[];
|
|
private readonly gameConfig: any;
|
|
private readonly packageMap: { [name: string]: string[] };
|
|
private readonly subpackageInfoData: SubpackageInfoData;
|
|
private readonly subpackageContentData: SubpackageContentData;
|
|
|
|
private subpackageConfigs: SubpackageConfig[];
|
|
|
|
constructor(projectDir: string, xlsxPath: string, xxtea?: string) {
|
|
this.assetsDir = path.join(projectDir, 'assets');
|
|
|
|
const buildJson = fs.readFileSync(path.join(projectDir, 'build', 'build.json'));
|
|
const buildData = JSON.parse(buildJson.toString());
|
|
this.uuidMap = buildData.uuid;
|
|
|
|
const gameConfigPath = path.join(this.assetsDir, 'resources', 'conf', 'allConf.json');
|
|
const gameConfigContent = fs.readFileSync(gameConfigPath);
|
|
this.gameConfig = JSON.parse(gameConfigContent.toString());
|
|
|
|
this.packageMap = {}
|
|
for (let db in buildData.pac) {
|
|
const url: string = buildData.pac[db];
|
|
const name = url.substring(url.lastIndexOf('\\') + 1, url.lastIndexOf('.'));
|
|
this.packageMap[name] = this.packageMap[name] || [];
|
|
this.packageMap[name].push(db);
|
|
}
|
|
|
|
this.subpackageContentData = {};
|
|
const data = xlsx.parse(xlsxPath);
|
|
for (const item of data) {
|
|
switch (item.name) {
|
|
case 'Subpackage':
|
|
this.subpackageInfoData = this.decodeSubpackageInfoData(item.data as string[][]);
|
|
break;
|
|
default:
|
|
this.subpackageContentData[item.name] = this.initializeSubpackageData(item.data as string[][]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private dataArrayToObjectArray(data: any[][]): any[] {
|
|
const title: string[] = data.shift()!;
|
|
const objArray: { [title: string]: string }[] = [];
|
|
for (const dataItem of data) {
|
|
const dataObj: { [title: string]: string } = {}
|
|
for (let i = 0, length = title.length; i < length; i++) {
|
|
const key: string = title[i];
|
|
if (!key) break;
|
|
dataObj[key] = dataItem[i];
|
|
}
|
|
objArray.push(dataObj);
|
|
}
|
|
return objArray;
|
|
}
|
|
|
|
private decodeSubpackageInfoData(data: string[][]): SubpackageInfoData {
|
|
const subpackageInfoData: SubpackageInfoData = {}
|
|
data.splice(1, 1);//排除说明行
|
|
const objArray = this.dataArrayToObjectArray(data);
|
|
for (const obj of objArray) {
|
|
obj.name && (subpackageInfoData[obj.key] = { key: obj.key, name: obj.name, des: obj.des });
|
|
}
|
|
return subpackageInfoData;
|
|
}
|
|
|
|
private initializeSubpackageData(data: string[][]): SubpackageContentDataItem {
|
|
const files: SubpackageContentDataItem = [];
|
|
data.splice(1, 1);//排除说明行
|
|
const objArray = this.dataArrayToObjectArray(data);
|
|
for (const obj of objArray) {
|
|
const path: string = obj.path;
|
|
const type: number = parseInt(obj.type);
|
|
files.push({ path, type });
|
|
}
|
|
return files;
|
|
}
|
|
|
|
private getUUIDsInPath(filePath: string, uuids?: { db: string, uuid: string }[]): { db: string, uuid: string }[] {
|
|
uuids = uuids || [];
|
|
this.uuidMap.forEach(value => {
|
|
const db = value.db.substring(12);//"db://assets/".length
|
|
if (!db.startsWith(filePath)) return;
|
|
if (uuids.findIndex(item => item.uuid === value.uuid) >= 0) return;
|
|
uuids.push(value);
|
|
});
|
|
return uuids;
|
|
}
|
|
|
|
private getUUIDsByRegExp(regExp: RegExp, uuids?: { db: string, uuid: string }[]): { db: string, uuid: string }[] {
|
|
uuids = uuids || [];
|
|
this.uuidMap.forEach(value => {
|
|
const db = value.db.substring(12);//"db://assets/".length
|
|
if (!regExp.test(db)) return;
|
|
if (uuids.findIndex(item => item.uuid === value.uuid) >= 0) return;
|
|
uuids.push(value);
|
|
});
|
|
return uuids;
|
|
}
|
|
|
|
private updatePackageAssets(uuids?: { db: string, uuid: string }[]): { db: string, uuid: string }[] {
|
|
for (const fileName in this.packageMap) {
|
|
const packageDBs = this.packageMap[fileName];
|
|
let match = true;
|
|
const removedUUIDs: { db: string, uuid: string }[] = [];
|
|
for (const packageDB of packageDBs) {
|
|
const index = uuids.findIndex(value => value.db === packageDB);
|
|
match = index >= 0;
|
|
if (match) {
|
|
removedUUIDs.push(...uuids.splice(index, 1));
|
|
} else {
|
|
uuids.push(...removedUUIDs);
|
|
match = false;
|
|
break;
|
|
}
|
|
}
|
|
match && uuids.push({ db: null, uuid: fileName });
|
|
}
|
|
return uuids;
|
|
}
|
|
|
|
//通过鱼属性表读取相关资源所属的房间
|
|
private decodeRoomFishData(): RoomFishData {
|
|
const filesRoomData: RoomFishData = {};
|
|
const fishAttribute = this.dataArrayToObjectArray(this.gameConfig['FishAttribute']);
|
|
|
|
for (const fish of fishAttribute) {
|
|
//房间数据
|
|
const fishName: string = fish.name;
|
|
if (!fishName) continue;
|
|
|
|
|
|
//处理鱼资源、鱼技能资源
|
|
this.updateRoomFishData(filesRoomData, `resources/anim/clip/fish/${fishName}`, fish);//鱼动画
|
|
this.updateRoomFishData(filesRoomData, `res/anim/texture/fish/${fishName}`, fish);;//鱼动画纹理
|
|
this.updateRoomFishData(filesRoomData, `resources/spine/fish/play/${fishName}`, fish);//鱼技能Spine
|
|
this.updateRoomFishData(filesRoomData, `res/spine/fish/play/${fishName}`, fish);//鱼技能Spine
|
|
|
|
//处理背景资源
|
|
// const backgroundString: string | null = fish.Background
|
|
// if (backgroundString) {
|
|
// const background = backgroundString.split('|');
|
|
// switch (background[0]) {
|
|
// case '1':
|
|
// this.updateRoomFishData(filesRoomData, `resources/texture/mainScene/bg/${background[1]}`, fish);//鱼背景静态图
|
|
// break;
|
|
// case '2':
|
|
// }
|
|
// }
|
|
}
|
|
return filesRoomData;
|
|
}
|
|
|
|
private updateRoomFishData(container: RoomFishData, key: string, fish: any): void {
|
|
const exitsData = container[key] || {};
|
|
for (let i = 1; i <= ROOM_COUNT; i++) {
|
|
exitsData[i] = exitsData[i] || (fish[`room${i}`] === 1);
|
|
}
|
|
container[key] = exitsData;
|
|
}
|
|
|
|
private initExcelSubpackage(config: SubpackageConfig[]): void {
|
|
|
|
const fileRoomData: RoomFishData = this.decodeRoomFishData();
|
|
Utils.log(`fileRoomData: ${JSON.stringify(fileRoomData)}`, Utils.LogLevel.Particular);
|
|
for (const key in this.subpackageContentData) {
|
|
Utils.log(`-------------------------------------------Decode package [${key}] config---------------------------------------------------`, Utils.LogLevel.Particular);
|
|
|
|
const uuids: { db: string, uuid: string }[] = [];
|
|
const files = this.subpackageContentData[key];
|
|
const roomTypes: number[] = [];
|
|
const excludeRoomTypes: number[] = [];
|
|
for (const file of files) {
|
|
switch (file.type) {
|
|
case 1:
|
|
{
|
|
Utils.log(`Add path: ${file.path}`, Utils.LogLevel.Particular);
|
|
this.getUUIDsInPath(file.path, uuids);
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
Utils.log(`Add path: ${file.path}`, Utils.LogLevel.Particular);
|
|
const regexp = new RegExp(file.path, 'i');
|
|
this.getUUIDsByRegExp(regexp, uuids);
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
const roomType = parseInt(file.path);
|
|
roomTypes.indexOf(roomType) >= 0 || roomTypes.push(roomType);
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
const roomType = parseInt(file.path);
|
|
excludeRoomTypes.indexOf(roomType) >= 0 || excludeRoomTypes.push(roomType);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (roomTypes.length || excludeRoomTypes.length) {
|
|
for (const filePath in fileRoomData) {
|
|
let isSubFile = true;
|
|
const data = fileRoomData[filePath];
|
|
for (let i = 0; i < roomTypes.length && isSubFile; i++) {
|
|
const roomType = roomTypes[i];
|
|
if (!data[roomType]) isSubFile = false;
|
|
}
|
|
|
|
for (let i = 0; i < excludeRoomTypes.length && isSubFile; i++) {
|
|
const roomType = excludeRoomTypes[i];
|
|
if (data[roomType]) isSubFile = false;
|
|
}
|
|
|
|
if (isSubFile) {
|
|
Utils.log(`Add path: ${filePath}`, Utils.LogLevel.Particular);
|
|
this.getUUIDsInPath(filePath, uuids);
|
|
}
|
|
}
|
|
}
|
|
this.updatePackageAssets(uuids);
|
|
|
|
const base = this.subpackageInfoData[key];
|
|
|
|
|
|
console.log(`Package ${key} files: \n${uuids.join(', ')}`);
|
|
config.push({ key: base.key, name: base.name, des: base.des, uuids: uuids.map(value => value.uuid) });
|
|
}
|
|
}
|
|
|
|
// private initWelfareSubpackage(config: SubpackageConfig[]): void {
|
|
// const welfare = this.dataArrayToObjectArray(this.gameConfig['Welfare']);
|
|
// welfare.forEach(({ id, page, pic }) => {
|
|
// const uuids: { db: string; uuid: string; }[] = [];
|
|
// this.getUUIDsInPath(`res/spine/welfare/${page}`, uuids);
|
|
// this.getUUIDsInPath(`res/prefab/welfare/${page}`, uuids);
|
|
// this.getUUIDsInPath(`res/texture/welfare/${page}`, uuids);
|
|
// this.getUUIDsInPath(`res/texture/_atlasexclude/welfare/${page}`, uuids);
|
|
// this.getUUIDsInPath(`resources/texture/welfareImgs/${pic}`, uuids);
|
|
// this.updatePackageAssets(uuids);
|
|
// config.push({ name: `welfare${id}`, des: '', uuids: uuids.map(value => value.uuid) });
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
private initSubpackageConfig(): SubpackageConfig[] {
|
|
const config: SubpackageConfig[] = [];
|
|
this.initExcelSubpackage(config);
|
|
return config;
|
|
}
|
|
|
|
public getSubpackageConfig(): SubpackageConfig[] {
|
|
this.subpackageConfigs = this.subpackageConfigs || this.initSubpackageConfig();
|
|
return this.subpackageConfigs;
|
|
}
|
|
} |