Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Anti-Cheat Toolkit: stop cheaters easily!

Discussion in 'Assets and Asset Store' started by codestage, Aug 20, 2013.

  1. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    This is weird. I just tried to encrypt value with 1.0.1.2 version. And it was successfully decrypted with latest version using key e806f69e7aea3ee30fe27a6abfae967f and 4444 key for ObscuredString.EncryptDecrypt() method as I described above.

    Could you please confirm you use both e806f69e7aea3ee30fe27a6abfae967f and 4444?
    And you set new crypto key before accessing prefs?

    I'd be glad to contact with you via skype for higher productivity and help you to resolve this issue. Feel free to add me there (dmitry.you).
     
  2. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    I checked one more time, that was my mistake - i rewrote data with new encryption key and tried to read with the old one.
    Thank you very much!
     
  3. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Yey, glad it worked!
    Thanks for letting me know it.
     
  4. Sashko

    Sashko

    Joined:
    Apr 25, 2014
    Posts:
    1
    Great plugin, Dmitriy.
    But I had an unfortunate issue after applying ObscuredPrefs to our project with update.

    The problem is when user still has unencrypted PlayerPrefs keys, method "HasKey" doesn't check for it, but look only for encrypted key.
    So here is fixed “HasKey” method, and I also added deleting original unobscured key in “DeleteKey” method.
    Code (csharp):
    1.  
    2. public static bool HasKey(string key)
    3. {
    4.     if (PlayerPrefs.HasKey(EncryptKey(key)))
    5.         return true;
    6.  
    7.     return PlayerPrefs.HasKey(key);
    8. }
    9.  
    10. public static void DeleteKey(string key)
    11. {
    12.     PlayerPrefs.DeleteKey(key);
    13.     PlayerPrefs.DeleteKey(EncryptKey(key));
    14. }
     
  5. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks for noticing this, Sashko!
    Will apply these fixes at the upcoming update.
     
  6. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey there! I glad to let you know another update just hit the Asset Store!
    It's kind of maintenance release mostly.

    What's new in 1.2.9:
    - cheating detection added to the ObscuredQuaternion, ObscuredVector3, ObscuredVector2, ObscuredString
    - fixed rare critical bug in ++ and -- operators of some obscured types leading to false detections (huge thanks redux!)
    - fixed ObscuredPrefs.HasKey() and ObscuredPrefs.DeleteKey() were not count regular PlayerPrefs keys (thanks Sashko)
    - fixed possible access issue while reading from AllowedAssemblies.bytes file in editor (thanks Sabastiano)
    - fixed possible fndid file corruption leading to the false positives in Injection Detector (thanks Sabastiano)
    - access to the x, y, z fields was added to the ObscuredVector3 (access by index was implemented as well)
    - access to the x and y fields was added to the ObscuredVector2 (access by index was implemented as well)
    - DetectorsUsageExample script was moved from Anti-Cheat Toolkit Detectors prefab to the separate GameObject
    - minor fixes in the API docs

    Have fun!
     
    Last edited: May 2, 2014
  7. Whiskan

    Whiskan

    Joined:
    Apr 13, 2014
    Posts:
    4
    Is this playmaker compatible or does it have custom playmaker actions?
     
  8. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Currently I did not implement any Playmaker support here and actually I'm not sure if it needs to be done at all. I never tried to use playmaker so I can't say if it will work with it or not, sorry.

    I'll add playmaker integration into the TODO and investigate it later though. Thanks for your question!
     
  9. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
  10. Whiskan

    Whiskan

    Joined:
    Apr 13, 2014
    Posts:
    4
    Excellent! If I knew it had some sort of playmaker support, I wouldn't think twice about picking this up! And, yes - the 50% off sale is the reason I thought I'd ask! Hopefully this is something you consider ;)
     
  11. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks once again, I try to implement all features my customers requesting for (if it is possible and reasonable of course). So yeah, I consider supporting playmaker for sure, will investigate this.
     
  12. spectra

    spectra

    Joined:
    May 6, 2014
    Posts:
    11
    Please, open your facebook message.

    I have 2 question related to this AntiCheat Toolkit asset. :)
     
    Last edited: Jan 18, 2015
  13. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey. Sylvia! I'm sorry, but I don't see any messages from you on facebook. Could you please send it some another way, like skype or contact form in my blog: http://blog.codestage.ru/contacts/?

    Thanks!
     
  14. spectra

    spectra

    Joined:
    May 6, 2014
    Posts:
    11
    Owh, firefox my slow internet connection fools me. Yeah, my PM was not send. I send a message again. Please, check your Facebook inbox. Why facebook? Most of my online time is for facebook. It's very fast on my slow internet connection.

    Please check it.. Thank you.. :)
     
  15. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    It's really sorry to admit, but I still have no new messages in my inbox on the facebook =(
     
  16. spectra

    spectra

    Joined:
    May 6, 2014
    Posts:
    11
    Well... I've just checked it. And yes, facebook tell me that my message was send successfully.

    Since you're quite sure that didn't receive my message. Then, give your email contact that I can send my 2 questions. Why not posted here? Because I also provided a link to my file that you can investigate with AntiCheat_Toolkit.

    Oh, I got an idea. I send you a PM in this forum. Please, check it!
     
    Last edited: May 8, 2014
  17. basilmon92

    basilmon92

    Joined:
    Apr 25, 2014
    Posts:
    2
    I bought ACT but I got the following error just after importing them.

    Please check the screenshot attached.

    $error.png
     
  18. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, I just answered you in email, it was not necessary to send me additional pm and post here simultaneously, any of these is enough =)
     
  19. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Hi Friend,

    I was just trying to wrap my head around this: Obscured types usually require additional resources comparing to the regular ones. Please, try keeping obscured
    variables away from Updates, loops, huge arrays, etc. or just keep an eye on your Profiler metrics, especially while
    working on mobile projects (I tried to use simple obscured variables in Update() on iPad1 without any noticeable
    performance drop though).

    and I came to a conclusion if I do my speed (on an agent NavMesh) like this;

    if (agent.speed != Speed)
    {
    Debug.Log("changing speed through obscured...");
    agent.speed = Speed;
    }

    (Speed is an ObscuredFloat)

    basically this will only change it while the obscured speed is different than the actual "agent" speed, meaning it will not slow down as much until "speed" has actually changed? is this a good work around to not "call it on update" often or does this fix nothing :D

    also can you please explain to me a little more about how to use; SetNewCryptoKey(). I couldn't get much from the pdf.

    and is Speed Hack Detector useful for mobile games?

    also :) Don't forget you still need to call SpeedHackDetector.StartMonitoring() from code to start detector!

    I cannot do a SpeedHackDetector.StartMonitoring() in my script, am i missing something?

    thanks
     
    Last edited: May 13, 2014
  20. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey again!

    I'm afraid it doesn't help too much here since when you compare regular float with obscured one, obscured type automatically decrypts (to let you compare it with not obscured value) and uses same amount of resources it would use for encryption. So, if agent.speed != Speed, you'll get both decryption and encryption, and only decryption otherwise.

    I'd suggest to not bother about it and look closer into the profiler to make sure obscured type is really slows something down there.

    Sure, this method allows to change default crypto key, used to obscure data. Every obscured type and ObscuredPrefs has such method. Not sure what more can I add here.

    Yes, Speed Hack Detector should work just fine on mobiles and detect speed hacking there.
    Please, use StartDetection() method instead of StartMonitoring, since it was renamed (you could notice it in the changelog). I forgot to update it in readme (already did, will roll out with next update).
     
  21. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Okay makes sense about the StartDetection vs StartMonitoring,

    is there any way you can please give me an example on how to use SetNewCryptoKey()
     
  22. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Sure, I'd suggest to use it somewhere in the initial stage of your application. You need to call it only once.
    In Awake of any main game object in the first stage, for example:

    Code (csharp):
    1. void Awake()
    2. {
    3.     ObscuredFloat.SetNewCryptoKey(12345);
    4.     ObscuredInt.SetNewCryptoKey(65432);
    5.     // etc.
    6. }
    Same for any other obscured type you wish to use in your project with your custom encryption key.

    One important note here: if you wish to use custom crypto key for ObscuredPrefs - you should consider any data saved with one encryption key will not be accessible with any other encryption key, so set it once somewhere, before using ObscuredPrefs.
     
  23. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Perfect,

    so this just sets a key so only I will know it and can use it, how do I then use this key, or for what do I use the key ?

    all I have to do is set it and then I'm done, or is there any other stuff later on I have to do to use it?



     
  24. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    This key will be used to obscure variables.
    Obscured types use hard coded keys by default, but you may change them using this method if you wish.
    I'd suggest to do that if you have chance to store your key outside of your app, on server for example. You also may set this key in the editor inspector for additional security (just like it's done in example).
    But it's not necessary to change default crypto key at all, I just let you do it for additional flexibility, so don't bother if you're not sure why do you need it at all =)
     
  25. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    haha perfect, thanks sounds great :)
     
  26. Agostino

    Agostino

    Joined:
    Nov 18, 2013
    Posts:
    21
    Hello, I'd like to know 2 things:
    - the encryption algorithm you are using
    - if the commented source is available

    Thanks.
     
  27. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hi!
    I use fastest and most basic encryption there, based on the XOR operation (since there is no sense in using stronger encryption with additional resources waste in this case).
    Full sources are included, all public API is fully documented (and has online API reference, generated by doxygen). There are no comments in the methods and for any private \ internal stuff though. I tried to keep code clean and readable.
     
  28. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Here I go again with some stupid questions :)

    SpeedHackDetector.StartDetection(KZSpeedHackDetected, 9.99f, 5);
    InjectionDetector.StartDetection(KZInjectionDetected);

    this is my script, on start

    now, do I need to have a gameobject with SpeedHackDetector component and Injection Detector on my scene or?


    Can't i just go with the code:

    SpeedHackDetector.StartDetection(KZSpeedHackDetected, 9.99f, 5);
    InjectionDetector.StartDetection(KZInjectionDetected);

    Or maybe I do have to have the gameobjects too hey? lol
     
  29. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey again! =)
    You may go with that code only, appropriate game objects will be created automatically if they are not exist.
     
  30. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    great,

    so I guess

    afterwards when your awesome asset tracks down the wanker which trying to cheat you do stuff here:

    protected void KZSpeedHackDetected()
    {
    // example
    Application.Quit();
    }
    protected void KZInjectionDetected()
    {
    Application.Quit();

    }
     
  31. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Yep. You even may use same callback for both detectors if you wish to perform same actions.
    I'd suggest to use InjectionDetector with care and test it for any false positives first though, it's still in beta stage and may produce false detections.
     
  32. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    I guess that'll piss off some players, I'll give them your contact info so they can take it out on you :D haha i joke
     
  33. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Hey how come a public ObscuredFloat does not show up in the inspector?
     
  34. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    This is a known issue (Unity limitation) and it will be fixed in one of next updates.
     
  35. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    ah,

    okay they better fix their issues when they wanna squeeze out 4500$ for pro + the plugins...
     
  36. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    It's already fixed and will be rolled out with Unity 4.5, so I'll release support for this after 4.5 release.
     
  37. Agostino

    Agostino

    Joined:
    Nov 18, 2013
    Posts:
    21
    Well, then don't worry about the key length problem with Apple, this is not really secure encryption anyway.
    The key should be at least as long as what you are trying to mask, but I guess you can hash it to lengthen it.

    This kind of simple xor encryption, called one time pad (OTP), becomes very easy to break if it's used more than one time (on different numbers)
    https://www.google.com/search?q=one+time+pad+used+twice
    Moreover, it's even easier to break if you know what the encrypted message looks like.
    I guess you know that, and it's probably not a problem for RAM analysis, but save-games could use a stronger encryption, IMHO.
     
    Last edited: May 15, 2014
  38. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Yep, I did brute-forced XOR in past and absolutely know what I'm doing ;)
    Any stronger encryption has no point here, since any code you use on client is available for cheater and if he is be able to brute-force xor - any other encryption will not stop him. You'll just get lower performance and possible issues with Apple (key length should be 64 bit or shorter, see my answer on Apply stuff here: http://forum.unity3d.com/threads/196578-Anti-Cheat-Toolkit-RELEASED?p=1393380&viewfull=1#post1393380, and it's really easy to brute-force such short keys, even if we are talking about RSA, El-Gamal, etc.) with almost no efficiency against skilled people.
     
  39. Agostino

    Agostino

    Joined:
    Nov 18, 2013
    Posts:
    21
    My point is, there really is no need to even use brute force, you can use very efficient tricks to extract a xored password.
    Example here. Such simple calculations could be done even by hand.

    The problem is not with Cheat Engine and variables in memory, your trick is enough to stop most of the script kiddies.
    My point is that then those variables are saved in savegames, it becomes really trivial to fire up an HEX editor and start xoring values.
     
  40. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    It doesn't changes anything actually, since it's doesn't enough to just open saves in HEX editor, since I do not save plain XOR result, so you'll have to look at sources anyway to understand how to reach xorred values and how to change them. Moreover, I have tampering detection included, so cheater will have to deal with tampering detection algorithms as well to avoid being banned or whatever developer prepared for such people. And it of course will not stop any really skilled enough for hacking all this cheater, as any other encryption will not stop him as well.
     
  41. kreischweide

    kreischweide

    Joined:
    Jan 2, 2013
    Posts:
    7
    Hi, thanks for you great asset.

    I have completed the integration to a project that is based on PlayMaker and only had one or two major problems. Still there are some minor issues / suggestions I have:

    - Would'nt it be better to have monitoring of all variables or specific ones? I was suprised that I had to use the static delegate ObscuredInt.onCheatingDetected instead of a event for a specific instance of ObscuredInt. I guess, even if i wanted to react onCheatingDetected, would'nt I want to do it on every available obscured type, like ObscuredViolationDetector.StartDetection(callbackMethodName, ...)? I found it quite handy the way it is handled for the SpeedHackDetector.

    - It seems that the spawned "Speed Hack Detector" GameObject can not be killed after playing the game in Editor Mode. The objects stays until it is deleted manually. Maybe its a racing condition with something?

    - If I use the SpeedHackDetector, what would be the right way to dispose of it? Will it stop when the starting GameObject/Script will be killed or would there be a way to do so? Is it enough to call StopMonitoring?

    - Using the ObscuredTypes in PlayMaker was a bit of a challenge. Maybe my approach could help you on how to possibly integrate it: As PM does not support new data types, I had to work around it. PM offers a type "Object" which needs to be at least UnityEngine.Object or MonoBehaiviour. So I had to create an empty game object, attach a proxy class to it, which holds the obfuscated data type (int and bool in my case) and prefab that thing. Everytime i would need a new variable, I just added a FsmObject, attached the Prefab and could use CallMethod and or customized implementations. It makes it a bit more prone to attacks but hey, at least it works ;) If you want to can take a look at https://dl.dropboxusercontent.com/u/3963769/projekte/unity/act-stuff.zip for example implementation of some int and bool stuff.
     
    Last edited: May 16, 2014
    codestage likes this.
  42. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, kreischweide!

    Thanks for letting me know it is possible to integrate ACT within PlayMaker-based project!
    I'd glad to know about major issues you faced with (except obscured types proxies) though. Did you changed something in plugin code to make it work with your project?

    Yes, this is a one of features I'm going to re-implement in future. It is really annoying you have to set delegate for each possible obscured type you'll use in project. I'm going to make one common cheating detection manager for all obscure dtypes.
    Currently Obscured*.onCheatingDetected will fire only once for each obscured type, on first cheating detection. So until I implement one central obscured types cheating detector, you're free to set same delegate for all used obscured types and unsubscribe from it on detection by hand.
    Thanks for popping it up again, I'll move it upper in my TODO list.

    This is weird. It should remove itself from scene if it was spawned at Play Mode =\ Could you please contact me in PM or via skype (dmitry.you) for further inspection of this issue?

    You may dispose it correctly using SpeedHackDetector.Dispose(); method. It will destroy spawned game object and stop all internal processes. StopMonitoring (will be renamed to the StopDetection in new update) allows to stop all internal processes and keep object for further usage (new object will not be spawned on StartDetection() in such case).

    Huge thanks, I'll look at this of course as I approach "PlayMaker support" item in my TODO.
    And thanks for overall feedback as well, very appreciated!
     
  43. mog-mog-mog

    mog-mog-mog

    Joined:
    Feb 12, 2014
    Posts:
    266
    Hello, I've purchased the asset and trying to understand it by reading pdf. As per documentation, it covers 4 types of threats:
    - Memory cheating (prevention + detection)
    - Saves cheating (prevention + detection)
    - Speed hack (detection)
    - DLL injection (detection, experimental)

    Can you please help me in understanding Which threats are applicable to which platform? We are trying to use this asset in our mobile- ios + android game- and would like to know which threats could be of concern to us. Does Speedhack is also applicable for mobile?
     
  44. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hi, lilboylost!

    All these threats are actual for mobile platforms with one exception - DLL Injection have no effect on iOS since iOS builds are compiled to native code and managed assemblies are left for compatibility reasons only (reflection, etc.), so cheater will have no benefits of his managed assembly injected into your iOS app, if it is possible at all.

    SpeedHack is absolutely possible on mobile, at least on rooted Android (saw working solutions).

    I'd suggest to consider first three threats are possible on your target platforms. DLL Injection is theoretically possible on Android AFAIK, but I didn't saw working solutions yet.
     
  45. PDZ

    PDZ

    Joined:
    Sep 12, 2013
    Posts:
    18
    Hey Dmitriy,

    In my project I have a class which I serialize. I bought your plugin and want to use some of your obscured data types instead of the normal ints/strings etc. However because the obscured data type classes aren't serializable I can no longer serialize the class that uses them.

    If I make some of your classes implement ISerilizble does that have any negative affect on your system or will it create any vulnerabilities if that serialized class is saved and restored?

    Thanks,

    Peter
     
  46. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, Peter!
    I'm sorry for the late reply, looks like notifications were broken for some time on new forums.
    I'd suggest you to use GetEncrypted \ SetEncrypted methods of the obscured types vars of you wish to store or send encrypted values somewhere and read it to the obscured vars later.

    Also you may try to serialize few types I made serializable for Unity in 1.3.0 update (see my next post here for details).
     
  47. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Anti-Cheat Toolkit 1.3.0 update is already at the Asset Store, yay!
    Lots of stuff were done.
    Most important:
    - Unity inspector support for ObscuredString, ObscuredInt and ObscuredFloat. Last two requires Unity 4.5 or later (structs serialization needed). I'll add inspector support for some other obscured types in future as well.
    - I've made InjectionDetector whitelist. Now you can add any dynamic or external assemblies there to let detector skip them.
    - Centralized Obscured variables cheating detector. No more need to set callbacks for every obscured type.

    So, here is full changelog:
    1.3.0 [06.06.14]
    - ObscuredString fields are now editable from inspector
    - ObscuredInt and ObscuredFloat fields are now editable from inspector (Unity 4.5 or higher required)
    * in case int->ObscuredInt \ float->ObscuredFloat replacement, old values set in inspector will be reset to defaults!
    * experimental inspector support for the obscured structs instances, report any bugs please
    - ObscuredCheatingDetector implemented
    * central detector for all Obscured types (except ObscuredPrefs) cheating detection
    * replacement for legacy onCheatingDetected Action callback
    - Injection Detector user-defined Whitelist Editor implemented
    * allows gather assembly data both from files and manually (for assemblies made in realtime)
    - ObscuredPrefs.ForceDeviceID(string) method introduced
    * useful if you have server-side authorization, especially on iOS (we have no reliable way to get device ID there)
    - Injection Detector data file is restored now if it was accidentally removed
    - public API StopMonitoring was renamed to the StopDetection for all detectors
    - most of Vector3 operators are now supported by ObscuredVector3
    - fixed possible false positives in Speed Hack Detector caused by system time / date change
    - fixed exception in ActPostprocessor while trying to write into the read-only file (thanks Sebastiano Mandalà)
    - fixed possible false positives for ObscuredVector3, ObscuredVector2, ObscuredQuaternion cheating detection.
    - added ability to force Injection Detector data collection for unsupported platforms for debugging
    - Injection Detector will be re-enabled after switching from unsupported target if it was enabled previously
    - significant refactorings in the detectors code
    - service data cleanup code simplified
    - improved removing of obsolete editor prefs used by ACT
    - refactorings in the Editor scripts and file structure (remove prev version before updating to avoid collisions!)
    - fixed possible name conflicts: MenuItem, Action
    - minor fixes and optimizations
    - minor fixes in documentation

    Have fun!
     
    Last edited: Jun 9, 2014
  48. mog-mog-mog

    mog-mog-mog

    Joined:
    Feb 12, 2014
    Posts:
    266
    Hello,

    I am using ObscuredInt and other datatypes in my game. When I try to save them to cloud, I am using .NEt serialization which complains - ObscuredTypes are not serializable. I've added atrribute [Serialiazable] to ObscuredInt and it works fine. My worry is - I'll lose my changes with future updates.

    Is it possible for you to make all types Serializable? They should behave as close as possible to the primary datatypes and native serialization will surely help. Would be great if you can add that in next update.

    Thanks
     
  49. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @lilboylost!
    Looks like you're talking about previous versions. Current release version has [Serializable] ObscuredInt, ObscuredFloat and ObscuredString (they need to be serializable for inspector support).

    Current dev version has ObscuredBool exposed to the inspector as well. And [Serializable] attribute will present on all other obscured types as well in that update.

    Please, note: XmlSerializer is not supported, only binary serialization possible.
     
    Last edited: Jun 30, 2014
  50. mog-mog-mog

    mog-mog-mog

    Joined:
    Feb 12, 2014
    Posts:
    266
    Yes, you are correct. I am using ObscuredLong - which does not have the attribute. Just checked that Int has Serializable attribute, would be great to add to other primitive types as well.

    Thanks