Serial Numbers

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 02:48, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   11.5 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
I want to add a serial number registration to my plugin.  Do I create an completely new function to do this or do I do this in Init()?

I have never done this so I am guessing that I create a dialog that only shows up if the product has not been registered?  The dialog will be looking for a serial number based on SerialInfo and my own  algorithm.

Then when the user enters the info, I somehow store it to a file on their computer somewhere and when the plugin loads, it should look for the existance of that file?

Is that about what I will need to do?

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 03:42, xxxxxxxx wrote:

It's a pity that the SDK doesn't contain a standardised method of doing this. As it is, when I was working out how to do this, it seemed that there were as many methods of writing these routines as there are plugin authors! The result is that I don't really know if the method I used is valid (i.e. secure), just that it works. This is how I did it:

1. I have a global boolean indicating if the plugin is registered. When the plugin is called by the user, that boolean is checked in the Execute() function. The first time the plugin is called in any session of using C4D, the boolean will be false, so I do a serial number check.

2. To do that, I attempt to load the serial using ReadPluginInfo(), and if I can read someting, I run a serial check on what has been loaded (you need to provide your own algorithm for that).

3. If the serial is valid, the global boolean is set to true, so from then on whenever the user calls the plugin, Execute() checks the boolean and doesn't need to check the serial again.

4. If the serial is bad, or ReadPluginInfo() couldn't read anything, I ask the user to enter a serial, and if they enter a valid one that is saved to disk using WritePluginInfo(). From then on, it's registered and the user won't have to do that again.

Complications arise if you provide a demo - you have to decide how that will work. It seems to me that there are three choices: a limited functionality demo, which is made fully functional when a valid serial is entered; a time-limited fully-functional demo, which is the option I favoured but then you have the bother of saving the initial installation date and checking that if the serial check is not valid; or letting the demo version only work in the C4D demo, which I personally dislike as it means having the demo installated alongside my registered C4D installation.

Hope that helps a little.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 05:36, xxxxxxxx wrote:

Thanks a lot for your reply.  That helps  alot.

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 06:21, xxxxxxxx wrote:

Originally posted by xxxxxxxx

It's a pity that the SDK doesn't contain a standardised method of doing this.

Actually there is, the SDK provides the Serial number library. Please check the SDK documentation for the SNHookClass class.

In the end it is of course up to the plugin developers how they handle the serialisation of their plugins.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 07:07, xxxxxxxx wrote:

So to use the SNHookClass I need to get a unique ID number from plugincafe right?

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 07:29, xxxxxxxx wrote:

Originally posted by xxxxxxxx

So to use the SNHookClass I need to get a unique ID number from plugincafe right?

Yes. Please check the serial_hook.cpp file in the SDK examples.

Serial hook registration is in C4DPL_INIT_SYS, see main.cpp.

There is also another plugin serialization SDK example to create your own serial dialog, check serial.cpp.

The difference is SNHookClass serialization has no own dialog but uses the CINEMA 4D 'Personalize' dialog and simplyfies reading/writing of the serial number.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 08:45, xxxxxxxx wrote:

Originally posted by xxxxxxxx

The difference is SNHookClass serialization has no own dialog but uses the CINEMA 4D 'Personalize' dialog and simplyfies reading/writing of the serial number.cheers,Matthias

Hi Matthias,

Yes, I was aware of that class but many plugin writers seem to do things in other ways, for reasons that aren't clear to me. Is this now the Maxon 'recommended' way of handling serials for plugins? I somehow got the impression it was only intended for Maxon's own modules, although I know a few authors have used it as well.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 11:20, xxxxxxxx wrote:

There is no 'recommended' way. It's really up to you. Currently there are two serialization methods supported directly through the SDK. One is to use the SNHookClass and the other to use the WritePluginInfo/ReadPluginInfo WriteRegInfo/ReadRegInfo function to write/read private data for your plugin serialization.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 13:05, xxxxxxxx wrote:

OK, that's very useful, thank you.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 13:07, xxxxxxxx wrote:

Thanks spedler and Matthias for the info.  I will put it to good use as soon as I get home tonight.

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2010 at 17:44, xxxxxxxx wrote:

Okay so This is the code I have in my .cpp file now for the serial number..

  
////////////////////////////////////////////////////////////////////////////////////  
//const ID_PLANET_OBJECT_SERIAL  = 1024924;  
    
class PlanetXSerial : public SNHookClass  
{  
public:  
  String name;  
  
