コード例 #1
0
size_t Handshake::deserialize(const Buffer& _src, size_t _offset)
{
	_offset = _pm_checkPacketId(_src, _offset);

	_offset = ReadInt8(_src, _offset, _pf_protVer);
	_offset = ReadString16(_src, _offset, _pf_username);
	_offset = ReadString16(_src, _offset, _pf_host);
	_offset = ReadInt32(_src, _offset, _pf_port);
	_pf_initialized = true;
	return _offset;
}
コード例 #2
0
size_t ChatMessage::deserialize(const Buffer& _src, size_t _offset)
{
	_offset = _pm_checkPacketId(_src, _offset);

	_offset = ReadString16(_src, _offset, _pf_text);
	_pf_initialized = true;
	return _offset;
}
コード例 #3
0
size_t DisplayScoreboard::deserialize(const Buffer& _src, size_t _offset)
{
	_offset = _pm_checkPacketId(_src, _offset);

	_offset = ReadInt8(_src, _offset, _pf_position);
	_offset = ReadString16(_src, _offset, _pf_scoreName);
	_pf_initialized = true;
	return _offset;
}
コード例 #4
0
size_t Particle::deserialize(const Buffer& _src, size_t _offset)
{
	_offset = _pm_checkPacketId(_src, _offset);

	_offset = ReadString16(_src, _offset, _pf_particleName);
	_offset = ReadFloat(_src, _offset, _pf_x);
	_offset = ReadFloat(_src, _offset, _pf_y);
	_offset = ReadFloat(_src, _offset, _pf_z);
	_offset = ReadFloat(_src, _offset, _pf_offsetX);
	_offset = ReadFloat(_src, _offset, _pf_offsetY);
	_offset = ReadFloat(_src, _offset, _pf_offsetZ);
	_offset = ReadFloat(_src, _offset, _pf_particleSpeed);
	_offset = ReadInt32(_src, _offset, _pf_numOfParticles);
	_pf_initialized = true;
	return _offset;
}
コード例 #5
0
FString FKismetBytecodeDisassembler::ReadString(int32& ScriptIndex)
{
	const EExprToken Opcode = (EExprToken)Script[ScriptIndex++];

	switch (Opcode)
	{
	case EX_StringConst:
		return ReadString8(ScriptIndex);

	case EX_UnicodeStringConst:
		return ReadString16(ScriptIndex);

	default:
		checkf(false, TEXT("FKismetBytecodeDisassembler::ReadString - Unexpected opcode. Expected %d or %d, got %d"), EX_StringConst, EX_UnicodeStringConst, Opcode);
		break;
	}

	return FString();
}
コード例 #6
0
void FKismetBytecodeDisassembler::ProcessCommon(int32& ScriptIndex, EExprToken Opcode)
{
	switch (Opcode)
	{
	case EX_PrimitiveCast:
		{
			// A type conversion.
			uint8 ConversionType = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: PrimitiveCast of type %d"), *Indents, (int32)Opcode, ConversionType);
			AddIndent();

			Ar.Logf(TEXT("%s Argument:"), *Indents);
			ProcessCastByte(ConversionType, ScriptIndex);

			//@TODO:
			//Ar.Logf(TEXT("%s Expression:"), *Indents);
			//SerializeExpr( ScriptIndex );
			break;
		}
	case EX_ObjToInterfaceCast:
		{
			// A conversion from an object variable to a native interface variable.
			// We use a different bytecode to avoid the branching each time we process a cast token

			// the interface class to convert to
			UClass* InterfaceClass = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: ObjToInterfaceCast to %s"), *Indents, (int32)Opcode, *InterfaceClass->GetName());

			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_CrossInterfaceCast:
		{
			// A conversion from one interface variable to a different interface variable.
			// We use a different bytecode to avoid the branching each time we process a cast token

			// the interface class to convert to
			UClass* InterfaceClass = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: InterfaceToInterfaceCast to %s"), *Indents, (int32)Opcode, *InterfaceClass->GetName());

			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_InterfaceToObjCast:
		{
			// A conversion from an interface variable to a object variable.
			// We use a different bytecode to avoid the branching each time we process a cast token

			// the interface class to convert to
			UClass* ObjectClass = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: InterfaceToObjCast to %s"), *Indents, (int32)Opcode, *ObjectClass->GetName());

			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_Let:
		{
			Ar.Logf(TEXT("%s $%X: Let (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );

			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetObj:
	case EX_LetWeakObjPtr:
		{
			if( Opcode == EX_LetObj )
			{
				Ar.Logf(TEXT("%s $%X: Let Obj (Variable = Expression)"), *Indents, (int32)Opcode);
			}
			else
			{
				Ar.Logf(TEXT("%s $%X: Let WeakObjPtr (Variable = Expression)"), *Indents, (int32)Opcode);
			}
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );

			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetBool:
		{
			Ar.Logf(TEXT("%s $%X: LetBool (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );

			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case Ex_LetValueOnPersistentFrame:
		{
			Ar.Logf(TEXT("%s $%X: LetValueOnPersistentFrame"), *Indents, (int32)Opcode);
			AddIndent();

			auto Prop = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s Destination variable: %s, offset: %d"), *Indents, *GetNameSafe(Prop), 
				Prop ? Prop->GetOffset_ForDebug() : 0);
			
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr(ScriptIndex);

			DropIndent();

			break;
		}
	case EX_StructMemberContext:
		{
			Ar.Logf(TEXT("%s $%X: Struct member context "), *Indents, (int32)Opcode);
			AddIndent();

			UProperty* Prop = ReadPointer<UProperty>(ScriptIndex);

			Ar.Logf(TEXT("%s Expression within struct %s, offset %d"), *Indents, *(Prop->GetName()), 
				Prop->GetOffset_ForDebug()); // although that isn't a UFunction, we are not going to indirect the props of a struct, so this should be fine

			Ar.Logf(TEXT("%s Expression to struct:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();

			break;
		}
	case EX_LetDelegate:
		{
			Ar.Logf(TEXT("%s $%X: LetDelegate (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );
				
			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: LetMulticastDelegate (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );
				
			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}

	case EX_ComputedJump:
		{
			Ar.Logf(TEXT("%s $%X: Computed Jump, offset specified by expression:"), *Indents, (int32)Opcode);

			AddIndent();
			SerializeExpr( ScriptIndex );
			DropIndent();

			break;
		}

	case EX_Jump:
		{
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Jump to offset 0x%X"), *Indents, (int32)Opcode, SkipCount);
			break;
		}
	case EX_LocalVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Local variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_InstanceVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Instance variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_LocalOutVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Local out variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_InterfaceContext:
		{
			Ar.Logf(TEXT("%s $%X: EX_InterfaceContext:"), *Indents, (int32)Opcode);
			SerializeExpr(ScriptIndex);
			break;
		}
	case EX_DeprecatedOp4A:
		{
			Ar.Logf(TEXT("%s $%X: This opcode has been removed and does nothing."), *Indents, (int32)Opcode);
			break;
		}
	case EX_Nothing:
		{
			Ar.Logf(TEXT("%s $%X: EX_Nothing"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndOfScript:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndOfScript"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndFunctionParms:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndFunctionParms"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndStructConst:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndStructConst"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndArray:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndArray"), *Indents, (int32)Opcode);
			break;
		}
	case EX_IntZero:
		{
			Ar.Logf(TEXT("%s $%X: EX_IntZero"), *Indents, (int32)Opcode);
			break;
		}
	case EX_IntOne:
		{
			Ar.Logf(TEXT("%s $%X: EX_IntOne"), *Indents, (int32)Opcode);
			break;
		}
	case EX_True:
		{
			Ar.Logf(TEXT("%s $%X: EX_True"), *Indents, (int32)Opcode);
			break;
		}
	case EX_False:
		{
			Ar.Logf(TEXT("%s $%X: EX_False"), *Indents, (int32)Opcode);
			break;
		}
	case EX_NoObject:
		{
			Ar.Logf(TEXT("%s $%X: EX_NoObject"), *Indents, (int32)Opcode);
			break;
		}
	case EX_NoInterface:
		{
			Ar.Logf(TEXT("%s $%X: EX_NoObject"), *Indents, (int32)Opcode);
			break;
		}
	case EX_Self:
		{
			Ar.Logf(TEXT("%s $%X: EX_Self"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndParmValue:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndParmValue"), *Indents, (int32)Opcode);
			break;
		}
	case EX_Return:
		{
			Ar.Logf(TEXT("%s $%X: Return expression"), *Indents, (int32)Opcode);

			SerializeExpr( ScriptIndex ); // Return expression.
			break;
		}
	case EX_FinalFunction:
		{
			UStruct* StackNode = ReadPointer<UStruct>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Final Function (stack node %s::%s)"), *Indents, (int32)Opcode, StackNode ? *StackNode->GetOuter()->GetName() : TEXT("(null)"), StackNode ? *StackNode->GetName() : TEXT("(null)"));

			while (SerializeExpr( ScriptIndex ) != EX_EndFunctionParms)
			{
				// Params
			}
			break;
		}
	case EX_CallMulticastDelegate:
		{
			UStruct* StackNode = ReadPointer<UStruct>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: CallMulticastDelegate (signature %s::%s) delegate:"), *Indents, (int32)Opcode, StackNode ? *StackNode->GetOuter()->GetName() : TEXT("(null)"), StackNode ? *StackNode->GetName() : TEXT("(null)"));
			SerializeExpr( ScriptIndex );
			Ar.Logf(TEXT("Params:"));
			while (SerializeExpr( ScriptIndex ) != EX_EndFunctionParms)
			{
				// Params
			}
			break;
		}
	case EX_VirtualFunction:
		{
			FString FunctionName = ReadName(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Virtual Function named %s"), *Indents, (int32)Opcode, *FunctionName);

			while (SerializeExpr(ScriptIndex) != EX_EndFunctionParms)
			{
			}
			break;
		}
	case EX_Context:
	case EX_Context_FailSilent:
		{
			Ar.Logf(TEXT("%s $%X: %s"), *Indents, (int32)Opcode, TEXT("Context"));
			AddIndent();

			// Object expression.
			Ar.Logf(TEXT("%s ObjectExpression:"), *Indents);
			SerializeExpr( ScriptIndex );

			if (Opcode == EX_Context_FailSilent)
			{
				Ar.Logf(TEXT(" Can fail silently on access none "));
			}

			// Code offset for NULL expressions.
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s Skip Bytes: 0x%X"), *Indents, SkipCount);

			// Property corresponding to the r-value data, in case the l-value needs to be mem-zero'd
			UField* Field = ReadPointer<UField>(ScriptIndex);
			Ar.Logf(TEXT("%s R-Value Property: %s"), *Indents, Field ? *Field->GetName() : TEXT("(null)"));

			// Property type, in case the r-value is a non-property such as dynamic array length
			uint8 PropType = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s PropertyTypeIfNeeded: %d"), *Indents, PropType);

			// Context expression.
			Ar.Logf(TEXT("%s ContextExpression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_IntConst:
		{
			int32 ConstValue = ReadINT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal int32 %d"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_SkipOffsetConst:
		{
			CodeSkipSizeType ConstValue = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal CodeSkipSizeType 0x%X"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_FloatConst:
		{
			float ConstValue = ReadFLOAT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal float %f"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_StringConst:
		{
			FString ConstValue = ReadString8(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal ansi string \"%s\""), *Indents, (int32)Opcode, *ConstValue);
			break;
		}
	case EX_UnicodeStringConst:
		{
			FString ConstValue = ReadString16(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal unicode string \"%s\""), *Indents, (int32)Opcode, *ConstValue);
			break;
		}
	case EX_TextConst:
		{
			Ar.Logf(TEXT("%s $%X: literal text"), *Indents, (int32)Opcode);
			break;
		}
	case EX_ObjectConst:
		{
			UObject* Pointer = ReadPointer<UObject>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: EX_ObjectConst (%p:%s)"), *Indents, (int32)Opcode, Pointer, *Pointer->GetFullName());
			break;
		}
	case EX_NameConst:
		{
			FString ConstValue = ReadName(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal name %s"), *Indents, (int32)Opcode, *ConstValue);
			break;
		}
	case EX_RotationConst:
		{
			float Pitch = ReadFLOAT(ScriptIndex);
			float Yaw = ReadFLOAT(ScriptIndex);
			float Roll = ReadFLOAT(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: literal rotation (%f,%f,%f)"), *Indents, (int32)Opcode, Pitch, Yaw, Roll);
			break;
		}
	case EX_VectorConst:
		{
			float X = ReadFLOAT(ScriptIndex);
			float Y = ReadFLOAT(ScriptIndex);
			float Z = ReadFLOAT(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: literal vector (%f,%f,%f)"), *Indents, (int32)Opcode, X, Y, Z);
			break;
		}
	case EX_TransformConst:
		{

			float RotX = ReadFLOAT(ScriptIndex);
			float RotY = ReadFLOAT(ScriptIndex);
			float RotZ = ReadFLOAT(ScriptIndex);
			float RotW = ReadFLOAT(ScriptIndex);

			float TransX = ReadFLOAT(ScriptIndex);
			float TransY = ReadFLOAT(ScriptIndex);
			float TransZ = ReadFLOAT(ScriptIndex);

			float ScaleX = ReadFLOAT(ScriptIndex);
			float ScaleY = ReadFLOAT(ScriptIndex);
			float ScaleZ = ReadFLOAT(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: literal transform R(%f,%f,%f,%f) T(%f,%f,%f) S(%f,%f,%f)"), *Indents, (int32)Opcode, TransX, TransY, TransZ, RotX, RotY, RotZ, RotW, ScaleX, ScaleY, ScaleZ);
			break;
		}
	case EX_StructConst:
		{
			UScriptStruct* Struct = ReadPointer<UScriptStruct>(ScriptIndex);
			int32 SerializedSize = ReadINT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal struct %s (serialized size: %d)"), *Indents, (int32)Opcode, *Struct->GetName(), SerializedSize);
			while( SerializeExpr(ScriptIndex) != EX_EndStructConst )
			{
				// struct contents
			}
			break;
		}
	case EX_SetArray:
		{
 			Ar.Logf(TEXT("%s $%X: set array"), *Indents, (int32)Opcode);
			SerializeExpr(ScriptIndex);
 			while( SerializeExpr(ScriptIndex) != EX_EndArray)
 			{
 				// Array contents
 			}
 			break;
		}
	case EX_ByteConst:
		{
			uint8 ConstValue = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal byte %d"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_IntConstByte:
		{
			int32 ConstValue = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal int %d"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_MetaCast:
		{
			UClass* Class = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: MetaCast to %s of expr:"), *Indents, (int32)Opcode, *Class->GetName());
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_DynamicCast:
		{
			UClass* Class = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: DynamicCast to %s of expr:"), *Indents, (int32)Opcode, *Class->GetName());
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_JumpIfNot:
		{
			// Code offset.
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
				
			Ar.Logf(TEXT("%s $%X: Jump to offset 0x%X if not expr:"), *Indents, (int32)Opcode, SkipCount);

			// Boolean expr.
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_Assert:
		{
			uint16 LineNumber = ReadWORD(ScriptIndex);
			uint8 InDebugMode = ReadBYTE(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: assert at line %d, in debug mode = %d with expr:"), *Indents, (int32)Opcode, LineNumber, InDebugMode);
			SerializeExpr( ScriptIndex ); // Assert expr.
			break;
		}
	case EX_Skip:
		{
			CodeSkipSizeType W = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: possibly skip 0x%X bytes of expr:"), *Indents, (int32)Opcode, W);

			// Expression to possibly skip.
			SerializeExpr( ScriptIndex );

			break;
		}
	case EX_InstanceDelegate:
		{
			// the name of the function assigned to the delegate.
			FString FuncName = ReadName(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: instance delegate function named %s"), *Indents, (int32)Opcode, *FuncName);
			break;
		}
	case EX_AddMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: Add MC delegate"), *Indents, (int32)Opcode);
			SerializeExpr( ScriptIndex );
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_RemoveMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: Remove MC delegate"), *Indents, (int32)Opcode);
			SerializeExpr( ScriptIndex );
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_ClearMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: Clear MC delegate"), *Indents, (int32)Opcode);
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_BindDelegate:
		{
			// the name of the function assigned to the delegate.
			FString FuncName = ReadName(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: BindDelegate '%s' "), *Indents, (int32)Opcode, *FuncName);

			Ar.Logf(TEXT("%s Delegate:"), *Indents);
			SerializeExpr( ScriptIndex );

			Ar.Logf(TEXT("%s Object:"), *Indents);
			SerializeExpr( ScriptIndex );

			break;
		}
	case EX_PushExecutionFlow:
		{
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: FlowStack.Push(0x%X);"), *Indents, (int32)Opcode, SkipCount);
			break;
		}
	case EX_PopExecutionFlow:
		{
			Ar.Logf(TEXT("%s $%X: if (FlowStack.Num()) { jump to statement at FlowStack.Pop(); } else { ERROR!!! }"), *Indents, (int32)Opcode);
			break;
		}
	case EX_PopExecutionFlowIfNot:
		{
			Ar.Logf(TEXT("%s $%X: if (!condition) { if (FlowStack.Num()) { jump to statement at FlowStack.Pop(); } else { ERROR!!! } }"), *Indents, (int32)Opcode);
			// Boolean expr.
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_Breakpoint:
		{
			Ar.Logf(TEXT("%s $%X: <<< BREAKPOINT >>>"), *Indents, (int32)Opcode);
			break;
		}
	case EX_WireTracepoint:
		{
			Ar.Logf(TEXT("%s $%X: .. wire debug site .."), *Indents, (int32)Opcode);
			break;
		}
	case EX_Tracepoint:
		{
			Ar.Logf(TEXT("%s $%X: .. debug site .."), *Indents, (int32)Opcode);
			break;
		}
	default:
		{
			// This should never occur.
			UE_LOG(LogScriptDisassembler, Warning, TEXT("Unknown bytecode 0x%02X; ignoring it"), (uint8)Opcode );
			break;
		}
	}
}
コード例 #7
0
void FKismetBytecodeDisassembler::ProcessCommon(int32& ScriptIndex, EExprToken Opcode)
{
	switch (Opcode)
	{
	case EX_PrimitiveCast:
		{
			// A type conversion.
			uint8 ConversionType = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: PrimitiveCast of type %d"), *Indents, (int32)Opcode, ConversionType);
			AddIndent();

			Ar.Logf(TEXT("%s Argument:"), *Indents);
			ProcessCastByte(ConversionType, ScriptIndex);

			//@TODO:
			//Ar.Logf(TEXT("%s Expression:"), *Indents);
			//SerializeExpr( ScriptIndex );
			break;
		}
	case EX_ObjToInterfaceCast:
		{
			// A conversion from an object variable to a native interface variable.
			// We use a different bytecode to avoid the branching each time we process a cast token

			// the interface class to convert to
			UClass* InterfaceClass = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: ObjToInterfaceCast to %s"), *Indents, (int32)Opcode, *InterfaceClass->GetName());

			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_CrossInterfaceCast:
		{
			// A conversion from one interface variable to a different interface variable.
			// We use a different bytecode to avoid the branching each time we process a cast token

			// the interface class to convert to
			UClass* InterfaceClass = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: InterfaceToInterfaceCast to %s"), *Indents, (int32)Opcode, *InterfaceClass->GetName());

			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_InterfaceToObjCast:
		{
			// A conversion from an interface variable to a object variable.
			// We use a different bytecode to avoid the branching each time we process a cast token

			// the interface class to convert to
			UClass* ObjectClass = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: InterfaceToObjCast to %s"), *Indents, (int32)Opcode, *ObjectClass->GetName());

			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_Let:
		{
			Ar.Logf(TEXT("%s $%X: Let (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			ReadPointer<UProperty>(ScriptIndex);

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );

			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetObj:
	case EX_LetWeakObjPtr:
		{
			if( Opcode == EX_LetObj )
			{
				Ar.Logf(TEXT("%s $%X: Let Obj (Variable = Expression)"), *Indents, (int32)Opcode);
			}
			else
			{
				Ar.Logf(TEXT("%s $%X: Let WeakObjPtr (Variable = Expression)"), *Indents, (int32)Opcode);
			}
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );

			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetBool:
		{
			Ar.Logf(TEXT("%s $%X: LetBool (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );

			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetValueOnPersistentFrame:
		{
			Ar.Logf(TEXT("%s $%X: LetValueOnPersistentFrame"), *Indents, (int32)Opcode);
			AddIndent();

			auto Prop = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s Destination variable: %s, offset: %d"), *Indents, *GetNameSafe(Prop), 
				Prop ? Prop->GetOffset_ForDebug() : 0);
			
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr(ScriptIndex);

			DropIndent();

			break;
		}
	case EX_StructMemberContext:
		{
			Ar.Logf(TEXT("%s $%X: Struct member context "), *Indents, (int32)Opcode);
			AddIndent();

			UProperty* Prop = ReadPointer<UProperty>(ScriptIndex);

			Ar.Logf(TEXT("%s Expression within struct %s, offset %d"), *Indents, *(Prop->GetName()), 
				Prop->GetOffset_ForDebug()); // although that isn't a UFunction, we are not going to indirect the props of a struct, so this should be fine

			Ar.Logf(TEXT("%s Expression to struct:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();

			break;
		}
	case EX_LetDelegate:
		{
			Ar.Logf(TEXT("%s $%X: LetDelegate (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );
				
			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_LetMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: LetMulticastDelegate (Variable = Expression)"), *Indents, (int32)Opcode);
			AddIndent();

			// Variable expr.
			Ar.Logf(TEXT("%s Variable:"), *Indents);
			SerializeExpr( ScriptIndex );
				
			// Assignment expr.
			Ar.Logf(TEXT("%s Expression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}

	case EX_ComputedJump:
		{
			Ar.Logf(TEXT("%s $%X: Computed Jump, offset specified by expression:"), *Indents, (int32)Opcode);

			AddIndent();
			SerializeExpr( ScriptIndex );
			DropIndent();

			break;
		}

	case EX_Jump:
		{
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Jump to offset 0x%X"), *Indents, (int32)Opcode, SkipCount);
			break;
		}
	case EX_LocalVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Local variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_DefaultVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Default variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_InstanceVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Instance variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_LocalOutVariable:
		{
			UProperty* PropertyPtr = ReadPointer<UProperty>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Local out variable named %s"), *Indents, (int32)Opcode, PropertyPtr ? *PropertyPtr->GetName() : TEXT("(null)"));
			break;
		}
	case EX_InterfaceContext:
		{
			Ar.Logf(TEXT("%s $%X: EX_InterfaceContext:"), *Indents, (int32)Opcode);
			SerializeExpr(ScriptIndex);
			break;
		}
	case EX_DeprecatedOp4A:
		{
			Ar.Logf(TEXT("%s $%X: This opcode has been removed and does nothing."), *Indents, (int32)Opcode);
			break;
		}
	case EX_Nothing:
		{
			Ar.Logf(TEXT("%s $%X: EX_Nothing"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndOfScript:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndOfScript"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndFunctionParms:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndFunctionParms"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndStructConst:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndStructConst"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndArray:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndArray"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndArrayConst:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndArrayConst"), *Indents, (int32)Opcode);
			break;
		}
	case EX_IntZero:
		{
			Ar.Logf(TEXT("%s $%X: EX_IntZero"), *Indents, (int32)Opcode);
			break;
		}
	case EX_IntOne:
		{
			Ar.Logf(TEXT("%s $%X: EX_IntOne"), *Indents, (int32)Opcode);
			break;
		}
	case EX_True:
		{
			Ar.Logf(TEXT("%s $%X: EX_True"), *Indents, (int32)Opcode);
			break;
		}
	case EX_False:
		{
			Ar.Logf(TEXT("%s $%X: EX_False"), *Indents, (int32)Opcode);
			break;
		}
	case EX_NoObject:
		{
			Ar.Logf(TEXT("%s $%X: EX_NoObject"), *Indents, (int32)Opcode);
			break;
		}
	case EX_NoInterface:
		{
			Ar.Logf(TEXT("%s $%X: EX_NoObject"), *Indents, (int32)Opcode);
			break;
		}
	case EX_Self:
		{
			Ar.Logf(TEXT("%s $%X: EX_Self"), *Indents, (int32)Opcode);
			break;
		}
	case EX_EndParmValue:
		{
			Ar.Logf(TEXT("%s $%X: EX_EndParmValue"), *Indents, (int32)Opcode);
			break;
		}
	case EX_Return:
		{
			Ar.Logf(TEXT("%s $%X: Return expression"), *Indents, (int32)Opcode);

			SerializeExpr( ScriptIndex ); // Return expression.
			break;
		}
	case EX_CallMath:
		{
			UStruct* StackNode = ReadPointer<UStruct>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Call Math (stack node %s::%s)"), *Indents, (int32)Opcode, *GetNameSafe(StackNode ? StackNode->GetOuter() : nullptr), *GetNameSafe(StackNode));

			while (SerializeExpr(ScriptIndex) != EX_EndFunctionParms)
			{
				// Params
			}
			break;
		}
	case EX_FinalFunction:
		{
			UStruct* StackNode = ReadPointer<UStruct>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Final Function (stack node %s::%s)"), *Indents, (int32)Opcode, StackNode ? *StackNode->GetOuter()->GetName() : TEXT("(null)"), StackNode ? *StackNode->GetName() : TEXT("(null)"));

			while (SerializeExpr( ScriptIndex ) != EX_EndFunctionParms)
			{
				// Params
			}
			break;
		}
	case EX_CallMulticastDelegate:
		{
			UStruct* StackNode = ReadPointer<UStruct>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: CallMulticastDelegate (signature %s::%s) delegate:"), *Indents, (int32)Opcode, StackNode ? *StackNode->GetOuter()->GetName() : TEXT("(null)"), StackNode ? *StackNode->GetName() : TEXT("(null)"));
			SerializeExpr( ScriptIndex );
			Ar.Logf(TEXT("Params:"));
			while (SerializeExpr( ScriptIndex ) != EX_EndFunctionParms)
			{
				// Params
			}
			break;
		}
	case EX_VirtualFunction:
		{
			FString FunctionName = ReadName(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: Virtual Function named %s"), *Indents, (int32)Opcode, *FunctionName);

			while (SerializeExpr(ScriptIndex) != EX_EndFunctionParms)
			{
			}
			break;
		}
	case EX_ClassContext:
	case EX_Context:
	case EX_Context_FailSilent:
		{
			Ar.Logf(TEXT("%s $%X: %s"), *Indents, (int32)Opcode, Opcode == EX_ClassContext ? TEXT("Class Context") : TEXT("Context"));
			AddIndent();

			// Object expression.
			Ar.Logf(TEXT("%s ObjectExpression:"), *Indents);
			SerializeExpr( ScriptIndex );

			if (Opcode == EX_Context_FailSilent)
			{
				Ar.Logf(TEXT(" Can fail silently on access none "));
			}

			// Code offset for NULL expressions.
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s Skip Bytes: 0x%X"), *Indents, SkipCount);

			// Property corresponding to the r-value data, in case the l-value needs to be mem-zero'd
			UField* Field = ReadPointer<UField>(ScriptIndex);
			Ar.Logf(TEXT("%s R-Value Property: %s"), *Indents, Field ? *Field->GetName() : TEXT("(null)"));

			// Context expression.
			Ar.Logf(TEXT("%s ContextExpression:"), *Indents);
			SerializeExpr( ScriptIndex );

			DropIndent();
			break;
		}
	case EX_IntConst:
		{
			int32 ConstValue = ReadINT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal int32 %d"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_SkipOffsetConst:
		{
			CodeSkipSizeType ConstValue = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal CodeSkipSizeType 0x%X"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_FloatConst:
		{
			float ConstValue = ReadFLOAT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal float %f"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_StringConst:
		{
			FString ConstValue = ReadString8(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal ansi string \"%s\""), *Indents, (int32)Opcode, *ConstValue);
			break;
		}
	case EX_UnicodeStringConst:
		{
			FString ConstValue = ReadString16(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal unicode string \"%s\""), *Indents, (int32)Opcode, *ConstValue);
			break;
		}
	case EX_TextConst:
		{
			// What kind of text are we dealing with?
			const EBlueprintTextLiteralType TextLiteralType = (EBlueprintTextLiteralType)Script[ScriptIndex++];

			switch (TextLiteralType)
			{
			case EBlueprintTextLiteralType::Empty:
				{
					Ar.Logf(TEXT("%s $%X: literal text - empty"), *Indents, (int32)Opcode);
				}
				break;

			case EBlueprintTextLiteralType::LocalizedText:
				{
					const FString SourceString = ReadString(ScriptIndex);
					const FString KeyString = ReadString(ScriptIndex);
					const FString Namespace = ReadString(ScriptIndex);
					Ar.Logf(TEXT("%s $%X: literal text - localized text { namespace: \"%s\", key: \"%s\", source: \"%s\" }"), *Indents, (int32)Opcode, *Namespace, *KeyString, *SourceString);
				}
				break;

			case EBlueprintTextLiteralType::InvariantText:
				{
					const FString SourceString = ReadString(ScriptIndex);
					Ar.Logf(TEXT("%s $%X: literal text - invariant text: \"%s\""), *Indents, (int32)Opcode, *SourceString);
				}
				break;

			case EBlueprintTextLiteralType::LiteralString:
				{
					const FString SourceString = ReadString(ScriptIndex);
					Ar.Logf(TEXT("%s $%X: literal text - literal string: \"%s\""), *Indents, (int32)Opcode, *SourceString);
				}
				break;

			default:
				checkf(false, TEXT("Unknown EBlueprintTextLiteralType! Please update FKismetBytecodeDisassembler::ProcessCommon to handle this type of text."));
				break;
			}
			break;
		}
	case EX_ObjectConst:
		{
			UObject* Pointer = ReadPointer<UObject>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: EX_ObjectConst (%p:%s)"), *Indents, (int32)Opcode, Pointer, *Pointer->GetFullName());
			break;
		}
	case EX_AssetConst:
		{
			Ar.Logf(TEXT("%s $%X: EX_AssetConst"), *Indents, (int32)Opcode);
			SerializeExpr(ScriptIndex);
			break;
		}
	case EX_NameConst:
		{
			FString ConstValue = ReadName(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal name %s"), *Indents, (int32)Opcode, *ConstValue);
			break;
		}
	case EX_RotationConst:
		{
			float Pitch = ReadFLOAT(ScriptIndex);
			float Yaw = ReadFLOAT(ScriptIndex);
			float Roll = ReadFLOAT(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: literal rotation (%f,%f,%f)"), *Indents, (int32)Opcode, Pitch, Yaw, Roll);
			break;
		}
	case EX_VectorConst:
		{
			float X = ReadFLOAT(ScriptIndex);
			float Y = ReadFLOAT(ScriptIndex);
			float Z = ReadFLOAT(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: literal vector (%f,%f,%f)"), *Indents, (int32)Opcode, X, Y, Z);
			break;
		}
	case EX_TransformConst:
		{

			float RotX = ReadFLOAT(ScriptIndex);
			float RotY = ReadFLOAT(ScriptIndex);
			float RotZ = ReadFLOAT(ScriptIndex);
			float RotW = ReadFLOAT(ScriptIndex);

			float TransX = ReadFLOAT(ScriptIndex);
			float TransY = ReadFLOAT(ScriptIndex);
			float TransZ = ReadFLOAT(ScriptIndex);

			float ScaleX = ReadFLOAT(ScriptIndex);
			float ScaleY = ReadFLOAT(ScriptIndex);
			float ScaleZ = ReadFLOAT(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: literal transform R(%f,%f,%f,%f) T(%f,%f,%f) S(%f,%f,%f)"), *Indents, (int32)Opcode, TransX, TransY, TransZ, RotX, RotY, RotZ, RotW, ScaleX, ScaleY, ScaleZ);
			break;
		}
	case EX_StructConst:
		{
			UScriptStruct* Struct = ReadPointer<UScriptStruct>(ScriptIndex);
			int32 SerializedSize = ReadINT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal struct %s (serialized size: %d)"), *Indents, (int32)Opcode, *Struct->GetName(), SerializedSize);
			while( SerializeExpr(ScriptIndex) != EX_EndStructConst )
			{
				// struct contents
			}
			break;
		}
	case EX_SetArray:
		{
 			Ar.Logf(TEXT("%s $%X: set array"), *Indents, (int32)Opcode);
			SerializeExpr(ScriptIndex);
 			while( SerializeExpr(ScriptIndex) != EX_EndArray)
 			{
 				// Array contents
 			}
 			break;
		}
	case EX_ArrayConst:
		{
			UProperty* InnerProp = ReadPointer<UProperty>(ScriptIndex);
			int32 Num = ReadINT(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: set array const - elements number: %d, inner property: %s"), *Indents, (int32)Opcode, Num, *GetNameSafe(InnerProp));
			while (SerializeExpr(ScriptIndex) != EX_EndArrayConst)
			{
				// Array contents
			}
			break;
		}
	case EX_ByteConst:
		{
			uint8 ConstValue = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal byte %d"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_IntConstByte:
		{
			int32 ConstValue = ReadBYTE(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: literal int %d"), *Indents, (int32)Opcode, ConstValue);
			break;
		}
	case EX_MetaCast:
		{
			UClass* Class = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: MetaCast to %s of expr:"), *Indents, (int32)Opcode, *Class->GetName());
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_DynamicCast:
		{
			UClass* Class = ReadPointer<UClass>(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: DynamicCast to %s of expr:"), *Indents, (int32)Opcode, *Class->GetName());
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_JumpIfNot:
		{
			// Code offset.
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
				
			Ar.Logf(TEXT("%s $%X: Jump to offset 0x%X if not expr:"), *Indents, (int32)Opcode, SkipCount);

			// Boolean expr.
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_Assert:
		{
			uint16 LineNumber = ReadWORD(ScriptIndex);
			uint8 InDebugMode = ReadBYTE(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: assert at line %d, in debug mode = %d with expr:"), *Indents, (int32)Opcode, LineNumber, InDebugMode);
			SerializeExpr( ScriptIndex ); // Assert expr.
			break;
		}
	case EX_Skip:
		{
			CodeSkipSizeType W = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: possibly skip 0x%X bytes of expr:"), *Indents, (int32)Opcode, W);

			// Expression to possibly skip.
			SerializeExpr( ScriptIndex );

			break;
		}
	case EX_InstanceDelegate:
		{
			// the name of the function assigned to the delegate.
			FString FuncName = ReadName(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: instance delegate function named %s"), *Indents, (int32)Opcode, *FuncName);
			break;
		}
	case EX_AddMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: Add MC delegate"), *Indents, (int32)Opcode);
			SerializeExpr( ScriptIndex );
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_RemoveMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: Remove MC delegate"), *Indents, (int32)Opcode);
			SerializeExpr( ScriptIndex );
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_ClearMulticastDelegate:
		{
			Ar.Logf(TEXT("%s $%X: Clear MC delegate"), *Indents, (int32)Opcode);
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_BindDelegate:
		{
			// the name of the function assigned to the delegate.
			FString FuncName = ReadName(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: BindDelegate '%s' "), *Indents, (int32)Opcode, *FuncName);

			Ar.Logf(TEXT("%s Delegate:"), *Indents);
			SerializeExpr( ScriptIndex );

			Ar.Logf(TEXT("%s Object:"), *Indents);
			SerializeExpr( ScriptIndex );

			break;
		}
	case EX_PushExecutionFlow:
		{
			CodeSkipSizeType SkipCount = ReadSkipCount(ScriptIndex);
			Ar.Logf(TEXT("%s $%X: FlowStack.Push(0x%X);"), *Indents, (int32)Opcode, SkipCount);
			break;
		}
	case EX_PopExecutionFlow:
		{
			Ar.Logf(TEXT("%s $%X: if (FlowStack.Num()) { jump to statement at FlowStack.Pop(); } else { ERROR!!! }"), *Indents, (int32)Opcode);
			break;
		}
	case EX_PopExecutionFlowIfNot:
		{
			Ar.Logf(TEXT("%s $%X: if (!condition) { if (FlowStack.Num()) { jump to statement at FlowStack.Pop(); } else { ERROR!!! } }"), *Indents, (int32)Opcode);
			// Boolean expr.
			SerializeExpr( ScriptIndex );
			break;
		}
	case EX_Breakpoint:
		{
			Ar.Logf(TEXT("%s $%X: <<< BREAKPOINT >>>"), *Indents, (int32)Opcode);
			break;
		}
	case EX_WireTracepoint:
		{
			Ar.Logf(TEXT("%s $%X: .. wire debug site .."), *Indents, (int32)Opcode);
			break;
		}
	case EX_InstrumentationEvent:
		{
			const uint8 EventType = ReadBYTE(ScriptIndex);
			switch (EventType)
			{
				case EScriptInstrumentation::InlineEvent:
					Ar.Logf(TEXT("%s $%X: .. instrumented inline event .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::Stop:
					Ar.Logf(TEXT("%s $%X: .. instrumented event stop .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::PureNodeEntry:
					Ar.Logf(TEXT("%s $%X: .. instrumented pure node entry site .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::NodeDebugSite:
					Ar.Logf(TEXT("%s $%X: .. instrumented debug site .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::NodeEntry:
					Ar.Logf(TEXT("%s $%X: .. instrumented wire entry site .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::NodeExit:
					Ar.Logf(TEXT("%s $%X: .. instrumented wire exit site .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::PushState:
					Ar.Logf(TEXT("%s $%X: .. push execution state .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::RestoreState:
					Ar.Logf(TEXT("%s $%X: .. restore execution state .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::ResetState:
					Ar.Logf(TEXT("%s $%X: .. reset execution state .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::SuspendState:
					Ar.Logf(TEXT("%s $%X: .. suspend execution state .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::PopState:
					Ar.Logf(TEXT("%s $%X: .. pop execution state .."), *Indents, (int32)Opcode);
					break;
				case EScriptInstrumentation::TunnelEndOfThread:
					Ar.Logf(TEXT("%s $%X: .. tunnel end of thread .."), *Indents, (int32)Opcode);
					break;
			}
			break;
		}
	case EX_Tracepoint:
		{
			Ar.Logf(TEXT("%s $%X: .. debug site .."), *Indents, (int32)Opcode);
			break;
		}
	case EX_SwitchValue:
		{
			const auto NumCases = ReadWORD(ScriptIndex);
			const auto AfterSkip = ReadSkipCount(ScriptIndex);

			Ar.Logf(TEXT("%s $%X: Switch Value %d cases, end in 0x%X"), *Indents, (int32)Opcode, NumCases, AfterSkip);
			AddIndent();
			Ar.Logf(TEXT("%s Index:"), *Indents);
			SerializeExpr(ScriptIndex);

			for (uint16 CaseIndex = 0; CaseIndex < NumCases; ++CaseIndex)
			{
				Ar.Logf(TEXT("%s [%d] Case Index (label: 0x%X):"), *Indents, CaseIndex, ScriptIndex);
				SerializeExpr(ScriptIndex);	// case index value term
				const auto OffsetToNextCase = ReadSkipCount(ScriptIndex);
				Ar.Logf(TEXT("%s [%d] Offset to the next case: 0x%X"), *Indents, CaseIndex, OffsetToNextCase);
				Ar.Logf(TEXT("%s [%d] Case Result:"), *Indents, CaseIndex);
				SerializeExpr(ScriptIndex);	// case term
			}

			Ar.Logf(TEXT("%s Default result (label: 0x%X):"), *Indents, ScriptIndex);
			SerializeExpr(ScriptIndex);
			Ar.Logf(TEXT("%s (label: 0x%X)"), *Indents, ScriptIndex);
			DropIndent();
			break;
		}
	case EX_ArrayGetByRef:
		{
			Ar.Logf(TEXT("%s $%X: Array Get-by-Ref Index"), *Indents, (int32)Opcode);
			AddIndent();
			SerializeExpr(ScriptIndex);
			SerializeExpr(ScriptIndex);
			DropIndent();
			break;
		}
	default:
		{
			// This should never occur.
			UE_LOG(LogScriptDisassembler, Warning, TEXT("Unknown bytecode 0x%02X; ignoring it"), (uint8)Opcode );
			break;
		}
	}
}
コード例 #8
0
    bool ConvertBufferToRenderer(BYTE* pBuffer, LONG lBufferLen, IMetafileToRenderter* pCorrector)
	{
		IRenderer* pRenderer = pCorrector->m_pRenderer;

		LONG lRendererType = 0;
		pRenderer->get_Type(&lRendererType);

		CommandType eCommand = ctError;

		bool bIsPathOpened = false;
		int curindex = 0;

		BYTE* current = pBuffer;
		while (curindex < lBufferLen)
		{
			eCommand = (CommandType)(*current);
			current++;
			curindex++;
			switch (eCommand)
			{
			case ctPageWidth:
			{
				pRenderer->put_Width(ReadInt(current, curindex) / 100000.0);
				break;
			}
			case ctPageHeight:
			{
				pRenderer->put_Height(ReadInt(current, curindex) / 100000.0);
				break;
			}
			case ctPageStart:
			{
				pRenderer->NewPage();
				pRenderer->BeginCommand(c_nPageType);

				// TODO:
				pRenderer->put_PenLineStartCap(Aggplus::LineCapFlat);
				pRenderer->put_PenLineEndCap(Aggplus::LineCapFlat);
				break;
			}
			case ctPageEnd:
			{
				if (bIsPathOpened)
				{
					pRenderer->PathCommandEnd();
					pRenderer->EndCommand(c_nPathType);
				}
				bIsPathOpened = false;

				pRenderer->EndCommand(c_nPageType);

				if (lRendererType == c_nGrRenderer)
					return true;

				break;
			}
			case ctPenColor:
			{
				pRenderer->put_PenColor(ReadInt(current, curindex));
				break;
			}
			case ctPenAlpha:
			{
				pRenderer->put_PenAlpha(*current);
				current++;
				curindex++;
				break;
			}
			case ctPenSize:
			{
				pRenderer->put_PenSize(ReadInt(current, curindex) / 100000.0);
				break;
			}
			case ctPenDashStyle:
			{
				BYTE nDashType = *current++;
				curindex++;
				switch (nDashType)
				{
				case Aggplus::DashStyleCustom:
				{
					int nCountDash = ReadInt(current, curindex);
					if (0 < nCountDash)
					{
						double* pDash = new double[nCountDash];
						for (int nDash = 0; nDash < nCountDash; ++nDash)
						{
							pDash[nDash] = ReadInt(current, curindex) / 100000.0;
						}

						if (c_nGrRenderer == lRendererType)
						{
							for (int nDash = 0; nDash < nCountDash; ++nDash)
							{
								// в отрисовщике - баг. зачем-то умножается на коеф 25.4/dpi
								// чтобы не менять там (перед выпуском) - умножаю здесь на обратку
								double dDpiX = 0;
								pRenderer->get_DpiX(&dDpiX);
								pDash[nDash] *= (dDpiX / 25.4);
							}
						}

                        pRenderer->PenDashPattern(pDash, nCountDash);
                        delete[] pDash;
					}
				}
				default:
                    pRenderer->put_PenDashStyle(nDashType);
                    break;
				}

				break;
			}
			case ctPenLineJoin:
			{
				pRenderer->put_PenLineJoin(*current);
				current++;
				curindex++;
				break;
			}
			case ctBrushType:
			{
				pRenderer->put_BrushType(ReadInt(current, curindex));
				break;
			}
			case ctBrushColor1:
			{
				pRenderer->put_BrushColor1(ReadInt(current, curindex));
				break;
			}
			case ctBrushAlpha1:
			{
				pRenderer->put_BrushAlpha1(*current);
				current++;
				curindex++;
				break;
			}
			case ctBrushColor2:
			{
				pRenderer->put_BrushColor1(ReadInt(current, curindex));
				break;
			}
			case ctBrushAlpha2:
			{
				pRenderer->put_BrushAlpha2(*current);
				current++;
				curindex++;
				break;
			}
			case ctBrushRectable:
			{
				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;
				double m3 = ReadInt(current, curindex) / 100000.0;
				double m4 = ReadInt(current, curindex) / 100000.0;
				pRenderer->BrushRect(0, m1, m2, m3, m4);
				break;
			}
			case ctBrushRectableEnabled:
			{
				bool bEnable = (1 == *current) ? true : false;
				pCorrector->EnableBrushRect(bEnable);

				current += 1;
				curindex += 1;
				break;
			}
			case ctBrushTexturePath:
			{
				int nLen = 2 * ReadUSHORT(current, curindex);
				std::wstring sTempPath = ReadString16(current, curindex, nLen);

				std::wstring sImagePath = pCorrector->GetImagePath(sTempPath);
				pRenderer->put_BrushTexturePath(sImagePath);
				break;
			}
			case ctBrushGradient:
			{
				current++;
				curindex++;

				while (true)
				{
					BYTE _command = *current;
					current++;
					curindex++;

					if (251 == _command)
						break;

					switch (_command)
					{
					case 0:
					{
						current += 5;
						curindex += 5;
						double x0 = ReadInt(current, curindex) / 100000.0;
						double y0 = ReadInt(current, curindex) / 100000.0;
						double x1 = ReadInt(current, curindex) / 100000.0;
						double y1 = ReadInt(current, curindex) / 100000.0;

                        pCorrector->SetLinearGradiant(x0, y0, x1, y1);
                        break;
                    }
                    case 1:
                    {
                        current++;
                        curindex++;
                        double x0 = ReadInt(current, curindex) / 100000.0;
                        double y0 = ReadInt(current, curindex) / 100000.0;
                        double x1 = ReadInt(current, curindex) / 100000.0;
                        double y1 = ReadInt(current, curindex) / 100000.0;
                        double r0 = ReadInt(current, curindex) / 100000.0;
                        double r1 = ReadInt(current, curindex) / 100000.0;
                        pCorrector->SetRadialGradiant(x0, y0, r0, x1, y1, r1);
                        break;
                    }
                    case 2:
                    {
                        LONG lColorsCount = (LONG)ReadInt(current, curindex);
                        if (0 >= lColorsCount)
                        {
                            pRenderer->put_BrushGradientColors(NULL, NULL, 0);
                        }
                        else
                        {
                            LONG* pColors = new LONG[lColorsCount];
                            double* pPositions = new double[lColorsCount];

                            if (!pColors)
                                break;

                            if (!pPositions)
                            {
                                delete[] pColors;
                                break;
                            }

                            for (LONG lIndex = 0; lIndex < lColorsCount; lIndex++)
                            {
                                pPositions[lIndex] = ReadInt(current, curindex) / 100000.0;
                                pColors[lIndex] = ReadInt(current, curindex);
                            }

                            pRenderer->put_BrushGradientColors(pColors, pPositions, lColorsCount);

                            delete[] pColors;
                            delete[] pPositions;
                        }

						break;
					}
					default:
					{
						break;
					}
					};
				}

				break;
			}
			case ctBrushTextureMode:
			{
				LONG lMode = (LONG)(*current);
				pRenderer->put_BrushTextureMode(lMode);

				current += 1;
				curindex += 1;
				break;
			}
			case ctBrushTextureAlpha:
			{
				LONG lAlpha = (LONG)(*current);
				pRenderer->put_BrushTextureAlpha(lAlpha);

				current += 1;
				curindex += 1;
				break;
			}
			case ctSetTransform:
			{
				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;
				double m3 = ReadInt(current, curindex) / 100000.0;
				double m4 = ReadInt(current, curindex) / 100000.0;
				double m5 = ReadInt(current, curindex) / 100000.0;
				double m6 = ReadInt(current, curindex) / 100000.0;
				pRenderer->SetTransform(m1, m2, m3, m4, m5, m6);
				break;
			}
			case ctPathCommandStart:
			{
				if (bIsPathOpened)
				{
					pRenderer->PathCommandEnd();
					pRenderer->EndCommand(c_nPathType);
				}

				pRenderer->BeginCommand(c_nPathType);
				pRenderer->PathCommandStart();

				bIsPathOpened = true;
				break;
			}
			case ctPathCommandMoveTo:
			{
				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;
				pRenderer->PathCommandMoveTo(m1, m2);
				break;
			}
			case ctPathCommandLineTo:
			{
				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;
				pRenderer->PathCommandLineTo(m1, m2);
				break;
			}
			case ctPathCommandCurveTo:
			{
				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;
				double m3 = ReadInt(current, curindex) / 100000.0;
				double m4 = ReadInt(current, curindex) / 100000.0;
				double m5 = ReadInt(current, curindex) / 100000.0;
				double m6 = ReadInt(current, curindex) / 100000.0;
				pRenderer->PathCommandCurveTo(m1, m2, m3, m4, m5, m6);
				break;
			}
			case ctPathCommandClose:
			{
				pRenderer->PathCommandClose();
				break;
			}
			case ctPathCommandEnd:
			{
				if (bIsPathOpened)
				{
					pRenderer->PathCommandEnd();
					pRenderer->EndCommand(c_nPathType);
					bIsPathOpened = false;
				}
				break;
			}
			case ctDrawPath:
			{
				pRenderer->DrawPath(ReadInt(current, curindex));
				break;
			}
			case ctDrawImageFromFile:
			{
				int nLen = ReadInt(current, curindex);
				std::wstring sTempPath = ReadString16(current, curindex, nLen);
				std::wstring sImagePath = pCorrector->GetImagePath(sTempPath);

				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;
				double m3 = ReadInt(current, curindex) / 100000.0;
				double m4 = ReadInt(current, curindex) / 100000.0;

				try
				{
					pRenderer->DrawImageFromFile(sImagePath, m1, m2, m3, m4);
				}
				catch (...)
				{
				}

				break;
			}
			case ctFontName:
			{
				int _sLen = 2 * (int)ReadUSHORT(current, curindex);
				std::wstring wsTempString = ReadString16(current, curindex, _sLen);
				pRenderer->put_FontName(wsTempString);
				break;
			}
			case ctFontSize:
			{
				double m1 = ReadInt(current, curindex) / 100000.0;
				pRenderer->put_FontSize(m1);
				break;
			}
			case ctFontStyle:
			{
				pRenderer->put_FontStyle(ReadInt(current, curindex));
				break;
			}
			case ctDrawText:
			{
				int _sLen = 2 * (int)ReadUSHORT(current, curindex);
				std::wstring wsTempString = ReadString16(current, curindex, _sLen);

				double m1 = ReadInt(current, curindex) / 100000.0;
				double m2 = ReadInt(current, curindex) / 100000.0;

				pRenderer->CommandDrawText(wsTempString, m1, m2, 0, 0);
				break;
			}
			case ctBeginCommand:
			{
				if (bIsPathOpened)
				{
					pRenderer->PathCommandEnd();
					pRenderer->EndCommand(4);
					bIsPathOpened = false;
				}
				pRenderer->BeginCommand((DWORD)(ReadInt(current, curindex)));
				break;
			}
			case ctEndCommand:
			{
				if (bIsPathOpened)
				{
					pRenderer->EndCommand(4);
					bIsPathOpened = false;
				}
				pRenderer->EndCommand((DWORD)(ReadInt(current, curindex)));
				pRenderer->PathCommandEnd();
				break;
			}
			case ctGradientFill:
			{
				// TODO: Эта команда не должна приходить
				INT32 gradientType = ReadInt(current, curindex);

				std::wstring sXml, sXmlStop;
				if (0 == gradientType)	//	linearGradient
				{
					double x1 = ReadInt(current, curindex) / 100000.0;
					double x2 = ReadInt(current, curindex) / 100000.0;
					double y1 = ReadInt(current, curindex) / 100000.0;
					double y2 = ReadInt(current, curindex) / 100000.0;

					int stops = ReadInt(current, curindex);

					for (int i = 0; i < stops; ++i)
					{
						INT32 color   = static_cast<INT32>(*current);
						double opacity = static_cast<double>(static_cast<INT32>(*(current + 1))) / 255.0;
						double offset  = static_cast<double>(static_cast<INT32>(*(current + 2))) / 255.0;

						current  += 6 * 4; // 4 + 1 + 1
						curindex += 6 * 4;
					}
				}
				else if (1 == gradientType)
				{
					double cx = ReadInt(current, curindex) / 100000.0;
					double cy = ReadInt(current, curindex) / 100000.0;
					double r  = ReadInt(current, curindex) / 100000.0;
					double fx = ReadInt(current, curindex) / 100000.0;
					double fy = ReadInt(current, curindex) / 100000.0;

					int stops = ReadInt(current, curindex);

					for (int i = 0; i < stops; ++i)
					{
						INT32 color   = static_cast<INT32>(*current);
						double opacity = static_cast<double>(static_cast<INT32>(*(current + 1))) / 255.0;
						double offset  = static_cast<double>(static_cast<INT32>(*(current + 2))) / 255.0;

						current  += 6 * 4;		//	4 + 1 + 1
						curindex += 6 * 4;
					}
				}
				break;
			}
			case ctGradientFillXML:
			{
				// TODO: Эта команда не должна приходить
				INT32 gradientType = ReadInt(current, curindex);
				int _sLen = ReadInt(current, curindex);
				std::wstring wsTempString = ReadString16(current, curindex, _sLen);
				break;
			}
			case ctGradientStroke:
			{
				// TODO: Эта команда не должна приходить
				INT32 gradientType = ReadInt(current, curindex);
				if (0 == gradientType)	//	linearGradient
				{
					double x1 = ReadInt(current, curindex) / 100000.0;
					double x2 = ReadInt(current, curindex) / 100000.0;
					double y1 = ReadInt(current, curindex) / 100000.0;
					double y2 = ReadInt(current, curindex) / 100000.0;
					int stops = ReadInt(current, curindex);

					for (int i = 0; i < stops; ++i)
					{
						INT32 color   = static_cast<INT32>(*current);
						double opacity = static_cast<double>(static_cast<INT32>(*(current + 1))) / 255.0;
						double offset  = static_cast<double>(static_cast<INT32>(*(current + 2))) / 255.0;

						current  += 6 * 4; // 4 + 1 + 1
						curindex += 6 * 4;
					}
				}
				else if (1 == gradientType)
				{
					double cx = ReadInt(current, curindex) / 100000.0;
					double cy = ReadInt(current, curindex) / 100000.0;
					double r  = ReadInt(current, curindex) / 100000.0;
					double fx = ReadInt(current, curindex) / 100000.0;
					double fy = ReadInt(current, curindex) / 100000.0;
					int stops = ReadInt(current, curindex);

					for (int i = 0; i < stops; ++i)
					{
						INT32 color   = static_cast<INT32>(*current);
						double opacity = static_cast<double>(static_cast<INT32>(*(current + 1))) / 255.0;
						double offset  = static_cast<double>(static_cast<INT32>(*(current + 2))) / 255.0;

						current  += 6 * 4; // 4 + 1 + 1
						curindex += 6 * 4;
					}
				}
				break;
			}
			case ctGradientStrokeXML:
			{
				// TODO: Эта команда не должна приходить
				INT32 gradientType = ReadInt(current, curindex);
				int _sLen = (int)ReadInt(current, curindex);
				std::wstring wsTempString = ReadString16(current, curindex, _sLen);
				break;
			}
			default:
			{
				break;
			}
			}; // switch (eCommand)
		} // while (curindex < len)

		return true;
	}