Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Unity is telling me this object should be marked "ExtensionOfNativeClass"

Discussion in 'Scripting' started by MikeyJY, Dec 7, 2021.

  1. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    I have this save class:
    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.IO;
    4. using System.Runtime.Serialization.Formatters.Binary;
    5.  
    6. public static class SaveManager
    7. {
    8.     public static string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\GameName\Save1\World.save";
    9.  
    10.     public static void SaveDataToFile(Save save)
    11.     {
    12.         BinaryFormatter formatter = new BinaryFormatter();
    13.         FileStream file = new FileStream(path, FileMode.OpenOrCreate);
    14.         formatter.Serialize(file, save);
    15.         file.Close();
    16.     }
    17. }
    The parameter save of type Save is an instance of a serializable class which contains fields of data, for example, player position, buildings, items, etc. Unity tells me in console that I need to mark the static SaveManager class as an extension of a native class. I don't know what that attribute means or why I should use it here. The World.save file however seems to appear in the %appdata%/local/GameName/Save1/World.save, but is empty.

    The LoadManager looks similar:

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.IO;
    4. using System.Runtime.Serialization.Formatters.Binary;
    5.  
    6. public static class LoadManager
    7. {
    8.  
    9.     public static string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\0    TheOceanGame\Save1\World.pirate";
    10.  
    11.     public static Save LoadDataFromFile()
    12.     {
    13.         BinaryFormatter formatter = new BinaryFormatter();
    14.         FileStream file = new FileStream(path, FileMode.Open);
    15.         Save save = (Save) formatter.Deserialize(file);
    16.         file.Close();
    17.         return save;
    18.     }
    19. }
     
    Last edited: Dec 7, 2021
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    Dunno about all that, but did you know this:

    Don't use the binary formatter/serializer: it is insecure, it cannot be made secure, and it makes debugging very difficult, plus it actually will NOT prevent people from modifying your save data on their computers.

    https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide

    I'd suggest JSON as an alternative mechanism.

    Problems with Unity "tiny lite" built-in JSON:

    In general I highly suggest staying away from Unity's JSON "tiny lite" package. It's really not very capable at all and will silently fail on very common data structures, such as Dictionaries and Hashes and ALL properties.

    Instead grab Newtonsoft JSON .NET off the asset store for free, or else install it from the Unity Package Manager (Window -> Package Manager).

    https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

    Also, always be sure to leverage sites like:

    https://jsonlint.com
    https://json2csharp.com
    https://csharp2json.io
     
    Deleted User likes this.
  3. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    If BinarySerialization will not prevent users to edit data in the save I will need another methods of save. However I guess JSON is not safe either from this perspective since is human-readable, nor XML.
    So:
    JSON is human readable
    XML is human readable to
    Serialization is editable with special tools

    then what 100% non editable solution I have? Maybe I can code an entire alphabet where each letter is different and save with the encoded alphabet. Or maybe I can use the steam clouds to save players data and no one can access their own game saves.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    Absolutely none; if you can edit your files so can another app. No security is 100%.

    Want to get to 99%, though? Easy. Use JSON, then run the resulting string through some encryption layer where your app holds the keys. They'd have to crack the encryption to read the file.

    (Never XML. It's the absolute worst. Objectively worse than JSON in every possible measure.)
     
    Kurt-Dekker likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    If you're concerned about the user 'hacking your save files,' or 'cheating in your game,' just don't be. There's nothing you can do about it. Nothing is secure, it is not your computer, it is the user's computer. If it must be secure, store it on your own server and have the user connect to download it.

    Anything else is a waste of your time and the only person you're going to inconvenience is yourself when you're debugging the game and you have savegame errors. Work on your game instead.

    Remember, it only takes one 12-year-old in Finland to write a script to read/write your game files and everybody else can now use that script. Read about Cheat Engine to see more ways you cannot possibly control this.
     
  6. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,907
    Write it in binary and encode it. Burry the key randomly. Use native plugin to do all of these.
    But even that isn't 100%. Anything exist on a computer at the user is breakable.

    If you want to deter average Joe, here is a binary save system explanation: https://catlikecoding.com/unity/tutorials/hex-map/part-12/
    You will need to ignore the environment, it is part of a bigger tutorial series about hexmaps, but you can separate the save/load technique.
     
  7. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    To be honest, If I think about it, I probable don't really care. When I was a kid and played games I saw cheating in single player like this: If having all items you want without work is entertaining, then do it. So, for most people, the enjoyment of a game comes from challenges. If you want to modify the save file and give you all items then do it. It is not the developer's business if a random user decides to hack the save. They will take the entertaining part of the game, which is something I can't control.
    Probable I will place the save files on the steam cloud since it is free, if you have a steam app. Not for secureness, just because on the steam page Steam Clouds Saves are a feature that can appear on the store page.
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    Considering how many folks post issues related to integrating Steam, it's certainly not technically free.

    Good luck! :)
     
  9. MikeyJY

    MikeyJY

    Joined:
    Mar 2, 2018
    Posts:
    530
    And for the initial problem, in case anyone has that error. It caused it because the class SaveManager was not static and was attached to a game object, then I changed it to be static and not derive from MonoBehavior and the component from the gameobject remained in the scene with this error. I deleted the game object and now the error is gone.