Skip to content

Commit

Permalink
Merge pull request #44 from mika-f/feature/blender-3.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mika-f authored Jul 17, 2023
2 parents 67bf19d + bc9b26a commit 0d4f2ff
Show file tree
Hide file tree
Showing 19 changed files with 308 additions and 140 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/release-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ jobs:
$Dest = "bin/x64/DragAndDropSupport-v${{ needs.setup.outputs.version }}"
Compress-Archive "$Dest" "$Dest.zip"
Remove-Item -Recure $Dest
Get-FileHash -Algorithm SHA256 "$Dest.zip" | Select-Object -ExpandProperty Hash | Tee-Object -FilePath "$Dest.zip.sha256"
Get-FileHash -Algorithm MD5 "$Dest.zip" | Select-Object -ExpandProperty Hash | Tee-Object -FilePath "$Dest.zip.md5"
Expand Down
4 changes: 2 additions & 2 deletions build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ echo F | xcopy /s "src\blender-injection\%1\"%2"\*.dll" "%DEST%\drag-and-drop-su
echo F | xcopy /s "src\blender-extension\*" "%DEST%\drag-and-drop-support\"
echo F | xcopy "src\LICENSE.txt" "%DEST%\"

powershell compress-archive "%DEST%\drag-and-drop-support" "%DEST%\drag-and-drop-support.zip"
pwsh -Command compress-archive "%DEST%\drag-and-drop-support" "%DEST%\drag-and-drop-support.zip"
echo Y | rmdir /s "%DEST%\drag-and-drop-support"

echo ******************************************************************************************************
Expand All @@ -106,7 +106,7 @@ if exist "%DEST%.zip" (
del "%DEST%.zip"
)

powershell compress-archive %DEST% %DEST%.zip
pwsh -Command compress-archive %DEST% %DEST%.zip


set HASH=
Expand Down
127 changes: 10 additions & 117 deletions src/blender-injection/BlenderObj.h
Original file line number Diff line number Diff line change
@@ -1,119 +1,12 @@
#pragma once

// define memory layouts of Blender

struct bContext
{
int thread;

struct
{
void* manager;
void* window;
void* workspace;
void* screen;
void* area;
void* region;
void* menu;
void* gizmo_group;
void* store;

const char* operator_poll_msg;

struct PollMsgDyn_Params
{
char* (*get_fn)(bContext*, void*);
char* (*free_fn)(bContext*, void*);
void* user_data;
} operator_poll_msg_dyn_params;
} wm;

struct
{
void* main;
void* scene;
int recursion;
bool py_init;
void* py_context;
void* py_context_orig;
} data;
};

using eWM_DragFlags = enum eWM_DragFlags
{
WM_DRAG_NOP = 0,
WM_DRAG_FREE_DATA = 1,
};

using ListBase = struct ListBase
{
void *first, *last;
};

using wmDragActiveDropState = struct wmDragActiveDropState
{
struct wmDropBox* active_dropbox;
struct ScrArea* area_from;
struct ARegion* region_from;
struct bContextStore* ui_context;
const char* disabled_info;
bool free_disabled_info;
};

using wmDrag = struct wmDrag
{
struct wmDrag *next, *prev;
int icon;
int type;
void* poin;
char path[1024];
double value;
struct ImBuf* imb;
float imbuf_scale;
wmDragActiveDropState drop_state;
eWM_DragFlags flags;
ListBase ids;
ListBase asset_items;
};

using wmTabletData = struct wmTabletData
{
int active;
float pressure;
float x_tilt;
float y_tilt;
char is_motion_absolute;
};

using eWM_EventFlag = enum eWM_EventFlag
{
WM_EVENT_SCROLL_INVERT = (1 << 0),
WM_EVENT_IS_REPEAT = (1 << 1),
WM_EVENT_FORCE_DRAG_THRESHOLD = (1 << 2),
};

