- Create a new empty C++ project
- Go to
Project>Properties
- Set
Configuration Type
fromApplication (.exe)
toDynamic Library (.dll)
- In the same settings set the
C++ Language Standard
fromDefault (ISO C++14 Standard)
toPreview - Latest...
- Hit Apply and close the settings
- Switch your build configuration from
x86
tox64
- Add a file
Main.cpp
to your project - Add a
DllMain
function and aMainThread
function (See code here)
-
Take the contents of your CppSDK folder (by default
C:\\Dumper-7\\GameName-GameVersion\\CppSDK
)
-
If you do not care about your projects' compilation time, add
#include "SDK.hpp"
at the top of yourMain.cpp
file -
If you do care, and you want faster compilation-times, directly include only the files you require.
Adding#include "SDK/Engine_classes.hpp"
is a good start in this case. -
Add
Basic.cpp
andCoreUObject_functions.cpp
to your VS project -
If you call a function from the SDK you need to add the .cpp file, that contains the function-body, to your project.
Example:
CallingGetViewportSize()
fromAPlayerController
requires you to addEngine_functions.cpp
to your project.
-
If there are any static_asserts failing, or other errors occuring, during building, read the Issue part of the ReadMe
- FindObject, used to find an object by its' name
SDK::UObject* Obj1 = SDK::UObject::FindObject("ClassName PackageName.Outer1.Outer2.ObjectName"); SDK::UObject* Obj2 = SDK::UObject::FindObjectFast("ObjectName"); SDK::UObject* Obj3 = SDK::UObject::FindObjectFast("StructName", EClassCastFlags::Struct); // Finds a UStruct
- StaticFunctions / GlobalVariables, used to retreive class-instances from static variables
/* UWorld::GetWorld() replaces GWorld, no offset required */ SDK::UWorld* World = SDK::UWorld::GetWorld(); SDK::APlayerController* MyController = World->OwningGameInstance->LocalPlayers[0]->PlayerController;
- Non-Static functions
SDK::APlayerController* MyController = MagicFuncToGetPlayerController(); float OutX, OutY; MyController->GetMousePosition(&OutX, &OutY);
- Static functions
/* static functions do not require an instance, they are automatically called using their DefaultObject */ SDK::FName MyNewName = SDK::UKismetStringLibrary::Conv_StringToName(L"DemoNetDriver");
- With EClassCastFlags
/* Limited to some few types, but fast */ const bool bIsActor = Obj->IsA(EClassCastFlags::Actor);
- With a
UClass*
/* For every class, but slower (faster than string-comparison) */ const bool bIsSpecificActor = Obj->IsA(ASomeSpecificActor::StaticClass());
UnrealEngine heavily relies on inheritance and often uses pointers to a base class, which are later assigned addresses to
instances of child classes.
if (MyController->Pawn->IsA(SDK::AGameSpecificPawn::StaticClass()))
{
SDK::AGameSpecificPawn* MyGamePawn = static_cast<SDK::AGameSpecificPawn*>(MyController->Pawn);
MyGamePawn->GameSpecificVariable = 30;
}
#include <Windows.h>
#include <iostream>
DWORD MainThread(HMODULE Module)
{
/* Code to open a console window */
AllocConsole();
FILE* Dummy;
freopen_s(&Dummy, "CONOUT$", "w", stdout);
freopen_s(&Dummy, "CONIN$", "r", stdin);
// Your code here
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MainThread, hModule, 0, 0);
break;
}
return TRUE;
}
#include <Windows.h>
#include <iostream>
#include "SDK/Engine_classes.hpp"
// Basic.cpp was added to the VS project
// Engine_functions.cpp was added to the VS project
DWORD MainThread(HMODULE Module)
{
/* Code to open a console window */
AllocConsole();
FILE* Dummy;
freopen_s(&Dummy, "CONOUT$", "w", stdout);
freopen_s(&Dummy, "CONIN$", "r", stdin);
/* Functions returning "static" instances */
SDK::UEngine* Engine = SDK::UEngine::GetEngine();
SDK::UWorld* World = SDK::UWorld::GetWorld();
/* Getting the PlayerController, World, OwningGameInstance, ... should all be checked not to be nullptr! */
SDK::APlayerController* MyController = World->OwningGameInstance->LocalPlayers[0]->PlayerController;
/* Print the full-name of an object ("ClassName PackageName.OptionalOuter.ObjectName") */
std::cout << Engine->ConsoleClass->GetFullName() << std::endl;
/* Manually iterating GObjects and printing the FullName of every UObject that is a Pawn (not recommended) */
for (int i = 0; i < SDK::UObject::GObjects->Num(); i++)
{
SDK::UObject* Obj = SDK::UObject::GObjects->GetByIndex(i);
if (!Obj)
continue;
if (!Obj->IsDefaultObject())
continue;
/* Only the 'IsA' check using the cast flags is required, the other 'IsA' is redundant */
if (Obj->IsA(SDK::APawn::StaticClass()) || Obj->HasTypeFlag(SDK::EClassCastFlags::Pawn))
{
std::cout << Obj->GetFullName() << "\n";
}
}
/* You might need to loop all levels in UWorld::Levels */
SDK::ULevel* Level = World->PersistentLevel;
SDK::TArray<SDK::AActor*>& volatile Actors = Level->Actors;
for (SDK::AActor* Actor : Actors)
{
/* The 2nd and 3rd checks are equal, prefer using EClassCastFlags if available for your class. */
if (!Actor || !Actor->IsA(SDK::EClassCastFlags::Pawn) || !Actor->IsA(SDK::APawn::StaticClass()))
continue;
SDK::APawn* Pawn = static_cast<SDK::APawn*>(Actor);
// Use Pawn here
}
/*
* Changes the keyboard-key that's used to open the UE console
*
* This is a rare case of a DefaultObjects' member-variables being changed.
* By default you do not want to use the DefaultObject, this is a rare exception.
*/
SDK::UInputSettings::GetDefaultObj()->ConsoleKeys[0].KeyName = SDK::UKismetStringLibrary::Conv_StringToName(L"F2");
/* Creates a new UObject of class-type specified by Engine->ConsoleClass */
SDK::UObject* NewObject = SDK::UGameplayStatics::SpawnObject(Engine->ConsoleClass, Engine->GameViewport);
/* The Object we created is a subclass of UConsole, so this cast is **safe**. */
Engine->GameViewport->ViewportConsole = static_cast<SDK::UConsole*>(NewObject);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MainThread, hModule, 0, 0);
break;
}
return TRUE;
}