www.pudn.com > ro4fserver.rar > grfio.c
#include#include #include #include #include #include "grfio.h" static unsigned char IP[64]={ 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; static unsigned char RIP[64]={ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; static unsigned char S[8][64]; static unsigned char S_[8][64]={ { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }, { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }, { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }, { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }, { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }, { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }, { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }, { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }; static unsigned char P[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; static unsigned char shift[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; static unsigned int getlong(unsigned char *p) { return *p+p[1]*256+(p[2]+p[3]*256)*65536; } static void do_ip(unsigned char *buf,int len) { int i,j,k; unsigned char tmp[8]; for(i=0;i >3)] & shift[k&7]) tmp[j>>3] |= shift[j&7]; } *((long*)(buf+i))=*((long*)tmp); *((long*)(buf+i+4))=*((long*)(tmp+4)); } } static void do_rip(unsigned char *buf,int len) { int i,j,k; unsigned char tmp[8]; for(i=0;i >3)] & shift[k&7]) tmp[j>>3] |= shift[j&7]; } *((long*)(buf+i))=*((long*)tmp); *((long*)(buf+i+4))=*((long*)(tmp+4)); } } static void do_f(unsigned char *buf,int len) { unsigned char tmp[8]; unsigned long a; int i,j,k; for(i=0;i >27); tmp[1]=(a>>23)&0x3f; tmp[2]=(a>>19)&0x3f; tmp[3]=(a>>15)&0x3f; tmp[4]=(a>>11)&0x3f; tmp[5]=(a>>7)&0x3f; tmp[6]=(a>>3)&0x3f; tmp[7]=((a<<1)+(a>>31))&0x3f; // S for(j=0;j<4;j++) tmp[j]=(S[j*2][tmp[j*2]]<<4)+S[j*2+1][tmp[j*2+1]]; // P *((long*)(tmp+4))=0; for(j=0;j<32;j++){ k=P[j]-1; if(tmp[k>>3] & shift[k&7]) tmp[(j>>3)+4] |= shift[j&7]; } *((long*)(buf+i))^=*((long*)(tmp+4)); } } static void decode_des_etc(unsigned char *p,int s,int type,int cycle) { int i,j=0; if(cycle<3) cycle=3; else if(cycle<5) cycle++; else if(cycle<7) cycle+=9; else cycle+=15; for(i=0;i*8 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; err = inflateInit(&stream); if (err != Z_OK) return err; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { inflateEnd(&stream); return err == Z_OK ? Z_BUF_ERROR : err; } *destLen = stream.total_out; err = inflateEnd(&stream); return err; } static struct { int srclen,srclen_aligned,declen,srcpos; short next; char cycle,type; char fn[128-4*5]; } *filelist; static int filelist_hash[256]; static int filehash(unsigned char *fn) { unsigned int a=0; while(*fn){ a=((a<<1)+(a>>7)*9+tolower(*fn)); fn++; } return a&255; } int grfio_size(char *fn) { int f; for(f=filelist_hash[filehash(fn)];f>=0;f=filelist[f].next) if(strcasecmp(filelist[f].fn,fn)==0) break; if(f<0){ printf("file not found in data.grf : %s\n",fn); exit(1); } return filelist[f].declen; } void* grfio_read(char *fn) { FILE *in; unsigned char *buf,*buf2; int f; in=fopen("data.grf","rb"); if(in==NULL){ printf("data.grf not found\n"); exit(1); } for(f=filelist_hash[filehash(fn)];f>=0;f=filelist[f].next) if(strcasecmp(filelist[f].fn,fn)==0) break; if(f<0){ printf("file not found in data.grf : %s\n",fn); exit(1); } fseek(in,filelist[f].srcpos,0); buf=malloc(filelist[f].srclen_aligned+1024); fread(buf,1,filelist[f].srclen_aligned,in); fclose(in); buf2=malloc(filelist[f].declen+1024); if(filelist[f].type==1){ uLongf len; decode_des_etc(buf,filelist[f].srclen_aligned,filelist[f].cycle==0,filelist[f].cycle); len=filelist[f].declen; decode_zip(buf2,&len,buf,filelist[f].srclen); if(len!=filelist[f].declen){ printf("%d != %d\n",(int)len,filelist[f].declen); exit(1); } } else { memcpy(buf2,buf,filelist[f].declen); } free(buf); return buf2; } static unsigned char * decode_filename(unsigned char *buf,int len) { int i; for(i=0;i>4)&0xff); do_ip(buf,len); do_f(buf,len); do_rip(buf,len); return buf; } void grfio_init(void) { FILE *fp; int s,i; unsigned char tmp[0x2e]; int j,num; unsigned char *fn; unsigned char *buf,*p; for(i=0;i<8;i++){ for(j=0;j<64;j++){ S[i][j]=S_[i][(j&0x20)+((j&1)<<4)+((j&0x1e)>>1)]; } } fp=fopen("data.grf","rb"); if(fp==NULL){ printf("data.grf not found\n"); exit(2); } fseek(fp,0,2); s=ftell(fp); fseek(fp,0,0); fread(tmp,1,0x2e,fp); if(strcmp(tmp,"Master of Magic") || fseek(fp,getlong(tmp+0x1e),1)){ printf("data.grf read error\n"); exit(2); } s-=ftell(fp); buf=malloc(s); if(buf==NULL){ printf("out of memory : grf_filelist\n"); exit(1); } fread(buf,1,s,fp); fclose(fp); for(j=0;j<256;j++) filelist_hash[j]=-1; for(j=0,num=0;j =sizeof(filelist[i].fn)-1){ printf("file name too long : %s\n",fn); exit(1); } srclen=0; if((period_ptr=rindex(fn,'.'))!=NULL){ int l; for(l=0;l<4;l++) if(strcasecmp(period_ptr,".gnd\0.gat\0.act\0.str"+l*5)==0) break; srclen=getlong(buf+k)-getlong(buf+k+8)-715; if(l==4){ for(l=10,srccount=1;srclen>=l;l=l*10,srccount++); } else srccount=0; } else srccount=0; filelist[i].srclen=srclen; filelist[i].srclen_aligned=getlong(buf+k+4)-37579; filelist[i].declen=getlong(buf+k+8); filelist[i].srcpos=getlong(buf+k+13)+0x2e; filelist[i].cycle=srccount; filelist[i].type=buf[k+12]; strcpy(filelist[i].fn,fn); filelist[i].next=filelist_hash[h=filehash(fn)]; filelist_hash[h]=i; } free(buf); buf=grfio_read("data\\resnametable.txt"); s=grfio_size("data\\resnametable.txt"); buf[s]=0; for(i=num,p=buf;i=0;f=filelist[f].next) if(strcasecmp(filelist[f].fn,dst)==0) break; if(f>=0){ memcpy(&filelist[i],&filelist[f],sizeof(filelist[0])); strcpy(filelist[i].fn,src); filelist[i].next=filelist_hash[j=filehash(src)]; filelist_hash[j]=i; } else { //printf("file not found in data.grf : %s < %s\n",dst,src); i--; } } p=strchr(p,'\n'); if(!p) break; p++; } free(buf); }