pluginconfigviewer.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. class PluginConfigViewer extends PluginBase
  2. {
  3. void PluginConfigViewer()
  4. {
  5. }
  6. string MakeTabs( int count, bool inheritance = false )
  7. {
  8. if ( count == 0 )
  9. {
  10. return "";
  11. }
  12. string tabs = "|--";
  13. if ( inheritance )
  14. {
  15. tabs = "|<<";
  16. }
  17. for ( int i = 0; i < count - 1; i++ )
  18. {
  19. tabs = "| " + tabs;
  20. }
  21. return tabs;
  22. }
  23. string GetOnlyChildPath( string config_class_path, string class_path )
  24. {
  25. int config_class_path_len = config_class_path.Length();
  26. int class_path_len = class_path.Length();
  27. if ( class_path_len > config_class_path_len )
  28. {
  29. int start = config_class_path_len;
  30. int count = class_path_len - start;
  31. return class_path.Substring(start, count).Trim();
  32. }
  33. else
  34. {
  35. return "";
  36. }
  37. }
  38. string GetBaseClassPath( string config_class_path, string class_path, string config_class )
  39. {
  40. if ( class_path == "" )
  41. {
  42. return "";
  43. }
  44. int start = config_class_path.Length();
  45. int count = class_path.Length() - start;
  46. string class_path_without_config_class = GetOnlyChildPath( config_class_path, class_path );
  47. ref TStringArray full_path = new TStringArray;
  48. GetGame().ConfigGetFullPath( config_class_path, full_path );
  49. if ( full_path.Count() > 1 && class_path_without_config_class != "" )
  50. {
  51. return GetBaseClassPathRecursive( config_class + " " + full_path.Get(1), class_path_without_config_class, config_class );
  52. }
  53. else
  54. {
  55. return "";
  56. }
  57. }
  58. string GetBaseClassPathCombined( string child_path, string base_class )
  59. {
  60. int current = -1;
  61. int last = 0;
  62. while ( true )
  63. {
  64. current = child_path.IndexOfFrom(last, " " );
  65. if ( current > -1 )
  66. {
  67. last = current+1;
  68. }
  69. else
  70. {
  71. break;
  72. }
  73. }
  74. string result = child_path.Substring(0, last ) + base_class;
  75. return result;
  76. }
  77. string GetBaseClassPathRecursive( string config_class_path, string class_path, string config_class )
  78. {
  79. if ( ContainsFirstClass(config_class_path, class_path) )
  80. {
  81. return config_class_path + " " + class_path;
  82. }
  83. else
  84. {
  85. ref TStringArray full_path = new TStringArray;
  86. GetGame().ConfigGetFullPath( config_class_path, full_path );
  87. if ( full_path.Count() > 1 )
  88. {
  89. return GetBaseClassPathRecursive( config_class + " " + full_path.Get(1), class_path, config_class );
  90. }
  91. else
  92. {
  93. return "";
  94. }
  95. }
  96. }
  97. bool ContainsFirstClass( string config_class_path, string class_path )
  98. {
  99. int start = class_path.IndexOf(" ");
  100. string name = class_path;
  101. if ( start > -1 )
  102. {
  103. name = class_path.Substring(0, start );
  104. }
  105. int cfg_class_count = GetGame().ConfigGetChildrenCount( config_class_path );
  106. for ( int i = 0; i < cfg_class_count; i++ )
  107. {
  108. string cfg_class_name = "";
  109. GetGame().ConfigGetChildName( config_class_path, i, cfg_class_name );
  110. if ( cfg_class_name == name )
  111. {
  112. string full_name = config_class_path + " " + name;
  113. int type = GetGame().ConfigGetType( full_name );
  114. if ( type == CT_CLASS )
  115. {
  116. return true;
  117. }
  118. }
  119. }
  120. if ( start == -1 )
  121. {
  122. return false;
  123. }
  124. else
  125. {
  126. string new_name = class_path.Substring(start + 1, class_path.Length() - (start + 1) );
  127. return ContainsFirstClass( config_class_path + " " + name, new_name );
  128. }
  129. }
  130. TStringArray GetConfigRecursive( string path, string name, string config_class_path, string config_class, local array<string> overridden, int depth = 0, local bool check_base_class_of_class = false )
  131. {
  132. string tabs = MakeTabs( depth + 1 );
  133. string child_path = path;
  134. int count = GetGame().ConfigGetChildrenCount( child_path );
  135. int i = 0;
  136. bool name_printed = false;
  137. TStringArray result = new TStringArray;
  138. for ( i = 0; i < count; i++ )
  139. {
  140. string child_name = "";
  141. GetGame().ConfigGetChildName( child_path, i, child_name );
  142. string c_child_path = child_path + " " + child_name;
  143. string child_name_lower = child_name;
  144. child_name_lower.ToLower();
  145. if ( overridden.Find(child_name_lower) == -1 )
  146. {
  147. if ( !name_printed )
  148. {
  149. result.Insert( ":" + MakeTabs(depth, check_base_class_of_class) + "!" + name );
  150. name_printed = true;
  151. }
  152. overridden.Insert( child_name_lower );
  153. int type = GetGame().ConfigGetType( c_child_path );
  154. if ( type != CT_CLASS )
  155. {
  156. if ( type != CT_ARRAY )
  157. {
  158. result.Insert( "-" + tabs + "!" + child_name + " = " + GetGame().ConfigGetTextOut(c_child_path) );
  159. }
  160. else
  161. {
  162. result.Insert( "-" + tabs + "!" + child_name + "[] = {" );
  163. TStringArray strs = new TStringArray;
  164. GetGame().ConfigGetTextArray( c_child_path, strs );
  165. string tabs_array = MakeTabs( depth + 2 );
  166. int j;
  167. for ( j = 0; j < strs.Count(); j++ )
  168. {
  169. result.Insert( "-" + tabs + "!" + child_name + "[]" + j.ToStringLen(6) + "~" + strs.Get(j) + "," );
  170. }
  171. result.Insert( "-" + tabs + "!" + child_name + "[]" + j.ToStringLen(6) + "~}" );
  172. }
  173. }
  174. else
  175. {
  176. array<string> overridden_sub = new array<string>;
  177. if ( GetGame().ConfigGetChildrenCount(c_child_path) > 0 )
  178. {
  179. TStringArray config1 = GetConfigRecursive( c_child_path, child_name, config_class_path, config_class, overridden_sub, depth + 1 );
  180. result.InsertAll( config1 );
  181. }
  182. else
  183. {
  184. result.Insert( ":" + tabs + "!" + child_name );
  185. }
  186. string cc_child_path = c_child_path;
  187. string c_config_class_path = config_class_path;
  188. string c_child_name = child_name;
  189. int cc = 0;
  190. while ( true )
  191. {
  192. string base_class = "";
  193. GetGame().ConfigGetBaseName( cc_child_path, base_class );
  194. int start = c_config_class_path.Length() + 1;
  195. int len = cc_child_path.Length();
  196. len -= c_config_class_path.Length() + c_child_name.Length();
  197. len -= 2;
  198. if ( base_class != "" )
  199. {
  200. string only_child_path = "";
  201. if ( len < 0 )
  202. {
  203. only_child_path = base_class;
  204. }
  205. else
  206. {
  207. only_child_path = cc_child_path.Substring( start, len ) + " " + base_class;
  208. }
  209. string c_base_child_path = GetBaseClassPathCombined( cc_child_path, base_class );
  210. string base_class_path = GetBaseClassPath( c_config_class_path, c_base_child_path, config_class );
  211. if ( base_class_path != "" )
  212. {
  213. TStringArray config2 = GetConfigRecursive( base_class_path, base_class, base_class_path, config_class, overridden_sub, depth + 1, true );
  214. result.InsertAll( config2 );
  215. }
  216. else
  217. {
  218. TStringArray config3 = GetConfigRecursive( base_class, base_class, base_class, config_class, overridden_sub, depth + 1, true );
  219. result.InsertAll( config3 );
  220. break;
  221. }
  222. cc_child_path = base_class_path;
  223. c_child_name = base_class;
  224. c_config_class_path = cc_child_path.Substring( 0, cc_child_path.Length() - only_child_path.Length() - 1);
  225. }
  226. else
  227. {
  228. break;
  229. }
  230. }
  231. }
  232. }
  233. }
  234. if ( name_printed )
  235. {
  236. result.Insert( ":" + MakeTabs(depth, check_base_class_of_class) + "#" + name );
  237. }
  238. if ( !check_base_class_of_class )
  239. {
  240. TStringArray full_path = new TStringArray;
  241. GetGame().ConfigGetFullPath( child_path, full_path );
  242. if ( full_path.Count() > 1 )
  243. {
  244. TStringArray config4 = GetConfigRecursive( config_class + " " + full_path.Get(1), full_path.Get(1), config_class + " " + full_path.Get(1), config_class, overridden, depth );
  245. result.InsertAll( config4 );
  246. }
  247. }
  248. else
  249. {
  250. string class_base_class = "";
  251. GetGame().ConfigGetBaseName( child_path, class_base_class );
  252. if ( class_base_class != "" )
  253. {
  254. string base_child_path = GetBaseClassPathCombined( child_path, class_base_class );
  255. string cc_base_child_path = GetBaseClassPath( config_class_path, base_child_path, config_class );
  256. if ( cc_base_child_path != "" )
  257. {
  258. TStringArray config5 = GetConfigRecursive( cc_base_child_path, class_base_class, cc_base_child_path, config_class, overridden, depth, true );
  259. result.InsertAll( config5 );
  260. }
  261. else
  262. {
  263. TStringArray config6 = GetConfigRecursive( class_base_class, class_base_class, class_base_class, config_class, overridden, depth, true );
  264. result.InsertAll( config6 );
  265. }
  266. }
  267. }
  268. return result;
  269. }
  270. TStringArray GetConfig( string class_path, string filter_char )
  271. {
  272. int i;
  273. TStringArray filtered = new TStringArray;
  274. if ( class_path != "" )
  275. {
  276. PluginDeveloper module_dev = PluginDeveloper.Cast( GetPlugin( PluginDeveloper ) );
  277. TStringArray path_nodes = new TStringArray;
  278. class_path.Split( " ", path_nodes );
  279. if ( path_nodes.Count() >= 3 )
  280. {
  281. string c_class_path = path_nodes.Get(0) + " " + path_nodes.Get(1) + " " + path_nodes.Get(2);
  282. array<string> overridden = new array<string>;
  283. string config_class = path_nodes.Get( 1 );
  284. string class_name = path_nodes.Get( 2 );
  285. TStringArray result = GetConfigRecursive( c_class_path, class_name, c_class_path, config_class, overridden );
  286. TStringArray nested_start = new TStringArray;
  287. TStringArray nested_end = new TStringArray;
  288. TStringArray nested_inherited_start = new TStringArray;
  289. TStringArray nested_inherited_end = new TStringArray;
  290. string tabs = MakeTabs( 1 );
  291. string tabs_inherited = MakeTabs( 1, true );
  292. string check_tabs = MakeTabs( path_nodes.Count() - 1, true );
  293. nested_start.Insert( ":!" );
  294. nested_end.Insert( ":#" );
  295. nested_inherited_start.Insert( ":!" );
  296. nested_inherited_end.Insert( ":#" );
  297. string last_node = filter_char + MakeTabs( nested_start.Count() ) + "!";
  298. if ( path_nodes.Count() == 3 )
  299. {
  300. last_node = filter_char + MakeTabs( 1 ) + "!";
  301. }
  302. else
  303. {
  304. for ( i = 1; i < path_nodes.Count() - 2; i++ )
  305. {
  306. tabs = MakeTabs( i );
  307. tabs_inherited = MakeTabs( i, true );
  308. string path_node = path_nodes.Get(i+2);
  309. path_node.ToLower( );
  310. nested_start.Insert( ":" + tabs + "!" + path_node );
  311. nested_end.Insert( ":" + tabs + "#" + path_node );
  312. nested_inherited_start.Insert( ":" + tabs_inherited + "!" + path_node );
  313. nested_inherited_end.Insert( ":" + tabs_inherited + "#" + path_node );
  314. }
  315. last_node = filter_char + MakeTabs( i ) + "!";
  316. }
  317. int current_nest = 0;
  318. for ( i = 0; i < result.Count(); i++ )
  319. {
  320. string current = result.Get( i );
  321. string current_lower = current;
  322. current_lower.ToLower( );
  323. int len_current = current.Length();
  324. if ( current_nest < nested_start.Count() )
  325. {
  326. int len_start = nested_start.Get(current_nest).Length();
  327. if ( len_current >= len_start )
  328. {
  329. string prefix_start = current_lower;
  330. if ( current_nest == 0 )
  331. {
  332. prefix_start = current_lower.Substring( 0, len_start );
  333. }
  334. if ( prefix_start == nested_start.Get(current_nest) || prefix_start == nested_inherited_start.Get(current_nest) )
  335. {
  336. current_nest++;
  337. continue;
  338. }
  339. }
  340. }
  341. if ( current_nest >= 1 )
  342. {
  343. int len_end = nested_end.Get(current_nest - 1).Length();
  344. if ( len_current >= len_end )
  345. {
  346. string prefix_end = current_lower;
  347. if ( current_nest == 0 )
  348. {
  349. prefix_start = current_lower.Substring( 0, len_start );
  350. }
  351. if ( prefix_end == nested_end.Get(current_nest - 1) || prefix_end == nested_inherited_end.Get(current_nest - 1) )
  352. {
  353. current_nest--;
  354. }
  355. }
  356. }
  357. if ( current_nest == nested_start.Count() )
  358. {
  359. string first_char = current.Substring( 0, 1 );
  360. if ( first_char == filter_char )
  361. {
  362. int bang_pos = current.IndexOf( "!" );
  363. if ( bang_pos > -1 )
  364. {
  365. int len_last_node = last_node.Length();
  366. if ( len_current >= len_last_node )
  367. {
  368. string prefix_current = current_lower.Substring( 0, len_last_node );
  369. if ( last_node == prefix_current )
  370. {
  371. filtered.Insert( current.Substring(bang_pos + 1, current.Length() - (bang_pos + 1)) );
  372. }
  373. }
  374. }
  375. }
  376. }
  377. }
  378. TStringArray without_duplications = new TStringArray;
  379. map<string, string> lowered = new map<string, string>;
  380. for ( i = 0; i < filtered.Count(); i++ )
  381. {
  382. string c = filtered.Get( i );
  383. string lower_c = c;
  384. lower_c.ToLower();
  385. if ( without_duplications.Find(lower_c) < 0 )
  386. {
  387. without_duplications.Insert( lower_c );
  388. if ( lower_c != c )
  389. {
  390. lowered.Set( lower_c, c );
  391. }
  392. }
  393. }
  394. module_dev.SortStringArray( without_duplications );
  395. for ( i = 0; i < without_duplications.Count(); i++ )
  396. {
  397. string cc = without_duplications.Get( i );
  398. if ( lowered.Contains(cc) )
  399. {
  400. cc = lowered.Get( cc );
  401. }
  402. int tilda_index = cc.IndexOf( "~" );
  403. if ( tilda_index > -1 )
  404. {
  405. string spaces = " ";
  406. if ( cc.IndexOf( "~}" ) > -1 )
  407. {
  408. spaces = "";
  409. }
  410. cc = spaces + cc.Substring(tilda_index + 1, cc.Length() - (tilda_index + 1) );
  411. }
  412. without_duplications.Set( i, cc );
  413. }
  414. return without_duplications;
  415. }
  416. else if ( filter_char == ":" )
  417. {
  418. int cnt_config = GetGame().ConfigGetChildrenCount( class_path );
  419. for ( i = 0; i < cnt_config; i++ )
  420. {
  421. string config_name = "";
  422. GetGame().ConfigGetChildName( class_path, i, config_name );
  423. filtered.Insert( config_name );
  424. }
  425. module_dev.SortStringArray( filtered );
  426. }
  427. }
  428. else if ( filter_char == ":" )
  429. {
  430. filtered.Insert( "configfile" );
  431. filtered.Insert( "missionconfigfile" );
  432. }
  433. return filtered;
  434. }
  435. TStringArray GetConfigVariables( string class_path )
  436. {
  437. return GetConfig( class_path, "-" );
  438. }
  439. TStringArray GetConfigHierarchy( string class_path )
  440. {
  441. return GetConfig( class_path, ":" );
  442. }
  443. string GetBaseClasses(string path, string item)
  444. {
  445. string adjustedPath = path;
  446. bool run = true;
  447. TStringArray resultArr = new TStringArray();
  448. resultArr.Insert(item);
  449. while (run)
  450. {
  451. //Print("checking for path:'" + adjustedPath +"'");
  452. string baseClass = "";
  453. run = GetGame().ConfigGetBaseName( adjustedPath, baseClass );
  454. if (baseClass)
  455. {
  456. TStringArray strs = new TStringArray;
  457. adjustedPath.Split(" ",strs);
  458. strs.Remove(strs.Count() - 1);
  459. strs.Insert(baseClass);
  460. adjustedPath = string.Join(" ", strs);
  461. resultArr.Insert(baseClass);
  462. if (adjustedPath == path)
  463. break;
  464. }
  465. }
  466. string result;
  467. resultArr.Invert();
  468. foreach (int i, string str: resultArr)
  469. {
  470. if (i != 0)
  471. result += " >> " + str;
  472. else
  473. result += str;
  474. }
  475. return result;
  476. }
  477. }