· 8 years ago · Apr 24, 2018, 12:36 PM
1package org.takino.mods;
2
3import com.wurmonline.server.behaviours.ActionEntry;
4import com.wurmonline.server.creatures.Creature;
5import com.wurmonline.server.items.Item;
6import javassist.*;
7import javassist.bytecode.Descriptor;
8import javassist.expr.ExprEditor;
9import javassist.expr.MethodCall;
10import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
11import org.gotti.wurmunlimited.modloader.interfaces.Initable;
12import org.gotti.wurmunlimited.modloader.interfaces.PreInitable;
13import org.gotti.wurmunlimited.modloader.interfaces.ServerStartedListener;
14import org.gotti.wurmunlimited.modloader.interfaces.WurmServerMod;
15import org.gotti.wurmunlimited.modsupport.ModSupportDb;
16import org.gotti.wurmunlimited.modsupport.actions.ModAction;
17import org.gotti.wurmunlimited.modsupport.actions.ModActions;
18
19import java.sql.Connection;
20import java.sql.SQLException;
21import java.util.logging.Level;
22import java.util.logging.Logger;
23
24/**
25 * BulkItemsSeparated is a mod that separates bulk stored items by QL. Only for BSBs.
26 * Blessed BSBs act WurmOnline way.
27 */
28public class BulkItemsSeparated implements WurmServerMod, PreInitable, Initable, ServerStartedListener {
29
30 private static Logger logger = Logger.getLogger("bulkItemsSeparated");
31 public static final short ENABLE_ACTION = (short) ModActions.getNextActionId();
32 public static final short DISABLE_ACTION = (short) ModActions.getNextActionId();
33
34 public static ActionEntry enableEntry;
35 public static ActionEntry disableEntry;
36 static String TABLE_NAME = "takinoseparateditems";
37
38
39 static void logException(String msg, Throwable e) {
40 logger.log(Level.SEVERE, msg, e);
41 }
42
43 @Override
44 public void preInit() {
45 try {
46
47 ClassPool classPool = HookManager.getInstance().getClassPool();
48 CtClass ctItemBehaviour = classPool.getCtClass("com.wurmonline.server.behaviours.ItemBehaviour");
49 ctItemBehaviour.getMethod("moveBulkItemAsAction",
50 "(Lcom/wurmonline/server/behaviours/Action;Lcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/items/Item;Lcom/wurmonline/server/items/Item;F)Z")
51 .instrument(new ExprEditor() {
52 @Override
53 public void edit(MethodCall m) throws CannotCompileException {
54 if (m.getMethodName().equals("getItemsAsArray")) {
55 m.replace("if (!org.takino.mods.BulkItemsHooks.checkSorting($0)) $_ = $proceed($$); " +
56 "else $_ = org.takino.mods.BulkItemsHooks.getItemsAsArrayFiltered($0, source);");
57 }
58 }
59 });
60
61 } catch (NotFoundException | CannotCompileException e) {
62 logException("Error hooking moveBulkItemAsAction", e);
63 }
64
65 }
66
67 @Override
68 public void init() {
69 try {
70 CtClass returnType = CtPrimitiveType.booleanType;
71 CtClass[] inputTypes = {
72 HookManager.getInstance().getClassPool().get("com.wurmonline.server.creatures.Creature"),
73 HookManager.getInstance().getClassPool().get("com.wurmonline.server.items.Item")
74 };
75
76 HookManager.getInstance().registerHook("com.wurmonline.server.items.Item", "AddBulkItem", Descriptor.ofMethod(returnType, inputTypes),
77 () -> (proxy, method, args) -> {
78 Item target = (Item) args[1];
79 Creature mover = (Creature) args[0];
80 Item toInsert = (Item) proxy;
81 if (target.getBless() != null) {
82 return method.invoke(proxy, args);
83 } else {
84 return BulkItemsHooks.addBulkItem(target, mover, toInsert);
85 }
86 });
87
88 disableEntry = ActionEntry.createEntry(ENABLE_ACTION,
89 "Enable sorting", "modifies", new int[]{6 /* ACTION_TYPE_NOMOVE */});
90 enableEntry = ActionEntry.createEntry(DISABLE_ACTION,
91 "Disable sorting", "modifies", new int[]{6 /* ACTION_TYPE_NOMOVE */});
92
93 } catch (Exception e) {
94 logException("Error in init", e);
95 }
96 }
97
98
99 private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT not NULL" +
100 ", WURMID INTEGER not NULL, SORTING INTEGER DEFAULT 1)";
101
102 private void createDefaultTables() throws SQLException {
103 Connection connection = ModSupportDb.getModSupportDb();
104 connection.createStatement().execute(CREATE_TABLE);
105 }
106
107 public static void setSorting(Item item, boolean sorted) throws SQLException {
108 String insertorupdate = "INSERT OR REPLACE into " + TABLE_NAME + "(WURMID, SORTING) values (" + item.getWurmId() + "," +
109 (sorted ? 1 : 0) + ")";
110 Connection connection = ModSupportDb.getModSupportDb();
111 connection.createStatement().execute(insertorupdate);
112 }
113
114 @Override
115 public void onServerStarted() {
116 ModActions.registerAction(new SortActionPerformer());
117 ModActions.registerAction(new UnsortActionPerformer());
118
119 try {
120 createDefaultTables();
121 } catch (SQLException e) {
122 e.printStackTrace();
123 }
124
125 }
126}