  PlanetXSerial()  
  {  
      name = GeLoadString(IDS_SERIAL_HOOK);  
      if(!name.Content())  
          name = "C++ SDK - Example Serial Hook";  
  }  
  
  virtual LONG SNCheck(const String &c4dsn,const String &sn,LONG regdate,LONG curdate)  
  {  
      return sn == String("123456789-abcdef") ? SN_OKAY : SN_WRONGNUMBER;  
  }  
  
  virtual const String& GetTitle()  
  {  
      return name;  
  }  
};  
  
PlanetXSerial *snhook = NULL;  
  
Bool RegisterPlanetXSerial()  
{  
  snhook = gNew PlanetXSerial;  
  if (!snhook->Register(450000241, SNFLAG_OWN))  
      return FALSE;  
  return TRUE;  
}  
  
void FreePlanetXSerial()  
{  
  if (snhook)  
      gDelete(snhook);  
}  
    
///////////////////////////////////////////////////////////////////////////////////////////////////////////  

My question is, what am I supposed to do to prompt the user to put in their serial number, and where do I determine the algorithm for the serial number.    When I finally do determine that,  I will of course not post it on this forum .  LOL

Also, shouldn't I see another serial field when I go to the personalize dialog box with the code I have?

Once again I am new to this whole part of it so any help you can offer would be greatly appreciated.

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2010 at 01:23, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Also, shouldn't I see another serial field when I go to the personalize dialog box with the code I have?

Did you call RegisterPlanetXSerial() during C4DPL_INIT_SYS to register the plugin with Cinema?

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2010 at 02:40, xxxxxxxx wrote:

Yes, I did,
Here's my main.cpp

  
/////////////////////////////////////////////////////////////  
// Planet  
  
// Starts the plugin registration  
  
#include "c4d.h"  
#include <string.h>  
  
// forward declarations  
Bool RegisterPlanet(void);  
Bool RegisterSun(void);  
Bool RegisterPlanetXSerial();  
void FreePlanetXSerial();  
  
C4D_CrashHandler old_handler;  
  
void SDKCrashHandler(CHAR *crashinfo)  
{  
  // don't forget to call the original handler!!!  
  if (old_handler) (*old_handler)(crashinfo);  
}  
  
void EnhanceMainMenu(void)   
{  
  // do this only if necessary - otherwise the user will end up with dozens of menus!  
  
  if (!(GeGetVersionType()&VERSION_CINEMA4D)) // only if C4D is loaded  
      return;  
  
  BaseContainer *bc = GetMenuResource(String("M_EDITOR"));  
  if (!bc) return;  
  
  // search for the most important menu entry. if present, the user has customized the settings  
  // -> don't add menu again  
  if (SearchMenuResource(bc,String("PLUGIN_CMD_1000472")))  
      return;   
  
  GeData *last = SearchPluginMenuResource();  
  
  BaseContainer sc;  
  sc.InsData(MENURESOURCE_SUBTITLE,String("SDK Test"));  
  sc.InsData(MENURESOURCE_COMMAND,String("IDM_NEU")); // add C4D's new scene command to menu  
  sc.InsData(MENURESOURCE_SEPERATOR,TRUE);  
  sc.InsData(MENURESOURCE_COMMAND,String("PLUGIN_CMD_1000472")); // add ActiveObject dialog to menu  
    
  if (last)  
      bc->InsDataAfter(MENURESOURCE_STRING,sc,last);  
  else // user killed plugin menu - add as last overall entry  
      bc->InsData(MENURESOURCE_STRING,sc);  
}  
  
Bool PluginStart(void)  
{  
  // example of installing a crashhandler  
  old_handler = C4DOS.CrashHandler; // backup the original handler (must be called!)  
  C4DOS.CrashHandler = SDKCrashHandler; // insert the own handler  
    
  // Planet Object  
  if (!RegisterPlanet()) return FALSE;  
  // Sun Object  
  if (!RegisterSun()) return FALSE;  
  
  return TRUE;  
}  
  
