Advertisement
Guest User

DW2 seed lock name search script

a guest
Feb 3rd, 2016
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.02 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. $| = 1;
  7.  
  8. # Text input layout:
  9. # A B C D E F G H I J K
  10. # L M N O P Q R S T U V
  11. # W X Y Z ' , . ; ‥ → <space>
  12. # a b c d e f g h i j k
  13. # l m n o p q r s t u v
  14. # w x y z ! ? BACK END
  15. # Moving down from "s" goes to BACK, "t" and "v" go to END.
  16.  
  17. my @textmap = (
  18. [0x60, " "],
  19. [0x0A, "a"],
  20. [0x0B, "b"],
  21. [0x0C, "c"],
  22. [0x0D, "d"],
  23. [0x0E, "e"],
  24. [0x0F, "f"],
  25. [0x10, "g"],
  26. [0x11, "h"],
  27. [0x12, "i"],
  28. [0x13, "j"],
  29. [0x14, "k"],
  30. [0x15, "l"],
  31. [0x16, "m"],
  32. [0x17, "n"],
  33. [0x18, "o"],
  34. [0x19, "p"],
  35. [0x1A, "q"],
  36. [0x1B, "r"],
  37. [0x1C, "s"],
  38. [0x1D, "t"],
  39. [0x1E, "u"],
  40. [0x1F, "v"],
  41. [0x20, "w"],
  42. [0x21, "x"],
  43. [0x22, "y"],
  44. [0x23, "z"],
  45. [0x24, "A"],
  46. [0x25, "B"],
  47. [0x26, "C"],
  48. [0x27, "D"],
  49. [0x28, "E"],
  50. [0x29, "F"],
  51. [0x2A, "G"],
  52. [0x2B, "H"],
  53. [0x2C, "I"],
  54. [0x2D, "J"],
  55. [0x2E, "K"],
  56. [0x2F, "L"],
  57. [0x30, "M"],
  58. [0x31, "N"],
  59. [0x32, "O"],
  60. [0x33, "P"],
  61. [0x34, "Q"],
  62. [0x35, "R"],
  63. [0x36, "S"],
  64. [0x37, "T"],
  65. [0x38, "U"],
  66. [0x39, "V"],
  67. [0x3A, "W"],
  68. [0x3B, "X"],
  69. [0x3C, "Y"],
  70. [0x3D, "Z"],
  71. [0x60, " "],
  72. [0x63, "→"],
  73. [0x67, "'"],
  74. [0x69, ","],
  75. [0x6B, "."],
  76. [0x6E, "?"],
  77. [0x6F, "!"],
  78. [0x70, ";"],
  79. [0x75, "‥"],
  80. );
  81.  
  82. my @initial_names = (
  83. ["Bran", "Glynn", "Talint", "Numor", "Lars", "Orfeo", "Artho", "Esgar"],
  84. ["Varia", "Elani", "Ollisa", "Roz", "Kailin", "Peta", "Illyth", "Gwen"],
  85. );
  86. for (my $i = 0; $i < @initial_names; $i++) {
  87. for (my $j = 0; $j < 8; $j++) {
  88. my $name = "";
  89. for (my $k = 0; $k < 8; $k++) {
  90. if ($k >= length($initial_names[$i][$j])) {
  91. $name .= "\x5F";
  92. } else {
  93. my $ch = substr($initial_names[$i][$j], $k, 1);
  94. my $code = undef;
  95. for (my $l = 1; $l < @textmap; $l++) {
  96. if ($textmap[$l][1] eq $ch) {
  97. $code = $textmap[$l][0];
  98. last;
  99. }
  100. }
  101. die if !defined($code);
  102. $name .= pack("C", $code);
  103. }
  104. }
  105. $initial_names[$i][$j] = $name;
  106. }
  107. }
  108.  
  109. my @name = (0,0,0,0,0,0,0,0);
  110. for ($name[3] = 0; $name[3] < @textmap; $name[3]++) {
  111. next if !$name[3] && $name[4];
  112. next if $textmap[$name[3]][0] == 0x50 && !$name[4];
  113. for ($name[2] = 0; $name[2] < @textmap; $name[2]++) {
  114. next if !$name[2] && $name[3];
  115. next if $textmap[$name[2]][0] == 0x50 && !$name[3];
  116. for ($name[1] = 0; $name[1] < @textmap; $name[1]++) {
  117. next if !$name[1] && $name[2];
  118. next if $textmap[$name[1]][0] == 0x50 && !$name[2];
  119. printf STDERR "Name: a%s\r", join("", map {$textmap[$_][1]} @name[1..$#name]);
  120. for ($name[0] = 1; $name[0] < @textmap; $name[0]++) {
  121. next if $textmap[$name[0]][0] == 0x50 && !$name[1];
  122. for (my $speed = 0; $speed < 3; $speed++) {
  123. my $save = &gen_save(\@name, $speed);
  124. my $checksum = &checksum($save);
  125. if ($checksum == 0x5FEA || $checksum == 0xAFF5) {
  126. printf "Name: %-4s Speed: %-6s Checksum: \$%04X\n",
  127. join("", map {$textmap[$_][1]} @name),
  128. ("Fast", "Medium", "Slow")[$speed], $checksum;
  129. }
  130. }
  131. }
  132. }
  133. }
  134. }
  135.  
  136.  
  137. sub gen_save {
  138. my ($name, $speed) = @_;
  139.  
  140. my $save = "\0" x 0x71;
  141.  
  142. substr($save, 0x09, 4) = pack("C*", map {$textmap[$_][0]} @name[0..3]);
  143. substr($save, 0x63, 4) = pack("C*", map {$textmap[$_][0]} @name[4..7]);
  144.  
  145. my $name_index = 0;
  146. for (my $i = 3; $i >= 0; $i--) {
  147. $name_index += $textmap[$name[$i]][0];
  148. $name_index += $name_index >> 8;
  149. $name_index &= 0xFF;
  150. $name_index += $textmap[$name[$i+4]][0];
  151. $name_index += $name_index >> 8;
  152. $name_index &= 0xFF;
  153. }
  154. substr($save, 0x0D, 4) = substr($initial_names[0][$name_index & 7], 0, 4);
  155. substr($save, 0x67, 4) = substr($initial_names[0][$name_index & 7], 4, 4);
  156. substr($save, 0x11, 4) = substr($initial_names[1][$name_index>>3 & 7], 0, 4);
  157. substr($save, 0x6B, 4) = substr($initial_names[1][$name_index>>3 & 7], 4, 4);
  158.  
  159. substr($save, 0x6F, 1) = ("\x28", "\x46", "\xFF")[$speed];
  160.  
  161. my $seed = &checksum($save);
  162.  
  163. substr($save, 0x15, 1) = "\x84";
  164.  
  165. # Hero stats
  166. substr($save, 0x18, 1) = "\x1C";
  167. substr($save, 0x1E, 4) = "\x05\x04\x05\x08";
  168. substr($save, 0x23, 1) = "\x1C";
  169. substr($save, 0x26, 1) = "\x01";
  170.  
  171. # Prince stats
  172. substr($save, 0x2A, 1) = "\x1F";
  173. substr($save, 0x2C, 1) = "\x06";
  174. substr($save, 0x30, 4) = "\x04\x04\x0C\x08";
  175. substr($save, 0x35, 1) = "\x1F";
  176. substr($save, 0x37, 2) = "\x06\x01";
  177.  
  178. # Princess stats
  179. substr($save, 0x3C, 1) = "\x20";
  180. substr($save, 0x3E, 1) = "\x1C";
  181. substr($save, 0x42, 4) = "\x02\x16\x04\x0D";
  182. substr($save, 0x47, 1) = "\x20";
  183. substr($save, 0x49, 2) = "\x1C\x01";
  184.  
  185. substr($save, 0x4B, 1) = "\x55";
  186. substr($save, 0x53, 2) = "\x45\x55";
  187. substr($save, 0x5B, 2) = "\x41\x51";
  188.  
  189. return $save;
  190. }
  191.  
  192.  
  193. sub random {
  194. my ($seed_ref) = @_;
  195. my $seed = $$seed_ref;
  196.  
  197. for (my $i = 0; $i < 2; $i++) {
  198. for (my $y = 8; $y > 0; $y--) {
  199. my $a = ($seed >> 15) ^ 1;
  200. $seed = ($seed << 1) & 0xFFFF;
  201. if ($a) {
  202. $seed ^= 0x1021;
  203. }
  204. }
  205. }
  206. my $random = $seed & 0xFF;
  207.  
  208. $$seed_ref = $seed;
  209. return $random;
  210. }
  211.  
  212.  
  213. sub checksum {
  214. my ($data) = @_;
  215. my $seed = 0x7070;
  216. foreach my $byte (reverse(unpack("C*", $data))) {
  217. for (my $y = 8; $y > 0; $y--) {
  218. my $a = ($seed >> 8) ^ $byte;
  219. $seed = ($seed << 1) & 0xFFFF;
  220. $byte = ($byte << 1) & 0xFF;
  221. if ($a & 0x80) {
  222. $seed ^= 0x1021;
  223. }
  224. }
  225. }
  226. return $seed;
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement