ago

[RELEASED] Server mod loader + priest + crops + seasons + server packs + bag of holding

Recommended Posts

Can I use the mod loader to completely replace the body of a method?  Looking through Javassist its apparent this would be possible if it had a way to collaborate with the server.jar to make sure that modified classes (and hence methods) would be loaded instead of the original ones.


Share this post


Link to post
Share on other sites

Can I use the mod loader to completely replace the body of a method?  Looking through Javassist its apparent this would be possible if it had a way to collaborate with the server.jar to make sure that modified classes (and hence methods) would be loaded instead of the original ones.

Share this post


Link to post
Share on other sites

Yes. that should be possible

CtClass ctClass = HookManger.getInstance().getClassPool().get("com.wurmonline.server.some.class");CtMethod ctMethod = ctClass.getMethod("methodName", methodDescriptor /* e.g. "(J)I" for int methodName(long) */);ctMethod.setBody("do funky stuff here");
You can also define a static method in the mod and call it from the replacement code

static void staticMethod(args) {...}

setBody("com.your.mod.ModClass.staticMethod($$)")
For this to work you'll have to elevate the mod into the main classloader by adding

sharedClassLoader=true
to the mod properties file. Otherwise the modified class will not know about the mod.

Share this post


Link to post
Share on other sites

Thanks. Ago, I like how you did your mods (cropmod, bagofholding....) it's just that it's confusing. I'm going to take baby-steps at this and a good first step seems to be a complete replacement of method bodies. 


Edited by joedobo

Share this post


Link to post
Share on other sites

I am wondering if you can use the same technique you did for Bag of Holding to enable flight when BoH is cast on a person or your own body.


 


In a perfect world a status indicator would appear letting you know when the power of flight runs out. If you are flying when it happens you crash to the ground.


 


I am super impressed with both the modlauncher and the various mods produced thus far!


 


~Nappy


Share this post


Link to post
Share on other sites

I've developed another mod for your modloader, NoDecay.  Does just what it says on the tin except for a few exceptions necessary for functioning gameplay.


 


Had a devil of a time making it, though.  Turns out that using insertBefore() and setBody() won't let you access the method's original arguments.  Took a bit of searching to discover that you have to reference arguments as $1, $2, etc if you want to use them in the function.


 


That is, if the original method was defined as ThisFunction(argumentOne, argumentTwo, argumentThree), I can't use the variable name argumentOne in my code.  I have to refer to it as $1.


Share this post


Link to post
Share on other sites

Yes, the javassist tutorial explains the use of the placeholders.

When the code is compiled without debug information the variable names are not available at all, so I guess they just went with the option that will always work

Share this post


Link to post
Share on other sites

Hello,


 


I love your mod.  I have it working on my server atm.


 


I do have a question regarding the creature mod.   I am seeing old and venerable Calf's plural. I am wondering does your mod have them die off or due they advance to the next stage aka cow bull or a foal going to a horse?


 


 


Ps thanks for running such a smooth interface patching method.


Edited by Drpox

Share this post


Link to post
Share on other sites

The mod should just shorten the span between age checks. Everything else should be the same. My calves, foals and lambs grew into the propert adult creatures but at mature state.

Did those calves spawn naturally (maybe even at that age) or were they breed and grew to venerable?

Share this post


Link to post
Share on other sites

Quick question, where do logger.log() outputs get placed?  Is there a log file somewhere or do they only print to console or what?


 


edit:  nvm, found it in the console output


Edited by cantorsdust

Share this post


Link to post
Share on other sites

Yes. that should be possible

 

CtClass ctClass = HookManger.getInstance().getClassPool().get("com.wurmonline.server.some.class");CtMethod ctMethod = ctClass.getMethod("methodName", methodDescriptor /* e.g. "(J)I" for int methodName(long) */);ctMethod.setBody("do funky stuff here");
You can also define a static method in the mod and call it from the replacement code

static void staticMethod(args) {...}
setBody("com.your.mod.ModClass.staticMethod($$)")
For this to work you'll have to elevate the mod into the main classloader by adding

sharedClassLoader=true
to the mod properties file. Otherwise the modified class will not know about the mod.

 

 

Is there any way for a function to call a non-static method or for a method.setBody() to refer to a previously assigned variable in the mod?

 

I want to create an int[] blacklist and have my code check that the item templateId is not on this list.  See code below:

    private boolean checkBlacklist(int targetValue) {        for(int s: this._blacklist){            if(s == targetValue)                return true;        }        return false;    }    private void NoItemDecayFunction() {        try {            ClassPool classPool = HookManager.getInstance().getClassPool();            CtClass ex = HookManager.getInstance().getClassPool().get("com.wurmonline.server.items.Item");            CtMethod method = ex.getDeclaredMethod("getDecayTime");            method.insertBefore("{ if (!(checkBlacklist(this.getTemplateId()))) {" +                    " return 9223372036854775807L; } }");            method = null;            ex = null;        } catch (NotFoundException | CannotCompileException var4) {            throw new HookException(var4);        }    }

