realm / realm-dotnet

Realm is a mobile database: a replacement for SQLite & ORMs
https://realm.io
Apache License 2.0
1.26k stars 165 forks source link

Missing realm-wrappers.dll #3332

Closed LulaczTV closed 1 year ago

LulaczTV commented 1 year ago

What happened?

I don't even know if I should post it here, but someone on stack overflow told me to do so (and also noone on mongodb forum is responding for 19 days).

I'm making a plugin for SCP Secret Laboratory server. I used before MongoDB driver as a connector to my DB, but I had some issues with it and someone told me to try realm. And I have problem with missing realm-wrappers file. Excatly, I have MongoDB server on my VPS, and whenever the plugin tries to connect to that, it throws error. I tried also compiling realm-wrappers on myself on linux (but due to .so file, it wasn't loading) and on windows, but it was throwing same error as I wrote below named as "second error".

Also, here's a plugin loader which one I'm using --> plugin loader link

Repro steps

  1. put plugin into Plugins folder.
  2. put dependencies to dependencies folder.
  3. restart server. 4.1. boom, error on loading dependencies (with realm-wrappers.dll) 4.2 boom, error on event (w/o realm-wrappers.dll)

Version

10.21.1.0

What Atlas Services are you using?

Local Database only

What type of application is this?

Unity

Client OS and version

Linux, I think it's debian 11 with pterodactyl panel.

Code snippets

`public async Task MongoDBConnect() { var app = App.Create("my-realm");

var user = await app.LogInAsync(Credentials.Anonymous());

var mongoClient = user.GetMongoClient("mongodb://user:password@ip:port/&authSource=admin&connectTimeoutMS=1000&socketTimeoutMS=1000&serverSelectionTimeoutMS=1000");
    var database = mongoClient.GetDatabase("db");
    collection = (IMongoCollection<PlayerModel>)database.GetCollection<PlayerModel>("playerdatas");

}`

Stacktrace of the exception/crash you're getting

The code is throwing this error on first line:

System.TypeInitializationException: The type initializer for 'Realms.Sync.AppHandle' threw an exception. ---> System.DllNotFoundException: realm-wrappers
    at (wrapper managed-to-native) Realms.SynchronizationContextScheduler.install_scheduler_callbacks(Realms.SynchronizationContextScheduler/get_context,Realms.SynchronizationContextScheduler/post_on_context,Realms.SynchronizationContextScheduler/release_context,Realms.SynchronizationContextScheduler/is_on_context)

and its second error after I added realm-wrappers.dll as a dependency which was generated by Visual Studio.

realm-wrappers.dll[0m" caused an exception.
    System.BadImageFormatException: 0x0x7f0195798020
    File name: 'In memory assembly'
        at (wrapper managed-to-native) System.AppDomain.LoadAssemblyRaw(System.AppDomain,byte[],byte[],System.Security.Policy.Evidence,bool)
        at System.AppDomain.Load (System.Byte[] rawAssembly, System.Byte[] rawSymbolStore, System.Security.Policy.Evidence securityEvidence, System.Boolean refonly) [0x0000e] in <05089c1b6989455fb1452c627044bac4>:0 
        at System.AppDomain.Load (System.Byte[] rawAssembly, System.Byte[] rawSymbolStore, System.Security.Policy.Evidence securityEvidence) [0x00000] in <05089c1b6989455fb1452c627044bac4>:0 
        at (wrapper remoting-invoke-with-check) System.AppDomain.Load(byte[],byte[],System.Security.Policy.Evidence)
        at System.AppDomain.Load (System.Byte[] rawAssembly) [0x00000] in <05089c1b6989455fb1452c627044bac4>:0 
        at (wrapper remoting-invoke-with-check) System.AppDomain.Load(byte[])
        at System.Reflection.Assembly.Load (System.Byte[] rawAssembly) [0x00005] in <05089c1b6989455fb1452c627044bac4>:0 
        at PluginAPI.Loader.AssemblyLoader.TryGetAssembly (System.String path, System.Reflection.Assemblyassembly) [0x00007] in <daac6f5711f648cd8233e51784f7642b>:0

Relevant log output

No response

nirinchev commented 1 year ago

Hm, I'm not super familiar with plugin development for SCP Secret Laboratory server, but here are some notes and questions:

  1. We should be able to support Debian 11 out of the box.
  2. The error message you're getting is slightly misleading because it's saying it's looking for realm-wrappers.dll, but in reality the extension is not necessarily that (it's an artifact of the windows-only days of .NET). So on Linux, the correct library would indeed be realm-wrappers.so.
  3. What CPU architecture are you deploying on? Is it x64 or Arm-based? If it's Arm, you'll need 11.0.0 of the SDK as 10.x only supports x64.
  4. When you're deploying the game, do you have the realm-wrappers.so file somewhere in the output directory?
  5. If you have a minimal project you can share with us, that will also be super helpful.
