chuyiwen_gmsv/autil.c
chuyiwen bea5ac05b3 sq_gmsv_chuyiwen
sa_sever
2016-12-24 09:45:52 +09:00

520 lines
14 KiB
C

// Arminius' protocol utilities ver 0.1
//
// Any questions and bugs, mailto: arminius@mail.hwaei.com.tw
// -------------------------------------------------------------------
// The following definitions is to define game-dependent codes.
// Before compiling, remove the "//".
#define __STONEAGE
#include "version.h"
#include <stdio.h>
#include <stdlib.h>
#include "autil.h"
#include "char.h"
#ifdef __STONEAGE
#include "lssproto_util.h"
#include "common.h"
#endif
// Nuke 0701 fix
char *MesgSlice[SLICE_MAX];
int SliceCount;
char PersonalKey[1024*4];
// -------------------------------------------------------------------
// Initialize utilities
//
BOOL util_Init( void)
{
int i;
for (i=0; i<SLICE_MAX; i++){
MesgSlice[i] = (char *) calloc( 1,SLICE_SIZE);
if(MesgSlice[i]==NULL) return FALSE;
}
SliceCount = 0;
strcpysafe(PersonalKey,sizeof( PersonalKey ), getDefaultKey(-1));
return TRUE;
}
// -------------------------------------------------------------------
// Split up a message into slices by spearator. Store those slices
// into a global buffer "char **MesgSlice"
//
// arg: source=message string; separator=message separator (1 byte)
// ret: (none)
// WON ADD
//void util_SplitMessage(char *source, char *separator)
BOOL util_SplitMessage(char *source, char *separator)
{
if (source && separator) { // NULL input is invalid.
char *ptr;
char *head = source;
// Nuke 1006 : Bug fix
while ((ptr = (char *) strstr(head, separator)) && (SliceCount<SLICE_MAX) && (SliceCount>=0)) {
ptr[0] = '\0';
if (strlen(head)<SLICE_SIZE) { // discard slices too large
// Nuke 0701
// if (*MesgSlice != *dumb) {
//print("Warning! Mem may be broken\n");
//}
/*
if (MesgSlice[SliceCount]==0xffffffff) {
print("MesgSlice[%d] broken\n",SliceCount);
return FALSE;
} else {
*/
strcpy(MesgSlice[SliceCount], head);
SliceCount++;
//}
}
head = ptr+1;
}
strcpy(source, head); // remove splited slices
}
return TRUE;
}
// -------------------------------------------------------------------
// Encode the message
//
// arg: dst=output src=input
// ret: (none)
void util_EncodeMessage(char *dst, char *src)
{
// strcpy(dst, src);
// util_xorstring(dst, src);
int rn = rand() % 99;
int t1, t2;
char t3[1024*64], tz[1024*64];
util_swapint(&t1, &rn, "2413");
t2 = t1 ^ 0xffffffff;
util_256to64(tz, (char *) &t2, sizeof(int), DEFAULTTABLE);
util_shlstring(t3, src, rn);
strcat(tz, t3);
util_xorstring(dst, tz);
}
// -------------------------------------------------------------------
// Decode the message
//
// arg: dst=output src=input
// ret: (none)
void util_DecodeMessage(char *dst, char *src)
{
// strcpy(dst, src);
// util_xorstring(dst, src);
#define INTCODESIZE (sizeof(int)*8+5)/6
int rn;
int *t1, t2;
char t3[1024*4], t4[1024*4]; // This buffer is enough for an integer.
char tz[1024*64];
if (src[strlen(src)-1]=='\n') src[strlen(src)-1]='\0';
util_xorstring(tz, src);
// get seed
strncpy(t4, tz, INTCODESIZE);
t4[INTCODESIZE] = '\0';
util_64to256(t3, t4, DEFAULTTABLE);
t1 = (int *) t3;
t2 = *t1 ^ 0xffffffff;
util_swapint(&rn, &t2, "3142");
util_shrstring(dst, tz + INTCODESIZE, rn);
}
// -------------------------------------------------------------------
// Get a function information from MesgSlice. A function is a complete
// and identifiable message received, beginned at DEFAULTFUNCBEGIN and
// ended at DEFAULTFUNCEND. This routine will return the function ID
// (Action ID) and how many fields this function have.
//
// arg: func=return function ID fieldcount=return fields of the function
// ret: 1=success 0=failed (function not complete)
int util_GetFunctionFromSlice(int *func, int *fieldcount)
{
char t1[1024*16];
int i;
// if (strcmp(MesgSlice[0], DEFAULTFUNCBEGIN)!=0) util_DiscardMessage();
strcpy(t1, MesgSlice[1]);
// Robin adjust
//*func=atoi(t1);
*func=atoi(t1)-13;
for (i=0; i<SLICE_MAX; i++)
if (strcmp(MesgSlice[i], DEFAULTFUNCEND)==0) {
*fieldcount=i-2; // - "&" - "#" - "func" 3 fields
return 1;
}
return 0; // failed: message not complete
}
void util_DiscardMessage(void)
{
SliceCount=0;
}
extern int clisendfunc;
void _util_SendMesg(char *file, int line, int fd, int func, char *buffer)
{
//print("\nfunc=%d,buff=%s\n",func,buffer);
// char t1[16384], t2[16384];
char t1[1024*32], t2[1024*32];
clisendfunc=func;
// WON ADD
if( fd < 0 ){
//print("\n SendMesg fd err %s:%d!! ==> func(%d)\n", file, line, func);
return;
}
// Robin adjust
//sprintf(t1, "&;%d%s;#;", func, buffer);
sprintf(t1, "&;%d%s;#;", func+23, buffer);
util_EncodeMessage(t2, t1);
#ifdef __STONEAGE
lssproto_Send(fd, t2);
#endif
}
int util_256to64(char *dst, char *src, int len, char *table)
{
unsigned int dw,dwcounter,i;
if (!dst || !src || !table) return 0;
dw=0;
dwcounter=0;
for (i=0; i<len; i++) {
dw = ( ((unsigned int)src[i] & 0xff) << ((i%3)*2) ) | dw;
dst[ dwcounter++ ] = table[ dw & 0x3f ];
dw = ( dw >> 6 );
if (i%3==2) {
dst[ dwcounter++ ] = table[ dw & 0x3f ];
dw = 0;
}
}
if (dw) dst[ dwcounter++ ] = table[ dw ];
dst[ dwcounter ] = '\0';
return dwcounter;
}
// -------------------------------------------------------------------
// Convert 6-bit strings into 8-bit strings, buffers that store these strings
// must have enough space.
//
// arg: dst=6-bit string; src=8-bit string; table=mapping table
// ret: 0=failed >0=bytes converted
int util_64to256(char *dst, char *src, char *table)
{
unsigned int dw,dwcounter,i;
char *ptr = NULL;
dw=0;
dwcounter=0;
if (!dst || !src || !table) return 0;
for (i=0; i<strlen(src); i++) {
ptr = (char *) index(table, src[i]);
if (!ptr) return 0;
if (i%4) {
dw = ((unsigned int)(ptr-table) & 0x3f) << ((4-(i%4))*2) | dw;
dst[ dwcounter++ ] = dw & 0xff;
dw = dw >> 8;
} else {
dw = (unsigned int)(ptr-table) & 0x3f;
}
}
if (dw) dst[ dwcounter++ ] = dw & 0xff;
dst[ dwcounter ] = '\0';
return dwcounter;
}
// -------------------------------------------------------------------
// This basically is a 256to64 encoder. But it shifts the result by key.
//
// arg: dst=6-bit string; src=8-bit string; len=src strlen;
// table=mapping table; key=rotate key;
// ret: 0=failed >0=bytes converted
int util_256to64_shr(char *dst, char *src, int len, char *table, char *key)
{
unsigned int dw,dwcounter,i,j;
if (!dst || !src || !table || !key) return 0;
if (strlen(key)<1) return 0; // key can't be empty.
dw=0;
dwcounter=0;
j=0;
for (i=0; i<len; i++) {
dw = ( ((unsigned int)src[i] & 0xff) << ((i%3)*2) ) | dw;
dst[ dwcounter++ ] = table[ ((dw & 0x3f) + key[j]) % 64 ]; // check!
j++; if (!key[j]) j=0;
dw = ( dw >> 6 );
if (i%3==2) {
dst[ dwcounter++ ] = table[ ((dw & 0x3f) + key[j]) % 64 ];// check!
j++; if (!key[j]) j=0;
dw = 0;
}
}
if (dw) dst[ dwcounter++ ] = table[ (dw + key[j]) % 64 ]; // check!
dst[ dwcounter ] = '\0';
return dwcounter;
}
// -------------------------------------------------------------------
// Decoding function of util_256to64_shr.
//
// arg: dst=8-bit string; src=6-bit string; table=mapping table;
// key=rotate key;
// ret: 0=failed >0=bytes converted
int util_shl_64to256(char *dst, char *src, char *table, char *key)
{
unsigned int dw,dwcounter,i,j;
char *ptr = NULL;
if (!key || (strlen(key)<1)) return 0; // must have key
dw=0;
dwcounter=0;
j=0;
if (!dst || !src || !table) return 0;
for (i=0; i<strlen(src); i++) {
ptr = (char *) index(table, src[i]);
if (!ptr) return 0;
if (i%4) {
// check!
dw = ((((unsigned int)(ptr-table) & 0x3f) + 64 - key[j]) % 64)
<< ((4-(i%4))*2) | dw;
j++; if (!key[j]) j=0;
dst[ dwcounter++ ] = dw & 0xff;
dw = dw >> 8;
} else {
// check!
dw = (((unsigned int)(ptr-table) & 0x3f) + 64 - key[j]) % 64;
j++; if (!key[j]) j=0;
}
}
if (dw) dst[ dwcounter++ ] = dw & 0xff;
dst[ dwcounter ] = '\0';
return dwcounter;
}
// -------------------------------------------------------------------
// This basically is a 256to64 encoder. But it shifts the result by key.
//
// arg: dst=6-bit string; src=8-bit string; len=src strlen;
// table=mapping table; key=rotate key;
// ret: 0=failed >0=bytes converted
int util_256to64_shl(char *dst, char *src, int len, char *table, char *key)
{
unsigned int dw,dwcounter,i,j;
if (!dst || !src || !table || !key) return 0;
if (strlen(key)<1) return 0; // key can't be empty.
dw=0;
dwcounter=0;
j=0;
for (i=0; i<len; i++) {
dw = ( ((unsigned int)src[i] & 0xff) << ((i%3)*2) ) | dw;
dst[ dwcounter++ ] = table[ ((dw & 0x3f) + 64 - key[j]) % 64 ]; // check!
j++; if (!key[j]) j=0;
dw = ( dw >> 6 );
if (i%3==2) {
dst[ dwcounter++ ] = table[ ((dw & 0x3f) + 64 - key[j]) % 64 ]; // check!
j++; if (!key[j]) j=0;
dw = 0;
}
}
if (dw) dst[ dwcounter++ ] = table[ (dw + 64 - key[j]) % 64 ]; // check!
dst[ dwcounter ] = '\0';
return dwcounter;
}
// -------------------------------------------------------------------
// Decoding function of util_256to64_shl.
//
// arg: dst=8-bit string; src=6-bit string; table=mapping table;
// key=rotate key;
// ret: 0=failed >0=bytes converted
int util_shr_64to256(char *dst, char *src, char *table, char *key)
{
unsigned int dw,dwcounter,i,j;
char *ptr = NULL;
if (!key || (strlen(key)<1)) return 0; // must have key
dw=0;
dwcounter=0;
j=0;
if (!dst || !src || !table) return 0;
for (i=0; i<strlen(src); i++) {
ptr = (char *) index(table, src[i]);
if (!ptr) return 0;
if (i%4) {
// check!
dw = ((((unsigned int)(ptr-table) & 0x3f) + key[j]) % 64)
<< ((4-(i%4))*2) | dw;
j++; if (!key[j]) j=0;
dst[ dwcounter++ ] = dw & 0xff;
dw = dw >> 8;
} else {
// check!
dw = (((unsigned int)(ptr-table) & 0x3f) + key[j]) % 64;
j++; if (!key[j]) j=0;
}
}
if (dw) dst[ dwcounter++ ] = dw & 0xff;
dst[ dwcounter ] = '\0';
return dwcounter;
}
// -------------------------------------------------------------------
// Swap a integer (4 byte).
// The value "rule" indicates the swaping rule. It's a 4 byte string
// such as "1324" or "2431".
//
void util_swapint(int *dst, int *src, char *rule)
{
char *ptr, *qtr;
int i;
ptr = (char *) src;
qtr = (char *) dst;
for (i=0; i<4; i++) qtr[rule[i]-'1']=ptr[i];
}
// -------------------------------------------------------------------
// Xor a string. Be careful that your string contains '0xff'. Your
// data may lose.
//
void util_xorstring(char *dst, char *src)
{
int i;
if (strlen(src)>1024*64) return;
for (i=0; i<strlen(src); i++){
dst[i]=src[i]^255;
}
dst[i]='\0';
}
// -------------------------------------------------------------------
// Shift the string right.
//
void util_shrstring(char *dst, char *src, int offs)
{
char *ptr;
if (!dst || !src || (strlen(src)<1)) return;
offs = strlen(src) - (offs % strlen(src));
ptr = src+offs;
strcpy(dst, ptr);
strncat(dst, src, offs);
dst[strlen(src)]='\0';
}
// -------------------------------------------------------------------
// Shift the string left.
//
void util_shlstring(char *dst, char *src, int offs)
{
char *ptr;
if (!dst || !src || (strlen(src)<1)) return;
offs = offs % strlen(src);
ptr = src+offs;
strcpy(dst, ptr);
strncat(dst, src, offs);
dst[strlen(src)]='\0';
}
// -------------------------------------------------------------------
// Convert a message slice into integer. Return a checksum.
//
// arg: sliceno=slice index in MesgSlice value=result
// ret: checksum, this value must match the one generated by util_mkint
int util_deint(int fd,int sliceno, int *value)
{
int *t1, t2;
char t3[1024*4]; // This buffer is enough for an integer.
if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd));
util_shl_64to256(t3, MesgSlice[sliceno], DEFAULTTABLE, PersonalKey);
t1 = (int *) t3;
t2 = *t1 ^ 0xffffffff;
util_swapint(value, &t2, "2413");
return *value;
}
int util_mkint(int fd,char *buffer, int value)
{
int t1, t2;
char t3[1024*4];
if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd));
util_swapint(&t1, &value, "3142");
t2 = t1 ^ 0xffffffff;
util_256to64_shr(t3, (char *) &t2, sizeof(int), DEFAULTTABLE, PersonalKey);
strcat(buffer, ";");
strcat(buffer, t3);
return value;
}
// -------------------------------------------------------------------
// Convert a message slice into string. Return a checksum.
//
// arg: sliceno=slice index in MesgSlice value=result
// ret: checksum, this value must match the one generated by util_mkstring
int util_destring(int fd,int sliceno, char *value)
{
if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd));
util_shr_64to256(value, MesgSlice[sliceno], DEFAULTTABLE, PersonalKey);
return strlen(value);
}
// -------------------------------------------------------------------
// Convert a string into buffer (a string). Return a checksum.
//
// arg: buffer=output value=data to pack
// ret: checksum, this value must match the one generated by util_destring
int util_mkstring(int fd,char *buffer, char *value)
{
char t1[SLICE_SIZE];
if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd));
util_256to64_shl(t1, value, strlen(value), DEFAULTTABLE, PersonalKey);
strcat(buffer, ";"); // It's important to append a SEPARATOR between fields
strcat(buffer, t1);
return strlen(value);
}
#ifdef _FIX_LSSP_S_BUG
int is_digit(char *str)
{
uint len = strlen(str);
while(len > 0) {
if (*str < '0' || *str > '9') {
return -1;
}
str++;
len--;
}
return 0;
}
#endif