Question

I am building a sort of modding system for a certain aspect of my game in Unity. It basically allows the common user to write some C# code which will be used to give access to certain elements of the game at certain times, like giving the host of a multiplayer server the ability to decide what map to load with what parameters etc.

For those of you who don't know, Unity uses Mono's equivalent of .NET 2.0, so this question is less specific to Unity and rather more towards C# and .NET.

I already have the assembly loading working, but now I've come to the point where it would be very nice if I could give the "user" some access to assemblies such as System and UnityEngine. I could of course include the dll's in the ReferenceAssemblies property of the CompilerParameters, but that would give them access to possibly harmful functionality, such as reflection, Instantiate, Destroy as well as many others.

How would I limit the assembly references to only certain namespaces, such as System.IO and System.Collections, without giving access to System.Reflection?

Now for the posting of some possibly relevant code:

//Excuse the UnityScript... I find it quicker to do things in
//It's basically C# with Javascript syntax ;)

//Create compiler parameters
var params:CompilerParameters = new CompilerParameters();
params.GenerateExecutable = false;
params.GenerateInMemory = false;

//Add assembly reference
params.ReferencedAssemblies.Add("System.dll");
//I wish I could put System.IO in here instead of System.dll

//Create provider and load/compile assembly
var provider:CodeDomProvider = new CodeDomProvider.CreateProvider("CSharp");
var results:CompilerResults = provider.CompileAssemblyFromFile(params, path);

I am already aware of the workarounds, such as creating a wrapper assembly and only give them that, however it would save a lot of time if I was able to do this in a more direct way.

Was it helpful?

Solution

EDIT

There is a library (a set of libraries actually) called NRefactory. Have a look here for an indepth look at its features.

Basically what you can do is analyse all of the DLL's that you load at runtime using NRefactory and create wrappers with a simple C# program that you will write yourself.

The idea is that you create some boilerplate invoke wrappers that will be part of your gateway class and then process all of the libraries you are interested in and populate the gateway class.

Now you have a gateway that is able to call every method in question. Then you just cut the invoke wrappers that you don't need.

It sounds complicated but in reality it's not. I've used this approach to produce something similar on another project. NRefactory is a very powerful tool that gives you amazing possibilities when it comes to analysing and emitting C# code.

ORIGINAL

From what I know (which is not a lot :) ) you can't do this. The simple reason being that your domain will get the dll and all of it's publicly accessible members.

Blocking invokes on those members is not possible without some sort of a gateway.

Implementation of such a gateway is a different story altogether. But as you said it will take time and effort to do this.

I don't think that limiting use of UnityEngine is a good idea. You are basically cutting all relevant Unity functionality.

Perhaps you shouldn't restrict your modders in such a 'strict' way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top