Compare commits

...
348 Commits
Author SHA1 Message Date
isanae c922b97578 Merge pull request #56 from Holt59/fix-ifiletree-copy
Fix IFileTree copy
2020-08-06 09:00:16 -04:00
Mikaël Capelle fed261e9eb Fix IFileTree::copy() bindings. 2020-08-06 11:10:26 +02:00
isanae f531905e4a Merge pull request #54 from Holt59/add-missing-iplugin-bases
Add missing bpy::bases<IPluginX> for some plugin types.
2020-07-28 21:26:13 -04:00
Mikaël Capelle e25fa00285 Add missing bpy::bases<IPlugin> for some plugin types. 2020-07-22 21:23:47 +02:00
isanae 5c63d62a1e Merge pull request #53 from Holt59/add-executableforcedloadsetting-converter
Add executableforcedloadsetting converter
2020-07-20 15:18:42 -04:00
Mikaël Capelle 624c5257bd Add missing converter for QList<ExecutableForcedLoadSetting>. 2020-07-20 19:44:51 +02:00
Mikaël Capelle 480eb3f30e Fix name of default argument in persistent(). 2020-07-20 19:36:58 +02:00
isanae 4909b6cff0 Merge pull request #52 from Holt59/add-arg-names
Add arg names
2020-07-14 12:23:02 -04:00
Mikaël Capelle 331416d1e7 Add binding for IInstallationManager::getSupportedExtensions(). 2020-07-14 16:39:45 +02:00
Mikaël Capelle c955b4e8de Fix argument name for getSaveGameWidget. 2020-07-14 15:00:26 +02:00
Mikaël Capelle 727a55e1a8 Add missing argument names. 2020-07-14 14:36:11 +02:00
Mikaël Capelle 6c1f961d83 Add missing arg names for GuessedString constructor. 2020-07-14 13:33:48 +02:00
Mikaël Capelle a3e9916400 Fix order of overloads for VersionInfo constructors. 2020-07-14 13:21:30 +02:00
Mikaël Capelle 0fbb88b3c1 Add argument names to bindings. 2020-07-14 13:14:53 +02:00
isanae 5023a13aa2 Merge pull request #51 from isanae/ts
updated translations
2020-07-10 12:21:48 -04:00
isanae fe8a0b849c updated translations
disabled translations for plugin_python, identical to pythonrunner
2020-07-10 12:17:45 -04:00
isanae e1a1b70121 Merge pull request #50 from Holt59/add-movariant
Add module variable to fake MoVariant.
2020-06-17 18:08:03 -04:00
Mikaël Capelle 671776f306 Clarify comment for MoVariant export. 2020-06-16 22:12:25 +02:00
Mikaël Capelle 95ed8ae14a Add module variable to fake MoVariant. 2020-06-16 21:57:31 +02:00
isanae e6ca79c694 Merge pull request #49 from Holt59/new-iorganizer-callbacks
Update for new organizer callbacks.
2020-06-16 15:40:04 -04:00
Mikaël Capelle c521178769 Update for new organizer callbacks. 2020-06-15 22:48:21 +02:00
Al 1cbfde96a0 Merge pull request #48 from Holt59/fix-game-plugins-getloadorder
Change getLoadOrder() to return the load order in python.
2020-06-14 15:59:29 -07:00
Mikaël Capelle e7ae48f633 Update getLoadOrder() bindings following game_features change. 2020-06-14 15:31:21 +02:00
Mikaël Capelle d0fd776648 Change getLoadOrder() to return the load order in python. 2020-06-14 14:51:52 +02:00
Al cbdf8fee14 Merge pull request #46 from Holt59/allow-plugins-to-fix-filetree
Update following ModDataChecker change.
2020-06-14 05:48:54 -07:00
Al 5fe9c44f26 Merge pull request #47 from Holt59/executable-forced-load-settings-bindings
Add missing bindings for executableForcedLoads and fix ExecutableInfo.
2020-06-14 05:48:21 -07:00
Mikaël Capelle 3f02f975aa Add missing bindings for executableForcedLoads and fix ExecutableInfo. 2020-06-14 10:52:45 +02:00
Mikaël Capelle b2b0b6f5c5 Missing includes and fix names in bindings. 2020-06-14 00:06:41 +02:00
Mikaël Capelle 6ee58c6bf9 Update following ModDataChecker change. 2020-06-13 23:51:52 +02:00
isanae 2efc6d4af6 Merge pull request #45 from Holt59/fix-exception-transfer-at-startup
Fix Python -> C++ error transfer during plugin creation.
2020-06-13 13:10:04 -04:00
Mikaël Capelle 760cca172f Fix Python -> C++ error transfer during plugin creation. 2020-06-13 19:04:58 +02:00
Al 26c0e628b8 Merge pull request #44 from Holt59/add-ifiletree-copy
Add bindings for IFileTree::copy().
2020-06-13 02:52:10 -07:00
Mikaël Capelle ab4a067042 Add bindings for IFileTree::copy(). 2020-06-12 20:54:52 +02:00
Al 38188e0b17 Merge pull request #43 from Holt59/add-utility-functions
Add bindings for utility functions from uibase.
2020-06-10 04:00:05 -07:00
Mikaël Capelle 863893cc31 Add bindings for utility functions from uibase. 2020-06-09 23:31:25 +02:00
Al 06b11c86ba Merge pull request #40 from Holt59/fix-exceptions-plugin-preview
Fix genFilePreview issue with exceptions not being properly translated to C++.
2020-06-09 05:53:15 -07:00
Al d4a6a57f14 Merge pull request #42 from Holt59/fix-iprofile-invalidationactive
Fix IProfile::invalidationActive
2020-06-08 13:10:17 -07:00
Mikaël Capelle 2ea33f4faa Return a tuple<bool, bool> for IProfile::invalidationActive() to replace the bool* parameter. 2020-06-08 21:45:01 +02:00
Al b4c23ad733 Merge pull request #41 from Holt59/iorganizer-findfiles-glob
Add findFiles overload with glob patterns.
2020-06-08 12:05:26 -07:00
Mikaël Capelle 71db9d81d4 Add findFiles overload with glob patterns. 2020-06-08 18:37:59 +02:00
Mikaël Capelle e712448ca0 Fix genFilePreview issue with exceptions not being properly translated to C++. 2020-06-08 17:54:30 +02:00
Al 98b8d92350 Merge pull request #39 from Holt59/qclass-converter-fix
Fix issue with QClass converter for overloaded functions.
2020-06-08 08:40:46 -07:00
Mikaël Capelle 7cc0f974f5 Use a sequence converter for QStringList instead of a QClass converter. 2020-06-07 17:56:58 +02:00
Mikaël Capelle 48c35a8f92 Switch 0 for nullptr. 2020-06-07 17:01:46 +02:00
Mikaël Capelle 4b9fc2d32a Fix issue with QClass converter for overloaded functions. 2020-06-07 16:54:53 +02:00
Al be63c1d9de Merge pull request #38 from Holt59/set-plugin-setting-signal
Add IOrganizer signal when a plugin setting is changed.
2020-06-07 03:45:50 -07:00
Mikaël Capelle 100a2d03f0 Add IOrganizer signal when a plugin setting is changed. 2020-06-05 16:48:42 +02:00
Al fcd1177acd Merge pull request #37 from Holt59/install-manager-improvements
Installation manager improvements
2020-06-01 13:56:14 -07:00
Mikaël Capelle 5eeb02403f Update bindings after uibase update. 2020-05-30 14:58:50 +02:00
isanae eca495c849 Merge pull request #36 from Holt59/mod-data-content
Add ModDataContent to the python interface.
2020-05-28 23:43:02 -04:00
Mikaël Capelle 024a333194 Update to match game features. 2020-05-27 22:44:32 +02:00
Mikaël Capelle ead37d1dbe Add ModDataContent to the python interface. 2020-05-25 21:24:50 +02:00
Al 65003ef4ad Merge pull request #35 from Holt59/moddatachecker
Minor updates following changes in uibase.
2020-05-23 14:07:30 -07:00
Mikaël Capelle a3b593f714 Remove time() method from FileTreeEntry. 2020-05-23 21:45:05 +02:00
Mikaël Capelle ab4168fd93 Minor updates following changes in uibase. 2020-05-23 17:32:01 +02:00
Al bfad575467 Merge pull request #34 from Holt59/cleaning
Cleaning and improvements
2020-05-22 12:30:48 +02:00
Mikaël Capelle d5f44f424d Add comments for basicWrapperFunction functions. 2020-05-21 23:15:41 +02:00
Mikaël Capelle da679b1d6d Common code for basicWrapperFunction functions. 2020-05-21 23:11:56 +02:00
Mikaël Capelle 751e67e86c Fix issue with Python errors not being retrieved correctly in C++. 2020-05-21 22:08:20 +02:00
Mikaël Capelle c96fe2d21a Add missing qflags converter for ModState. 2020-05-21 17:47:08 +02:00
Mikaël Capelle 4b4c36df7a Add possibility to create multiple plugins object from a single .py file or python module. 2020-05-20 20:52:31 +02:00
Mikaël Capelle 5f9d2b296d Remove usage of getDataFolderName() for ModDataChecker. 2020-05-20 19:53:49 +02:00
Mikaël Capelle 05e79cc13b Merge remote-tracking branch 'origin/master' into cleaning 2020-05-20 18:32:22 +02:00
Al 3f5aa49dee Merge pull request #33 from Holt59/python-module
Allow implementation of python plugin as whole module.
2020-05-20 13:15:46 +02:00
Al 3e9209a191 Merge pull request #32 from Holt59/new-filetree
Update python bindings for UI base change and new filetree implementation
2020-05-20 13:03:39 +02:00
Mikaël Capelle d70942efa1 Rollback to setGameName instead of setGamePlugin for mod interface. 2020-05-19 17:58:44 +02:00
Mikaël Capelle d9393a2d2b Add WalkReturn enumeration. 2020-05-18 16:16:26 +02:00
Mikaël Capelle 7c1389d479 Add ModDataChecker game feature and clean some game-feature related code. 2020-05-16 20:47:41 +02:00
Mikaël Capelle 7333bde006 Add makeTree in moprivate. 2020-05-16 17:37:57 +02:00
Mikaël Capelle fae9f1b52f Allow None value from python in functor converter. 2020-05-16 17:37:41 +02:00
Mikaël Capelle 23c6f3fad9 Better arity check for functor converter. 2020-05-16 17:37:22 +02:00
Mikaël Capelle f12bb05d61 Update python version to 3.8. 2020-05-14 23:24:38 +02:00
Mikaël Capelle d931d71a43 Translate failure in exceptions for some IFileTree methods. Add IFileTree::walk. 2020-05-14 23:18:23 +02:00
Mikaël Capelle aa75c3b18e Add .feature() method to the Python interface of IPluginGame. 2020-05-13 17:35:33 +02:00
Mikaël Capelle eb29202b2f Use UPPER_CASE for enumeration values (kept non-uppercase for backward compatibility). 2020-05-13 15:55:05 +02:00
Mikaël Capelle fe0a75b819 Add to-python converter for QVariant holding QStringList. 2020-05-13 15:35:50 +02:00
Mikaël Capelle 90a99b37c9 Add missing override annotation and use using to bring invalidate in public scope. 2020-05-13 14:34:17 +02:00
Mikaël Capelle 7c474c58ca Add small comments. 2020-05-13 14:33:15 +02:00
Mikaël Capelle 288f9f9a95 Rename IModRepositoryBridge to be consistent with other interfaces. 2020-05-12 19:25:57 +02:00
Mikaël Capelle a05006a0b3 Allow implementation of python plugin as whole module. 2020-05-11 23:51:58 +02:00
Mikaël Capelle d6b8c66911 Move include directive where they should be. 2020-05-11 23:40:06 +02:00
Mikaël Capelle 0c52c2417c Remove unused global variable. 2020-05-11 23:39:55 +02:00
Mikaël Capelle 24205bba66 Remove useless wrappers. 2020-05-11 23:36:35 +02:00
Mikaël Capelle f0f949c4ef Remove ModRepositoryBridgeWrapper since it is not needed anymore. 2020-05-11 23:26:29 +02:00
Mikaël Capelle 6b88cee9d8 Remove useless includes. 2020-05-11 23:26:06 +02:00
Mikaël Capelle 1825c58666 Remove comment. 2020-05-11 23:18:44 +02:00
Mikaël Capelle 83a89ca595 Move utils::register_ at the top of the module definition. 2020-05-11 23:16:51 +02:00
Mikaël Capelle e9fdfd40aa Add comment for Q_DELEGATE. 2020-05-11 23:02:08 +02:00
Mikaël Capelle fcf1aa8b42 Move converter to a dedicate file. Add Q_DELEGATE for QObject-derived wrappers. 2020-05-11 23:00:29 +02:00
Mikaël Capelle d404a37fed Add/fix bindings for ISaveGame and ISaveGameInfoWidget. 2020-05-10 16:01:14 +02:00
Mikaël Capelle b360cae555 Add missing include in error.h. 2020-05-10 15:57:46 +02:00
Mikaël Capelle 039e33f5fa Minor clean and first try for ISaveGameInfoWidget. 2020-05-09 23:30:10 +02:00
Mikaël Capelle 622d4246a7 Clean some comments. 2020-05-09 21:32:23 +02:00
Mikaël Capelle 2f1646a2e6 Remove HANDLE_converters since it is not used anymore and did not really work. 2020-05-09 21:27:00 +02:00
Mikaël Capelle 716cbcf733 More cleaning. 2020-05-09 21:16:30 +02:00
Mikaël Capelle 62f10c03ff Temporary commit. 2020-05-09 21:13:45 +02:00
Mikaël Capelle 957b786d8c Start cleaning interfaces. 2020-05-09 18:19:31 +02:00
Mikaël Capelle 29a5eb8366 Remove wrong static_assert(). 2020-05-07 00:19:11 +02:00
Mikaël Capelle 4209d90533 Remove left-out method not implemented. 2020-05-06 22:08:25 +02:00
Mikaël Capelle 7bbf05bc0c Apply appendIfInstance for each class separately. 2020-05-06 12:51:27 +02:00
Mikaël Capelle 154c643bff Replace TRY_PLUGIN_TYPE with a more modern C++ variant. 2020-05-05 17:52:54 +02:00
Mikaël Capelle 2146cc9207 Fix wrapper for custom installer. 2020-05-04 20:17:02 +02:00
Mikaël Capelle 163ed213ef Update the install() bindings to allow more flexibility and be easier to use. 2020-05-04 20:09:24 +02:00
Mikaël Capelle 6919539d35 Remove left-out comment. 2020-05-04 18:40:53 +02:00
Mikaël Capelle 917b8dfb4b Slight modification for tuple and variant registers using C++17 fold expressions. 2020-05-04 01:58:56 +02:00
Mikaël Capelle 54e447c0a9 Switch from boost variant/tuple to std. 2020-05-04 01:47:30 +02:00
Mikaël Capelle 206454c34e Remove makeTree that was meant for testing purpose. 2020-05-03 23:16:58 +02:00
Mikaël Capelle 457529546b Add a bit of documentation to register functions. 2020-05-03 21:01:43 +02:00
Mikaël Capelle b9de35772f Clean sequence converters. 2020-05-03 20:57:50 +02:00
Mikaël Capelle 4589cab093 Add missing std::vector register for installation manager. 2020-05-03 20:19:25 +02:00
Mikaël Capelle 2b4eedb62b Clean std::set/std::vector from/to python conversions. 2020-05-03 20:17:49 +02:00
Mikaël Capelle 36022774e3 Add methods to utils to register map, vector and set. 2020-05-03 20:17:14 +02:00
Mikaël Capelle aac45a39e2 Make register_variant work for all variant types. 2020-05-03 20:16:57 +02:00
Mikaël Capelle 61ad2ef2b6 Clean bindings for IFileTree and FileTreeEntry. 2020-05-03 18:27:26 +02:00
Mikaël Capelle 1ea006b74e Add bindings for FileInfo. 2020-05-03 18:26:27 +02:00
Mikaël Capelle af37a451f9 Better variant handling for IFileTree::merge. 2020-05-03 18:26:11 +02:00
Mikaël Capelle 473cef6217 Add utility package with register_map for std::map. 2020-05-03 18:25:35 +02:00
Mikaël Capelle 5cd7917709 Add to_python to register_variant.h. 2020-05-03 18:25:16 +02:00
Mikaël Capelle 585296d527 Fix issue with shared pointer being registered twice. 2020-05-03 18:24:32 +02:00
Mikaël Capelle 221949f48b Fix issue with Functor_converter when return type was not bool or void. 2020-05-03 13:39:04 +02:00
Mikaël Capelle 8b118ad898 Better handling of boost::variant. 2020-05-03 13:38:47 +02:00
Mikaël Capelle f83ed39287 Modify FileTypes enumeration for FileTreeEntry. 2020-05-03 12:57:23 +02:00
Mikaël Capelle 8a286f9cfc Change Functor_converter to use a function-type template argument. 2020-05-03 12:57:01 +02:00
Mikaël Capelle 70172ddda6 Add possibility to create GuessedString from python. 2020-05-02 15:34:06 +02:00
Mikaël Capelle 817f8d7238 Fix variants() method of GuessedValue. 2020-05-02 15:05:24 +02:00
Mikaël Capelle 9f5dab285d Fix return_value_policy for methods returning QWidget. 2020-05-02 15:04:44 +02:00
Mikaël Capelle 53b91f0092 Update exposed method names for installer to be consistent with others. 2020-05-02 13:28:08 +02:00
Mikaël Capelle f1d5a1f31b Improve GuessedValue binding and switch to upper-case for enumerations in Python. 2020-05-02 13:22:55 +02:00
Mikaël Capelle 626a7bc670 Update python bindings for tree to be consistent with others. 2020-05-02 13:22:34 +02:00
Mikaël Capelle c9115e7ad0 Add python interface for IPluginInstallerSimple. 2020-05-02 00:30:17 +02:00
Mikaël Capelle 6cececc7a0 Fix issue with default QDateTime() throwing error. 2020-05-01 21:32:30 +02:00
Mikaël Capelle d82640455f Update wrappers and expose the new file tree interface. 2020-05-01 21:32:08 +02:00
Mikaël Capelle f25602cc69 Update the wrapper and the python interface after change to IModInterface. 2020-05-01 21:30:31 +02:00
Silarn 168b9d7b0d Appveyor CMAKE fix 2020-05-01 04:59:02 -05:00
isanae 247944baa8 Merge pull request #31 from isanae/new-cmakefiles
New cmakefiles
2020-04-26 02:53:56 -04:00
isanae 332b8239bb unused 2020-04-25 00:51:20 -04:00
isanae 97a93a5989 now using new cmakefiles 2020-04-25 00:51:14 -04:00
Al e871617843 Merge pull request #30 from AnyOldName3/threadsafe
Make runner threadsafe again
2020-04-17 14:41:38 +02:00
AnyOldName3 c5d4857f47 Make functor converter variadic
Duplicating code three times is silly.
2020-04-16 00:56:57 +01:00
AnyOldName3 5825661a4f Only initialise Python once
When switching instances, the Python runner gets another initPython call, despite the previous interpreter existing. Most of the function was either a no-op or was redundant, and the GIL state got confusing. This is the simplest fix.

If things catch fire that I haven't anticipated, instead of returning true, we can destroy the pre-existing interpreter and create a new one by running the rest of the function.
2020-04-16 00:53:29 +01:00
AnyOldName3 2e13cf0dab Ensure we relinquish the GIL after initialising Python and have it when destroying callables 2020-04-15 17:01:28 +01:00
Chris Bessent d6dd0342b7 Merge pull request #29 from ModOrganizer2/2_2_2
Pull in 2.2.2.1 changes
2020-01-13 23:05:28 -07:00
Chris Bessent 67abab0779 Merge pull request #28 from ModOrganizer2/Develop
Stage for release 2.2.2
2020-01-06 05:11:19 -07:00
Silarn b0ef81214a Fix cmakelists and use zip 2019-10-29 01:35:15 -05:00
Silarn b2ae43a0e5 Add lightPluginsAreSupported to the wrapped game plugin functions 2019-10-19 02:28:01 -05:00
LostDragonist 52dd7454be Update version 2019-10-06 17:22:09 -05:00
LostDragonist 059dc8b9d2 Report plugin as active even if failed
This is required for the plugin to report notifications.  This
behavior was changed in the main MO program at some point.
2019-10-06 17:20:53 -05:00
Silarn b8bcecbed4 Update Appveyor to official VS 2019 image 2019-09-28 00:41:47 -05:00
Jeremy Rimpo 42e559b59c Merge pull request #26 from ModOrganizer2/Develop
Stage for release 2.2.1
2019-07-22 01:02:42 -05:00
Jeremy Rimpo b7d343a8dd Merge pull request #27 from AnyOldName3/message-forwarding
Message forwarding
2019-07-22 00:56:29 -05:00
AnyOldName3 63a6c504b0 Restore logging of historically-logged Python exceptions. 2019-07-22 00:08:35 +01:00
AnyOldName3 19dcdd95c0 Prevent PyQt from using its buggy exception logging by making it look like we're using custom exception handling. 2019-07-15 20:04:44 +01:00
AnyOldName3 ac5540ba87 Forward Python stdout and stderr to qDebug and qCritical 2019-07-15 20:02:18 +01:00
Silarn 0708bdedbf Improve error parser for _C_API loader 2019-07-02 12:33:18 -05:00
Silarn 2b6f453fbc Add better error handling when loading the SIP API 2019-07-01 22:19:14 -05:00
Brian Munro 4f86e542cc Merge pull request #25 from AnyOldName3/sip-transfer-fix
Correctly use SIP to transfer ownership of objects from Python to C++
2019-06-01 09:02:05 +02:00
AnyOldName3 e280b07cb6 Correctly use SIP to transfer ownership of objects from Python to C++ 2019-06-01 00:59:39 +01:00
Silarn 0c11e75f0f Set optimization for release builds 2019-05-22 02:04:22 -05:00
Silarn ab72c2f42f Fix artifact paths 2019-05-22 01:07:13 -05:00
Silarn cbe679aad8 Add logs to build artifacts on CI fail, commit translation changes 2019-05-21 23:46:06 -05:00
Silarn 59e5f1acf2 Switch to local build files as appveyor can't use installed files 2019-05-21 02:27:58 -05:00
Silarn d0598cd849 Unify artifacts source path to install path 2019-05-21 01:37:18 -05:00
Silarn 174abb3cea Enable parallel building 2019-05-09 02:10:42 -05:00
Silarn dee8825960 Set appveyor image to VS 2019 Preview 2019-05-08 23:10:34 -05:00
LostDragonist 46a4ee8653 Merge pull request #24 from ModOrganizer2/Develop
Stage for Release 2.2.0
2019-05-03 21:09:18 -05:00
Brian Munro 4721ab35df Merge pull request #23 from ModOrganizer2/Appveyor
Support Appveyor.
2019-04-29 14:18:19 +02:00
LePresidente 352e5c2103 Fixed artifacts for proxy_python. 2019-04-29 14:07:19 +02:00
LePresidente 78278ae57d Support Appveyor. 2019-04-29 10:30:47 +02:00
LostDragonist 3eb85cd17f Update for startApplication 2019-03-24 21:28:13 -05:00
Brian Munro 208965b96d Merge pull request #22 from ModOrganizer2/Appveyor
Removed unneeded cmake variables due to that umbrella handles them co…
2019-03-09 20:20:01 +02:00
LostDragonist c17d703b15 Add function for tracking status 2019-03-07 11:20:59 -06:00
LostDragonist 65eb0c6374 Add function to get configured mods directory 2019-02-23 07:11:19 -06:00
LostDragonist 97a20d522a Add setGameName to the mod interface 2019-02-22 22:16:17 -06:00
Silarn caee1fb7f6 Change to uibase requires Qt5Network linkage 2019-02-18 21:40:12 -06:00
Silarn bab649af43 Update to support API changes to uibase 2019-02-18 21:40:12 -06:00
Brian Munro 30ab7b8e14 Removed unneeded cmake variables due to that umbrella handles them correctly.
Requires testing.
2019-02-12 21:37:41 +02:00
LostDragonist 956d481ca4 Make logs more consistent in format and content 2019-01-30 20:53:48 -06:00
LostDragonist 41a4f273d6 Support for force loading libraries 2019-01-11 01:39:05 -06:00
LostDragonist 66391098b6 Update version to 2.0.1.0 2019-01-05 16:43:30 -06:00
LostDragonist c9d77cf948 Change qPrintable to qUtf8Printable to better support non-ASCII text 2019-01-05 16:34:11 -06:00
LostDragonist b939f7e88e Add enumerations for plugin states and mod states 2018-12-21 02:30:58 -06:00
LostDragonist be6b102599 Merge pull request #21 from ModOrganizer2/Develop
Stage for release 2.1.6
2018-12-20 13:58:41 -06:00
LostDragonist a1bc87e75a Fix the crash in a better, non-leaky way 2018-12-17 17:56:24 -06:00
LostDragonist 4160dea823 Convert a crash when converting strings to QStrings to possibly a memory leak 2018-12-16 18:27:45 -06:00
LostDragonist 1bd5dda7d8 Update version to 2.0.0.0 2018-12-12 02:14:02 -06:00
LostDragonist 9780aeb477 Improve refresh of data when changing profile settings 2018-12-08 00:12:09 -06:00
LostDragonist f6d41a1a81 Update for archive invalidation changes 2018-12-05 06:34:30 -06:00
Al 69ff972b12 Merge pull request #20 from AnyOldName3/settable-plugin-settings
Fix typo preventing IOrganizer::setPluginSetting from being used in P…
2018-09-25 20:28:15 +02:00
Al ada342e818 Merge pull request #19 from AnyOldName3/qvariant-from-unicode
Add missing PyUnicode_Check which prevented QVariants being created f…
2018-09-25 20:27:58 +02:00
AnyOldName3 051c14fe72 Add working version of IOrganizer::waitForApplication (#18) 2018-09-25 20:27:23 +02:00
AnyOldName3 f841a3b13a Add support for the default (invalid) QVariant 2018-09-19 22:52:40 +01:00
AnyOldName3 60701b6ba0 Add forgotten PyDict_Check 2018-09-19 22:36:11 +01:00
AnyOldName3 a8cf8d45f3 Fix typo preventing IOrganizer::setPluginSetting from being used in Python 2018-09-19 22:16:50 +01:00
AnyOldName3 84c04c32dc Add missing PyUnicode_Check which prevented QVariants being created from Python 3 strings 2018-09-19 21:45:42 +01:00
Al 6ce4138b31 Add new function wrapper for archive conflicts (#17) 2018-09-09 23:28:53 +02:00
Silarn d1f6766e16 Allow installs to pass Mod ID through (fixes NCC installs losing ID) 2018-09-09 04:20:21 -05:00
LostDragonist aa2b0744f7 Update for changes to local save game class 2018-08-26 17:55:31 -05:00
Jeremy Rimpo f1997b4788 Merge pull request #15 from ModOrganizer2/python3
Migrate to python 3.7
2018-08-23 11:48:07 -05:00
Brian Munro 423e6f8842 Merge pull request #14 from Modorganizer2/Develop
Stage for 2.1.5 release
2018-08-21 12:11:25 +02:00
Silarn b5b547e041 Changes to compile and run with python3 (WIP) 2018-08-20 19:01:18 -05:00
Silarn 61977d6149 Remove archive conflict code from python 3 branch 2018-08-20 19:00:06 -05:00
Silarn fbf59519c0 Fix to use modularized sip API and embedded python libs 2018-08-20 18:49:15 -05:00
Silarn 08bcebe19c Changes to compile and run with python3 (WIP) 2018-08-20 18:49:15 -05:00
LostDragonist 4900135130 Merge pull request #13 from AnyOldName3/free-plugin-support
Add support for free plugins which don't implement any specialised interface
2018-08-15 15:41:55 -05:00
AnyOldName3 b70fa8174e Add support for free plugins which don't implement any specialised interface 2018-08-15 15:34:08 +01:00
Brian Munro 437d89fc04 Merge pull request #12 from Modorganizer2/Develop
Stage for 2.1.3 release
2018-05-08 12:20:04 +02:00
Silarn 51b59de04d Changes to allow installer_NCC to use the game source set in the DL meta 2018-05-07 01:28:59 -05:00
Silarn 19015289cb Updating gitignore 2018-05-04 00:28:40 -05:00
Silarn e004b56dc9 Fit primarySources to new wrapper method 2018-05-03 22:32:31 -05:00
Jeremy Rimpo fba18c2b96 Merge pull request #11 from AnyOldName3/reusable-wrapper-template
Helpful error message and reduce code duplication
2018-05-03 20:49:05 -05:00
AnyOldName3 00c38f5f03 Remove superfluous template parameter specification to shrink lines to a more readable length. 2018-05-03 22:22:32 +01:00
AnyOldName3 8919fbd351 Use new template for game features wrappers. 2018-05-03 22:19:55 +01:00
Silarn 6a3a257ecd Allow for primary game sources and marking mods as converted/working 2018-05-03 16:17:39 -05:00
AnyOldName3 ec4945db3e Use new template for (non-pointless) uibase wrappers. 2018-05-03 22:02:06 +01:00
AnyOldName3 9f975b92b2 Create template for wrapper functions and add helpful error message. Use this for plugin wrappers. 2018-05-03 21:56:23 +01:00
Jeremy Rimpo 17c86ef540 Merge pull request #10 from AnyOldName3/proxy-multiple-inheritance-support
Return a plugin as multiple (differently-typed) instances to work aro…
2018-05-02 14:02:13 -05:00
AnyOldName3 7ab4b71ed3 Return a plugin as multiple (differently-typed) instances to work around multiple inheritance issues 2018-05-02 17:24:09 +01:00
Jeremy Rimpo 61ecb68918 Merge pull request #9 from AnyOldName3/implement-more-interfaces-2
Implement more interfaces
2018-05-01 18:25:53 -05:00
AnyOldName3 94886104f3 Prevent the C++ part of PyQt objects being deleted while the Python component is still accessible. 2018-05-02 00:19:29 +01:00
AnyOldName3 902024e508 Add Game Features support 2018-04-25 17:25:12 +01:00
AnyOldName3 0a9b4b9fc4 Change the capitalisation of sipapiaccess.h to make it consistent with other files 2018-04-22 15:39:09 +01:00
AnyOldName3 028c14a951 Add missing include guard to sipApiAccess.h 2018-04-22 15:37:29 +01:00
AnyOldName3 bf8f427cd8 Move sipAPI getter function to a shared header so it isn't duplicated. 2018-04-22 00:59:42 +01:00
AnyOldName3 8fe091ab48 Implement IPluginProxy bindings. 2018-04-22 00:34:59 +01:00
AnyOldName3 8877fee4fa Implement IpluginModPage bindings. 2018-04-20 16:40:39 +01:00
AnyOldName3 f13a5961df Align ModRepositoryFileInfo indentation 2018-04-20 16:40:39 +01:00
AnyOldName3 7b6ca76dec Handle conversion for types IPluginModPage depends on 2018-04-20 16:40:39 +01:00
AnyOldName3 a35208d902 Improve QVariant conversion and generalise QMap conversion 2018-04-20 16:40:39 +01:00
AnyOldName3 4feb06a099 Add IPluginFileMapper Wrapper and bindings. 2018-04-20 16:40:39 +01:00
AnyOldName3 0abbab9f8c Add missing parts of IOrganizer bindings 2018-04-20 16:40:39 +01:00
AnyOldName3 86d859d430 Allow anonymous Python functions to return values 2018-04-20 16:40:38 +01:00
AnyOldName3 5a730941db Implement wrapper and bindings for IPluginDiagnose 2018-04-20 16:40:38 +01:00
AnyOldName3 c70f78adfe Reduce code duplication by moving common implementation to macros 2018-04-20 16:40:38 +01:00
AnyOldName3 e8af8819df Add PYCATCH missed when rebasing 2018-04-20 16:40:38 +01:00
AnyOldName3 de809c6d57 Fix simple errors with IPluginGame proxy and add warning when the unimplemented part is encountered 2018-04-20 16:40:38 +01:00
AnyOldName3 01168483c5 handle errors in Python game plugins 2018-04-20 16:40:38 +01:00
AnyOldName3 317f13177e Move IPluginGameWrapper's mentod implementations into the cpp file 2018-04-20 16:40:38 +01:00
AnyOldName3 c47b94d534 Restore indentation which rearraging things broke 2018-04-20 16:40:38 +01:00
AnyOldName3 ca51a53d41 Make IPluginGameWrapper into a class and include the necessary Qt annotations 2018-04-20 16:40:38 +01:00
AnyOldName3 9722d5b093 Move IPluginGameWrapper to proxypluginwrappers.h as it's a wrapper for a plugin. 2018-04-20 16:40:38 +01:00
AnyOldName3 2df983e22c Create ExecutableInfo interface 2018-04-20 16:40:38 +01:00
AnyOldName3 52417d64e4 Implement missing handling for QFileInfo 2018-04-20 16:40:38 +01:00
AnyOldName3 4a558d4caf Implement from_python handling for QStringList 2018-04-20 16:40:38 +01:00
AnyOldName3 8dd9a710b4 Replace wrong QDir converter 2018-04-20 16:40:38 +01:00
AnyOldName3 377199f233 Put plugin wrappers in alphabetical order 2018-04-20 16:40:38 +01:00
Silarn 18a73c2f54 Remove remnants of QtScript and fix some CMake issues 2018-04-19 01:43:57 -05:00
Silarn fba28bb9ab Add SortMechanism check 2018-04-18 03:30:09 -05:00
Silarn cdbc0f3bdb Support for multi-game downloads 2018-04-16 13:07:56 -05:00
Silarn ffbd4e3f11 Support for multi-game downloads 2018-04-16 12:51:40 -05:00
Jeremy Rimpo e1ba01777d Merge pull request #8 from AnyOldName3/version-info-missing-parts
Add missing comparison operators and functions for MOBase::VersionInfo
2018-04-13 12:44:29 -05:00
Jeremy Rimpo 9cbb35d354 Merge pull request #7 from AnyOldName3/cleanup
Cleanup dead code & update .gitignore
2018-04-13 12:43:44 -05:00
Brian Munro abff0e890d Merge pull request #6 from Modorganizer2/Develop
Merge to Master for Release
2018-04-13 08:44:06 +02:00
Jeremy Rimpo c076d7a8bb Remove extraneous search code 2018-04-13 00:38:21 -05:00
AnyOldName3 e277c9b56b Add missing comparison operators and functions for MOBase::VersionInfo 2018-04-12 01:16:27 +01:00
AnyOldName3 d8ad6569ba remove dead include 2018-04-11 17:27:23 +01:00
AnyOldName3 e08b8be570 Remove dead code 2018-04-11 17:12:27 +01:00
AnyOldName3 aca861194d Update .gitignore with msbuild stuff 2018-04-11 17:10:55 +01:00
Silarn fdffe6f277 Prep for Qt 5.11 (backward-compatible) 2018-04-10 23:28:32 -05:00
Silarn 341daf5c5f Fix up CMAKE to use /MP and allow building through umbrella 2018-04-07 17:12:21 -05:00
Jeremy Rimpo b272bd12fe Merge pull request #5 from Modorganizer2/LePresidente-patch-1
Fixed typo causing compilation to fail
2018-03-19 13:33:10 -05:00
Brian Munro d6b673f149 Fixed typo causing compilation to fail
Fixed typo causing compilation to fail
2018-03-19 11:05:00 +02:00
Jeremy Rimpo 81ec421adb Merge pull request #4 from AnyOldName3/better-qflags-support
Better QFlags support
2018-03-17 00:02:12 -05:00
AnyOldName3 f3fa0baa41 Make indentation consistent 2018-03-17 00:35:59 +00:00
AnyOldName3 9a3465cc7a Register converters for all remaining uses of QFlags in the Python wrappers 2018-03-17 00:19:45 +00:00
AnyOldName3 277a2862b1 Make QFlags conversion bidirectional and register the converter for more uses of QFlags 2018-03-17 00:05:17 +00:00
Jeremy Rimpo 046e080943 Merge pull request #3 from AnyOldName3/register-missing-functions
Register some functions which Tannin created wrappers for, but omitte…
2018-03-16 13:28:41 -05:00
AnyOldName3 af7823b920 Register some functions which Tannin created wrappers for, but omitted to make accessible from Python 2018-03-16 17:03:48 +00:00
Jeremy Rimpo d408512a2c Merge pull request #2 from AnyOldName3/full-unicode-support
Allow conversion of any unicode sequence into a QString
2018-03-15 22:25:04 -05:00
AnyOldName3 10437e0aca Allow conversion of any unicode sequence into a QString 2018-03-16 00:32:21 +00:00
Al c6e8a223e1 Merge pull request #1 from AnyOldName3/unicode-support
Add support for converting Python unicode strings to QStrings
2018-03-15 23:26:31 +01:00
AnyOldName3 425ec8df5a Add support for converting Python unicode strings to QStrings 2018-03-15 21:21:23 +00:00
Jeremy Rimpo 39e17ebbe3 Merge pull request #6 from Silarn/mainline_dev
Allow getLauncherName to be overridden
2017-12-12 15:44:01 -06:00
Jeremy Rimpo fc0a257b51 Allow getLauncherName to be overridden 2017-12-12 12:41:28 -06:00
Brian Munro fe87c841a8 Merge pull request #5 from Silarn/mainline_dev
Add QDir and required function to pythonrunner to fix missing definition
2017-12-08 19:40:40 +02:00
Jeremy Rimpo 705d423839 Add QDir and required function to pythonrunner to fix missing definition 2017-12-08 02:41:53 -06:00
Brian Munro 9dff2ab02e Merge pull request #4 from Silarn/mainline_dev
Add CCPlugins support
2017-12-03 07:51:57 +02:00
Jeremy Rimpo 1bc41a72b4 Add CCPlugins support 2017-11-18 12:28:36 -06:00
Brian Munro d212bff9e9 Merge pull request #3 from Silarn/mainline_dev
Fix bind failure due to function overload and move to std bind (MSVC 2017 - Boost 1.65.1)
2017-11-05 17:26:29 +02:00
Jeremy Rimpo 85cb9b18e4 Fix bind failure due to function overload and move to std bind 2017-11-05 03:49:56 -06:00
LePresidente 6a5ab7f747 Updated cmakelists to get the QT5 location from the QT_ROOT variable, instead of expecting it in DEPENDENCIES_DIR. 2017-09-21 16:48:15 +02:00
Brian Munro 539b068b71 Merge pull request #2 from Hugues92/master
Cannot override basePath as it is not present in parent class
2017-03-29 07:35:28 -07:00
Hugues92 96dbb56467 Cannot override basePath as it is not present in parent class 2017-03-22 23:22:38 +01:00
Brian Munro ea408a05af Merge pull request #1 from ZachHaber/master
Adding basePath to python plugins
2017-01-17 20:23:22 -08:00
ZachHaber fa66025024 Adding basePath to python plugins
Adds the virtual function override to the boost python wrapper.
2017-01-17 17:05:22 -06:00
LePresidente 3e61a88abb added if statement to allow to build on msvc2013 2016-12-12 05:13:08 -08:00
lepresidente 828e35a129 changes required by adding gameNexusName to uibase. 2016-12-04 17:52:43 +02:00
lepresidente cc58ccc992 Fixed cmake python location.
Fixed build issue with VS2015.
2016-11-27 16:54:19 +02:00
Tannin aa37f30c68 bugfix: invalid return type in python api 2016-06-06 20:27:29 +02:00
Tannin f9353e4da0 translation 2016-06-04 20:39:14 +02:00
Tannin 9a310229e7 updated wrappers to current api 2016-05-06 22:45:52 +02:00
Tannin a78db4cbdc Merge branch 'ThosRTanner-issue/418' 2016-02-10 18:55:43 +01:00
Tannin 9502ea561e Merge branch 'issue/418' of https://github.com/ThosRTanner/modorganizer-plugin_python into ThosRTanner-issue/418
Conflicts:
	src/runner/uibasewrappers.h
2016-02-10 18:55:18 +01:00
Tannin 179deda6e4 Merge branch 'ThosRTanner-master' 2016-02-10 18:52:48 +01:00
Tannin fa85cc89d3 Merge branch 'master' of https://github.com/ThosRTanner/modorganizer-plugin_python into ThosRTanner-master
Conflicts:
	src/runner/uibasewrappers.h
2016-02-10 18:52:20 +01:00
Tannin ee31647014 minor cleanup 2016-02-09 19:34:09 +01:00
Thomas Tanner 4bb0994d71 Merge branch 'master' into issue/418 2016-01-24 15:57:54 +00:00
Thomas Tanner 4b8b75e641 Removing the 'get' in all function names and making FO4 plugin build
Merge branch 'master' of https://github.com/TanninOne/modorganizer-plugin_python

# Conflicts:
#	src/runner/uibasewrappers.h
2016-01-24 15:23:30 +00:00
Tannin 2fcb932e16 allow for game plugins to be written in python 2016-01-10 19:50:19 +01:00
Tannin 40192cb583 Merge branch 'master' of https://github.com/TanninOne/modorganizer-plugin_python 2015-12-28 14:35:43 +01:00
Tannin 163e3d4544 removed get-prefix from many getters 2015-12-28 14:35:35 +01:00
TanninOne a65763fb58 fixes to build system 2015-12-28 13:46:31 +01:00
Thomas Tanner d144d7c97b Fix const correctness 2015-12-26 15:47:50 +00:00
Thomas Tanner de99a71085 Merge branch 'master' into issue/418 2015-12-26 15:26:41 +00:00
Thomas Tanner 9bdb48c6bc Merge remote-tracking branch 'refs/remotes/TanninOne/master' into issue/418 2015-12-26 15:04:13 +00:00
Thomas Tanner a20b166290 Restore start download file method (3 of 3) 2015-12-20 22:25:45 +00:00
Thomas Tanner d1b2259cc5 For TanninOne/modarganizer#418
Changes to support getting list of mods / esps to activate from game plugin
2015-12-19 20:49:30 +00:00
Tannin 4bb048aa67 Merge branch 'master' of https://github.com/TanninOne/modorganizer-plugin_python
Conflicts:
	src/runner/pythonrunner.cpp
	src/runner/uibasewrappers.h
2015-12-06 20:58:22 +01:00
Tannin 0b53e86e5a updated python api 2015-12-06 20:55:36 +01:00
Thomas Tanner 9077573b9d Merge remote-tracking branch 'refs/remotes/TanninOne/master' 2015-12-06 18:08:43 +00:00
TanninOne 0fa436fc0f Merge pull request #5 from ThosRTanner/issue/344
Issue 344
2015-12-06 18:44:14 +01:00
Thomas Tanner d75eda53fc Merge remote-tracking branch 'TanninOne/master' into issue/344 2015-12-06 17:31:13 +00:00
Thomas Tanner a71566122e Merge remote-tracking branch 'TanninOne/master' into issue/344
# Conflicts:
#	src/runner/pythonrunner.cpp
#	src/runner/uibasewrappers.h
2015-12-06 17:31:02 +00:00
TanninOne 69b988eede Merge pull request #1 from ThosRTanner/issue/308
View web pages from non-nexus installs (3 of 4)
2015-12-06 17:56:42 +01:00
Thomas Tanner c106d6f342 Merge remote-tracking branch 'TanninOne/master' 2015-12-06 16:22:27 +00:00
Thomas Tanner 4a6f8e84f4 work through build issues 2015-12-06 16:13:29 +00:00
TanninOne efc0b1962f Merge branch 'ThosRTanner-issue/344' 2015-12-06 16:24:22 +01:00
TanninOne 8f408a77d2 Merge branch 'issue/344' of https://github.com/ThosRTanner/modorganizer-plugin_python into ThosRTanner-issue/344 2015-12-06 16:23:29 +01:00
Thomas Tanner dccc265364 Merge remote-tracking branch 'TanninOne/master' 2015-12-06 14:56:14 +00:00
TanninOne aa9c6ead94 Merge pull request #4 from ThosRTanner/issue/356
Refactor gameinfo & 'shared' library to use game plugins (7 of 17)
2015-12-06 13:21:25 +01:00
Thomas Tanner f94f37b635 Merge remote-tracking branch 'refs/remotes/TanninOne/master' into issue/356
Conflicts:
	src/runner/pythonrunner.cpp
2015-12-05 12:48:39 +00:00
Thomas Tanner 9fdcde3bd5 Merge remote-tracking branch 'TanninOne/master' into issue/344 2015-12-05 10:33:09 +00:00
Thomas Tanner 11c92e7e96 Merge remote-tracking branch 'refs/remotes/TanninOne/master' 2015-12-05 10:02:16 +00:00
Thomas Tanner 287a82ed48 Most of work for savegame 2015-12-05 06:51:41 +00:00
Thomas Tanner c9299bb623 Addition of directory validity check to IPluginGame API 2015-11-28 14:48:28 +00:00
Tannin 7d6d51b213 fixed build scripts and added fallout 4 support 2015-11-28 10:58:49 +01:00
Thomas Tanner e60121b21f Renamed getNexusName to getGameShortName as previously because it hopefully isn't too nexus related. 2015-11-26 21:17:06 +00:00
Thomas Tanner 7f7a3fb1ca Replaced the IPluginGame getNexusDisplayURL with some APIs in NexusInterface
It makes more sense to have them here as they have very little to do with the game, more to do with the origin of the mod.
2015-11-26 21:03:23 +00:00
Thomas Tanner 9ba337ef17 Remove the getNexusManagementURL as it is a property of how you talk to nexus, not the game 2015-11-26 17:45:30 +00:00
Thomas Tanner 1455bda2f8 Sigh - python wrapper version of the 2 URL fetch functions 2015-11-26 07:40:53 +00:00
Thomas Tanner cc62f15cc8 Replace GameInfo::getNexusModID with IPluginGame::getNexusModOrganizerID()
Also implement IPluginGame::getNexusGameID() but not hooked it in yet.
2015-11-24 16:16:10 +00:00
Thomas Tanner 0b9a56fa7a Replace GameInfo::getLoadorderMechanism with IPluginGame::getLoadOrderMechanism 2015-11-24 14:20:47 +00:00
Thomas Tanner fc8f6c77bc Remove most instances of GameInfo::getname, and transfer getDLCPlugins to the plugingame interface
Also removed startDownloadNextFile as it doesn't appear to be used anywhere
2015-11-23 18:34:04 +00:00
Thomas Tanner 55e9c9c7b6 Final eradication of igameinfo and adding python wrappers for IPluginGame 2015-11-22 21:18:12 +00:00
Thomas Tanner 47e25da95e Removes igameinfo.h from everywhere apart from (sort of) the pythonrunner plugin. 2015-11-22 08:42:42 +00:00
Thomas Tanner cb5d3b4e62 Replace GameInfo::path with iPluginGame::gameDirectory (or dataDirectory where applicable)
Note: this isn''t ideal as it's not backward compatible
2015-11-21 16:41:28 +00:00
Thomas Tanner 542ef73a30 Removal of (get)BinaryName.
Note in pythonrunner this is a bit commented out so I can think about how to deal with it.
2015-11-21 12:28:48 +00:00
Thomas Tanner f6d499e6c6 Merge remote-tracking branch 'refs/remotes/TanninOne/master' 2015-11-18 20:46:19 +00:00
Tannin fe2169650e updated build scripts 2015-11-16 21:39:53 +01:00
Thomas Tanner 07798f2e23 More changes suggested by compiling with clang 2015-11-09 18:14:57 +00:00
Thomas Tanner 86d2ce34f3 Fix compilation issues with clang, requires adding widgets to build 2015-11-08 23:15:55 +00:00
Thomas Tanner 88846e52f5 Add support for version dependency checks 2015-11-01 18:27:03 +00:00
Thomas Tanner 27704407a3 Add the python wrapper changes for the new setURL method 2015-10-15 19:06:04 +01:00
Thomas Tanner 3648690c5e Merge remote-tracking branch 'TanninOne/master' 2015-10-10 14:00:38 +01:00
Tannin 97787553f7 more work on build system 2015-10-09 19:57:45 +02:00
Tannin 10fd3e77d7 more work on build system 2015-10-09 19:57:17 +02:00
convert-repo f806d29a75 update tags 2015-09-07 16:36:52 +00:00
Tom Tanner 25ac05622a Small fix to shut up messages about long boost names 2015-08-20 19:53:39 +01:00
Tannin f29d9ac993 added plugin interface to add/remove/list categories to/from/of mods 2015-06-10 22:09:32 +02:00
37 changed files with 3941 additions and 2392 deletions
+5
View File
@@ -0,0 +1,5 @@
edit
CMakeLists.txt.user
/msbuild.log
/*std*.log
/*build
+15
View File
@@ -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)
+40
View File
@@ -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
+12
View File
@@ -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)
-11
View File
@@ -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
-213
View File
@@ -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;
}
-80
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
-112
View File
@@ -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;
}
-44
View File
@@ -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
-80
View File
@@ -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();
}
}
-56
View File
@@ -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
+103
View File
@@ -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-&gt;Plugins-&gt;ProxyPython-&gt;plugin_dir is set incorrectly or it is empty and auto-detection doesn&apos;t work for whatever reason.
Do you want to try initializing python again (at the risk of another crash)?
Suggestion: Select &quot;no&quot;, 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-&amp;gt;plugins.&lt;br&gt;If you want to use those plugins, please install the 32-bit version of Python 2.7.x from &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;.&lt;br&gt;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.&lt;br&gt;If you have multiple versions of python installed you may have to configure the path to 2.7 (32 bit) in the settings dialog.&lt;br&gt;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-&gt;Plugins-&gt;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&apos;t know why this would happen but you can try to fix it by setting python_dir in Settings-&gt;Plugins-&gt;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&apos;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. &lt;br&gt;While this is legal on NTFS drives there is a lot of software that doesn&apos;t handle it correctly.&lt;br&gt;Unfortunately MO depends on libraries that seem to fall into that group.&lt;br&gt;As a result the python plugin can&apos;t be loaded.&lt;br&gt;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>
+24
View File
@@ -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)
+5 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+355
View File
@@ -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