0

I'm modding a game, and I've run across a problem. I'm trying to draw text to the screen in C# with .NET and XNA, so i'm using XNA's SpriteBatch.

The problem is, I can't modify any source files. I can only load external .cs files. I can LOOK at the source, and the variable is defined as so in the class Main.cs:

private SpriteBatch spriteBatch;

If I define my own SpriteBatch as so:

public SpriteBatch spriteBatch;

then it doesn't draw, because I don't have a draw method. Now, all I want to do is access Main.spriteBatch, but that variable is private as mentioned before.

Any ideas?

Otiel
  • 18,404
  • 16
  • 78
  • 126
Ari Lotter
  • 605
  • 8
  • 23

2 Answers2

2

You can use reflection to retrieve the value of private variables or methods.

http://www.csharp-examples.net/reflection-examples/

namespace Test
{
    public class Calculator
    {
        public Calculator() { ... }
        private double _number;
        public double Number { get { ... } set { ... } }
        public void Clear() { ... }
        private void DoClear() { ... }
        public double Add(double number) { ... }
        public static double Pi { ... }
        public static double GetPi() { ... }
    }
}

Calculator calc = new Calculator();

// invoke private instance method: private void DoClear()
calcType.InvokeMember("DoClear",
    BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
    null, calc, null);

To invoke with arguments, pass a array of the arguments in instead of null.

Link to further documentation from the msdn.

N_A
  • 19,799
  • 4
  • 52
  • 98
  • This isn't exactly what I'm looking for. spriteBatch isn't a variable, it's a sub-function. I'm trying to call Main.spriteBatch.DrawString. – Ari Lotter Nov 28 '11 at 22:41
  • Either way you can do it using reflection: `calcType.InvokeMember("Clear", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, calcInstance, null); ` – N_A Nov 28 '11 at 22:42
  • With reflection you can also call a private Method!http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethod.aspx – oberfreak Nov 28 '11 at 22:42
  • 1
    It might be worth noting that reflection will probably only work on Windows games. Xbox and Windows Phone 7 runtime environments have restrictions around such things. – lzcd Nov 28 '11 at 22:46
  • 1
    @lzcd: XNA allows reflection (PC and xbox, don't know about phone). It's slow though, so do it once to get a reference to the `spritebatch` on loading. – George Duckett Nov 28 '11 at 22:48
  • So something like this: `SpriteBatch spriteBatch = MethodInfo GetMethod(string spriteBatch, BindingFlags (BindingAttr) Default);` EDIT: it throws an "Invalid token: Using" where I put `using System.Reflection;` – Ari Lotter Nov 28 '11 at 22:52
  • If you have access to the class type without using reflections then there is no need to use `GetMethod`; simply use `InvokeMember` directly. Otherwise you will need to use `GetType` as well. – N_A Nov 28 '11 at 22:54
  • If you're having a new problem it would be easier if you created a new question so you can post code. – N_A Nov 28 '11 at 22:55
  • @mydogisbox no, i'm just not quite sure how to do this. I'm a beginner to C#. What code would I use to do this? All I want is to call Main.spriteBatch.DrawString(); – Ari Lotter Nov 28 '11 at 22:58
  • I don't know why you're having problems with your using statement, but other than that I have posted pretty much everything you need to invoke the method. Simply replace your object and method name in the example I gave. If you have issues with getting your using statement to work that would probably require asking a new question. – N_A Nov 28 '11 at 23:01
  • @mydogisbox Ah, I didn't see your edit. If the function I'm calling takes arguments, where would I input them? The MSDN doc isn't really help. – Ari Lotter Nov 28 '11 at 23:08
  • Updated with more information and a useful link to the msdn (does contain notes on how to pass in arguments). – N_A Nov 29 '11 at 01:33
0

You could use reflection to access the private member, but this isn't a recommended practice to actually use. The internal implementation of objects is subject to change and accessing them is a violation of good OOP principal.

The similar answer here will help you accomplish the task though:

Can I change a private readonly field in C# using reflection?

Community
  • 1
  • 1
Frazell Thomas
  • 6,031
  • 1
  • 20
  • 21