void PluginEnd(void)  
{  
FreePlanetXSerial();  
}  
  
  
Bool PluginMessage(LONG id, void *data)  
{  
  //use the following lines to set a plugin priority  
  //  
  switch (id)  
  {  
      case C4DPL_INIT_SYS:  
          if (!resource.Init()) return FALSE; // don't start plugin without resource  
          return TRUE;  
          if (!RegisterPlanetXSerial()) return FALSE;  
  
      case C4DPL_ENDACTIVITY:  
          FreePlanetXSerial(); return TRUE;  
  
      case C4DMSG_PRIORITY:   
          return TRUE;  
  
      case C4DPL_BUILDMENU:  
          //EnhanceMainMenu();       
          break;  
            
      case C4DPL_COMMANDLINEARGS:  
          {  
              C4DPL_CommandLineArgs *args = (C4DPL_CommandLineArgs* )data;  
              LONG i;  
  
              for (i=0;i<args->argc;i++)  
              {  
                  if (!args->argv[i]) continue;  
                    
                  if (!strcmp(args->argv[i],"--help") || !strcmp(args->argv[i],"-help"))  
                  {  
                      // do not clear the entry so that other plugins can make their output!!!  
                      GePrint("\x01-SDK is here :-)");  
                  }  
                  else if (!strcmp(args->argv[i],"-SDK"))  
                  {  
                      args->argv[i] = NULL;  
                      GePrint("\x01-SDK executed:-)");  
                  }  
                  else if (!strcmp(args->argv[i],"-plugincrash"))  
                  {  
                      args->argv[i] = NULL;  
                      *((LONG* )0) = 1234;  
                  }  
              }  
          }  
          break;  
  
      case C4DPL_EDITIMAGE:  
          {  
              GePrint("Something Changed");  
              C4DPL_EditImage *editimage = (C4DPL_EditImage* )data;  
              if (!data) break;  
              if (editimage->return_processed) break;  
              GePrint("C4DSDK - Edit Image Hook: "+editimage->imagefn->GetString());  
              // editimage->return_processed = TRUE; if image was processed  
          }  
          return FALSE;  
  }  
  
  return FALSE;  
}  
  

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2010 at 03:34, xxxxxxxx wrote:

Instead of

  
...  
case C4DPL_INIT_SYS:  
  if (!resource.Init()) return FALSE; // don't start plugin without resource  
  return TRUE;  
  if (!RegisterPlanetXSerial()) return FALSE;  
...  

do this

  
...  
case C4DPL_INIT_SYS:  
  if (!resource.Init()) return FALSE; // don't start plugin without resource  
  if (!RegisterPlanetXSerial()) return FALSE;  
  return TRUE;  
...  

Otherwise RegisterPlanetXSerial() will never be called.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2010 at 03:36, xxxxxxxx wrote:

LOL...  woops.  thanks Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2010 at 17:56, xxxxxxxx wrote:

okay so here's the code I am using right now.   Just the code to get me started.

  
//SERIAL CODE/////////////////////////////////  
//////////////////////////////////////////////  
#define ID_PLANET_OBJECT_SERIAL  = 1024924  
    
class PlanetXSerial : public SNHookClass  
{  
public:  
  String name;  
  
  PlanetXSerial()  
  {  
      name = GeLoadString(IDS_SERIAL_HOOK);  
      if(!name.Content())  
          name = "Planet X Generator";  
  }  
  
  virtual LONG SNCheck(const String &c4dsn,const String &sn,LONG regdate,LONG curdate)  
  {  
      return sn == String(name) ? SN_OKAY : SN_WRONGNUMBER;  
        
  }  
  
  virtual const String& GetTitle()  
  {  
      return name;  
  }  
};  
  
PlanetXSerial *snhook = NULL;  
  
Bool RegisterPlanetXSerial()  
{  
  snhook = gNew PlanetXSerial;  
  if (!snhook->Register(450000241, SNFLAG_OWN))  
      return FALSE;  
  return TRUE;  
}  
  
void FreePlanetXSerial()  
{  
  if (snhook)  
      gDelete(snhook);  
}  
    
///////////////////////////////////////////////////////////////////////////////////////////////////////////  

Here's the result I get when I look in the personalize dialog box. 
For some reason, it is saying "StrNotFound"  Where do I set the name.   And,  where do I check to see if the serial number they entered matches what they should enter?

Thanks,  Shawn

_<_img src="http://www.c4davenue.com/mag/wrong.jpg" height="291" width="703" border="0" /_>_

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 22/01/2010 at 08:50, xxxxxxxx wrote:

Any thoughts on this?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/01/2010 at 08:59, xxxxxxxx wrote:

figured it out..  Thanks,

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/01/2010 at 09:26, xxxxxxxx wrote:

I am trying to use StringToLong()   to convert the serial number to a long so that I can perform an algorithm on it.

For some reason, even though I have included c4d_string.h,   I am getting the error.

'StringToLong': identifier not found

Can anyone tell me why this is?

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/01/2010 at 19:56, xxxxxxxx wrote:

lol..  figured this one out too..    had to do

LONG lngMyLONG =  myString.StringToLong(&err);