pass.c 20 KB

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