y_hooks_tests.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. /*
  2. Legal:
  3. Version: MPL 1.1
  4. The contents of this file are subject to the Mozilla Public License Version
  5. 1.1 the "License"; you may not use this file except in compliance with
  6. the License. You may obtain a copy of the License at
  7. http://www.mozilla.org/MPL/
  8. Software distributed under the License is distributed on an "AS IS" basis,
  9. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  10. for the specific language governing rights and limitations under the
  11. License.
  12. The Original Code is the YSI framework.
  13. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  14. Portions created by the Initial Developer are Copyright C 2011
  15. the Initial Developer. All Rights Reserved.
  16. Contributors:
  17. Y_Less
  18. koolk
  19. JoeBullet/Google63
  20. g_aSlice/Slice
  21. Misiur
  22. samphunter
  23. tianmeta
  24. maddinat0r
  25. spacemud
  26. Crayder
  27. Dayvison
  28. Ahmad45123
  29. Zeex
  30. irinel1996
  31. Yiin-
  32. Chaprnks
  33. Konstantinos
  34. Masterchen09
  35. Southclaws
  36. PatchwerkQWER
  37. m0k1
  38. paulommu
  39. udan111
  40. Thanks:
  41. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  42. ZeeX - Very productive conversations.
  43. koolk - IsPlayerinAreaEx code.
  44. TheAlpha - Danish translation.
  45. breadfish - German translation.
  46. Fireburn - Dutch translation.
  47. yom - French translation.
  48. 50p - Polish translation.
  49. Zamaroht - Spanish translation.
  50. Los - Portuguese translation.
  51. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes for
  52. me to strive to better.
  53. Pixels^ - Running XScripters where the idea was born.
  54. Matite - Pestering me to release it and using it.
  55. Very special thanks to:
  56. Thiadmer - PAWN, whose limits continue to amaze me!
  57. Kye/Kalcor - SA:MP.
  58. SA:MP Team past, present and future - SA:MP.
  59. Optional plugins:
  60. Gamer_Z - GPS.
  61. Incognito - Streamer.
  62. Me - sscanf2, fixes2, Whirlpool.
  63. */
  64. static
  65. YSI_g_sValue;
  66. #if !defined CHAIN_ORDER
  67. #define CHAIN_ORDER() 0
  68. #endif
  69. CHAIN_HOOK(TestPrehook)
  70. #undef CHAIN_ORDER
  71. #define CHAIN_ORDER CHAIN_NEXT(TestPrehook)
  72. forward OnTestPrehook();
  73. public OnTestPrehook()
  74. {
  75. YSI_g_sValue = 89;
  76. TestPrehook_OnTestPrehook();
  77. }
  78. CHAIN_FORWARD:TestPrehook_OnTestPrehook() = 1;
  79. #define OnTestPrehook(%0) CHAIN_PUBLIC:TestPrehook_OnTestPrehook(%0)
  80. HOOK__ OnTestPrehook()
  81. {
  82. ++YSI_g_sValue;
  83. }
  84. TEST__ y_hooksPrehook()
  85. {
  86. YSI_g_sValue = 91;
  87. CallLocalFunction("OnTestPrehook", "");
  88. ASSERT_EQ(YSI_g_sValue, 90);
  89. }
  90. forward OnTestCallback();
  91. public OnTestCallback()
  92. {
  93. YSI_g_sValue = 89;
  94. // TestPrehook_OnTestCallback();
  95. }
  96. CHAIN_FORWARD:TestPrehook_OnTestCallback() = 1;
  97. #define OnTestCallback(%0) CHAIN_PUBLIC:TestPrehook_OnTestCallback(%0)
  98. HOOK__ OnTestCallback()
  99. {
  100. ++YSI_g_sValue;
  101. }
  102. TEST__ y_hooksOrdering()
  103. {
  104. YSI_g_sValue = 91;
  105. CallLocalFunction("OnTestCallback", "");
  106. ASSERT_EQ(YSI_g_sValue, 89);
  107. }
  108. static
  109. bool:y_hooks_OnScriptInit_called = false;
  110. HOOK__ OnScriptInit()
  111. {
  112. y_hooks_OnScriptInit_called = true;
  113. }
  114. TEST__ OnScriptInit()
  115. {
  116. ASSERT(y_hooks_OnScriptInit_called);
  117. }
  118. static
  119. bool:y_hooks_OnCodeInit_called = false;
  120. public OnCodeInit()
  121. {
  122. y_hooks_OnCodeInit_called = true;
  123. #if defined HooksTest_OnCodeInit
  124. HooksTest_OnCodeInit();
  125. #endif
  126. return 1;
  127. }
  128. #undef OnCodeInit
  129. #define OnCodeInit HooksTest_OnCodeInit
  130. #if defined HooksTest_OnCodeInit
  131. forward HooksTest_OnCodeInit();
  132. #endif
  133. TEST__ OnCodeInit()
  134. {
  135. ASSERT(y_hooks_OnCodeInit_called);
  136. }
  137. #if defined YSI_FAILING_TESTS
  138. DEFINE_HOOK_REPLACEMENT__(VeryLongTarget_, YyYy);
  139. HOOK__ y_hooks_YyYy0()
  140. {
  141. // The length after replacement here will be longer than the hook name,
  142. // even with prefix/suffixes. This means you can't generate the
  143. // original name because there is no original.
  144. ASSERT(true);
  145. YSI_g_sValue = 101;
  146. }
  147. HOOK__ y_hooks_YyYy1()
  148. {
  149. // The length after replacement here will be longer than the hook name,
  150. // even with prefix/suffixes. This means you can't generate the
  151. // original name because there is no original.
  152. ASSERT(true);
  153. YSI_g_sValue = 202;
  154. }
  155. HOOK__ y_hooks_YyYz1()
  156. {
  157. // Will come very next in the header.
  158. ASSERT(true);
  159. YSI_g_sValue = 303;
  160. }
  161. forward y_hooks_VeryLongTarget_0();
  162. public y_hooks_VeryLongTarget_0()
  163. {
  164. // This one should work, because we have the original function to use
  165. // for a pointer, not a newly generated version.
  166. ASSERT_EQ(YSI_g_sValue, 101);
  167. YSI_g_sValue += 404;
  168. }
  169. TEST__ y_hooks_TooLongReplacements()
  170. {
  171. YSI_g_sValue = 0;
  172. CallLocalFunction("y_hooks_VeryLongTarget_0", "");
  173. ASSERT_EQ(YSI_g_sValue, 505);
  174. YSI_g_sValue = 0;
  175. CallLocalFunction("y_hooks_YyYz1", "");
  176. ASSERT_EQ(YSI_g_sValue, 303);
  177. YSI_g_sValue = 0;
  178. // Currently fails.
  179. CallLocalFunction("y_hooks_VeryLongTarget_1", "");
  180. ASSERT_EQ(YSI_g_sValue, 202);
  181. }
  182. #endif
  183. HOOK__ Ony_hooksShortUpdate()
  184. {
  185. ++YSI_g_sValue;
  186. }
  187. HOOK__ Ony_hooksShortUpd()
  188. {
  189. ++YSI_g_sValue;
  190. }
  191. TEST__ Ony_hooksShortUpdate()
  192. {
  193. YSI_g_sValue = 0;
  194. CallLocalFunction("Ony_hooksShortUpdate", "");
  195. ASSERT_EQ(YSI_g_sValue, 2);
  196. }
  197. #if defined YSI_FAILING_TESTS
  198. DEFINE_HOOK_REPLACEMENT__(TTTTT_YYYYY, YHook);
  199. forward Ony_hooksTTTTT_YYYYY_WtExtras();
  200. HOOK__ Ony_hooksYHook()
  201. {
  202. ++YSI_g_sValue;
  203. }
  204. HOOK__ Ony_hooksTTTTT_YYYYY()
  205. {
  206. ++YSI_g_sValue;
  207. }
  208. TEST__ y_hooksReplacement2()
  209. {
  210. YSI_g_sValue = 0;
  211. CallLocalFunction("Ony_hooksTTTTT_YYYYY", "");
  212. ASSERT_EQ(YSI_g_sValue, 2);
  213. }
  214. public Ony_hooksTTTTT_YYYYY_WtExtras()
  215. {
  216. ++YSI_g_sValue;
  217. }
  218. HOOK__ Ony_hooksYHook_WtExtras()
  219. {
  220. ++YSI_g_sValue;
  221. }
  222. TEST__ y_hooksReplacement3()
  223. {
  224. YSI_g_sValue = 0;
  225. CallLocalFunction("Ony_hooksTTTTT_YYYYY_WtExtras", "");
  226. ASSERT_EQ(YSI_g_sValue, 2);
  227. }
  228. #endif
  229. forward Ony_hooksTest2(cmd[]);
  230. HOOK__ Ony_hooksTest2@000(cmd[])
  231. {
  232. ++YSI_g_sValue;
  233. return 1;
  234. }
  235. HOOK__ Ony_hooksTest2@001(cmd[])
  236. {
  237. // Called second due to forced orderings.
  238. ++YSI_g_sValue;
  239. return 1;
  240. }
  241. public Ony_hooksTest2(cmd[])
  242. {
  243. // Called second due to forced orderings.
  244. //if (YSI_g_sValue) return YSI_g_sValue - 7;
  245. ASSERT_SAME(cmd, "IGNORE_ME");
  246. return 1;
  247. }
  248. TEST__ y_hooks_Ony_hooksTest2()
  249. {
  250. // Check both hooks are called.
  251. YSI_g_sValue = 0;
  252. ASSERT_NZ(CallLocalFunction("Ony_hooksTest2", "s", "IGNORE_ME"));
  253. ASSERT_EQ(YSI_g_sValue, 2);
  254. YSI_g_sValue = 0;
  255. }
  256. forward y_hooks_PassParams(i1, a0[], i2);
  257. public y_hooks_PassParams(i1, a0[], i2)
  258. {
  259. ASSERT_EQ(i1, 42);
  260. ASSERT_SAME(a0, "Hello world");
  261. ASSERT_EQ(i2, 101);
  262. }
  263. HOOK__ y_hooks_PassParams@3(i1, a0[], i2)
  264. {
  265. ASSERT_EQ(i1, 42);
  266. ASSERT_SAME(a0, "Hello world");
  267. ASSERT_EQ(i2, 101);
  268. }
  269. HOOK__ y_hooks_PassParams@2(i1, a0[], i2)
  270. {
  271. ASSERT_EQ(i1, 42);
  272. ASSERT_SAME(a0, "Hello world");
  273. ASSERT_EQ(i2, 101);
  274. }
  275. HOOK__ y_hooks_PassParams@1(i1, a0[], i2)
  276. {
  277. ASSERT_EQ(i1, 42);
  278. ASSERT_SAME(a0, "Hello world");
  279. ASSERT_EQ(i2, 101);
  280. }
  281. HOOK__ y_hooks_PassParams(i1, a0[], i2)
  282. {
  283. ASSERT_EQ(i1, 42);
  284. ASSERT_SAME(a0, "Hello world");
  285. ASSERT_EQ(i2, 101);
  286. }
  287. TEST__ y_hooks_PassParams()
  288. {
  289. CallLocalFunction("y_hooks_PassParams", "isi", 42, "Hello world", 101);
  290. }
  291. forward y_hooks_ReturnM2();
  292. public y_hooks_ReturnM2()
  293. {
  294. YSI_g_sValue = 8;
  295. return -2;
  296. }
  297. HOOK__ y_hooks_ReturnM2()
  298. {
  299. YSI_g_sValue = 4;
  300. return -2;
  301. }
  302. TEST__ y_hooks_ReturnM2()
  303. {
  304. YSI_g_sValue = 0;
  305. ASSERT_EQ(CallLocalFunction("y_hooks_ReturnM2", ""), 1);
  306. ASSERT_EQ(YSI_g_sValue, 4);
  307. }
  308. forward y_hooks_ReturnM1();
  309. public y_hooks_ReturnM1()
  310. {
  311. YSI_g_sValue = 8;
  312. return -1;
  313. }
  314. HOOK__ y_hooks_ReturnM1()
  315. {
  316. YSI_g_sValue = 4;
  317. return -1;
  318. }
  319. TEST__ y_hooks_ReturnM1()
  320. {
  321. YSI_g_sValue = 0;
  322. ASSERT_ZE(CallLocalFunction("y_hooks_ReturnM1", ""));
  323. ASSERT_EQ(YSI_g_sValue, 4);
  324. }
  325. forward y_hooks_Return0();
  326. public y_hooks_Return0()
  327. {
  328. YSI_g_sValue = 8;
  329. return 0;
  330. }
  331. HOOK__ y_hooks_Return0()
  332. {
  333. YSI_g_sValue = 4;
  334. return 0;
  335. }
  336. TEST__ y_hooks_Return0()
  337. {
  338. YSI_g_sValue = 0;
  339. ASSERT_ZE(CallLocalFunction("y_hooks_Return0", ""));
  340. ASSERT_EQ(YSI_g_sValue, 8);
  341. }
  342. forward y_hooks_Return1();
  343. public y_hooks_Return1()
  344. {
  345. YSI_g_sValue = 8;
  346. return 1;
  347. }
  348. HOOK__ y_hooks_Return1()
  349. {
  350. YSI_g_sValue = 4;
  351. return 1;
  352. }
  353. TEST__ y_hooks_Return1()
  354. {
  355. YSI_g_sValue = 0;
  356. ASSERT_EQ(CallLocalFunction("y_hooks_Return1", ""), 1);
  357. ASSERT_EQ(YSI_g_sValue, 8);
  358. }
  359. forward Ony_hooksTest3(cmd[]);
  360. HOOK__ Ony_hooksTest3@000(cmd[])
  361. {
  362. ++YSI_g_sValue;
  363. //printf("a");
  364. return 1;
  365. }
  366. HOOK__ Ony_hooksTest3@001(cmd[])
  367. {
  368. // Called second due to forced orderings.
  369. ++YSI_g_sValue;
  370. //printf("b");
  371. return 1;
  372. }
  373. TEST__ y_hooks_Ony_hooksTest3()
  374. {
  375. // Check both hooks are called.
  376. YSI_g_sValue = 0;
  377. ASSERT_NZ(CallLocalFunction("Ony_hooksTest3", "s", "IGNORE_ME"));
  378. ASSERT_EQ(YSI_g_sValue, 2);
  379. YSI_g_sValue = 0;
  380. }
  381. forward Ony_hooksTest1(cmd[]);
  382. HOOK__ Ony_hooksTest1@000(cmd[])
  383. {
  384. ++YSI_g_sValue;
  385. return 1;
  386. }
  387. HOOK__ Ony_hooksTest1@001(cmd[])
  388. {
  389. // Called second due to forced orderings.
  390. ++YSI_g_sValue;
  391. return 0;
  392. }
  393. TEST__ y_hooks_Ony_hooksTest1()
  394. {
  395. // Check both hooks are called.
  396. YSI_g_sValue = 0;
  397. ASSERT_ZE(CallLocalFunction("Ony_hooksTest1", "s", "IGNORE_ME"));
  398. ASSERT_EQ(YSI_g_sValue, 2);
  399. YSI_g_sValue = 0;
  400. }
  401. forward Ony_hooksTest4(cmd[]);
  402. HOOK__ Ony_hooksTest4@000(cmd[])
  403. {
  404. ++YSI_g_sValue;
  405. return -1;
  406. }
  407. HOOK__ Ony_hooksTest4@001(cmd[])
  408. {
  409. // Called second due to forced orderings.
  410. ++YSI_g_sValue;
  411. return 0;
  412. }
  413. TEST__ y_hooks_Ony_hooksTest4()
  414. {
  415. // Check only one hook is called.
  416. YSI_g_sValue = 0;
  417. ASSERT_ZE(CallLocalFunction("Ony_hooksTest4", "s", "IGNORE_ME"));
  418. ASSERT_EQ(YSI_g_sValue, 1);
  419. YSI_g_sValue = 0;
  420. }
  421. forward Ony_hooksTest5(cmd[]);
  422. HOOK__ Ony_hooksTest5@000(cmd[])
  423. {
  424. ++YSI_g_sValue;
  425. return -2;
  426. }
  427. HOOK__ Ony_hooksTest5@001(cmd[])
  428. {
  429. // Called second due to forced orderings.
  430. ++YSI_g_sValue;
  431. return 0;
  432. }
  433. TEST__ y_hooks_Ony_hooksTest5()
  434. {
  435. // Check only one hook is called.
  436. YSI_g_sValue = 0;
  437. ASSERT_EQ(CallLocalFunction("Ony_hooksTest5", "s", "IGNORE_ME"), 1);
  438. ASSERT_EQ(YSI_g_sValue, 1);
  439. YSI_g_sValue = 0;
  440. }
  441. static stock y_hooks_funcidx2(const str[])
  442. {
  443. new
  444. func[32],
  445. buf,
  446. idx;
  447. while ((idx = AMX_GetPublicName(idx, func, str)))
  448. {
  449. if (!strcmp(func, str))
  450. {
  451. AMX_GetPublicEntry(idx - 1, buf);
  452. return buf;
  453. }
  454. }
  455. return -1;
  456. }
  457. forward y_hooks_Invalidate1();
  458. public y_hooks_Invalidate1() {}
  459. TEST__ y_hooks_Invalidate1()
  460. {
  461. ASSERT_NE(funcidx("y_hooks_Invalidate1"), -1);
  462. Hooks_InvalidateName(y_hooks_funcidx2("y_hooks_Invalidate1"));
  463. Hooks_SortPublics();
  464. ASSERT_EQ(funcidx("y_hooks_Invalidate1"), -1);
  465. }
  466. forward y_hooks_Invalidate2();
  467. public y_hooks_Invalidate2() {}
  468. forward y_hooks_Invalidate3();
  469. public y_hooks_Invalidate3() {}
  470. TEST__ y_hooks_Invalidate23()
  471. {
  472. new
  473. base0,
  474. count0;
  475. AMX_GetBaseCount(AMX_TABLE_PUBLICS, base0, count0);
  476. ASSERT_NE(funcidx("y_hooks_Invalidate2"), -1);
  477. ASSERT_NE(funcidx("y_hooks_Invalidate3"), -1);
  478. Hooks_InvalidateName(y_hooks_funcidx2("y_hooks_Invalidate2"));
  479. Hooks_InvalidateName(y_hooks_funcidx2("y_hooks_Invalidate3"));
  480. Hooks_SortPublics();
  481. ASSERT_EQ(funcidx("y_hooks_Invalidate2"), -1);
  482. ASSERT_EQ(funcidx("y_hooks_Invalidate3"), -1);
  483. new
  484. base1,
  485. count1;
  486. AMX_GetBaseCount(AMX_TABLE_PUBLICS, base1, count1);
  487. ASSERT(base1 > base0);
  488. ASSERT(count1 < count0);
  489. }
  490. TEST__ y_hooks_IsolateName1()
  491. {
  492. new
  493. name[32];
  494. name = "@yH_Hello@Other";
  495. Hooks_IsolateName(name);
  496. ASSERT_FALSE(strcmp(name, "Hello"));
  497. name = "@yH_Hi@@Other";
  498. Hooks_IsolateName(name);
  499. ASSERT_FALSE(strcmp(name, "Hi"));
  500. name = "@yH_No@Other@More";
  501. Hooks_IsolateName(name);
  502. ASSERT_FALSE(strcmp(name, "No"));
  503. name = "@yH_Yes_Other@N";
  504. Hooks_IsolateName(name);
  505. ASSERT_FALSE(strcmp(name, "Yes_Other"));
  506. }
  507. TEST__ y_hooks_IsolateName2()
  508. {
  509. new
  510. func[32];
  511. #define FUNC:%0; func = "_yH@"#%0"@";Hooks_IsolateName(func);ASSERT(!strcmp(func, #%0));
  512. FUNC:A;
  513. FUNC:AAA;
  514. FUNC:AAB;
  515. FUNC:ABA;
  516. FUNC:ABB;
  517. FUNC:aB;
  518. FUNC:ab;
  519. FUNC:Ab;
  520. #undef FUNC
  521. }
  522. static g_y_hooksVar;
  523. TEST__ y_hooks_Customs()
  524. {
  525. g_y_hooksVar = 0;
  526. CallLocalFunction("y_hooks_MyFunc1", "ii", 4, 5);
  527. ASSERT_EQ(g_y_hooksVar, (4 + 5) * 6);
  528. }
  529. forward y_hooks_MyFunc1(a, b);
  530. public y_hooks_MyFunc1(a, b)
  531. {
  532. // printf("Part 1 %d %d", a, b);
  533. g_y_hooksVar += a + b;
  534. }
  535. #tryinclude "..\YSI_Coding\y_unique"
  536. #tryinclude "..\..\YSI_Coding\y_unique"
  537. HOOK__ y_hooks_MyFunc1(a, b)
  538. {
  539. // printf("Part 2 %d", a);
  540. g_y_hooksVar += a + b;
  541. }
  542. #tryinclude "..\YSI_Coding\y_unique"
  543. #tryinclude "..\..\YSI_Coding\y_unique"
  544. HOOK__ y_hooks_MyFunc1(a, b)
  545. {
  546. // printf("Part 3 %d", b);
  547. g_y_hooksVar += a + b;
  548. }
  549. #tryinclude "..\YSI_Coding\y_unique"
  550. #tryinclude "..\..\YSI_Coding\y_unique"
  551. HOOK__ y_hooks_MyFunc1(a, b)
  552. {
  553. // printf("Part 3 %d", b);
  554. g_y_hooksVar += a + b;
  555. }
  556. #tryinclude "..\YSI_Coding\y_unique"
  557. #tryinclude "..\..\YSI_Coding\y_unique"
  558. HOOK__ y_hooks_MyFunc1(a, b)
  559. {
  560. // printf("Part 3 %d", b);
  561. g_y_hooksVar += a + b;
  562. }
  563. #tryinclude "..\YSI_Coding\y_unique"
  564. #tryinclude "..\..\YSI_Coding\y_unique"
  565. HOOK__ y_hooks_MyFunc1(a, b)
  566. {
  567. // printf("Part 3 %d", b);
  568. g_y_hooksVar += a + b;
  569. }
  570. forward OnPlayerEnterDynamicArea(p, a);
  571. public OnPlayerEnterDynamicArea(p, a) { g_y_hooksVar += 100; }
  572. HOOK__ OnPlayerEnterDynArea(p, a) { g_y_hooksVar += 10; }
  573. TEST__ y_hooks_SpecialCases()
  574. {
  575. g_y_hooksVar = 0;
  576. CallLocalFunction("OnPlayerEnterDynamicArea", "ii", 0, 0);
  577. ASSERT_EQ(g_y_hooksVar, 110);
  578. }
  579. TEST__ Hooks_MakeLongName0()
  580. {
  581. new
  582. name[64];
  583. name = "OnUpd";
  584. ASSERT_EQ(Hooks_MakeLongName(name), 8);
  585. ASSERT_SAME(name, "OnUpdate");
  586. name = "OnUpdD";
  587. ASSERT_EQ(Hooks_MakeLongName(name), 9);
  588. ASSERT_SAME(name, "OnUpdateD");
  589. name = "OnUpda";
  590. ASSERT_EQ(Hooks_MakeLongName(name), 6);
  591. ASSERT_SAME(name, "OnUpda");
  592. }
  593. TEST__ Hooks_MakeLongName1()
  594. {
  595. new
  596. name[64];
  597. name = "CP";
  598. ASSERT_EQ(Hooks_MakeLongName(name), 10);
  599. ASSERT_SAME(name, "Checkpoint");
  600. name = "TD";
  601. ASSERT_EQ(Hooks_MakeLongName(name), 8);
  602. ASSERT_SAME(name, "TextDraw");
  603. name = "Upd";
  604. ASSERT_EQ(Hooks_MakeLongName(name), 6);
  605. ASSERT_SAME(name, "Update");
  606. name = "Dyn";
  607. ASSERT_EQ(Hooks_MakeLongName(name), 7);
  608. ASSERT_SAME(name, "Dynamic");
  609. name = "Obj";
  610. ASSERT_EQ(Hooks_MakeLongName(name), 6);
  611. ASSERT_SAME(name, "Object");
  612. name = "Cmd";
  613. ASSERT_EQ(Hooks_MakeLongName(name), 7);
  614. ASSERT_SAME(name, "Command");
  615. name = "DynamicCP";
  616. ASSERT_EQ(Hooks_MakeLongName(name), 9);
  617. ASSERT_SAME(name, "DynamicCP");
  618. }
  619. TEST__ Hooks_MakeLongName2()
  620. {
  621. new
  622. name[64];
  623. name = "OnUpdTDCP";
  624. ASSERT_EQ(Hooks_MakeLongName(name), 26);
  625. ASSERT_SAME(name, "OnUpdateTextDrawCheckpoint");
  626. name = "OnUpdTDObjCmd";
  627. ASSERT_EQ(Hooks_MakeLongName(name), 29);
  628. ASSERT_SAME(name, "OnUpdateTextDrawObjectCommand");
  629. name = "OnUpdTDCPObjCmd";
  630. ASSERT_EQ(Hooks_MakeLongName(name), 31);
  631. ASSERT_SAME(name, "OnUpdateTextDrawCPObjectCommand");
  632. }
  633. TEST__ Hooks_MakeShortName1()
  634. {
  635. new
  636. name[64];
  637. name = "OnPlayerEnterRaceCP";
  638. ASSERT_EQ(Hooks_MakeShortName(name), 19);
  639. ASSERT_SAME(name, "OnPlayerEnterRaceCP");
  640. name = "OnPlayerEnterRaceCheckpoint";
  641. ASSERT_EQ(Hooks_MakeShortName(name), 27);
  642. ASSERT_SAME(name, "OnPlayerEnterRaceCheckpoint");
  643. name = "OnPlayerEnterDynamicCP";
  644. ASSERT_EQ(Hooks_MakeShortName(name), 22);
  645. ASSERT_SAME(name, "OnPlayerEnterDynamicCP");
  646. name = "OnPlayerEnterDynamicRaceCheckpoint";
  647. ASSERT_EQ(Hooks_MakeShortName(name), 26);
  648. ASSERT_SAME(name, "OnPlayerEnterDynamicRaceCP");
  649. name = "AAAAAAAAAAAAAAAAAAAUpdateTextDraw";
  650. Hooks_MakeShortName(name);
  651. ASSERT_SAME(name, "AAAAAAAAAAAAAAAAAAAUpdateTD");
  652. name = "BBBBBAAAAAAAAAAAAAAAAAAAUpdateTextDraw";
  653. Hooks_MakeShortName(name);
  654. ASSERT_SAME(name, "BBBBBAAAAAAAAAAAAAAAAAAAUpdTD");
  655. }
  656. TEST__ Hooks_MakeShortName2()
  657. {
  658. new
  659. name[64];
  660. name = "AAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCC";
  661. ASSERT_EQ(Hooks_MakeShortName(name), 43);
  662. ASSERT_SAME(name, "AAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCC");
  663. name = "AAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCommandCCCC";
  664. ASSERT_EQ(Hooks_MakeShortName(name), 45);
  665. ASSERT_SAME(name, "AAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCmdCCCC");
  666. }
  667. TEST__ Hooks_GetDefaultReturn()
  668. {
  669. ASSERT_EQ(Hooks_GetDefaultReturn("OnHookRet\0\0\0\0\0\0\0\0"), 1);
  670. ASSERT_ZE(Hooks_GetDefaultReturn("OnPlayerCommandText\0\0\0\0\0\0\0\0"));
  671. ASSERT_ZE(Hooks_GetDefaultReturn("OnHookRet2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"));
  672. ASSERT_EQ(Hooks_GetDefaultReturn("OnPlayerConnect\0\0\0\0\0\0\0\0"), 1);
  673. }
  674. DEFINE_HOOK_RETURN__(OnHookRet2, 0);
  675. DEFINE_HOOK_REPLACEMENT__(Replacement, Rpl);
  676. forward OnPlayerCustomReplacement();
  677. public OnPlayerCustomReplacement() { g_y_hooksVar += 500; }
  678. HOOK__ OnPlayerCustomRpl() { g_y_hooksVar += 55; }
  679. TEST__ y_hooks_CustomReplacement()
  680. {
  681. g_y_hooksVar = 0;
  682. CallLocalFunction("OnPlayerCustomReplacement", "");
  683. ASSERT_EQ(g_y_hooksVar, 555);
  684. }
  685. #if !defined BAD_numargs
  686. #error y_hooks tests require BAD_numargs
  687. #endif
  688. HOOK__ OnTestNumArgs0(a, b, c, d, e, f)
  689. {
  690. ASSERT_EQ(Hooks_NumArgs(), 6);
  691. ASSERT_EQ(numargs(), 6);
  692. }
  693. HOOK__ OnTestNumArgs1(a, b, c, d, f)
  694. {
  695. ASSERT_EQ(Hooks_NumArgs(), 5);
  696. ASSERT_NE(BAD_numargs(), 5);
  697. ASSERT_EQ(numargs(), 5);
  698. }
  699. forward OnTestNumArgs1(a, b, c, d, f);
  700. public OnTestNumArgs1(a, b, c, d, f)
  701. {
  702. ASSERT_EQ(Hooks_NumArgs(), 5);
  703. ASSERT_NE(BAD_numargs(), 5);
  704. ASSERT_EQ(numargs(), 5);
  705. }
  706. HOOK__ OnTestNumArgs2(a, b, c, f)
  707. {
  708. ASSERT_EQ(Hooks_NumArgs(), 4);
  709. ASSERT_NE(BAD_numargs(), 4);
  710. ASSERT_EQ(numargs(), 4);
  711. }
  712. #tryinclude "..\YSI_Coding\y_unique"
  713. #tryinclude "..\..\YSI_Coding\y_unique"
  714. HOOK__ OnTestNumArgs2(a, b, c, f)
  715. {
  716. ASSERT_EQ(Hooks_NumArgs(), 4);
  717. ASSERT_NE(BAD_numargs(), 4);
  718. ASSERT_EQ(numargs(), 4);
  719. }
  720. forward OnTestNumArgs2(a, b, c, f);
  721. public OnTestNumArgs2(a, b, c, f)
  722. {
  723. ASSERT_EQ(Hooks_NumArgs(), 4);
  724. ASSERT_NE(BAD_numargs(), 4);
  725. ASSERT_EQ(numargs(), 4);
  726. }
  727. static OnTestNumArgs4(total, ...)
  728. {
  729. ASSERT_EQ(numargs(), total + 1);
  730. }
  731. TEST__ y_hooks_numargs()
  732. {
  733. CallLocalFunction("OnTestNumArgs0", "iiiiii", 0, 0, 0, 0, 0, 0);
  734. CallLocalFunction("OnTestNumArgs1", "iiiii", 0, 0, 0, 0, 0);
  735. CallLocalFunction("OnTestNumArgs2", "iiii", 0, 0, 0, 0);
  736. OnTestNumArgs4(0);
  737. OnTestNumArgs4(1, 1);
  738. OnTestNumArgs4(2, 1, 2);
  739. OnTestNumArgs4(3, 1, 2, 3);
  740. OnTestNumArgs4(4, 1, 2, 3, 4);
  741. OnTestNumArgs4(5, 1, 2, 3, 4, 5);
  742. OnTestNumArgs4(6, 1, 2, 3, 4, 5, 6);
  743. }
  744. HOOK__ y_hooks_State1(string:c[]) <y_hooks_state : y_hooks_state_1>
  745. {
  746. g_y_hooksVar = strval(c[0]);
  747. }
  748. HOOK__ y_hooks_State1(string:c[]) <y_hooks_state : y_hooks_state_2>
  749. {
  750. g_y_hooksVar = strval(c[5]);
  751. }
  752. REHOOK__ y_hooks_State1(string:c[]) <y_hooks_state : y_hooks_state_3>
  753. {
  754. g_y_hooksVar += strval(c[5]);
  755. }
  756. //HOOK__ public y_hooks_State1(string:c[]) <y_hooks_state : y_hooks_state_4>
  757. hook y_hooks_State1(string:c[]) <y_hooks_state : y_hooks_state_4>
  758. {
  759. g_y_hooksVar = strval(c[5]);
  760. }
  761. TEST__ y_hooks_State1()
  762. {
  763. state y_hooks_state : y_hooks_state_1;
  764. CallLocalFunction("y_hooks_State1", "s", "1000 2000");
  765. ASSERT_EQ(g_y_hooksVar, 1000);
  766. state y_hooks_state : y_hooks_state_2;
  767. CallLocalFunction("y_hooks_State1", "s", "1000 2000");
  768. ASSERT_EQ(g_y_hooksVar, 2000);
  769. state y_hooks_state : y_hooks_state_1;
  770. CallLocalFunction("y_hooks_State1", "s", "1000 2000");
  771. state y_hooks_state : y_hooks_state_3;
  772. CallLocalFunction("y_hooks_State1", "s", "1000 2000");
  773. ASSERT_EQ(g_y_hooksVar, 3000);
  774. }
  775. static stock y_hooks_CrashTrigger()
  776. {
  777. #emit HALT 1
  778. }
  779. HOOK__ y_hooks_Crash@1()
  780. {
  781. }
  782. HOOK__ y_hooks_Crash@2()
  783. {
  784. }
  785. HOOK__ y_hooks_Crash@3()
  786. {
  787. y_hooks_CrashTrigger();
  788. }
  789. HOOK__ y_hooks_Crash@4()
  790. {
  791. }
  792. TEST__ y_hooks_Crash()
  793. {
  794. CallLocalFunction("y_hooks_Crash", "");
  795. Testing_SurpressOneFail();
  796. }