├── PTA ├── pitem.cpp ├── data │ ├── excludes.json │ ├── discriminators.json │ ├── armour_locals.json │ ├── weapon_locals.json │ ├── base_categories.json │ └── enchant_rules.json ├── Resources │ ├── ui.png │ ├── logo.ico │ ├── client.png │ ├── hotkey.png │ ├── macros.png │ ├── pricing.png │ ├── splash.png │ ├── settings.png │ └── logo.svg ├── search │ ├── src │ │ ├── sass │ │ │ └── variables.scss │ │ ├── assets │ │ │ └── Fontin-SmallCaps.ttf │ │ ├── plugins │ │ │ ├── bridge.js │ │ │ └── vuetify.js │ │ ├── main.js │ │ ├── bridge │ │ │ └── qtbridge.js │ │ ├── components │ │ │ ├── ModCheckbox.vue │ │ │ ├── ModNumInput.vue │ │ │ ├── PredTab.vue │ │ │ ├── BaseModFilter.vue │ │ │ ├── ModFilter.vue │ │ │ └── ResultTab.vue │ │ └── App.vue │ ├── babel.config.js │ ├── vue.config.js │ ├── .gitignore │ ├── README.md │ ├── public │ │ └── index.html │ └── package.json ├── version.h ├── pta.qrc ├── logwindow.h ├── putil.h ├── PTA.rc ├── runguard.h ├── pta.ui ├── configdialog.h ├── clientmonitor.h ├── configpages.h ├── macrohandler.h ├── main.cpp ├── webwidget.h ├── runguard.cpp ├── pta.h ├── logwindow.cpp ├── webwidget.cpp ├── pta_types.h ├── clientmonitor.cpp ├── configdialog.cpp ├── PTA.vcxproj.filters ├── putil.cpp ├── pitem.h └── macrohandler.cpp ├── QHotkey ├── QHotkey │ ├── QHotkey │ ├── qhotkey.pri │ ├── QHotkey.pro │ ├── QHotkey_resource.rc │ ├── QHotkey.vcxproj.filters │ ├── qhotkey_p.h │ ├── qhotkey.h │ └── qhotkey_x11.cpp ├── qhotkey.prc ├── QHotkey.pro ├── .gitignore ├── qhotkey.pri ├── HotkeyTest │ ├── HotkeyTest.pro │ ├── main.cpp │ ├── hottestwidget.h │ └── HotkeyTest.vcxproj.filters ├── qpm.json ├── qpmx.json └── LICENSE ├── framelesswindow ├── darkstyle │ ├── icon_close.png │ ├── icon_vline.png │ ├── icon_restore.png │ ├── icon_undock.png │ ├── icon_branch_end.png │ ├── icon_branch_more.png │ ├── icon_branch_open.png │ ├── icon_branch_closed.png │ ├── icon_checkbox_checked.png │ ├── icon_checkbox_unchecked.png │ ├── icon_radiobutton_checked.png │ ├── icon_checkbox_indeterminate.png │ ├── icon_radiobutton_unchecked.png │ ├── icon_checkbox_checked_disabled.png │ ├── icon_checkbox_checked_pressed.png │ ├── icon_checkbox_unchecked_disabled.png │ ├── icon_checkbox_unchecked_pressed.png │ ├── icon_radiobutton_checked_pressed.png │ ├── icon_checkbox_indeterminate_pressed.png │ ├── icon_radiobutton_checked_disabled.png │ ├── icon_radiobutton_unchecked_disabled.png │ ├── icon_radiobutton_unchecked_pressed.png │ └── icon_checkbox_indeterminate_disabled.png ├── images │ ├── icon_window_close.png │ ├── icon_window_maximize.png │ ├── icon_window_minimize.png │ └── icon_window_restore.png ├── framelesswindow.qrc ├── darkstyle.h ├── darkstyle.qrc ├── windowdragger.h ├── frameless_window_dark.pro ├── windowdragger.cpp ├── framelesswindow.vcxproj.filters ├── framelesswindow.h ├── darkstyle.cpp ├── README.md └── framelesswindow.vcxproj ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── build.yml ├── appveyor.yml ├── deploy └── package.ps1 ├── QtMsBuild ├── moc │ ├── qt_import.props │ └── qtmoc.props ├── rcc │ ├── qt_import.props │ └── qtrcc.props ├── uic │ ├── qt_import.props │ └── qtuic.props ├── repc │ ├── qt_import.props │ └── qtrepc.props ├── qml │ ├── qt_import.props │ └── qtqml.props ├── qt_settings.targets ├── qt_defaults.props ├── qt.targets ├── qt_settings.xml └── qt_settings_vs2015.xml ├── PTA.sln ├── README.md └── .clang-format /PTA/pitem.cpp: -------------------------------------------------------------------------------- 1 | #include "pitem.h" 2 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/QHotkey: -------------------------------------------------------------------------------- 1 | #include "qhotkey.h" 2 | -------------------------------------------------------------------------------- /PTA/data/excludes.json: -------------------------------------------------------------------------------- 1 | {"excludes":["explicit.stat_3640956958"]} 2 | -------------------------------------------------------------------------------- /PTA/Resources/ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/ui.png -------------------------------------------------------------------------------- /PTA/Resources/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/logo.ico -------------------------------------------------------------------------------- /PTA/Resources/client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/client.png -------------------------------------------------------------------------------- /PTA/Resources/hotkey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/hotkey.png -------------------------------------------------------------------------------- /PTA/Resources/macros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/macros.png -------------------------------------------------------------------------------- /PTA/Resources/pricing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/pricing.png -------------------------------------------------------------------------------- /PTA/Resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/splash.png -------------------------------------------------------------------------------- /PTA/Resources/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/Resources/settings.png -------------------------------------------------------------------------------- /QHotkey/QHotkey/qhotkey.pri: -------------------------------------------------------------------------------- 1 | message(The pri file has been moved one directory up! use that one instead) 2 | -------------------------------------------------------------------------------- /PTA/search/src/sass/variables.scss: -------------------------------------------------------------------------------- 1 | $body-font-family: "Fontin-SmallCaps", Verdana, Arial, Helvetica, sans-serif; 2 | -------------------------------------------------------------------------------- /PTA/search/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_close.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_vline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_vline.png -------------------------------------------------------------------------------- /PTA/search/src/assets/Fontin-SmallCaps.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/PTA/search/src/assets/Fontin-SmallCaps.ttf -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_restore.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_undock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_undock.png -------------------------------------------------------------------------------- /PTA/search/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "publicPath": "", 3 | "transpileDependencies": [ 4 | "vuetify" 5 | ] 6 | } -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_branch_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_branch_end.png -------------------------------------------------------------------------------- /framelesswindow/images/icon_window_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/images/icon_window_close.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_branch_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_branch_more.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_branch_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_branch_open.png -------------------------------------------------------------------------------- /framelesswindow/images/icon_window_maximize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/images/icon_window_maximize.png -------------------------------------------------------------------------------- /framelesswindow/images/icon_window_minimize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/images/icon_window_minimize.png -------------------------------------------------------------------------------- /framelesswindow/images/icon_window_restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/images/icon_window_restore.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_branch_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_branch_closed.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_checked.png -------------------------------------------------------------------------------- /PTA/version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define VER_FILEVERSION 0, 2, 0, 3 4 | #define VER_PRODUCTVERSION 0, 2, 0, 3 5 | #define VER_STRING "v0.2.0.3" 6 | -------------------------------------------------------------------------------- /QHotkey/qhotkey.prc: -------------------------------------------------------------------------------- 1 | mac: LIBS += -framework Carbon 2 | else:win32: LIBS += -luser32 3 | else:unix { 4 | QT += x11extras 5 | LIBS += -lX11 6 | } 7 | -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_unchecked.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_radiobutton_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_radiobutton_checked.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_indeterminate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_indeterminate.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_radiobutton_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_radiobutton_unchecked.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_checked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_checked_disabled.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_checked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_checked_pressed.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_unchecked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_unchecked_disabled.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_unchecked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_unchecked_pressed.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_radiobutton_checked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_radiobutton_checked_pressed.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_indeterminate_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_indeterminate_pressed.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_radiobutton_checked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_radiobutton_checked_disabled.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_radiobutton_unchecked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_radiobutton_unchecked_disabled.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_radiobutton_unchecked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_radiobutton_unchecked_pressed.png -------------------------------------------------------------------------------- /framelesswindow/darkstyle/icon_checkbox_indeterminate_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r52/PTA/HEAD/framelesswindow/darkstyle/icon_checkbox_indeterminate_disabled.png -------------------------------------------------------------------------------- /PTA/search/src/plugins/bridge.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import QtBridge from '../bridge/qtbridge' 3 | 4 | if(process.env.NODE_ENV === 'production') 5 | Vue.use(QtBridge) 6 | -------------------------------------------------------------------------------- /PTA/data/discriminators.json: -------------------------------------------------------------------------------- 1 | {"explicit.stat_665823128":{"unused":["jewel.abyss"]},"explicit.stat_1330109706":{"unused":["jewel.abyss"]},"implicit.stat_983749596":{"unused":["jewel","jewel.abyss"]}} 2 | -------------------------------------------------------------------------------- /QHotkey/QHotkey.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += \ 4 | HotkeyTest \ 5 | QHotkey 6 | 7 | DISTFILES += README.md \ 8 | LICENSE \ 9 | doc/qhotkey.doxy \ 10 | doc/qhotkey.dox 11 | -------------------------------------------------------------------------------- /PTA/data/armour_locals.json: -------------------------------------------------------------------------------- 1 | {"data":["# to maximum Energy Shield","#% increased Evasion Rating","#% increased Armour","# to Armour","# to Accuracy Rating","# to Evasion Rating", "#% increased Energy Shield"]} 2 | -------------------------------------------------------------------------------- /PTA/data/weapon_locals.json: -------------------------------------------------------------------------------- 1 | {"data":["#% increased Attack Speed","Adds # to # Physical Damage","Adds # to # Lightning Damage","# to Accuracy Rating","Adds # to # Fire Damage","Adds # to # Cold Damage","#% chance to Poison on Hit","Adds # to # Chaos Damage"]} 2 | -------------------------------------------------------------------------------- /PTA/search/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import vuetify from './plugins/vuetify'; 4 | import './plugins/bridge' 5 | 6 | Vue.config.productionTip = false 7 | 8 | new Vue({ 9 | vuetify, 10 | render: h => h(App) 11 | }).$mount('#app') 12 | -------------------------------------------------------------------------------- /framelesswindow/framelesswindow.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/icon_window_minimize.png 4 | images/icon_window_restore.png 5 | images/icon_window_maximize.png 6 | images/icon_window_close.png 7 | 8 | 9 | -------------------------------------------------------------------------------- /PTA/search/src/plugins/vuetify.js: -------------------------------------------------------------------------------- 1 | import 'typeface-roboto/index.css' 2 | import Vue from 'vue'; 3 | import Vuetify from 'vuetify/lib'; 4 | 5 | Vue.use(Vuetify); 6 | 7 | export default new Vuetify({ 8 | theme: { 9 | dark: true 10 | }, 11 | icons: { 12 | iconfont: 'mdiSvg' 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /PTA/search/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /PTA/search/src/bridge/qtbridge.js: -------------------------------------------------------------------------------- 1 | import QWebChannel from './qwebchannel' 2 | 3 | export default { 4 | install(Vue) { 5 | Vue.prototype.$api = new Promise((resolve) => { 6 | new QWebChannel(window.qt.webChannelTransport, function (channel) { 7 | const api = channel.objects.api 8 | resolve(api) 9 | }) 10 | }) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/QHotkey.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | win32: CONFIG += dll 3 | 4 | TARGET = QHotkey 5 | VERSION = 1.2.1 6 | 7 | include(../qhotkey.pri) 8 | 9 | DEFINES += QHOTKEY_LIB QHOTKEY_LIB_BUILD 10 | 11 | # use INSTALL_ROOT to modify the install location 12 | headers.files = $$PUBLIC_HEADERS 13 | headers.path = $$[QT_INSTALL_HEADERS] 14 | target.path = $$[QT_INSTALL_LIBS] 15 | INSTALLS += target headers 16 | 17 | -------------------------------------------------------------------------------- /PTA/search/README.md: -------------------------------------------------------------------------------- 1 | # search 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /QHotkey/.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | #QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | -------------------------------------------------------------------------------- /QHotkey/qhotkey.pri: -------------------------------------------------------------------------------- 1 | CONFIG += C++11 2 | 3 | PUBLIC_HEADERS += $$PWD/QHotkey/qhotkey.h \ 4 | $$PWD/QHotkey/QHotkey 5 | 6 | HEADERS += $$PUBLIC_HEADERS \ 7 | $$PWD/QHotkey/qhotkey_p.h 8 | 9 | SOURCES += $$PWD/QHotkey/qhotkey.cpp 10 | 11 | mac: SOURCES += $$PWD/QHotkey/qhotkey_mac.cpp 12 | else:win32: SOURCES += $$PWD/QHotkey/qhotkey_win.cpp 13 | else:unix: SOURCES += $$PWD/QHotkey/qhotkey_x11.cpp 14 | 15 | INCLUDEPATH += $$PWD/QHotkey 16 | 17 | include($$PWD/qhotkey.prc) 18 | -------------------------------------------------------------------------------- /PTA/pta.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/pricing.png 4 | Resources/settings.png 5 | Resources/ui.png 6 | Resources/hotkey.png 7 | Resources/logo.svg 8 | Resources/splash.png 9 | Resources/logo.ico 10 | Resources/macros.png 11 | Resources/client.png 12 | 13 | 14 | -------------------------------------------------------------------------------- /QHotkey/HotkeyTest/HotkeyTest.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-02-05T22:01:03 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = HotkeyTest 12 | TEMPLATE = app 13 | 14 | include(../qhotkey.pri) 15 | 16 | SOURCES += main.cpp\ 17 | hottestwidget.cpp 18 | 19 | HEADERS += hottestwidget.h 20 | 21 | FORMS += hottestwidget.ui 22 | -------------------------------------------------------------------------------- /QHotkey/HotkeyTest/main.cpp: -------------------------------------------------------------------------------- 1 | #include "hottestwidget.h" 2 | #include 3 | 4 | //#define START_BACKGROUND 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | QApplication a(argc, argv); 9 | HotTestWidget w; 10 | 11 | #ifdef START_BACKGROUND 12 | auto startKey = new QHotkey(QKeySequence(Qt::MetaModifier | Qt::ControlModifier | Qt::Key_S), true, &w); 13 | QObject::connect(startKey, &QHotkey::activated, 14 | &w, &QWidget::show); 15 | #else 16 | w.show(); 17 | #endif 18 | 19 | return a.exec(); 20 | } 21 | -------------------------------------------------------------------------------- /PTA/logwindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | QT_FORWARD_DECLARE_CLASS(QPlainTextEdit) 6 | 7 | class LogWindow : public QObject 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | ~LogWindow(); 13 | explicit LogWindow(QObject* parent = nullptr); 14 | 15 | QPlainTextEdit* release(); 16 | 17 | private: 18 | bool m_released = false; 19 | 20 | LogWindow(const LogWindow&) = delete; 21 | LogWindow(LogWindow&&) = delete; 22 | LogWindow& operator=(const LogWindow&) = delete; 23 | LogWindow& operator=(LogWindow&&) = delete; 24 | }; 25 | -------------------------------------------------------------------------------- /PTA/putil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace pta 8 | { 9 | bool IsPoEForeground(); 10 | INPUT CreateInput(WORD vk, bool isDown); 11 | 12 | namespace hook 13 | { 14 | void InitializeHooks(); 15 | void ShutdownHooks(); 16 | void InstallForegroundHookCb(std::function fgcb); 17 | void InstallMouseHookCb(std::function cb); 18 | void InstallKeyboardHookCb(std::function cb); 19 | } 20 | } -------------------------------------------------------------------------------- /PTA/PTA.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "Resources/logo.ico" 2 | 3 | #include 4 | #include "version.h" 5 | 6 | VS_VERSION_INFO VERSIONINFO 7 | FILEVERSION VER_FILEVERSION 8 | PRODUCTVERSION VER_PRODUCTVERSION 9 | BEGIN 10 | BLOCK "StringFileInfo" 11 | BEGIN 12 | BLOCK "040904E4" 13 | BEGIN 14 | VALUE "FileDescription", "PTA" 15 | VALUE "FileVersion", VER_STRING 16 | VALUE "OriginalFilename", "PTA.exe" 17 | VALUE "ProductName", "PTA" 18 | VALUE "ProductVersion", VER_STRING 19 | END 20 | END 21 | 22 | BLOCK "VarFileInfo" 23 | BEGIN 24 | VALUE "Translation", 0x409, 1200 25 | END 26 | END 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report about a PTA bug or error 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Is it consistently reproducible?** 14 | Yes/No 15 | 16 | **Item that caused the bug or error (if applicable)** 17 | Include the item code that caused the bug or error if applicable. 18 | 19 | **Log data** 20 | If applicable, include any log data that may help describe the internal issue. 21 | 22 | **Additional context** 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /PTA/search/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /PTA/runguard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // From https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class RunGuard 10 | { 11 | public: 12 | RunGuard(const QString& key); 13 | ~RunGuard(); 14 | 15 | bool isAnotherRunning(); 16 | bool tryToRun(); 17 | void release(); 18 | 19 | private: 20 | const QString key; 21 | const QString memLockKey; 22 | const QString sharedmemKey; 23 | 24 | QSharedMemory sharedMem; 25 | QSystemSemaphore memLock; 26 | 27 | Q_DISABLE_COPY(RunGuard) 28 | }; 29 | -------------------------------------------------------------------------------- /QHotkey/qpm.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "email": "skycoder42.de@gmx.de", 4 | "name": "Skycoder" 5 | }, 6 | "dependencies": [ 7 | ], 8 | "description": "A global shortcut/hotkey for Desktop Qt-Applications", 9 | "license": "BSD_3_CLAUSE", 10 | "name": "de.skycoder42.qhotkey", 11 | "pri_filename": "qhotkey.pri", 12 | "repository": { 13 | "type": "GITHUB", 14 | "url": "https://github.com/Skycoder42/QHotkey.git" 15 | }, 16 | "version": { 17 | "fingerprint": "", 18 | "label": "1.2.2", 19 | "revision": "" 20 | }, 21 | "webpage": "https://github.com/Skycoder42/QHotkey" 22 | } 23 | -------------------------------------------------------------------------------- /PTA/pta.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | PTAClass 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 400 11 | 12 | 13 | 14 | PTA 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /PTA/configdialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | QT_FORWARD_DECLARE_CLASS(QListWidget) 8 | QT_FORWARD_DECLARE_CLASS(QListWidgetItem) 9 | QT_FORWARD_DECLARE_CLASS(QStackedWidget) 10 | 11 | class ItemAPI; 12 | 13 | using json = nlohmann::json; 14 | 15 | class ConfigDialog : public QDialog 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit ConfigDialog(ItemAPI* api); 21 | 22 | public slots: 23 | void changePage(QListWidgetItem* current, QListWidgetItem* previous); 24 | 25 | public: 26 | json results; 27 | 28 | private: 29 | void createIcons(); 30 | 31 | QListWidget* contentsWidget; 32 | QStackedWidget* pagesWidget; 33 | }; -------------------------------------------------------------------------------- /PTA/search/src/components/ModCheckbox.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 36 | -------------------------------------------------------------------------------- /QHotkey/qpmx.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | ], 4 | "license": { 5 | "file": "LICENSE", 6 | "name": "BSD_3_CLAUSE" 7 | }, 8 | "prcFile": "qhotkey.prc", 9 | "priFile": "qhotkey.pri", 10 | "priIncludes": [ 11 | ], 12 | "publishers": { 13 | "qpm": { 14 | "author": { 15 | "email": "skycoder42.de@gmx.de", 16 | "name": "Skycoder" 17 | }, 18 | "description": "A global shortcut/hotkey for Desktop Qt-Applications", 19 | "name": "de.skycoder42.qhotkey", 20 | "repository": { 21 | "type": "GITHUB", 22 | "url": "https://github.com/Skycoder42/QHotkey.git" 23 | }, 24 | "webpage": "https://github.com/Skycoder42/QHotkey" 25 | } 26 | }, 27 | "source": false 28 | } 29 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/QHotkey_resource.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VS_VERSION_INFO VERSIONINFO 4 | FILEVERSION 1,2,1,0 5 | PRODUCTVERSION 1,2,1,0 6 | FILEFLAGSMASK 0x3fL 7 | #ifdef _DEBUG 8 | FILEFLAGS VS_FF_DEBUG 9 | #else 10 | FILEFLAGS 0x0L 11 | #endif 12 | FILEOS VOS__WINDOWS32 13 | FILETYPE VFT_DLL 14 | FILESUBTYPE 0x0L 15 | BEGIN 16 | BLOCK "StringFileInfo" 17 | BEGIN 18 | BLOCK "040904b0" 19 | BEGIN 20 | VALUE "CompanyName", "\0" 21 | VALUE "FileDescription", "\0" 22 | VALUE "FileVersion", "1.2.1.0\0" 23 | VALUE "LegalCopyright", "\0" 24 | VALUE "OriginalFilename", "QHotkey1.dll\0" 25 | VALUE "ProductName", "QHotkey\0" 26 | VALUE "ProductVersion", "1.2.1.0\0" 27 | END 28 | END 29 | BLOCK "VarFileInfo" 30 | BEGIN 31 | VALUE "Translation", 0x0409, 1200 32 | END 33 | END 34 | /* End of Version info */ 35 | 36 | -------------------------------------------------------------------------------- /PTA/data/base_categories.json: -------------------------------------------------------------------------------- 1 | {"Bow":"weapon.bow","Claw":"weapon.claw","Dagger":"weapon.dagger","One Hand Axe":"weapon.oneaxe","One Hand Mace":"weapon.onemace","One Hand Sword":"weapon.onesword","Thrusting One Hand Sword":"weapon.onesword","Sceptre":"weapon.sceptre","Staff":"weapon.staff","Two Hand Axe":"weapon.twoaxe","Two Hand Mace":"weapon.twomace","Two Hand Sword":"weapon.twosword","Wand":"weapon.wand","Body Armour":"armour.chest","Boots":"armour.boots","Gloves":"armour.gloves","Helmet":"armour.helmet","Shield":"armour.shield","Belt":"accessory.belt","Amulet":"accessory.amulet","StackableCurrency":"currency","HybridFlask":"flask","LifeFlask":"flask","ManaFlask":"flask","UtilityFlaskCritical":"flask","UtilityFlask":"flask","Active Skill Gem":"gem.activegem","Support Skill Gem":"gem.supportgem","AbyssJewel":"jewel.abyss","Jewel":"jewel","Quiver":"armour.quiver","Ring":"accessory.ring"} 2 | -------------------------------------------------------------------------------- /PTA/search/src/components/ModNumInput.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 39 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{branch}-{build}' 2 | image: Visual Studio 2019 3 | configuration: Release 4 | platform: x64 5 | init: 6 | - ps: >- 7 | if ($env:APPVEYOR_REPO_TAG -eq "true") 8 | { 9 | Update-AppveyorBuild -Version "$env:APPVEYOR_REPO_TAG_NAME-$env:APPVEYOR_BUILD_NUMBER" 10 | } 11 | else 12 | { 13 | Update-AppveyorBuild -Version "$($env:APPVEYOR_REPO_COMMIT.Substring(0, 7))-$env:APPVEYOR_BUILD_NUMBER" 14 | } 15 | environment: 16 | QTDIR: C:\Qt\5.12.6\msvc2017_64 17 | OPENSSL: C:\OpenSSL-v111-Win64\bin 18 | nodejs_version: "LTS" 19 | install: 20 | - ps: Install-Product node $env:nodejs_version 21 | - cmd: cd "C:\projects\pta\PTA\search\" && npm ci 22 | build_script: 23 | - cmd: msbuild "C:\projects\pta\PTA.sln" /m /verbosity:normal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:QtInstall=%QTDIR% 24 | - cmd: cd "C:\projects\pta\PTA\search\" && npm run build 25 | after_build: 26 | - ps: .\deploy\package.ps1 27 | -------------------------------------------------------------------------------- /PTA/clientmonitor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | class QTimer; 8 | 9 | class ClientMonitor : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | ClientMonitor(QObject* parent = nullptr); 15 | ~ClientMonitor(); 16 | 17 | void setPath(QString logpath); 18 | 19 | bool enabled(); 20 | 21 | QString getLastWhisperer(); 22 | 23 | private slots: 24 | void processLogChange(); 25 | void processLogLine(QString line); 26 | 27 | private: 28 | static const std::chrono::milliseconds polling_rate; 29 | 30 | // We are FORCED to use a polling technique for Client.txt because it doesn't flush AT ALL 31 | // unless the file is accessed externally. This renders functions like QFileSystemWatcher and 32 | // even the WinAPI ReadDirectoryChangesW UNUSABLE for our purposes :(. 33 | std::unique_ptr m_watcher; 34 | 35 | QString m_logpath; 36 | 37 | bool m_enabled; 38 | qint64 m_lastpos = -1; 39 | 40 | QString m_last_whisper; 41 | }; -------------------------------------------------------------------------------- /PTA/configpages.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | class ItemAPI; 9 | 10 | using json = nlohmann::json; 11 | 12 | class GeneralPage : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | GeneralPage(json& set, QWidget* parent = 0); 18 | }; 19 | 20 | /* 21 | class UIPage : public QWidget 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | UIPage(json& set, QWidget* parent = 0); 27 | }; 28 | */ 29 | 30 | class HotkeyPage : public QWidget 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | HotkeyPage(json& set, QWidget* parent = 0); 36 | }; 37 | 38 | class PriceCheckPage : public QWidget 39 | { 40 | Q_OBJECT 41 | 42 | public: 43 | PriceCheckPage(json& set, ItemAPI* api, QWidget* parent = 0); 44 | }; 45 | 46 | class MacrosPage : public QWidget 47 | { 48 | Q_OBJECT 49 | 50 | public: 51 | MacrosPage(json& set, QWidget* parent = 0); 52 | }; 53 | 54 | class ClientPage : public QWidget 55 | { 56 | Q_OBJECT 57 | 58 | public: 59 | ClientPage(json& set, QWidget* parent = 0); 60 | }; 61 | -------------------------------------------------------------------------------- /PTA/macrohandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | using json = nlohmann::json; 11 | 12 | class ClientMonitor; 13 | 14 | class MacroHandler : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | MacroHandler(ClientMonitor* client, QObject* parent = nullptr); 20 | 21 | void setMacros(json macrolist); 22 | void clearMacros(); 23 | 24 | signals: 25 | void humour(const QString& msg); 26 | 27 | public slots: 28 | void handleForegroundChange(bool isPoe); 29 | 30 | private: 31 | void insertKeyPress(std::vector& keystrokes, WORD key); 32 | void insertChatCommand(std::vector& keystrokes, std::string command); 33 | bool processChatCommand(std::string& command); 34 | void sendChatCommand(std::string command); 35 | 36 | private slots: 37 | void handleMacro(QString key); 38 | 39 | private: 40 | QMap> m_variables; 41 | 42 | ClientMonitor* m_client; 43 | 44 | json m_macrolist; 45 | std::vector> m_macros; 46 | }; -------------------------------------------------------------------------------- /PTA/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pta.h" 2 | 3 | #include "logwindow.h" 4 | #include "runguard.h" 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | int main(int argc, char* argv[]) 15 | { 16 | RunGuard guard("pta_app_key"); 17 | if (!guard.tryToRun()) 18 | return 0; 19 | 20 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 21 | QCoreApplication::setApplicationName("PTA"); 22 | QCoreApplication::setOrganizationName("PTA"); 23 | QSettings::setDefaultFormat(QSettings::IniFormat); 24 | 25 | QApplication a(argc, argv); 26 | a.setStyle(new DarkStyle); 27 | a.setQuitOnLastWindowClosed(false); 28 | 29 | LogWindow* log = new LogWindow(); 30 | 31 | QPixmap pixmap(":/Resources/splash.png"); 32 | QSplashScreen splash(pixmap); 33 | auto align = Qt::AlignHCenter | Qt::AlignBottom; 34 | auto color = Qt::white; 35 | splash.show(); 36 | 37 | splash.showMessage("Downloading API data...", align, color); 38 | a.processEvents(); 39 | 40 | PTA w(log); 41 | 42 | w.hide(); 43 | 44 | splash.finish(&w); 45 | 46 | return a.exec(); 47 | } 48 | -------------------------------------------------------------------------------- /PTA/search/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "search", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^3.6.4", 12 | "vue": "^2.6.11", 13 | "vuetify": "^2.2.17" 14 | }, 15 | "devDependencies": { 16 | "@mdi/js": "^4.9.95", 17 | "@vue/cli-plugin-babel": "^4.2.3", 18 | "@vue/cli-plugin-eslint": "^4.2.3", 19 | "@vue/cli-service": "^4.2.3", 20 | "babel-eslint": "^10.1.0", 21 | "eslint": "^6.7.2", 22 | "eslint-plugin-vue": "^6.2.2", 23 | "sass": "^1.26.3", 24 | "sass-loader": "^8.0.0", 25 | "typeface-roboto": "0.0.75", 26 | "vue-cli-plugin-vuetify": "~2.0.5", 27 | "vue-template-compiler": "^2.6.11", 28 | "vuetify-loader": "^1.3.0" 29 | }, 30 | "eslintConfig": { 31 | "root": true, 32 | "env": { 33 | "node": true 34 | }, 35 | "extends": [ 36 | "plugin:vue/essential", 37 | "eslint:recommended" 38 | ], 39 | "parserOptions": { 40 | "parser": "babel-eslint" 41 | }, 42 | "rules": {} 43 | }, 44 | "browserslist": [ 45 | "last 2 Firefox versions", 46 | "last 4 Chrome versions" 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /deploy/package.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [switch]$debug = $false 3 | ) 4 | 5 | $qtpath = $env:QTDIR 6 | 7 | $rel = "Release" 8 | $rels = "--release" 9 | 10 | if ($debug) 11 | { 12 | $rel = "Debug" 13 | $rels = "--debug" 14 | } 15 | 16 | if ($null -eq $qtpath) 17 | { 18 | $qtpath = "C:\Qt\5.12.6\msvc2017_64" 19 | } 20 | 21 | $windeploy = "$($qtpath)\bin\windeployqt.exe" 22 | 23 | # Copy files 24 | $pkpath = "PTA_x64" 25 | $binpath = "$($pkpath)\PTA.exe" 26 | $dllpath = "$($pkpath)\QHotkey.dll" 27 | 28 | New-Item $pkpath -Type Directory -Force > $null 29 | Copy-Item ("x64\" + $rel + "\PTA.exe") -Destination $binpath -Force 30 | Copy-Item ("x64\" + $rel + "\QHotkey.dll") -Destination $dllpath -Force 31 | 32 | # Copy templates 33 | Copy-Item .\PTA\search\dist\ -Destination ($pkpath + "\search\dist\") -Recurse -Force 34 | 35 | # Copy SSL lib 36 | if (($env:OPENSSL) -and (Test-Path $env:OPENSSL -pathType container)) { 37 | Copy-Item $env:OPENSSL\libcrypto-1_1-x64.dll -Destination $pkpath -Force 38 | Copy-Item $env:OPENSSL\libssl-1_1-x64.dll -Destination $pkpath -Force 39 | } 40 | 41 | # Deploy Qt 42 | & $windeploy $rels $binpath 43 | 44 | $pkgname = "$($pkpath).7z" 45 | Write-Host "Packaging $($pkgname)..." 46 | 47 | & 7z a -t7z $pkgname .\$pkpath 48 | 49 | if ($env:APPVEYOR -eq $true) { 50 | Get-ChildItem $pkgname | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } 51 | } 52 | -------------------------------------------------------------------------------- /framelesswindow/darkstyle.h: -------------------------------------------------------------------------------- 1 | /* 2 | ############################################################################### 3 | # # 4 | # The MIT License # 5 | # # 6 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 7 | # >> https://github.com/Jorgen-VikingGod # 8 | # # 9 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 10 | # # 11 | ############################################################################### 12 | */ 13 | 14 | #ifndef DARKSTYLE_HPP 15 | #define DARKSTYLE_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | class DarkStyle : public QProxyStyle 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | DarkStyle(); 29 | explicit DarkStyle(QStyle* style); 30 | 31 | QStyle* baseStyle() const; 32 | 33 | void polish(QPalette& palette) override; 34 | void polish(QApplication* app) override; 35 | 36 | private: 37 | QStyle* styleBase(QStyle* style = Q_NULLPTR) const; 38 | }; 39 | 40 | #endif // DARKSTYLE_HPP 41 | -------------------------------------------------------------------------------- /PTA/webwidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pitem.h" 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | QT_FORWARD_DECLARE_CLASS(ItemAPI); 13 | 14 | class PWebView : public QWebEngineView 15 | { 16 | public: 17 | PWebView(QWidget* parent = nullptr) : QWebEngineView{parent} { setContextMenuPolicy(Qt::NoContextMenu); } 18 | }; 19 | 20 | class PWebPage : public QWebEnginePage 21 | { 22 | public: 23 | PWebPage(QObject* parent = nullptr) : QWebEnginePage{parent} {} 24 | PWebPage(QWebEngineProfile* profile, QObject* parent = nullptr) : QWebEnginePage{profile, parent} {} 25 | 26 | protected: 27 | virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override; 28 | }; 29 | 30 | class WebWidget : public FramelessWindow 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | explicit WebWidget(ItemAPI* api, const QString& data, QWidget* parent = nullptr); 36 | ~WebWidget(); 37 | 38 | void saveSettings(); 39 | 40 | static QString generateDataScript(const QString& data); 41 | 42 | private: 43 | QString getSettingKey(QString key); 44 | 45 | // Web engine widget 46 | PWebView* webview; 47 | 48 | // Page script 49 | QWebEngineScript script; 50 | 51 | Q_DISABLE_COPY(WebWidget); 52 | }; 53 | -------------------------------------------------------------------------------- /QHotkey/HotkeyTest/hottestwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef HOTTESTWIDGET_H 2 | #define HOTTESTWIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Ui { 9 | class HotTestWidget; 10 | } 11 | 12 | class HotTestWidget : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit HotTestWidget(QWidget *parent = 0); 18 | ~HotTestWidget(); 19 | 20 | private slots: 21 | void setShortcut_1(const QKeySequence &sequence); 22 | void setShortcut_2(const QKeySequence &sequence); 23 | void setShortcut_3(const QKeySequence &sequence); 24 | void setShortcut_4(const QKeySequence &sequence); 25 | void setShortcut_5(const QKeySequence &sequence); 26 | 27 | void increase_1(); 28 | void increase_2(); 29 | void increase_3(); 30 | void increase_4(); 31 | void increase_5(); 32 | 33 | void on_resetButton_1_clicked(); 34 | void on_resetButton_2_clicked(); 35 | void on_resetButton_3_clicked(); 36 | void on_resetButton_4_clicked(); 37 | void on_resetButton_5_clicked(); 38 | 39 | void on_groupBox_toggled(bool checked); 40 | void on_threadEnableCheckBox_clicked(); 41 | 42 | void on_registeredCheckBox_toggled(bool checked); 43 | void increase_native(); 44 | 45 | private: 46 | Ui::HotTestWidget *ui; 47 | 48 | QHotkey *hotkey_1; 49 | QHotkey *hotkey_2; 50 | QHotkey *hotkey_3; 51 | QHotkey *hotkey_4; 52 | QHotkey *hotkey_5; 53 | 54 | QThread *thread4; 55 | QThread *thread5; 56 | 57 | QList testHotkeys; 58 | 59 | QHotkey *nativeHotkey; 60 | }; 61 | 62 | #endif // HOTTESTWIDGET_H 63 | -------------------------------------------------------------------------------- /PTA/search/src/components/PredTab.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 53 | 54 | 59 | -------------------------------------------------------------------------------- /QHotkey/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Felix Barz 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of QHotkey nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /framelesswindow/darkstyle.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | darkstyle/darkstyle.qss 4 | darkstyle/icon_close.png 5 | darkstyle/icon_restore.png 6 | darkstyle/icon_undock.png 7 | darkstyle/icon_branch_closed.png 8 | darkstyle/icon_branch_end.png 9 | darkstyle/icon_branch_more.png 10 | darkstyle/icon_branch_open.png 11 | darkstyle/icon_vline.png 12 | darkstyle/icon_checkbox_checked.png 13 | darkstyle/icon_checkbox_indeterminate.png 14 | darkstyle/icon_checkbox_unchecked.png 15 | darkstyle/icon_checkbox_checked_pressed.png 16 | darkstyle/icon_checkbox_indeterminate_pressed.png 17 | darkstyle/icon_checkbox_unchecked_pressed.png 18 | darkstyle/icon_checkbox_checked_disabled.png 19 | darkstyle/icon_checkbox_indeterminate_disabled.png 20 | darkstyle/icon_checkbox_unchecked_disabled.png 21 | darkstyle/icon_radiobutton_checked.png 22 | darkstyle/icon_radiobutton_unchecked.png 23 | darkstyle/icon_radiobutton_checked_pressed.png 24 | darkstyle/icon_radiobutton_unchecked_pressed.png 25 | darkstyle/icon_radiobutton_checked_disabled.png 26 | darkstyle/icon_radiobutton_unchecked_disabled.png 27 | 28 | 29 | -------------------------------------------------------------------------------- /framelesswindow/windowdragger.h: -------------------------------------------------------------------------------- 1 | /* 2 | ############################################################################### 3 | # # 4 | # The MIT License # 5 | # # 6 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 7 | # >> https://github.com/Jorgen-VikingGod # 8 | # # 9 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 10 | # # 11 | ############################################################################### 12 | */ 13 | 14 | #ifndef WINDOWDRAGGER_H 15 | #define WINDOWDRAGGER_H 16 | 17 | #include 18 | #include 19 | 20 | class WindowDragger : public QWidget 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit WindowDragger(QWidget* parent = Q_NULLPTR); 26 | virtual ~WindowDragger() {} 27 | 28 | signals: 29 | void doubleClicked(); 30 | 31 | protected: 32 | void mousePressEvent(QMouseEvent* event); 33 | void mouseMoveEvent(QMouseEvent* event); 34 | void mouseReleaseEvent(QMouseEvent* event); 35 | void mouseDoubleClickEvent(QMouseEvent* event); 36 | void paintEvent(QPaintEvent* event); 37 | 38 | protected: 39 | QPoint mousePos; 40 | QPoint wndPos; 41 | bool mousePressed; 42 | }; 43 | 44 | #endif // WINDOWDRAGGER_H 45 | -------------------------------------------------------------------------------- /framelesswindow/frameless_window_dark.pro: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # # 3 | # The MIT License # 4 | # # 5 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 6 | # >> https://github.com/Jorgen-VikingGod # 7 | # # 8 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 9 | # # 10 | ############################################################################### 11 | 12 | QT += core gui 13 | 14 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 15 | 16 | INCLUDEPATH +="framelesswindow" 17 | 18 | TARGET = QtFramelessWindowDarkStyle 19 | TEMPLATE = app 20 | 21 | SOURCES += main.cpp\ 22 | mainwindow.cpp \ 23 | framelesswindow/framelesswindow.cpp \ 24 | framelesswindow/windowdragger.cpp \ 25 | DarkStyle.cpp 26 | 27 | 28 | HEADERS += mainwindow.h \ 29 | framelesswindow/framelesswindow.h \ 30 | framelesswindow/windowdragger.h \ 31 | DarkStyle.h 32 | 33 | 34 | FORMS += mainwindow.ui \ 35 | framelesswindow/framelesswindow.ui 36 | 37 | RESOURCES += darkstyle.qrc \ 38 | framelesswindow.qrc 39 | -------------------------------------------------------------------------------- /PTA/search/src/components/BaseModFilter.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 62 | 63 | 68 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/QHotkey.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 6 | h;hpp;hxx;hm;inl;inc;xsd 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 14 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 15 | 16 | 17 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 18 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /PTA/runguard.cpp: -------------------------------------------------------------------------------- 1 | // From https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection 2 | 3 | #include "runguard.h" 4 | 5 | #include 6 | 7 | namespace 8 | { 9 | QString generateKeyHash(const QString& key, const QString& salt) 10 | { 11 | QByteArray data; 12 | 13 | data.append(key.toUtf8()); 14 | data.append(salt.toUtf8()); 15 | data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex(); 16 | 17 | return data; 18 | } 19 | } 20 | 21 | RunGuard::RunGuard(const QString& key) 22 | : key(key) 23 | , memLockKey(generateKeyHash(key, "_memLockKey")) 24 | , sharedmemKey(generateKeyHash(key, "_sharedmemKey")) 25 | , sharedMem(sharedmemKey) 26 | , memLock(memLockKey, 1) 27 | { 28 | memLock.acquire(); 29 | { 30 | QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/ 31 | fix.attach(); 32 | } 33 | memLock.release(); 34 | } 35 | 36 | RunGuard::~RunGuard() 37 | { 38 | release(); 39 | } 40 | 41 | bool RunGuard::isAnotherRunning() 42 | { 43 | if (sharedMem.isAttached()) 44 | return false; 45 | 46 | memLock.acquire(); 47 | const bool isRunning = sharedMem.attach(); 48 | if (isRunning) 49 | sharedMem.detach(); 50 | memLock.release(); 51 | 52 | return isRunning; 53 | } 54 | 55 | bool RunGuard::tryToRun() 56 | { 57 | if (isAnotherRunning()) // Extra check 58 | return false; 59 | 60 | memLock.acquire(); 61 | const bool result = sharedMem.create(sizeof(quint64)); 62 | memLock.release(); 63 | if (!result) 64 | { 65 | release(); 66 | return false; 67 | } 68 | 69 | return true; 70 | } 71 | 72 | void RunGuard::release() 73 | { 74 | memLock.acquire(); 75 | if (sharedMem.isAttached()) 76 | sharedMem.detach(); 77 | memLock.release(); 78 | } 79 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/qhotkey_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QHOTKEY_P_H 2 | #define QHOTKEY_P_H 3 | 4 | #include "qhotkey.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNativeEventFilter 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | QHotkeyPrivate();//singleton!!! 16 | ~QHotkeyPrivate(); 17 | 18 | static QHotkeyPrivate *instance(); 19 | 20 | QHotkey::NativeShortcut nativeShortcut(Qt::Key keycode, Qt::KeyboardModifiers modifiers); 21 | 22 | bool addShortcut(QHotkey *hotkey); 23 | bool removeShortcut(QHotkey *hotkey); 24 | 25 | protected: 26 | void activateShortcut(QHotkey::NativeShortcut shortcut); 27 | 28 | virtual quint32 nativeKeycode(Qt::Key keycode, bool &ok) = 0;//platform implement 29 | virtual quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) = 0;//platform implement 30 | 31 | virtual bool registerShortcut(QHotkey::NativeShortcut shortcut) = 0;//platform implement 32 | virtual bool unregisterShortcut(QHotkey::NativeShortcut shortcut) = 0;//platform implement 33 | 34 | private: 35 | QHash, QHotkey::NativeShortcut> mapping; 36 | QMultiHash shortcuts; 37 | 38 | Q_INVOKABLE void addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, const QHotkey::NativeShortcut &nativeShortcut); 39 | Q_INVOKABLE bool addShortcutInvoked(QHotkey *hotkey); 40 | Q_INVOKABLE bool removeShortcutInvoked(QHotkey *hotkey); 41 | Q_INVOKABLE QHotkey::NativeShortcut nativeShortcutInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers); 42 | }; 43 | 44 | #define NATIVE_INSTANCE(ClassName) \ 45 | Q_GLOBAL_STATIC(ClassName, hotkeyPrivate) \ 46 | \ 47 | QHotkeyPrivate *QHotkeyPrivate::instance()\ 48 | {\ 49 | return hotkeyPrivate;\ 50 | } 51 | 52 | Q_DECLARE_METATYPE(Qt::Key) 53 | Q_DECLARE_METATYPE(Qt::KeyboardModifiers) 54 | 55 | #endif // QHOTKEY_P_H 56 | -------------------------------------------------------------------------------- /QtMsBuild/moc/qt_import.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 38 | $(QtMsBuildProps); 39 | $(MSBuildThisFileDirectory)qtmoc.props 40 | 41 | 42 | $(QtMsBuildTargets); 43 | $(MSBuildThisFileDirectory)qtmoc.targets 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /QtMsBuild/rcc/qt_import.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 38 | $(QtMsBuildProps); 39 | $(MSBuildThisFileDirectory)qtrcc.props 40 | 41 | 42 | $(QtMsBuildTargets); 43 | $(MSBuildThisFileDirectory)qtrcc.targets 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /QtMsBuild/uic/qt_import.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 38 | $(QtMsBuildProps); 39 | $(MSBuildThisFileDirectory)qtuic.props 40 | 41 | 42 | $(QtMsBuildTargets); 43 | $(MSBuildThisFileDirectory)qtuic.targets 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /QtMsBuild/repc/qt_import.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 38 | $(QtMsBuildProps); 39 | $(MSBuildThisFileDirectory)qtrepc.props 40 | 41 | 42 | $(QtMsBuildTargets); 43 | $(MSBuildThisFileDirectory)qtrepc.targets 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /QtMsBuild/qml/qt_import.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 38 | $(QtMsBuildProps_AfterRcc); 39 | $(MSBuildThisFileDirectory)qtqml.props 40 | 41 | 42 | $(QtMsBuildTargets_AfterRcc); 43 | $(MSBuildThisFileDirectory)qtqml.targets 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /PTA.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28922.388 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTA", "PTA\PTA.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QHotkey", "QHotkey\QHotkey\QHotkey.vcxproj", "{08D030C4-E638-3BC8-BCC8-1D156146FF5A}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "framelesswindow", "framelesswindow\framelesswindow.vcxproj", "{2209748B-F881-499B-A1F5-C916D3CD7352}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|x64 = Debug|x64 15 | Release|x64 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64 19 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64 20 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64 21 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64 22 | {08D030C4-E638-3BC8-BCC8-1D156146FF5A}.Debug|x64.ActiveCfg = Debug|x64 23 | {08D030C4-E638-3BC8-BCC8-1D156146FF5A}.Debug|x64.Build.0 = Debug|x64 24 | {08D030C4-E638-3BC8-BCC8-1D156146FF5A}.Release|x64.ActiveCfg = Release|x64 25 | {08D030C4-E638-3BC8-BCC8-1D156146FF5A}.Release|x64.Build.0 = Release|x64 26 | {2209748B-F881-499B-A1F5-C916D3CD7352}.Debug|x64.ActiveCfg = Debug|x64 27 | {2209748B-F881-499B-A1F5-C916D3CD7352}.Debug|x64.Build.0 = Debug|x64 28 | {2209748B-F881-499B-A1F5-C916D3CD7352}.Release|x64.ActiveCfg = Release|x64 29 | {2209748B-F881-499B-A1F5-C916D3CD7352}.Release|x64.Build.0 = Release|x64 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {C26DA8C0-0CBC-431A-952B-BC9B98173F7B} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /framelesswindow/windowdragger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ############################################################################### 3 | # # 4 | # The MIT License # 5 | # # 6 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 7 | # >> https://github.com/Jorgen-VikingGod # 8 | # # 9 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 10 | # # 11 | ############################################################################### 12 | */ 13 | 14 | #include "windowdragger.h" 15 | #include 16 | #include 17 | 18 | WindowDragger::WindowDragger(QWidget* parent) : QWidget(parent) 19 | { 20 | mousePressed = false; 21 | } 22 | 23 | void WindowDragger::mousePressEvent(QMouseEvent* event) 24 | { 25 | mousePressed = true; 26 | mousePos = event->globalPos(); 27 | 28 | QWidget* parent = parentWidget(); 29 | if (parent) 30 | parent = parent->parentWidget(); 31 | 32 | if (parent) 33 | wndPos = parent->pos(); 34 | } 35 | 36 | void WindowDragger::mouseMoveEvent(QMouseEvent* event) 37 | { 38 | QWidget* parent = parentWidget(); 39 | if (parent) 40 | parent = parent->parentWidget(); 41 | 42 | if (parent && mousePressed) 43 | parent->move(wndPos + (event->globalPos() - mousePos)); 44 | } 45 | 46 | void WindowDragger::mouseReleaseEvent(QMouseEvent* event) 47 | { 48 | Q_UNUSED(event); 49 | mousePressed = false; 50 | } 51 | 52 | void WindowDragger::paintEvent(QPaintEvent* event) 53 | { 54 | Q_UNUSED(event); 55 | QStyleOption styleOption; 56 | styleOption.init(this); 57 | QPainter painter(this); 58 | style()->drawPrimitive(QStyle::PE_Widget, &styleOption, &painter, this); 59 | } 60 | 61 | void WindowDragger::mouseDoubleClickEvent(QMouseEvent* event) 62 | { 63 | Q_UNUSED(event); 64 | emit doubleClicked(); 65 | } 66 | -------------------------------------------------------------------------------- /framelesswindow/framelesswindow.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 14 | qrc;* 15 | false 16 | 17 | 18 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 19 | qrc;* 20 | false 21 | 22 | 23 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 24 | ui 25 | true 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | 40 | 41 | Header Files 42 | 43 | 44 | Header Files 45 | 46 | 47 | Header Files 48 | 49 | 50 | 51 | 52 | Resource Files 53 | 54 | 55 | Resource Files 56 | 57 | 58 | 59 | 60 | Form Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Windows Build 2 | 3 | on: 4 | push: 5 | pull_request: 6 | release: 7 | types: [published, prereleased] 8 | 9 | env: 10 | PACKAGE_NAME: PTA_x64 11 | OPENSSL: 'C:\Program Files\OpenSSL\bin' 12 | 13 | jobs: 14 | build: 15 | runs-on: windows-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: Install Qt 21 | uses: jurplel/install-qt-action@v2 22 | with: 23 | version: 5.12.7 24 | modules: qtwebengine 25 | 26 | - name: Add msbuild to PATH 27 | uses: microsoft/setup-msbuild@v1 28 | 29 | - name: Build PTA 30 | shell: cmd 31 | run: msbuild PTA.sln /m /verbosity:normal /p:configuration=Release /p:QtInstall=%Qt5_Dir% 32 | 33 | - name: Clean install and build UI 34 | working-directory: ./PTA/search 35 | run: | 36 | npm ci 37 | npm run build 38 | 39 | - name: Package archive 40 | shell: pwsh 41 | run: | 42 | $pkpath = ${env:PACKAGE_NAME} 43 | $binpath = "$($pkpath)\PTA.exe" 44 | $dllpath = "$($pkpath)\QHotkey.dll" 45 | New-Item $pkpath -Type Directory -Force > $null 46 | Copy-Item ("x64\Release\PTA.exe") -Destination $binpath -Force 47 | Copy-Item ("x64\Release\QHotkey.dll") -Destination $dllpath -Force 48 | Copy-Item .\PTA\search\dist\ -Destination ($pkpath + "\search\dist\") -Recurse -Force 49 | if (($env:OPENSSL) -and (Test-Path $env:OPENSSL -pathType container)) { 50 | Copy-Item ${env:OPENSSL}\libcrypto-1_1-x64.dll -Destination $pkpath -Force 51 | Copy-Item ${env:OPENSSL}\libssl-1_1-x64.dll -Destination $pkpath -Force 52 | } 53 | & windeployqt.exe --release $binpath 54 | $pkgname = "$($pkpath).7z" 55 | & 7z a -t7z $pkgname .\$pkpath 56 | 57 | - name: Upload artifact 58 | uses: actions/upload-artifact@v1 59 | with: 60 | name: ${{ env.PACKAGE_NAME }} 61 | path: ${{ env.PACKAGE_NAME }} 62 | 63 | - name: Upload release 64 | if: github.event.action == 'published' || github.event.action == 'prereleased' 65 | uses: actions/upload-release-asset@v1 66 | env: 67 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 68 | with: 69 | upload_url: ${{ github.event.release.upload_url }} 70 | asset_path: ${{ env.PACKAGE_NAME }}.7z 71 | asset_name: ${{ env.PACKAGE_NAME }}.7z 72 | asset_content_type: application/x-7z-compressed 73 | -------------------------------------------------------------------------------- /PTA/search/src/components/ModFilter.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 79 | 80 | 85 | -------------------------------------------------------------------------------- /framelesswindow/framelesswindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | ############################################################################### 3 | # # 4 | # The MIT License # 5 | # # 6 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 7 | # >> https://github.com/Jorgen-VikingGod # 8 | # # 9 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 10 | # # 11 | ############################################################################### 12 | */ 13 | 14 | #ifndef FRAMELESSWINDOW_H 15 | #define FRAMELESSWINDOW_H 16 | 17 | #include 18 | 19 | namespace Ui 20 | { 21 | class FramelessWindow; 22 | } 23 | 24 | class FramelessWindow : public QWidget 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit FramelessWindow(QWidget* parent = Q_NULLPTR); 30 | virtual ~FramelessWindow(); 31 | void setContent(QWidget* w); 32 | 33 | private: 34 | bool leftBorderHit(const QPoint& pos); 35 | bool rightBorderHit(const QPoint& pos); 36 | bool topBorderHit(const QPoint& pos); 37 | bool bottomBorderHit(const QPoint& pos); 38 | void styleWindow(bool bActive, bool bNoState); 39 | 40 | public slots: 41 | void setWindowTitle(const QString& text); 42 | void setWindowIcon(const QIcon& ico); 43 | 44 | private slots: 45 | void on_applicationStateChanged(Qt::ApplicationState state); 46 | void on_minimizeButton_clicked(); 47 | void on_restoreButton_clicked(); 48 | void on_maximizeButton_clicked(); 49 | void on_closeButton_clicked(); 50 | void on_windowTitlebar_doubleClicked(); 51 | 52 | protected: 53 | virtual void changeEvent(QEvent* event); 54 | virtual void mouseDoubleClickEvent(QMouseEvent* event); 55 | virtual void checkBorderDragging(QMouseEvent* event); 56 | virtual void mousePressEvent(QMouseEvent* event); 57 | virtual void mouseReleaseEvent(QMouseEvent* event); 58 | virtual bool eventFilter(QObject* obj, QEvent* event); 59 | 60 | private: 61 | Ui::FramelessWindow* ui; 62 | QRect m_StartGeometry; 63 | const quint8 CONST_DRAG_BORDER_SIZE = 5; 64 | bool m_bMousePressed; 65 | bool m_bDragTop; 66 | bool m_bDragLeft; 67 | bool m_bDragRight; 68 | bool m_bDragBottom; 69 | }; 70 | 71 | #endif // FRAMELESSWINDOW_H 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### **Looking for PTA updates? Check out [PTA-Next](https://github.com/r52/pta-next) instead!** 2 | 3 | # PTA 4 | 5 | [![License](https://img.shields.io/github/license/r52/PTA)](https://github.com/r52/PTA/blob/master/LICENSE) 6 | ![Windows Build](https://github.com/r52/PTA/workflows/Windows%20Build/badge.svg) 7 | [![Build status](https://ci.appveyor.com/api/projects/status/m0mh6snl47uxdcs1?svg=true)](https://ci.appveyor.com/project/r52/pta) 8 | 9 | **PTA** (PoE Trade Assistant) is currently a [PoE-TradeMacro](https://github.com/PoE-TradeMacro/POE-TradeMacro) clone (with fewer features) that operates on the [Official Path of Exile Trade](https://www.pathofexile.com/trade) website instead of third-party alternatives. It hopes to become a full fledged trade assistant tool in the future. 10 | 11 | **NOTE:** As with any pricing tools, never trust or rely on its results entirely. If something seems off, confirm with a manual search. It could very well be an issue with the app itself. 12 | 13 | PTA is licensed under GPL-3.0 14 | 15 | ## Installation and Usage 16 | 17 | [Download the latest release from Releases](https://github.com/r52/PTA/releases/latest/) **OR** a development build from [here](https://github.com/r52/PTA/actions?query=workflow%3A%22Windows+Build%22) or [here](https://ci.appveyor.com/project/r52/pta/build/artifacts). 18 | 19 | Extract the archive and run **PTA.exe** 20 | 21 | **If your PC is not running Windows 10 with the latest feature updates or you are getting a VC runtime error, you MUST download and install the [Microsoft Visual C++ Redistributable](https://aka.ms/vs/16/release/VC_redist.x64.exe)!** 22 | 23 | ## Features 24 | 25 | - Simple and advanced item searches (**Ctrl+D** and **Ctrl+Alt+D** ala [PoE-TradeMacro](https://github.com/PoE-TradeMacro/POE-TradeMacro)) on www.pathofexile.com/trade 26 | - Custom macros with Client.txt support. See [wiki](https://github.com/r52/PTA/wiki) for more information. 27 | 28 | All shortcuts and macros can be re-configured in the settings. 29 | 30 | ## Building 31 | 32 | ### Requirements 33 | 34 | - [Visual Studio 2019](https://www.visualstudio.com/) 35 | - [Qt 5.12](http://www.qt.io/) (other versions such as Qt 5.14 are **NOT** supported) 36 | - [Node.js 12](https://nodejs.org/) 37 | 38 | Only Windows x64 is supported. 39 | 40 | ### Instructions 41 | 42 | 1. Build the PTA executable using `PTA.sln`. 43 | 2. `cd ./PTA/search/` 44 | 3. `npm ci && npm run build` 45 | 46 | ## Credits 47 | 48 | - [Grinding Gear Games](http://www.grindinggear.com/) for [Path of Exile](https://www.pathofexile.com/) 49 | - [brather1ng](https://github.com/brather1ng) for [RePoE](https://github.com/brather1ng/RePoE). 50 | - [PoE-TradeMacro](https://github.com/PoE-TradeMacro/POE-TradeMacro) 51 | - [poeprices.info](https://poeprices.info/) 52 | -------------------------------------------------------------------------------- /QtMsBuild/qt_settings.targets: -------------------------------------------------------------------------------- 1 | 2 | 31 | 35 | 36 | 38 | HKEY_CURRENT_USER\Software\Digia\Versions 40 | $([MSBuild]::GetRegistryValue('$(QtVersionsRegKey)','VersionNames')) 42 | 43 | 44 | 47 | Project 48 | 49 | 52 | 56 | Project 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /PTA/data/enchant_rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "Elemental Hit has #% chance to Freeze, Shock and Ignite": { 3 | "id": "enchant.stat_3205997967" 4 | }, 5 | "Elemental Hit Always Freezes, Shocks and Ignites": { 6 | "value": 100 7 | }, 8 | "Wild Strike Chains an additional # times": { 9 | "id": "enchant.stat_2447447843" 10 | }, 11 | "Wild Strike Chains an additional time": { 12 | "value": 1 13 | }, 14 | "Magma Orb Chains an additional # times": { 15 | "id": "enchant.stat_2589980605" 16 | }, 17 | "Magma Orb Chains an additional time": { 18 | "value": 1 19 | }, 20 | "Tempest Shield chains an additional # times": { 21 | "id": "enchant.stat_3096183736" 22 | }, 23 | "Tempest Shield chains an additional time": { 24 | "value": 1 25 | }, 26 | "Molten Strike fires # additional Projectiles": { 27 | "id": "enchant.stat_995860222" 28 | }, 29 | "Molten Strike fires an additional Projectile": { 30 | "value": 1 31 | }, 32 | "Lightning Strike fires # additional Projectiles": { 33 | "id": "enchant.stat_1213035889" 34 | }, 35 | "Lightning Strike fires an additional Projectile": { 36 | "value": 1 37 | }, 38 | "Spark fires # additional Projectiles": { 39 | "id": "enchant.stat_186513618" 40 | }, 41 | "Spark fires an additional Projectile": { 42 | "value": 1 43 | }, 44 | "Split Arrow fires # additional Projectiles": { 45 | "id": "enchant.stat_2278715446" 46 | }, 47 | "Split Arrow fires an additional Projectile": { 48 | "value": 1 49 | }, 50 | "Holy Flame Totem fires # additional Projectiles": { 51 | "id": "enchant.stat_775200811" 52 | }, 53 | "Holy Flame Totem fires an additional Projectile": { 54 | "value": 1 55 | }, 56 | "Summoned Agony Crawler fires # additional Projectiles": { 57 | "id": "enchant.stat_155429578" 58 | }, 59 | "Power Siphon fires # additional Projectiles": { 60 | "id": "enchant.stat_1177831984" 61 | }, 62 | "Power Siphon fires an additional Projectile": { 63 | "value": 1 64 | }, 65 | "Divine Ire Damages # additional nearby Enemies when gaining Stages": { 66 | "id": "enchant.stat_1477213724" 67 | }, 68 | "Divine Ire Damages an additional nearby Enemy when gaining Stages": { 69 | "value": 1 70 | }, 71 | "Blast Rain fires an additional Arrow": { 72 | "id": "enchant.stat_297308603", 73 | "value": 100 74 | }, 75 | "Cobra Lash Chains # additional times": { 76 | "id":"enchant.stat_1471796012" 77 | }, 78 | "Cobra Lash Chains an additional time": { 79 | "value": 1 80 | }, 81 | "Spectral Shield Throw fires # additional Shard Projectiles": { 82 | "id":"enchant.stat_3608981617" 83 | }, 84 | "Spectral Shield Throw fires an additional Shard Projectile": { 85 | "value": 1 86 | }, 87 | "Has # Abyssal Socket": { 88 | "id": "explicit.stat_3527617737" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /QtMsBuild/repc/qtrepc.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 41 | 44 | 45 | 49 | 50 | 51 | repc %(Identity) 52 | $(QtInstallDir) 53 | $(QTDIR) 54 | %(FullPath) 55 | replica 56 | .h]]> 57 | rep 58 | moc_cpp 59 | true 60 | [AllOptions] [AdditionalOptions] 61 | %(OutputFile) 62 | 63 | 64 | 65 | 69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /QtMsBuild/qt_defaults.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 38 | true 39 | 40 | 41 | bin 43 | bin 45 | 46 | 48 | DEFINES=/-D(\w+)/$1/ 50 | INCLUDEPATH=INCPATH/-I(\x22[^\x22]+\x22|[^\s]+)/$1/ 52 | LIBS=/(?:\/LIBPATH:(?:\x22[^\x22]+\x22|[^\s]+))|(\x22[^\x22]+\x22|[^\s]+)/$1/ 54 | LIBPATH=LIBS/\/LIBPATH:(\x22[^\x22]+\x22|[^\s]+)/$1/ 56 | $(QMake_DEFINES_);$(QMake_INCLUDEPATH_);$(QMake_LIBS_);$(QMake_LIBPATH_) 59 | 60 | 61 | HKEY_CURRENT_USER\Software\Digia\Versions 63 | $([MSBuild]::GetRegistryValue('$(QtVersionsRegKey)','DefaultQtVersion')) 65 | 66 | 67 | debug 68 | release 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /PTA/pta.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ui_pta.h" 4 | 5 | #include "clientmonitor.h" 6 | #include "macrohandler.h" 7 | #include "pitem.h" 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | QT_FORWARD_DECLARE_CLASS(LogWindow) 19 | QT_FORWARD_DECLARE_CLASS(ItemAPI) 20 | 21 | enum search_check_flag : uint32_t 22 | { 23 | PC_SIMPLE = 0, 24 | PC_ADVANCED, 25 | WIKI_SEARCH, 26 | PC_MAX 27 | }; 28 | 29 | class ConfigDialog; 30 | 31 | class PTA : public QMainWindow 32 | { 33 | Q_OBJECT 34 | 35 | class InputHandler 36 | { 37 | public: 38 | InputHandler(PTA* parent = nullptr); 39 | 40 | private: 41 | bool handleKeyboardEvent(WPARAM wParam, LPARAM lParam); 42 | bool handleMouseEvent(WPARAM wParam, LPARAM lParam); 43 | 44 | private: 45 | PTA* m_parent; 46 | bool m_ctrldown = false; 47 | }; 48 | 49 | public: 50 | explicit PTA(LogWindow* log, QWidget* parent = Q_NULLPTR); 51 | ~PTA(); 52 | 53 | signals: 54 | void foregroundWindowChanged(bool isPoe); 55 | 56 | public slots: 57 | void showPriceWidget(const QString& data); 58 | void showToolTip(QString message); 59 | 60 | protected: 61 | virtual void closeEvent(QCloseEvent* event) override; 62 | 63 | private: 64 | void createTrayIcon(); 65 | void createActions(); 66 | 67 | void setupFunctionality(); 68 | void checkForUpdates(); 69 | 70 | void foregroundEventCb(bool isPoe); 71 | 72 | private slots: 73 | void trayIconActivated(QSystemTrayIcon::ActivationReason reason); 74 | 75 | void openSettings(); 76 | void saveSettings(int result); 77 | 78 | void handleScrollHotkey(short data); 79 | void handleItemHotkey(uint32_t flag); 80 | void handleClipboard(); 81 | void processClipboard(); 82 | void handleForegroundChange(bool isPoe); 83 | 84 | void processUpdates(QNetworkReply* reply); 85 | 86 | private: 87 | Ui::PTAClass ui; 88 | 89 | // Log Window 90 | LogWindow* m_logWindow; 91 | 92 | // Tray 93 | QSystemTrayIcon* m_trayIcon; 94 | QMenu* m_trayIconMenu; 95 | 96 | // Actions/menus 97 | QAction* m_settingsAction; 98 | QAction* m_logAction; 99 | QAction* m_suspendAction; 100 | QAction* m_aboutAction; 101 | QAction* m_aboutQtAction; 102 | QAction* m_quitAction; 103 | 104 | // API 105 | ItemAPI* m_api; 106 | 107 | // Hotkeys 108 | std::unique_ptr m_simpleKey; 109 | std::unique_ptr m_advancedKey; 110 | std::unique_ptr m_wikiKey; 111 | 112 | // Client Monitor 113 | ClientMonitor m_clientmonitor; 114 | 115 | // Macros 116 | MacroHandler m_macrohandler; 117 | 118 | // Input Handler 119 | InputHandler m_inputhandler; 120 | 121 | // Networking 122 | QNetworkAccessManager* m_netmanager; 123 | QNetworkRequest m_updrequest; 124 | 125 | bool m_blockHotkeys = false; 126 | bool m_pcTriggered = false; 127 | uint32_t m_pctype; 128 | 129 | ConfigDialog* m_configdialog = nullptr; 130 | 131 | Q_DISABLE_COPY(PTA); 132 | }; 133 | -------------------------------------------------------------------------------- /QtMsBuild/uic/qtuic.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 41 | 44 | 45 | 49 | 50 | 51 | uic %(Identity) 52 | 53 | $(QTDIR) 55 | $(QtInstallDir) 57 | 58 | %(FullPath) 59 | 60 | $(ProjectDir)GeneratedFiles\$(Configuration)\ui_%(Filename).h 62 | 63 | $(IntDir)\uic\%(RelativeDir) 65 | ui_%(Filename).h 67 | 68 | true 69 | [AllOptions] [AdditionalOptions] 70 | %(OutputFile) 71 | 72 | 73 | 74 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /QtMsBuild/moc/qtmoc.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 35 | 36 | 40 | 43 | 44 | 48 | 49 | 50 | moc %(Identity) 51 | 52 | $(QTDIR) 54 | $(QtInstallDir) 56 | 57 | %(FullPath) 58 | 59 | $(ProjectDir)GeneratedFiles\$(Configuration)\moc_%(Filename).cpp 61 | 62 | $(IntDir)\moc\%(RelativeDir) 64 | moc_%(Filename).cpp 66 | 67 | output 68 | true 69 | [AllOptions] [AdditionalOptions] 70 | %(OutputFile) 71 | false 72 | 73 | 74 | 75 | 79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /QtMsBuild/rcc/qtrcc.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 35 | 36 | 40 | 43 | 44 | 48 | 49 | 50 | rcc %(Identity) 51 | 52 | $(QTDIR) 54 | $(QtInstallDir) 56 | 57 | %(FullPath) 58 | 59 | $(ProjectDir)GeneratedFiles\$(Configuration)\qrc_%(Filename).cpp 61 | 62 | $(IntDir)\rcc\%(RelativeDir) 64 | qrc_%(Filename).cpp 66 | 67 | %(Filename) 68 | default 69 | output 70 | true 71 | [AllOptions] [AdditionalOptions] 72 | %(OutputFile) 73 | 74 | 75 | 76 | 80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /framelesswindow/darkstyle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ############################################################################### 3 | # # 4 | # The MIT License # 5 | # # 6 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 7 | # >> https://github.com/Jorgen-VikingGod # 8 | # # 9 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 10 | # # 11 | ############################################################################### 12 | */ 13 | 14 | #include "darkstyle.h" 15 | 16 | DarkStyle::DarkStyle() : DarkStyle(styleBase()) {} 17 | 18 | DarkStyle::DarkStyle(QStyle* style) : QProxyStyle(style) {} 19 | 20 | QStyle* DarkStyle::styleBase(QStyle* style) const 21 | { 22 | static QStyle* base = !style ? QStyleFactory::create(QStringLiteral("Fusion")) : style; 23 | return base; 24 | } 25 | 26 | QStyle* DarkStyle::baseStyle() const 27 | { 28 | return styleBase(); 29 | } 30 | 31 | void DarkStyle::polish(QPalette& palette) 32 | { 33 | // modify palette to dark 34 | palette.setColor(QPalette::Window, QColor(53, 53, 53)); 35 | palette.setColor(QPalette::WindowText, Qt::white); 36 | palette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127)); 37 | palette.setColor(QPalette::Base, QColor(42, 42, 42)); 38 | palette.setColor(QPalette::AlternateBase, QColor(66, 66, 66)); 39 | palette.setColor(QPalette::ToolTipBase, Qt::white); 40 | palette.setColor(QPalette::ToolTipText, QColor(53, 53, 53)); 41 | palette.setColor(QPalette::Text, Qt::white); 42 | palette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127)); 43 | palette.setColor(QPalette::Dark, QColor(35, 35, 35)); 44 | palette.setColor(QPalette::Shadow, QColor(20, 20, 20)); 45 | palette.setColor(QPalette::Button, QColor(53, 53, 53)); 46 | palette.setColor(QPalette::ButtonText, Qt::white); 47 | palette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127)); 48 | palette.setColor(QPalette::BrightText, Qt::red); 49 | palette.setColor(QPalette::Link, QColor(42, 130, 218)); 50 | palette.setColor(QPalette::Highlight, QColor(42, 130, 218)); 51 | palette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80)); 52 | palette.setColor(QPalette::HighlightedText, Qt::white); 53 | palette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127, 127, 127)); 54 | } 55 | 56 | void DarkStyle::polish(QApplication* app) 57 | { 58 | if (!app) 59 | return; 60 | 61 | // increase font size for better reading, 62 | // setPointSize was reduced from +2 because when applied this way in Qt5, the 63 | // font is larger than intended for some reason 64 | QFont defaultFont = QApplication::font(); 65 | defaultFont.setPointSize(defaultFont.pointSize() + 1); 66 | app->setFont(defaultFont); 67 | 68 | // loadstylesheet 69 | QFile qfDarkstyle(QStringLiteral(":/darkstyle/darkstyle.qss")); 70 | if (qfDarkstyle.open(QIODevice::ReadOnly | QIODevice::Text)) 71 | { 72 | // set stylesheet 73 | QString qsStylesheet = QString::fromLatin1(qfDarkstyle.readAll()); 74 | app->setStyleSheet(qsStylesheet); 75 | qfDarkstyle.close(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /QtMsBuild/qt.targets: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 36 | 37 | 41 | 42 | 0 45 | 0 48 | 0 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 66 | 69 | 71 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /QtMsBuild/qml/qtqml.props: -------------------------------------------------------------------------------- 1 | 2 | 31 | 35 | 36 | 40 | 43 | 44 | 48 | 49 | 50 | false 51 | 53 | ahead of time]]> 55 | _%.cpp]]> 57 | 59 | Qt Quick Compiler: filtering %(Identity) 61 | $(ProjectDir)GeneratedFiles\%(Filename)_qmlcache.qrc 63 | $(ProjectDir)GeneratedFiles\qrc_%(Filename)_qmlcache.cpp 65 | %(Filename)_qmlcache 67 | 69 | Qt Quick Compiler: generating cache loader 71 | $(ProjectDir)GeneratedFiles\qmlcache_loader.cpp 73 | 74 | 75 | 76 | 80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | #BasedOnStyle: WebKit 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: true 7 | AlignConsecutiveDeclarations: true 8 | AlignEscapedNewlines: Left 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: false 12 | AllowShortBlocksOnASingleLine: true 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: Inline 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterReturnType: None 18 | AlwaysBreakBeforeMultilineStrings: false 19 | AlwaysBreakTemplateDeclarations: Yes 20 | BinPackArguments: false 21 | BinPackParameters: false 22 | BreakBeforeBraces: Custom 23 | BraceWrapping: 24 | AfterCaseLabel: true 25 | AfterClass: true 26 | AfterControlStatement: true 27 | AfterEnum: true 28 | AfterFunction: true 29 | AfterNamespace: true 30 | AfterObjCDeclaration: false 31 | AfterStruct: true 32 | AfterUnion: true 33 | AfterExternBlock: false 34 | BeforeCatch: false 35 | BeforeElse: true 36 | IndentBraces: false 37 | SplitEmptyFunction: false 38 | SplitEmptyRecord: false 39 | SplitEmptyNamespace: false 40 | 41 | BreakAfterJavaFieldAnnotations: false 42 | BreakBeforeBinaryOperators: None 43 | BreakBeforeTernaryOperators: false 44 | BreakConstructorInitializers: AfterColon 45 | BreakInheritanceList: AfterColon 46 | BreakStringLiterals: true 47 | ColumnLimit: 160 48 | CommentPragmas: '^IWYUpragma: ' 49 | CompactNamespaces: false 50 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 51 | ConstructorInitializerIndentWidth: 4 52 | ContinuationIndentWidth: 4 53 | Cpp11BracedListStyle: true 54 | DerivePointerAlignment: false 55 | DisableFormat: false 56 | ExperimentalAutoDetectBinPacking: false 57 | FixNamespaceComments: false 58 | ForEachMacros: ['foreach','Q_FOREACH','BOOST_FOREACH'] 59 | IncludeBlocks: Preserve 60 | 61 | IncludeCategories: 62 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 63 | Priority: 2 64 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 65 | Priority: 3 66 | - Regex: '<[[:alnum:].]+>' 67 | Priority: 4 68 | - Regex: '.*' 69 | Priority: 1 70 | 71 | IncludeIsMainRegex: '$' 72 | IndentCaseLabels: true 73 | IndentPPDirectives: AfterHash 74 | IndentWidth: 4 75 | IndentWrappedFunctionNames: false 76 | JavaScriptQuotes: Leave 77 | JavaScriptWrapImports: true 78 | KeepEmptyLinesAtTheStartOfBlocks: false 79 | MacroBlockBegin: '' 80 | MacroBlockEnd: '' 81 | MaxEmptyLinesToKeep: 1 82 | NamespaceIndentation: All 83 | ObjCBlockIndentWidth: 4 84 | ObjCSpaceAfterProperty: true 85 | ObjCSpaceBeforeProtocolList: true 86 | PenaltyBreakBeforeFirstCallParameter: 19 87 | PenaltyBreakComment: 300 88 | PenaltyBreakFirstLessLess: 120 89 | PenaltyBreakString: 1000 90 | PenaltyExcessCharacter: 1000000 91 | PenaltyReturnTypeOnItsOwnLine: 60 92 | PointerAlignment: Left 93 | ReflowComments: true 94 | SortIncludes: true 95 | SortUsingDeclarations: true 96 | SpaceAfterCStyleCast: true 97 | SpaceAfterTemplateKeyword: true 98 | SpaceBeforeAssignmentOperators: true 99 | SpaceBeforeCpp11BracedList: false 100 | SpaceBeforeCtorInitializerColon: true 101 | SpaceBeforeInheritanceColon: true 102 | SpaceBeforeParens: ControlStatements 103 | SpaceBeforeRangeBasedForLoopColon: true 104 | SpaceInEmptyParentheses: false 105 | SpacesBeforeTrailingComments: 1 106 | SpacesInAngles: false 107 | SpacesInCStyleCastParentheses: false 108 | SpacesInContainerLiterals: false 109 | SpacesInParentheses: false 110 | SpacesInSquareBrackets: false 111 | Standard: Cpp11 112 | StatementMacros: ['Q_UNUSED','Q_OBJECT'] 113 | TabWidth: 4 114 | UseTab: Never 115 | -------------------------------------------------------------------------------- /PTA/logwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "logwindow.h" 2 | 3 | #include "pta_types.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | /* 14 | * This is a fake singleton unique pointer hybrid monster thing 15 | * designed to work around the fact that Qt widget parents take 16 | * ownership of added child widgets, so that the lifetime of 17 | * the logedit widget can be maximized and ensure proper clean up 18 | */ 19 | 20 | namespace 21 | { 22 | std::mutex s_logMutex; 23 | QPlainTextEdit* s_logEdit = nullptr; 24 | QScopedPointer s_logFile; 25 | } 26 | 27 | void open_log_file() 28 | { 29 | QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); 30 | QString logFileExt = ".log"; 31 | 32 | s_logFile.reset(new QFile(path + logFileExt)); 33 | s_logFile->open(QFile::Append | QFile::Text); 34 | 35 | // 1MB limit 36 | if (s_logFile->size() > 1048576) 37 | { 38 | size_t logidx = 1; 39 | while (false == s_logFile->rename(path + logFileExt + QString(".%1").arg(QString::number(logidx)))) 40 | { 41 | logidx++; 42 | } 43 | 44 | s_logFile.reset(new QFile(path + logFileExt)); 45 | s_logFile->open(QFile::Append | QFile::Text); 46 | } 47 | } 48 | 49 | void msg_handler(QtMsgType type, const QMessageLogContext& context, const QString& msg) 50 | { 51 | QSettings setting; 52 | int loglevel = setting.value(PTA_CONFIG_LOGLEVEL, PTA_CONFIG_DEFAULT_LOGLEVEL).toInt(); 53 | bool logFile = setting.value(PTA_CONFIG_LOGFILE, false).toBool(); 54 | bool print = false; 55 | 56 | switch (type) 57 | { 58 | case QtDebugMsg: 59 | print = (loglevel == PTA_LOG_DEBUG); 60 | break; 61 | 62 | case QtInfoMsg: 63 | print = (loglevel <= PTA_LOG_INFO); 64 | break; 65 | 66 | case QtWarningMsg: 67 | print = (loglevel <= PTA_LOG_WARNING); 68 | break; 69 | 70 | case QtCriticalMsg: 71 | print = (loglevel <= PTA_LOG_CRITICAL); 72 | break; 73 | 74 | default: 75 | print = true; 76 | break; 77 | } 78 | 79 | if (print) 80 | { 81 | std::unique_lock lock(s_logMutex); 82 | 83 | QString output = qFormatLogMessage(type, context, msg); 84 | 85 | if (s_logEdit) 86 | { 87 | s_logEdit->appendPlainText(output); 88 | } 89 | 90 | if (logFile && !s_logFile) 91 | { 92 | open_log_file(); 93 | } 94 | 95 | if (s_logFile) 96 | { 97 | QTextStream out(s_logFile.data()); 98 | out << output << endl; 99 | out.flush(); 100 | } 101 | } 102 | } 103 | 104 | LogWindow::~LogWindow() 105 | { 106 | // if released, s_logEdit is not owned anymore 107 | // otherwise it needs to be cleaned 108 | if (!m_released && nullptr != s_logEdit) 109 | { 110 | delete s_logEdit; 111 | } 112 | 113 | s_logEdit = nullptr; 114 | } 115 | 116 | LogWindow::LogWindow(QObject* parent) : QObject(parent) 117 | { 118 | if (nullptr != s_logEdit) 119 | { 120 | throw std::runtime_error("log window already created"); 121 | } 122 | 123 | s_logEdit = new QPlainTextEdit(); 124 | 125 | s_logEdit->setReadOnly(true); 126 | 127 | // max lines in log viewer 128 | s_logEdit->setMaximumBlockCount(250); 129 | 130 | qInstallMessageHandler(msg_handler); 131 | qSetMessagePattern("[%{time}] %{type} %{message} - (%{function}:%{line})"); 132 | } 133 | 134 | QPlainTextEdit* LogWindow::release() 135 | { 136 | if (nullptr != s_logEdit) 137 | { 138 | m_released = true; 139 | } 140 | 141 | return s_logEdit; 142 | } 143 | -------------------------------------------------------------------------------- /PTA/webwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "webwidget.h" 2 | #include "itemapi.h" 3 | #include "pta_types.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void PWebPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) 13 | { 14 | QString msg = "CONSOLE: " + message + " (" + sourceID + ":" + QString::number(lineNumber) + ")"; 15 | 16 | switch (level) 17 | { 18 | case InfoMessageLevel: 19 | qInfo().noquote() << msg; 20 | break; 21 | case WarningMessageLevel: 22 | qWarning().noquote() << msg; 23 | break; 24 | case ErrorMessageLevel: 25 | qCritical().noquote() << msg; 26 | break; 27 | } 28 | } 29 | 30 | WebWidget::WebWidget(ItemAPI* api, const QString& data, QWidget* parent) : FramelessWindow(parent) 31 | { 32 | QIcon icon(":/Resources/logo.svg"); 33 | setWindowIcon(icon); 34 | 35 | setAttribute(Qt::WA_DeleteOnClose); 36 | 37 | setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); 38 | 39 | webview = new PWebView(this); 40 | webview->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); 41 | webview->settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, false); 42 | 43 | QUrl startFile; 44 | 45 | QFileInfo tmplFile(PTA_CONFIG_DEFAULT_PRICE_TEMPLATE); 46 | 47 | if (!tmplFile.exists()) 48 | { 49 | qWarning() << "Template file" << PTA_CONFIG_DEFAULT_PRICE_TEMPLATE << "does not exist. Ensure that PTA has been properly extracted."; 50 | } 51 | 52 | QString startFilePath = tmplFile.absoluteFilePath(); 53 | startFile = QUrl::fromLocalFile(startFilePath); 54 | 55 | PWebPage* page = new PWebPage(this); 56 | 57 | QWebChannel* channel = new QWebChannel(this); 58 | channel->registerObject(QStringLiteral("api"), api); 59 | page->setWebChannel(channel); 60 | 61 | page->load(startFile); 62 | 63 | webview->setPage(page); 64 | 65 | connect(page, &QWebEnginePage::windowCloseRequested, this, &QWidget::close); 66 | 67 | // resize 68 | QSize defaultsize = {PTA_CONFIG_DEFAULT_TEMPLATE_WIDTH, PTA_CONFIG_DEFAULT_TEMPLATE_HEIGHT}; 69 | 70 | webview->resize(defaultsize); 71 | resize(defaultsize); 72 | 73 | // No context menu 74 | setContextMenuPolicy(Qt::PreventContextMenu); 75 | 76 | // Inject global script 77 | QString dataScript = generateDataScript(data); 78 | script.setName("Data"); 79 | script.setInjectionPoint(QWebEngineScript::DocumentCreation); 80 | script.setWorldId(0); 81 | script.setSourceCode(dataScript); 82 | webview->page()->scripts().insert(script); 83 | 84 | setWindowTitle("PTA Price Check"); 85 | 86 | setContent(webview); 87 | 88 | // Restore settings 89 | QSettings settings; 90 | restoreGeometry(settings.value(getSettingKey("geometry")).toByteArray()); 91 | 92 | // quick close shortcuts 93 | auto escshc = new QShortcut(QKeySequence(QKeySequence::Cancel), this); 94 | connect(escshc, &QShortcut::activated, [=] { close(); }); 95 | 96 | auto qshc = new QShortcut(QKeySequence(Qt::Key_Q), this); 97 | connect(qshc, &QShortcut::activated, [=] { close(); }); 98 | 99 | // Force focus the webview 100 | webview->setFocus(); 101 | } 102 | 103 | WebWidget::~WebWidget() 104 | { 105 | saveSettings(); 106 | } 107 | 108 | QString WebWidget::generateDataScript(const QString& data) 109 | { 110 | QString pscript = QString("var item = %1;").arg(data); 111 | return pscript; 112 | } 113 | 114 | void WebWidget::saveSettings() 115 | { 116 | QSettings settings; 117 | settings.setValue(getSettingKey("geometry"), saveGeometry()); 118 | } 119 | 120 | QString WebWidget::getSettingKey(QString key) 121 | { 122 | return "widget/" + key; 123 | } 124 | -------------------------------------------------------------------------------- /QHotkey/HotkeyTest/HotkeyTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 6 | ui 7 | false 8 | 9 | 10 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 11 | ui 12 | false 13 | 14 | 15 | {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} 16 | cpp;c;cxx;moc;h;def;odl;idl;res; 17 | 18 | 19 | {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} 20 | cpp;c;cxx;moc;h;def;odl;idl;res; 21 | 22 | 23 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 24 | h;hpp;hxx;hm;inl;inc;xsd 25 | 26 | 27 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 28 | h;hpp;hxx;hm;inl;inc;xsd 29 | 30 | 31 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 32 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 33 | 34 | 35 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 36 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 37 | 38 | 39 | 40 | 41 | Source Files 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | Source Files 51 | 52 | 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | 68 | 69 | Generated Files 70 | 71 | 72 | Generated Files 73 | 74 | 75 | Generated Files 76 | 77 | 78 | Generated Files 79 | 80 | 81 | Generated Files 82 | 83 | 84 | Generated Files 85 | 86 | 87 | Generated Files 88 | 89 | 90 | Generated Files 91 | 92 | 93 | Generated Files 94 | 95 | 96 | 97 | 98 | Form Files 99 | 100 | 101 | -------------------------------------------------------------------------------- /PTA/pta_types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum pta_log_level_t 4 | { 5 | PTA_LOG_DEBUG, //!< Debug level. 6 | PTA_LOG_INFO, //!< Info level. 7 | PTA_LOG_WARNING, //!< Warning level. 8 | PTA_LOG_CRITICAL //!< Critical level. 9 | }; 10 | 11 | // Config defs 12 | constexpr auto PTA_CONFIG_LOGLEVEL = "global/loglevel"; 13 | constexpr auto PTA_CONFIG_LOGFILE = "global/logfile"; 14 | 15 | // constexpr auto PTA_CONFIG_PRICE_TEMPLATE = "ui/pricetemplate"; 16 | 17 | constexpr auto PTA_CONFIG_SIMPLE_CHECK_HOTKEY = "hotkey/simplecheck"; 18 | constexpr auto PTA_CONFIG_SIMPLE_CHECK_HOTKEY_ENABLED = "hotkey/simplecheck/enabled"; 19 | constexpr auto PTA_CONFIG_ADV_CHECK_HOTKEY = "hotkey/advcheck"; 20 | constexpr auto PTA_CONFIG_ADV_CHECK_HOTKEY_ENABLED = "hotkey/advcheck/enabled"; 21 | constexpr auto PTA_CONFIG_WIKI_HOTKEY = "hotkey/wiki"; 22 | constexpr auto PTA_CONFIG_WIKI_HOTKEY_ENABLED = "hotkey/wiki/enabled"; 23 | constexpr auto PTA_CONFIG_CTRL_SCROLL_HOTKEY_ENABLED = "hotkey/cscroll/enabled"; 24 | 25 | constexpr auto PTA_CONFIG_LEAGUE = "pricecheck/league"; 26 | constexpr auto PTA_CONFIG_DISPLAYLIMIT = "pricecheck/displaylimit"; 27 | constexpr auto PTA_CONFIG_CORRUPTOVERRIDE = "pricecheck/corruptoverride"; 28 | constexpr auto PTA_CONFIG_CORRUPTSEARCH = "pricecheck/corruptsearch"; 29 | constexpr auto PTA_CONFIG_PRIMARY_CURRENCY = "pricecheck/primarycurrency"; 30 | constexpr auto PTA_CONFIG_SECONDARY_CURRENCY = "pricecheck/secondarycurrency"; 31 | constexpr auto PTA_CONFIG_ONLINE_ONLY = "pricecheck/online"; 32 | constexpr auto PTA_CONFIG_BUYOUT_ONLY = "pricecheck/buyout"; 33 | constexpr auto PTA_CONFIG_REMOVE_DUPES = "pricecheck/duplicates"; 34 | constexpr auto PTA_CONFIG_POEPRICES = "pricecheck/poeprices"; 35 | constexpr auto PTA_CONFIG_PREFILL_MIN = "pricecheck/prefillmin"; 36 | constexpr auto PTA_CONFIG_PREFILL_MAX = "pricecheck/prefillmax"; 37 | constexpr auto PTA_CONFIG_PREFILL_RANGE = "pricecheck/prefillrange"; 38 | constexpr auto PTA_CONFIG_PREFILL_NORMALS = "pricecheck/prefillnormals"; 39 | constexpr auto PTA_CONFIG_PREFILL_PSEUDOS = "pricecheck/prefillpseudos"; 40 | constexpr auto PTA_CONFIG_PREFILL_ILVL = "pricecheck/prefillilvl"; 41 | constexpr auto PTA_CONFIG_PREFILL_BASE = "pricecheck/prefillbase"; 42 | 43 | constexpr auto PTA_CONFIG_CUSTOM_MACROS = "macro/list"; 44 | 45 | constexpr auto PTA_CONFIG_CLIENTLOG_PATH = "client/path"; 46 | 47 | // defaults 48 | constexpr auto PTA_CONFIG_DEFAULT_PRICE_TEMPLATE = "search/dist/index.html"; 49 | constexpr auto PTA_CONFIG_DEFAULT_TEMPLATE_WIDTH = 820; 50 | constexpr auto PTA_CONFIG_DEFAULT_TEMPLATE_HEIGHT = 870; 51 | 52 | constexpr auto PTA_CONFIG_DEFAULT_SIMPLE_CHECK_HOTKEY = "Ctrl+D"; 53 | constexpr auto PTA_CONFIG_DEFAULT_ADV_CHECK_HOTKEY = "Ctrl+Alt+D"; 54 | constexpr auto PTA_CONFIG_DEFAULT_WIKI_HOTKEY = "Ctrl+Alt+G"; 55 | 56 | constexpr auto PTA_CONFIG_DEFAULT_LEAGUE = 0; 57 | constexpr auto PTA_CONFIG_DEFAULT_DISPLAYLIMIT = 20; 58 | constexpr auto PTA_CONFIG_DEFAULT_CORRUPTOVERRIDE = false; 59 | constexpr auto PTA_CONFIG_DEFAULT_CORRUPTSEARCH = "Any"; 60 | constexpr auto PTA_CONFIG_DEFAULT_PRIMARY_CURRENCY = "chaos"; 61 | constexpr auto PTA_CONFIG_DEFAULT_SECONDARY_CURRENCY = "exa"; 62 | constexpr auto PTA_CONFIG_DEFAULT_ONLINE_ONLY = true; 63 | constexpr auto PTA_CONFIG_DEFAULT_BUYOUT_ONLY = true; 64 | constexpr auto PTA_CONFIG_DEFAULT_REMOVE_DUPES = true; 65 | constexpr auto PTA_CONFIG_DEFAULT_POEPRICES = true; 66 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_MIN = false; 67 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_MAX = false; 68 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_RANGE = 0; 69 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_NORMALS = false; 70 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_PSEUDOS = true; 71 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_ILVL = false; 72 | constexpr auto PTA_CONFIG_DEFAULT_PREFILL_BASE = false; 73 | 74 | enum MacroType : uint8_t 75 | { 76 | MACRO_TYPE_CHAT = 0, 77 | MACRO_TYPE_URL, 78 | MACRO_TYPE_MAX 79 | }; 80 | 81 | #ifdef _DEBUG 82 | # define PTA_CONFIG_DEFAULT_LOGLEVEL PTA_LOG_DEBUG 83 | #else 84 | # define PTA_CONFIG_DEFAULT_LOGLEVEL PTA_LOG_INFO 85 | #endif 86 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/qhotkey.h: -------------------------------------------------------------------------------- 1 | #ifndef QHOTKEY_H 2 | #define QHOTKEY_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef QHOTKEY_LIB 10 | #ifdef QHOTKEY_LIB_BUILD 11 | #define QHOTKEY_SHARED_EXPORT Q_DECL_EXPORT 12 | #else 13 | #define QHOTKEY_SHARED_EXPORT Q_DECL_IMPORT 14 | #endif 15 | #else 16 | #define QHOTKEY_SHARED_EXPORT 17 | #endif 18 | 19 | //! A class to define global, systemwide Hotkeys 20 | class QHOTKEY_SHARED_EXPORT QHotkey : public QObject 21 | { 22 | Q_OBJECT 23 | friend class QHotkeyPrivate; 24 | 25 | //! Specifies whether this hotkey is currently registered or not 26 | Q_PROPERTY(bool registered READ isRegistered WRITE setRegistered NOTIFY registeredChanged) 27 | //! Holds the shortcut this hotkey will be triggered on 28 | Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut RESET resetShortcut) 29 | 30 | public: 31 | //! Defines shortcut with native keycodes 32 | class QHOTKEY_SHARED_EXPORT NativeShortcut { 33 | public: 34 | //! The native keycode 35 | quint32 key; 36 | //! The native modifiers 37 | quint32 modifier; 38 | 39 | //! Creates an invalid native shortcut 40 | NativeShortcut(); 41 | //! Creates a valid native shortcut, with the given key and modifiers 42 | NativeShortcut(quint32 key, quint32 modifier = 0); 43 | 44 | //! Checks, whether this shortcut is valid or not 45 | bool isValid() const; 46 | 47 | //! Equality operator 48 | bool operator ==(const NativeShortcut &other) const; 49 | //! Inequality operator 50 | bool operator !=(const NativeShortcut &other) const; 51 | 52 | private: 53 | bool valid; 54 | }; 55 | 56 | static void addGlobalMapping(const QKeySequence &shortcut, const NativeShortcut &nativeShortcut); 57 | 58 | //! Constructor 59 | explicit QHotkey(QObject *parent = Q_NULLPTR); 60 | //! Constructs a hotkey with a shortcut and optionally registers it 61 | explicit QHotkey(const QKeySequence &shortcut, bool autoRegister = false, QObject *parent = Q_NULLPTR); 62 | //! Constructs a hotkey with a key and modifiers and optionally registers it 63 | explicit QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false, QObject *parent = Q_NULLPTR); 64 | //! Constructs a hotkey from a native shortcut and optionally registers it 65 | explicit QHotkey(const NativeShortcut &shortcut, bool autoRegister = false, QObject *parent = Q_NULLPTR); 66 | //! Destructor 67 | ~QHotkey(); 68 | 69 | //! READ-Accessor for QHotkey::registered 70 | bool isRegistered() const; 71 | //! READ-Accessor for QHotkey::shortcut - the key and modifiers as a QKeySequence 72 | QKeySequence shortcut() const; 73 | //! READ-Accessor for QHotkey::shortcut - the key only 74 | Qt::Key keyCode() const; 75 | //! READ-Accessor for QHotkey::shortcut - the modifiers only 76 | Qt::KeyboardModifiers modifiers() const; 77 | 78 | //! Get the current native shortcut 79 | NativeShortcut currentNativeShortcut() const; 80 | 81 | public slots: 82 | //! WRITE-Accessor for QHotkey::registered 83 | bool setRegistered(bool registered); 84 | 85 | //! WRITE-Accessor for QHotkey::shortcut 86 | bool setShortcut(const QKeySequence &shortcut, bool autoRegister = false); 87 | //! WRITE-Accessor for QHotkey::shortcut 88 | bool setShortcut(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false); 89 | //! RESET-Accessor for QHotkey::shortcut 90 | bool resetShortcut(); 91 | 92 | //! Set this hotkey to a native shortcut 93 | bool setNativeShortcut(NativeShortcut nativeShortcut, bool autoRegister = false); 94 | 95 | signals: 96 | //! Will be emitted if the shortcut is pressed 97 | void activated(QPrivateSignal); 98 | 99 | //! NOTIFY-Accessor for QHotkey::registered 100 | void registeredChanged(bool registered); 101 | 102 | private: 103 | Qt::Key _keyCode; 104 | Qt::KeyboardModifiers _modifiers; 105 | 106 | NativeShortcut _nativeShortcut; 107 | bool _registered; 108 | }; 109 | 110 | uint QHOTKEY_SHARED_EXPORT qHash(const QHotkey::NativeShortcut &key); 111 | uint QHOTKEY_SHARED_EXPORT qHash(const QHotkey::NativeShortcut &key, uint seed); 112 | 113 | QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) 114 | 115 | Q_DECLARE_METATYPE(QHotkey::NativeShortcut) 116 | 117 | #endif // QHOTKEY_H 118 | -------------------------------------------------------------------------------- /PTA/clientmonitor.cpp: -------------------------------------------------------------------------------- 1 | #include "clientmonitor.h" 2 | 3 | #include "pta_types.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std::chrono_literals; 12 | 13 | const std::chrono::milliseconds ClientMonitor::polling_rate = 350ms; 14 | 15 | ClientMonitor::ClientMonitor(QObject* parent) : QObject(parent), m_enabled(false), m_last_whisper(QString()) 16 | { 17 | QSettings settings; 18 | 19 | QString logpath = settings.value(PTA_CONFIG_CLIENTLOG_PATH, QString()).toString(); 20 | 21 | if (logpath.isEmpty()) 22 | { 23 | qInfo() << "Client.txt path not set. Client features disabled."; 24 | } 25 | else 26 | { 27 | setPath(logpath); 28 | } 29 | } 30 | 31 | ClientMonitor::~ClientMonitor() 32 | { 33 | m_watcher.reset(); 34 | } 35 | 36 | void ClientMonitor::setPath(QString logpath) 37 | { 38 | if (logpath.isEmpty()) 39 | { 40 | // If empty path, disable monitor 41 | m_enabled = false; 42 | 43 | // Clear file watcher 44 | if (m_watcher) 45 | { 46 | m_watcher.reset(); 47 | } 48 | 49 | m_logpath.clear(); 50 | 51 | return; 52 | } 53 | 54 | if (!QFileInfo::exists(logpath)) 55 | { 56 | qWarning() << "Client log file not found at" << logpath; 57 | return; 58 | } 59 | 60 | if (m_logpath == logpath) 61 | { 62 | // Same file 63 | return; 64 | } 65 | 66 | m_logpath = logpath; 67 | 68 | // Pre-read size 69 | QFile log(m_logpath); 70 | 71 | if (!log.open(QIODevice::ReadOnly | QIODevice::Text)) 72 | { 73 | qWarning() << "Cannot process client log file found at" << m_logpath; 74 | return; 75 | } 76 | 77 | m_lastpos = log.size(); 78 | 79 | log.close(); 80 | 81 | m_watcher.reset(new QTimer(this)); 82 | 83 | connect(m_watcher.get(), &QTimer::timeout, this, &ClientMonitor::processLogChange); 84 | m_watcher->start(polling_rate); 85 | 86 | m_enabled = true; 87 | 88 | qInfo() << "Client.txt set to" << m_logpath; 89 | } 90 | 91 | bool ClientMonitor::enabled() 92 | { 93 | return m_enabled; 94 | } 95 | 96 | QString ClientMonitor::getLastWhisperer() 97 | { 98 | return m_last_whisper; 99 | } 100 | 101 | void ClientMonitor::processLogLine(QString line) 102 | { 103 | auto parts = line.splitRef("] ", QString::SkipEmptyParts); 104 | 105 | if (parts.size() < 2) 106 | { 107 | // If not a game info line, skip 108 | return; 109 | } 110 | 111 | // Get last part 112 | auto ltxt = parts[parts.size() - 1].trimmed().toString(); 113 | 114 | if (ltxt.startsWith('@')) 115 | { 116 | // Whisper 117 | 118 | // Remove whisper tags 119 | ltxt.remove(QRegularExpression("^@(From|To) (<\\S+> )?")); 120 | 121 | auto msgparts = ltxt.splitRef(": ", QString::SkipEmptyParts); 122 | 123 | if (msgparts.size() < 1) 124 | { 125 | qWarning() << "Error parsing whisper text:" << ltxt; 126 | return; 127 | } 128 | 129 | auto pname = msgparts[0].toString(); 130 | 131 | m_last_whisper = pname; 132 | } 133 | } 134 | 135 | void ClientMonitor::processLogChange() 136 | { 137 | if (!enabled()) 138 | { 139 | // Shouldn't ever get here 140 | return; 141 | } 142 | 143 | QFile log(m_logpath); 144 | 145 | if (!log.open(QIODevice::ReadOnly | QIODevice::Text)) 146 | { 147 | qWarning() << "Cannot process client log file found at" << m_logpath; 148 | return; 149 | } 150 | 151 | qint64 lastpos = log.size(); 152 | 153 | if (lastpos < m_lastpos) 154 | { 155 | // File got reset, so reset our position too 156 | m_lastpos = lastpos; 157 | return; 158 | } 159 | 160 | if (lastpos == m_lastpos) 161 | { 162 | // No change 163 | return; 164 | } 165 | 166 | // Start reading from 167 | log.seek(m_lastpos); 168 | 169 | QTextStream in(&log); 170 | while (!in.atEnd()) 171 | { 172 | QString line = in.readLine(); 173 | processLogLine(line); 174 | } 175 | 176 | m_lastpos = lastpos; 177 | 178 | log.close(); 179 | } 180 | -------------------------------------------------------------------------------- /PTA/Resources/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 47 | 49 | 50 | 52 | image/svg+xml 53 | 55 | 56 | 57 | 58 | 59 | 64 | 70 | P 81 | 82 | 83 | -------------------------------------------------------------------------------- /PTA/configdialog.cpp: -------------------------------------------------------------------------------- 1 | #include "configdialog.h" 2 | 3 | #include "configpages.h" 4 | 5 | #include 6 | 7 | ConfigDialog::ConfigDialog(ItemAPI* api) 8 | { 9 | setAttribute(Qt::WA_DeleteOnClose); 10 | 11 | contentsWidget = new QListWidget; 12 | contentsWidget->setViewMode(QListView::IconMode); 13 | contentsWidget->setIconSize(QSize(32, 32)); 14 | contentsWidget->setMovement(QListView::Static); 15 | contentsWidget->setMaximumWidth(128); 16 | contentsWidget->setMinimumWidth(128); 17 | contentsWidget->setMinimumHeight(300); 18 | contentsWidget->setSpacing(12); 19 | contentsWidget->setFlow(QListView::TopToBottom); 20 | contentsWidget->setWrapping(false); 21 | 22 | pagesWidget = new QStackedWidget; 23 | pagesWidget->addWidget(new GeneralPage(results)); 24 | // pagesWidget->addWidget(new UIPage(results)); 25 | pagesWidget->addWidget(new HotkeyPage(results)); 26 | pagesWidget->addWidget(new PriceCheckPage(results, api)); 27 | pagesWidget->addWidget(new MacrosPage(results)); 28 | pagesWidget->addWidget(new ClientPage(results)); 29 | 30 | QPushButton* saveButton = new QPushButton(tr("Save")); 31 | QPushButton* closeButton = new QPushButton(tr("Close")); 32 | 33 | createIcons(); 34 | contentsWidget->setCurrentRow(0); 35 | 36 | connect(saveButton, &QAbstractButton::clicked, this, &QDialog::accept); 37 | connect(closeButton, &QAbstractButton::clicked, this, &QDialog::reject); 38 | 39 | QHBoxLayout* horizontalLayout = new QHBoxLayout; 40 | horizontalLayout->addWidget(contentsWidget); 41 | horizontalLayout->addWidget(pagesWidget, 1); 42 | 43 | QHBoxLayout* buttonsLayout = new QHBoxLayout; 44 | buttonsLayout->addStretch(1); 45 | buttonsLayout->addWidget(saveButton); 46 | buttonsLayout->addWidget(closeButton); 47 | 48 | QVBoxLayout* mainLayout = new QVBoxLayout; 49 | mainLayout->addLayout(horizontalLayout); 50 | mainLayout->addSpacing(12); 51 | mainLayout->addLayout(buttonsLayout); 52 | setLayout(mainLayout); 53 | 54 | setWindowTitle(tr("Settings")); 55 | setMinimumWidth(600); 56 | } 57 | 58 | void ConfigDialog::createIcons() 59 | { 60 | QListWidgetItem* generalButton = new QListWidgetItem(contentsWidget); 61 | generalButton->setText(tr("General")); 62 | generalButton->setTextAlignment(Qt::AlignHCenter); 63 | generalButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 64 | generalButton->setIcon(QIcon(":/Resources/settings.png")); 65 | 66 | /* 67 | QListWidgetItem* uiButton = new QListWidgetItem(contentsWidget); 68 | uiButton->setText(tr("UI")); 69 | uiButton->setTextAlignment(Qt::AlignHCenter); 70 | uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 71 | uiButton->setIcon(QIcon(":/Resources/ui.png")); 72 | */ 73 | 74 | QListWidgetItem* hotkeyButton = new QListWidgetItem(contentsWidget); 75 | hotkeyButton->setText(tr("Hotkey")); 76 | hotkeyButton->setTextAlignment(Qt::AlignHCenter); 77 | hotkeyButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 78 | hotkeyButton->setIcon(QIcon(":/Resources/hotkey.png")); 79 | 80 | QListWidgetItem* pcButton = new QListWidgetItem(contentsWidget); 81 | pcButton->setText(tr("Price Check")); 82 | pcButton->setTextAlignment(Qt::AlignHCenter); 83 | pcButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 84 | pcButton->setIcon(QIcon(":/Resources/pricing.png")); 85 | 86 | QListWidgetItem* macroButton = new QListWidgetItem(contentsWidget); 87 | macroButton->setText(tr("Custom Macros")); 88 | macroButton->setTextAlignment(Qt::AlignHCenter); 89 | macroButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 90 | macroButton->setIcon(QIcon(":/Resources/macros.png")); 91 | 92 | QListWidgetItem* clientButton = new QListWidgetItem(contentsWidget); 93 | clientButton->setText(tr("Client")); 94 | clientButton->setTextAlignment(Qt::AlignHCenter); 95 | clientButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 96 | clientButton->setIcon(QIcon(":/Resources/client.png")); 97 | 98 | connect(contentsWidget, &QListWidget::currentItemChanged, this, &ConfigDialog::changePage); 99 | } 100 | 101 | void ConfigDialog::changePage(QListWidgetItem* current, QListWidgetItem* previous) 102 | { 103 | if (!current) 104 | current = previous; 105 | 106 | pagesWidget->setCurrentIndex(contentsWidget->row(current)); 107 | } 108 | -------------------------------------------------------------------------------- /PTA/PTA.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 14 | qrc;* 15 | false 16 | 17 | 18 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 19 | ui 20 | 21 | 22 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 23 | qrc;* 24 | false 25 | 26 | 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | Source Files 51 | 52 | 53 | Source Files 54 | 55 | 56 | Source Files 57 | 58 | 59 | Source Files 60 | 61 | 62 | Source Files 63 | 64 | 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | Header Files 74 | 75 | 76 | Header Files 77 | 78 | 79 | Header Files 80 | 81 | 82 | Header Files 83 | 84 | 85 | Header Files 86 | 87 | 88 | Header Files 89 | 90 | 91 | 92 | 93 | Form Files 94 | 95 | 96 | 97 | 98 | Resource Files 99 | 100 | 101 | Resource Files 102 | 103 | 104 | Resource Files 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | Header Files 113 | 114 | 115 | Header Files 116 | 117 | 118 | Header Files 119 | 120 | 121 | Header Files 122 | 123 | 124 | Header Files 125 | 126 | 127 | -------------------------------------------------------------------------------- /framelesswindow/README.md: -------------------------------------------------------------------------------- 1 | # Qt Frameless Window with DarkStyle 2 | simple MainWindow class implementation with frameless window and custom dark style. 3 | 4 | It adds also support for titlebar and buttons (minimize, maximize, close) 5 | 6 | Look is based on the VS2013 application window (flat and frameless window) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Screenshots
mac enabledmac disabled
16 | 17 | 18 | ## Qt and OS 19 | * tested with Qt5.5.0, Qt5.9.0 and Qt5.10.0 20 | * tested on Windows 7, Windows 10,MacOSX 10.12.5 and MacOS 10.13.2 21 | 22 | ## PyQt5 23 | Here is an [unofficial Python port](https://github.com/gmarull/qtmodern) of my implementation. 24 | 25 | ## How to use 26 | * add additional include plath to **framelesswindow** 27 | * add resources **framelesswindow.qrc** and **darkstyle.qrc** 28 | * add ``#include "framelesswindow.h"`` into **main.cpp**, create window ``FramelessWindow framelessWindow;`` and assign your mainwindow object as content ``framelessWindow.setContent(mainWindow);`` and show it ``framelessWindow.show();`` 29 | * add ``#include "DarkStyle.h"`` into **main.cpp** and call ``a.setStyle(new DarkStyle);`` 30 | 31 | 32 | ```qt 33 | #include 34 | #include "DarkStyle.h" 35 | #include "framelesswindow.h" 36 | #include "mainwindow.h" 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | QApplication a(argc, argv); 41 | 42 | // style our application with custom dark style 43 | a.setStyle(new DarkStyle); 44 | 45 | // create frameless window (and set windowState or title) 46 | FramelessWindow framelessWindow; 47 | //framelessWindow.setWindowState(Qt::WindowMaximized); 48 | //framelessWindow.setWindowTitle("test title"); 49 | //framelessWindow.setWindowIcon(a.style()->standardIcon(QStyle::SP_DesktopIcon)); 50 | 51 | // create our mainwindow instance 52 | MainWindow *mainWindow = new MainWindow; 53 | 54 | // add the mainwindow to our custom frameless window 55 | framelessWindow.setContent(mainWindow); 56 | framelessWindow.show(); 57 | 58 | return a.exec(); 59 | } 60 | ``` 61 | 62 | 63 | ## features 64 | * frameless window 65 | * custom dark style (based on **Fusion style** with dark palette and custom stylesheets) 66 | * title bar 67 | * buttons (minimize | restore | maximize | close) 68 | * move window by drag the title bar 69 | * dobule click title bar to toggle between window styte (maximize and normal) 70 | * use of native events, like minimizing or system menu 71 | 72 | 73 | ## todo 74 | * [ ] [resize window on each corner [#1]](https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle/issues/1) (some work done by [notecola](https://github.com/notecola) :+1:) 75 | * [ ] [snap on screen edges [#3]](https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle/issues/3) 76 | 77 | 78 | ## thanks 79 | Many thanks goes to the [Qt Forum](https://forum.qt.io/topic/80654/how-to-create-vs2013-like-frameless-window-with-dark-style) and especially to [Chris Kawa](https://forum.qt.io/user/chris-kawa) for pointing me to some usual issues and hints of great must have features. 80 | 81 | 82 | ## Licence 83 | > The MIT License 84 | > 85 | > Copyright (c) 2018, Juergen Skrotzky (https://github.com/Jorgen-VikingGod, JorgenVikingGod@gmail.com) 86 | > 87 | > Permission is hereby granted, free of charge, to any person obtaining a copy 88 | > of this software and associated documentation files (the "Software"), to deal 89 | > in the Software without restriction, including without limitation the rights 90 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 91 | > copies of the Software, and to permit persons to whom the Software is 92 | > furnished to do so, subject to the following conditions: 93 | > 94 | > The above copyright notice and this permission notice shall be included in 95 | > all copies or substantial portions of the Software. 96 | > 97 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 98 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 99 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 100 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 101 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 102 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 103 | > THE SOFTWARE. 104 | -------------------------------------------------------------------------------- /PTA/putil.cpp: -------------------------------------------------------------------------------- 1 | #include "putil.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace 10 | { 11 | HWINEVENTHOOK g_ForegroundHook = nullptr; 12 | HHOOK g_MouseHook = nullptr; 13 | HHOOK g_KeyboardHook = nullptr; 14 | 15 | std::function g_ForegroundHookCb = nullptr; 16 | std::function g_MouseHookCb = nullptr; 17 | std::function g_KeyboardHookCb = nullptr; 18 | } 19 | 20 | namespace pta 21 | { 22 | bool IsPoEForeground() 23 | { 24 | static const std::wstring s_poeCls = L"POEWindowClass"; 25 | 26 | HWND hwnd = GetForegroundWindow(); 27 | 28 | if (nullptr == hwnd) 29 | { 30 | return false; 31 | } 32 | 33 | wchar_t cls[512]; 34 | GetClassName(hwnd, cls, std::size(cls)); 35 | 36 | if (s_poeCls != cls) 37 | { 38 | return false; 39 | } 40 | 41 | return true; 42 | } 43 | 44 | INPUT CreateInput(WORD vk, bool isDown) 45 | { 46 | INPUT input = {}; 47 | input.type = INPUT_KEYBOARD; 48 | input.ki.wVk = vk; 49 | input.ki.wScan = 0; 50 | input.ki.dwFlags = (isDown ? 0 : KEYEVENTF_KEYUP); 51 | input.ki.time = 0; 52 | input.ki.dwExtraInfo = 0; 53 | return input; 54 | } 55 | 56 | namespace hook 57 | { 58 | VOID CALLBACK 59 | ForegroundHookCallback(HWINEVENTHOOK hWinEventHook, DWORD dwEvent, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) 60 | { 61 | if (g_ForegroundHookCb) 62 | { 63 | g_ForegroundHookCb(IsPoEForeground()); 64 | } 65 | } 66 | 67 | LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) 68 | { 69 | if (nCode >= HC_ACTION && g_MouseHookCb && g_MouseHookCb(wParam, lParam)) 70 | { 71 | // consume the input 72 | return -1; 73 | } 74 | 75 | return CallNextHookEx(g_MouseHook, nCode, wParam, lParam); 76 | } 77 | 78 | LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 79 | { 80 | if (nCode >= HC_ACTION && g_KeyboardHookCb && g_KeyboardHookCb(wParam, lParam)) 81 | { 82 | // consume the input 83 | return -1; 84 | } 85 | 86 | return CallNextHookEx(g_KeyboardHook, nCode, wParam, lParam); 87 | } 88 | 89 | void InitializeHooks() 90 | { 91 | g_ForegroundHook = SetWinEventHook( 92 | EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL, ForegroundHookCallback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); 93 | 94 | if (!g_ForegroundHook) 95 | { 96 | qWarning() << "Failed to set foreground event hook. Macros may not work."; 97 | } 98 | 99 | g_MouseHook = SetWindowsHookEx(WH_MOUSE_LL, &LowLevelMouseProc, GetModuleHandle(NULL), NULL); 100 | 101 | if (!g_MouseHook) 102 | { 103 | qWarning() << "Failed to set mouse event hook. Some functions may not work."; 104 | } 105 | 106 | g_KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, GetModuleHandle(NULL), NULL); 107 | 108 | if (!g_KeyboardHook) 109 | { 110 | qWarning() << "Failed to set keyboard event hook. Some functions may not work."; 111 | } 112 | } 113 | 114 | void ShutdownHooks() 115 | { 116 | if (g_ForegroundHook) 117 | { 118 | UnhookWinEvent(g_ForegroundHook); 119 | } 120 | 121 | if (g_MouseHook) 122 | { 123 | UnhookWindowsHookEx(g_MouseHook); 124 | } 125 | 126 | if (g_KeyboardHook) 127 | { 128 | UnhookWindowsHookEx(g_KeyboardHook); 129 | } 130 | } 131 | 132 | void InstallForegroundHookCb(std::function fgcb) 133 | { 134 | if (fgcb) 135 | { 136 | g_ForegroundHookCb = fgcb; 137 | } 138 | } 139 | 140 | void InstallMouseHookCb(std::function cb) 141 | { 142 | if (cb) 143 | { 144 | g_MouseHookCb = cb; 145 | } 146 | } 147 | 148 | void InstallKeyboardHookCb(std::function cb) 149 | { 150 | if (cb) 151 | { 152 | g_KeyboardHookCb = cb; 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /PTA/search/src/App.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 133 | 134 | 197 | -------------------------------------------------------------------------------- /PTA/pitem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using json = nlohmann::json; 6 | using jptr = json::json_pointer; 7 | using Item = json; 8 | 9 | /* 10 | 11 | JSON Item Schema 12 | 13 | { 14 | origtext: string, 15 | rarity: string, 16 | type: string, 17 | name: string, 18 | category: string, 19 | quality: integer, 20 | ilvl: integer, 21 | unidentified: bool, 22 | corrupted: bool, 23 | 24 | influences: ["shaper", "crusader", ...], 25 | 26 | requirements: { 27 | lvl: integer, 28 | str: integer, 29 | dex: integer, 30 | int: integer 31 | }, 32 | 33 | weapon: { 34 | aps: float, 35 | crit: float, 36 | pdps: { 37 | min: integer, 38 | max: integer 39 | }, 40 | edps: { 41 | min: integer, 42 | max: integer 43 | } 44 | }, 45 | 46 | armour: { 47 | ar: integer, 48 | ev: integer, 49 | es: integer, 50 | block: integer 51 | }, 52 | 53 | sockets: { 54 | links: int, 55 | total: int, 56 | R: int, 57 | G: int, 58 | B: int, 59 | W: int, 60 | A: int 61 | }, 62 | 63 | misc: { 64 | disc: string, 65 | synthesis: bool, 66 | gem_level: int, 67 | gem_progress: string, 68 | map_tier: integer 69 | }, 70 | 71 | filters: { 72 | ...PoE mod filters... 73 | }, 74 | 75 | pseudos: { 76 | ...PoE mod filters... 77 | } 78 | 79 | 80 | } 81 | 82 | ********************************* 83 | 84 | JSON Data Schema 85 | 86 | { 87 | item: Item, 88 | 89 | settings: { 90 | ...PTA settings... 91 | } 92 | 93 | searchopts: { 94 | use_pdps: bool, 95 | use_edps: bool, 96 | use_ar: bool, 97 | use_ev: bool, 98 | use_es: bool, 99 | use_sockets: bool, 100 | use_links: bool, 101 | use_ilvl: bool, 102 | use_item_base: bool, 103 | influences: Array 104 | } 105 | } 106 | 107 | */ 108 | 109 | constexpr auto p_enabled = "enabled"; 110 | constexpr auto p_item = "item"; 111 | constexpr auto p_results = "results"; 112 | 113 | constexpr auto p_min = "min"; 114 | constexpr auto p_max = "max"; 115 | 116 | constexpr auto p_origtext = "origtext"; 117 | constexpr auto p_rarity = "rarity"; 118 | constexpr auto p_type = "type"; 119 | constexpr auto p_name = "name"; 120 | constexpr auto p_category = "category"; 121 | constexpr auto p_sockets = "sockets"; 122 | constexpr auto p_quality = "quality"; 123 | constexpr auto p_ilvl = "ilvl"; 124 | constexpr auto p_unidentified = "unidentified"; 125 | constexpr auto p_corrupted = "corrupted"; 126 | constexpr auto p_influences = "influences"; 127 | constexpr auto p_filters = "filters"; 128 | constexpr auto p_pseudos = "pseudos"; 129 | 130 | constexpr auto p_requirements = "requirements"; 131 | inline const auto p_reqlvl = "/requirements/lvl"_json_pointer; 132 | inline const auto p_reqstr = "/requirements/str"_json_pointer; 133 | inline const auto p_reqdex = "/requirements/dex"_json_pointer; 134 | inline const auto p_reqint = "/requirements/int"_json_pointer; 135 | 136 | constexpr auto p_misc = "misc"; 137 | inline const auto p_mdisc = "/misc/disc"_json_pointer; 138 | inline const auto p_msynth = "/misc/synthesis"_json_pointer; 139 | inline const auto p_mglvl = "/misc/gem_level"_json_pointer; 140 | inline const auto p_mgexp = "/misc/gem_progress"_json_pointer; 141 | inline const auto p_mmtier = "/misc/map_tier"_json_pointer; 142 | 143 | constexpr auto p_weapon = "weapon"; 144 | inline const auto p_waps = "/weapon/aps"_json_pointer; 145 | inline const auto p_wcrit = "/weapon/crit"_json_pointer; 146 | inline const auto p_wpdps = "/weapon/pdps"_json_pointer; 147 | inline const auto p_wedps = "/weapon/edps"_json_pointer; 148 | 149 | constexpr auto p_armour = "armour"; 150 | inline const auto p_aar = "/armour/ar"_json_pointer; 151 | inline const auto p_aev = "/armour/ev"_json_pointer; 152 | inline const auto p_aes = "/armour/es"_json_pointer; 153 | inline const auto p_ablock = "/armour/block"_json_pointer; 154 | 155 | constexpr auto p_settings = "settings"; 156 | 157 | constexpr auto p_opts = "searchopts"; 158 | inline const auto p_usepdps = "/searchopts/use_pdps"_json_pointer; 159 | inline const auto p_useedps = "/searchopts/use_edps"_json_pointer; 160 | inline const auto p_usear = "/searchopts/use_ar"_json_pointer; 161 | inline const auto p_useev = "/searchopts/use_ev"_json_pointer; 162 | inline const auto p_usees = "/searchopts/use_es"_json_pointer; 163 | inline const auto p_usesockets = "/searchopts/use_sockets"_json_pointer; 164 | inline const auto p_uselinks = "/searchopts/use_links"_json_pointer; 165 | inline const auto p_useilvl = "/searchopts/use_ilvl"_json_pointer; 166 | inline const auto p_usebase = "/searchopts/use_item_base"_json_pointer; 167 | inline const auto p_useinfluences = "/searchopts/influences"_json_pointer; 168 | inline const auto p_usesynth = "/searchopts/use_synthesis_base"_json_pointer; 169 | inline const auto p_usecorrupted = "/searchopts/use_corrupted"_json_pointer; 170 | -------------------------------------------------------------------------------- /PTA/search/src/components/ResultTab.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 202 | 203 | 212 | -------------------------------------------------------------------------------- /QtMsBuild/qt_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 31 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | 70 | 74 | 75 | 76 | 77 | 78 | 83 | 84 | 85 | 86 | 92 | 98 | 102 | 106 | 113 | 117 | 122 | 123 | 128 | 133 | 138 | 139 | -------------------------------------------------------------------------------- /framelesswindow/framelesswindow.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {2209748B-F881-499B-A1F5-C916D3CD7352} 15 | QtVS_v302 16 | 10.0 17 | $(SolutionDir)QtMsBuild 18 | 19 | 20 | 21 | StaticLibrary 22 | v142 23 | Unicode 24 | 25 | 26 | StaticLibrary 27 | v142 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | C:\Qt\5.12.7\msvc2017_64 48 | core;widgets 49 | 50 | 51 | C:\Qt\5.12.7\msvc2017_64 52 | core;widgets 53 | 54 | 55 | 56 | 57 | 58 | 59 | true 60 | Disabled 61 | ProgramDatabase 62 | MultiThreadedDebugDLL 63 | true 64 | FRAMELESSWINDOW_LIB;BUILD_STATIC;%(PreprocessorDefinitions) 65 | stdcpplatest 66 | 67 | 68 | Windows 69 | $(OutDir)\$(ProjectName).lib 70 | true 71 | 72 | 73 | 74 | 75 | true 76 | ProgramDatabase 77 | MultiThreadedDLL 78 | true 79 | FRAMELESSWINDOW_LIB;BUILD_STATIC;%(PreprocessorDefinitions) 80 | stdcpplatest 81 | 82 | 83 | Windows 84 | $(OutDir)\$(ProjectName).lib 85 | false 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /PTA/macrohandler.cpp: -------------------------------------------------------------------------------- 1 | #include "macrohandler.h" 2 | 3 | #include "clientmonitor.h" 4 | #include "pta_types.h" 5 | #include "putil.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std::placeholders; 15 | 16 | MacroHandler::MacroHandler(ClientMonitor* client, QObject* parent) : QObject(parent), m_client(client) 17 | { 18 | // Setup variables 19 | m_variables.insert("last_whisper", std::bind(&ClientMonitor::getLastWhisperer, m_client)); 20 | 21 | QSettings settings; 22 | 23 | auto macstr = settings.value(PTA_CONFIG_CUSTOM_MACROS).toString().toStdString(); 24 | 25 | if (!macstr.empty()) 26 | { 27 | auto macrolist = json::parse(macstr); 28 | 29 | setMacros(macrolist); 30 | } 31 | } 32 | 33 | void MacroHandler::setMacros(json macrolist) 34 | { 35 | m_macros.clear(); 36 | 37 | m_macrolist = macrolist; 38 | 39 | for (const auto& [k, v] : macrolist.items()) 40 | { 41 | auto key = QString::fromStdString(k); 42 | auto seq = QString::fromStdString(v["sequence"].get()); 43 | 44 | std::unique_ptr macro(new QHotkey(QKeySequence(seq), true)); 45 | 46 | if (!macro->isRegistered()) 47 | { 48 | qWarning() << "Macro" << key << "failed to register"; 49 | } 50 | 51 | qDebug() << "Macro" << key << "Registered:" << macro->isRegistered(); 52 | 53 | connect(macro.get(), &QHotkey::activated, [=]() { handleMacro(key); }); 54 | 55 | m_macros.push_back(std::move(macro)); 56 | } 57 | } 58 | 59 | void MacroHandler::clearMacros() 60 | { 61 | m_macros.clear(); 62 | } 63 | 64 | void MacroHandler::insertKeyPress(std::vector& keystrokes, WORD key) 65 | { 66 | keystrokes.push_back(pta::CreateInput(key, true)); 67 | keystrokes.push_back(pta::CreateInput(key, false)); 68 | } 69 | 70 | void MacroHandler::insertChatCommand(std::vector& keystrokes, std::string command) 71 | { 72 | QGuiApplication::clipboard()->setText(QString::fromStdString(command)); 73 | 74 | // ensure all used keys are up 75 | keystrokes.push_back(pta::CreateInput(VK_MENU, false)); 76 | keystrokes.push_back(pta::CreateInput(VK_CONTROL, false)); 77 | keystrokes.push_back(pta::CreateInput('V', false)); 78 | keystrokes.push_back(pta::CreateInput('A', false)); 79 | keystrokes.push_back(pta::CreateInput(VK_BACK, false)); 80 | 81 | // open chat 82 | insertKeyPress(keystrokes, VK_RETURN); 83 | 84 | // select all and delete 85 | keystrokes.push_back(pta::CreateInput(VK_CONTROL, true)); 86 | keystrokes.push_back(pta::CreateInput('A', true)); 87 | keystrokes.push_back(pta::CreateInput('A', false)); 88 | keystrokes.push_back(pta::CreateInput(VK_CONTROL, false)); 89 | insertKeyPress(keystrokes, VK_BACK); 90 | 91 | // paste command 92 | keystrokes.push_back(pta::CreateInput(VK_CONTROL, true)); 93 | keystrokes.push_back(pta::CreateInput('V', true)); 94 | keystrokes.push_back(pta::CreateInput('V', false)); 95 | keystrokes.push_back(pta::CreateInput(VK_CONTROL, false)); 96 | 97 | // press enter 98 | insertKeyPress(keystrokes, VK_RETURN); 99 | } 100 | 101 | bool MacroHandler::processChatCommand(std::string& command) 102 | { 103 | QString qcmd = QString::fromStdString(command); 104 | 105 | QRegularExpression re("!(\\w+)!"); 106 | QRegularExpressionMatch match = re.match(qcmd); 107 | 108 | if (match.hasMatch()) 109 | { 110 | if (!m_client->enabled()) 111 | { 112 | qWarning() << "Client features unavailable. Please set Client.txt path in settings to enable."; 113 | emit humour(tr("Client features unavailable. Please set Client.txt path in settings to enable.")); 114 | 115 | return false; 116 | } 117 | 118 | QString var = match.captured(1); 119 | 120 | if (!m_variables.contains(var)) 121 | { 122 | qWarning() << "Command variable" << var << "not found."; 123 | emit humour(tr("Command variable not found. See log for more details.")); 124 | 125 | return false; 126 | } 127 | 128 | QString getvar = m_variables[var](); 129 | 130 | if (getvar.isEmpty()) 131 | { 132 | qWarning() << "Failed to retrieve variable" << var << ". Variable returned empty string."; 133 | emit humour(tr("Failed to retrieve variable. See log for more details.")); 134 | return false; 135 | } 136 | 137 | qcmd.replace(re, getvar); 138 | } 139 | 140 | command = qcmd.toStdString(); 141 | 142 | return true; 143 | } 144 | 145 | void MacroHandler::sendChatCommand(std::string command) 146 | { 147 | std::vector keystroke; 148 | 149 | insertChatCommand(keystroke, command); 150 | 151 | // Send input 152 | SendInput(keystroke.size(), keystroke.data(), sizeof(keystroke[0])); 153 | } 154 | 155 | void MacroHandler::handleForegroundChange(bool isPoe) 156 | { 157 | // Gotta do this because hotkeys are consumed by the app :( 158 | for (auto& macro : m_macros) 159 | { 160 | macro->setRegistered(isPoe); 161 | } 162 | } 163 | 164 | void MacroHandler::handleMacro(QString key) 165 | { 166 | if (!pta::IsPoEForeground()) 167 | return; 168 | 169 | auto skey = key.toStdString(); 170 | 171 | if (!m_macrolist.contains(skey)) 172 | { 173 | qWarning() << "Macro" << key << "not found."; 174 | return; 175 | } 176 | 177 | auto& macro = m_macrolist[skey]; 178 | 179 | int type = macro["type"].get(); 180 | auto command = macro["command"].get(); 181 | 182 | switch (type) 183 | { 184 | case MACRO_TYPE_CHAT: 185 | { 186 | if (processChatCommand(command)) 187 | { 188 | sendChatCommand(command); 189 | } 190 | break; 191 | } 192 | 193 | case MACRO_TYPE_URL: 194 | { 195 | QDesktopServices::openUrl(QUrl(QString::fromStdString(command))); 196 | break; 197 | } 198 | 199 | default: 200 | { 201 | qWarning() << "Invalid macro type:" << type; 202 | return; 203 | } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /QtMsBuild/qt_settings_vs2015.xml: -------------------------------------------------------------------------------- 1 | 2 | 31 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | 70 | 71 | 72 | 73 | 77 | 78 | 79 | 80 | 81 | 86 | 87 | 88 | 89 | 95 | 101 | 105 | 109 | 116 | 120 | 125 | 126 | 131 | 136 | 141 | 142 | -------------------------------------------------------------------------------- /QHotkey/QHotkey/qhotkey_x11.cpp: -------------------------------------------------------------------------------- 1 | #include "qhotkey.h" 2 | #include "qhotkey_p.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | //compability to pre Qt 5.8 10 | #ifndef Q_FALLTHROUGH 11 | #define Q_FALLTHROUGH() (void)0 12 | #endif 13 | 14 | class QHotkeyPrivateX11 : public QHotkeyPrivate 15 | { 16 | public: 17 | // QAbstractNativeEventFilter interface 18 | bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; 19 | 20 | protected: 21 | // QHotkeyPrivate interface 22 | quint32 nativeKeycode(Qt::Key keycode, bool &ok) Q_DECL_OVERRIDE; 23 | quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) Q_DECL_OVERRIDE; 24 | QString getX11String(Qt::Key keycode); 25 | bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; 26 | bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; 27 | 28 | private: 29 | static const QVector specialModifiers; 30 | static const quint32 validModsMask; 31 | 32 | static QString formatX11Error(Display *display, int errorCode); 33 | 34 | class HotkeyErrorHandler { 35 | public: 36 | HotkeyErrorHandler(); 37 | ~HotkeyErrorHandler(); 38 | 39 | static bool hasError; 40 | static QString errorString; 41 | 42 | private: 43 | XErrorHandler prevHandler; 44 | 45 | static int handleError(Display *display, XErrorEvent *error); 46 | }; 47 | }; 48 | NATIVE_INSTANCE(QHotkeyPrivateX11) 49 | 50 | const QVector QHotkeyPrivateX11::specialModifiers = {0, Mod2Mask, LockMask, (Mod2Mask | LockMask)}; 51 | const quint32 QHotkeyPrivateX11::validModsMask = ShiftMask | ControlMask | Mod1Mask | Mod4Mask; 52 | 53 | bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *message, long *result) 54 | { 55 | Q_UNUSED(eventType); 56 | Q_UNUSED(result); 57 | 58 | xcb_generic_event_t *genericEvent = static_cast(message); 59 | if (genericEvent->response_type == XCB_KEY_PRESS) { 60 | xcb_key_press_event_t *keyEvent = static_cast(message); 61 | this->activateShortcut({keyEvent->detail, keyEvent->state & QHotkeyPrivateX11::validModsMask}); 62 | } 63 | 64 | return false; 65 | } 66 | 67 | QString QHotkeyPrivateX11::getX11String(Qt::Key keycode) 68 | { 69 | switch(keycode){ 70 | 71 | case Qt::Key_MediaLast : 72 | case Qt::Key_MediaPrevious : 73 | return "XF86AudioPrev"; 74 | case Qt::Key_MediaNext : 75 | return "XF86AudioNext"; 76 | case Qt::Key_MediaPause : 77 | case Qt::Key_MediaPlay : 78 | case Qt::Key_MediaTogglePlayPause : 79 | return "XF86AudioPlay"; 80 | case Qt::Key_MediaRecord : 81 | return "XF86AudioRecord"; 82 | case Qt::Key_MediaStop : 83 | return "XF86AudioStop"; 84 | default : 85 | return QKeySequence(keycode).toString(QKeySequence::NativeText); 86 | } 87 | } 88 | 89 | quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool &ok) 90 | { 91 | QString keyString = getX11String(keycode); 92 | 93 | KeySym keysym = XStringToKeysym(keyString.toLatin1().constData()); 94 | if (keysym == NoSymbol) { 95 | //not found -> just use the key 96 | if(keycode <= 0xFFFF) 97 | keysym = keycode; 98 | else 99 | return 0; 100 | } 101 | 102 | Display *display = QX11Info::display(); 103 | if(display) { 104 | auto res = XKeysymToKeycode(QX11Info::display(), keysym); 105 | if(res != 0) 106 | ok = true; 107 | return res; 108 | } else 109 | return 0; 110 | } 111 | 112 | quint32 QHotkeyPrivateX11::nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) 113 | { 114 | quint32 nMods = 0; 115 | if (modifiers & Qt::ShiftModifier) 116 | nMods |= ShiftMask; 117 | if (modifiers & Qt::ControlModifier) 118 | nMods |= ControlMask; 119 | if (modifiers & Qt::AltModifier) 120 | nMods |= Mod1Mask; 121 | if (modifiers & Qt::MetaModifier) 122 | nMods |= Mod4Mask; 123 | ok = true; 124 | return nMods; 125 | } 126 | 127 | bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) 128 | { 129 | Display *display = QX11Info::display(); 130 | if(!display) 131 | return false; 132 | 133 | HotkeyErrorHandler errorHandler; 134 | for(quint32 specialMod : QHotkeyPrivateX11::specialModifiers) { 135 | XGrabKey(display, 136 | shortcut.key, 137 | shortcut.modifier | specialMod, 138 | DefaultRootWindow(display), 139 | True, 140 | GrabModeAsync, 141 | GrabModeAsync); 142 | } 143 | XSync(display, False); 144 | 145 | if(errorHandler.hasError) { 146 | qCWarning(logQHotkey) << "Failed to register hotkey. Error:" 147 | << qPrintable(errorHandler.errorString); 148 | this->unregisterShortcut(shortcut); 149 | return false; 150 | } else 151 | return true; 152 | } 153 | 154 | bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut) 155 | { 156 | Display *display = QX11Info::display(); 157 | if(!display) 158 | return false; 159 | 160 | HotkeyErrorHandler errorHandler; 161 | for(quint32 specialMod : QHotkeyPrivateX11::specialModifiers) { 162 | XUngrabKey(display, 163 | shortcut.key, 164 | shortcut.modifier | specialMod, 165 | DefaultRootWindow(display)); 166 | } 167 | XSync(display, False); 168 | 169 | if(errorHandler.hasError) { 170 | qCWarning(logQHotkey) << "Failed to unregister hotkey. Error:" 171 | << qPrintable(errorHandler.errorString); 172 | return false; 173 | } else 174 | return true; 175 | } 176 | 177 | QString QHotkeyPrivateX11::formatX11Error(Display *display, int errorCode) 178 | { 179 | char errStr[256]; 180 | XGetErrorText(display, errorCode, errStr, 256); 181 | return QString::fromLatin1(errStr); 182 | } 183 | 184 | 185 | 186 | // ---------- QHotkeyPrivateX11::HotkeyErrorHandler implementation ---------- 187 | 188 | bool QHotkeyPrivateX11::HotkeyErrorHandler::hasError = false; 189 | QString QHotkeyPrivateX11::HotkeyErrorHandler::errorString; 190 | 191 | QHotkeyPrivateX11::HotkeyErrorHandler::HotkeyErrorHandler() 192 | { 193 | prevHandler = XSetErrorHandler(&HotkeyErrorHandler::handleError); 194 | } 195 | 196 | QHotkeyPrivateX11::HotkeyErrorHandler::~HotkeyErrorHandler() 197 | { 198 | XSetErrorHandler(prevHandler); 199 | hasError = false; 200 | errorString.clear(); 201 | } 202 | 203 | int QHotkeyPrivateX11::HotkeyErrorHandler::handleError(Display *display, XErrorEvent *error) 204 | { 205 | switch (error->error_code) { 206 | case BadAccess: 207 | case BadValue: 208 | case BadWindow: 209 | if (error->request_code == 33 || //grab key 210 | error->request_code == 34) {// ungrab key 211 | hasError = true; 212 | errorString = QHotkeyPrivateX11::formatX11Error(display, error->error_code); 213 | return 1; 214 | } 215 | Q_FALLTHROUGH(); 216 | // fall through 217 | default: 218 | return 0; 219 | } 220 | } 221 | --------------------------------------------------------------------------------