LulaczTV commented 1 year ago

I checked and updated version to 11.0.0 and it seems to be working (it's not trying to find realm-wrappers), but now it throws new error:

System.TypeLoadException: VTable setup of type _4Site_Main.PlayerModel+RealmHelper failed
    at (wrapper managed-to-native) System.RuntimeType.GetMethodsByName_native(System.RuntimeType,intptr,System.Reflection.BindingFlags,System.RuntimeType/MemberListType)
    at System.RuntimeType.GetMethodsByName (System.String name, System.Reflection.BindingFlags bindingAttr, System.RuntimeType+MemberListType listType, System.RuntimeType reflectedType) [0x0001b] in <05089c1b6989455fb1452c627044bac4>:0 
    at System.RuntimeType.GetMethodCandidates (System.String name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConv, System.Type[] types, System.Int32 genericParamCount, System.Boolean allowPrefixLookup) [0x00010] in <05089c1b6989455fb1452c627044bac4>:0 
    at System.RuntimeType.GetMethods (System.Reflection.BindingFlags bindingAttr) [0x00000] in <05089c1b6989455fb1452c627044bac4>:0 
    at PluginAPI.Core.Extensions.ReflectionExtensions.IsValidEntrypoint (System.Type type) [0x00000] in <daac6f5711f648cd8233e51784f7642b>:0 
    at PluginAPI.Loader.AssemblyLoader.LoadPlugins (PluginAPI.Loader.Features.PluginDirectory directory) [0x0018c] in <daac6f5711f648cd8233e51784f7642b>:0

I think it's about my playermodel class, but I have no idea what can cause that:

    public class PlayerModel : RealmObject
    {
        public ObjectId Id { get; set; } 
        public string DiscordID { get; set; }
        public string SteamID { get; set; }
        public int Level { get; set; }
        public int Points { get; set; }
        public int HPLevel { get; set; }
        public int StaminaReg { get; set; }
        public int StaminaLevel { get; set; }
        public int AvailablePerks { get; set; }
        public int Kills { get; set; }
        public int Deaths { get; set; }
        public int Escapes { get; set; }
        public int ColasUsed { get; set; }
        public int AdrenalinesUsed { get; set; }
        public int BallsUsed { get; set; }
        public int MedkitsUsed { get; set; }
        public int PillsUsed { get; set; }
        public int RoundsPlayed { get; set; }

    }
nirinchev commented 1 year ago

That seems pretty awkward error and your model seems perfectly reasonable, so I wouldn't expect it to fail in such a way. Can you double check that you're not accidentally referencing different versions of Realm in your project? That's the only thing I can think of that would cause this error. Not sure how your project is setup, but if you're somehow including Realm via multiple paths, you need to make sure these are all at the same version. Then you probably want to wipe all intermediate build artifacts to make sure you're doing a clean build and Unity is not copying some outdated dlls somewhere. If that fails, I'll probably need to see either the compiled dlls or a repro project that I can debug locally.

LulaczTV commented 1 year ago

Sorry, I forgot to update Realm.dll in dependencies, after restart plugin again throws error about missing dll. Here's my whole project: https://github.com/LulaczTV/4Site-Main

nirinchev commented 1 year ago

Looking at the bin/release folder, it doesn't seem like you're including the wrappers for linux - only the windows wrappers are included. This is most likely because you're including the net46 props file which copies them to the output directory. Not sure how this plugin is being imported into the main Unity project, but you probably need to either copy the wrappers for other platforms or have your Unity project take a dependency on the Realm unity package.

Note that if you're copying the native binaries manually, you probably want to configure their metadata so that they're only included when building for their respective platforms.

LulaczTV commented 1 year ago

I don't import anything to unity, it's actually just a visual studio project with some game dependencies which one I compile. And also I'm not sure what about are you actually talking about, I'm not that advanced in things like that.

nirinchev commented 1 year ago

Hm, looks like there's some misunderstanding - I assumed your project is eventually getting imported into a Unity game because in the issue template you filled out, you said the type of application you're using Realm in is "Unity". I guess you meant this being a game and Unity seemed closest from the options.

In any case, things seem clearer now - forget everything about Unity. The issue appears to be that when you compile your project, the native binaries for Linux are not included because MSBuild has no idea it needs to include them. To test if that's the case, can you try copying librealm-wrappers.so from the runtimes/linux-x64/native folder from the NuGet package (should be in packages/Realm) to the bin/Release folder. This should hopefully allow the application to find the native dependency automatically.

LulaczTV commented 1 year ago

It didn't help, but I fixed it finally on my own. I saw in logs some strange spam of this information: [2023-06-01 15:33:29.491 +02:00] [STDOUT] Fallback handler could not load library /home/container/SCPSL_Data/MonoBleedingEdge/x86_64/librealm-wrappers [2023-06-01 15:33:29.491 +02:00] [STDOUT] Fallback handler could not load library /home/container/SCPSL_Data/MonoBleedingEdge/x86_64/librealm-wrappers.so [2023-06-01 15:33:29.491 +02:00] [STDOUT] Fallback handler could not load library /home/container/SCPSL_Data/MonoBleedingEdge/x86_64/librealm-wrappers.so [2023-06-01 15:33:29.491 +02:00] [STDOUT] Fallback handler could not load library /home/container/SCPSL_Data/MonoBleedingEdge/x86_64/librealm-wrappers [2023-06-01 15:33:29.491 +02:00] [STDOUT] gpath.c:115: assertion 'filename != NULL' failed and I just needed to put .so file into this folder.

So yeah, missing dll is fixed, but now, how I can connect to my MongoDB using realms? as I can see I need client app ID, but how I can get it when I have DB hosted on my VPS?

nirinchev commented 1 year ago

Hm... unfortunately, Realm only works with MongoDB Atlas - it cannot connect to a self-hosted MongoDB instance if that's what you mean by I have DB hosted on my VPS.

LulaczTV commented 1 year ago

oh, so what I should use instead of realm, do u know any which I can use?

nirinchev commented 1 year ago

If you want to connect to MongoDB directly, you can use the MongoDB C# driver. If you want to store data locally on the device, you can use Realm as a local database where you pull the data from MongoDB using the C# driver, then transform it and store it into Realm using the Realm SDK.

LulaczTV commented 1 year ago

I can't use MongoDB C# driver, as I said before I had problems with this error: MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.MissingMethodException: void System.Security.Cryptography.Rfc2898DeriveBytes..ctor(string,byte[],int,System.Security.Cryptography.HashAlgorithmName)

and someone told me to use Realm instead but yeah...

nirinchev commented 1 year ago

The driver exception seems weird since this constructor is definitely available on .NET 4.8. Might be a good idea to ask in the MongoDB forums/StackOverflow since that would be your best bet for connecting to a self-hosted MongoDB instance.