Skip to content

Commit

Permalink
Updated SampleWithLicensing
Browse files Browse the repository at this point in the history
  • Loading branch information
dalefugier committed Jan 24, 2018
1 parent 7bb071e commit d4dff9b
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 121 deletions.
43 changes: 25 additions & 18 deletions cpp/SampleWithLicensing/SampleWithLicensingPlugIn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,28 @@ RHINO_PLUG_IN_UPDATE_URL(L"https://github.com/mcneel/rhino-developer-samples");
// The one and only CSampleWithLicensingPlugIn object
static CSampleWithLicensingPlugIn thePlugIn;

static CRhinoPlugIn::license_capabilities g_capabilities = (
CRhinoPlugIn::license_capabilities)(CRhinoPlugIn::license_capabilities::can_be_evaluated
| CRhinoPlugIn::license_capabilities::can_be_purchased
| CRhinoPlugIn::license_capabilities::can_be_specified
//| CRhinoPlugIn::license_capabilities::supports_rhino_accounts
);
/////////////////////////////////////////////////////////////////////////////
// CSampleWithLicensingPlugIn licensing info

// When prompted for a license, the use interface will use this text
// mask to assist the user in entering the correct code.
static wchar_t* g_text_mask = L"AAAAAAAA-AAA-AAA";

// The UUID used by this plug0in to request a license.
// {FBDC82F8-578C-4DD7-827C-51B8C3DA7BD1}
static const GUID g_license_id =
{ 0xfbdc82f8, 0x578c, 0x4dd7,{ 0x82, 0x7c, 0x51, 0xb8, 0xc3, 0xda, 0x7b, 0xd1 } };

// Our plug-in's license capabilities
static CRhinoPlugIn::license_capabilities g_capabilities = (CRhinoPlugIn::license_capabilities)
(
CRhinoPlugIn::license_capabilities::can_be_evaluated
| CRhinoPlugIn::license_capabilities::can_be_purchased
| CRhinoPlugIn::license_capabilities::can_be_specified
// This sample current does not support Rhino accounts.
//| CRhinoPlugIn::license_capabilities::supports_rhino_accounts
);

static wchar_t* g_text_mask = L"AAAAAAA-AAA-AAA";

/////////////////////////////////////////////////////////////////////////////
// CSampleWithLicensingPlugIn definition
Expand All @@ -62,41 +76,34 @@ CSampleWithLicensingPlugIn& SampleWithLicensingPlugIn()

CSampleWithLicensingPlugIn::CSampleWithLicensingPlugIn()
{
// TODO: Add construction code here
m_plugin_version = RhinoPlugInVersion();
}

CSampleWithLicensingPlugIn::~CSampleWithLicensingPlugIn()
{
// TODO: Add destruction code here
}

/////////////////////////////////////////////////////////////////////////////
// Required overrides

const wchar_t* CSampleWithLicensingPlugIn::PlugInName() const
{
// TODO: Return a short, friendly name for the plug-in.
return RhinoPlugInName();
}

const wchar_t* CSampleWithLicensingPlugIn::PlugInVersion() const
{
// TODO: Return the version number of the plug-in.
return m_plugin_version;
}

GUID CSampleWithLicensingPlugIn::PlugInID() const
{
// TODO: Return a unique identifier for the plug-in.
// {1F88325E-FA51-4B61-B3AC-27B589B70670}
return ON_UuidFromString(RhinoPlugInId());
}

