⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actions.c

📁 Flush解码源程序
💻 C
字号:
#include <ctype.h>#include <string.h>#include <math.h>#include "swfdec_internal.h"#define DEBUG printftypedef struct {	void *SwfdecDecoder;} SwfdecActionContext;typedef struct {	int type;	char *s;	double num;} SwfdecActionVal;enum {	ACTIONVAL_TYPE_UNKNOWN = 0,	ACTIONVAL_TYPE_BOOLEAN,	ACTIONVAL_TYPE_INTEGER,	ACTIONVAL_TYPE_DOUBLE,	ACTIONVAL_TYPE_STRING,};#define ACTIONVAL_IS_BOOLEAN(val) ((val)->type == ACTIONVAL_TYPE_BOOLEAN)#define ACTIONVAL_IS_INTEGER(val) ((val)->type == ACTIONVAL_TYPE_INTEGER)#define ACTIONVAL_IS_DOUBLE(val) ((val)->type == ACTIONVAL_TYPE_DOUBLE)#define ACTIONVAL_IS_STRING(val) ((val)->type == ACTIONVAL_TYPE_STRING)#define ACTIONVAL_IS_NUM(val) (ACTIONVAL_IS_BOOLEAN(val) || \		ACTIONVAL_IS_INTEGER(val) || ACTIONVAL_IS_DOUBLE(val))typedef int SwfdecActionFunc(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2);static SwfdecActionFunc	action_add,	action_subtract,	action_multiply,	action_divide,	action_equal,	action_less_than,	action_logical_and,	action_logical_or,	action_logical_not,	action_string_equal,	action_string_length,	action_substring,	action_int,	action_string_concat;struct action_struct {	int action;	char * name;	SwfdecActionFunc *func;	int n_src;	int n_dest;};static struct action_struct actions[] = {	{ 0x04, "next frame",		NULL,			0, 0 },	{ 0x05, "prev frame",		NULL,			0, 0 },	{ 0x06, "play",			NULL,			0, 0 },	{ 0x07, "stop",			NULL,			0, 0 },	{ 0x08, "toggle quality",	NULL,			0, 0 },	{ 0x09, "stop sounds",		NULL,			0, 0 },	{ 0x0a, "add",			action_add,		2, 1 },	{ 0x0b, "subtract",		action_subtract,	2, 1 },	{ 0x0c, "multiply",		action_multiply,	2, 1 },	{ 0x0d, "divide",		action_divide,		2, 1 },	{ 0x0e, "equal",		action_equal,		2, 1 },	{ 0x0f, "less than",		action_less_than,	2, 1 },	{ 0x10, "and",			action_logical_and,	2, 1 },	{ 0x11, "or",			action_logical_or,	2, 1 },	{ 0x12, "not",			action_logical_not,	1, 1 },	{ 0x13, "string equal",		action_string_equal,	2, 1 },	{ 0x14, "string length",	action_string_length,	1, 1 },	{ 0x15, "substring",		action_substring,	3, 1 },//	{ 0x17, "unknown",		NULL },	{ 0x18, "int",			action_int,		1, 1 },	{ 0x1c, "eval",			NULL,			1, 1 },	{ 0x1d, "set variable",		NULL,			2, 0 },	{ 0x20, "set target expr",	NULL,			1, 0 },	{ 0x21, "string concat",	action_string_concat,	2, 1 },	{ 0x22, "get property",		NULL,			2, 1 },	{ 0x23, "set property",		NULL,			3, 0 },	{ 0x24, "duplicate clip",	NULL,			3, 0 },	{ 0x25, "remove clip",		NULL,			1, 0 },	{ 0x26, "trace",		NULL,			0, 0 },	{ 0x27, "start drag movie",	NULL,			3, 0 }, /* 3 or 7 */	{ 0x28, "stop drag movie",	NULL,			0, 0 },	{ 0x29, "string compare",	NULL,			2, 1 },	{ 0x30, "random",		NULL,			1, 1 },	{ 0x31, "mb length",		NULL,			1, 1 },	{ 0x32, "ord",			NULL,			1, 1 },	{ 0x33, "chr",			NULL,			1, 1 },	{ 0x34, "get timer",		NULL,			0, 1 },	{ 0x35, "mb substring",		NULL,			3, 1 },	{ 0x36, "mb ord",		NULL,			1, 1 },	{ 0x37, "mb chr",		NULL,			1, 1 },	{ 0x3b, "call function",	NULL },	{ 0x3a, "delete",		NULL },	{ 0x3c, "declare local var",	NULL },//	{ 0x3d, "unknown",		NULL },	{ 0x3e, "return from function",	NULL },	{ 0x3f, "modulo",		NULL },	{ 0x40, "instantiate",		NULL },//	{ 0x41, "unknown",		NULL },	{ 0x44, "typeof",		NULL },	{ 0x46, "unknown",		NULL },	{ 0x47, "add",			NULL },	{ 0x48, "less than",		NULL },	{ 0x49, "equals",		NULL },	{ 0x4c, "make boolean",		NULL },	{ 0x4e, "get member",		NULL },	{ 0x4f, "set member",		NULL },	{ 0x50, "increment",		NULL },	{ 0x52, "call method",		NULL },	{ 0x60, "bitwise and",		NULL },	{ 0x61, "bitwise or",		NULL },	{ 0x62, "bitwise xor",		NULL },	{ 0x63, "shift left",		NULL },	{ 0x64, "shift right",		NULL },	{ 0x65, "rotate right",		NULL },//	{ 0x67, "unknown",		NULL },	{ 0x81, "goto frame",		NULL },	{ 0x83, "get url",		NULL },	{ 0x87, "get next dict member",	NULL },	{ 0x88, "declare dictionary",	NULL },	{ 0x8a, "wait for frame",	NULL },//	{ 0x8b, "unknown",		NULL },//	{ 0x8c, "unknown",		NULL },	{ 0x8d, "wait for frame expr",	NULL,			1, 0 },	{ 0x94, "with",			NULL },	{ 0x96, "push data",		NULL },	{ 0x99, "branch",		NULL,			0, 0 },	{ 0x9a, "get url2",		NULL,			2, 0 },	{ 0x9b, "declare function",	NULL },	{ 0x9d, "branch if",		NULL,			1, 0 },	{ 0x9e, "call frame",		NULL,			1, 0 },	{ 0x9f, "goto expr",		NULL,			1, 0 },//	{ 0xb7, "unknown",		NULL },/* in 1394C148d01.swf */	{ 0x8b, "unknown",		NULL },	{ 0x8c, "unknown",		NULL },};static int n_actions = sizeof(actions)/sizeof(actions[0]);static void hexdump(unsigned char *data, int len){	int i;	int j;	while(len>0){		printf("    ");		j = (len<16)?len:16;		for(i=0;i<j;i++){			printf("%02x ",data[i]);		}		for(;i<16;i++){			printf("   ");		}		for(i=0;i<j;i++){			printf("%c",isprint(data[i])?data[i]:'.');		}		printf("\n");		data += j;		len -= j;	}}void get_actions(SwfdecDecoder *s,bits_t *bits){	int action;	int len;	//int index;	//int skip_count;	int i;	SWF_DEBUG(0,"get_actions\n");	while(1){		action = get_u8(bits);		if(action==0)break;		if(action&0x80){			len = get_u16(bits);		}else{			len = 0;		}		for(i=0;i<n_actions;i++){			if(actions[i].action == action){				if(s->debug<1){					printf("  [%02x] %s\n",action, actions[i].name);				}				break;			}		}		if(i==n_actions){			if(s->debug<3){				printf("  [%02x] *** unknown action\n",action);			}		}		if(s->debug<1){			hexdump(bits->ptr, len);		}		bits->ptr += len;	}}int tag_func_do_action(SwfdecDecoder *s){	get_actions(s,&s->b);	return SWF_OK;}int swfdec_action_script_execute(SwfdecDecoder *s, bits_t *bits){	int action;	int len;	//int index;	//int skip_count;	int i;	SWF_DEBUG(0,"swfdec_action_script_execute\n");	while(1){		action = get_u8(bits);		if(action==0)break;		if(action&0x80){			len = get_u16(bits);		}else{			len = 0;		}		for(i=0;i<n_actions;i++){			if(actions[i].action == action){				if(s->debug<1){					printf("  [%02x] %s\n",action, actions[i].name);				}				break;			}		}		if(i==n_actions){			if(s->debug<3){				printf("  [%02x] *** unknown action\n",action);			}		}		hexdump(bits->ptr, len);		bits->ptr += len;	}	return SWF_OK;}static int action_promote(SwfdecActionVal *src1, SwfdecActionVal *src2){	if(ACTIONVAL_IS_DOUBLE(src1))return ACTIONVAL_TYPE_DOUBLE;	if(ACTIONVAL_IS_DOUBLE(src2))return ACTIONVAL_TYPE_DOUBLE;	if(ACTIONVAL_IS_INTEGER(src1))return ACTIONVAL_TYPE_INTEGER;	if(ACTIONVAL_IS_INTEGER(src2))return ACTIONVAL_TYPE_INTEGER;	return ACTIONVAL_TYPE_BOOLEAN;}static SwfdecActionVal *action_pop(SwfdecActionContext *context){	/* FIXME unimplemented */	return NULL;}static int action_add(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_NUM(src1) && ACTIONVAL_IS_NUM(src2)){		dest->type = action_promote(src1,src2);		dest->num = src1->num + src2->num;	}else if(ACTIONVAL_IS_STRING(src1) && ACTIONVAL_IS_STRING(src2)){		dest->type = ACTIONVAL_TYPE_STRING;		dest->s = malloc(strlen(src1->s) + strlen(src2->s) + 1);		strcpy(dest->s, src1->s);		strcat(dest->s, src2->s);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_subtract(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_NUM(src1) && ACTIONVAL_IS_NUM(src2)){		dest->type = action_promote(src1,src2);		dest->num = src1->num - src2->num;	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_multiply(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_NUM(src1) && ACTIONVAL_IS_NUM(src2)){		dest->type = action_promote(src1,src2);		dest->num = src1->num * src2->num;	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_divide(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_NUM(src1) && ACTIONVAL_IS_NUM(src2)){		dest->type = action_promote(src1,src2);		dest->num = src1->num / src2->num;	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_equal(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_NUM(src1) && ACTIONVAL_IS_NUM(src2)){		dest->type = ACTIONVAL_TYPE_BOOLEAN;		dest->num = (src1->num == src2->num);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_less_than(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_NUM(src1) && ACTIONVAL_IS_NUM(src2)){		dest->type = ACTIONVAL_TYPE_BOOLEAN;		dest->num = (src1->num < src2->num);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_logical_and(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_BOOLEAN(src1) && ACTIONVAL_IS_BOOLEAN(src2)){		dest->type = ACTIONVAL_TYPE_BOOLEAN;		dest->num = (src1->num && src2->num);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_logical_or(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_BOOLEAN(src1) && ACTIONVAL_IS_BOOLEAN(src2)){		dest->type = ACTIONVAL_TYPE_BOOLEAN;		dest->num = (src1->num || src2->num);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_logical_not(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2==NULL);	if(ACTIONVAL_IS_BOOLEAN(src1)){		dest->type = ACTIONVAL_TYPE_BOOLEAN;		dest->num = !src1->num;	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_string_equal(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_STRING(src1) && ACTIONVAL_IS_STRING(src2)){		dest->type = ACTIONVAL_TYPE_BOOLEAN;		dest->num = (strcmp(src1->s,src2->s)==0);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_string_length(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2==NULL);	if(ACTIONVAL_IS_STRING(src1)){		dest->type = ACTIONVAL_TYPE_INTEGER;		dest->num = strlen(src1->s);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_substring(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	unsigned int len;	unsigned int slen;	unsigned int offset;	SwfdecActionVal *src3;	g_assert(dest);	g_assert(src1);	g_assert(src2);	src3 = action_pop(context);	g_assert(src3);	if(ACTIONVAL_IS_STRING(src1) && ACTIONVAL_IS_NUM(src2) &&			ACTIONVAL_IS_NUM(src3)){		dest->type = ACTIONVAL_TYPE_STRING;		slen = strlen(src1->s);		offset = src2->num;		if(offset>slen)offset = slen;		len = src3->num;		if(len>slen - offset)len = slen - offset;		dest->s = malloc(len + 1);		memcpy(dest->s, src1->s + offset, len);		dest->s[len] = 0;	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_int(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2==NULL);	if(ACTIONVAL_IS_NUM(src1)){		dest->type = ACTIONVAL_TYPE_INTEGER;		dest->num = floor(src1->num);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}static int action_string_concat(SwfdecActionContext *context, SwfdecActionVal *dest,	SwfdecActionVal *src1, SwfdecActionVal *src2){	g_assert(dest);	g_assert(src1);	g_assert(src2);	if(ACTIONVAL_IS_STRING(src1) && ACTIONVAL_IS_STRING(src2)){		dest->type = ACTIONVAL_TYPE_STRING;		dest->s = malloc(strlen(src1->s) + strlen(src2->s) + 1);		strcpy(dest->s, src1->s);		strcat(dest->s, src2->s);	}else{		DEBUG("incompatible types\n");		return SWF_ERROR;	}	return SWF_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -