// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved // Please see LICENSE.md in repository root for license information // https://github.com/AtomicGameEngine/AtomicGameEngine // 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; } 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(); /* UIModalOps* ops = GetSubsystem(); ops->ShowActivation(); */ } 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() { 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