1 /* adrift.c Treaty of Babel module for Adrift files
\r
3 * PROVISIONAL - Hold for someone else
\r
5 * This file depends on treaty_builder.h
\r
7 * This file is public domain, but note that any changes to this file
\r
8 * may render it noncompliant with the Treaty of Babel
\r
11 #define FORMAT adrift
\r
12 #define HOME_PAGE "http://www.adrift.org.uk"
\r
13 #define FORMAT_EXT ".taf"
\r
17 #include "treaty_builder.h"
\r
23 /* VB RNG constants */
\r
24 #define VB_RAND1 0x43FD43FD
\r
25 #define VB_RAND2 0x00C39EC3
\r
26 #define VB_RAND3 0x00FFFFFF
\r
27 #define VB_INIT 0x00A09E86
\r
28 static int32 vbr_state;
\r
31 Unobfuscates one byte from a taf file. This should be called on each byte
\r
32 in order, as the ADRIFT obfuscation function is stately.
\r
34 The de-obfuscation algorithm works by xoring the byte with the next
\r
35 byte in the sequence produced by the Visual Basic pseudorandom number
\r
36 generator, which is simulated here.
\r
38 static unsigned char taf_translate (unsigned char c)
\r
42 vbr_state = (vbr_state*VB_RAND1+VB_RAND2) & VB_RAND3;
\r
43 r=UCHAR_MAX * (unsigned) vbr_state;
\r
44 r/=((unsigned) VB_RAND3)+1;
\r
48 static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent)
\r
51 unsigned char buf[4];
\r
52 unsigned char *sf=(unsigned char *)story_file;
\r
55 if (extent <12) return INVALID_STORY_FILE_RV;
\r
58 /* Burn the first 8 bytes of translation */
\r
59 for(adv=0;adv<8;adv++) taf_translate(0);
\r
60 /* Bytes 8-11 contain the Adrift version number in the formay N.NN */
\r
61 buf[0]=taf_translate(sf[8]);
\r
63 buf[1]=taf_translate(sf[10]);
\r
64 buf[2]=taf_translate(sf[11]);
\r
65 adv=atoi((char *) buf);
\r
66 ASSERT_OUTPUT_SIZE(12);
\r
67 sprintf(output,"ADRIFT-%03d-",adv);
\r
68 return INCOMPLETE_REPLY_RV;
\r
72 /* The claim algorithm for ADRIFT is to unobfuscate the first
\r
73 seven bytes, and check for the word "Version".
\r
74 It seems fairly unlikely that the obfuscated form of that
\r
75 word would occur in the wild
\r
77 static int32 claim_story_file(void *story_file, int32 extent)
\r
79 unsigned char buf[8];
\r
81 unsigned char *sf=(unsigned char *)story_file;
\r
84 if (extent<12) return INVALID_STORY_FILE_RV;
\r
85 for(i=0;i<7;i++) buf[i]=taf_translate(sf[i]);
\r
86 if (strcmp((char *)buf,"Version")) return INVALID_STORY_FILE_RV;
\r
87 return VALID_STORY_FILE_RV;
\r