// // Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // BEGIN LICENSE MANAGEMENT #ifdef ATOMIC_PLATFORM_WINDOWS #ifndef _MSC_VER #define _WIN32_IE 0x501 #endif #include #include #include #include #include #include #endif #include #include #include #include #include #include #include "LicenseEvents.h" #include "LicenseSystem.h" #include #include namespace ToolCore { LicenseSystem::LicenseSystem(Context* context) : Object(context) , eulaAgreementConfirmed_(false) { FileSystem* filesystem = GetSubsystem(); licenseFilePath_ = filesystem->GetAppPreferencesDir("AtomicEditor", "License"); licenseFilePath_ = AddTrailingSlash(licenseFilePath_); if (!filesystem->DirExists(licenseFilePath_)) { Poco::File dirs(licenseFilePath_.CString()); dirs.createDirectories(); } licenseCachePath_ = licenseFilePath_; licenseCachePath_ += "AtomicLicenseCache"; licenseFilePath_ += "AtomicLicense"; eulaAgreementPath_ = filesystem->GetAppPreferencesDir("AtomicEditor", "License"); eulaAgreementPath_ = AddTrailingSlash(eulaAgreementPath_); eulaAgreementPath_ += "EulaConfirmed"; ResetLicense(); } LicenseSystem::~LicenseSystem() { } void LicenseSystem::Initialize() { FileSystem* filesystem = GetSubsystem(); eulaAgreementConfirmed_ = filesystem->FileExists(eulaAgreementPath_); if (!eulaAgreementConfirmed_) { SendEvent(E_LICENSE_EULAREQUIRED); return; } // TODO: Cleanup for MIT if (!LoadLicense() || !key_.Length()) { ResetLicense(); SendEvent(E_LICENSE_ACTIVATIONREQUIRED); return; } else { // RequestServerVerification(key_); } } void LicenseSystem::LicenseAgreementConfirmed() { eulaAgreementConfirmed_ = true; SharedPtr file(new File(context_, eulaAgreementPath_, FILE_WRITE)); file->WriteInt(1); file->Close(); if (!LoadLicense() || !key_.Length()) SendEvent(E_LICENSE_ACTIVATIONREQUIRED); } String LicenseSystem::GenerateMachineID() { #if defined(ATOMIC_PLATFORM_OSX) || defined(ATOMIC_PLATFORM_LINUX) String path = getenv("HOME"); #else wchar_t pathName[MAX_PATH]; pathName[0] = 0; SHGetSpecialFolderPathW(0, pathName, CSIDL_PERSONAL, 0); String path(pathName); #endif Poco::MD5Engine md5; md5.update(path.CString(), path.Length()); String id = Poco::MD5Engine::digestToHex(md5.digest()).c_str(); return id; } void LicenseSystem::ResetLicense() { key_ = ""; licenseWindows_ = false; licenseMac_ = false; licenseAndroid_ = false; licenseIOS_ = false; licenseHTML5_ = false; licenseModule3D_ = false; } bool LicenseSystem::LoadLicense() { key_ = "ATOMIC-XXXX-XXXX-XXXX-XXXX"; licenseWindows_ = true; licenseMac_ = true; licenseAndroid_ = true; licenseIOS_ = true; licenseHTML5_ = true; licenseModule3D_ = true; return true; // TODO: Cleanup for MIT /* ResetLicense(); FileSystem* filesystem = GetSubsystem(); if (!filesystem->FileExists(licenseFilePath_)) return false; SharedPtr file(new File(context_, licenseFilePath_, FILE_READ)); file->ReadInt(); // version String key = file->ReadString(); if (!ValidateKey(key)) return false; key_ = key; licenseWindows_ = file->ReadBool(); licenseMac_ = file->ReadBool(); licenseAndroid_ = file->ReadBool(); licenseIOS_ = file->ReadBool(); licenseHTML5_ = file->ReadBool(); licenseModule3D_ = file->ReadBool(); return true; */ } bool LicenseSystem::ValidateKey(const String& key) { if (!key.StartsWith("ATOMIC-")) return false; Vector elements = key.Split('-'); if (elements.Size() != 5) return false; for (unsigned i = 1; i < elements.Size(); i++) { String element = elements[i]; if (element.Length() != 4) return false; for (unsigned j = 0; j < 4; j++) { char c = element[j]; if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) continue; return false; } } return true; } void LicenseSystem::SaveLicense() { SharedPtr file(new File(context_, licenseFilePath_, FILE_WRITE)); file->WriteInt(1); // version file->WriteString(key_); file->WriteBool(licenseWindows_); file->WriteBool(licenseMac_); file->WriteBool(licenseAndroid_); file->WriteBool(licenseIOS_); file->WriteBool(licenseHTML5_); file->WriteBool(licenseModule3D_); file->Close(); } void LicenseSystem::RemoveLicense() { FileSystem* filesystem = GetSubsystem(); if (filesystem->FileExists(licenseFilePath_)) { filesystem->Delete(licenseFilePath_); } if (filesystem->FileExists(licenseCachePath_)) { filesystem->Delete(licenseCachePath_); } } bool LicenseSystem::IsStandardLicense() { return !licenseAndroid_; } void LicenseSystem::RequestServerVerification(const String& key) { if (serverVerification_.NotNull()) { LOGERROR("LicenseSystem::RequestServerLicense - request already exists"); return; } FileSystem* fileSystem = GetSubsystem(); if (fileSystem->FileExists(licenseCachePath_)) { Time* time = GetSubsystem