ttmg-pack 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -403,4 +403,6 @@ for unity plugin
403
403
  优化 wasmcode 分包提示问题
404
404
 
405
405
  ## 0.4.7
406
- wasm 不校验必接能力,避免误提示
406
+ wasm 不校验必接能力,避免误提示
407
+ ## 0.4.8
408
+ packConfig 扩展 __engine_meta__ 字段,用于后续 C 端数据分析使用
@@ -0,0 +1 @@
1
+ module.exports = {};
@@ -0,0 +1,3 @@
1
+ require('cocos/cocos2d-js-min.js');
2
+ require('./ccRequire');
3
+ window.boot();
@@ -0,0 +1,3 @@
1
+ {
2
+ "deviceOrientation": "portrait"
3
+ }
@@ -0,0 +1,3 @@
1
+ require('./libs/laya.core.js');
2
+ Laya.MiniAdpter.init();
3
+ loadLib('libs/laya.wxmini.js');
@@ -0,0 +1,3 @@
1
+ {
2
+ "deviceOrientation": "portrait"
3
+ }
@@ -0,0 +1 @@
1
+ module.exports = {};
@@ -0,0 +1,3 @@
1
+ {
2
+ "version": "1.0.0"
3
+ }
@@ -15,6 +15,16 @@ describe('getGameEngine', function() {
15
15
  assert.strictEqual(result, 'cocos');
16
16
  });
17
17
 