using wmEvent = struct wmEvent
{
struct wmEvent *next, *prev;
short type;
short val;
int xy[2];
int mval[2];
char utf8_buf[6];
uint8_t modifier;
int8_t direction;
short keymodifier;
wmTabletData tablet;
eWM_EventFlag flag;
short custom;
short customdata_free;
void* customdata;
short prev_type;
short prev_val;
int prev_xy[2];
short prev_press_type;
int prev_press_xy[2];
uint8_t prev_press_modifier;
short prev_press_keymodifier;
double prev_press_time;
};
#include "./stubs/bContext.h"
#include "./stubs/eWM_DragDataType.h"
#include "./stubs/eWM_DragFlags.h"
#include "./stubs/eWM_EventFlag.h"
#include "./stubs/ListBase.h"
#include "./stubs/wmDrag.h"
#include "./stubs/wmDragActiveDropState.h"
#include "./stubs/wmDragPath.h"
#include "./stubs/wmEvent.h"
#include "./stubs/wmTabletData.h"
9 changes: 9 additions & 0 deletions src/blender-injection/BlenderPatchPatterns.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,14 @@ static std::unordered_map<std::string, BlenderPatchPattern> Patchers{
"E8 7B FF FF FF 84 C0",
"E8 0B BC 00 00 48 85 C0"
}
},
{
"3.6.0", {
"E8 FC 8F 41 00 E8 C7 AD 22 04", // CALL and CALL
// "E8 DE 2F 41 00 40 84 F6", // CALL and TEST
"4C 8D 05 F9 07 00 00",
"E8 7B FF FF FF 84 C0",
"E8 EB BD 00 00 48 85 C0"
}
}
};
14 changes: 10 additions & 4 deletions src/blender-injection/BlenderPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ void BlenderPatcher::FetchVersion()

VerQueryValue(version, "\\", reinterpret_cast<void**>(&pFileInfo), &len);

this->_version = format("%d.%d.%d", HIWORD(pFileInfo->dwFileVersionMS), LOWORD(pFileInfo->dwFileVersionMS), HIWORD(pFileInfo->dwFileVersionLS));
this->_versionString = format("%d.%d.%d", HIWORD(pFileInfo->dwFileVersionMS), LOWORD(pFileInfo->dwFileVersionMS), HIWORD(pFileInfo->dwFileVersionLS));
this->_version = std::make_tuple(HIWORD(pFileInfo->dwFileVersionMS), LOWORD(pFileInfo->dwFileVersionMS), HIWORD(pFileInfo->dwFileVersionLS));
}
}

void BlenderPatcher::ApplyInjector()
{
const auto patterns = &Patchers.at(this->_version);
const auto patterns = &Patchers.at(this->_versionString);
this->_patch = new BlenderPatch(patterns);

const auto address = this->_patch->Get_view3d_ima_empty_drop_poll();
Expand Down Expand Up @@ -126,7 +127,7 @@ void BlenderPatcher::Patch()
{
std::cout << "[ERROR] exception: out of range" << std::endl;
std::cout << "[ERROR] injector detected the unsupported version of Blender. Please upgrade Drag-and-Drop Support or downgrade Blender" << std::endl;
std::cout << "[ERROR] detected version : " << this->_version << std::endl;
std::cout << "[ERROR] detected version : " << this->_versionString << std::endl;
}
}

Expand All @@ -140,10 +141,15 @@ void BlenderPatcher::UnPatch()
{
std::cout << "[ERROR] exception: out of range" << std::endl;
std::cout << "[ERROR] injector detected the unsupported version of Blender. Please upgrade Drag-and-Drop Support or downgrade Blender" << std::endl;
std::cout << "[ERROR] detected version : " << this->_version << std::endl;
std::cout << "[ERROR] detected version : " << this->_versionString << std::endl;
}
}

std::tuple<int, int, int> BlenderPatcher::GetVersion() const
{
return this->_version;
}


