Browse Source

CLI activation/deactivation

Josh Engebretson 10 years ago
parent
commit
365372894e

+ 40 - 1
CLI/atomic-cli/bin/atomic-cli.js

@@ -7,13 +7,52 @@
 var path = require("path");
 var program = require('commander');
 var cli = require("atomic-cli")
+var open = require("open");
+var prompt = require('prompt');
 
-
+prompt.message = "";
+prompt.delimiter = "";
 
 program
   .version('0.0.1')
   .parse(process.argv);
 
+// activation command
+program
+  .command('activate')
+  .description('activate')
+  .action(function(folder){
+
+    prompt.start();
+
+    prompt.get([ { description: 'Please confirm EULA agreement (Y)es, (N)o, or (V)iew', default: "Y", name: "eulaconfirm" }], function (err, result) {
+        var eulaconfirm = result.eulaconfirm.toLowerCase();
+        if (eulaconfirm == 'y') {
+          prompt.get([ { description: 'Please enter Product Key or (G)et free key: ', name: "productkey" }], function (err, result) {
+            var productkey = result.productkey.toLowerCase();
+            if (productkey == 'g') {
+              console.log ("Opening Atomic Store in default browser window");
+              open("https://store.atomicgameengine.com/site");
+            } else {
+              cli.activate(productkey);
+            }
+          });
+        } else if (eulaconfirm == 'v') {
+          console.log ("Opening EULA in default browser window");
+          open("https://github.com/AtomicGameEngine/AtomicGameEngine/blob/master/LICENSE.md");
+        }
+    });
+  });
+
+// deactivation
+program
+  .command('deactivate')
+  .description('deactivates and returns a product activation to the server')
+  .action(function(){
+    cli.deactivate();
+  });
+
+
 // new project command
 program
   .command('new <folder>')

+ 11 - 1
CLI/atomic-cli/lib/atomictool.js

@@ -39,6 +39,14 @@ var build = function (platform) {
   return atomictool(["build", platform], {output:true});
 };
 
+var activate = function (productkey) {
+  return atomictool(["--activate", productkey.toUpperCase()], {output:true});
+};
+
+var deactivate = function () {
+  return atomictool(["--deactivate"], {output:true});
+};
+
 var run = function (platform, opts) {
 
     opts = opts || {};
@@ -109,5 +117,7 @@ module.exports = {
   "newProject" : newProject,
   "addPlatform" : addPlatform,
   "build" : build,
-  "run" : run
+  "run" : run,
+  "activate" : activate,
+  "deactivate" : deactivate
 }

+ 2 - 0
CLI/atomic-cli/lib/main.js

@@ -12,6 +12,8 @@ module.exports = {
   "addPlatform" : atomictool.addPlatform,
   "build" : atomictool.build,
   "run" : atomictool.run,
+  "activate" : atomictool.activate,
+  "deactivate" : atomictool.deactivate,
   "atomiceditor" : atomiceditor
 
 }

+ 2 - 1
CLI/atomic-cli/package.json

@@ -11,7 +11,8 @@
     "q": "*",
     "commander" : "*",
     "update-notifier" : "*",
-    "open": "*"
+    "open": "*",
+    "prompt": "latest"
   },
   "devDependencies" : {
   },

+ 96 - 4
Source/AtomicTool/AtomicTool.cpp

@@ -21,7 +21,8 @@ namespace AtomicTool
 {
 
 AtomicTool::AtomicTool(Context* context) :
-    Application(context)
+    Application(context),
+    deactivate_(false)
 {
 
 }
@@ -49,6 +50,18 @@ void AtomicTool::Setup()
 
                 cliDataPath_ = AddTrailingSlash(value);
             }
+            else if (argument == "--activate")
+            {
+                if (!value.Length())
+                    ErrorExit("Unable to parse --activation product key");
+
+                activationKey_ = value;
+            }
+            else if (argument == "--deactivate")
+            {
+                deactivate_ = true;
+            }
+
         }
 
     }
@@ -57,7 +70,7 @@ void AtomicTool::Setup()
         ErrorExit("Unable to parse --data-path");
 
     engineParameters_["Headless"] = true;
-    engineParameters_["LogLevel"] = LOG_INFO;
+    engineParameters_["LogLevel"] = LOG_WARNING;
     engineParameters_["ResourcePaths"] = "";
 }
 
