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; }
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; }
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; }
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; }
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(); }
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; } } }
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; } } }
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; }