0

I am trying to create tools for a game to learn, as well as improve my own playing experience.

The primary .NET assembly, csass.dll, that controls the client is heavily obfuscated, and I have no control over this .dll-file at all and reading it's code is very time consuming. The game also includes a mainapi.dll which handles the communication between server and client. I have full control over this assembly and I can listen to the servers responses and send my own requests, which already gives me some pretty nice functionality, however there are some limitations I'd like to work around.

csass.dll references mainapi.dll, by default mainapi does not reference csass. In csass.dll there is a class, let's call it clickHandler, that has a public, non-static method ClickObj() of return type void. I want to call this method from within mainapi.dll, but I have no idea how to go about this, given that I have to leave csass.dll untouched.

Are there any feasible ways to 'retrieve' a clickHandler object (to then call its ClickObj() method) from within the mainapi assembly, without making any changes in csass.dll? Appreciate any and all input!

Bagdan Gilevich
  • 1,231
  • 1
  • 11
  • 17
  • If `csass.dll` references `mainapi.dll`, then the `mainapi.dll` can't reference `csass.dll` since that would create a circular dependency. But to access a method on `csass` you need to reference it. I feel like you have a design issue with the system? – Sach Aug 23 '18 at 22:57
  • See here. https://stackoverflow.com/a/6929681/302248 – Sach Aug 23 '18 at 23:00
  • If the `clickHandler` is an event handler in `csass` then you need to invoke the event and `csass` will handle it. Find out what tuggers the event. – CodingYoshi Aug 23 '18 at 23:07
  • Thank you Sach, I will look into circular dependency and see if it creates any issues in my usecase/how to work around it, I did not have a chance to play around with it so far. CodingYoshi, 'clickHandler' is just a class name I made up, like i said csass is very obfuscated so I didn't want to write out the gibberish class name, perhaps my naming was confusing. 'clickHandler' actually derives from MonoBehaviour. – Wandering_Bear Aug 23 '18 at 23:14

1 Answers1

0

Create an interface:

public interface IClickHandler 
{
    void ClickObject();
}

Now create a helper class implementing that interface:

using CsAss;

public class ObjectClicker : IClickHandler
{
    CsAss _csass;
    public ObjectClicker(CsAss csass)
    {
        _csass = csass;
    }

    public void ClickObject()
    {
        _csass.clickObject();
    }
}

Add a dependency on an instance of the interface into your MainAPI class:

public class MainApi
{
    IClickHandler _clickHandler;

    public MainApi(IClickHandler clickHandler)
    {
        _clickHandler = clickHandler;
        // Now you have a class that can call the click handler for you
    }
}

Now wire it all up:

public void StartupMethod()
{
    var csass = new CsAss();
    IClickHandler clickHandler = new ObjectClicker(csass);
    var main = new MainApi(clickHandler);

    // TODO: Start your app now that MainApi is properly configured
}

That last step is the only potentially tricky part, depending on your project layout. You need something that can create an instance of CsAss, MainApi and ObjectClicker. Normally I would solve that with the dependency injection (DI) pattern, either using a framework such as Autofac or so-called "poor man's DI" by manually instantiating from a central startup method. That gets a little more difficult with Unity since there isn't an easily accessible startup point. You could start looking into https://github.com/svermeulen/Zenject and go from there for options.

Monolith
  • 1,067
  • 1
  • 13
  • 29
Colin Young
  • 3,018
  • 1
  • 22
  • 46