From 3c7f3d02fd964cc336f3911f700cb9294e1ca66c Mon Sep 17 00:00:00 2001 From: LUCASTUCIOUS Date: Fri, 27 Sep 2024 14:18:20 +0200 Subject: [PATCH] Logging the fuck out everything --- Source/SkyPortal/Private/SkyPortalIO.cpp | 52 +++++++++++++++---- Source/SkyPortal/Private/SkyPortalRunner.cpp | 7 ++- .../SkyPortal/Private/SkyPortalSubsystem.cpp | 27 +++++++--- .../SkyPortal/Public/SkyPortalDefinitions.h | 2 +- Source/SkyPortal/Public/SkyPortalIO.h | 4 +- Source/SkyPortal/Public/SkyPortalSubsystem.h | 4 +- 6 files changed, 74 insertions(+), 22 deletions(-) diff --git a/Source/SkyPortal/Private/SkyPortalIO.cpp b/Source/SkyPortal/Private/SkyPortalIO.cpp index 7663a41..19821ed 100644 --- a/Source/SkyPortal/Private/SkyPortalIO.cpp +++ b/Source/SkyPortal/Private/SkyPortalIO.cpp @@ -110,11 +110,11 @@ struct hid_device_ { }; -void USkyPortalIO::Write(FWriteBlock* pb) +bool USkyPortalIO::Write(FWriteBlock* pb) { if (!ensure(PortalDevice)) { UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); - return; + return false; } BOOL res; @@ -130,11 +130,12 @@ void USkyPortalIO::Write(FWriteBlock* pb) &bytes_returned, &ol); ensureMsgf(res, TEXT("Unable to write to Portal")); pb->BytesTransferred = bytes_returned; + return res; } #else -void USkyPortalIO::Write(FWriteBlock* pb) { +bool USkyPortalIO::Write(FWriteBlock* pb) { if (!ensure(PortalDevice)) { UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); @@ -146,6 +147,7 @@ void USkyPortalIO::Write(FWriteBlock* pb) { res = hid_write(PortalDevice, pb->data, write_buf_size); ensureMsgf(res != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice)); pb->BytesTransferred = res; + return res; } #endif @@ -163,12 +165,16 @@ void USkyPortalIO::WriteRaw(const TArray* block) uint8* USkyPortalIO::Read() { uint8* output = new byte[0x20]; - hid_read(PortalDevice, output, 0x20); + if (hid_read(PortalDevice, output, 0x20) == -1) { + UE_LOG(LogSkyportalIO, Error, TEXT("Unable to read data from Portal. error:\n %s"), hid_error(PortalDevice)); + return 0; + }; return output; } uint8* USkyPortalIO::QueryBlock(uint8 FigureIndex, uint8 BlockIndex) { + UE_LOG(LogSkyportalIO, Verbose, TEXT("Querying block %d - Start"), BlockIndex); FWriteBlock command; memset(command.data, 0, write_buf_size); //maybe not needed here command.data[1] = 'Q'; @@ -177,9 +183,9 @@ uint8* USkyPortalIO::QueryBlock(uint8 FigureIndex, uint8 BlockIndex) unsigned char* output; do { Write(&command); - output = Read(); + output = Read(); } while (output[0] != 'Q' || (output[1] % 0x10 != FigureIndex && output[1] != 0x01) || output[2] != BlockIndex); - + return output; } @@ -229,6 +235,25 @@ EPortalCommand GetPortalCommandFromChar(unsigned char Char) } +FString DataToString(const uint8* data) +{ + FString OutString; + for (int32 i = 0; i < 16; i++) + { + OutString += FString::Printf(TEXT("%02x"), data[i]); + } + return OutString; +} + +FString OutputToString(const unsigned char* output) { + FString OutString; + for (int32 i = 0; i < 0x20; i++) + { + OutString += FString::Printf(TEXT("%02x"), output[i]); + } + return OutString; +} + FPortalStatusData ParsePortalStatus(const uint8* StatusResponse) { FPortalStatusData result; @@ -284,12 +309,14 @@ FPortalStatusData ParsePortalStatus(const uint8* StatusResponse) void DecryptAES128(uint8* OutData, const uint8* InData, const uint8* Key) { + UE_LOG(LogSkyportalIO, VeryVerbose, TEXT("DECRYPT -- Starting decryting data %s with %s key"), *DataToString(InData), *DataToString(Key)); AES_KEY AesKey; // Set the decryption key (16 bytes for AES-128) AES_set_decrypt_key(Key, 128, &AesKey); // Perform AES-128 decryption (ECB mode) AES_ecb_encrypt(InData, OutData, &AesKey, AES_DECRYPT); + UE_LOG(LogSkyportalIO, VeryVerbose, TEXT("DECRYPT -- data %s with %s key decryted"), *DataToString(InData), *DataToString(Key)); } FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex) @@ -305,16 +332,18 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex) { // Query the block from the portal uint8* output = QueryBlock(FigureIndex, BlockIndex); - + // Copy 16 bytes from the output, starting at the third byte FMemory::Memcpy(TempFigureData.data, output + 3, FIGURE_BLOCK_SIZE); // Block 1 is sometimes a duplicate of block 0 if (BlockIndex == 1) { - if (FMemory::Memcmp(TempFigureData.data, TempFigureData.data[0], FIGURE_BLOCK_SIZE) == 0) + if (FMemory::Memcmp(TempFigureData.data[1], TempFigureData.data[0], FIGURE_BLOCK_SIZE) == 0) { - --BlockIndex; // Decrement index to reprocess + // Decrement BlockIndex to reprocess block 1 if it's a duplicate of block 0 + --BlockIndex; + UE_LOG(LogSkyportalIO, Verbose, TEXT("Block 1 is a duplicate of block 0, reprocessing...")); continue; } } @@ -323,11 +352,12 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex) { // Direct copy from data to decryptedData for certain blocks FMemory::Memcpy(TempFigureData.decryptedData[BlockIndex], TempFigureData.data[BlockIndex], FIGURE_BLOCK_SIZE); - + UE_LOG(LogSkyportalIO, Verbose, TEXT("Block %d doesnt need decryption"), BlockIndex); } else { /***** MD5 Hash Calculation *****/ // Prepare the hash input buffer + UE_LOG(LogSkyportalIO, Verbose, TEXT("DECRYPT -- Starting decryting block %d"), BlockIndex); uint8 hashIn[0x56]; FMemory::Memcpy(hashIn, TempFigureData.data[0], 16); FMemory::Memcpy(hashIn + 0x10, TempFigureData.data[1], 16); @@ -349,7 +379,9 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex) //TODO: FAES implementation in Unreal is AES-256. We need AES-128 //FAES::DecryptData(TempFigureData.decryptedData[BlockIndex], TempFigureData.data[BlockIndex], 16, AesKey); DecryptAES128(TempFigureData.decryptedData[BlockIndex], TempFigureData.data[BlockIndex], key); + UE_LOG(LogSkyportalIO, Verbose, TEXT("DECRYPT -- block %d decrypted"), BlockIndex); } + UE_LOG(LogSkyportalIO, VeryVerbose, TEXT("block %d readed with success"), BlockIndex); } diff --git a/Source/SkyPortal/Private/SkyPortalRunner.cpp b/Source/SkyPortal/Private/SkyPortalRunner.cpp index c537dc7..bb2fda3 100644 --- a/Source/SkyPortal/Private/SkyPortalRunner.cpp +++ b/Source/SkyPortal/Private/SkyPortalRunner.cpp @@ -18,8 +18,11 @@ uint32 FPortalStatusChecker::Run() // Main loop of the thread, runs until Stop() is called while (bShouldRun) { - // Check the portal status - CheckPortalStatus(); + USkyPortalSubsystem* subref = Cast(SkyPortalSubsystemRef); + if (subref && !(subref->bShouldPauseRunner)) { + // Check the portal status + CheckPortalStatus(); + } // Sleep for the specified interval FPlatformProcess::Sleep(CheckInterval); diff --git a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp index f48194c..fb3124c 100644 --- a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp +++ b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp @@ -11,10 +11,7 @@ void USkyPortalSubsystem::Initialize(FSubsystemCollectionBase& Collection) { Super::Initialize(Collection); - // Start the status checker thread - StatusChecker = new FPortalStatusChecker(this, RunnerInterval); - StatusCheckerThread = FRunnableThread::Create(StatusChecker, TEXT("PortalStatusCheckerThread"), 0, TPri_AboveNormal); - + UE_LOG(LogTemp, Log, TEXT("SkyPortalSubsystem Initialized")); } @@ -211,6 +208,17 @@ void USkyPortalSubsystem::Sleep(int sleepMs) { bool USkyPortalSubsystem::PortalConnect() { + if (StatusChecker) + { + StatusChecker->Stop(); + StatusCheckerThread->WaitForCompletion(); + + delete StatusCheckerThread; + delete StatusChecker; + StatusChecker = nullptr; + StatusCheckerThread = nullptr; + } + PortalHandle = NewObject(); if (IsValid(PortalHandle) && PortalHandle->bPortalReady) { UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: ")); @@ -219,6 +227,11 @@ bool USkyPortalSubsystem::PortalConnect() Sleep(500); ChangePortalColor(FLinearColor(0.5, 0.5, 0.5)); + + // Start the status checker thread + StatusChecker = new FPortalStatusChecker(this, RunnerInterval); + StatusCheckerThread = FRunnableThread::Create(StatusChecker, TEXT("PortalStatusCheckerThread"), 0, TPri_AboveNormal); + return true; } return false; @@ -240,9 +253,11 @@ bool USkyPortalSubsystem::IsPortalReady() void USkyPortalSubsystem::PortalAnalyze(const uint8 index) { - FigureArray[index] = PortalHandle->ReadFigureBlocks(index); + bShouldPauseRunner = true; UE_LOG(LogSkyportalIO, Log, TEXT("Reading figure...")); - UE_LOG(LogSkyportalIO, Log, TEXT("decrypted Figure ID : %d"), FigureArray[index].GetFigureID()); + FigureArray[index] = PortalHandle->ReadFigureBlocks(index); + UE_LOG(LogSkyportalIO, Log, TEXT("Figure ID : %d"), FigureArray[index].GetFigureID()); + bShouldPauseRunner = false; } void USkyPortalSubsystem::GetFigureArray() { diff --git a/Source/SkyPortal/Public/SkyPortalDefinitions.h b/Source/SkyPortal/Public/SkyPortalDefinitions.h index fda362b..5e87a14 100644 --- a/Source/SkyPortal/Public/SkyPortalDefinitions.h +++ b/Source/SkyPortal/Public/SkyPortalDefinitions.h @@ -80,4 +80,4 @@ struct FPortalStatusData { return !(*this == Other); } -}; \ No newline at end of file +}; diff --git a/Source/SkyPortal/Public/SkyPortalIO.h b/Source/SkyPortal/Public/SkyPortalIO.h index ea9ed3d..c1aa39a 100644 --- a/Source/SkyPortal/Public/SkyPortalIO.h +++ b/Source/SkyPortal/Public/SkyPortalIO.h @@ -25,6 +25,8 @@ const int ProductIds[4] = { 0x150, 0x967, 0x1f17 }; FPortalStatusData ParsePortalStatus(const uint8* StatusResponse); EPortalCommand GetPortalCommandFromChar(unsigned char Char); +FString DataToString(const uint8* data); +FString OutputToString(const unsigned char* output); /* Contain all the data that pass inside hidapi write + the number of bytes in case of successful write * @@ -62,7 +64,7 @@ public: bool OpenPortalHandle(); /* Send block to portal. In windows, don't use the hidapi */ - void Write(FWriteBlock* Block); + bool Write(FWriteBlock* Block); /* Send raw command to portal */ void WriteRaw(const TArray* block); diff --git a/Source/SkyPortal/Public/SkyPortalSubsystem.h b/Source/SkyPortal/Public/SkyPortalSubsystem.h index 9565cd3..b9b51d4 100644 --- a/Source/SkyPortal/Public/SkyPortalSubsystem.h +++ b/Source/SkyPortal/Public/SkyPortalSubsystem.h @@ -142,8 +142,8 @@ public: UPROPERTY() bool bPortalConnected_DEPRECATED = PortalHandle ? PortalHandle->bPortalReady : false; - - + UPROPERTY() + bool bShouldPauseRunner;