diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ccc897..25e2e37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,11 @@ set(BUILD_GUI_DEPS ON) set(BUILD_64 ON CACHE BOOL "Build 64-bit binaries") set(INSTALL_VENDORED_LIBUNBOUND ${STATIC}) set(USE_SINGLE_BUILDDIR ON) +if(UNIX AND NOT APPLE) + set(LINUX_ACTIVATION ON) +else() + set(LINUX_ACTIVATION OFF) +endif() # Are we in debug mode? set(_CMAKE_BUILD_TYPE "") @@ -362,6 +367,11 @@ if(STATIC) endif() endif() +if(LINUX_ACTIVATION) + find_package(Cairo REQUIRED) + find_package(Xfixes REQUIRED) +endif() + # With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that # is fixed in the code (Issue #847), force compiler to be conservative. add_c_flag_if_supported(-fno-strict-aliasing C_SECURITY_FLAGS) diff --git a/cmake/FindCairo.cmake b/cmake/FindCairo.cmake new file mode 100644 index 0000000..cbda752 --- /dev/null +++ b/cmake/FindCairo.cmake @@ -0,0 +1,81 @@ +# - Try to find Cairo +# Once done, this will define +# +# CAIRO_FOUND - system has Cairo +# CAIRO_INCLUDE_DIRS - the Cairo include directories +# CAIRO_LIBRARIES - link these to use Cairo +# +# Copyright (C) 2012 Raphael Kubo da Costa +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FIND_PACKAGE(PkgConfig) +PKG_CHECK_MODULES(PC_CAIRO cairo) # FIXME: After we require CMake 2.8.2 we can pass QUIET to this call. + +FIND_PATH(CAIRO_INCLUDE_DIRS + NAMES cairo.h + HINTS ${PC_CAIRO_INCLUDEDIR} + ${PC_CAIRO_INCLUDE_DIRS} + PATH_SUFFIXES cairo + ) + +FIND_LIBRARY(CAIRO_LIBRARIES + NAMES cairo + HINTS ${PC_CAIRO_LIBDIR} + ${PC_CAIRO_LIBRARY_DIRS} + ) + +IF (CAIRO_INCLUDE_DIRS) + IF (EXISTS "${CAIRO_INCLUDE_DIRS}/cairo-version.h") + FILE(READ "${CAIRO_INCLUDE_DIRS}/cairo-version.h" CAIRO_VERSION_CONTENT) + + STRING(REGEX MATCH "#define +CAIRO_VERSION_MAJOR +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}") + SET(CAIRO_VERSION_MAJOR "${CMAKE_MATCH_1}") + + STRING(REGEX MATCH "#define +CAIRO_VERSION_MINOR +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}") + SET(CAIRO_VERSION_MINOR "${CMAKE_MATCH_1}") + + STRING(REGEX MATCH "#define +CAIRO_VERSION_MICRO +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}") + SET(CAIRO_VERSION_MICRO "${CMAKE_MATCH_1}") + + SET(CAIRO_VERSION "${CAIRO_VERSION_MAJOR}.${CAIRO_VERSION_MINOR}.${CAIRO_VERSION_MICRO}") + ENDIF () +ENDIF () + +# FIXME: Should not be needed anymore once we start depending on CMake 2.8.3 +SET(VERSION_OK TRUE) +IF (Cairo_FIND_VERSION) + IF (Cairo_FIND_VERSION_EXACT) + IF ("${Cairo_FIND_VERSION}" VERSION_EQUAL "${CAIRO_VERSION}") + # FIXME: Use IF (NOT ...) with CMake 2.8.2+ to get rid of the ELSE block + ELSE () + SET(VERSION_OK FALSE) + ENDIF () + ELSE () + IF ("${Cairo_FIND_VERSION}" VERSION_GREATER "${CAIRO_VERSION}") + SET(VERSION_OK FALSE) + ENDIF () + ENDIF () +ENDIF () + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cairo DEFAULT_MSG CAIRO_INCLUDE_DIRS CAIRO_LIBRARIES VERSION_OK) diff --git a/cmake/FindXfixes.cmake b/cmake/FindXfixes.cmake new file mode 100644 index 0000000..6bb6d6e --- /dev/null +++ b/cmake/FindXfixes.cmake @@ -0,0 +1,26 @@ +# - Find XFixes +# Find the XFixes libraries +# +# This module defines the following variables: +# XFIXES_FOUND - 1 if XFIXES_INCLUDE_DIR & XFIXES_LIBRARY are found, 0 otherwise +# XFIXES_INCLUDE_DIR - where to find Xlib.h, etc. +# XFIXES_LIBRARY - the X11 library +# + +find_path( XFIXES_INCLUDE_DIR + NAMES X11/extensions/Xfixes.h + PATH_SUFFIXES X11/extensions + DOC "The XFixes include directory" ) + +find_library( XFIXES_LIBRARY + NAMES Xfixes + PATHS /usr/lib /lib + DOC "The XFixes library" ) + +if( XFIXES_INCLUDE_DIR AND XFIXES_LIBRARY ) + set( XFIXES_FOUND 1 ) +else() + set( XFIXES_FOUND 0 ) +endif() + +mark_as_advanced( XFIXES_INCLUDE_DIR XFIXES_LIBRARY ) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f5325e..0a57784 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -152,6 +152,13 @@ target_include_directories(wowlet PUBLIC ${Qt5WebSockets_INCLUDE_DIRS} ) +if(LINUX_ACTIVATION) + target_include_directories(wowlet PUBLIC + ${CAIRO_INCLUDE_DIRS} + ${XFIXES_INCLUDE_DIR} + ) +endif() + if(OPENVR) target_include_directories(wowlet PUBLIC ${CMAKE_SOURCE_DIR}/contrib/) endif() @@ -181,8 +188,8 @@ if(STATIC) target_compile_definitions(wowlet PRIVATE STATIC=1) endif() -if(STATIC) - target_compile_definitions(wowlet PRIVATE STATIC=1) +if(LINUX_ACTIVATION) + target_compile_definitions(wowlet PRIVATE LINUX_ACTIVATION=1) endif() if("$ENV{DRONE}" STREQUAL "true") @@ -290,6 +297,15 @@ target_link_libraries(wowlet PUBLIC ${QRENCODE_LIBRARY} ) +# Link Cairo and Xfixes +if(LINUX_ACTIVATION) + target_link_libraries(wowlet PUBLIC + ${CAIRO_LIBRARIES} + ${XFIXES_LIBRARY} + ${X11_Xinerama_LIB} + ) +endif() + # Link scanner if(WITH_SCANNER) target_link_libraries(wowlet PUBLIC qrdecoder qrscanner) @@ -367,12 +383,26 @@ message(STATUS "[+] Include Valve's OpenVR library: ${OPENVR}") message(STATUS "[+] This build is for Android: ${ANDROID}") message(STATUS "[+] This build is for testing the Android app on desktop: ${ANDROID_DEBUG}") message(STATUS "[+] TOR_BIN: ${TOR_BIN}") +message(STATUS "[+] LINUX_ACTIVATION: ${LINUX_ACTIVATION}") message(STATUS "[+] OpenSSL") message(STATUS " - version: ${OPENSSL_VERSION}") message(STATUS " - dirs: ${OPENSSL_INCLUDE_DIR}") message(STATUS " - libs: ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}") +if(CAIRO_FOUND) + message(STATUS "[+] Cairo") + message(STATUS " - version: ${CAIRO_VERSION}") + message(STATUS " - dirs: ${CAIRO_INCLUDE_DIRS}") + message(STATUS " - libs: ${CAIRO_LIBRARIES}") +endif() + +if(XFIXES_FOUND) + message(STATUS "[+] Xfixes") + message(STATUS " - dirs: ${XFIXES_INCLUDE_DIR}") + message(STATUS " - libs: ${XFIXES_LIBRARY}") +endif() + message(STATUS "[+] Boost") message(STATUS " - version: ${Boost_VERSION}") message(STATUS " - dirs: ${Boost_INCLUDE_DIRS}") diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 89c32df..eb83229 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include "globals.h" #include "config-wowlet.h" #include "utils/ColorScheme.h" +#include "utils/activate_linux.h" // libwalletqt #include "libwalletqt/AddressBook.h" @@ -359,6 +361,13 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) : m_touchbarWizardItems = {m_touchbarActionWelcome}; #endif +#ifdef LINUX_ACTIVATION + // Linux activation kek + auto activatedSerial = config()->get(Config::LinuxActivated).toString(); + if(activatedSerial.isEmpty()) + LinuxActivator::start(); +#endif + // setup some UI this->initMain(); this->initWidgets(); diff --git a/src/settings.cpp b/src/settings.cpp index ed0cfc8..ec91267 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -3,9 +3,12 @@ #include "settings.h" #include "ui_settings.h" + #include "mainwindow.h" +#include "utils/activate_linux.h" #include +#include Settings::Settings(QWidget *parent) : QDialog(parent), @@ -83,6 +86,41 @@ Settings::Settings(QWidget *parent) : ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir); }); +#ifdef LINUX_ACTIVATION + // Setup activation tab + auto activatedSerial = config()->get(Config::LinuxActivated).toString(); + if(!activatedSerial.isEmpty()) { + ui->serialEdit->setText(activatedSerial); + ui->label_license->setText("Paid"); + ui->serialEdit->setEnabled(false); + ui->btn_serialKey->setEnabled(false); + ui->frameActivationHelp->hide(); + } + + ui->labelActivationText->setTextFormat(Qt::RichText); + + // activation check + connect(ui->btn_serialKey, &QPushButton::clicked, [this] { + auto serial = ui->serialEdit->text(); + if(LinuxActivator::activate(serial)) { + ui->serialEdit->setText(serial); + ui->label_license->setText("Paid"); + ui->serialEdit->setEnabled(false); + ui->btn_serialKey->setEnabled(false); + ui->frameActivationHelp->hide(); + + QMessageBox::information(this, "Thanks", + "Thank you for purchasing a WOWlet license! The funds " + "will go straight into our coke & hookers fund. \n\n" + "Restart WOWlet to get rid of the watermark in the " + "bottom right corner."); + } else { + QMessageBox::warning(this, "Warning", "Bad serial!"); + } + }); +#else + ui->tabWidget->setTabVisible(5, false); +#endif this->adjustSize(); } diff --git a/src/settings.ui b/src/settings.ui index f8bc787..04f6c14 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -558,6 +558,133 @@ + + + Activation + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + <html><head/><body><p>Please support the development team by upgrading to a paid WOWlet subscription. </p><p>You will get access to: the dankest memes, a better built-in miner, faster startup times, and embarrassing pictures of jwinterm!</p><p>Side-note: <a href="https://forum.wownero.com/t/free-wowlet-license-keys/1294"><span style=" text-decoration: underline; color:#0000ff;">we condone the piracy of licenses</span></a></p><p>Thanks in advance.</p></body></html> + + + true + + + true + + + Qt::TextBrowserInteraction + + + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + + + + + + + + Subscription License: + + + + + + + + 75 + true + + + + Skint + + + + + + + + + + Serial key: + + + + + + + Submit serial key + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + diff --git a/src/utils/activate_linux.cpp b/src/utils/activate_linux.cpp new file mode 100644 index 0000000..1f8e82c --- /dev/null +++ b/src/utils/activate_linux.cpp @@ -0,0 +1,176 @@ +#ifdef LINUX_ACTIVATION + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "activate_linux.h" +#include "utils/config.h" + +namespace LinuxActivator +{ + bool activate(QString &serial) { + auto isActivated = config()->get(Config::LinuxActivated).toString(); + if(!isActivated.isEmpty()) + return true; + + QStringList serials{ + "bd898635-6fbe-4cc8-bf50-adee9f76f091", + "6c153b1c-da23-41cf-a606-8888436d4efb", + "b8962f75-35fd-4237-9732-dd14eb9c71c7", + "6f5f8449-efab-4666-86a5-a25da0c6c5bd", + "5ef5e95b-a1ef-489a-9583-6cdb0b369ff4", + "a055609a-7873-42fe-9644-f6261d32fa57", + "772f7941-0d1c-4158-9c09-701198e71dff", + "d7f9c0d0-6361-4145-831f-490d396bb30f", + "68aa6270-7765-437d-8aab-e09c56b9f897", + "7f7e2aef-96a4-4420-b0d8-86135019fcc2" + }; + + serial = serial.trimmed(); + if(serials.contains(serial)) { + config()->set(Config::LinuxActivated, serial); + return true; + } + return false; + } + + // fire & forget + void start() { + QRect rec = QApplication::desktop()->screenGeometry(); + std::thread([rec](){ + const short height = rec.height(); + const short width = rec.width(); + LinuxActivator::show(width, height); + }).detach(); + } + + // draw text + void draw(cairo_t *cr, const char *title, const char *subtitle, float scale) { + //set color + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4); + + // set font size, and scale up or down + cairo_set_font_size(cr, 24 * scale); + cairo_move_to(cr, 20, 30 * scale); + cairo_show_text(cr, title); + + cairo_set_font_size(cr, 16 * scale); + cairo_move_to(cr, 20, 55 * scale); + cairo_show_text(cr, subtitle); + } + + int show(const short width, const short height) { + Display *d = XOpenDisplay(NULL); + Window root = DefaultRootWindow(d); + int default_screen = XDefaultScreen(d); + + char const *title = "Activate Wownero"; + char const *subtitle = "Go to Settings to hacktivate Wownero."; + + // default scale + float scale = 1.0f; + if(width >= 2560) { + scale = 1.2f; + } else if(width >= 3440) { + scale = 1.5f; + } + + int overlay_width = 380; + int overlay_height = 120; + overlay_height *= scale; + overlay_width *= scale; + + XSetWindowAttributes attrs; + attrs.override_redirect = 1; + + XVisualInfo vinfo; + int colorDepth = 32; + + if (!XMatchVisualInfo(d, default_screen, colorDepth, TrueColor, &vinfo)) { + printf("Activate linux: no visual found supporting 32 bit color, terminating\n"); + exit(EXIT_FAILURE); + } + + // sets 32 bit color depth + attrs.colormap = XCreateColormap(d, root, vinfo.visual, AllocNone); + attrs.background_pixel = 0; + attrs.border_pixel = 0; + + Window overlay; + cairo_surface_t *surface; + cairo_t *cairo_ctx; + + overlay = XCreateWindow( + d, // display + root, // parent + width - overlay_width, // x position + height - overlay_height, // y position + overlay_width, // width + overlay_height, // height + 0, // border width + vinfo.depth, // depth + InputOutput, // class + vinfo.visual, // visual + CWOverrideRedirect | // value mask + CWColormap | + CWBackPixel | + CWBorderPixel, + &attrs // attributes + ); + XMapWindow(d, overlay); + + // allows the mouse to click through the overlay + XRectangle rect; + XserverRegion region = XFixesCreateRegion(d, &rect, 1); + XFixesSetWindowShapeRegion(d, overlay, ShapeInput, 0, 0, region); + XFixesDestroyRegion(d, region); + + // sets a WM_CLASS to allow the user to blacklist some effect from compositor + XClassHint *xch = XAllocClassHint(); + xch->res_name = "activate-linux"; + xch->res_class = "activate-linux"; + XSetClassHint(d, overlay, xch); + + // cairo context + surface = cairo_xlib_surface_create(d, overlay, vinfo.visual, overlay_width, overlay_height); + cairo_ctx = cairo_create(surface); + draw(cairo_ctx, title, subtitle, scale); + + // wait for X events forever + XEvent event; + while(1) { + XNextEvent(d, &event); + } + + // free used resources + XUnmapWindow(d, overlay); + cairo_destroy(cairo_ctx); + cairo_surface_destroy(surface); + + XCloseDisplay(d); + return 0; + } +} + +#endif \ No newline at end of file diff --git a/src/utils/activate_linux.h b/src/utils/activate_linux.h new file mode 100644 index 0000000..4983bbd --- /dev/null +++ b/src/utils/activate_linux.h @@ -0,0 +1,16 @@ +#ifndef ACTIVATE_LINUX_H +#define ACTIVATE_LINUX_H + +#ifdef LINUX_ACTIVATION +#include +#include + +namespace LinuxActivator { + bool activate(QString &serial); + void start(); + void draw(cairo_t *cr, const char *title, const char *subtitle, float scale); + int show(short width, short height); +} +#endif + +#endif // ACTIVATE_LINUX_H diff --git a/src/utils/config.cpp b/src/utils/config.cpp index ea90c53..ad7e113 100644 --- a/src/utils/config.cpp +++ b/src/utils/config.cpp @@ -50,7 +50,8 @@ static const QHash configStrings = { {Config::redditFrontend, {QS("redditFrontend"), "old.reddit.com"}}, {Config::showHistorySyncNotice, {QS("showHistorySyncNotice"), true}}, {Config::ignoreUpdateWarning, {QS("ignoreUpdateWarning"), ""}}, - {Config::suchWowTipAmount, {QS("suchWowTipAmount"), 0.75}} + {Config::suchWowTipAmount, {QS("suchWowTipAmount"), 0.75}}, + {Config::LinuxActivated, {QS("linuxActivated"), ""}} }; diff --git a/src/utils/config.h b/src/utils/config.h index 6e75adc..92f1335 100644 --- a/src/utils/config.h +++ b/src/utils/config.h @@ -52,7 +52,8 @@ public: redditFrontend, showHistorySyncNotice, ignoreUpdateWarning, - suchWowTipAmount + suchWowTipAmount, + LinuxActivated }; ~Config() override;