18
+ it('should detect cocos by file signatures when gameEngine is missing', function() {
19
+ const result = getGameEngine(path.join(fixturesPath, 'game-cocos-by-files'));
20
+ assert.strictEqual(result, 'cocos');
21
+ });
22
+
23
+ it('should detect laya by file signatures when gameEngine is missing', function() {
24
+ const result = getGameEngine(path.join(fixturesPath, 'game-laya-by-files'));
25
+ assert.strictEqual(result, 'laya');
26
+ });
27
+
18
28
  it('should return unknown when game.json does not exist', function() {
19
29
  const result = getGameEngine(path.join(fixturesPath, 'game-no-config'));
20
30
  assert.strictEqual(result, 'unknown');
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * ==========================================
3
3
  * @Description: ttmg pack
4
- * @Version: 0.4.7
4
+ * @Version: 0.4.8
5
5
  * @Author: zhanghongyang.mocha
6
- * @Date: 2026-04-03 17:13:01
6
+ * @Date: 2026-04-09 16:30:51
7
7
  * ==========================================
8
8
  */
9
9
  'use strict';
@@ -625,21 +625,126 @@ function getProjectSize({ entryDir }) {
625
625
  }
626
626
 
627
627
  function getGameEngine(gameEntry) {
628
+ const gameJsonConfig = getGameJsonConfig(gameEntry);
629
+ const gameEngine = normalizeGameEngine(gameJsonConfig === null || gameJsonConfig === void 0 ? void 0 : gameJsonConfig.gameEngine);
630
+ if (gameEngine !== 'unknown') {
631
+ return gameEngine;
632
+ }
633
+ return detectGameEngineByFiles(gameEntry);
634
+ }
635
+ function getGameJsonConfig(gameEntry) {
628
636
  const gameJsonConfigPath = path.join(gameEntry, GAME_ORIGIN_CONFIG_FILE_NAME);
629
637
  if (!fs.existsSync(gameJsonConfigPath)) {
630
- return 'unknown';
638
+ return null;
631
639
  }
632
- let gameJsonConfig;
633
640
  try {
634
- gameJsonConfig = JSON.parse(fs.readFileSync(gameJsonConfigPath, 'utf-8'));
635
- const gameEngine = gameJsonConfig === null || gameJsonConfig === void 0 ? void 0 : gameJsonConfig.gameEngine;
636
- if (!gameEngine) {
641
+ return JSON.parse(fs.readFileSync(gameJsonConfigPath, 'utf-8'));
642
+ }
643
+ catch (error) {
644
+ return null;
645
+ }
646
+ }
647
+ function normalizeGameEngine(gameEngine) {
648
+ if (typeof gameEngine !== 'string') {
649
+ return 'unknown';
650
+ }
651
+ switch (gameEngine.trim().toLowerCase()) {
652
+ case 'unity':
653
+ case 'cocos':
654
+ case 'laya':
655
+ case 'layabox':
656
+ return gameEngine.trim().toLowerCase() === 'layabox'
657
+ ? 'laya'
658
+ : gameEngine.trim().toLowerCase();
659
+ default:
637
660
  return 'unknown';
661
+ }
662
+ }
663
+ function detectGameEngineByFiles(gameEntry) {
664
+ const cocosScore = getCocosScore(gameEntry);
665
+ const layaScore = getLayaScore(gameEntry);
666
+ if (cocosScore < 4 && layaScore < 4) {
667
+ return 'unknown';
668
+ }
669
+ if (cocosScore === layaScore) {
670
+ return 'unknown';
671
+ }
672
+ return cocosScore > layaScore ? 'cocos' : 'laya';
673
+ }
674
+ function getCocosScore(gameEntry) {
675
+ let score = 0;
676
+ if (pathExists(gameEntry, 'cocos/cocos2d-js-min.js')) {
677
+ score += 4;
678
+ }
679
+ if (pathExists(gameEntry, 'cocos-js')) {
680
+ score += 4;
681
+ }
682
+ if (pathExists(gameEntry, 'ccRequire.js')) {
683
+ score += 3;
684
+ }
685
+ if (pathExists(gameEntry, 'engine-adapter.js') || pathExists(gameEntry, 'web-adapter.js')) {
686
+ score += 2;
687
+ }
688
+ if (pathExists(gameEntry, 'src/settings.js') || hasFileName(path.join(gameEntry, 'src'), /^settings(?:\.[^.]+)?\.json$/i)) {
689
+ score += 2;
690
+ }
691
+ if (fileContains(path.join(gameEntry, 'game.js'), [
692
+ /cocos\/cocos2d-js/i,
693
+ /ccRequire/i,
694
+ /__globalAdapter\.adaptEngine\(/,
695
+ /window\.boot\(/,
696
+ ])) {
697
+ score += 4;
698
+ }
699
+ return score;
700
+ }
701
+ function getLayaScore(gameEntry) {
702
+ let score = 0;
703
+ if (hasLayaLibFile(path.join(gameEntry, 'libs'))) {
704
+ score += 4;
705
+ }
706
+ if (pathExists(gameEntry, 'fileconfig.json')) {
707
+ score += 3;
708
+ }
709
+ if (pathExists(gameEntry, 'version.json')) {
710
+ score += 2;
711
+ }
712
+ if (fileContains(path.join(gameEntry, 'game.js'), [
713
+ /loadLib\(/,
714
+ /Laya\./,
715
+ /require\((['"])\.?\/?libs\/laya/i,
716
+ ])) {
717
+ score += 4;
718
+ }
719
+ return score;
720
+ }
721
+ function hasLayaLibFile(libsDir) {
722
+ return hasFileName(libsDir, /^laya(?:\.[^.]+)*\.js$/i) || hasFileName(path.join(libsDir, 'min'), /^laya(?:\.[^.]+)*\.js$/i);
723
+ }
724
+ function pathExists(gameEntry, relativePath) {
725
+ return fs.existsSync(path.join(gameEntry, relativePath));
726
+ }
727
+ function hasFileName(dirPath, pattern) {
728
+ try {
729
+ if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
730
+ return false;
638
731
  }
639
- return gameEngine;
732
+ return fs.readdirSync(dirPath).some(fileName => pattern.test(fileName));
640
733
  }
641
734
  catch (error) {
642
- return 'unknown';
735
+ return false;
736
+ }
737
+ }
738
+ function fileContains(filePath, patterns) {
739
+ if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
740
+ return false;
741
+ }
742
+ try {
743
+ const content = fs.readFileSync(filePath, 'utf-8');
744
+ return patterns.some(pattern => pattern.test(content));
745
+ }
746
+ catch (error) {
747
+ return false;
643
748
  }
644
749
  }
645
750
 
@@ -1654,6 +1759,14 @@ async function setup(config) {
1654
1759
  logger.info(t('log.setup.startGeneratePackageConfig'));
1655
1760
  const gameJsonPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);
1656
1761
  const gameJson = JSON.parse(fs.readFileSync(gameJsonPath, 'utf-8'));
1762
+ let gameEngine = 'unknown';
1763
+ try {
1764
+ gameEngine = getGameEngine(entryDir);
1765
+ }
1766
+ catch (error) {
1767
+ const errorMessage = error instanceof Error ? error.message : String(error);
1768
+ logger.warn(`Failed to detect game engine for __engine_meta__, fallback to unknown: ${errorMessage}`);
1769
+ }
1657
1770
  const packages = {};
1658
1771
  // fyf for your feed 缩写,代表可用于视频锚点投放使用的包
1659
1772
  const fyfPackages = [
@@ -1696,6 +1809,10 @@ async function setup(config) {
1696
1809
  const result = {
1697
1810
  packages,
1698
1811
  fyf_packages: fyfPackages,
1812
+ // 游戏引擎类型
1813
+ __engine_meta__: {
1814
+ gameEngine,
1815
+ },
1699
1816
  };
1700
1817
  if (fs.existsSync(outputDir)) {
1701
1818
  fs.rmSync(outputDir, { recursive: true });
@@ -2428,6 +2545,7 @@ async function debugPkgs(config, context = {}) {
2428
2545
  isSuccess: true,
2429
2546
  packages: packageConfigJson.packages,
2430
2547
  checkResults,
2548
+ packageConfig: packageConfigJson,
2431
2549
  };
2432
2550
  }
2433
2551
  catch (error) {
@@ -2445,7 +2563,7 @@ async function buildPkgs(config, context = {}) {
2445
2563
  let startTime = Date.now();
2446
2564
  logger.init(outputDir, true);
2447
2565
  logger.info(t('log.build.version', {
2448
- version: "0.4.7",
2566
+ version: "0.4.8",
2449
2567
  }));
2450
2568
  logger.info(t('log.build.start', { startTime }));
2451
2569
  /**