where _blacklist is defined as:

        _blackliststring = properties.getProperty("blackliststring", _blackliststring);        this.Log(("blacklist string from properties is :" + _blackliststring), true);        String[] items = _blackliststring.replaceAll("\\[", "").replaceAll("\\]", "").split(",");        int[] results = new int[items.length];        for (int i = 0; i < items.length; i++) {            results[i] = Integer.parseInt(items[i]);        }        this._blacklist = results;        this.Log(("blacklist array created from string is: " + Arrays.toString(items)), true);

The problem is, I get checkBlacklist(int) not found in com.wurmonline.server.items.Item as my error.  I can't make it a static function and have it be referenced using the sharedclassloader way you described earlier because the blacklist is dynamically defined using the properties file, not static in the class.

 

Any ideas?

Share this post


Link to post
Share on other sites

Is there any way for a function to call a non-static method or for a method.setBody() to refer to a previously assigned variable in the mod?

No. Not directly. The class file editing does not know anything about object instances. It's pure code without any data. Object instances are data.

The invocation handler has a similar problem. The correct invocation handler for a hooked method is resolved from a static map in the hook manager. This currently only works for hooks but I'll probably extend this interface so any mod can register an invocation handler in the hook manager and provide a way to call the handler without the need to put the mod in the main classloader.

The problem is, I get checkBlacklist(int) not found in com.wurmonline.server.items.Item as my error.  I can't make it a static function and have it be referenced using the sharedclassloader way you described earlier because the blacklist is dynamically defined using the properties file, not static in the class.

 

Any ideas?

You can make checkBlacklist(int) a static method and blacklist a static field and fill it in the configure phase.

The CreatureAgeMod had the same problem: https://github.com/ago1024/WurmServerModLauncher/blob/master/src/mods/creatureagemod/org/gotti/wurmunlimited/mods/creatureagemod/CreatureAgeMod.java

Share this post


Link to post
Share on other sites

Version 0.9 has been posted: https://github.com/ago1024/WurmServerModLauncher/releases/tag/v0.9

Notable changes: Added patcher, HarvestHelper mod and ServerPacks mod

The patcher will modify server.jar and patch WurmServerLauncher to run the modloader.

HarvestHelper will print a message on login if there is anything in season or will soon be. There's also a /seasons command which prints the time until the season starts

  • Like 1

Share this post


Link to post
Share on other sites

Running headless as we talked about before..  


FireDaemon: 


Commandline: 



C:\Wurm\runtime\bin\java -Dworkdir=C:\Wurm -Djava.library.path=C:\Wurm\nativelibs -Xmn256M -Xms512m -Xmx2048m -XX:+OptimizeStringConcat -XX:+AggressiveOpts -jar C:\Wurm\modlauncher.jar  Start=RazorsEdge4096

Patcher: 


Do i need to change any of that with the new patcher? 


 


HarvestHelper: 


Displaying the season on login but the /season command is not working.      


Edited by razoreqx

Share this post


Link to post
Share on other sites

The commandline for firedaemon can stay the same. The patcher is primarily meant for people who want or have to run the WurmServerLauncher binary.

The command for the seasons is /seasons (with an "s" at the end)

  • Like 1

Share this post


Link to post
Share on other sites

The commandline for firedaemon can stay the same. The patcher is primarily meant for people who want or have to run the WurmServerLauncher binary.

The command for the seasons is /seasons (with an "s" at the end)

 

Gotcha.  And we figured out the season(s) typo on my part.. Thats why i did the strikeout.       Nice work Ago!!!    

Share this post


Link to post
Share on other sites

Can Bag of Holding be used to create fountain pans? if so, how?


 


I have set BoH properties to effectModifier=100000 and have a 94 cast on a saucepan, but can't move a fountain into it.... 


when i try, nothing happens - I drag the fountain but when I drop it, nothing.


 


is there something else I should be doing?


Share this post


Link to post
Share on other sites

There is a check that for any of those conditions

* the items dimension will fit into the containers dimension

* the container is the inventory or a pile of items

* the item is combinable, food or a liquid and there is free volume

The fountain does not fit any of the categories. It's specificly to large for the containers dimensions and I did not change the actual container dimensions, just the computed volume.

Share this post


Link to post
Share on other sites

In what way does bag of holding spell expand a container? does it change x y z size? I have cast an 81 on a backpack but a shovel still wont fit. To be honest I don't know what volume the shovel would take up anyways but I was expecting the backpack to start accepting some of the larger tools. I will try some other stuff like a pelt. maybe a saw.


Share this post


Link to post
Share on other sites

I know that with the big container mod -- all the tools fit in the backpack. 


Share this post


Link to post
Share on other sites

In what way does bag of holding spell expand a container? does it change x y z size? I have cast an 81 on a backpack but a shovel still wont fit. To be honest I don't know what volume the shovel would take up anyways but I was expecting the backpack to start accepting some of the larger tools. I will try some other stuff like a pelt. maybe a saw.

LOL, story of my life. You posted the info I needed to know just before this question.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now