mirror of
https://github.com/ModOrganizer2/modorganizer-plugin_python.git
synced 2026-07-27 14:03:33 -07:00
Compare commits
348
Commits
release_v1.3.6
...
2_3_0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c922b97578 | ||
|
|
fed261e9eb | ||
|
|
f531905e4a | ||
|
|
e25fa00285 | ||
|
|
5c63d62a1e | ||
|
|
624c5257bd | ||
|
|
480eb3f30e | ||
|
|
4909b6cff0 | ||
|
|
331416d1e7 | ||
|
|
c955b4e8de | ||
|
|
727a55e1a8 | ||
|
|
6c1f961d83 | ||
|
|
a3e9916400 | ||
|
|
0fbb88b3c1 | ||
|
|
5023a13aa2 | ||
|
|
fe8a0b849c | ||
|
|
e1a1b70121 | ||
|
|
671776f306 | ||
|
|
95ed8ae14a | ||
|
|
e6ca79c694 | ||
|
|
c521178769 | ||
|
|
1cbfde96a0 | ||
|
|
e7ae48f633 | ||
|
|
d0fd776648 | ||
|
|
cbdf8fee14 | ||
|
|
5fe9c44f26 | ||
|
|
3f02f975aa | ||
|
|
b2b0b6f5c5 | ||
|
|
6ee58c6bf9 | ||
|
|
2efc6d4af6 | ||
|
|
760cca172f | ||
|
|
26c0e628b8 | ||
|
|
ab4a067042 | ||
|
|
38188e0b17 | ||
|
|
863893cc31 | ||
|
|
06b11c86ba | ||
|
|
d4a6a57f14 | ||
|
|
2ea33f4faa | ||
|
|
b4c23ad733 | ||
|
|
71db9d81d4 | ||
|
|
e712448ca0 | ||
|
|
98b8d92350 | ||
|
|
7cc0f974f5 | ||
|
|
48c35a8f92 | ||
|
|
4b9fc2d32a | ||
|
|
be63c1d9de | ||
|
|
100a2d03f0 | ||
|
|
fcd1177acd | ||
|
|
5eeb02403f | ||
|
|
eca495c849 | ||
|
|
024a333194 | ||
|
|
ead37d1dbe | ||
|
|
65003ef4ad | ||
|
|
a3b593f714 | ||
|
|
ab4168fd93 | ||
|
|
bfad575467 | ||
|
|
d5f44f424d | ||
|
|
da679b1d6d | ||
|
|
751e67e86c | ||
|
|
c96fe2d21a | ||
|
|
4b4c36df7a | ||
|
|
5f9d2b296d | ||
|
|
05e79cc13b | ||
|
|
3f5aa49dee | ||
|
|
3e9209a191 | ||
|
|
d70942efa1 | ||
|
|
d9393a2d2b | ||
|
|
7c1389d479 | ||
|
|
7333bde006 | ||
|
|
fae9f1b52f | ||
|
|
23c6f3fad9 | ||
|
|
f12bb05d61 | ||
|
|
d931d71a43 | ||
|
|
aa75c3b18e | ||
|
|
eb29202b2f | ||
|
|
fe0a75b819 | ||
|
|
90a99b37c9 | ||
|
|
7c474c58ca | ||
|
|
288f9f9a95 | ||
|
|
a05006a0b3 | ||
|
|
d6b8c66911 | ||
|
|
0c52c2417c | ||
|
|
24205bba66 | ||
|
|
f0f949c4ef | ||
|
|
6b88cee9d8 | ||
|
|
1825c58666 | ||
|
|
83a89ca595 | ||
|
|
e9fdfd40aa | ||
|
|
fcf1aa8b42 | ||
|
|
d404a37fed | ||
|
|
b360cae555 | ||
|
|
039e33f5fa | ||
|
|
622d4246a7 | ||
|
|
2f1646a2e6 | ||
|
|
716cbcf733 | ||
|
|
62f10c03ff | ||
|
|
957b786d8c | ||
|
|
29a5eb8366 | ||
|
|
4209d90533 | ||
|
|
7bbf05bc0c | ||
|
|
154c643bff | ||
|
|
2146cc9207 | ||
|
|
163ed213ef | ||
|
|
6919539d35 | ||
|
|
917b8dfb4b | ||
|
|
54e447c0a9 | ||
|
|
206454c34e | ||
|
|
457529546b | ||
|
|
b9de35772f | ||
|
|
4589cab093 | ||
|
|
2b4eedb62b | ||
|
|
36022774e3 | ||
|
|
aac45a39e2 | ||
|
|
61ad2ef2b6 | ||
|
|
1ea006b74e | ||
|
|
af37a451f9 | ||
|
|
473cef6217 | ||
|
|
5cd7917709 | ||
|
|
585296d527 | ||
|
|
221949f48b | ||
|
|
8b118ad898 | ||
|
|
f83ed39287 | ||
|
|
8a286f9cfc | ||
|
|
70172ddda6 | ||
|
|
817f8d7238 | ||
|
|
9f5dab285d | ||
|
|
53b91f0092 | ||
|
|
f1d5a1f31b | ||
|
|
626a7bc670 | ||
|
|
c9115e7ad0 | ||
|
|
6cececc7a0 | ||
|
|
d82640455f | ||
|
|
f25602cc69 | ||
|
|
168b9d7b0d | ||
|
|
247944baa8 | ||
|
|
332b8239bb | ||
|
|
97a93a5989 | ||
|
|
e871617843 | ||
|
|
c5d4857f47 | ||
|
|
5825661a4f | ||
|
|
2e13cf0dab | ||
|
|
d6dd0342b7 | ||
|
|
67abab0779 | ||
|
|
b0ef81214a | ||
|
|
b2ae43a0e5 | ||
|
|
52dd7454be | ||
|
|
059dc8b9d2 | ||
|
|
b8bcecbed4 | ||
|
|
42e559b59c | ||
|
|
b7d343a8dd | ||
|
|
63a6c504b0 | ||
|
|
19dcdd95c0 | ||
|
|
ac5540ba87 | ||
|
|
0708bdedbf | ||
|
|
2b6f453fbc | ||
|
|
4f86e542cc | ||
|
|
e280b07cb6 | ||
|
|
0c11e75f0f | ||
|
|
ab72c2f42f | ||
|
|
cbe679aad8 | ||
|
|
59e5f1acf2 | ||
|
|
d0598cd849 | ||
|
|
174abb3cea | ||
|
|
dee8825960 | ||
|
|
46a4ee8653 | ||
|
|
4721ab35df | ||
|
|
352e5c2103 | ||
|
|
78278ae57d | ||
|
|
3eb85cd17f | ||
|
|
208965b96d | ||
|
|
c17d703b15 | ||
|
|
65eb0c6374 | ||
|
|
97a20d522a | ||
|
|
caee1fb7f6 | ||
|
|
bab649af43 | ||
|
|
30ab7b8e14 | ||
|
|
956d481ca4 | ||
|
|
41a4f273d6 | ||
|
|
66391098b6 | ||
|
|
c9d77cf948 | ||
|
|
b939f7e88e | ||
|
|
be6b102599 | ||
|
|
a1bc87e75a | ||
|
|
4160dea823 | ||
|
|
1bd5dda7d8 | ||
|
|
9780aeb477 | ||
|
|
f6d41a1a81 | ||
|
|
69ff972b12 | ||
|
|
ada342e818 | ||
|
|
051c14fe72 | ||
|
|
f841a3b13a | ||
|
|
60701b6ba0 | ||
|
|
a8cf8d45f3 | ||
|
|
84c04c32dc | ||
|
|
6ce4138b31 | ||
|
|
d1f6766e16 | ||
|
|
aa2b0744f7 | ||
|
|
f1997b4788 | ||
|
|
423e6f8842 | ||
|
|
b5b547e041 | ||
|
|
61977d6149 | ||
|
|
fbf59519c0 | ||
|
|
08bcebe19c | ||
|
|
4900135130 | ||
|
|
b70fa8174e | ||
|
|
437d89fc04 | ||
|
|
51b59de04d | ||
|
|
19015289cb | ||
|
|
e004b56dc9 | ||
|
|
fba18c2b96 | ||
|
|
00c38f5f03 | ||
|
|
8919fbd351 | ||
|
|
6a3a257ecd | ||
|
|
ec4945db3e | ||
|
|
9f975b92b2 | ||
|
|
17c86ef540 | ||
|
|
7ab4b71ed3 | ||
|
|
61ecb68918 | ||
|
|
94886104f3 | ||
|
|
902024e508 | ||
|
|
0a9b4b9fc4 | ||
|
|
028c14a951 | ||
|
|
bf8f427cd8 | ||
|
|
8fe091ab48 | ||
|
|
8877fee4fa | ||
|
|
f13a5961df | ||
|
|
7b6ca76dec | ||
|
|
a35208d902 | ||
|
|
4feb06a099 | ||
|
|
0abbab9f8c | ||
|
|
86d859d430 | ||
|
|
5a730941db | ||
|
|
c70f78adfe | ||
|
|
e8af8819df | ||
|
|
de809c6d57 | ||
|
|
01168483c5 | ||
|
|
317f13177e | ||
|
|
c47b94d534 | ||
|
|
ca51a53d41 | ||
|
|
9722d5b093 | ||
|
|
2df983e22c | ||
|
|
52417d64e4 | ||
|
|
4a558d4caf | ||
|
|
8dd9a710b4 | ||
|
|
377199f233 | ||
|
|
18a73c2f54 | ||
|
|
fba28bb9ab | ||
|
|
cdbc0f3bdb | ||
|
|
ffbd4e3f11 | ||
|
|
e1ba01777d | ||
|
|
9cbb35d354 | ||
|
|
abff0e890d | ||
|
|
c076d7a8bb | ||
|
|
e277c9b56b | ||
|
|
d8ad6569ba | ||
|
|
e08b8be570 | ||
|
|
aca861194d | ||
|
|
fdffe6f277 | ||
|
|
341daf5c5f | ||
|
|
b272bd12fe | ||
|
|
d6b673f149 | ||
|
|
81ec421adb | ||
|
|
f3fa0baa41 | ||
|
|
9a3465cc7a | ||
|
|
277a2862b1 | ||
|
|
046e080943 | ||
|
|
af7823b920 | ||
|
|
d408512a2c | ||
|
|
10437e0aca | ||
|
|
c6e8a223e1 | ||
|
|
425ec8df5a | ||
|
|
39e17ebbe3 | ||
|
|
fc0a257b51 | ||
|
|
fe87c841a8 | ||
|
|
705d423839 | ||
|
|
9dff2ab02e | ||
|
|
1bc41a72b4 | ||
|
|
d212bff9e9 | ||
|
|
85cb9b18e4 | ||
|
|
6a5ab7f747 | ||
|
|
539b068b71 | ||
|
|
96dbb56467 | ||
|
|
ea408a05af | ||
|
|
fa66025024 | ||
|
|
3e61a88abb | ||
|
|
828e35a129 | ||
|
|
cc58ccc992 | ||
|
|
aa37f30c68 | ||
|
|
f9353e4da0 | ||
|
|
9a310229e7 | ||
|
|
a78db4cbdc | ||
|
|
9502ea561e | ||
|
|
179deda6e4 | ||
|
|
fa85cc89d3 | ||
|
|
ee31647014 | ||
|
|
4bb0994d71 | ||
|
|
4b8b75e641 | ||
|
|
2fcb932e16 | ||
|
|
40192cb583 | ||
|
|
163e3d4544 | ||
|
|
a65763fb58 | ||
|
|
d144d7c97b | ||
|
|
de99a71085 | ||
|
|
9bdb48c6bc | ||
|
|
a20b166290 | ||
|
|
d1b2259cc5 | ||
|
|
4bb048aa67 | ||
|
|
0b53e86e5a | ||
|
|
9077573b9d | ||
|
|
0fa436fc0f | ||
|
|
d75eda53fc | ||
|
|
a71566122e | ||
|
|
69b988eede | ||
|
|
c106d6f342 | ||
|
|
4a6f8e84f4 | ||
|
|
efc0b1962f | ||
|
|
8f408a77d2 | ||
|
|
dccc265364 | ||
|
|
aa9c6ead94 | ||
|
|
f94f37b635 | ||
|
|
9fdcde3bd5 | ||
|
|
11c92e7e96 | ||
|
|
287a82ed48 | ||
|
|
c9299bb623 | ||
|
|
7d6d51b213 | ||
|
|
e60121b21f | ||
|
|
7f7a3fb1ca | ||
|
|
9ba337ef17 | ||
|
|
1455bda2f8 | ||
|
|
cc62f15cc8 | ||
|
|
0b9a56fa7a | ||
|
|
fc8f6c77bc | ||
|
|
55e9c9c7b6 | ||
|
|
47e25da95e | ||
|
|
cb5d3b4e62 | ||
|
|
542ef73a30 | ||
|
|
f6d499e6c6 | ||
|
|
fe2169650e | ||
|
|
07798f2e23 | ||
|
|
86d2ce34f3 | ||
|
|
88846e52f5 | ||
|
|
27704407a3 | ||
|
|
3648690c5e | ||
|
|
97787553f7 | ||
|
|
10fd3e77d7 | ||
|
|
f806d29a75 | ||
|
|
25ac05622a | ||
|
|
f29d9ac993 |
@@ -0,0 +1,5 @@
|
||||
edit
|
||||
CMakeLists.txt.user
|
||||
/msbuild.log
|
||||
/*std*.log
|
||||
/*build
|
||||
@@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(plugin_python)
|
||||
set(project_type plugin)
|
||||
set(enable_warnings OFF)
|
||||
set(create_translations OFF)
|
||||
|
||||
if(DEFINED DEPENDENCIES_DIR)
|
||||
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/project.cmake)
|
||||
else()
|
||||
include(../cmake_common/project.cmake)
|
||||
endif()
|
||||
add_subdirectory(src/proxy)
|
||||
|
||||
add_subdirectory(src/runner)
|
||||
@@ -0,0 +1,40 @@
|
||||
version: 1.0.{build}
|
||||
skip_branch_with_pr: true
|
||||
image: Visual Studio 2019
|
||||
environment:
|
||||
WEBHOOK_URL:
|
||||
secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1Vbg57wBaeLhi49uGjxPw5GVujHku6kxN6ab89zhbS5GVeluR76GM83IbKV4Sh7udXzoYZZdg6YudtYHzdhCgUeiedpswbuczTq9ceIkkfSEWZuh/lMAAVVwvcGsJAnoPFw=
|
||||
build:
|
||||
parallel: true
|
||||
build_script:
|
||||
- cmd: >-
|
||||
git clone --depth=1 --branch=%APPVEYOR_REPO_BRANCH% https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella 2> $null
|
||||
|
||||
mkdir c:\projects\modorganizer-build -type directory
|
||||
|
||||
cd c:\projects\modorganizer-umbrella
|
||||
|
||||
C:\Python37-x64\python.exe unimake.py -d c:\projects\modorganizer-build -s Appveyor_Build=True %APPVEYOR_PROJECT_NAME%
|
||||
artifacts:
|
||||
- path: build\src\proxy\plugin_python.dll
|
||||
name: plugin_python_dll
|
||||
- path: build\src\proxy\plugin_python.pdb
|
||||
name: plugin_python_pdb
|
||||
- path: build\src\proxy\plugin_python.lib
|
||||
name: plugin_python_lib
|
||||
- path: build\src\runner\pythonrunner.dll
|
||||
name: pythonrunner_dll
|
||||
- path: build\src\runner\pythonrunner.pdb
|
||||
name: pythonrunner_pdb
|
||||
- path: build\src\runner\pythonrunner.lib
|
||||
name: pythonrunner_lib
|
||||
on_success:
|
||||
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
|
||||
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||
- ps: ./send.ps1 success $env:WEBHOOK_URL
|
||||
on_failure:
|
||||
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
|
||||
- ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stdout.log
|
||||
- ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stderr.log
|
||||
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||
- ps: ./send.ps1 failure $env:WEBHOOK_URL
|
||||
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
# appveyor does not build modorganizer in its standard location, so use
|
||||
# DEPENDENCIES_DIR to find cmake_common
|
||||
if(DEFINED DEPENDENCIES_DIR)
|
||||
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/src.cmake)
|
||||
else()
|
||||
include(../../../cmake_common/src.cmake)
|
||||
endif()
|
||||
|
||||
requires_library(python)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src/runner)
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "resource.h"
|
||||
|
||||
#ifdef SCONS_BUILD
|
||||
IDR_LOADER_DLL BINARY MOVEABLE PURE pythonRunner.dll
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
IDR_LOADER_DLL BINARY MOVEABLE PURE "..\\..\\pythonRunner\\debug\\pythonRunner.dll"
|
||||
#else // _DEBUG
|
||||
IDR_LOADER_DLL BINARY MOVEABLE PURE "..\\..\\pythonRunner\\release\\pythonRunner.dll"
|
||||
#endif // _DEBUG
|
||||
#endif
|
||||
@@ -1,213 +0,0 @@
|
||||
#include "proxypluginwrappers.h"
|
||||
#include <boost/python.hpp>
|
||||
#include <utility.h>
|
||||
#include "error.h"
|
||||
#include "gilock.h"
|
||||
|
||||
namespace bpy = boost::python;
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
|
||||
#define PYCATCH catch (const bpy::error_already_set &) { reportPythonError(); throw MyException("unhandled exception"); }\
|
||||
catch (...) { throw MyException("An unknown exception was thrown in python code"); }
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// IPluginTool Wrapper
|
||||
|
||||
|
||||
bool IPluginToolWrapper::init(MOBase::IOrganizer *moInfo)
|
||||
{
|
||||
try {
|
||||
return this->get_override("init")(bpy::ptr(moInfo));
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::name() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("name")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::author() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("author")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::description() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("description")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
MOBase::VersionInfo IPluginToolWrapper::version() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("version")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
bool IPluginToolWrapper::isActive() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("isActive")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QList<MOBase::PluginSetting> IPluginToolWrapper::settings() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("settings")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::displayName() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("displayName")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::tooltip() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("tooltip")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QIcon IPluginToolWrapper::icon() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("icon")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
void IPluginToolWrapper::setParentWidget(QWidget *parent)
|
||||
{
|
||||
try {
|
||||
this->get_override("setParentWidget")(parent);
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
void IPluginToolWrapper::display() const
|
||||
{
|
||||
try {
|
||||
GILock lock;
|
||||
|
||||
this->get_override("display")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
/// end IPluginTool Wrapper
|
||||
/////////////////////////////////////
|
||||
/// IPluginInstallerCustom Wrapper
|
||||
|
||||
|
||||
bool IPluginInstallerCustomWrapper::init(MOBase::IOrganizer *moInfo)
|
||||
{
|
||||
try {
|
||||
return this->get_override("init")(bpy::ptr(moInfo));
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginInstallerCustomWrapper::name() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("name")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginInstallerCustomWrapper::author() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("author")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginInstallerCustomWrapper::description() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("description")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
MOBase::VersionInfo IPluginInstallerCustomWrapper::version() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("version")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
bool IPluginInstallerCustomWrapper::isActive() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("isActive")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QList<MOBase::PluginSetting> IPluginInstallerCustomWrapper::settings() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("settings")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
unsigned int IPluginInstallerCustomWrapper::priority() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("priority")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
bool IPluginInstallerCustomWrapper::isManualInstaller() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("isManualInstaller")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
bool IPluginInstallerCustomWrapper::isArchiveSupported(const DirectoryTree &tree) const
|
||||
{
|
||||
try {
|
||||
//return this->get_override("isArchiveSupported")(tree);
|
||||
return false;
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
bool IPluginInstallerCustomWrapper::isArchiveSupported(const QString &archiveName) const
|
||||
{
|
||||
try {
|
||||
return this->get_override("isArchiveSupported")(archiveName);
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
std::set<QString> IPluginInstallerCustomWrapper::supportedExtensions() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("supportedExtensions")();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
|
||||
IPluginInstaller::EInstallResult IPluginInstallerCustomWrapper::install(GuessedValue<QString> &modName, const QString &archiveName,
|
||||
const QString &version, int modID)
|
||||
{
|
||||
try {
|
||||
return this->get_override("install")(modName, archiveName, version, modID);
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
|
||||
void IPluginInstallerCustomWrapper::setParentWidget(QWidget *parent)
|
||||
{
|
||||
try {
|
||||
this->get_override("setParentWidget")(parent);
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#ifndef PROXYPLUGINWRAPPERS_H
|
||||
#define PROXYPLUGINWRAPPERS_H
|
||||
|
||||
|
||||
#include <iplugintool.h>
|
||||
#include <iplugininstallersimple.h>
|
||||
#include <iplugininstallercustom.h>
|
||||
#include <iplugindiagnose.h>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <boost/python.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
class IPluginWrapper : public boost::python::wrapper<MOBase::IPlugin>
|
||||
{
|
||||
public:
|
||||
virtual bool init(MOBase::IOrganizer *moInfo);
|
||||
virtual QString name() const;
|
||||
virtual QString author() const;
|
||||
virtual QString description() const;
|
||||
virtual MOBase::VersionInfo version() const;
|
||||
virtual bool isActive() const;
|
||||
virtual QList<MOBase::PluginSetting> settings() const;
|
||||
};
|
||||
|
||||
|
||||
class IPluginToolWrapper: public MOBase::IPluginTool, public boost::python::wrapper<MOBase::IPluginTool>
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginTool)
|
||||
|
||||
public:
|
||||
virtual bool init(MOBase::IOrganizer *moInfo);
|
||||
virtual QString name() const;
|
||||
virtual QString author() const;
|
||||
virtual QString description() const;
|
||||
virtual MOBase::VersionInfo version() const;
|
||||
virtual bool isActive() const;
|
||||
virtual QList<MOBase::PluginSetting> settings() const;
|
||||
|
||||
virtual QString displayName() const;
|
||||
virtual QString tooltip() const;
|
||||
virtual QIcon icon() const;
|
||||
virtual void setParentWidget(QWidget *parent);
|
||||
|
||||
public slots:
|
||||
virtual void display() const;
|
||||
};
|
||||
|
||||
|
||||
class IPluginInstallerCustomWrapper: public MOBase::IPluginInstallerCustom, public boost::python::wrapper<MOBase::IPluginInstallerCustom>
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginInstaller MOBase::IPluginInstallerCustom)
|
||||
|
||||
public:
|
||||
virtual bool init(MOBase::IOrganizer *moInfo);
|
||||
virtual QString name() const;
|
||||
virtual QString author() const;
|
||||
virtual QString description() const;
|
||||
virtual MOBase::VersionInfo version() const;
|
||||
virtual bool isActive() const;
|
||||
virtual QList<MOBase::PluginSetting> settings() const;
|
||||
|
||||
virtual unsigned int priority() const;
|
||||
virtual bool isManualInstaller() const;
|
||||
virtual bool isArchiveSupported(const MOBase::DirectoryTree &tree) const;
|
||||
virtual bool isArchiveSupported(const QString &archiveName) const;
|
||||
virtual std::set<QString> supportedExtensions() const;
|
||||
virtual EInstallResult install(MOBase::GuessedValue<QString> &modName, const QString &archiveName,
|
||||
const QString &version, int modID);
|
||||
virtual void setParentWidget(QWidget *parent);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // PROXYPLUGINWRAPPERS_H
|
||||
+21
-16
@@ -28,7 +28,6 @@ along with python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QCoreApplication>
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
|
||||
@@ -135,8 +134,6 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
return true;
|
||||
}
|
||||
|
||||
//m_TempRunnerFile = ExtractResource(IDR_LOADER_DLL, "__pythonRunner.dll");
|
||||
//m_RunnerLib = ::LoadLibraryW(ToWString(m_TempRunnerFile).c_str());
|
||||
m_RunnerLib = ::LoadLibraryW(QDir::toNativeSeparators(m_MOInfo->pluginDataPath() + "/pythonRunner.dll").toStdWString().c_str());
|
||||
if (m_RunnerLib != nullptr) {
|
||||
CreatePythonRunner_func CreatePythonRunner = (CreatePythonRunner_func)::GetProcAddress(m_RunnerLib, "CreatePythonRunner");
|
||||
@@ -173,7 +170,7 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
return true;
|
||||
} else {
|
||||
DWORD error = ::GetLastError();
|
||||
qCritical("Failed to load python runner (%s): %s", qPrintable(m_TempRunnerFile), qPrintable(windowsErrorString(error)));
|
||||
qCritical("Failed to load python runner (%s): %s", qUtf8Printable(m_TempRunnerFile), qUtf8Printable(windowsErrorString(error)));
|
||||
if (error == ERROR_MOD_NOT_FOUND) {
|
||||
m_LoadFailure = FAIL_MISSINGDEPENDENCIES;
|
||||
}
|
||||
@@ -198,12 +195,12 @@ QString ProxyPython::description() const
|
||||
|
||||
VersionInfo ProxyPython::version() const
|
||||
{
|
||||
return VersionInfo(1, 3, 1, VersionInfo::RELEASE_FINAL);
|
||||
return VersionInfo(2, 1, 0, VersionInfo::RELEASE_FINAL);
|
||||
}
|
||||
|
||||
bool ProxyPython::isActive() const
|
||||
{
|
||||
return m_LoadFailure == FAIL_NONE;
|
||||
return m_LoadFailure == FAIL_NOTINIT;
|
||||
}
|
||||
|
||||
QList<PluginSetting> ProxyPython::settings() const
|
||||
@@ -216,24 +213,37 @@ QList<PluginSetting> ProxyPython::settings() const
|
||||
|
||||
QStringList ProxyPython::pluginList(const QString &pluginPath) const
|
||||
{
|
||||
QDirIterator iter(pluginPath, QStringList("*.py"));
|
||||
QDir dir(pluginPath);
|
||||
dir.setFilter(dir.filter() | QDir::NoDotAndDotDot);
|
||||
QDirIterator iter(dir);
|
||||
|
||||
// Note: We put python script (.py) and directory names, not the __init__.py
|
||||
// files in those since it is easier for the runner to import them.
|
||||
QStringList result;
|
||||
while (iter.hasNext()) {
|
||||
result.append(iter.next());
|
||||
QString name = iter.next();
|
||||
QFileInfo info = iter.fileInfo();
|
||||
|
||||
if (info.isFile() && name.endsWith(".py")) {
|
||||
result.append(name);
|
||||
}
|
||||
else if (info.isDir() && QDir(info.absoluteFilePath()).exists("__init__.py")) {
|
||||
result.append(name);
|
||||
// result.append(info.baseName());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
QObject *ProxyPython::instantiate(const QString &pluginName)
|
||||
QList<QObject*> ProxyPython::instantiate(const QString &pluginName)
|
||||
{
|
||||
if (m_Runner != nullptr) {
|
||||
QObject *result = m_Runner->instantiate(pluginName);
|
||||
QList<QObject*> result = m_Runner->instantiate(pluginName);
|
||||
return result;
|
||||
} else {
|
||||
return nullptr;
|
||||
return QList<QObject*>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,8 +350,3 @@ void ProxyPython::startGuidedFix(unsigned int key) const
|
||||
::ShellExecuteA(nullptr, "open", s_DownloadPythonURL, nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
Q_EXPORT_PLUGIN2(proxyPython, ProxyPython)
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
virtual QList<MOBase::PluginSetting> settings() const;
|
||||
|
||||
QStringList pluginList(const QString &pluginPath) const;
|
||||
QObject *instantiate(const QString &pluginName);
|
||||
QList<QObject*> instantiate(const QString &pluginName);
|
||||
|
||||
/**
|
||||
* @return the parent widget for newly created dialogs
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
#include "pythonpluginwrapper.h"
|
||||
|
||||
|
||||
using boost::python::extract;
|
||||
using boost::python::handle_exception;
|
||||
|
||||
|
||||
PythonPluginWrapper::PythonPluginWrapper(const boost::python::object &initFunction,
|
||||
const boost::python::object &nameFunction,
|
||||
const boost::python::object &authorFunction,
|
||||
const boost::python::object &descriptionFunction,
|
||||
const boost::python::object &versionFunction,
|
||||
const boost::python::object &isActiveFunction,
|
||||
const boost::python::object &settingsFunction)
|
||||
: m_InitFunction(initFunction)
|
||||
, m_NameFunction(nameFunction)
|
||||
, m_AuthorFunction(authorFunction)
|
||||
, m_DescriptionFunction(descriptionFunction)
|
||||
, m_VersionFunction(versionFunction)
|
||||
, m_IsActiveFunction(isActiveFunction)
|
||||
, m_SettingsFunction(settingsFunction)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PythonPluginWrapper::reportPythonError() const
|
||||
{
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
} else {
|
||||
qCritical("An unexpected C++ exception was thrown in python code");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PythonPluginWrapper::init(MOBase::IOrganizer *moInfo)
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<bool>(m_InitFunction(boost::python::ptr(moInfo)));
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString PythonPluginWrapper::name() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<QString>(m_NameFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString PythonPluginWrapper::author() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<QString>(m_AuthorFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString PythonPluginWrapper::description() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<QString>(m_DescriptionFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
MOBase::VersionInfo PythonPluginWrapper::version() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<MOBase::VersionInfo>(m_VersionFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return MOBase::VersionInfo();
|
||||
}
|
||||
}
|
||||
|
||||
bool PythonPluginWrapper::isActive() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<bool>(m_IsActiveFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QList<MOBase::PluginSetting> PythonPluginWrapper::settings() const
|
||||
{
|
||||
QList<MOBase::PluginSetting> result;
|
||||
try {
|
||||
boost::python::object l = m_SettingsFunction();
|
||||
if (!l.is_none()) {
|
||||
// boost::python::list l = extract<boost::python::list>(temp);
|
||||
for (int i = 0; i < boost::python::len(l); ++i) {
|
||||
result.append(extract<MOBase::PluginSetting>(l[i]));
|
||||
}
|
||||
}
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef PYTHONPLUGINWRAPPER_H
|
||||
#define PYTHONPLUGINWRAPPER_H
|
||||
|
||||
#include <iplugin.h>
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <boost/python.hpp>
|
||||
#endif
|
||||
|
||||
class PythonPluginWrapper : public virtual MOBase::IPlugin
|
||||
{
|
||||
|
||||
public:
|
||||
PythonPluginWrapper(const boost::python::object &initFunction,
|
||||
const boost::python::object &nameFunction,
|
||||
const boost::python::object &authorFunction,
|
||||
const boost::python::object &descriptionFunction,
|
||||
const boost::python::object &versionFunction,
|
||||
const boost::python::object &isActiveFunction,
|
||||
const boost::python::object &settingsFunction);
|
||||
|
||||
virtual bool init(MOBase::IOrganizer *moInfo);
|
||||
virtual QString name() const;
|
||||
virtual QString author() const;
|
||||
virtual QString description() const;
|
||||
virtual MOBase::VersionInfo version() const;
|
||||
virtual bool isActive() const;
|
||||
virtual QList<MOBase::PluginSetting> settings() const;
|
||||
|
||||
protected:
|
||||
void reportPythonError() const;
|
||||
|
||||
private:
|
||||
|
||||
boost::python::object m_InitFunction;
|
||||
boost::python::object m_NameFunction;
|
||||
boost::python::object m_AuthorFunction;
|
||||
boost::python::object m_DescriptionFunction;
|
||||
boost::python::object m_VersionFunction;
|
||||
boost::python::object m_IsActiveFunction;
|
||||
boost::python::object m_SettingsFunction;
|
||||
|
||||
};
|
||||
|
||||
#endif // PYTHONPLUGINWRAPPER_H
|
||||
@@ -1,80 +0,0 @@
|
||||
#include "pythontoolwrapper.h"
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
|
||||
using boost::python::extract;
|
||||
using boost::python::handle_exception;
|
||||
|
||||
PythonToolWrapper::PythonToolWrapper(const boost::python::object &initFunction,
|
||||
const boost::python::object &nameFunction,
|
||||
const boost::python::object &authorFunction,
|
||||
const boost::python::object &descriptionFunction,
|
||||
const boost::python::object &versionFunction,
|
||||
const boost::python::object &isActiveFunction,
|
||||
const boost::python::object &settingsFunction,
|
||||
const boost::python::object &displayNameFunction,
|
||||
const boost::python::object &tooltipFunction,
|
||||
const boost::python::object &iconFunction,
|
||||
const boost::python::object &displayFunction,
|
||||
const boost::python::object &setParentWidget)
|
||||
: PythonPluginWrapper(initFunction, nameFunction, authorFunction, descriptionFunction,
|
||||
versionFunction, isActiveFunction, settingsFunction)
|
||||
, m_DisplayNameFunction(displayNameFunction)
|
||||
, m_ToolTipFunction(tooltipFunction)
|
||||
, m_IconFunction(iconFunction)
|
||||
, m_DisplayFunction(displayFunction)
|
||||
, m_SetParentWidget(setParentWidget)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString PythonToolWrapper::displayName() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<QString>(m_DisplayNameFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString PythonToolWrapper::tooltip() const
|
||||
{
|
||||
try {
|
||||
return boost::python::extract<QString>(m_ToolTipFunction());
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QIcon PythonToolWrapper::icon() const
|
||||
{
|
||||
try {
|
||||
std::vector<const char*> rows;
|
||||
boost::python::object l = m_IconFunction();
|
||||
if (!l.is_none()) {
|
||||
for (int i = 0; i < boost::python::len(l); ++i) {
|
||||
rows.push_back(extract<const char*>(l[i]));
|
||||
}
|
||||
return QIcon(QPixmap(&rows[0]));
|
||||
} else {
|
||||
return QIcon();
|
||||
}
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
return QIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void PythonToolWrapper::display() const
|
||||
{
|
||||
try {
|
||||
m_SetParentWidget(parentWidget());
|
||||
|
||||
m_DisplayFunction();
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#ifndef PYTHONTOOLWRAPPER_H
|
||||
#define PYTHONTOOLWRAPPER_H
|
||||
|
||||
|
||||
#include <iplugintool.h>
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <boost/python.hpp>
|
||||
#endif
|
||||
|
||||
#include "pythonpluginwrapper.h"
|
||||
|
||||
|
||||
class PythonToolWrapper : public QObject, public MOBase::IPluginTool, public PythonPluginWrapper
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginTool)
|
||||
|
||||
public:
|
||||
PythonToolWrapper(const boost::python::object &initFunction,
|
||||
const boost::python::object &nameFunction,
|
||||
const boost::python::object &authorFunction,
|
||||
const boost::python::object &descriptionFunction,
|
||||
const boost::python::object &versionFunction,
|
||||
const boost::python::object &isActiveFunction,
|
||||
const boost::python::object &settingsFunction,
|
||||
const boost::python::object &displayNameFunction,
|
||||
const boost::python::object &tooltipFunction,
|
||||
const boost::python::object &iconFunction,
|
||||
const boost::python::object &displayFunction,
|
||||
const boost::python::object &setParentWidget);
|
||||
|
||||
using PythonPluginWrapper::init;
|
||||
using PythonPluginWrapper::name;
|
||||
|
||||
virtual QString displayName() const;
|
||||
virtual QString tooltip() const;
|
||||
virtual QIcon icon() const;
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void display() const;
|
||||
|
||||
private:
|
||||
|
||||
boost::python::object m_DisplayNameFunction;
|
||||
boost::python::object m_ToolTipFunction;
|
||||
boost::python::object m_IconFunction;
|
||||
boost::python::object m_DisplayFunction;
|
||||
|
||||
boost::python::object m_SetParentWidget;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // PYTHONTOOLWRAPPER_H
|
||||
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>ProxyPython</name>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="149"/>
|
||||
<source>Python Initialization failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="150"/>
|
||||
<source>On a previous start the Python Plugin failed to initialize.
|
||||
Either the value in Settings->Plugins->ProxyPython->plugin_dir is set incorrectly or it is empty and auto-detection doesn't work for whatever reason.
|
||||
Do you want to try initializing python again (at the risk of another crash)?
|
||||
Suggestion: Select "no", and click the warning sign for further help. Afterwards you have to re-enable the python plugin.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="193"/>
|
||||
<source>Proxy Plugin to allow plugins written in python to be loaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="281"/>
|
||||
<source>Python not installed or not found</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="284"/>
|
||||
<source>Python version is incompatible</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="287"/>
|
||||
<source>Invalid python path</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="290"/>
|
||||
<source>Initializing Python failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="293"/>
|
||||
<source>Python auto-detection failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="296"/>
|
||||
<source>ModOrganizer path contains a semicolon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="299"/>
|
||||
<source>invalid problem key %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="308"/>
|
||||
<source>Some MO plugins require the python interpreter to be installed. These plugins will not even show up in settings-&gt;plugins.<br>If you want to use those plugins, please install the 32-bit version of Python 2.7.x from <a href="%1">%1</a>.<br>This is only required to use some extended functionality in MO, you do not need Python to play the game.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="314"/>
|
||||
<source>Your installed python version has a different version than 2.7. Some MO plugins may not work.<br>If you have multiple versions of python installed you may have to configure the path to 2.7 (32 bit) in the settings dialog.<br>This is only required to use some extended functionality in MO, you do not need Python to play the game.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="321"/>
|
||||
<source>Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="324"/>
|
||||
<source>The auto-detection of the python path failed. I don't know why this would happen but you can try to fix it by setting python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="328"/>
|
||||
<source>Sorry, I don't know any details. Most likely your python installation is not supported.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="proxy/proxypython.cpp" line="331"/>
|
||||
<source>The path to Mod Organizer (%1) contains a semicolon. <br>While this is legal on NTFS drives there is a lot of software that doesn't handle it correctly.<br>Unfortunately MO depends on libraries that seem to fall into that group.<br>As a result the python plugin can't be loaded.<br>The only solution I can offer is to remove the semicolon / move MO to a path without a semicolon.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="runner/error.h" line="68"/>
|
||||
<source>An unexpected C++ exception was thrown in python code.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="runner/error.h" line="117"/>
|
||||
<source>An unknown exception was thrown in python code.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
@@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(pythonrunner)
|
||||
set(project_type plugin)
|
||||
set(enable_warnings OFF)
|
||||
set(install_dir bin/plugins/data)
|
||||
set(create_translations ON)
|
||||
|
||||
add_compile_definitions(
|
||||
QT_NO_KEYWORDS
|
||||
PYTHONRUNNER_LIBRARY)
|
||||
|
||||
# appveyor does not build modorganizer in its standard location, so use
|
||||
# DEPENDENCIES_DIR to find cmake_common
|
||||
if(DEFINED DEPENDENCIES_DIR)
|
||||
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/project.cmake)
|
||||
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/src.cmake)
|
||||
else()
|
||||
include(../../../cmake_common/project.cmake)
|
||||
include(../../../cmake_common/src.cmake)
|
||||
endif()
|
||||
|
||||
requires_project(game_features)
|
||||
requires_library(python)
|
||||
@@ -2,7 +2,7 @@ Import('qt_env')
|
||||
|
||||
env = qt_env.Clone()
|
||||
|
||||
env.EnableQtModules('Core', 'Gui')
|
||||
env.EnableQtModules('Core', 'Gui', 'Widgets')
|
||||
|
||||
env.AppendUnique(CPPDEFINES = 'PYTHONRUNNER_LIBRARY')
|
||||
|
||||
@@ -13,6 +13,10 @@ env.AppendUnique(CPPDEFINES = [
|
||||
'HAVE_ROUND'
|
||||
])
|
||||
|
||||
# Boost produces very long names with msvc truncates. Doesn't seem to cause
|
||||
# problems.
|
||||
env.AppendUnique(CPPFLAGS = [ '-wd4503' ])
|
||||
|
||||
# QMAKE_CXXFLAGS += /Zi
|
||||
# QMAKE_LFLAGS += /DEBUG
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+36
-14
@@ -1,26 +1,48 @@
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <boost/python.hpp>
|
||||
#endif
|
||||
#include <QString>
|
||||
#include <utility.h>
|
||||
#include <QDebug>
|
||||
#include "error.h"
|
||||
|
||||
using namespace MOBase;
|
||||
namespace bpy = boost::python;
|
||||
|
||||
void reportPythonError()
|
||||
ErrWrapper & ErrWrapper::instance()
|
||||
{
|
||||
if (PyErr_Occurred()) {
|
||||
// prints to s_ErrIO buffer
|
||||
PyErr_Print();
|
||||
// extract data from python buffer
|
||||
bpy::object mainModule = bpy::import("__main__");
|
||||
bpy::object mainNamespace = mainModule.attr("__dict__");
|
||||
bpy::object errMsgObj = bpy::eval("s_ErrIO.getvalue()", mainNamespace);
|
||||
QString errMsg = bpy::extract<QString>(errMsgObj.ptr());
|
||||
bpy::eval("s_ErrIO.truncate(0)", mainNamespace);
|
||||
static ErrWrapper err;
|
||||
return err;
|
||||
}
|
||||
|
||||
throw MyException(errMsg);
|
||||
} else {
|
||||
throw MyException("An unexpected C++ exception was thrown in python code");
|
||||
void ErrWrapper::write(const char * message)
|
||||
{
|
||||
buffer << message;
|
||||
if (buffer.tellp() != 0 && buffer.str().back() == '\n')
|
||||
{
|
||||
// actually put the string in a variable so it doesn't get destroyed as soon as we get a pointer to its data
|
||||
std::string string = buffer.str().substr(0, buffer.str().length() - 1);
|
||||
qCritical().nospace().noquote() << string.c_str();
|
||||
buffer = std::stringstream();
|
||||
}
|
||||
|
||||
if (recordingExceptionMessage)
|
||||
{
|
||||
lastException << message;
|
||||
}
|
||||
}
|
||||
|
||||
void ErrWrapper::startRecordingExceptionMessage()
|
||||
{
|
||||
recordingExceptionMessage = true;
|
||||
lastException = std::stringstream();
|
||||
}
|
||||
|
||||
void ErrWrapper::stopRecordingExceptionMessage()
|
||||
{
|
||||
recordingExceptionMessage = false;
|
||||
}
|
||||
|
||||
QString ErrWrapper::getLastExceptionMessage()
|
||||
{
|
||||
return QString::fromStdString(lastException.str());
|
||||
}
|
||||
|
||||
+118
-2
@@ -1,7 +1,123 @@
|
||||
#ifndef ERROR_H
|
||||
#define ERROR_H
|
||||
|
||||
// turn an error from the python interpreter into an exception
|
||||
void reportPythonError();
|
||||
#include <QString>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <utility.h>
|
||||
|
||||
struct ErrWrapper
|
||||
{
|
||||
static ErrWrapper& instance();
|
||||
|
||||
void write(const char* message);
|
||||
|
||||
void startRecordingExceptionMessage();
|
||||
|
||||
void stopRecordingExceptionMessage();
|
||||
|
||||
QString getLastExceptionMessage();
|
||||
|
||||
std::stringstream buffer;
|
||||
bool recordingExceptionMessage;
|
||||
std::stringstream lastException;
|
||||
};
|
||||
|
||||
namespace pyexcept {
|
||||
|
||||
/**
|
||||
* @brief Exception to throw when a python implementation does not implement
|
||||
* a pure virtual function.
|
||||
*/
|
||||
class MissingImplementation : public MOBase::MyException {
|
||||
public:
|
||||
MissingImplementation(std::string const& className, std::string const& methodName) :
|
||||
MyException(QString::fromStdString(
|
||||
fmt::format("Python class implementing \"{}\" has no implementation of method \"{}\".",
|
||||
className, methodName))) { }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception to throw when a python error occurs.
|
||||
*/
|
||||
class PythonError : public MOBase::MyException {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Create a new PythonError, fetching the error message from python. If the message
|
||||
* cannot be retrieved, `defaultErrorMessage()` is used instead.
|
||||
*/
|
||||
PythonError() : MyException(getPythonErrorMessage()) { }
|
||||
|
||||
/**
|
||||
* @brief Create a new PythonError with the given message.
|
||||
*
|
||||
* @param message Message for the exception.
|
||||
*/
|
||||
PythonError(QString message) : MyException(message) { }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static QString defaultErrorMessage() {
|
||||
return QObject::tr("An unexpected C++ exception was thrown in python code.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static QString getPythonErrorMessage() {
|
||||
if (PyErr_Occurred()) {
|
||||
ErrWrapper& errWrapper = ErrWrapper::instance();
|
||||
|
||||
errWrapper.startRecordingExceptionMessage();
|
||||
PyErr_Print();
|
||||
errWrapper.stopRecordingExceptionMessage();
|
||||
|
||||
return errWrapper.getLastExceptionMessage();
|
||||
}
|
||||
else {
|
||||
return defaultErrorMessage();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception to throw when an unknown error occured. This is typically thrown
|
||||
* from a catch(...) block.
|
||||
*/
|
||||
class UnknownException : public MOBase::MyException {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Create a new UnknownException with the default message.
|
||||
*
|
||||
* @see defaultErrorMessage
|
||||
*/
|
||||
UnknownException() : MyException(defaultErrorMessage()) { }
|
||||
|
||||
/**
|
||||
* @brief Create a new UnknownException with the given message.
|
||||
*
|
||||
* @param message Message for the exception.
|
||||
*/
|
||||
UnknownException(QString message) : MyException(message) { }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static QString defaultErrorMessage() {
|
||||
return QObject::tr("An unknown exception was thrown in python code.");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ERROR_H
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
#include "gamefeatureswrappers.h"
|
||||
|
||||
#include <boost/any.hpp>
|
||||
|
||||
#include <typeindex>
|
||||
|
||||
#include <ipluginlist.h>
|
||||
#include <iprofile.h>
|
||||
#include <isavegame.h>
|
||||
#include <isavegameinfowidget.h>
|
||||
|
||||
#include "ifiletree.h"
|
||||
#include "pythonwrapperutilities.h"
|
||||
|
||||
/////////////////////////////
|
||||
/// BSAInvalidation Wrapper
|
||||
|
||||
|
||||
bool BSAInvalidationWrapper::isInvalidationBSA(const QString &bsaName)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<bool>(this, "isInvalidationBSA", bsaName);
|
||||
}
|
||||
|
||||
void BSAInvalidationWrapper::deactivate(MOBase::IProfile *profile)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<void>(this, "deactivate", boost::python::ptr(profile));
|
||||
}
|
||||
|
||||
void BSAInvalidationWrapper::activate(MOBase::IProfile *profile)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<void>(this, "activate", boost::python::ptr(profile));
|
||||
}
|
||||
|
||||
bool BSAInvalidationWrapper::prepareProfile(MOBase::IProfile *profile)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<bool>(this, "prepareProfile", boost::python::ptr(profile));
|
||||
}
|
||||
/// end BSAInvalidation Wrapper
|
||||
/////////////////////////////
|
||||
/// DataArchives Wrapper
|
||||
|
||||
|
||||
QStringList DataArchivesWrapper::vanillaArchives() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QStringList>(this, "vanillaArchives");
|
||||
}
|
||||
|
||||
QStringList DataArchivesWrapper::archives(const MOBase::IProfile *profile) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QStringList>(this, "archives", boost::python::ptr(profile));
|
||||
}
|
||||
|
||||
void DataArchivesWrapper::addArchive(MOBase::IProfile *profile, int index, const QString &archiveName)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<void>(this, "addArchive", boost::python::ptr(profile), index, archiveName);
|
||||
}
|
||||
|
||||
void DataArchivesWrapper::removeArchive(MOBase::IProfile *profile, const QString &archiveName)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<void>(this, "removeArchive", boost::python::ptr(profile), archiveName);
|
||||
}
|
||||
/// end DataArchives Wrapper
|
||||
/////////////////////////////
|
||||
/// GamePlugins Wrapper
|
||||
|
||||
|
||||
void GamePluginsWrapper::writePluginLists(const MOBase::IPluginList * pluginList)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<void>(this, "writePluginLists", boost::python::ptr(pluginList));
|
||||
}
|
||||
|
||||
void GamePluginsWrapper::readPluginLists(MOBase::IPluginList * pluginList)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<void>(this, "readPluginLists", boost::python::ptr(pluginList));
|
||||
}
|
||||
|
||||
QStringList GamePluginsWrapper::getLoadOrder()
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QStringList>(this, "getLoadOrder");
|
||||
}
|
||||
|
||||
bool GamePluginsWrapper::lightPluginsAreSupported()
|
||||
{
|
||||
return basicWrapperFunctionImplementation<bool>(this, "lightPluginsAreSupported");
|
||||
}
|
||||
|
||||
/// end GamePlugins Wrapper
|
||||
/////////////////////////////
|
||||
/// LocalSavegames Wrapper
|
||||
|
||||
|
||||
MappingType LocalSavegamesWrapper::mappings(const QDir & profileSaveDir) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<MappingType>(this, "mappings", profileSaveDir);
|
||||
}
|
||||
|
||||
bool LocalSavegamesWrapper::prepareProfile(MOBase::IProfile * profile)
|
||||
{
|
||||
return basicWrapperFunctionImplementation<bool>(this, "prepareProfile", boost::python::ptr(profile));
|
||||
}
|
||||
|
||||
/// end LocalSavegames Wrapper
|
||||
/////////////////////////////
|
||||
/// ModDataChecker Wrapper
|
||||
|
||||
ModDataChecker::CheckReturn ModDataCheckerWrapper::dataLooksValid(std::shared_ptr<const MOBase::IFileTree> fileTree) const {
|
||||
return basicWrapperFunctionImplementation<CheckReturn>(this, "dataLooksValid", fileTree);
|
||||
}
|
||||
|
||||
std::shared_ptr<MOBase::IFileTree> ModDataCheckerWrapper::fix(std::shared_ptr<MOBase::IFileTree> fileTree) const {
|
||||
return basicWrapperFunctionImplementationWithDefault<std::shared_ptr<MOBase::IFileTree>>(this, [](auto&&... args) { return nullptr; }, "fix", fileTree);
|
||||
}
|
||||
|
||||
/// end ModDataChecker Wrapper
|
||||
/////////////////////////////
|
||||
/// ModDataContent Wrapper
|
||||
|
||||
std::vector<ModDataContent::Content> ModDataContentWrapper::getAllContents() const {
|
||||
return basicWrapperFunctionImplementation<std::vector<Content>>(this, "getAllContents");
|
||||
}
|
||||
std::vector<int> ModDataContentWrapper::getContentsFor(std::shared_ptr<const MOBase::IFileTree> fileTree) const {
|
||||
return basicWrapperFunctionImplementation<std::vector<int>>(this, "getContentsFor", fileTree);
|
||||
}
|
||||
|
||||
/// end ModDataContent Wrapper
|
||||
/////////////////////////////
|
||||
/// SaveGameInfo Wrapper
|
||||
|
||||
|
||||
MOBase::ISaveGame const * SaveGameInfoWrapper::getSaveGameInfo(QString const & file) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<MOBase::ISaveGame*>(this, m_SaveGames[file], "getSaveGameInfo", file);
|
||||
}
|
||||
|
||||
SaveGameInfoWrapper::MissingAssets SaveGameInfoWrapper::getMissingAssets(QString const & file) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<SaveGameInfoWrapper::MissingAssets>(this, "getMissingAssets", file);
|
||||
}
|
||||
|
||||
MOBase::ISaveGameInfoWidget* SaveGameInfoWrapper::getSaveGameWidget(QWidget* parent) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<MOBase::ISaveGameInfoWidget*>(this, m_SaveGameWidget, "getSaveGameWidget", parent);
|
||||
}
|
||||
|
||||
bool SaveGameInfoWrapper::hasScriptExtenderSave(QString const & file) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<bool>(this, "hasScriptExtenderSave", file);
|
||||
}
|
||||
/// end SaveGameInfo Wrapper
|
||||
/////////////////////////////
|
||||
/// ScriptExtender Wrapper
|
||||
|
||||
QString ScriptExtenderWrapper::BinaryName() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QString>(this, "BinaryName");
|
||||
}
|
||||
|
||||
QString ScriptExtenderWrapper::PluginPath() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QString>(this, "PluginPath");
|
||||
}
|
||||
|
||||
QString ScriptExtenderWrapper::loaderName() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QString>(this, "loaderName");
|
||||
}
|
||||
|
||||
QString ScriptExtenderWrapper::loaderPath() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QString>(this, "loaderPath");
|
||||
}
|
||||
|
||||
QStringList ScriptExtenderWrapper::saveGameAttachmentExtensions() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QStringList>(this, "saveGameAttachmentExtensions");
|
||||
}
|
||||
|
||||
bool ScriptExtenderWrapper::isInstalled() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<bool>(this, "isInstalled");
|
||||
}
|
||||
|
||||
QString ScriptExtenderWrapper::getExtenderVersion() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QString>(this, "getExtenderVersion");
|
||||
}
|
||||
|
||||
WORD ScriptExtenderWrapper::getArch() const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<WORD>(this, "getArch");
|
||||
}
|
||||
|
||||
/// end ScriptExtender Wrapper
|
||||
/////////////////////////////
|
||||
/// UnmanagedMods Wrapper
|
||||
|
||||
|
||||
QStringList UnmanagedModsWrapper::mods(bool onlyOfficial) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QStringList>(this, "mods", onlyOfficial);
|
||||
}
|
||||
|
||||
QString UnmanagedModsWrapper::displayName(const QString & modName) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QString>(this, "displayName", modName);
|
||||
}
|
||||
|
||||
QFileInfo UnmanagedModsWrapper::referenceFile(const QString & modName) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QFileInfo>(this, "referenceFile", modName);
|
||||
}
|
||||
|
||||
QStringList UnmanagedModsWrapper::secondaryFiles(const QString & modName) const
|
||||
{
|
||||
return basicWrapperFunctionImplementation<QStringList>(this, "secondaryFiles", modName);
|
||||
}
|
||||
/// end UnmanagedMods Wrapper
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
game_features_map_from_python::game_features_map_from_python()
|
||||
{
|
||||
boost::python::converter::registry::push_back(&convertible, &construct, boost::python::type_id<std::map<std::type_index, boost::any>>());
|
||||
}
|
||||
|
||||
void * game_features_map_from_python::convertible(PyObject * objPtr)
|
||||
{
|
||||
return PyDict_Check(objPtr) ? objPtr : nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void insertGameFeature(std::map<std::type_index, boost::any>& map, const boost::python::object& pyObject)
|
||||
{
|
||||
map[std::type_index(typeid(T))] = boost::python::extract<T*>(pyObject)();
|
||||
}
|
||||
|
||||
void game_features_map_from_python::construct(PyObject * objPtr, boost::python::converter::rvalue_from_python_stage1_data * data)
|
||||
{
|
||||
void *storage = ((boost::python::converter::rvalue_from_python_storage<std::map<std::type_index, boost::any>>*)data)->storage.bytes;
|
||||
std::map<std::type_index, boost::any> *result = new (storage) std::map<std::type_index, boost::any>();
|
||||
boost::python::dict source(boost::python::handle<>(boost::python::borrowed(objPtr)));
|
||||
boost::python::list keys = source.keys();
|
||||
int len = boost::python::len(keys);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
boost::python::object pyKey = keys[i];
|
||||
boost::python::object pyValue = source[pyKey];
|
||||
|
||||
boost::mp11::mp_for_each<
|
||||
// Must user pointers because mp_for_each construct object:
|
||||
boost::mp11::mp_transform<std::add_pointer_t, MpGameFeaturesList>
|
||||
>([&](auto* pt) {
|
||||
using T = std::remove_pointer_t<decltype(pt)>;
|
||||
boost::python::extract<T*> extract(pyValue);
|
||||
if (extract.check()) {
|
||||
(*result)[std::type_index(typeid(T))] = extract();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
data->convertible = storage;
|
||||
}
|
||||
|
||||
void registerGameFeaturesPythonConverters()
|
||||
{
|
||||
namespace bpy = boost::python;
|
||||
|
||||
game_features_map_from_python();
|
||||
|
||||
// Features require defs for all methods as Python can access C++ features
|
||||
bpy::class_<BSAInvalidationWrapper, boost::noncopyable>("BSAInvalidation")
|
||||
.def("isInvalidationBSA", bpy::pure_virtual(&BSAInvalidation::isInvalidationBSA), bpy::arg("name"))
|
||||
.def("deactivate", bpy::pure_virtual(&BSAInvalidation::deactivate), bpy::arg("profile"))
|
||||
.def("activate", bpy::pure_virtual(&BSAInvalidation::activate), bpy::arg("profile"))
|
||||
;
|
||||
|
||||
bpy::class_<DataArchivesWrapper, boost::noncopyable>("DataArchives")
|
||||
.def("vanillaArchives", bpy::pure_virtual(&DataArchives::vanillaArchives))
|
||||
.def("archives", bpy::pure_virtual(&DataArchives::archives), bpy::arg("profile"))
|
||||
.def("addArchive", bpy::pure_virtual(&DataArchives::addArchive), (bpy::arg("profile"), "index", "name"))
|
||||
.def("removeArchive", bpy::pure_virtual(&DataArchives::removeArchive), (bpy::arg("profile"), "name"))
|
||||
;
|
||||
|
||||
bpy::class_<GamePluginsWrapper, boost::noncopyable>("GamePlugins")
|
||||
.def("writePluginLists", bpy::pure_virtual(&GamePlugins::writePluginLists), bpy::arg("plugin_list"))
|
||||
.def("readPluginLists", bpy::pure_virtual(&GamePlugins::readPluginLists), bpy::arg("plugin_list"))
|
||||
.def("getLoadOrder", bpy::pure_virtual(&GamePlugins::getLoadOrder))
|
||||
.def("lightPluginsAreSupported", bpy::pure_virtual(&GamePlugins::lightPluginsAreSupported))
|
||||
;
|
||||
|
||||
bpy::class_<LocalSavegamesWrapper, boost::noncopyable>("LocalSavegames")
|
||||
.def("mappings", bpy::pure_virtual(&LocalSavegames::mappings), bpy::arg("profile_save_dir"))
|
||||
.def("prepareProfile", bpy::pure_virtual(&LocalSavegames::prepareProfile), bpy::arg("profile"))
|
||||
;
|
||||
|
||||
auto modDataCheckerClass = bpy::class_<ModDataCheckerWrapper, boost::noncopyable>("ModDataChecker");
|
||||
{
|
||||
bpy::scope scope = modDataCheckerClass;
|
||||
|
||||
bpy::enum_<ModDataChecker::CheckReturn>("CheckReturn")
|
||||
.value("INVALID", ModDataChecker::CheckReturn::INVALID)
|
||||
.value("FIXABLE", ModDataChecker::CheckReturn::FIXABLE)
|
||||
.value("VALID", ModDataChecker::CheckReturn::VALID)
|
||||
.export_values()
|
||||
;
|
||||
|
||||
modDataCheckerClass
|
||||
.def("dataLooksValid", bpy::pure_virtual(&ModDataChecker::dataLooksValid), bpy::arg("filetree"))
|
||||
.def("fix", bpy::pure_virtual(&ModDataChecker::fix), bpy::arg("filetree"))
|
||||
;
|
||||
}
|
||||
|
||||
{
|
||||
bpy::scope scope = bpy::class_<ModDataContentWrapper, boost::noncopyable>("ModDataContent")
|
||||
.def("getAllContents", bpy::pure_virtual(&ModDataContent::getAllContents))
|
||||
.def("getContentsFor", bpy::pure_virtual(&ModDataContent::getContentsFor), bpy::arg("filetree"))
|
||||
;
|
||||
|
||||
bpy::class_<ModDataContent::Content>("Content",
|
||||
bpy::init<int, QString, QString, bpy::optional<bool>>((bpy::arg("id"), "name", "icon", bpy::arg("filter_only") = false)))
|
||||
.add_property("id", &ModDataContent::Content::id)
|
||||
.add_property("name", &ModDataContent::Content::name)
|
||||
.add_property("icon", &ModDataContent::Content::icon)
|
||||
.def("isOnlyForFilter", &ModDataContent::Content::isOnlyForFilter)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
bpy::class_<SaveGameInfoWrapper, boost::noncopyable>("SaveGameInfo")
|
||||
.def("getSaveGameInfo", bpy::pure_virtual(&SaveGameInfo::getSaveGameInfo), bpy::return_value_policy<bpy::manage_new_object>(),
|
||||
bpy::arg("filepath"))
|
||||
.def("getMissingAssets", bpy::pure_virtual(&SaveGameInfo::getMissingAssets), bpy::arg("filepath"))
|
||||
.def("getSaveGameWidget", bpy::pure_virtual(&SaveGameInfo::getSaveGameWidget), bpy::return_value_policy<bpy::manage_new_object>(),
|
||||
bpy::arg("parent"), "[optional]")
|
||||
.def("hasScriptExtenderSave", bpy::pure_virtual(&SaveGameInfo::hasScriptExtenderSave), bpy::arg("filepath"))
|
||||
;
|
||||
|
||||
bpy::class_<ScriptExtenderWrapper, boost::noncopyable>("ScriptExtender")
|
||||
.def("BinaryName", bpy::pure_virtual(&ScriptExtender::BinaryName))
|
||||
.def("PluginPath", bpy::pure_virtual(&ScriptExtender::PluginPath))
|
||||
.def("loaderName", bpy::pure_virtual(&ScriptExtender::loaderName))
|
||||
.def("loaderPath", bpy::pure_virtual(&ScriptExtender::loaderPath))
|
||||
.def("saveGameAttachmentExtensions", bpy::pure_virtual(&ScriptExtender::saveGameAttachmentExtensions))
|
||||
.def("isInstalled", bpy::pure_virtual(&ScriptExtender::isInstalled))
|
||||
.def("getExtenderVersion", bpy::pure_virtual(&ScriptExtender::getExtenderVersion))
|
||||
.def("getArch", bpy::pure_virtual(&ScriptExtender::getArch))
|
||||
;
|
||||
|
||||
bpy::class_<UnmanagedModsWrapper, boost::noncopyable>("UnmanagedMods")
|
||||
.def("mods", bpy::pure_virtual(&UnmanagedMods::mods), bpy::arg("official_only"))
|
||||
.def("displayName", bpy::pure_virtual(&UnmanagedMods::displayName), bpy::arg("mod_name"))
|
||||
.def("referenceFile", bpy::pure_virtual(&UnmanagedMods::referenceFile), bpy::arg("mod_name"))
|
||||
.def("secondaryFiles", bpy::pure_virtual(&UnmanagedMods::secondaryFiles), bpy::arg("mod_name"))
|
||||
;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user