Make SolveSpace work unrestricted without a license file, and
increase its version number to 1.9. [git-p4: depot-paths = "//depot/solvespace/": change = 2198]solver
parent
e11347f613
commit
7919e7171d
40
export.cpp
40
export.cpp
|
@ -442,14 +442,6 @@ VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
|
|||
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) {
|
||||
STriangle *tr;
|
||||
SBezier *b;
|
||||
|
@ -494,38 +486,6 @@ void VectorFileWriter::Output(SBezierLoopSetSet *sblss, SMesh *sm) {
|
|||
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();
|
||||
if(sm && SS.exportShadedTriangles) {
|
||||
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 },
|
||||
|
||||
{ 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, "&About", MNU_ABOUT, 0, mHelp },
|
||||
{ -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;
|
||||
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) {
|
||||
CheckLicenseFromRegistry();
|
||||
|
||||
SS.tangentArcRadius = 10.0;
|
||||
|
||||
// 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) {
|
||||
switch(id) {
|
||||
case GraphicsWindow::MNU_WEBSITE:
|
||||
|
@ -847,21 +718,13 @@ void SolveSpace::MenuHelp(int id) {
|
|||
break;
|
||||
|
||||
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"
|
||||
"Built " __TIME__ " " __DATE__ ".\n\n"
|
||||
"Copyright 2008-2011 Useful Subset, LLC.\n"
|
||||
"Copyright 2008-2012 Useful Subset, LLC.\n"
|
||||
"All Rights Reserved.");
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_LICENSE: {
|
||||
char licenseFile[MAX_PATH] = "";
|
||||
if(GetOpenFile(licenseFile, LICENSE_EXT, LICENSE_PATTERN)) {
|
||||
SS.LoadLicenseFile(licenseFile);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: oops();
|
||||
}
|
||||
}
|
||||
|
|
28
solvespace.h
28
solvespace.h
|
@ -111,10 +111,6 @@ int SaveFileYesNoCancel(void);
|
|||
// Comma-separated value, like a spreadsheet would use
|
||||
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
||||
#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 GetOpenFile(char *file, char *defExtension, char *selPattern);
|
||||
void GetAbsoluteFilename(char *file);
|
||||
|
@ -667,7 +663,6 @@ public:
|
|||
|
||||
// The platform-dependent code calls this before entering the msg loop
|
||||
void Init(char *cmdLine);
|
||||
void CheckLicenseFromRegistry(void);
|
||||
void Exit(void);
|
||||
|
||||
// File load/save routines, including the additional files that get
|
||||
|
@ -802,30 +797,7 @@ public:
|
|||
} later;
|
||||
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);
|
||||
void CleanEol(char *s);
|
||||
void LoadLicenseFile(char *filename);
|
||||
bool LicenseValid(char *line1, char *line2, char *users, DWORD key);
|
||||
};
|
||||
|
||||
extern SolveSpace SS;
|
||||
|
|
|
@ -141,28 +141,6 @@ void TextWindow::ShowListOfGroups(void) {
|
|||
&(TextWindow::ScreenShowListOfStyles),
|
||||
&(TextWindow::ScreenShowEditView),
|
||||
&(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