patch_cesium_sampler3d.cjs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * 修补 Cesium.js:在 uniform 类型 switch-case 中添加 SAMPLER_3D (35679) 支持。
  3. *
  4. * SuperMap 定制的 Cesium.js 在 PostProcessStage 的 uniform setter 创建逻辑中
  5. * 缺少对 SAMPLER_3D 分支的处理,导致 sampler3D 类型的 uniform 绑定失败。
  6. *
  7. * 本脚本通过分析 obfuscated 代码中的 SAMPLER constants 定义,找到对应的
  8. * WebGL 常量值,并在 switch-case 中插入缺失的 SAMPLER_3D 分支。
  9. */
  10. const fs = require('fs');
  11. const path = require('path');
  12. const filePath = path.join(__dirname, 'public/Cesium/Cesium.js');
  13. let content = fs.readFileSync(filePath, 'utf8');
  14. // Step 1: Find SAMPLER_3D constant definition
  15. // Looking for: 'SAMPLER_3D':0x8b5f
  16. const sampler3DConstIdx = content.indexOf("'SAMPLER_3D'");
  17. if (sampler3DConstIdx < 0) {
  18. console.error('SAMPLER_3D constant not found in Cesium.js');
  19. process.exit(1);
  20. }
  21. console.log('SAMPLER_3D constant found at byte', sampler3DConstIdx);
  22. // Step 2: Find SAMPLER_2D constant definition to find its numeric value
  23. const sampler2DConstIdx = content.indexOf("'SAMPLER_2D'");
  24. if (sampler2DConstIdx < 0) {
  25. console.error('SAMPLER_2D constant not found');
  26. process.exit(1);
  27. }
  28. console.log('SAMPLER_2D constant found at byte', sampler2DConstIdx);
  29. // Step 3: Find the switch-case that handles uniform types
  30. // Looking for the pattern: case ... SAMPLER_2D ... case ... SAMPLER_CUBE
  31. // These are used in the uniform setter creation function
  32. // Search for SAMPLER_CUBE in the context of a switch case
  33. const switchPattern = /case\s+[^;]*?SAMPLER_2D[^;]*?case\s+[^;]*?SAMPLER_CUBE/g;
  34. let match;
  35. let found = false;
  36. while ((match = switchPattern.exec(content)) !== null) {
  37. const fullMatch = match[0];
  38. console.log('\nFound SAMPLER_2D..SAMPLER_CUBE sequence at byte', match.index);
  39. console.log('Match:', fullMatch.substring(0, 200));
  40. // Check if SAMPLER_3D is already present between them
  41. if (fullMatch.includes('SAMPLER_3D')) {
  42. console.log('SAMPLER_3D already present - no patch needed!');
  43. found = true;
  44. continue;
  45. }
  46. // Find the pattern between SAMPLER_2D and SAMPLER_CUBE
  47. const s2Idx = fullMatch.indexOf('SAMPLER_2D');
  48. const scIdx = fullMatch.indexOf('SAMPLER_CUBE');
  49. const between = fullMatch.substring(s2Idx + 'SAMPLER_2D'.length, scIdx);
  50. console.log('Between SAMPLER_2D and SAMPLER_CUBE:', between.substring(0, 100));
  51. // Get the property access pattern: e.g., `_0x2cbe(0x...)` or `this.SAMPLER_2D`
  52. // We need to find how SAMPLER_2D's value is obtained
  53. const s2Access = fullMatch.substring(0, s2Idx).trim();
  54. const s2AccessClean = s2Access.replace(/^case\s+/, '').trim();
  55. console.log('SAMPLER_2D access pattern:', s2AccessClean.substring(0, 80));
  56. // The SAMPLER_2D access is via a property on an object
  57. // The SAMPLER_3D should use the SAME object but with SAMPLER_3D
  58. // e.g. if SAMPLER_2D is accessed as `_0x4b6e38.SAMPLER_2D`
  59. // then SAMPLER_3D should be `_0x4b6e38.SAMPLER_3D`
  60. const objMatch = s2AccessClean.match(/^([\w.]+)\.SAMPLER_2D$/);
  61. if (!objMatch) {
  62. console.log('Cannot parse access pattern, trying alternative...');
  63. // Could also be an array access like _0x...['SAMPLER_2D']
  64. continue;
  65. }
  66. const obj = objMatch[1];
  67. const sampler3DAccess = obj + ".SAMPLER_3D";
  68. const insertStr = "case " + sampler3DAccess + ":";
  69. console.log('Will insert:', insertStr);
  70. // Insert SAMPLER_3D case after SAMPLER_2D case
  71. const insertPos = match.index + s2Idx + 'SAMPLER_2D'.length + between.length;
  72. const insertion = "case " + sampler3DAccess + ":";
  73. content = content.substring(0, insertPos) + insertion + content.substring(insertPos);
  74. console.log('Inserted at byte', insertPos);
  75. found = true;
  76. break;
  77. }
  78. if (!found) {
  79. console.log('\nCould not find the switch-case pattern. Trying alternative approach...');
  80. // Alternative: Search for "SAMPLER_2D:SAMPLER_CUBE" or similar sequences
  81. // The obfuscated code might have these constant strings next to each other
  82. const altPattern = /SAMPLER_2D['"`:;,.\]]+SAMPLER_CUBE/g;
  83. while ((match = altPattern.exec(content)) !== null) {
  84. console.log('Alt pattern found at byte', match.index, ':', match[0].substring(0, 100));
  85. }
  86. }
  87. // Save the patched file
  88. fs.writeFileSync(filePath, content, 'utf8');
  89. console.log('\nPatch complete');