kopia lustrzana https://github.com/jameshball/osci-render
Add license key checking and registration
rodzic
1b4b826763
commit
b7da40b90c
|
@ -35,7 +35,7 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
|
|||
}
|
||||
}
|
||||
|
||||
addAndMakeVisible(visualiser);
|
||||
addChildComponent(visualiser);
|
||||
|
||||
int width = std::any_cast<int>(audioProcessor.getProperty("appWidth", defaultWidth));
|
||||
int height = std::any_cast<int>(audioProcessor.getProperty("appHeight", defaultHeight));
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "components/SvgButton.h"
|
||||
#include "components/VolumeComponent.h"
|
||||
#include "components/DownloaderComponent.h"
|
||||
#include "components/LicenseRegistrationComponent.h"
|
||||
|
||||
class CommonPluginEditor : public juce::AudioProcessorEditor {
|
||||
public:
|
||||
|
@ -68,11 +69,12 @@ public:
|
|||
VolumeComponent volume{audioProcessor};
|
||||
|
||||
std::unique_ptr<juce::FileChooser> chooser;
|
||||
juce::MenuBarComponent menuBar;
|
||||
|
||||
juce::TooltipWindow tooltipWindow{nullptr, 0};
|
||||
juce::MenuBarComponent menuBar; juce::TooltipWindow tooltipWindow{nullptr, 0};
|
||||
juce::DropShadower tooltipDropShadow{juce::DropShadow(juce::Colours::black.withAlpha(0.5f), 6, {0,0})};
|
||||
|
||||
LicenseRegistrationComponent licenseRegistration {audioProcessor, [this](bool success) {
|
||||
visualiser.setVisible(success);
|
||||
}};
|
||||
bool usingNativeMenuBar = false;
|
||||
|
||||
#if JUCE_LINUX
|
||||
|
|
|
@ -124,7 +124,7 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
|||
BooleanParameter* visualiserFullScreen = audioProcessor.visualiserParameters.visualiserFullScreen;
|
||||
pluginEditor.visualiser.setFullScreen(visualiserFullScreen->getBoolValue());
|
||||
|
||||
addAndMakeVisible(pluginEditor.visualiser);
|
||||
addChildComponent(pluginEditor.visualiser);
|
||||
pluginEditor.visualiser.setFullScreenCallback([this, visualiserFullScreen](FullScreenMode mode) {
|
||||
if (mode == FullScreenMode::TOGGLE) {
|
||||
visualiserFullScreen->setBoolValueNotifyingHost(!visualiserFullScreen->getBoolValue());
|
||||
|
|
|
@ -77,7 +77,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
|||
|
||||
addAndMakeVisible(lua);
|
||||
addAndMakeVisible(luaResizerBar);
|
||||
addAndMakeVisible(visualiser);
|
||||
addChildComponent(visualiser);
|
||||
|
||||
visualiser.openSettings = [this] {
|
||||
openVisualiserSettings();
|
||||
|
@ -95,6 +95,9 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
|||
#endif
|
||||
|
||||
initialiseMenuBar(model);
|
||||
|
||||
addAndMakeVisible(licenseRegistration);
|
||||
licenseRegistration.toFront(true);
|
||||
}
|
||||
|
||||
OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() {
|
||||
|
@ -183,6 +186,8 @@ void OscirenderAudioProcessorEditor::resized() {
|
|||
CommonPluginEditor::resized();
|
||||
|
||||
auto area = getLocalBounds();
|
||||
|
||||
licenseRegistration.setBounds(area);
|
||||
|
||||
if (audioProcessor.visualiserParameters.visualiserFullScreen->getBoolValue()) {
|
||||
visualiser.setBounds(area);
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
#include "LicenseRegistrationComponent.h"
|
||||
|
||||
LicenseRegistrationComponent::LicenseRegistrationComponent(CommonAudioProcessor& processor, std::function<void(bool)> onLicenseVerified)
|
||||
: audioProcessor(processor), onLicenseVerified(onLicenseVerified)
|
||||
{
|
||||
setupComponents();
|
||||
|
||||
// If we have a saved license, validate it in the background
|
||||
if (validateSavedLicense())
|
||||
{
|
||||
// Use Timer to ensure component is properly initialized before hiding
|
||||
juce::MessageManager::callAsync([this]() {
|
||||
setVisible(false);
|
||||
});
|
||||
// Start periodic checks every hour
|
||||
startTimer(1000 * 60 * 60);
|
||||
}
|
||||
}
|
||||
|
||||
LicenseRegistrationComponent::~LicenseRegistrationComponent()
|
||||
{
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
void LicenseRegistrationComponent::setupComponents()
|
||||
{
|
||||
titleLabel.setText("License Registration Required", juce::dontSendNotification);
|
||||
titleLabel.setFont(juce::Font(24.0f, juce::Font::bold));
|
||||
titleLabel.setJustificationType(juce::Justification::centred);
|
||||
addAndMakeVisible(titleLabel);
|
||||
|
||||
instructionsLabel.setText("Please enter your license key to continue", juce::dontSendNotification);
|
||||
instructionsLabel.setJustificationType(juce::Justification::centred);
|
||||
instructionsLabel.setFont(juce::Font(18.0f));
|
||||
addAndMakeVisible(instructionsLabel);
|
||||
|
||||
licenseKeyEditor.setTextToShowWhenEmpty("XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX", juce::Colours::grey);
|
||||
licenseKeyEditor.setInputRestrictions(35, "0123456789ABCDEF-"); // Only allow hex digits and hyphens
|
||||
licenseKeyEditor.onReturnKey = [this] { verifyButton.triggerClick(); };
|
||||
licenseKeyEditor.setFont(juce::Font(24.0f));
|
||||
addAndMakeVisible(licenseKeyEditor);
|
||||
|
||||
verifyButton.setButtonText("Verify License");
|
||||
verifyButton.onClick = [this] {
|
||||
if (!isVerifying)
|
||||
{
|
||||
verifyLicense(licenseKeyEditor.getText());
|
||||
}
|
||||
};
|
||||
addAndMakeVisible(verifyButton);
|
||||
}
|
||||
|
||||
void LicenseRegistrationComponent::paint(juce::Graphics& g)
|
||||
{
|
||||
g.fillAll(juce::Colours::black.withAlpha(0.9f));
|
||||
|
||||
auto bounds = getLocalBounds().toFloat();
|
||||
}
|
||||
|
||||
void LicenseRegistrationComponent::resized()
|
||||
{
|
||||
auto bounds = getLocalBounds().reduced(20);
|
||||
|
||||
titleLabel.setBounds(bounds.removeFromTop(40));
|
||||
bounds.removeFromTop(20);
|
||||
|
||||
instructionsLabel.setBounds(bounds.removeFromTop(30));
|
||||
bounds.removeFromTop(20);
|
||||
|
||||
auto row = bounds.removeFromTop(35);
|
||||
licenseKeyEditor.setBounds(row.reduced(50, 0));
|
||||
bounds.removeFromTop(20);
|
||||
|
||||
verifyButton.setBounds(bounds.removeFromTop(40).withSizeKeepingCentre(120, 40));
|
||||
}
|
||||
|
||||
void LicenseRegistrationComponent::verifyLicense(const juce::String& licenseKey, bool showErrorDialog)
|
||||
{
|
||||
if (licenseKey.isEmpty())
|
||||
return;
|
||||
|
||||
isVerifying = true;
|
||||
verifyButton.setEnabled(false);
|
||||
|
||||
juce::URL url("https://api.osci-render.com/api/verify-license");
|
||||
|
||||
auto jsonObj = std::make_unique<juce::DynamicObject>();
|
||||
jsonObj->setProperty("license_key", licenseKey);
|
||||
juce::var jsonData(jsonObj.release());
|
||||
|
||||
url = url.withPOSTData(juce::JSON::toString(jsonData));
|
||||
|
||||
auto webStream = url.createInputStream(false, nullptr, nullptr,
|
||||
"Content-Type: application/json",
|
||||
10000);
|
||||
|
||||
bool successfullyVerified = false;
|
||||
|
||||
if (webStream != nullptr)
|
||||
{
|
||||
auto response = webStream->readEntireStreamAsString();
|
||||
DBG(response);
|
||||
auto json = juce::JSON::parse(response);
|
||||
|
||||
if (json.hasProperty("success")) {
|
||||
bool success = json["success"];
|
||||
|
||||
if (success && json.hasProperty("valid") && json.hasProperty("purchase")) {
|
||||
bool valid = json["valid"];
|
||||
|
||||
auto purchase = json["purchase"].getDynamicObject();
|
||||
auto productId = purchase->getProperty("product_id").toString();
|
||||
|
||||
if (success && valid && productId == SOSCI_PRODUCT_ID)
|
||||
{
|
||||
// Save the license key and validation timestamp
|
||||
audioProcessor.setGlobalValue("license_key", licenseKey);
|
||||
audioProcessor.setGlobalValue("license_last_validated", juce::Time::getCurrentTime().toISO8601(true));
|
||||
audioProcessor.saveGlobalSettings();
|
||||
|
||||
successfullyVerified = true;
|
||||
|
||||
setVisible(false);
|
||||
startTimer(1000 * 60 * 60); // Check every hour
|
||||
}
|
||||
else if (showErrorDialog)
|
||||
{
|
||||
juce::AlertWindow::showMessageBoxAsync(juce::AlertWindow::WarningIcon,
|
||||
"Invalid License",
|
||||
"The license key you entered is not valid. Please check and try again.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Background check failed, clear the license
|
||||
clearLicense();
|
||||
}
|
||||
} else if (showErrorDialog && json.hasProperty("message")) {
|
||||
auto message = json["message"].toString();
|
||||
juce::AlertWindow::showMessageBoxAsync(juce::AlertWindow::WarningIcon, "Error", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (showErrorDialog)
|
||||
{
|
||||
juce::AlertWindow::showMessageBoxAsync(juce::AlertWindow::WarningIcon,
|
||||
"Connection Error",
|
||||
"Could not connect to the license server. Please check your internet connection and try again.");
|
||||
}
|
||||
|
||||
isVerifying = false;
|
||||
verifyButton.setEnabled(true);
|
||||
|
||||
if (onLicenseVerified != nullptr) {
|
||||
onLicenseVerified(successfullyVerified);
|
||||
}
|
||||
}
|
||||
|
||||
bool LicenseRegistrationComponent::validateSavedLicense()
|
||||
{
|
||||
auto savedKey = audioProcessor.getGlobalStringValue("license_key");
|
||||
if (savedKey.isNotEmpty())
|
||||
{
|
||||
auto lastValidated = audioProcessor.getGlobalStringValue("license_last_validated");
|
||||
if (lastValidated.isNotEmpty())
|
||||
{
|
||||
// Verify in the background without showing error dialogs
|
||||
verifyLicense(savedKey, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LicenseRegistrationComponent::clearLicense()
|
||||
{
|
||||
audioProcessor.removeGlobalValue("license_key");
|
||||
audioProcessor.removeGlobalValue("license_last_validated");
|
||||
audioProcessor.saveGlobalSettings();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
void LicenseRegistrationComponent::timerCallback()
|
||||
{
|
||||
auto savedKey = audioProcessor.getGlobalStringValue("license_key");
|
||||
if (savedKey.isNotEmpty()) {
|
||||
verifyLicense(savedKey, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "../CommonPluginProcessor.h"
|
||||
|
||||
class LicenseRegistrationComponent : public juce::Component,
|
||||
public juce::Timer
|
||||
{
|
||||
public:
|
||||
LicenseRegistrationComponent(CommonAudioProcessor& processor, std::function<void(bool)> onLicenseVerified);
|
||||
~LicenseRegistrationComponent() override;
|
||||
|
||||
void paint(juce::Graphics& g) override;
|
||||
void resized() override;
|
||||
|
||||
// Timer callback for background license verification
|
||||
void timerCallback() override;
|
||||
|
||||
private:
|
||||
void verifyLicense(const juce::String& licenseKey, bool showErrorDialog = true);
|
||||
bool validateSavedLicense();
|
||||
void clearLicense();
|
||||
void setupComponents();
|
||||
|
||||
CommonAudioProcessor& audioProcessor;
|
||||
juce::Label titleLabel;
|
||||
juce::Label instructionsLabel;
|
||||
juce::TextEditor licenseKeyEditor;
|
||||
juce::TextButton verifyButton;
|
||||
bool isVerifying = false;
|
||||
|
||||
const juce::String SOSCI_PRODUCT_ID = "Hsr9C58_YhTxYP0MNvsIow==";
|
||||
|
||||
std::function<void(bool)> onLicenseVerified;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LicenseRegistrationComponent)
|
||||
};
|
|
@ -184,6 +184,10 @@
|
|||
file="Source/components/ErrorCodeEditorComponent.h"/>
|
||||
<FILE id="L9DIT2" name="LabelledTextBox.h" compile="0" resource="0"
|
||||
file="Source/components/LabelledTextBox.h"/>
|
||||
<FILE id="mp7cFK" name="LicenseRegistrationComponent.cpp" compile="1"
|
||||
resource="0" file="Source/components/LicenseRegistrationComponent.cpp"/>
|
||||
<FILE id="eW7t3h" name="LicenseRegistrationComponent.h" compile="0"
|
||||
resource="0" file="Source/components/LicenseRegistrationComponent.h"/>
|
||||
<FILE id="tpNWJ3" name="LuaConsole.cpp" compile="1" resource="0" file="Source/components/LuaConsole.cpp"/>
|
||||
<FILE id="e3ZteP" name="LuaConsole.h" compile="0" resource="0" file="Source/components/LuaConsole.h"/>
|
||||
<FILE id="qIxm1z" name="LuaListComponent.cpp" compile="1" resource="0"
|
||||
|
|
|
@ -134,6 +134,10 @@
|
|||
file="Source/components/EffectComponent.cpp"/>
|
||||
<FILE id="u4UCwb" name="EffectComponent.h" compile="0" resource="0"
|
||||
file="Source/components/EffectComponent.h"/>
|
||||
<FILE id="GPZ9q4" name="LicenseRegistrationComponent.cpp" compile="1"
|
||||
resource="0" file="Source/components/LicenseRegistrationComponent.cpp"/>
|
||||
<FILE id="JcXyLX" name="LicenseRegistrationComponent.h" compile="0"
|
||||
resource="0" file="Source/components/LicenseRegistrationComponent.h"/>
|
||||
<FILE id="ka6rAh" name="MainMenuBarModel.cpp" compile="1" resource="0"
|
||||
file="Source/components/MainMenuBarModel.cpp"/>
|
||||
<FILE id="t6oUhv" name="MainMenuBarModel.h" compile="0" resource="0"
|
||||
|
|
Ładowanie…
Reference in New Issue