Posted November 10, 2015 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
Posted November 10, 2015 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
Posted November 10, 2015 Yes. that should be possibleCtClass 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 codestatic 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 addingsharedClassLoader=trueto the mod properties file. Otherwise the modified class will not know about the mod. Share this post Link to post Share on other sites
Posted November 10, 2015 (edited) 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 November 10, 2015 by joedobo Share this post Link to post Share on other sites
Posted November 13, 2015 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
Posted November 15, 2015 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
Posted November 15, 2015 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
Posted November 15, 2015 (edited) Very easy to use, thank you! Edited November 15, 2015 by Brash_Endeavors 1 Share this post Link to post Share on other sites
Posted November 15, 2015 (edited) 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 November 15, 2015 by Drpox Share this post Link to post Share on other sites
Posted November 15, 2015 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
Posted November 15, 2015 New server so naturally no one has bred anything yet. Share this post Link to post Share on other sites
Posted November 15, 2015 (edited) 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 November 15, 2015 by cantorsdust Share this post Link to post Share on other sites
Posted November 15, 2015 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 codestatic 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 addingsharedClassLoader=trueto 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
Posted November 16, 2015 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
Posted November 17, 2015 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 1 Share this post Link to post Share on other sites
Posted November 17, 2015 (edited) 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=RazorsEdge4096Patcher: 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 November 17, 2015 by razoreqx Share this post Link to post Share on other sites
Posted November 17, 2015 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) 1 Share this post Link to post Share on other sites
Posted November 17, 2015 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
Posted November 18, 2015 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
Posted November 18, 2015 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
Posted November 18, 2015 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
Posted November 18, 2015 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
Posted November 18, 2015 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
Posted November 18, 2015 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
Posted November 18, 2015 buried in the 2nd spoiler of the first post of this thread http://forum.wurmonline.com/index.php?/topic/134861-is-there-a-better-way-to-deal-with-itemtemplatecreator-class/ Share this post Link to post Share on other sites