[WIP] Event driving modding proof of concept + permanent fixed weather

Started by RawCode, July 28, 2014, 07:17:02 AM

Previous topic - Next topic

RawCode

This early development version but, it working just as designed.

At this moment "injection" done by additional "monitor" thread, this subject to change, perfectly - by original game developer.

there is only single def at play:


<?xml version="1.0" encoding="utf-8" ?>
<Loaders>
<Loader>
</Loader>
</Loaders>


this def will perform loading of *main* type of assembly, allowing to inject code at early stages of game.

payload code is


public class Loader : Def
    {
        static Loader()
        {
            Log.Error("<CINIT>(..cctor) Section invocation ((static)Type Constructor)");
            Thread branchA = new Thread(new ThreadStart(Loader.watchInternalState));
            branchA.Start();
//we start new thread here to monitor game activity and field change, this done in place of bytecode injection.
        }

        static void watchInternalState()
        {
            for(;;) //infinite loop
            {
                try //just in case, normal exceptions wont show up in console
                {

                    if (Find.RootMap == null) //as long as map not initialized we do nothing
                        continue;

                    Thread.Sleep(100); //when map is initialized, we wait to ensure object init and perform payload
                    //throw GameInitializeEvent and handle all mods that listen to it NYI
                    Find.Map.storyteller.weatherDecider = new WeatherDeciderImpl();
                    Log.Error("Weather Decider is replaced;");
                    break; //we no longer need this thread, we break loop and terminate it
                }catch( Exception E)
                {
                    Log.Error(E.ToString());
                }
            }
        }
    }


c# unlike java allows to override only methods marked virtual, this is severe limitation to hacking.
since WeatherDecider still have single virtual method - we override it.


    public class WeatherDeciderImpl : WeatherDecider
    {
        protected override WeatherDef NextWeather() //only method that can be "hooked"
        {
            Log.Error("Virtual method invocation");
            return DefDatabase<WeatherDef>.AllDefs.First(); //first def is "clear" weather, it's possible to define any other weather, including permanent dry thunderstorm or cycle weather in predefined order
        }
    }

RawCode

Small addition: always prisoners


    public class StoryIntender_PopulationImpl : StoryIntender_Population
    {
        override public float PopulationIntent
        {
            get
            {
                return 100f;
            }
        }
    }


initialized by


Find.Map.storyteller.intenderPopulation = new StoryIntender_PopulationImpl();

mrofa

Look cool i wonder if you could make a thing that detect what mod is installed and based on that choose a loader, so more than one mod could us that , than again mod devs could just save that in separate assembly ...
Anyways meaning to ask what is "catch( Exception E)" ?
And thanks for sharing this!
All i do is clutter all around.

RawCode

Mod can perform all actions that game can.

I plan to enumerate all assemblies and all types inside that assemblies for compatible methods and invoke them on specific event.

like invoking all onMapInit() methods of all defined types on that event.

basically iam going to copy cbukkit implementation of event system with minor modifications


superpirson

Yes, the whole virtual thing drives me nuts.  :P
How does rimworld work with multithreding? The majoraty of what I have seen looks like it's single threaded.
Won't you have to hault all of rimworld just to run your script? What about the lack of mutexs in the base game?
Forgive me if these are stupid questions, I just really want to get familiar with this.
specs: mid2009 MBP OSX 10.9.3 NVIDIA GeForce 9400M 256 MB