@@ -79,22 +92,91 @@ void AtomicTool::HandleCommandError(StringHash eventType, VariantMap& eventData)
 
 void AtomicTool::HandleLicenseEulaRequired(StringHash eventType, VariantMap& eventData)
 {
-
+    ErrorExit("\nActivation Required: Please run: atomic-cli activate\n");
 }
 
 void AtomicTool::HandleLicenseActivationRequired(StringHash eventType, VariantMap& eventData)
 {
-
+    ErrorExit("\nActivation Required: Please run: atomic-cli activate\n");
 }
 
 void AtomicTool::HandleLicenseSuccess(StringHash eventType, VariantMap& eventData)
 {
+    if (command_.Null())
+    {
+        GetSubsystem<Engine>()->Exit();
+        return;
+    }
+
     command_->Run();
 }
 
 void AtomicTool::HandleLicenseError(StringHash eventType, VariantMap& eventData)
 {
+    ErrorExit("\nActivation Required: Please run: atomic-cli activate\n");
+}
+
+void AtomicTool::HandleLicenseActivationError(StringHash eventType, VariantMap& eventData)
+{
+    String message = eventData[LicenseActivationError::P_MESSAGE].ToString();
+    ErrorExit(message);
+}
+
+void AtomicTool::HandleLicenseActivationSuccess(StringHash eventType, VariantMap& eventData)
+{
+    LOGRAW("\nActivation successful, thank you!\n\n");
+    GetSubsystem<Engine>()->Exit();
+}
+
+void AtomicTool::DoActivation()
+{
+    LicenseSystem* licenseSystem = GetSubsystem<LicenseSystem>();
+
+    if (!licenseSystem->ValidateKey(activationKey_))
+    {
+        ErrorExit(ToString("\nProduct key: %s is invalid. (Keys are in the form ATOMIC-XXXX-XXXX-XXXX-XXXX)\n"));
+        return;
+    }
+
+    licenseSystem->LicenseAgreementConfirmed();
+
+    SubscribeToEvent(E_LICENSE_ACTIVATIONERROR, HANDLER(AtomicTool, HandleLicenseActivationError));
+    SubscribeToEvent(E_LICENSE_ACTIVATIONSUCCESS, HANDLER(AtomicTool, HandleLicenseActivationSuccess));
+
+    licenseSystem->RequestServerActivation(activationKey_);
+
+}
+
+void AtomicTool::HandleLicenseDeactivationError(StringHash eventType, VariantMap& eventData)
+{
+    String message = eventData[LicenseDeactivationError::P_MESSAGE].ToString();
+    ErrorExit(message);
+}
 
+void AtomicTool::HandleLicenseDeactivationSuccess(StringHash eventType, VariantMap& eventData)
+{
+    LOGRAW("\nDeactivation successful\n\n");
+    GetSubsystem<Engine>()->Exit();
+}
+
+void AtomicTool::DoDeactivation()
+{
+    LicenseSystem* licenseSystem = GetSubsystem<LicenseSystem>();
+
+    if (!licenseSystem->LoadLicense())
+    {
+        ErrorExit("\nNot activated");
+        return;
+    }
+
+    SharedPtr<CurlRequest> request = licenseSystem->Deactivate();
+    if (request.Null())
+    {
+        ErrorExit("\nNot activated\n");
+        return;
+    }
+    SubscribeToEvent(E_LICENSE_DEACTIVATIONERROR, HANDLER(AtomicTool, HandleLicenseDeactivationError));
+    SubscribeToEvent(E_LICENSE_DEACTIVATIONSUCCESS, HANDLER(AtomicTool, HandleLicenseDeactivationSuccess));
 }
 
 void AtomicTool::Start()
@@ -115,6 +197,16 @@ void AtomicTool::Start()
     tsystem->SetCLI();
     tsystem->SetDataPath(cliDataPath_);
 
+    if (activationKey_.Length())
+    {
+        DoActivation();
+        return;
+    } else if (deactivate_)
+    {
+        DoDeactivation();
+        return;
+    }
+
     BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
 
     SharedPtr<CommandParser> parser(new CommandParser(context_));

+ 11 - 0
Source/AtomicTool/AtomicTool.h

