pass.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  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. keypad(stdscr, TRUE);
  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
  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 a
  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. int y,x,origy,origx,starty,startx; // values that keep track of current yx locations, and original ones
  146. int wordLength; // How long a word is
  147. int charStart; // where character counting starts for brackets
  148. int keyPress; // key pressed by user
  149. int charCounter; // counts currentChar - used for incrementing currentChar to print or change it
  150. int bracketLength; // length of a bracket trick
  151. char endBracket; // the end bracket that corresponds to currentChar[0];
  152. int bracketTricks=0; // Total number of bracket tricks used
  153. int needsClearing = 0; // Whether or not highlights need to be pur
  154. int needsClearingMultiLine = 0; // Whether or not a multi line highlight needs to be purged
  155. char output[13]; // Used for side terminal output
  156. int allowances = 4;
  157. // Get the key config
  158. int GO_LEFT, GO_RIGHT, GO_DOWN, GO_UP;
  159. switch(getKeyConfig()){
  160. case ARROWS:
  161. GO_LEFT = KEY_LEFT;
  162. GO_RIGHT = KEY_RIGHT;
  163. GO_UP = KEY_UP;
  164. GO_DOWN = KEY_DOWN;
  165. break;
  166. case WASD:
  167. GO_LEFT = 'a';
  168. GO_RIGHT = 'd';
  169. GO_UP = 'w';
  170. GO_DOWN = 's';
  171. break;
  172. case HJKL:
  173. GO_LEFT = 'h';
  174. GO_RIGHT = 'l';
  175. GO_UP = 'k';
  176. GO_DOWN = 'j';
  177. break;
  178. }
  179. // Get rid of all typed characters
  180. int ch = getch();
  181. while(ch != ERR)
  182. ch = getch();
  183. // Fianlly, set nodelay to false
  184. nodelay(stdscr, 0);
  185. while(1){
  186. getyx(stdscr,y,x);
  187. // Get allowances left
  188. mvprintw(1,0," ");
  189. mvprintw(3,0," ");
  190. switch(allowances){
  191. case 1: mvprintw(3,0,"1 ATTEMPT(S) LEFT: *");
  192. attron(A_BLINK);
  193. mvprintw(1,0,"!!! WARNING: LOCKOUT IMNINENT !!!");
  194. attroff(A_BLINK);
  195. attron(A_BOLD);
  196. break;
  197. case 2: mvprintw(3,0,"2 ATTEMPT(S) LEFT: * *");
  198. mvprintw(1,0,"ENTER PASSWORD NOW");
  199. break;
  200. case 3: mvprintw(3,0,"3 ATTEMPT(S) LEFT: * * *");
  201. mvprintw(1,0,"ENTER PASSWORD NOW");
  202. break;
  203. case 4: mvprintw(3,0,"4 ATTEMPT(S) LEFT: * * * *");
  204. mvprintw(1,0,"ENTER PASSWORD NOW");
  205. break;
  206. case 0: clear();
  207. mvprintw(10,20,"TERMINAL LOCKED");
  208. mvprintw(12,12,"PLEASE CONTACT AN ADMINISTRATOR");
  209. refresh();
  210. SLEEP(3000000);
  211. endwin();
  212. if(strlen(getCompleteProg())> 2)
  213. system(getCompleteProg());
  214. freeAll();
  215. exit(EXIT_FAILURE);
  216. }
  217. refresh();
  218. move(y,x);
  219. // Check if highlights need to be purged
  220. if(needsClearing){
  221. charCounter = 0;
  222. while(charCounter!=bracketLength+1){
  223. currentChar[charCounter] = (char)mvinch(origy,charStart+charCounter);
  224. mvprintw(origy,charStart+charCounter,"%c",(int)currentChar[charCounter]);
  225. charCounter++;
  226. }
  227. mvprintw(21,41," ",currentChar[0]);
  228. needsClearing = 0;
  229. move(y,origx);
  230. }
  231. if(needsClearingMultiLine){
  232. charCounter = 0;
  233. while(charCounter!=wordLength){
  234. currentChar[charCounter] = (char)mvinch(starty,startx);
  235. mvprintw(starty,startx,"%c",currentChar[charCounter]);
  236. charCounter++;
  237. startx++;
  238. if(startx==19 || startx==39){
  239. startx-=12;
  240. starty++;
  241. if(starty == 22) {
  242. starty = 5;
  243. startx+=20;
  244. }
  245. }
  246. }
  247. mvprintw(21,41," ",currentChar[0]);
  248. needsClearingMultiLine = 0;
  249. move(y,x);
  250. }
  251. // Clear the char array
  252. for(i=0;i<12;i++)
  253. currentChar[i]=' ';
  254. currentChar[0] = (char) (char)mvinch(y,x);
  255. // Set the new y and x to origy and origx
  256. origy = y;
  257. origx = x;
  258. // Check for bracket tricks
  259. if((currentChar[0]=='(' || currentChar[0]=='<' || currentChar[0]=='[' || currentChar[0]=='{') && usedBrackets[getCharLoc(y,x)] && bracketTricks<WORDS_CHOSEN){
  260. charStart = x;
  261. bracketLength=0;
  262. while(x!=18 && x!=38){
  263. x++;
  264. endBracket = (char)mvinch(y,x);
  265. bracketLength++;
  266. if((endBracket == ')' && currentChar[0]=='(') ||
  267. (endBracket == '>' && currentChar[0]=='<') ||
  268. (endBracket == ']' && currentChar[0]=='[') ||
  269. (endBracket == '}' && currentChar[0]=='{')){
  270. // Reprint the bracket trick with highlight
  271. attron(A_STANDOUT);
  272. charCounter = 0;
  273. while(1){
  274. currentChar[charCounter] = (char)mvinch(y,charStart+charCounter);
  275. mvprintw(y,charStart+charCounter,"%c",currentChar[charCounter]);
  276. if(currentChar[charCounter] == endBracket)
  277. break;
  278. charCounter++;
  279. }
  280. attroff(A_STANDOUT);
  281. // Print the bracket trick to output
  282. attron(A_BOLD);
  283. for(i=0;i<=charCounter;i++)
  284. mvprintw(21,41+i,"%c",(int)currentChar[i]);
  285. // Notify that highlighting will need to be cleared next move
  286. needsClearing = 1;
  287. }
  288. }
  289. if(!((endBracket == ')' && currentChar[0]=='(') ||
  290. (endBracket == '>' && currentChar[0]=='<') ||
  291. (endBracket == ']' && currentChar[0]=='[') ||
  292. (endBracket == '}' && currentChar[0]=='{'))){
  293. mvprintw(21,41,"%c",currentChar[0]);
  294. }
  295. }
  296. // Check for letters
  297. else if(currentChar[0]>64 && currentChar[0]<91){
  298. // Check for letter behind the current location
  299. int tempx = x;
  300. int tempy = y;
  301. while(bigString[getCharLoc(tempy,tempx)-1]>64 && bigString[getCharLoc(tempy,tempx)-1]<91){
  302. currentChar[0] = bigString[getCharLoc(tempy,tempx)];
  303. tempx--;
  304. if(tempx==6 || tempx==26){
  305. tempx+=12;
  306. tempy--;
  307. if(tempy == 4){
  308. tempy = 21;
  309. tempx-=20;
  310. }
  311. }
  312. }
  313. startx = tempx;
  314. starty = tempy; // We'll need the location of the first char for clean
  315. // And start there
  316. charCounter = 0;
  317. while(bigString[getCharLoc(tempy,tempx)+1]>64 && bigString[getCharLoc(tempy,tempx)+1]<91){
  318. currentChar[charCounter] = bigString[getCharLoc(tempy,tempx)];
  319. charCounter++;
  320. tempx++;
  321. if(tempx==19 || tempx==39){
  322. tempx-=12;
  323. tempy++;
  324. if(tempy == 22) {
  325. tempy = 5;
  326. tempx+=20;
  327. }
  328. }
  329. }
  330. // Now currentChar is the String, and charCounter+1 is the length
  331. wordLength = charCounter+1;
  332. // Reprint the word with highlight
  333. tempx = startx;
  334. tempy = starty;
  335. attron(A_STANDOUT);
  336. charCounter = 0;
  337. while(charCounter!=wordLength){
  338. currentChar[charCounter] = (char)mvinch(tempy,tempx);
  339. mvprintw(tempy,tempx,"%c",currentChar[charCounter]);
  340. charCounter++;
  341. tempx++;
  342. if(tempx==19 || tempx==39){
  343. tempx-=12;
  344. tempy++;
  345. if(tempy == 22) {
  346. tempy = 5;
  347. tempx+=20;
  348. }
  349. }
  350. }
  351. attroff(A_STANDOUT);
  352. // Print the word to output
  353. attron(A_BOLD);
  354. for(i=0;i<charCounter;i++)
  355. mvprintw(21,41+i,"%c",(int)currentChar[i]);
  356. // Notify that highlighting will need to be cleared next move
  357. needsClearingMultiLine = 1;
  358. }
  359. // Nothing was found, print current char
  360. else
  361. mvprintw(21,41,"%c",currentChar[0]);
  362. move(origy,origx);
  363. refresh();
  364. keyPress = getch();
  365. getyx(stdscr,y,x);
  366. if(keyPress==GO_UP){
  367. if(y>5)
  368. move(y-1,x);
  369. }
  370. if(keyPress==GO_DOWN){
  371. if(y<21)
  372. move(y+1,x);
  373. }
  374. if(keyPress==GO_LEFT){
  375. if(x>7){
  376. if(x==27)
  377. move(y,18);
  378. else
  379. move(y,x-1);
  380. }
  381. }
  382. if(keyPress==GO_RIGHT){
  383. if(x<38){
  384. if(x==18)
  385. move(y,27);
  386. else
  387. move(y,x+1);
  388. }
  389. }
  390. if(keyPress==3) // Ctrl-C
  391. exit(0);
  392. if(keyPress=='\n'){ // Enter
  393. mvprintw(17,40," ");
  394. mvprintw(18,40," ");
  395. mvprintw(19,40," ");
  396. // If the char is a left bracket
  397. if(((currentChar[0]=='(') && currentCharContains(currentChar,')')) ||
  398. (currentChar[0]=='<' && currentCharContains(currentChar,'>')) ||
  399. (currentChar[0]=='[' && currentCharContains(currentChar,']')) ||
  400. (currentChar[0]=='{' && currentCharContains(currentChar,'}'))){
  401. // Set the selected bracket as used
  402. usedBrackets[getCharLoc(y,x)] = 0;
  403. // Increment total bracket tricks used
  404. bracketTricks++;
  405. if(rand()%5==0){
  406. // 20% chance of allowance replenish
  407. sprintf(output,"Allowance ");
  408. mvprintw(18,40,">");
  409. for(i=0;i<12;i++){
  410. mvprintw(18,41+i,"%c",output[i]);
  411. }
  412. sprintf(output,"replenished.");
  413. mvprintw(19,40,">");
  414. for(i=0;i<12;i++){
  415. mvprintw(19,41+i,"%c",output[i]);
  416. }
  417. allowances = 4;
  418. }
  419. else{
  420. // Remove a dud
  421. int tempx,tempy;
  422. pickagain:do{
  423. if(rand()%2==0)
  424. tempx = (rand()%12)+7;
  425. else
  426. tempx = (rand()%12)+27;
  427. tempy = (rand()%17)+5;
  428. } while(!(bigString[getCharLoc(tempy,tempx)]>64 && bigString[getCharLoc(tempy,tempx)]<91));
  429. while(bigString[getCharLoc(tempy,tempx)-1]>64 && bigString[getCharLoc(tempy,tempx)-1]<91){
  430. tempx--;
  431. if(tempx==6 || tempx==26){
  432. tempx+=12;
  433. tempy--;
  434. }
  435. }
  436. startx = tempx;
  437. starty = tempy;
  438. charCounter = 0;
  439. while(bigString[getCharLoc(tempy,tempx)+1]>64 && bigString[getCharLoc(tempy,tempx)+1]<91){
  440. currentChar[charCounter] = bigString[getCharLoc(tempy,tempx)];
  441. charCounter++;
  442. tempx++;
  443. if(tempx==19 || tempx==39){
  444. tempx-=12;
  445. tempy++;
  446. }
  447. }
  448. // Check if currentChar = correctWord
  449. int allCorrect=1;
  450. for(i=0;i<WORD_SIZE;i++){
  451. if(currentChar[i]!=correctWord[i])
  452. allCorrect = 0;
  453. }
  454. if(allCorrect)
  455. goto pickagain;
  456. tempx = startx;
  457. tempy = starty;
  458. while(bigString[getCharLoc(tempy,tempx)]>64 && bigString[getCharLoc(tempy,tempx)]<91){
  459. mvprintw(tempy,tempx,"%c",'.');
  460. bigString[getCharLoc(tempy,tempx)] = '.';
  461. tempx++;
  462. if(tempx==19 || tempx==39){
  463. tempx-=12;
  464. tempy++;
  465. }
  466. }
  467. sprintf(output,"Dud removed.");
  468. mvprintw(19,40,">");
  469. for(i=0;i<12;i++){
  470. mvprintw(19,41+i,"%c",output[i]);
  471. }
  472. }
  473. }
  474. // Else compare it to the correct word
  475. else{
  476. int rightLetters = WORD_SIZE;
  477. for(i=0;i<WORD_SIZE; i++){
  478. if(currentChar[i]!=correctWord[i])
  479. rightLetters--;
  480. }
  481. if(rightLetters==WORD_SIZE){
  482. mvprintw(15,40,">");
  483. for(i=0;i<12;i++){
  484. mvprintw(15,41+i,"%c",currentChar[i]);
  485. }
  486. sprintf(output,"Exact match!");
  487. mvprintw(16,40,">");
  488. for(i=0;i<12;i++){
  489. mvprintw(16,41+i,"%c",output[i]);
  490. }
  491. sprintf(output,"Please wait ");
  492. mvprintw(17,40,">");
  493. for(i=0;i<12;i++){
  494. mvprintw(17,41+i,"%c",output[i]);
  495. }
  496. sprintf(output,"while system");
  497. mvprintw(18,40,">");
  498. for(i=0;i<12;i++){
  499. mvprintw(18,41+i,"%c",output[i]);
  500. }
  501. sprintf(output,"is accessed.");
  502. mvprintw(19,40,">");
  503. for(i=0;i<12;i++){
  504. mvprintw(19,41+i,"%c",output[i]);
  505. }
  506. refresh();
  507. SLEEP(3000000);
  508. endwin();
  509. if(strlen(getVictoryProg()) > 2)
  510. system(getVictoryProg());
  511. else if(strlen(getCompleteProg())> 2)
  512. system(getCompleteProg());
  513. freeAll();
  514. exit(EXIT_SUCCESS);
  515. }
  516. else{
  517. mvprintw(17,40,">");
  518. for(i=0;i<12;i++){
  519. mvprintw(17,41+i,"%c",currentChar[i]);
  520. }
  521. sprintf(output,"Entry denied");
  522. mvprintw(18,40,">");
  523. for(i=0;i<12;i++){
  524. mvprintw(18,41+i,"%c",output[i]);
  525. }
  526. sprintf(output,"%d/%d correct.",rightLetters,WORD_SIZE);
  527. mvprintw(19,40,">");
  528. for(i=0;i<12;i++){
  529. mvprintw(19,41+i,"%c",output[i]);
  530. }
  531. allowances--;
  532. }
  533. }
  534. move(y,x);
  535. }
  536. refresh();
  537. }
  538. endwin();
  539. freeAll();
  540. exit(EXIT_SUCCESS);
  541. }