views:

684

answers:

6

I'm working on a game (C#) that uses a Robocode-like programming model: participants inherit a base Class and add strategic behaviors. The game then loads instances of participants' Classes and the competition begins. Unfortunately, participants can "cheat" by sharing static variables between instances of their competitor Class.

How do I prevent static variable sharing between Class instances in a .NET language? I know this is accomplished in Java by using a separate ClassLoader per instance. What's the .NET equivalent?

Thanks in advance...

Note on the solution: my testing shows that separate AppDomains only work when loading a Class that extends MarshalByRefObject. I guess this makes sense - if you simply load a Serializable Class, the Class is copied into the current AppDomain so a second object from a different AppDomain will share its static vars. MarshalByRefObject guarantees that only a proxy is loaded into the current AppDomain and the statics stay behind in the loading AppDomain. See also: http://blogs.msdn.com/ericlippert/archive/2004/05/27/143203.aspx

+7  A: 

Load each competitor into a different AppDomain.

Roger Lipscombe
wouldn't that prevent the competitors from interacting (i.e. competing)?
James Curran
No, because you can marshal interfaces between the different appdomains, and have the communication restricted to only what the interface provides.
Roger Lipscombe
+6  A: 

static variables are per-AppDomain, so you could look into using different AppDomains, but I totally don't know what other consequences that may have.

Otherwise you could check the classes beforehand using reflection, and reject any classes that have static members.

Tobi
A: 

I don't have a specific answer, but I would look at the .NET Terrarium project. All participants are user loaded DLLs. They have done a lot of neat stuff to prevent unsafe and cheater code from loading/executing.

Justin Rogers has written extensively on Terrarium implementation details.

Anthony Mastrean
+2  A: 
if(typeof(CompetitorClass).GetFields(BindingFlags.Static))
{
 // take necessary steps against cheater!
}
ddc0660
A: 

That's solution in .NET plugin for real Robocode I'm working on.

Pavel Savara
A: 

Would the [ThreadStatic] attribute work for you? As long as your players are in different threads, it would probably do the trick. From the MSDN site:

A static (Shared in Visual Basic) field marked with ThreadStaticAttribute is not shared between threads. Each executing thread has a separate instance of the field, and independently sets and gets values for that field. If the field is accessed on a different thread, it will contain a different value.

Wagner Silveira