@@ -35,10 +35,21 @@ private:
     void HandleLicenseSuccess(StringHash eventType, VariantMap& eventData);
     void HandleLicenseError(StringHash eventType, VariantMap& eventData);
 
+    void HandleLicenseActivationError(StringHash eventType, VariantMap& eventData);
+    void HandleLicenseActivationSuccess(StringHash eventType, VariantMap& eventData);
+    void HandleLicenseDeactivationError(StringHash eventType, VariantMap& eventData);
+    void HandleLicenseDeactivationSuccess(StringHash eventType, VariantMap& eventData);
+
     void HandleCommandFinished(StringHash eventType, VariantMap& eventData);
     void HandleCommandError(StringHash eventType, VariantMap& eventData);
 
+    void DoActivation();
+    void DoDeactivation();
+
+    // use a variant map instead?
     String cliDataPath_;
+    String activationKey_;
+    bool deactivate_;
 
     SharedPtr<Command> command_;
 

+ 18 - 0
Source/ToolCore/License/LicenseEvents.h

@@ -35,6 +35,24 @@ EVENT(E_LICENSE_SUCCESS, LicenseSuccess)
 
 }
 
+EVENT(E_LICENSE_ACTIVATIONSUCCESS, LicenseActivationSuccess)
+{
+}
+
+EVENT(E_LICENSE_ACTIVATIONERROR, LicenseActivationError)
+{
+    PARAM(P_MESSAGE, Message); // String
+}
+
+EVENT(E_LICENSE_DEACTIVATIONSUCCESS, LicenseDeactivationSuccess)
+{
+}
+
+EVENT(E_LICENSE_DEACTIVATIONERROR, LicenseDeactivationError)
+{
+    PARAM(P_MESSAGE, Message); // String
+}
+
 
 // license error
 EVENT(E_LICENSE_ERROR, LicenseError)

+ 85 - 12
Source/ToolCore/License/LicenseSystem.cpp