BOOL CSampleWithLicensingPlugIn::OnLoadPlugIn()
{
SetLicenseCapabilities(g_text_mask, g_capabilities, ON_UuidFromString(L"1ABD5EFC-2C65-11D7-B6F7-0050BABF6BC2"));

// Before requesting a license, we must inform the license
// manager what we are capable of supporting.
SetLicenseCapabilities(g_text_mask, g_capabilities, g_license_id);

// Ask Rhino to get a product license for us.
bool rc = GetLicense();
if (!rc)
Expand Down
2 changes: 1 addition & 1 deletion cpp/SampleWithLicensing/SampleWithLicensingPlugIn.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class CSampleWithLicensingPlugIn : public CRhinoUtilityPlugIn
{
public:
CSampleWithLicensingPlugIn();
~CSampleWithLicensingPlugIn();
~CSampleWithLicensingPlugIn() = default;

// Required overrides
const wchar_t* PlugInName() const;
Expand Down
195 changes: 99 additions & 96 deletions cpp/SampleWithLicensing/SampleWithLicensingValidator.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "stdafx.h"
#include "SampleWithLicensingPlugIn.h"
#include "resource.h"

////////////////////////////////////////////////////////////////
Expand All @@ -16,7 +17,7 @@ class CSampleWithLicensingValidator : public CRhinoLicenseValidator
// Returns the 'build' type of this plug-in
CRhinoLicenseValidator::product_build_type ProductBuildType() override;

// Obsolete
// This member is obsolete.
CRhinoLicenseValidator::result ValidateProductKey(const wchar_t* product_key) override;

// This member is called by Rhino, from CRhinoPlugIn::GetLicense(), when it
Expand All @@ -31,146 +32,148 @@ class CSampleWithLicensingValidator : public CRhinoLicenseValidator
// Called by Rhino, from CRhinoPlugIn::GetLicense(), after a call to VerifyLicenseKey that
// sets m_requires_previous_version_license_verification to true.
bool VerifyPreviousVersionLicense(
const wchar_t* license,
const wchar_t* previousVersionLicense
const wchar_t* licenseKey,
const wchar_t* previousVersionLicenseKey
) override;

// When Rhino Accounts gets a new lease, this function is called.
void OnLeaseChanged(CRhinoLeaseChangedEventArgs&) override;

private:
ON_wString Reverse(const wchar_t* input);
bool ValidateSampleLicenseKey(const wchar_t* licenseKey);
};

// The one and only CSampleWithLicensingValidator object
static class CSampleWithLicensingValidator theSampleWithLicensingValidator;

// Class constructor
CSampleWithLicensingValidator::CSampleWithLicensingValidator()
{
m_requires_online_validation = true;
m_date_to_expire = 0.0;
m_license_count = 1;
}

// Return the 'build' type of this plug-in
CRhinoLicenseValidator::product_build_type CSampleWithLicensingValidator::ProductBuildType()
{
return CRhinoLicenseValidator::release_build;
}

// This member is obsolete.
CRhinoLicenseValidator::result CSampleWithLicensingValidator::ValidateProductKey(const wchar_t* product_key)
{
return CRhinoLicenseValidator::result::error_show_message;
}

// This member is called by Rhino, from CRhinoPlugIn::GetLicense(), when it
// needs your plug-in to validate your product key or license.
CRhinoLicenseValidator::result CSampleWithLicensingValidator::VerifyLicenseKey(
const wchar_t* licenseKey,
const wchar_t* validationCode,
const double validationCodeInstalledDate,
bool gracePeriodExpired
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

if (nullptr == product_key || 0 == product_key[0])
return CSampleWithLicensingValidator::error_show_message;
// This icon will displayed in the "Licenses" page in the Options dialog.
// TODO: provide a a product icon here.
if (0 == m_product_icon)
{
int size = CRhinoDpi::IconSize(CRhinoDpi::IconType::NormalIcon);
m_product_icon = CRhinoDpi::LoadIcon(AfxGetInstanceHandle(), IDI_MAIN, size);
}

CString license_key(licenseKey);
CString validation_code(validationCode);

// This sample current does not support Rhino accounts.
m_requires_online_validation = false;

m_requires_previous_version_license_verification = false;
bool bEvaluation = false;

// Verify license key (if provided)
if (license_key.IsEmpty())
{
license_key = "evaluate-111-222";
}
else if (license_key.Left(8).CompareNoCase(L"EVALUATE-") == 0)
{
bEvaluation = true;
}
else if (license_key.Left(8).CompareNoCase(L"UPGRADE*-") == 0)
{
m_requires_previous_version_license_verification = true;
}
else if (!ValidateSampleLicenseKey(licenseKey))
{
m_error_message = L"The license key is invalid.";
return CRhinoLicenseValidator::error_show_message;
}

// Verify validation code (if provided)
if (!validation_code.IsEmpty())
{
if (validation_code.CompareNoCase(L"invalid") == 0)
{
m_error_message = L"Your validation code is invalid.";
return CRhinoLicenseValidator::error_show_message;
}
}

// Fill in the class members based on the license key
// and validation code.

// This value will never be display in any user interface.
// When your plugin's ValidateProductKey function is called, it is
// When your plugin's VerifyLicenseKey function is called, it is
// passed a a product, or CD, key that was entered into the Zoo
// administrator console. Your ValidateProductKey function will validate
// administrator console. Your VerifyLicenseKey function will validate
// the product key and decode it into a product license. This is
// where you can store this license. This value will be passed
// to your application at runtime when it requests a license.
m_product_license = product_key;
m_product_license = license_key;

// This value will display in user interface items, such as in
// the Zoo console and in About dialog boxes. Also, this value
// is used to uniquely identify this license. Thus, it is
// critical that this value be unique per product key, entered
// by the administrator. No other license of this product, as
// validated by this plugin, should return this value.
//
// This example just reverses product_key...
m_serial_number = Reverse(product_key);
// TODO: provide an obfuscated license string here.
m_serial_number = license_key;

// This value will display in user interface items, such as in
// the Zoo console and in About dialog boxes.
// (e.g. "Rhinoceros 6", "Rhinoceros 6 Commercial", etc.)
m_license_title = "SampleWithLicensing 1.0 Commercial";

// The build of the product that this license work with.
// When your product requests a license from the Zoo, it
// will specify one of these build types. Note, this is just
// the int version of CRhinoLicenseValidator::product_build_type
// enum value.
m_build_type = CRhinoLicenseValidator::release_build;

// Zoo licenses can be used by more than one instance of any application.
// For example, a single Rhino Education Lab license can be used by up
// to 30 systems simultaneously. If your license supports multiple instance,
// then specify the number of supported instances here. Otherwise just
// specify a value of 1 for single instance use.
m_license_count = 1;
// TODO: provide a license title string here.
m_license_title = SampleWithLicensingPlugIn().PlugInName();

// The Zoo supports licenses that expire. If your licensing scheme
// is sophisticated enough to support this, then specify the
// expiration date here. Note, this value must be specified in
// Coordinated Universal Time (UTC). If your license does not expire,
// then just this value to null.
memset(&m_date_to_expire, 0, sizeof(m_date_to_expire));

// This icon will displayed in the "Licenses" page in the Options dialog.
// Note, Rhino will make a copy of this icon..
m_product_icon = CRhinoDpi::LoadIcon(AfxGetInstanceHandle(), IDI_MAIN, 32, 32);

return CRhinoLicenseValidator::success;
}

CRhinoLicenseValidator::result CSampleWithLicensingValidator::VerifyLicenseKey(
const wchar_t* licenseKey,
const wchar_t* validationCode,
const double validationCodeInstalledDate,
bool gracePeriodExpired
)
{
CString sLicenseKey(licenseKey);
CString sValidationCode(validationCode);
m_requires_online_validation = false;
m_requires_previous_version_license_verification = false;
if (sLicenseKey.IsEmpty())
{
sLicenseKey = "evaluate-111-222";
}

if (sLicenseKey.Left(8).CompareNoCase(L"evaluate-") == 0)
{
// Hard-coded evaluation licenses don't get validated online
m_requires_online_validation = false;
}

m_product_license = sLicenseKey;
m_serial_number = sLicenseKey.MakeReverse();
m_license_title = L"Sample License";
m_license_count = 1;

// This license expires in 90 days.
COleDateTime expire_date = COleDateTime::GetCurrentTime();
COleDateTimeSpan interval;
interval.SetDateTimeSpan(90, 0, 0, 0);
m_date_to_expire = expire_date + interval;

if (!sValidationCode.IsEmpty())
{
if (sValidationCode.CompareNoCase(L"invalid") == 0)
{
m_error_message = L"Your validation code is invalid";
return CRhinoLicenseValidator::error_show_message;
}
}

if (sLicenseKey.Left(8).CompareNoCase(L"upgrade-") == 0)
if (bEvaluation)
{
m_requires_previous_version_license_verification = true;
COleDateTime expire_date = COleDateTime::GetCurrentTime();
COleDateTimeSpan interval;
interval.SetDateTimeSpan(90, 0, 0, 0);
m_date_to_expire = expire_date + interval;
}

return CRhinoLicenseValidator::success;
}

// Called by Rhino, from CRhinoPlugIn::GetLicense(), after a call to VerifyLicenseKey that
// sets m_requires_previous_version_license_verification to true.
bool CSampleWithLicensingValidator::VerifyPreviousVersionLicense(
const wchar_t* license,
const wchar_t* previousVersionLicense
const wchar_t* licenseKey,
const wchar_t* previousVersionLicenseKey
)
{
CString sLicense(license);
CString sPrevVersionLicense(previousVersionLicense);
CString sLicense(licenseKey);
CString sPrevVersionLicense(previousVersionLicenseKey);

if (sLicense.IsEmpty())
return false;
Expand All @@ -181,10 +184,13 @@ bool CSampleWithLicensingValidator::VerifyPreviousVersionLicense(
return true;
}

// When Rhino Accounts gets a new lease, this function is called.
void CSampleWithLicensingValidator::OnLeaseChanged(CRhinoLeaseChangedEventArgs& args)
{
// This sample current does not support Rhino accounts.

CRhinoLicenseLease* pLease = args.GetLease();
if (pLease == nullptr)
if (nullptr == pLease)
{
// Lease has been voided; this product should behave as if it has no
// license. It is up to the plug-in to determine what that looks like.
Expand All @@ -197,19 +203,16 @@ void CSampleWithLicensingValidator::OnLeaseChanged(CRhinoLeaseChangedEventArgs&
// Verify that pLease->IsExpired() is false
}

ON_wString CSampleWithLicensingValidator::Reverse(const wchar_t* input)
// Our license key validation code. In this example, we'll accept
// anything but a null or empty string.
bool CSampleWithLicensingValidator::ValidateSampleLicenseKey(const wchar_t* licenseKey)
{
ON_wString str;

if (nullptr == input || 0 == input[0])
return str;

str = input;
str.MakeReverse();

return str;
if (nullptr == licenseKey || 0 == licenseKey)
return false;
return true;
}


//
// END SampleWithLicensingValidator license validator
//
Expand Down
7 changes: 1 addition & 6 deletions cpp/SampleWithLicensing/cmdSampleWithLicensing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,7 @@ static class CCommandSampleWithLicensing theSampleWithLicensingCommand;

CRhinoCommand::result CCommandSampleWithLicensing::RunCommand(const CRhinoCommandContext& context)
{
ON_wString wStr;
wStr.Format(L"The \"%s\" command is under construction.\n", EnglishCommandName());
if (context.IsInteractive())
RhinoMessageBox(wStr, PlugIn()->PlugInName(), MB_OK);
else
RhinoApp().Print(wStr);
RhinoApp().Print(L"%s plug-in loaded.\n", SampleWithLicensingPlugIn().PlugInName());
return CRhinoCommand::success;
}

Expand Down

0 comments on commit d4dff9b

Please sign in to comment.