Make SolveSpace work unrestricted without a license file, and
increase its version number to 1.9. [git-p4: depot-paths = "//depot/solvespace/": change = 2198]
This commit is contained in:
parent
e11347f613
commit
7919e7171d
40
export.cpp
40
export.cpp
|
@ -442,14 +442,6 @@ VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddUnregMessageCallback(void *fndata, Vector a, Vector b)
|
|
||||||
{
|
|
||||||
SBezierLoopSetSet *sblss = (SBezierLoopSetSet *)fndata;
|
|
||||||
SBezier sb = SBezier::From(a, b);
|
|
||||||
sb.auxA = Style::SELECTED;
|
|
||||||
sblss->AddOpenPath(&sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VectorFileWriter::Output(SBezierLoopSetSet *sblss, SMesh *sm) {
|
void VectorFileWriter::Output(SBezierLoopSetSet *sblss, SMesh *sm) {
|
||||||
STriangle *tr;
|
STriangle *tr;
|
||||||
SBezier *b;
|
SBezier *b;
|
||||||
|
@ -494,38 +486,6 @@ void VectorFileWriter::Output(SBezierLoopSetSet *sblss, SMesh *sm) {
|
||||||
ptMax.y = ptMin.y + (s*SS.exportCanvas.height);
|
ptMax.y = ptMin.y + (s*SS.exportCanvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the demo period has expired and there's no license, then print
|
|
||||||
// a message in any exported file.
|
|
||||||
if((!SS.license.licensed) && (SS.license.trialDaysRemaining <= 0) && sblss){
|
|
||||||
char *str =
|
|
||||||
"eval / nonprofit use only -- buy at http://solvespace.com/";
|
|
||||||
double aspect = (glxStrWidth(str, 1) / glxStrHeight(1));
|
|
||||||
double w = ptMax.x - ptMin.x, h = ptMax.y - ptMin.y;
|
|
||||||
Vector u, v, t;
|
|
||||||
double th;
|
|
||||||
if(w > h) {
|
|
||||||
th = w / aspect;
|
|
||||||
u = Vector::From(1, 0, 0);
|
|
||||||
v = Vector::From(0, 1, 0);
|
|
||||||
t = Vector::From(ptMin.x + (w/2), ptMin.y - 1.5*th, 0);
|
|
||||||
} else {
|
|
||||||
th = h / aspect;
|
|
||||||
u = Vector::From( 0, 1, 0);
|
|
||||||
v = Vector::From(-1, 0, 0);
|
|
||||||
t = Vector::From(ptMax.x + 1.5*th, ptMin.y + (h/2) , 0);
|
|
||||||
}
|
|
||||||
glxWriteTextRefCenter(
|
|
||||||
str,
|
|
||||||
0.9 * th * SS.GW.scale,
|
|
||||||
t, u, v,
|
|
||||||
AddUnregMessageCallback, sblss);
|
|
||||||
if(w > h) {
|
|
||||||
ptMin.y -= th*3;
|
|
||||||
} else {
|
|
||||||
ptMax.x += th*3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StartFile();
|
StartFile();
|
||||||
if(sm && SS.exportShadedTriangles) {
|
if(sm && SS.exportShadedTriangles) {
|
||||||
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
|
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
|
||||||
|
|
|
@ -132,8 +132,6 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
{ 1, "Step &Dimension...\tCtrl+Shift+D", MNU_STEP_DIM, 'D'|S|C,mAna },
|
{ 1, "Step &Dimension...\tCtrl+Shift+D", MNU_STEP_DIM, 'D'|S|C,mAna },
|
||||||
|
|
||||||
{ 0, "&Help", 0, 0, NULL },
|
{ 0, "&Help", 0, 0, NULL },
|
||||||
{ 1, "&Load License...", MNU_LICENSE, 0, mHelp },
|
|
||||||
{ 1, NULL, 0, 0, NULL },
|
|
||||||
{ 1, "&Website / Manual", MNU_WEBSITE, 0, mHelp },
|
{ 1, "&Website / Manual", MNU_WEBSITE, 0, mHelp },
|
||||||
{ 1, "&About", MNU_ABOUT, 0, mHelp },
|
{ 1, "&About", MNU_ABOUT, 0, mHelp },
|
||||||
{ -1 },
|
{ -1 },
|
||||||
|
|
64
keygen.pl
64
keygen.pl
|
@ -1,64 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
|
|
||||||
$POLY = 0xedb88320;
|
|
||||||
|
|
||||||
sub ProcessBit {
|
|
||||||
my ($bit) = @_;
|
|
||||||
|
|
||||||
my $topWasSet = ($shiftReg & (1 << 31));
|
|
||||||
|
|
||||||
$shiftReg <<= 1;
|
|
||||||
if($bit) {
|
|
||||||
$shiftReg |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($topWasSet) {
|
|
||||||
$shiftReg ^= $POLY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub ProcessByte {
|
|
||||||
my ($v) = @_;
|
|
||||||
for(0..7) {
|
|
||||||
ProcessBit($v & (1 << $_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub ProcessString {
|
|
||||||
my ($str) = @_;
|
|
||||||
for (split //, $str) {
|
|
||||||
if($_ ne "\n" and $_ ne "\r") {
|
|
||||||
ProcessByte(ord($_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub LicenseKey {
|
|
||||||
my @MAGIC = ( 203, 244, 134, 225, 45, 250, 70, 65,
|
|
||||||
224, 189, 35, 3, 228, 51, 77, 169, );
|
|
||||||
my $magic = join('', map { chr($_) } @MAGIC);
|
|
||||||
|
|
||||||
my ($line1, $line2, $users) = @_;
|
|
||||||
|
|
||||||
$shiftReg = 0;
|
|
||||||
ProcessString($line1);
|
|
||||||
ProcessString($line2);
|
|
||||||
ProcessString($users);
|
|
||||||
ProcessString($magic);
|
|
||||||
|
|
||||||
my $key = '±²³SolveSpaceLicense' . "\n";
|
|
||||||
$key .= $line1 . "\n";
|
|
||||||
$key .= $line2 . "\n";
|
|
||||||
$key .= $users . "\n";
|
|
||||||
$key .= sprintf("%08x\n", $shiftReg);
|
|
||||||
|
|
||||||
return $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$line1 = "Jonathan Westhues";
|
|
||||||
$line2 = "";
|
|
||||||
$users = "single-user license";
|
|
||||||
|
|
||||||
print LicenseKey($line1, $line2, $users);
|
|
||||||
|
|
141
solvespace.cpp
141
solvespace.cpp
|
@ -3,37 +3,7 @@
|
||||||
SolveSpace SS;
|
SolveSpace SS;
|
||||||
Sketch SK;
|
Sketch SK;
|
||||||
|
|
||||||
void SolveSpace::CheckLicenseFromRegistry(void) {
|
|
||||||
// First, let's see if we're running licensed or free
|
|
||||||
CnfThawString(license.line1, sizeof(license.line1), "LicenseLine1");
|
|
||||||
CnfThawString(license.line2, sizeof(license.line2), "LicenseLine2");
|
|
||||||
CnfThawString(license.users, sizeof(license.users), "LicenseUsers");
|
|
||||||
license.key = CnfThawDWORD(0, "LicenseKey");
|
|
||||||
|
|
||||||
license.licensed =
|
|
||||||
LicenseValid(license.line1, license.line2, license.users, license.key);
|
|
||||||
|
|
||||||
// Now see if we've recorded a previous first use time in the registry. If
|
|
||||||
// yes then we use that, otherwise we record the current time.
|
|
||||||
SQWORD now = GetUnixTime();
|
|
||||||
DWORD timeLow = CnfThawDWORD(0, "FirstUseLow");
|
|
||||||
DWORD timeHigh = CnfThawDWORD(0, "FirstUseHigh");
|
|
||||||
if(timeHigh == 0 && timeLow == 0) {
|
|
||||||
CnfFreezeDWORD((DWORD)((now ) & 0xffffffff), "FirstUseLow");
|
|
||||||
CnfFreezeDWORD((DWORD)((now >> 32) & 0xffffffff), "FirstUseHigh");
|
|
||||||
license.firstUse = now;
|
|
||||||
} else {
|
|
||||||
license.firstUse = (((SQWORD)timeHigh) << 32) | ((SQWORD)timeLow);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int SECONDS_IN_DAY = 60*60*24;
|
|
||||||
license.trialDaysRemaining = 30 -
|
|
||||||
(int)(((now - license.firstUse))/SECONDS_IN_DAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::Init(char *cmdLine) {
|
void SolveSpace::Init(char *cmdLine) {
|
||||||
CheckLicenseFromRegistry();
|
|
||||||
|
|
||||||
SS.tangentArcRadius = 10.0;
|
SS.tangentArcRadius = 10.0;
|
||||||
|
|
||||||
// Then, load the registry settings.
|
// Then, load the registry settings.
|
||||||
|
@ -741,105 +711,6 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpace::Crc::ProcessBit(int bit) {
|
|
||||||
bool topWasSet = ((shiftReg & (1 << 31)) != 0);
|
|
||||||
|
|
||||||
shiftReg <<= 1;
|
|
||||||
if(bit) {
|
|
||||||
shiftReg |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(topWasSet) {
|
|
||||||
shiftReg ^= POLY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::Crc::ProcessByte(BYTE b) {
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 8; i++) {
|
|
||||||
ProcessBit(b & (1 << i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::Crc::ProcessString(char *s) {
|
|
||||||
for(; *s; s++) {
|
|
||||||
if(*s != '\n' && *s != '\r') {
|
|
||||||
ProcessByte((BYTE)*s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SolveSpace::LicenseValid(char *line1, char *line2, char *users, DWORD key)
|
|
||||||
{
|
|
||||||
BYTE magic[17] = {
|
|
||||||
203, 244, 134, 225, 45, 250, 70, 65,
|
|
||||||
224, 189, 35, 3, 228, 51, 77, 169,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
crc.shiftReg = 0;
|
|
||||||
crc.ProcessString(line1);
|
|
||||||
crc.ProcessString(line2);
|
|
||||||
crc.ProcessString(users);
|
|
||||||
crc.ProcessString((char *)magic);
|
|
||||||
|
|
||||||
return (key == crc.shiftReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::CleanEol(char *in) {
|
|
||||||
char *s;
|
|
||||||
s = strchr(in, '\r');
|
|
||||||
if(s) *s = '\0';
|
|
||||||
s = strchr(in, '\n');
|
|
||||||
if(s) *s = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::LoadLicenseFile(char *filename) {
|
|
||||||
FILE *f = fopen(filename, "rb");
|
|
||||||
if(!f) {
|
|
||||||
Error("Couldn't open file '%s'", filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buf[100];
|
|
||||||
fgets(buf, sizeof(buf), f);
|
|
||||||
char *str = "±²³SolveSpaceLicense";
|
|
||||||
if(memcmp(buf, str, strlen(str)) != 0) {
|
|
||||||
fclose(f);
|
|
||||||
Error("This is not a license file,");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char line1[512], line2[512], users[512];
|
|
||||||
fgets(line1, sizeof(line1), f);
|
|
||||||
CleanEol(line1);
|
|
||||||
fgets(line2, sizeof(line2), f);
|
|
||||||
CleanEol(line2);
|
|
||||||
fgets(users, sizeof(users), f);
|
|
||||||
CleanEol(users);
|
|
||||||
|
|
||||||
fgets(buf, sizeof(buf), f);
|
|
||||||
DWORD key = 0;
|
|
||||||
sscanf(buf, "%x", &key);
|
|
||||||
|
|
||||||
if(LicenseValid(line1, line2, users, key)) {
|
|
||||||
// Install the new key
|
|
||||||
CnfFreezeString(line1, "LicenseLine1");
|
|
||||||
CnfFreezeString(line2, "LicenseLine2");
|
|
||||||
CnfFreezeString(users, "LicenseUsers");
|
|
||||||
CnfFreezeDWORD(key, "LicenseKey");
|
|
||||||
Message("License key successfully installed.");
|
|
||||||
|
|
||||||
// This updates our display in the text window to show that we're
|
|
||||||
// licensed now.
|
|
||||||
CheckLicenseFromRegistry();
|
|
||||||
SS.later.showTW = true;
|
|
||||||
} else {
|
|
||||||
Error("License key invalid.");
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::MenuHelp(int id) {
|
void SolveSpace::MenuHelp(int id) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case GraphicsWindow::MNU_WEBSITE:
|
case GraphicsWindow::MNU_WEBSITE:
|
||||||
|
@ -847,21 +718,13 @@ void SolveSpace::MenuHelp(int id) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_ABOUT:
|
case GraphicsWindow::MNU_ABOUT:
|
||||||
Message("This is SolveSpace version 1.8.\n\n"
|
Message("This is SolveSpace version 1.9.\n\n"
|
||||||
"For more information, see http://solvespace.com/\n\n"
|
"For more information, see http://solvespace.com/\n\n"
|
||||||
"Built " __TIME__ " " __DATE__ ".\n\n"
|
"Built " __TIME__ " " __DATE__ ".\n\n"
|
||||||
"Copyright 2008-2011 Useful Subset, LLC.\n"
|
"Copyright 2008-2012 Useful Subset, LLC.\n"
|
||||||
"All Rights Reserved.");
|
"All Rights Reserved.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_LICENSE: {
|
|
||||||
char licenseFile[MAX_PATH] = "";
|
|
||||||
if(GetOpenFile(licenseFile, LICENSE_EXT, LICENSE_PATTERN)) {
|
|
||||||
SS.LoadLicenseFile(licenseFile);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
solvespace.h
28
solvespace.h
|
@ -111,10 +111,6 @@ int SaveFileYesNoCancel(void);
|
||||||
// Comma-separated value, like a spreadsheet would use
|
// Comma-separated value, like a spreadsheet would use
|
||||||
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
||||||
#define CSV_EXT "csv"
|
#define CSV_EXT "csv"
|
||||||
// Native license file
|
|
||||||
#define LICENSE_PATTERN \
|
|
||||||
"License File (*.license)\0*.license\0All Files (*)\0*\0\0"
|
|
||||||
#define LICENSE_EXT "license"
|
|
||||||
BOOL GetSaveFile(char *file, char *defExtension, char *selPattern);
|
BOOL GetSaveFile(char *file, char *defExtension, char *selPattern);
|
||||||
BOOL GetOpenFile(char *file, char *defExtension, char *selPattern);
|
BOOL GetOpenFile(char *file, char *defExtension, char *selPattern);
|
||||||
void GetAbsoluteFilename(char *file);
|
void GetAbsoluteFilename(char *file);
|
||||||
|
@ -667,7 +663,6 @@ public:
|
||||||
|
|
||||||
// The platform-dependent code calls this before entering the msg loop
|
// The platform-dependent code calls this before entering the msg loop
|
||||||
void Init(char *cmdLine);
|
void Init(char *cmdLine);
|
||||||
void CheckLicenseFromRegistry(void);
|
|
||||||
void Exit(void);
|
void Exit(void);
|
||||||
|
|
||||||
// File load/save routines, including the additional files that get
|
// File load/save routines, including the additional files that get
|
||||||
|
@ -802,30 +797,7 @@ public:
|
||||||
} later;
|
} later;
|
||||||
void DoLater(void);
|
void DoLater(void);
|
||||||
|
|
||||||
// For the licensing
|
|
||||||
class Crc {
|
|
||||||
public:
|
|
||||||
static const DWORD POLY = 0xedb88320;
|
|
||||||
DWORD shiftReg;
|
|
||||||
|
|
||||||
void ProcessBit(int bit);
|
|
||||||
void ProcessByte(BYTE b);
|
|
||||||
void ProcessString(char *s);
|
|
||||||
};
|
|
||||||
Crc crc;
|
|
||||||
struct {
|
|
||||||
bool licensed;
|
|
||||||
char line1[512];
|
|
||||||
char line2[512];
|
|
||||||
char users[512];
|
|
||||||
DWORD key;
|
|
||||||
SQWORD firstUse;
|
|
||||||
int trialDaysRemaining;
|
|
||||||
} license;
|
|
||||||
static void MenuHelp(int id);
|
static void MenuHelp(int id);
|
||||||
void CleanEol(char *s);
|
|
||||||
void LoadLicenseFile(char *filename);
|
|
||||||
bool LicenseValid(char *line1, char *line2, char *users, DWORD key);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SolveSpace SS;
|
extern SolveSpace SS;
|
||||||
|
|
|
@ -141,28 +141,6 @@ void TextWindow::ShowListOfGroups(void) {
|
||||||
&(TextWindow::ScreenShowListOfStyles),
|
&(TextWindow::ScreenShowListOfStyles),
|
||||||
&(TextWindow::ScreenShowEditView),
|
&(TextWindow::ScreenShowEditView),
|
||||||
&(TextWindow::ScreenShowConfiguration));
|
&(TextWindow::ScreenShowConfiguration));
|
||||||
|
|
||||||
// Show license info
|
|
||||||
Printf(false, "");
|
|
||||||
if(SS.license.licensed) {
|
|
||||||
Printf(false, "%FtLicensed to:");
|
|
||||||
Printf(false, "%Fg %s", SS.license.line1);
|
|
||||||
if(strlen(SS.license.line2)) {
|
|
||||||
Printf(false, "%Fg %s", SS.license.line2);
|
|
||||||
}
|
|
||||||
Printf(false, "%Fg %s", SS.license.users);
|
|
||||||
} else {
|
|
||||||
Printf(false, "%Fx*** NO LICENSE FILE IS PRESENT ***");
|
|
||||||
if(SS.license.trialDaysRemaining > 0) {
|
|
||||||
Printf(false, "%Fx running as full demo, %d day%s remaining",
|
|
||||||
SS.license.trialDaysRemaining,
|
|
||||||
SS.license.trialDaysRemaining == 1 ? "" : "s");
|
|
||||||
} else {
|
|
||||||
Printf(false, "%Fx demo expired, now running in light mode");
|
|
||||||
}
|
|
||||||
Printf(false, "%Fx buy at %Fl%f%Llhttp://solvespace.com/%E",
|
|
||||||
&ScreenGoToWebsite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user