@@ -487,37 +487,36 @@ void LicenseSystem::HandleDeactivate(StringHash eventType, VariantMap& eventData
 {
     CurlRequest* request = (CurlRequest*) (eventData[CurlComplete::P_CURLREQUEST].GetPtr());
 
+    VariantMap eventDataOut;
+
     if (deactivate_.NotNull())
     {
         assert(request == deactivate_);
 
         if (deactivate_->GetError().Length())
         {
-            String msg;
+            String msg = "Deactivation Error:\n";
             msg.AppendWithFormat("Unable to deactivate with server: %s", deactivate_->GetError().CString());
-            //editor->PostModalError("Deactivation Error", msg);
-            LOGERROR(msg);
+
+            eventDataOut[LicenseDeactivationError::P_MESSAGE] = msg;
+            SendEvent(E_LICENSE_DEACTIVATIONERROR, eventDataOut);
         }
         else
         {
             String response = request->GetResponse();
             if (response.StartsWith("AC_FAILED"))
             {
-                String msg;
+                String msg = "Deactivation Error:\n";
                 msg.AppendWithFormat("Unable to deactivate with server: %s", response.CString());
-                //editor->PostModalError("Deactivation Error", msg);
-                LOGERROR(msg);
+
+                eventDataOut[LicenseDeactivationError::P_MESSAGE] = msg;
+                SendEvent(E_LICENSE_DEACTIVATIONERROR, eventDataOut);
             }
             else if (response.StartsWith("AC_NOTACTIVATED") || response.StartsWith("AC_SUCCESS"))
             {
                 ResetLicense();
                 RemoveLicense();
-
-                /*
-                UIModalOps* ops = GetSubsystem<UIModalOps>();
-                ops->Hide();
-                ops->ShowActivation();
-                */
+                SendEvent(E_LICENSE_DEACTIVATIONSUCCESS);
             }
 
         }
@@ -528,6 +527,80 @@ void LicenseSystem::HandleDeactivate(StringHash eventType, VariantMap& eventData
 
 }
 
+void LicenseSystem::HandleActivationResult(StringHash eventType, VariantMap& eventData)
+{
+    VariantMap eventDataOut;
+
+    if (serverActivation_->GetError().Length())
+    {
+        String errorMessage;
+        errorMessage.AppendWithFormat("There was an error contacting the activation server\n\n%s", serverActivation_->GetError().CString());
+
+        eventDataOut[LicenseActivationError::P_MESSAGE] = errorMessage;
+        SendEvent(E_LICENSE_ACTIVATIONERROR, eventDataOut);
+        return;
+    }
+    else
+    {
+        LicenseParse parse;
+        int code = ParseResponse(serverActivation_->GetResponse(), parse);
+
+        if (code == 0)
+        {
+            Activate(key_, parse);
+            SendEvent(E_LICENSE_ACTIVATIONSUCCESS);
+        }
+        else if (code == 1)
+        {
+            // TODO: check for CLI and prompt to use CLI command to return license
+            String message = "Activations Exceeded:\nThis key has 2 activations in use.\n\nPlease return a license from Atomic Editor - Manage License menu on one of these active computers.\n\nIf you are unable to do so, please contact [email protected] providing the key to reset it";
+            eventDataOut[LicenseActivationError::P_MESSAGE] = message;
+            SendEvent(E_LICENSE_ACTIVATIONERROR, eventDataOut);
+
+        }
+        else if (code == 2)
+        {
+            String message = "License Error:\nThere was a problem with the license key.\n\nPlease check the key and try again.\n\nIf the problem persists please contact [email protected]";
+            eventDataOut[LicenseActivationError::P_MESSAGE] = message;
+            SendEvent(E_LICENSE_ACTIVATIONERROR, eventDataOut);
+
+
+        }
+        else if (code == 3)
+        {
+            String message ="Activation Server Error:\nThere was an error on the activation server\n\nIf the problem persists please contact [email protected]";
+            eventDataOut[LicenseActivationError::P_MESSAGE] = message;
+            SendEvent(E_LICENSE_ACTIVATIONERROR, eventDataOut);
+        }
+
+    }
+
+    UnsubscribeFromEvents(serverActivation_);
+    serverActivation_ = 0;
+}
+
+void LicenseSystem::RequestServerActivation(const String& key)
+{
+    if (serverActivation_.NotNull())
+    {
+        LOGERROR("UIActivation::RequestServerActivation - request already exists");
+        return;
+    }
+
+    LicenseSystem* licenseSystem = GetSubsystem<LicenseSystem>();
+
+    key_ = key;
+    CurlManager* cm = GetSubsystem<CurlManager>();
+    String post;
+    String id = licenseSystem->GenerateMachineID();
+    post.AppendWithFormat("key=%s&id=%s", key.CString(), id.CString());
+
+    // todo, this should be a verify url (shouldn't auto add id)
+    serverActivation_ = cm->MakeRequest("https://store.atomicgameengine.com/licenses/license_activate.php", post);
+
+    SubscribeToEvent(serverActivation_, E_CURLCOMPLETE, HANDLER(LicenseSystem, HandleActivationResult));
+}
+
 }
 
 // END LICENSE MANAGEMENT

+ 7 - 1
Source/ToolCore/License/LicenseSystem.h

@@ -62,10 +62,14 @@ public:
     SharedPtr<CurlRequest>& Deactivate();
 
     void ResetLicense();
+    bool LoadLicense();
 
     /// Basic key validation
     bool ValidateKey(const String &key);
 
+    /// Activate on server
+    void RequestServerActivation(const String& key);
+
     const String& GetKey() { return key_; }
     String GenerateMachineID();
     String GetEmail() { return email_;}
@@ -78,7 +82,6 @@ private:
 
     void RequestServerVerification(const String& key);
 
-    bool LoadLicense();
     void SaveLicense();
     void RemoveLicense();
 
@@ -88,6 +91,8 @@ private:
     void HandleDeactivate(StringHash eventType, VariantMap& eventData);
     void HandleEditorShutdown(StringHash eventType, VariantMap& eventData);
 
+    void HandleActivationResult(StringHash eventType, VariantMap& eventData);
+
     bool eulaAgreementConfirmed_;
 
     String licenseFilePath_;
@@ -103,6 +108,7 @@ private:
     bool licenseHTML5_;
     bool licenseModule3D_;
 
+    SharedPtr<CurlRequest> serverActivation_;
     SharedPtr<CurlRequest> serverVerification_;
     SharedPtr<CurlRequest> deactivate_;