Sign in to follow this  
cantorsdust

[RELEASED] AlwaysForage

Recommended Posts

I'm pleased to release my first mod, AlwaysForage, using Ago's Modloader.  The source code is blatantly stolen adapted from Ulviirala's BetterGamemasters.


 


Allows you to forage, botanize, and rummage on a tile regardless of whether it had recently been foraged before. It does so by adding modloader code to ensure the function isForagable and isBotanizable always returns true.

 

It should remain up to date for any Wurm Unlimited version.

 

Installation instructions:

 

1.  Make sure you have Ago's Modloader

2.  Unzip AlwaysForage.zip to the Wurm Unlimited Dedicated Server folder so that modloader.bat and the mods folder are in the same directory as WurmServerLauncher.exe.

3.  Open modloader.bat and add (without quotes) "-noverify" to the list of runtime arguments. If you are unsure where to place it, put it between any set of words which begin with "-" and before the end which says modloader.jar. This is necessary to suppress a weird bytecode error.

4.  Start the game.

5.  IF YOU GET AN ERROR THAT SAYS "Expecting a stackmap frame", GO BACK AND READ NUMBER 2

 


 


  • Like 1

Share this post


Link to post
Share on other sites

So, this lets you stand in one place and continuously forage and botanize?

  • Like 1

Share this post


Link to post
Share on other sites

Correct. Mostly a cheaty mod for me, but I figure others might enjoy it. If not, it still provides an example of how to use the modloader.

Share this post


Link to post
Share on other sites

Javassist has a method to fix the altered classes:

 

   methodInfo.rebuildStackMap(classPool);
I had to use it to hook the player messages: https://github.com/ago1024/WurmServerModLauncher/blob/master/src/launcher/org/gotti/wurmunlimited/modloader/ProxyServerHook.java#L117

 

 

Thanks for this, but it throws a BadByteCode exception at me when I implement it.  I have tried both rebuildStackMap and rebuildStackMapIf6.  The thing is, I'm not actually even touching any bytecode directly.  I'm just telling a function which checks bytecode against a value to always return true.  Original function and my code below.

    public static boolean isForagable(int tilex, int tiley) {        int value = flagsMesh.getTile(tilex, tiley);        return (value & 64) == 64;    }
    private void ForagingFunction() {        try {            ClassPool classPool = HookManager.getInstance().getClassPool();            CtClass ex = HookManager.getInstance().getClassPool().get("com.wurmonline.server.Server");            ClassFile cf = ex.getClassFile();            CtClass[] parameters = new CtClass[]{CtPrimitiveType.intType, CtPrimitiveType.intType};            CtMethod method = ex.getMethod("isForagable", Descriptor.ofMethod(CtPrimitiveType.booleanType, parameters));            MethodInfo methodInfo = method.getMethodInfo();            method.insertBefore("return true;");            //methodInfo.rebuildStackMapIf6(classPool, cf);            methodInfo.rebuildStackMap(classPool);            method = null;            parameters = null;            ex = null;        } catch (NotFoundException | CannotCompileException var4) {            throw new HookException(var4);        }    }
Edited by cantorsdust

Share this post


Link to post
Share on other sites

rebuildStatckMap is required when jump addresses change.

Does method.setBody("return true;") work? Maybe there's an issue with the dead code after the return.

Share this post


Link to post
Share on other sites

rebuildStatckMap is required when jump addresses change.

Does method.setBody("return true;") work? Maybe there's an issue with the dead code after the return.

 

Nope, it doesn't prevent compiling but still throws the same stack map error, and the code still complains about a BadBytecode exception.

Share this post


Link to post
Share on other sites

lol To bad this doesn't work. No just kidding

Edited by Seodanrot
  • Like 1

Share this post


Link to post
Share on other sites

I think step 3 is causing an error for me. I have no skill in any of this, but this is what it looks like for me: %JAVA% "-Dworkdir=%CD%" -noverify "-Djava.library.path=%CD%.....

Whenever I try to run the server, it gives me the stackmap frame. I've verified step 2 4 times, before having my IT roommate verify it as well. It;s not step 2 that's causing the error, so I think it's something I might be doing wrong in step 3? I don't have a clue.

Edited by Stahe

Share this post


Link to post
Share on other sites

I didn't look at the code but if this is broken I use something like the following.

--

@Override
public void init() {
	try {
			jsAlwaysForage();
        } catch (NotFoundException | CannotCompileException e) {
            e.printStackTrace();
        }
}

--

private void jsAlwaysForage() throws NotFoundException, CannotCompileException {
  pool = HookManager.getInstance().getClassPool();
  CtMethod ctmIsForagable = pool.get("com.wurmonline.server.Server").getMethod("isForagable", "(II)Z");
  ctmIsForagable.setBody("{ return true; }");
  CtMethod ctmIsBotanizable = pool.get("com.wurmonline.server.Server").getMethod("isBotanizable", "(II)Z");
  ctmIsBotanizable.setBody("{ return true; }");
}

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
Sign in to follow this