pass.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. #define _BSD_SOURCE /* for unistd.h */
  2. #ifdef _WIN32
  3. # include <Windows.h>
  4. # include <curses.h>
  5. # define SLEEP(delay) Sleep(delay/1000)
  6. // Unix builds require ncurses.h for the Ncurses library.
  7. // Unix also requires unistd.h for usleep(microseconds).
  8. // usleep/1000 = Sleep
  9. #else
  10. # include <ncurses.h>
  11. # include <unistd.h>
  12. # define SLEEP(delay) usleep(delay)
  13. #endif
  14. #include <time.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "pass.h"
  18. #include "print.h"
  19. #include "wordParse.h"
  20. #include "intro.h"
  21. #define OFFSET_LEFT 0
  22. #define OFFSET_RIGHT 20
  23. #define BIGSTRING_SIZE 408
  24. static int currentCharContains(char arr[],char c){
  25. int i;
  26. for(i=0; i<12; i++)
  27. if(arr[i]==c)
  28. return 1;
  29. return 0;
  30. }
  31. static int getCharLoc(int y, int x){
  32. /* Left side */
  33. if(x<19)
  34. return 12*(y-5)+(x-7);
  35. /* Right side */
  36. else
  37. return 12*(y-5)+(x-27+204);
  38. }
  39. void pass(){
  40. /* Start a new screen where nodelay is false */
  41. erase();
  42. endwin();
  43. initscr();
  44. noecho();
  45. refresh();
  46. attron(A_BOLD);
  47. nodelay(stdscr, 0);
  48. if(has_colors() == 1){
  49. // Colors
  50. start_color();
  51. init_pair(1,COLOR_GREEN,COLOR_BLACK);
  52. attron(COLOR_PAIR(1));
  53. }
  54. /* Intro text */
  55. char prompt[] = "ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL";
  56. passPrint(prompt,strlen(prompt),0);
  57. char prompt2[] = "ENTER PASSWORD NOW";
  58. passPrint(prompt2, strlen(prompt2), 1);
  59. char prompt3[] = "4 ATTEMPT(S) LEFT: * * * *";
  60. passPrint(prompt3, strlen(prompt3), 3);
  61. /* Generate the hex values on the left sides */
  62. int arbHex;
  63. arbHex = (rand() % 200) + 63744;
  64. /* Generate the string to hold the bracket tricks and words */
  65. char bigString [BIGSTRING_SIZE];
  66. char randValues[] = "!@#$%^*()_-=+\\|/[]{}?\"\':;,.<>";
  67. int i;
  68. for(i=0; i<BIGSTRING_SIZE; i++){
  69. /* Fill bigString with random values */
  70. bigString[i] = randValues[rand()%29];
  71. }
  72. char ** wordArr = getWordArr();
  73. int WORD_POOL_SIZE = getNumWords();
  74. int WORD_SIZE = getWordLength();
  75. int WORDS_CHOSEN = getWordsToChoose();
  76. /* Place a word in the string total times, making sure it doesn't
  77. overwrite another word or get placed right next to it */
  78. int place; /* Current place for checking and word insertion*/
  79. int takenWords[WORDS_CHOSEN]; /* Words already placed in bigString */
  80. for(int i=0; i<WORDS_CHOSEN; i++)
  81. takenWords[i] = 0;
  82. int valid; /* 1 if selected word is not already used and
  83. does not conflict with other words, 0 otherwise */
  84. int pickedWord = 0; /* Indicate whether or not we've chosen the correct word */
  85. int left = WORDS_CHOSEN; /* # of words that still need to be chosen */
  86. char correctWord[WORD_SIZE]; /* the correct word */
  87. while(left>0){
  88. valid = 1;
  89. /* Choose a random place in bigString */
  90. place = rand()%(BIGSTRING_SIZE-WORD_SIZE);
  91. /* Check of any characters there or around it are A-Z */
  92. for(i=place-1; i<place+WORD_SIZE+1; i++){
  93. if(bigString[i] > 64 && bigString[i] < 91){
  94. valid = 0;
  95. break;
  96. }
  97. }
  98. if(valid){
  99. int wordLoc = rand()%WORD_POOL_SIZE;
  100. if(takenWords[wordLoc])
  101. valid=0;
  102. if(valid){
  103. takenWords[wordLoc] = 1;
  104. /* Add the word to bigString */
  105. for(i=place; i<place+WORD_SIZE; i++){
  106. bigString[i] = *(*(wordArr+wordLoc)+(i-place));
  107. /* If this is the first word chosen, it is the correct word. */
  108. if(!pickedWord)
  109. correctWord[i-place] = *(*(wordArr+wordLoc)+(i-place));
  110. }
  111. pickedWord = 1;
  112. left--;
  113. }
  114. }
  115. }
  116. /* Create and fill an array to keep track of which brackets were used */
  117. int usedBrackets[BIGSTRING_SIZE];
  118. for(i=0; i<BIGSTRING_SIZE; i++){
  119. usedBrackets[i] = 1;
  120. }
  121. /* Print the hex and the filled bigString */
  122. char temp[12];
  123. int current = 0;
  124. for(i=5; i<22; i++){
  125. /* Print left side */
  126. for(int j=0; j<12; j++){
  127. temp[j] = bigString[j+current];
  128. }
  129. printChoices(arbHex,temp,i, OFFSET_LEFT);
  130. current = current + 12;
  131. arbHex = arbHex + 12;
  132. }
  133. for(i=5; i<22; i++){
  134. /* Print right side */
  135. for(int j=0; j<12; j++){
  136. temp[j] = bigString[j+current];
  137. }
  138. printChoices(arbHex,temp,i, OFFSET_RIGHT);
  139. current = current + 12;
  140. arbHex = arbHex + 12;
  141. }
  142. mvprintw(21,40,"%c",'>');
  143. move(5,7);
  144. char currentChar[12]; /* Max length currentChar could be (total possible length of a bracket trick) */
  145. currentChar[0] = (char)mvinch(5,7);
  146. // TODO Clear any key presses that may have occurred during this loading sequence
  147. int y,x,origy,origx,starty,startx; /* values that keep track of current yx locations, and original ones */
  148. int wordLength; /* How long a word is */
  149. int charStart; /* where character counting starts for brackets */
  150. char keyPress; /* key pressed by user */
  151. int charCounter; /* counts currentChar - used for incrementing currentChar to print or change it */
  152. int bracketLength; /* length of a bracket trick */
  153. char endBracket; /* the end bracket that corresponds to currentChar[0]; */
  154. int bracketTricks=0; /* Total number of bracket tricks used */
  155. int needsClearing = 0; /* Whether or not highlights need to be purged */
  156. int needsClearingMultiLine = 0; /* Whether or not a multi line highlight needs to be purged */
  157. char output[12]; /* Used for side terminal output */
  158. int allowances = 4;
  159. while(1){
  160. getyx(stdscr,y,x);
  161. /* Get allowances left */
  162. mvprintw(1,0," ");
  163. mvprintw(3,0," ");
  164. switch(allowances){
  165. case 1: mvprintw(3,0,"1 ATTEMPT(S) LEFT: *");
  166. attron(A_BLINK);
  167. mvprintw(1,0,"!!! WARNING: LOCKOUT IMNINENT !!!");
  168. attroff(A_BLINK);
  169. attron(A_BOLD);
  170. break;
  171. case 2: mvprintw(3,0,"2 ATTEMPT(S) LEFT: * *");
  172. mvprintw(1,0,"ENTER PASSWORD NOW");
  173. break;
  174. case 3: mvprintw(3,0,"3 ATTEMPT(S) LEFT: * * *");
  175. mvprintw(1,0,"ENTER PASSWORD NOW");
  176. break;
  177. case 4: mvprintw(3,0,"4 ATTEMPT(S) LEFT: * * * *");
  178. mvprintw(1,0,"ENTER PASSWORD NOW");
  179. break;
  180. case 0: clear();
  181. mvprintw(10,20,"TERMINAL LOCKED");
  182. mvprintw(12,12,"PLEASE CONTACT AN ADMINISTRATOR");
  183. refresh();
  184. SLEEP(3000000);
  185. endwin();
  186. if(strlen(getCompleteProg())> 2)
  187. system(getCompleteProg());
  188. freeAll();
  189. exit(EXIT_FAILURE);
  190. }
  191. refresh();
  192. move(y,x);
  193. /* Check if highlights need to be purged */
  194. if(needsClearing){
  195. charCounter = 0;
  196. while(charCounter!=bracketLength+1){
  197. currentChar[charCounter] = (char)mvinch(origy,charStart+charCounter);
  198. mvprintw(origy,charStart+charCounter,"%c",(int)currentChar[charCounter]);
  199. charCounter++;
  200. }
  201. mvprintw(21,41," ",currentChar[0]);
  202. needsClearing = 0;
  203. move(y,origx);
  204. }
  205. if(needsClearingMultiLine){
  206. charCounter = 0;
  207. while(charCounter!=wordLength){
  208. currentChar[charCounter] = (char)mvinch(starty,startx);
  209. mvprintw(starty,startx,"%c",currentChar[charCounter]);
  210. charCounter++;
  211. startx++;
  212. if(startx==19 || startx==39){
  213. startx-=12;
  214. starty++;
  215. if(starty == 22) {
  216. starty = 5;
  217. startx+=20;
  218. }
  219. }
  220. }
  221. mvprintw(21,41," ",currentChar[0]);
  222. needsClearingMultiLine = 0;
  223. move(y,x);
  224. }
  225. /* Clear the char array */
  226. for(i=0;i<12;i++)
  227. currentChar[i]=' ';
  228. currentChar[0] = (char) (char)mvinch(y,x);
  229. /* Set the new y and x to origy and origx */
  230. origy = y;
  231. origx = x;
  232. /* Check for bracket tricks */
  233. if((currentChar[0]=='(' || currentChar[0]=='<' || currentChar[0]=='[' || currentChar[0]=='{') && usedBrackets[getCharLoc(y,x)] && bracketTricks<WORDS_CHOSEN){
  234. charStart = x;
  235. bracketLength=0;
  236. while(x!=18 && x!=38){
  237. x++;
  238. endBracket = (char)mvinch(y,x);
  239. bracketLength++;
  240. if((endBracket == ')' && currentChar[0]=='(') ||
  241. (endBracket == '>' && currentChar[0]=='<') ||
  242. (endBracket == ']' && currentChar[0]=='[') ||
  243. (endBracket == '}' && currentChar[0]=='{')){
  244. /* Reprint the bracket trick with highlight */
  245. attron(A_STANDOUT);
  246. charCounter = 0;
  247. while(1){
  248. currentChar[charCounter] = (char)mvinch(y,charStart+charCounter);
  249. mvprintw(y,charStart+charCounter,"%c",currentChar[charCounter]);
  250. if(currentChar[charCounter] == endBracket)
  251. break;
  252. charCounter++;
  253. }
  254. attroff(A_STANDOUT);
  255. /* Print the bracket trick to output */
  256. attron(A_BOLD);
  257. for(i=0;i<=charCounter;i++)
  258. mvprintw(21,41+i,"%c",(int)currentChar[i]);
  259. /* Notify that highlighting will need to be cleared next move */
  260. needsClearing = 1;
  261. }
  262. }
  263. if(!((endBracket == ')' && currentChar[0]=='(') ||
  264. (endBracket == '>' && currentChar[0]=='<') ||
  265. (endBracket == ']' && currentChar[0]=='[') ||
  266. (endBracket == '}' && currentChar[0]=='{'))){
  267. mvprintw(21,41,"%c",currentChar[0]);
  268. }
  269. }
  270. /* Check for letters */
  271. else if(currentChar[0]>64 && currentChar[0]<91){
  272. /* Check for letter behind the current location */
  273. int tempx = x;
  274. int tempy = y;
  275. while(bigString[getCharLoc(tempy,tempx)-1]>64 && bigString[getCharLoc(tempy,tempx)-1]<91){
  276. currentChar[0] = bigString[getCharLoc(tempy,tempx)];
  277. tempx--;
  278. if(tempx==6 || tempx==26){
  279. tempx+=12;
  280. tempy--;
  281. if(tempy == 4){
  282. tempy = 21;
  283. tempx-=20;
  284. }
  285. }
  286. }
  287. startx = tempx;
  288. starty = tempy; /* We'll need the location of the first char for cleaning */
  289. /* And start there */
  290. charCounter = 0;
  291. while(bigString[getCharLoc(tempy,tempx)+1]>64 && bigString[getCharLoc(tempy,tempx)+1]<91){
  292. currentChar[charCounter] = bigString[getCharLoc(tempy,tempx)];
  293. charCounter++;
  294. tempx++;
  295. if(tempx==19 || tempx==39){
  296. tempx-=12;
  297. tempy++;
  298. if(tempy == 22) {
  299. tempy = 5;
  300. tempx+=20;
  301. }
  302. }
  303. }
  304. /* Now currentChar is the String, and charCounter+1 is the length */
  305. wordLength = charCounter+1;
  306. /* Reprint the word with highlight */
  307. tempx = startx;
  308. tempy = starty;
  309. attron(A_STANDOUT);
  310. charCounter = 0;
  311. while(charCounter!=wordLength){
  312. currentChar[charCounter] = (char)mvinch(tempy,tempx);
  313. mvprintw(tempy,tempx,"%c",currentChar[charCounter]);
  314. charCounter++;
  315. tempx++;
  316. if(tempx==19 || tempx==39){
  317. tempx-=12;
  318. tempy++;
  319. if(tempy == 22) {
  320. tempy = 5;
  321. tempx+=20;
  322. }
  323. }
  324. }
  325. attroff(A_STANDOUT);
  326. /* Print the word to output */
  327. attron(A_BOLD);
  328. for(i=0;i<charCounter;i++)
  329. mvprintw(21,41+i,"%c",(int)currentChar[i]);
  330. /* Notify that highlighting will need to be cleared next move */
  331. needsClearingMultiLine = 1;
  332. }
  333. /* Nothing was found, print current char */
  334. else
  335. mvprintw(21,41,"%c",currentChar[0]);
  336. move(origy,origx);
  337. refresh();
  338. keyPress = getch();
  339. getyx(stdscr,y,x);
  340. if(keyPress=='w'){
  341. if(y>5)
  342. move(y-1,x);
  343. }
  344. if(keyPress=='s'){
  345. if(y<21)
  346. move(y+1,x);
  347. }
  348. if(keyPress=='a'){
  349. if(x>7){
  350. if(x==27)
  351. move(y,18);
  352. else
  353. move(y,x-1);
  354. }
  355. }
  356. if(keyPress=='d'){
  357. if(x<38){
  358. if(x==18)
  359. move(y,27);
  360. else
  361. move(y,x+1);
  362. }
  363. }
  364. if(keyPress==3) /* Ctrl-C */
  365. exit(0);
  366. if(keyPress=='\n'){ /* Enter */
  367. mvprintw(17,40," ");
  368. mvprintw(18,40," ");
  369. mvprintw(19,40," ");
  370. /* If the char is a left bracket */
  371. if(((currentChar[0]=='(') && currentCharContains(currentChar,')')) ||
  372. (currentChar[0]=='<' && currentCharContains(currentChar,'>')) ||
  373. (currentChar[0]=='[' && currentCharContains(currentChar,']')) ||
  374. (currentChar[0]=='{' && currentCharContains(currentChar,'}'))){
  375. /* Set the selected bracket as used */
  376. usedBrackets[getCharLoc(y,x)] = 0;
  377. /* Increment total bracket tricks used */
  378. bracketTricks++;
  379. if(rand()%5==0){
  380. /* 20% chance of allowance replenish */
  381. sprintf(output,"Allowance ");
  382. mvprintw(18,40,">");
  383. for(i=0;i<12;i++){
  384. mvprintw(18,41+i,"%c",output[i]);
  385. }
  386. sprintf(output,"replenished.");
  387. mvprintw(19,40,">");
  388. for(i=0;i<12;i++){
  389. mvprintw(19,41+i,"%c",output[i]);
  390. }
  391. allowances = 4;
  392. }
  393. else{
  394. /* Remove a dud */
  395. int tempx,tempy;
  396. pickagain:do{
  397. if(rand()%2==0)
  398. tempx = (rand()%12)+7;
  399. else
  400. tempx = (rand()%12)+27;
  401. tempy = (rand()%17)+5;
  402. } while(!(bigString[getCharLoc(tempy,tempx)]>64 && bigString[getCharLoc(tempy,tempx)]<91));
  403. while(bigString[getCharLoc(tempy,tempx)-1]>64 && bigString[getCharLoc(tempy,tempx)-1]<91){
  404. tempx--;
  405. if(tempx==6 || tempx==26){
  406. tempx+=12;
  407. tempy--;
  408. }
  409. }
  410. startx = tempx;
  411. starty = tempy;
  412. charCounter = 0;
  413. while(bigString[getCharLoc(tempy,tempx)+1]>64 && bigString[getCharLoc(tempy,tempx)+1]<91){
  414. currentChar[charCounter] = bigString[getCharLoc(tempy,tempx)];
  415. charCounter++;
  416. tempx++;
  417. if(tempx==19 || tempx==39){
  418. tempx-=12;
  419. tempy++;
  420. }
  421. }
  422. /* Check if currentChar = correctWord */
  423. int allCorrect=1;
  424. for(i=0;i<WORD_SIZE;i++){
  425. if(currentChar[i]!=correctWord[i])
  426. allCorrect = 0;
  427. }
  428. if(allCorrect)
  429. goto pickagain;
  430. tempx = startx;
  431. tempy = starty;
  432. while(bigString[getCharLoc(tempy,tempx)]>64 && bigString[getCharLoc(tempy,tempx)]<91){
  433. mvprintw(tempy,tempx,"%c",'.');
  434. bigString[getCharLoc(tempy,tempx)] = '.';
  435. tempx++;
  436. if(tempx==19 || tempx==39){
  437. tempx-=12;
  438. tempy++;
  439. }
  440. }
  441. sprintf(output,"Dud removed.");
  442. mvprintw(19,40,">");
  443. for(i=0;i<12;i++){
  444. mvprintw(19,41+i,"%c",output[i]);
  445. }
  446. }
  447. }
  448. /* Else compare it to the correct word */
  449. else{
  450. int rightLetters = WORD_SIZE;
  451. for(i=0;i<WORD_SIZE; i++){
  452. if(currentChar[i]!=correctWord[i])
  453. rightLetters--;
  454. }
  455. if(rightLetters==WORD_SIZE){
  456. mvprintw(15,40,">");
  457. for(i=0;i<12;i++){
  458. mvprintw(15,41+i,"%c",currentChar[i]);
  459. }
  460. sprintf(output,"Exact match!");
  461. mvprintw(16,40,">");
  462. for(i=0;i<12;i++){
  463. mvprintw(16,41+i,"%c",output[i]);
  464. }
  465. sprintf(output,"Please wait ");
  466. mvprintw(17,40,">");
  467. for(i=0;i<12;i++){
  468. mvprintw(17,41+i,"%c",output[i]);
  469. }
  470. sprintf(output,"while system");
  471. mvprintw(18,40,">");
  472. for(i=0;i<12;i++){
  473. mvprintw(18,41+i,"%c",output[i]);
  474. }
  475. sprintf(output,"is accessed.");
  476. mvprintw(19,40,">");
  477. for(i=0;i<12;i++){
  478. mvprintw(19,41+i,"%c",output[i]);
  479. }
  480. refresh();
  481. SLEEP(3000000);
  482. endwin();
  483. if(strlen(getVictoryProg()) > 2)
  484. system(getVictoryProg());
  485. else if(strlen(getCompleteProg())> 2)
  486. system(getCompleteProg());
  487. freeAll();
  488. exit(EXIT_SUCCESS);
  489. }
  490. else{
  491. mvprintw(17,40,">");
  492. for(i=0;i<12;i++){
  493. mvprintw(17,41+i,"%c",currentChar[i]);
  494. }
  495. sprintf(output,"Entry denied");
  496. mvprintw(18,40,">");
  497. for(i=0;i<12;i++){
  498. mvprintw(18,41+i,"%c",output[i]);
  499. }
  500. sprintf(output,"%d/%d correct.",rightLetters,WORD_SIZE);
  501. mvprintw(19,40,">");
  502. for(i=0;i<12;i++){
  503. mvprintw(19,41+i,"%c",output[i]);
  504. }
  505. allowances--;
  506. }
  507. }
  508. move(y,x);
  509. }
  510. refresh();
  511. }
  512. endwin();
  513. freeAll();
  514. exit(EXIT_SUCCESS);
  515. }