Tried with Unreal base approach

This commit is contained in:
Lucas Peter 2024-09-26 17:52:10 +02:00
parent 65652d3a2a
commit df5fd8b05b
No known key found for this signature in database
4 changed files with 81 additions and 16 deletions

View file

@ -1,4 +1,9 @@
#include "SkyPortalIO.h"
#include "Misc/AES.h"
#include "Misc/ArchiveMD5.h"
#include "Misc/ScopeLock.h"
#include "HAL/UnrealMemory.h"
DEFINE_LOG_CATEGORY(LogHIDApi);
DEFINE_LOG_CATEGORY(LogSkyportalIO);
@ -161,9 +166,20 @@ uint8* USkyPortalIO::Read()
return output;
}
TArray<uint8> USkyPortalIO::QueryBlock(uint8 characterIndex, uint8 block)
uint8* USkyPortalIO::QueryBlock(uint8 FigureIndex, uint8 BlockIndex)
{
return TArray<uint8>();
FWriteBlock command;
memset(command.data, 0, write_buf_size); //maybe not needed here
command.data[1] = 'Q';
command.data[2] = FigureIndex; // Figure index (0x00-0x0F)
command.data[3] = BlockIndex;
unsigned char* output;
do {
Write(&command);
output = Read();
} while (output[0] != 'Q' || (output[1] % 0x10 != FigureIndex && output[1] != 0x01) || output[2] != BlockIndex);
return output;
}
void USkyPortalIO::Close() {
@ -272,21 +288,59 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
FigureData FigureData;
FigureData.dataError = false; // Initialize error flag
FWriteBlock command;
// Loop over all 64 blocks
for (uint8 BlockIndex = 0; BlockIndex < FIGURE_TOTAL_BLOCKS; ++BlockIndex)
{
memset(command.data, 0, write_buf_size); //maybe not needed here
command.data[1] = 'Q';
command.data[2] = FigureIndex; // Figure index (0x00-0x0F)
command.data[3] = BlockIndex;
uint8* output;
do {
Write(&command);
output = Read();
} while (output[0] != 'Q');
// Query the block from the portal
uint8* output = QueryBlock(FigureIndex, BlockIndex);
// Copy 16 bytes from the output, starting at the third byte
FMemory::Memcpy(FigureData.data, output + 3, FIGURE_BLOCK_SIZE);
// Block 1 is sometimes a duplicate of block 0
if (BlockIndex == 1)
{
if (FMemory::Memcmp(FigureData.data, FigureData.data[0], FIGURE_BLOCK_SIZE) == 0)
{
--BlockIndex; // Decrement index to reprocess
continue;
}
}
if (((BlockIndex + 1) % 4 == 0) || BlockIndex < 8)
{
// Direct copy from data to decryptedData for certain blocks
FMemory::Memcpy(FigureData.decryptedData[BlockIndex], FigureData.data[BlockIndex], FIGURE_BLOCK_SIZE);
}
else {
/***** MD5 Hash Calculation *****/
// Prepare the hash input buffer
uint8 hashIn[0x56];
FMemory::Memcpy(hashIn, FigureData.data[0], 16);
FMemory::Memcpy(hashIn + 0x10, FigureData.data[1], 16);
hashIn[0x20] = BlockIndex;
// Append the 35-byte constant
FMemory::Memcpy(hashIn + 0x21, HASH_CONST, sizeof(HASH_CONST));
// Compute the MD5 hash
FMD5 MD5;
MD5.Update(hashIn, sizeof(hashIn));
uint8 key[16]; // MD5 produces 16 bytes
MD5.Final(key);
// AES-128 ECB decryption
FAES::FAESKey AesKey;
FMemory::Memcpy(AesKey.Key, key, 16);
//TODO: FAES implementation in Unreal is AES-256. We need AES-128
//FAES::DecryptData(FigureData.decryptedData[BlockIndex], FigureData.data[BlockIndex], 16, AesKey);
}
/*
if (output[1] == (0x10 + 'Q')) // Successful query
{
// Extract the 16 bytes of block data
@ -312,6 +366,7 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
// Copy block data into FigureData
//memcpy(FigureData.blockdata[BlockIndex], &res.buf[4], FIGURE_BLOCK_SIZE);
*/
}
// Some verifications should happen. Like if dataError is set.

View file

@ -118,6 +118,7 @@ SKYPORTAL_API bool USkyPortalSubsystem::RestartRunner()
StatusCheckerThread = FRunnableThread::Create(StatusChecker, TEXT("PortalStatusCheckerThread"), 0, TPri_AboveNormal);
UE_LOG(LogTemp, Log, TEXT("SkyPortalSubsystem Initialized"));
return true;
}

View file

@ -2,6 +2,12 @@
#include "CoreMinimal.h"
//#include "SkyPortalFigure.generated.h"
//Copyright (C) 2010 Activision.All Rights Reserved.
static const uint8 HASH_CONST[] = {
0x20, 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, // Copyright (C) 2
0x30, 0x31, 0x30, 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x2E, 0x20, // 010 Activision.
0x41, 0x6C, 0x6C, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, // All Rights Reser
0x76, 0x65, 0x64, 0x2E, 0x20 }; // ved.
#define FIGURE_TOTAL_BLOCKS 64
#define FIGURE_BLOCK_SIZE 16
@ -53,8 +59,8 @@ public:
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
uint32 GetFigureIdByIndex(uint32 index);
UFUNCTION()
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
//UFUNCTION()
//TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
void ReadData(uint8 index);
void ClearData();

View file

@ -72,8 +72,11 @@ public:
*/
uint8* Read();
UFUNCTION()
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
/*Trying to read a figure
* @return
*/
unsigned char* QueryBlock(uint8 characterIndex, uint8 block = 0x00);
FigureData ReadFigureBlocks(uint8 FigureIndex);