index.js 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327
  1. const path = require('./path.json');
  2. const readline = require('readline');
  3. var archiver = require('archiver');
  4. const fs = require('fs');
  5. const xl = require('xlsx');
  6. let excelDir = './excel'; // excel配置表目录
  7. let outDir = './out'; // 导出目录
  8. let outJsonFolder = 'excel'; // 导出的json目录
  9. //前端需要在load界面加载的表
  10. let loadJson = ["audioInfo", "languageLang", "languageClientText", "mathInfo", "packageInfo"]
  11. const cluster = require('cluster');
  12. //后端配置
  13. let serverPath = "../zhetian_backend_kaifa/common/"
  14. let apiurl = "../zhetian_backend_kaifa/public/api/assets/main.bundle.js"
  15. // 前后端解析索引的行
  16. let hang = 3; // 前端3 后端4
  17. // 表格列表 example: ["iconopen","mainTask"]
  18. let excelFiles = [];
  19. // 表名 +分表名
  20. let excelFen = [];
  21. // 表格与表单的数据类型 example:{iconopen:{id:string}}
  22. let excelAndSheets = {};
  23. var s_xls = require('./s_xls');
  24. const { exit } = require('process');
  25. // 检测传入的参数
  26. var args = process.argv.splice(2)
  27. var jiexiTarget = args[0] || "" // s:后端 c:前端
  28. function exeExcelConfig_c() {
  29. let str = '';
  30. str += `import GameController from "../GameController"\nimport { gameMethod } from "./gameMethod"\n`
  31. // 添加类型定义
  32. excelFiles.forEach((excelName) => {
  33. str += `// type for ${excelName}.excel\n`;
  34. for (const sheetName in excelAndSheets[excelName]) {
  35. str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
  36. //遍历索引存入类型定义
  37. let keyObjList = excelAndSheets[excelName][sheetName];
  38. for (const key in keyObjList) {
  39. str += `${key.split(',')[0]}:${keyObjList[key].value},`;
  40. }
  41. // 去掉最后一个逗号 ","
  42. if (str.charAt(str.length - 1) == ',') {
  43. str = str.substring(0, str.length - 1);
  44. }
  45. str += '}';
  46. str += '\n';
  47. }
  48. });
  49. str += '\n';
  50. //导出
  51. str += `export class XlsConfig {\n`;
  52. excelFen.forEach((element) => {
  53. str += ` xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
  54. });
  55. // str += ` constructor(callback: Function) {\n`
  56. // let str111 = [];
  57. // excelFen.forEach((element) => {
  58. // str111.push('"' + element + '"');
  59. // });
  60. // str += ` }\n`
  61. str += `
  62. constructor(bundleName:string, callback: Function, progressCallback?: Function) {
  63. cc.assetManager.loadBundle(bundleName, (err, bundle) => {
  64. if (err) {
  65. GameController.clear()
  66. cc.game.restart()
  67. if (progressCallback) {
  68. progressCallback(0, 0.99);
  69. }
  70. return
  71. }
  72. if (gameMethod.isEmpty(bundle) && cc.sys.platform == cc.sys.WECHAT_GAME) {
  73. //小游戏平台,缓存过期,自动清理缓存,重启游戏
  74. console.error("加载配置表的bundle失败,清理缓存重新加载")
  75. cc.assetManager.cacheManager.clearCache()
  76. GameController.clear()
  77. cc.game.restart()
  78. if (progressCallback) {
  79. progressCallback(0, 0.99);
  80. }
  81. return
  82. }
  83. bundle.loadDir("",(finish: number, total: number, item: any)=>{
  84. if (progressCallback) {
  85. progressCallback(finish, total);
  86. }
  87. }, (err2, assets: cc.JsonAsset[]) => {
  88. if (err2) {
  89. GameController.clear()
  90. cc.game.restart()
  91. if (progressCallback) {
  92. progressCallback(0, 0.99);
  93. }
  94. return
  95. }
  96. let current = 0;
  97. assets.forEach(element => {
  98. this["xls" + this.firstUpCase(element.name)] = element.json;
  99. current++;
  100. });
  101. callback(this)
  102. })
  103. })
  104. }
  105. // 首字母大写
  106. private firstUpCase(str: string) {
  107. return str[0].toUpperCase() + str.substring(1)
  108. }
  109. }`;
  110. if (hang == 3) {
  111. outDir = path.configPath;
  112. } else {
  113. outDir = serverPath;
  114. }
  115. // 写入文件
  116. let outPath = `${outDir}xlsConfig.ts`;
  117. fs.writeFile(outPath, str, function (err) {
  118. if (err) {
  119. console.log('xlsConfig写入失败:', err);
  120. }
  121. });
  122. let pro = '';
  123. if (hang == 4) {
  124. pro += 'import { CTX } from "../src/util/master";\n';
  125. }
  126. pro += `export default class ConfProxy<T> {
  127. static getKey(args: string[]): string {
  128. let out = ""
  129. args.forEach(element => {
  130. out += element
  131. out += "_"
  132. });
  133. return out
  134. }
  135. static setKey(target: any, args: string[]): string {
  136. let out = ""
  137. args.forEach(element => {
  138. out += target[element]
  139. out += "_"
  140. });
  141. return out
  142. }
  143. pool: { [key: string]: T } = {}
  144. name:string = ""
  145. constructor(xlsname:string,conf: T[], ...args: string[]) {
  146. this.name = xlsname
  147. conf.forEach(element => {
  148. this.pool[ConfProxy.setKey(element, args)] = element
  149. });
  150. }
  151. getItem(...args: string[]): T | null {
  152. return this.pool[ConfProxy.getKey(args)]
  153. }`;
  154. if (hang == 4) {
  155. pro += `
  156. getItemCtx(ctx:CTX,...args: string[]): T {
  157. let back = this.pool[ConfProxy.getKey(args)]
  158. if(back == null){
  159. console.error("配置错误"+args,this.name)
  160. ctx.throw("配置错误"+args)
  161. }
  162. return back
  163. }
  164. `;
  165. }
  166. pro += `
  167. }
  168. export class ConfListProxy<T> {
  169. pool: { [key: string]: T[] } = {}
  170. name:string = ""
  171. constructor(xlsname:string,conf: T[], ...args: string[]) {
  172. this.name = xlsname
  173. conf.forEach(element => {
  174. let key = ConfProxy.setKey(element, args)
  175. if (this.pool[key] == null) {
  176. this.pool[key] = []
  177. }
  178. this.pool[key].push(element)
  179. });
  180. }
  181. getItemList(...args: string[]): T[] | null {
  182. return this.pool[ConfProxy.getKey(args)]
  183. }
  184. }`;
  185. pro += '\n';
  186. // 写入文件
  187. let proPath = '';
  188. if (hang == 3) {
  189. proPath = `${path.configPath}confProxy.ts`;
  190. } else {
  191. proPath = serverPath + `confProxy.ts`;
  192. }
  193. fs.writeFile(proPath, pro, function (err) {
  194. if (err) {
  195. console.log('ConfProxy写入失败:', err);
  196. }
  197. });
  198. }
  199. function exeExcelConfig() {
  200. let str = '';
  201. // 引入ts文件
  202. excelFen.forEach((element) => {
  203. str += `const ${element} = require( "./excel/${element}.json")\n`;
  204. });
  205. str += '\n';
  206. // 添加类型定义
  207. excelFiles.forEach((excelName) => {
  208. str += `// type for ${excelName}.excel\n`;
  209. for (const sheetName in excelAndSheets[excelName]) {
  210. str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
  211. //遍历索引存入类型定义
  212. let keyObjList = excelAndSheets[excelName][sheetName];
  213. for (const key in keyObjList) {
  214. str += `${key.split(',')[0]}:${keyObjList[key].value},`;
  215. }
  216. // 去掉最后一个逗号 ","
  217. if (str.charAt(str.length - 1) == ',') {
  218. str = str.substring(0, str.length - 1);
  219. }
  220. str += '}';
  221. str += '\n';
  222. }
  223. });
  224. str += '\n';
  225. //导出
  226. str += `export class XlsConfig {\n`;
  227. excelFen.forEach((element) => {
  228. str += ` xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
  229. });
  230. str += ` constructor() {\n`;
  231. excelFen.forEach((element) => {
  232. str += ` this.xls${toUpperCaseByStr(element)} = <xls${toUpperCaseByStr(element)}[]>${element}\n`;
  233. });
  234. str += ` }\n`;
  235. str += '}\n';
  236. if (hang == 3) {
  237. outDir = path.configPath;
  238. } else {
  239. outDir = serverPath
  240. }
  241. // 写入文件
  242. let outPath = `${outDir}xlsConfig.ts`;
  243. fs.writeFile(outPath, str, function (err) {
  244. if (err) {
  245. console.log('xlsConfig写入失败:', err);
  246. }
  247. });
  248. let pro = '';
  249. if (hang == 4) {
  250. pro += 'import { CTX } from "../src/util/master";\n';
  251. }
  252. pro += `export default class ConfProxy<T> {
  253. static getKey(args: string[]): string {
  254. let out = ""
  255. args.forEach(element => {
  256. out += element
  257. out += "_"
  258. });
  259. return out
  260. }
  261. static setKey(target: any, args: string[]): string {
  262. let out = ""
  263. args.forEach(element => {
  264. out += target[element]
  265. out += "_"
  266. });
  267. return out
  268. }
  269. pool: { [key: string]: T } = {}
  270. name:string = ""
  271. constructor(xlsname:string,conf: T[], ...args: string[]) {
  272. this.name = xlsname
  273. conf.forEach(element => {
  274. this.pool[ConfProxy.setKey(element, args)] = this.deepFreeze(element)
  275. });
  276. }
  277. getItem(...args: string[]): T | null {
  278. return this.pool[ConfProxy.getKey(args)]
  279. }`;
  280. if (hang == 4) {
  281. pro += `
  282. getItemCtx(ctx:CTX,...args: string[]): T {
  283. let back = this.pool[ConfProxy.getKey(args)]
  284. if(back == null){
  285. console.error("配置错误"+args,this.name)
  286. ctx.throw("配置错误"+args)
  287. }
  288. return back
  289. }
  290. deepFreeze<T>(obj: T): T {
  291. Object.freeze(obj);
  292. Object.getOwnPropertyNames(obj).forEach(prop => {
  293. const value = (obj as Record<string, any>)[prop];
  294. if (value !== null
  295. && (typeof value === "object" || typeof value === "function")
  296. && !Object.isFrozen(value)) {
  297. this.deepFreeze(value);
  298. }
  299. });
  300. return obj as T;
  301. }
  302. `;
  303. }
  304. pro += `
  305. }
  306. export class ConfListProxy<T> {
  307. pool: { [key: string]: T[] } = {}
  308. name:string = ""
  309. constructor(xlsname:string,conf: T[], ...args: string[]) {
  310. this.name = xlsname
  311. conf.forEach(element => {
  312. let key = ConfProxy.setKey(element, args)
  313. if (this.pool[key] == null) {
  314. this.pool[key] = []
  315. }
  316. this.pool[key].push(element)
  317. });
  318. }
  319. getItemList(...args: string[]): T[] | null {
  320. return this.pool[ConfProxy.getKey(args)]
  321. }`;
  322. if (hang == 4) {
  323. pro += `
  324. getItemListCtx(ctx:CTX,...args: string[]): T[] {
  325. let back = this.pool[ConfProxy.getKey(args)]
  326. if(back == null){
  327. console.error("list配置错误"+args,this.name)
  328. ctx.throw("list配置错误"+args)
  329. }
  330. return back
  331. }
  332. `;
  333. }
  334. pro += `
  335. }
  336. `
  337. pro += '\n';
  338. // 写入文件
  339. let proPath = '';
  340. if (hang == 3) {
  341. proPath = `${path.configPath}confProxy.ts`;
  342. } else {
  343. proPath = serverPath + `confProxy.ts`;
  344. }
  345. fs.writeFile(proPath, pro, function (err) {
  346. if (err) {
  347. console.log('ConfProxy写入失败:', err);
  348. }
  349. });
  350. }
  351. // 字符串开头变为大写
  352. function toUpperCaseByStr(txt) {
  353. return txt.slice(0, 1).toUpperCase() + txt.slice(1);
  354. }
  355. // 分析配置表
  356. function doExcel(excel) {
  357. let excelName = excel.split('_')[0];
  358. if (s_xls.XlsBack[excelName] == null) {
  359. return
  360. }
  361. let fileDir = `${excelDir}/${excel}`;
  362. let workbook = xl.readFile(fileDir);
  363. // 获取 Excel 中所有表名
  364. const sheetNames = workbook.SheetNames; // 返回 ['sheet1', 'sheet2']
  365. let _sheetNames = [];
  366. for (const element of sheetNames) {
  367. if (s_xls.XlsBack[excelName][element] == null) {
  368. continue
  369. }
  370. _sheetNames.push(element);
  371. }
  372. if (_sheetNames.length == 0) {
  373. return;
  374. }
  375. console.time("...start excel " + excel)
  376. // 加到【excelAndSheets】中
  377. let obj = {};
  378. excelAndSheets[excelName] = {};
  379. _sheetNames.forEach((sheetName) => {
  380. let sheet = workbook.Sheets[sheetName];
  381. excelAndSheets[excelName][sheetName] = {};
  382. doSheet(obj, excelName, sheetName, sheet);
  383. });
  384. let outDir1 = ""
  385. let outDir2 = ""
  386. if (hang == 3) {
  387. outDir1 = `${path.jsonPath}`;
  388. if (!fs.existsSync(outDir1)) {
  389. fs.mkdirSync(outDir1)
  390. }
  391. outDir2 = `${path.loadJsonPath}`;
  392. if (!fs.existsSync(outDir2)) {
  393. fs.mkdirSync(outDir2)
  394. }
  395. } else {
  396. outDir1 = serverPath + `${outJsonFolder}`;
  397. if (!fs.existsSync(outDir1)) {
  398. fs.mkdirSync(outDir1)
  399. }
  400. }
  401. for (const key in obj) {
  402. let jsonStr = `${geshihua(obj[key])}`;
  403. if (outDir2 != "" && loadJson.indexOf(key) >= 0) {
  404. fs.writeFileSync(`${outDir2}/${key}.json`, jsonStr, function (err) {
  405. if (err) {
  406. console.log(err);
  407. }
  408. });
  409. } else {
  410. fs.writeFileSync(`${outDir1}/${key}.json`, jsonStr, function (err) {
  411. if (err) {
  412. console.log(err);
  413. }
  414. });
  415. }
  416. }
  417. console.timeEnd("...start excel " + excel)
  418. }
  419. function geshihua(data) {
  420. let count = 1;
  421. let _data = '[\n';
  422. for (const val of data) {
  423. if (count == 1) {
  424. _data += ' ' + JSON.stringify(val);
  425. } else {
  426. _data += `,\n`;
  427. _data += ' ' + JSON.stringify(val);
  428. }
  429. count++;
  430. }
  431. _data += '\n]';
  432. return _data;
  433. }
  434. //分析表单 obj数据,表名,表单名,表单数据内容
  435. function doSheet(obj, excelName, sheetName, sheet) {
  436. let newKey = excelName + toUpperCaseByStr(sheetName);
  437. excelFen.push(newKey);
  438. if (obj[newKey] == null) {
  439. obj[newKey] = [];
  440. }
  441. // 索引列表 example:{A:"",B:"id",C:"hp",D:"attack"}
  442. let keyList = {};
  443. // 类型列表 example:{A:"number",B:"string",C:"boolean",D:"{}[]"}
  444. let typeList = {};
  445. //备注
  446. let psList = {};
  447. let _tempObj = {};
  448. for (const key in sheet) {
  449. // 单元格定位id example: A25
  450. const sheetKey = sheet[key];
  451. // A25->25
  452. let _hang = key.replace(/[^0-9]+/gi, '');
  453. // A25->A
  454. let _lie = key.replace(/[^A-Z]+/gi, '');
  455. if (_lie == 'A') {
  456. if (Object.keys(_tempObj).length > 0) {
  457. //这边检测是否有放空配置的。如果有 , 补上默认类型
  458. let _tempObj_1 = {};
  459. for (const key in keyList) {
  460. if (_tempObj[keyList[key]] == null) {
  461. if (typeList[key] == 'number') {
  462. _tempObj_1[keyList[key]] = 0;
  463. } else if (typeList[key] == 'string') {
  464. _tempObj_1[keyList[key]] = '';
  465. } else if (typeList[key] == 'boolean') {
  466. _tempObj_1[keyList[key]] = false;
  467. } else if (typeList[key].indexOf('[]') != -1) {
  468. _tempObj_1[keyList[key]] = null;
  469. } else if (typeList[key].substring(0, 0 + 1) == '{') {
  470. _tempObj_1[keyList[key]] = null;
  471. } else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
  472. _tempObj_1[keyList[key]] = null;
  473. } else {
  474. console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
  475. }
  476. } else {
  477. _tempObj_1[keyList[key]] = _tempObj[keyList[key]];
  478. }
  479. }
  480. obj[newKey].push(_tempObj_1);
  481. _tempObj = {};
  482. }
  483. }
  484. if (sheet['A' + _hang] == null) {
  485. // 第一列没有配置参数,就跳过
  486. continue;
  487. }
  488. if (_hang == 1) {
  489. psList[_lie] = sheetKey.v;
  490. }
  491. // 储存类型
  492. if (_hang == 2) {
  493. typeList[_lie] = sheetKey.v;
  494. }
  495. // 储存索引
  496. if (_hang == hang && sheetKey.v && typeList[_lie]) {
  497. // 正则抽取真正的值(去掉所有的*)
  498. let realVal = sheetKey.v.replace(/[\*]/g, '');
  499. // 判断下作为key的字段
  500. let isKey = 0; // 0:不是key,1:单key,2:列表key
  501. if (sheetKey.v.slice(0, 2) == '**') {
  502. isKey = 2;
  503. } else if (sheetKey.v.slice(0, 1) == '*') {
  504. isKey = 1;
  505. }
  506. keyList[_lie] = realVal.split(',')[0].trim();
  507. // id:string
  508. excelAndSheets[excelName][sheetName][keyList[_lie]] = {
  509. ps: psList[_lie],
  510. isKey: isKey,
  511. value: typeList[_lie],
  512. keys: realVal
  513. };
  514. }
  515. // 储存数据
  516. if (_hang >= 5 && keyList[_lie] != null && typeList[_lie] != null) {
  517. // 根据类型转化数据内容,在做储存处理
  518. let _val;
  519. if (typeList[_lie] == 'number') {
  520. if (typeof sheetKey.v != 'number') {
  521. _val = Number(sheetKey.v);
  522. if (isNaN(_val)) {
  523. console.log(
  524. '\x1b[33m%s\x1b[0m',
  525. '警告,出现NaN数据类型,表名:' +
  526. excelName +
  527. ' 表单:' +
  528. sheetName +
  529. ' 索引:' +
  530. keyList[_lie] +
  531. ' 表格ID:' +
  532. key
  533. );
  534. }
  535. _val = 0;
  536. } else {
  537. _val = sheetKey.v;
  538. }
  539. } else if (typeList[_lie] == 'boolean') {
  540. if (sheetKey.v == 'true' || sheetKey.v == 'TRUE' || sheetKey.v == true) {
  541. _val = true;
  542. } else {
  543. _val = false;
  544. }
  545. } else if (typeList[_lie][0] == '{' || typeList[_lie].slice(-1) == ']') {
  546. try {
  547. _val = JSON.parse(sheetKey.v);
  548. } catch (error) {
  549. console.log(
  550. '\x1b[33m%s\x1b[0m',
  551. '警告:json格式错误,表名:' + excelName + ' 表单:' + sheetName + ' 索引:' + keyList[_lie] + ' 表格ID:' + key
  552. );
  553. }
  554. } else if (typeList[_lie] == 'string') {
  555. if (typeof sheetKey.v == 'number') {
  556. _val = Math.floor(sheetKey.v).toString();
  557. } else {
  558. _val = sheetKey.v;
  559. }
  560. } else {
  561. _val = sheetKey.v;
  562. }
  563. _tempObj[keyList[_lie].trim()] = _val;
  564. }
  565. }
  566. //这边检测是否有放空配置的。如果有 , 补上默认类型
  567. let _tempObj_1 = {};
  568. for (const key in keyList) {
  569. if (_tempObj[keyList[key]] == null) {
  570. if (typeList[key] == 'number') {
  571. _tempObj_1[keyList[key]] = 0;
  572. } else if (typeList[key] == 'string') {
  573. _tempObj_1[keyList[key]] = '';
  574. } else if (typeList[key] == 'boolean') {
  575. _tempObj_1[keyList[key]] = false;
  576. } else if (typeList[key].indexOf('[]') != -1) {
  577. _tempObj_1[keyList[key]] = null;
  578. } else if (typeList[key].substring(0, 0 + 1) == '{') {
  579. _tempObj_1[keyList[key]] = null;
  580. } else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
  581. _tempObj_1[keyList[key]] = null;
  582. } else {
  583. console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
  584. }
  585. } else {
  586. _tempObj_1[keyList[key]] = _tempObj[keyList[key]];
  587. }
  588. }
  589. // 储存最后一个
  590. obj[newKey].push(_tempObj_1);
  591. }
  592. // //--------------------start------------------- 控制台人机交互
  593. function readSyncByRl(tips) {
  594. tips = tips || '> ';
  595. return new Promise((resolve) => {
  596. const rl = readline.createInterface({
  597. input: process.stdin,
  598. output: process.stdout
  599. });
  600. rl.question(tips, (answer) => {
  601. rl.close();
  602. resolve(answer.trim());
  603. });
  604. });
  605. }
  606. /**
  607. * 后端创建xls对应gameCfg完成脚本
  608. */
  609. function createGameCfg_s() {
  610. let strs = '';
  611. strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
  612. let strHead = `XlsConfig`;
  613. let count = 2;
  614. for (const key1 in s_xls.XlsBack) {
  615. for (const key2 in s_xls.XlsBack[key1]) {
  616. if (s_xls.XlsBack[key1][key2].length <= 0) {
  617. continue;
  618. }
  619. strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
  620. count++;
  621. if (count % 9 == 0) {
  622. strHead += `\n`;
  623. }
  624. }
  625. }
  626. strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
  627. strs += `export default class Gamecfg {\n`;
  628. strs += ` static init() {\n`;
  629. strs += ` let xls = new XlsConfig()\n`;
  630. for (const key1 in s_xls.XlsBack) {
  631. for (const key2 in s_xls.XlsBack[key1]) {
  632. if (s_xls.XlsBack[key1][key2].length <= 0) {
  633. continue;
  634. }
  635. for (const val of s_xls.XlsBack[key1][key2]) {
  636. let cs = ``;
  637. for (let index = 1; index < val.length; index++) {
  638. cs += `,"${val[index]}"`;
  639. }
  640. if (val[0] == 'ConfProxy') {
  641. strs += ` Gamecfg.${key1}${toUpperCaseByStr(key2)} = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  642. continue;
  643. }
  644. if (val[0] == 'ConfListProxy') {
  645. strs += ` Gamecfg.${key1}${toUpperCaseByStr(key2)}List = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}List",xls.xls${toUpperCaseByStr(
  646. key1
  647. )}${toUpperCaseByStr(key2)} ${cs})\n`;
  648. continue;
  649. }
  650. let cs1 = ``;
  651. for (let index = 2; index < val.length; index++) {
  652. cs1 += `,"${val[index]}"`;
  653. }
  654. //别名
  655. if (val[1] == 'ConfProxy') {
  656. strs += ` Gamecfg.${key1}${toUpperCaseByStr(val[0])} = new ${val[1]}("${key1}${toUpperCaseByStr(val[0])}",xls.xls${toUpperCaseByStr(
  657. key1
  658. )}${toUpperCaseByStr(key2)} ${cs1})\n`;
  659. continue;
  660. }
  661. if (val[1] == 'ConfListProxy') {
  662. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  663. val[0]
  664. )}List = new ${val[1]}("${key1}${toUpperCaseByStr(
  665. val[0]
  666. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  667. continue;
  668. }
  669. }
  670. }
  671. }
  672. strs += ` }\n`;
  673. for (const key1 in s_xls.XlsBack) {
  674. for (const key2 in s_xls.XlsBack[key1]) {
  675. if (s_xls.XlsBack[key1][key2].length <= 0) {
  676. continue;
  677. }
  678. for (const val of s_xls.XlsBack[key1][key2]) {
  679. if (val[0] == 'ConfProxy') {
  680. strs += ` static ${key1}${toUpperCaseByStr(key2)} : ${val[0]}<xls${toUpperCaseByStr(
  681. key1
  682. )}${toUpperCaseByStr(key2)} >\n`;
  683. continue;
  684. }
  685. if (val[0] == 'ConfListProxy') {
  686. strs += ` static ${key1}${toUpperCaseByStr(key2)}List : ${val[0]}<xls${toUpperCaseByStr(
  687. key1
  688. )}${toUpperCaseByStr(key2)}>\n`;
  689. continue;
  690. }
  691. //别名
  692. if (val[1] == 'ConfProxy') {
  693. strs += ` static ${key1}${toUpperCaseByStr(val[0])} : ${val[1]}<xls${toUpperCaseByStr(
  694. key1
  695. )}${toUpperCaseByStr(key2)}>\n`;
  696. continue;
  697. }
  698. if (val[1] == 'ConfListProxy') {
  699. strs += ` static ${key1}${toUpperCaseByStr(
  700. val[0]
  701. )}List : ${val[1]}<xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}>\n`;
  702. continue;
  703. }
  704. }
  705. }
  706. }
  707. strs += `}\n`;
  708. // 写入文件
  709. let proPath = '';
  710. if (hang == 3) {
  711. proPath = `${path.configPath}gameCfg.ts`;
  712. } else {
  713. proPath = serverPath + `gameCfg.ts`;
  714. }
  715. fs.writeFile(proPath, strs, function (err) {
  716. if (err) {
  717. console.log('gameCfg写入失败:', err);
  718. }
  719. });
  720. }
  721. /**
  722. * 前端创建xls对应gameCfg完成脚本
  723. */
  724. function createGameCfg_c() {
  725. let strs = '';
  726. strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
  727. let strHead = `XlsConfig`;
  728. let count = 2;
  729. for (const key1 in s_xls.XlsBack) {
  730. for (const key2 in s_xls.XlsBack[key1]) {
  731. if (s_xls.XlsBack[key1][key2].length <= 0) {
  732. continue;
  733. }
  734. strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
  735. count++;
  736. if (count % 9 == 0) {
  737. strHead += `\n`;
  738. }
  739. }
  740. }
  741. strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
  742. strs += `export default class Gamecfg {\n`;
  743. for (const key1 in s_xls.XlsBack) {
  744. for (const key2 in s_xls.XlsBack[key1]) {
  745. if (s_xls.XlsBack[key1][key2].length <= 0) {
  746. continue;
  747. }
  748. for (const val of s_xls.XlsBack[key1][key2]) {
  749. if (val[0] == 'ConfProxy') {
  750. strs += ` static ${key1}${toUpperCaseByStr(key2)}:${val[0]}<xls${toUpperCaseByStr(
  751. key1
  752. )}${toUpperCaseByStr(key2)}>\n`;
  753. continue;
  754. }
  755. if (val[0] == 'ConfListProxy') {
  756. strs += ` static ${key1}${toUpperCaseByStr(key2)}List:${val[0]}<xls${toUpperCaseByStr(
  757. key1
  758. )}${toUpperCaseByStr(key2)}>\n`;
  759. continue;
  760. }
  761. //别名
  762. if (val[1] == 'ConfProxy') {
  763. strs += ` static ${key1}${toUpperCaseByStr(val[0])}:${val[1]}<xls${toUpperCaseByStr(
  764. key1
  765. )}${toUpperCaseByStr(key2)}>\n`;
  766. continue;
  767. }
  768. //别名
  769. if (val[1] == 'ConfListProxy') {
  770. strs += ` static ${key1}${toUpperCaseByStr(val[0])}List:${val[1]}<xls${toUpperCaseByStr(
  771. key1
  772. )}${toUpperCaseByStr(key2)}>\n`;
  773. continue;
  774. }
  775. }
  776. }
  777. }
  778. strs += `\n`;
  779. strs += ` static initLoading(loadSuccess: Function) {\n`;
  780. strs += ` try {\n`;
  781. strs += ` new XlsConfig("loadJson",(xls: XlsConfig) => {\n`;
  782. for (const key1 in s_xls.XlsBack) {
  783. for (const key2 in s_xls.XlsBack[key1]) {
  784. if (s_xls.XlsBack[key1][key2].length <= 0) {
  785. continue;
  786. }
  787. let jsonName = key1 + toUpperCaseByStr(key2)
  788. if (loadJson.indexOf(jsonName) < 0) {
  789. continue
  790. }
  791. for (const val of s_xls.XlsBack[key1][key2]) {
  792. let cs = ``;
  793. for (let index = 1; index < val.length; index++) {
  794. cs += `,"${val[index]}"`;
  795. }
  796. if (val[0] == 'ConfProxy') {
  797. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  798. key2
  799. )} = new ${val[0]}("${key1}${toUpperCaseByStr(
  800. key2
  801. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  802. continue;
  803. }
  804. if (val[0] == 'ConfListProxy') {
  805. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  806. key2
  807. )}List = new ${val[0]}("${key1}${toUpperCaseByStr(
  808. key2
  809. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  810. continue;
  811. }
  812. let cs1 = ``;
  813. for (let index = 2; index < val.length; index++) {
  814. cs1 += `,"${val[index]}"`;
  815. }
  816. //别名
  817. if (val[1] == 'ConfProxy') {
  818. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  819. val[0]
  820. )} = new ${val[1]}("${key1}${toUpperCaseByStr(
  821. val[0]
  822. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  823. continue;
  824. }
  825. if (val[1] == 'ConfListProxy') {
  826. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  827. val[0]
  828. )}List = new ${val[1]}("${key1}${toUpperCaseByStr(
  829. val[0]
  830. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  831. continue;
  832. }
  833. }
  834. }
  835. }
  836. strs += `
  837. loadSuccess(true)
  838. })
  839. } catch (error) {
  840. loadSuccess(false)
  841. }
  842. }`;
  843. strs += `\n`;
  844. strs += ` static init(loadSuccess: Function, progressCallback: Function) {\n`;
  845. strs += ` try {\n`;
  846. strs += ` new XlsConfig("pzwj",(xls: XlsConfig) => {\n`;
  847. for (const key1 in s_xls.XlsBack) {
  848. for (const key2 in s_xls.XlsBack[key1]) {
  849. if (s_xls.XlsBack[key1][key2].length <= 0) {
  850. continue;
  851. }
  852. let jsonName = key1 + toUpperCaseByStr(key2)
  853. if (loadJson.indexOf(jsonName) >= 0) {
  854. continue
  855. }
  856. for (const val of s_xls.XlsBack[key1][key2]) {
  857. let cs = ``;
  858. for (let index = 1; index < val.length; index++) {
  859. cs += `,"${val[index]}"`;
  860. }
  861. if (val[0] == 'ConfProxy') {
  862. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  863. key2
  864. )} = new ${val[0]}("${key1}${toUpperCaseByStr(
  865. key2
  866. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  867. continue;
  868. }
  869. if (val[0] == 'ConfListProxy') {
  870. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  871. key2
  872. )}List = new ${val[0]}("${key1}${toUpperCaseByStr(
  873. key2
  874. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
  875. continue;
  876. }
  877. let cs1 = ``;
  878. for (let index = 2; index < val.length; index++) {
  879. cs1 += `,"${val[index]}"`;
  880. }
  881. //别名
  882. if (val[1] == 'ConfProxy') {
  883. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  884. val[0]
  885. )} = new ${val[1]}("${key1}${toUpperCaseByStr(
  886. val[0]
  887. )}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  888. continue;
  889. }
  890. if (val[1] == 'ConfListProxy') {
  891. strs += ` Gamecfg.${key1}${toUpperCaseByStr(
  892. val[0]
  893. )}List = new ${val[1]}("${key1}${toUpperCaseByStr(
  894. val[0]
  895. )}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
  896. continue;
  897. }
  898. }
  899. }
  900. }
  901. strs += `
  902. loadSuccess(true)
  903. }, progressCallback)
  904. } catch (error) {
  905. loadSuccess(false)
  906. }
  907. }
  908. }`;
  909. // 写入文件
  910. let proPath = '';
  911. if (hang == 3) {
  912. proPath = `${path.configPath}gameCfg.ts`;
  913. } else {
  914. proPath = serverPath + `gameCfg.ts`;
  915. }
  916. fs.writeFile(proPath, strs, function (err) {
  917. if (err) {
  918. console.log('gameCfg写入失败:', err);
  919. }
  920. });
  921. }
  922. function createXyc() {
  923. const body = fs.readFileSync(apiurl, "utf-8");
  924. let arr = body.split('/a/apidoc"}]},')
  925. arr[1] = '[' + arr[1]
  926. let arr1 = arr[1].split('}];const');
  927. let str2 = arr1[0].replace(/!1/g, '0') + '}]';
  928. let apidoc = `//所有接口定义\n`
  929. apidoc += `export let apidoc:{[key:string]: {name:string,parms: {[key:string]: {type: string, desc: string}}}} = {\n`
  930. try {
  931. let strc = '';
  932. var jsons = eval('(' + str2 + ')');
  933. for (const json of jsons) {
  934. let jsontitle = json.url.split('/');
  935. let title = toUpperCaseByStr(jsontitle[1]) + toUpperCaseByStr(jsontitle[2]);
  936. let jsonUrl = json.url.slice(1);
  937. strc += `//${json.name}\n`;
  938. strc += `export class ${title}\n`;
  939. strc += `{\n`;
  940. strc += ` static url:string = "${jsonUrl}"\n`;
  941. strc += `}\n`;
  942. strc += `export interface ${title}Pram{\n`;
  943. apidoc += ` "/${jsonUrl}":{name:"${json.name}",parms:{`
  944. let _Parameter = [];
  945. let hasUuid = 0;
  946. let hasToken = 0;
  947. if (json.parameter != null) {
  948. for (const Parameter of json.parameter.fields.Parameter) {
  949. let description = Parameter.description;
  950. let arr11 = description.split('<p>');
  951. let arr12 = arr11[1].split('</p>');
  952. let _type = Parameter.type;
  953. _Parameter.push({
  954. type: _type,
  955. field: Parameter.field,
  956. description: arr12[0]
  957. });
  958. if (Parameter.field == 'uuid') {
  959. hasUuid = 1;
  960. }
  961. if (Parameter.field == 'token') {
  962. hasToken = 1;
  963. }
  964. }
  965. }
  966. for (const _rameter of _Parameter) {
  967. if (hasUuid == 1 && hasToken == 1) {
  968. if (_rameter.field == 'uuid' || _rameter.field == 'token') {
  969. continue;
  970. }
  971. }
  972. strc += ` ${_rameter.field}:${_rameter.type} //${_rameter.description}\n`;
  973. apidoc += `"${_rameter.field}": {type: "${_rameter.type}", desc: "${_rameter.description}"},`
  974. }
  975. strc += `}\n\n`;
  976. apidoc += `}},\n\n`;
  977. }
  978. apidoc += `}`
  979. if (hang == 3) {
  980. outDir = path.configPath;
  981. } else {
  982. outDir = serverPath
  983. }
  984. strc += `
  985. //前端返回的特殊事件
  986. export interface keyValue{
  987. [key:string]:number
  988. }
  989. export interface keyValues{
  990. [key:string]:number[]
  991. }
  992. export interface keyValueString{
  993. [key:string]:string
  994. }
  995. export type ZixuanSelectCs = [string,string,number];
  996. export type Wxmspinzhi = [number,number]
  997. export type Wxmskeys = [number,string,string];
  998. export type Wxmslm = [number,string];
  999. `
  1000. let proPath = `${outDir}Xyc.ts`;
  1001. fs.writeFileSync(proPath, strc, function (err) {
  1002. if (err) {
  1003. console.log('Xyc写入失败:', err);
  1004. }
  1005. });
  1006. let proPath1 = `${outDir}apidoc.ts`;
  1007. fs.writeFileSync(proPath1, apidoc, function (err) {
  1008. if (err) {
  1009. console.log('Xyc写入失败:', err);
  1010. }
  1011. });
  1012. } catch (error) {
  1013. console.log('===', error);
  1014. }
  1015. }
  1016. //拷贝 s_to_proto
  1017. function copy_s_to_proto() {
  1018. fs.copyFile(serverPath + 'Xys.ts', './s_to_proto/Xys.ts', (err) => {
  1019. console.log('=', err);
  1020. });
  1021. fs.copyFile(serverPath + 'Xyc.ts', './s_to_proto/Xyc.ts', (err) => {
  1022. console.log('=', err);
  1023. });
  1024. fs.copyFile(serverPath + 'gameMethod.ts', './s_to_proto/gameMethod.ts', (err) => {
  1025. console.log('=', err);
  1026. });
  1027. fs.copyFile(serverPath + 'fight.ts', './s_to_proto/fight.ts', (err) => {
  1028. console.log('=', err);
  1029. });
  1030. }
  1031. //拷贝 proto
  1032. function copy_proto_to_c() {
  1033. outDir = path.configPath;
  1034. fs.copyFile('./s_to_proto/Xys.ts', outDir + 'Xys.ts', (err) => {
  1035. console.log('=', err);
  1036. });
  1037. fs.copyFile('./s_to_proto/Xyc.ts', outDir + 'Xyc.ts', (err) => {
  1038. console.log('=', err);
  1039. });
  1040. fs.copyFile('./s_to_proto/gameMethod.ts', outDir + 'gameMethod.ts', (err) => {
  1041. console.log('=', err);
  1042. });
  1043. fs.copyFile('./s_to_proto/fight.ts', outDir + 'fight.ts', (err) => {
  1044. console.log('=', err);
  1045. });
  1046. }
  1047. /**
  1048. * 延迟多少毫秒
  1049. */
  1050. function sleep(ms) {
  1051. if (ms < 1) {
  1052. return;
  1053. }
  1054. return new Promise((reslove, reject) => {
  1055. setTimeout(() => {
  1056. reslove(1);
  1057. }, ms);
  1058. });
  1059. }
  1060. // 开始解析配置表
  1061. function doExe(res) {
  1062. // console.log(res);
  1063. if (res != 'c' && res != 's' && res != 'C' && res != 'S') {
  1064. console.log('非法输入');
  1065. return;
  1066. }
  1067. if (res == 'c' || res == 'C') {
  1068. hang = 3;
  1069. } else {
  1070. hang = 4;
  1071. }
  1072. if (hang == 3) {
  1073. outDir = path.configPath;
  1074. } else {
  1075. outDir = serverPath;
  1076. }
  1077. console.log('\x1b[37m'); // 控制台文字切为白色
  1078. if (hang == 4) {
  1079. fs.rm(serverPath + outJsonFolder, { recursive: true }, (err, data) => {
  1080. if (err) {
  1081. console.log('删除json文件失败' + err);
  1082. }
  1083. console.log('删除json文件成功');
  1084. let sendNum = 0
  1085. let overNum = 0
  1086. // 解析表格
  1087. fs.readdirSync(excelDir).forEach((excelName) => {
  1088. if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
  1089. excelFiles.push(excelName.split('_')[0]);
  1090. const worker = cluster.fork(excelName);
  1091. sendNum += 1
  1092. worker.send({ "hang": 4, "excelName": excelName })
  1093. worker.on('message', function (mes) {
  1094. let mesarr = JSON.parse(mes)
  1095. for (const ar of mesarr.excelFen) {
  1096. excelFen.push(ar)
  1097. }
  1098. for (const key in mesarr.excelAndSheets) {
  1099. excelAndSheets[key] = mesarr.excelAndSheets[key]
  1100. }
  1101. overNum += 1
  1102. console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
  1103. })
  1104. }
  1105. });
  1106. const intervalId = setInterval(() => {
  1107. if (sendNum <= overNum) {
  1108. createXyc();
  1109. console.log('*******创建xyc完成*******');
  1110. createGameCfg_s();
  1111. console.log('*******创建xls对应gameCfg完成*******');
  1112. copy_s_to_proto();
  1113. console.log('*******拷贝完成*******');
  1114. exeExcelConfig();
  1115. console.log('*******创建配置文件完成*******');
  1116. console.log("----全部完成----")
  1117. clearInterval(intervalId);
  1118. }
  1119. }, 1000);
  1120. });
  1121. }
  1122. if (hang == 3) {
  1123. fs.unlink(path.excelPath + outJsonFolder + '/excel.zip', (err, data) => {
  1124. if (err) {
  1125. console.log('删除zip文件失败' + err);
  1126. }
  1127. console.log('删除zip文件成功');
  1128. let sendNum = 0
  1129. let overNum = 0
  1130. let xls = {}
  1131. // 解析表格
  1132. fs.readdirSync(excelDir).forEach((excelName) => {
  1133. if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
  1134. excelFiles.push(excelName.split('_')[0]);
  1135. // doExcel(excelName);
  1136. xls[excelName] = 1
  1137. const worker = cluster.fork(excelName);
  1138. sendNum += 1
  1139. worker.send({ "hang": 3, "excelName": excelName })
  1140. worker.on('message', function (mes) {
  1141. let mesarr = JSON.parse(mes)
  1142. for (const ar of mesarr.excelFen) {
  1143. excelFen.push(ar)
  1144. }
  1145. for (const key in mesarr.excelAndSheets) {
  1146. excelAndSheets[key] = mesarr.excelAndSheets[key]
  1147. }
  1148. overNum += 1
  1149. delete xls[excelName]
  1150. console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
  1151. worker.destroy();
  1152. })
  1153. }
  1154. });
  1155. const intervalId = setInterval(() => {
  1156. if (sendNum <= overNum) {
  1157. // 生成配置表读取文件(ts)
  1158. exeExcelConfig_c();
  1159. console.log('*******创建配置文件完成*******');
  1160. // createXyc();
  1161. // console.log('*******创建xyc完成*******');
  1162. createGameCfg_c();
  1163. console.log('*******创建xls对应gameCfg完成*******');
  1164. copy_proto_to_c();
  1165. console.log('*******拷贝完成*******');
  1166. console.log("----全部完成----")
  1167. clearInterval(intervalId);
  1168. }
  1169. }, 1000);
  1170. });
  1171. }
  1172. sleep(4000);
  1173. // if (hang == 3) {
  1174. //
  1175. // }
  1176. }
  1177. if (!cluster.isMaster) {
  1178. process.on("message", function (message) {
  1179. hang = message.hang
  1180. doExcel(message.excelName)
  1181. process.send(JSON.stringify({ "excelFen": excelFen, "excelAndSheets": excelAndSheets }))
  1182. if(hang == 4){
  1183. process.exit()
  1184. }
  1185. });
  1186. return
  1187. }
  1188. if (jiexiTarget == "s" || jiexiTarget == "c") {
  1189. doExe(jiexiTarget)
  1190. } else {
  1191. readSyncByRl('exe client->c or server->s:').then((res) => {
  1192. doExe(res)
  1193. });
  1194. }
  1195. // //---------------------end-------------------- 控制台人机交互