bool BlenderPatcher::View3DImaDropPoll(void* c, void* drag, void* event) const
{
Expand Down
8 changes: 6 additions & 2 deletions src/blender-injection/BlenderPatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
class BlenderPatcher
{
private:
std::string _version;
std::string _versionString;
std::tuple<int, int, int> _version;

std::unordered_map<std::uintptr_t, std::vector<unsigned char>> _originals;

Expand All @@ -17,7 +18,8 @@ class BlenderPatcher

BlenderPatcher()
{
this->_version = "0.0.0";
this->_versionString = "0.0.0";
this->_version = std::make_tuple(0, 0, 0);
}

void FetchVersion();
Expand All @@ -32,7 +34,9 @@ class BlenderPatcher

void Patch();
void UnPatch();
std::tuple<int, int, int> GetVersion() const;

// reflections
bool View3DImaDropPoll(void* c, void* drag, void* event) const;
void* EDView3dGiveObjectUnderCursor(void* c, int mvals[2]) const;
void RunStringEval(void* c, const char* imports[], const char* expression) const;
Expand Down
10 changes: 10 additions & 0 deletions src/blender-injection/blender-injection.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,16 @@
<ClInclude Include="injector.hpp" />
<ClInclude Include="pch.h" />
<ClInclude Include="strings.h" />
<ClInclude Include="stubs\bContext.h" />
<ClInclude Include="stubs\eWM_DragDataType.h" />
<ClInclude Include="stubs\wmDragActiveDropState.h" />
<ClInclude Include="stubs\eWM_EventFlag.h" />
<ClInclude Include="stubs\eWM_DragFlags.h" />
<ClInclude Include="stubs\wmDragPath.h" />
<ClInclude Include="stubs\ListBase.h" />
<ClInclude Include="stubs\wmTabletData.h" />
<ClInclude Include="stubs\wmDrag.h" />
<ClInclude Include="stubs\wmEvent.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BlenderPatch.cpp" />
Expand Down
33 changes: 33 additions & 0 deletions src/blender-injection/blender-injection.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<Filter Include="Header Files\vendors">
<UniqueIdentifier>{ad1122c9-83f1-4044-8877-658ef202112d}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\stubs">
<UniqueIdentifier>{029e6076-4989-4c33-afd3-5b41785e0c80}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
Expand Down Expand Up @@ -54,6 +57,36 @@
<ClInclude Include="BlenderPatchPatterns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stubs\wmDrag.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\bContext.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\eWM_EventFlag.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\eWM_DragFlags.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\wmDragPath.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\ListBase.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\wmTabletData.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\wmEvent.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\wmDragActiveDropState.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
<ClInclude Include="stubs\eWM_DragDataType.h">
<Filter>Header Files\stubs</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
Expand Down
63 changes: 48 additions & 15 deletions src/blender-injection/extern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,65 @@ const std::vector<std::string> SUPPORTED_FORMATS = {

std::vector<std::intptr_t> isAlreadyTriggered = {};

const char* GetDropFilePath(void* pUnknown)
{
if (BlenderPatcher::GetInstance()->GetVersion() >= std::make_tuple(3, 6, 0))
{
const auto drag = static_cast<wmDrag360*>(pUnknown);
const auto pointer = static_cast<wmDragPath*>(drag->poin);
return pointer->path;
}

const auto drag = static_cast<wmDrag*>(pUnknown);
return drag->path;
}

bool ShouldTriggerDropEvent(const char* w)
{
const std::filesystem::path path(w);
const auto extension = path.extension();

if (const auto ref = std::ranges::find(SUPPORTED_FORMATS, extension); ref != std::end(SUPPORTED_FORMATS))
return true;
return false;
}

bool IsEventAlreadyTriggered(void* drag)
{
const auto ptr = reinterpret_cast<intptr_t>(drag);
if (const auto itr = std::ranges::find(isAlreadyTriggered, ptr); itr != std::end(isAlreadyTriggered))
return true;
return false;
}

bool TriggerDropEvent(bContext* c, const char* path, void* ptr)
{
isAlreadyTriggered.push_back(reinterpret_cast<intptr_t>(ptr));

const char* imports[] = {"bpy", nullptr};
const auto expression = R"(bpy.ops.object.drop_event_listener2("INVOKE_DEFAULT", filename=R")" + std::string(path) + "\")";

BlenderPatcher::GetInstance()->RunStringEval(c, imports, expression.c_str());
return false;
}


extern "C" void DropEventHookCallback(void* c, void* win, char* path)
{
std::cout << "f:" << path << std::endl;
}

// static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
extern "C" bool View3DImaEmptyDropPollHookCallback(bContext* c, wmDrag* drag, wmEvent* event)
{
const auto ptr = reinterpret_cast<intptr_t>(drag);

if (drag->type == /* WM_DRAG_PATH */ 4)
{
const std::filesystem::path path(drag->path);
const auto extension = path.extension();

if (const auto ref = std::ranges::find(SUPPORTED_FORMATS, extension); ref != std::end(SUPPORTED_FORMATS))
if (const auto path = GetDropFilePath(drag); ShouldTriggerDropEvent(path))
{
if (const auto itr = std::ranges::find(isAlreadyTriggered, ptr); itr != std::end(isAlreadyTriggered))
return false; // already triggered

isAlreadyTriggered.push_back(ptr);

const char* imports[] = {"bpy", nullptr};
const auto expression = R"(bpy.ops.object.drop_event_listener2("INVOKE_DEFAULT", filename=R")" + std::string(drag->path) + "\")";
if (IsEventAlreadyTriggered(drag))
return false;

BlenderPatcher::GetInstance()->RunStringEval(c, imports, expression.c_str());
return false; // already triggered
return TriggerDropEvent(c, path, drag);
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/blender-injection/stubs/ListBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

using ListBase = struct ListBase
{
void *first, *last;
};
Loading

0 comments on commit 0d4f2ff

Please sign in to comment.