diff --git a/.classpath b/.classpath
deleted file mode 100644
index f2dcd37..0000000
--- a/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e32b73d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.classpath
+/dist
+/dist/world
+/dist/world/region
+/dist/plugins
\ No newline at end of file
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..bc588e1
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugin.yml b/plugin.yml
index ddcc0bf..9a30143 100644
--- a/plugin.yml
+++ b/plugin.yml
@@ -1,7 +1,7 @@
name: DynamicMarket
-main: com.gmail.haloinverse.DynamicMarket.DynamicMarket
-version: 0.4.8
-author: HaloInverse
+main: com.gmail.haloinverse.DynamicMarket.DynamicMarket
+version: v0.4.8.magik.29
+author: HaloInverse
description: >
A shop plugin building towards an interesting and flexible market system.
commands:
@@ -11,4 +11,12 @@ commands:
/
/ help
/
- /
\ No newline at end of file
+ /
+ dshop:
+ description: Accesses the shop command system.
+ usage: |
+ /
+ / help
+ /
+ /
+
\ No newline at end of file
diff --git a/src/com/gmail/haloinverse/DynamicMarket/DatabaseCore.java b/src/com/gmail/haloinverse/DynamicMarket/DatabaseCore.java
index 3fa9721..074a233 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/DatabaseCore.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/DatabaseCore.java
@@ -1,276 +1,162 @@
package com.gmail.haloinverse.DynamicMarket;
-
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.sql.SQLWarning;
import java.util.ArrayList;
-
-public abstract class DatabaseCore
-{
- public Type databaseType = null;
- public String tableName; // default: SimpleMarket
- public DynamicMarket plugin = null;
- public String engine = "MyISAM";
-
- public DatabaseCore(Type databaseType, String tableAccessed, String thisEngine, DynamicMarket thisPlugin) {
- this.databaseType = databaseType;
- this.tableName = tableAccessed;
- if (thisEngine != null)
- engine = thisEngine;
- plugin = thisPlugin;
- initialize();
- }
-
- protected boolean initialize()
- {
- return initialize("");
- }
-
- protected boolean initialize(String tableSuffix) {
- if (!(checkTable(tableSuffix))) {
- plugin.log.info("[" + plugin.name + "] Creating database.");
- if (createTable(tableSuffix))
- {
- plugin.log.info("[" + plugin.name + "] Database Created.");
- return true;
- }
- else
- {
- plugin.log.severe("[" + plugin.name + "] Database creation *failed*.");
- return false;
- }
- }
- return false;
- }
-
- protected boolean deleteDatabase()
- {
- return deleteDatabase("");
- }
-
- protected boolean deleteDatabase(String tableSuffix)
- {
- SQLHandler myQuery = new SQLHandler(this);
- myQuery.executeStatement("DROP TABLE " + tableName+tableSuffix + ";");
- myQuery.close();
- if (myQuery.isOK)
- plugin.log.info("[" + plugin.name + "] Database table successfully deleted.");
- else
- plugin.log.severe("[" + plugin.name + "] Database table could not be deleted.");
- return myQuery.isOK;
- }
-
- public boolean resetDatabase()
- {
- return resetDatabase("");
- }
-
- public boolean resetDatabase(String tableSuffix)
- {
- deleteDatabase(tableSuffix);
- return initialize(tableSuffix);
- }
-
-
- protected Connection connection() throws ClassNotFoundException, SQLException {
- //CHANGED: Sets connections to auto-commit, rather than emergency commit-on-close behaviour.
- Connection newConn;
- if (this.databaseType.equals(Type.SQLITE)) {
-/* 52 */ Class.forName("org.sqlite.JDBC");
-/* 53 */ newConn = DriverManager.getConnection(DynamicMarket.sqlite);
- return newConn;
-/* */ }
-/* 55 */ Class.forName("com.mysql.jdbc.Driver");
-/* 56 */ newConn = DriverManager.getConnection(DynamicMarket.mysql, DynamicMarket.mysql_user, DynamicMarket.mysql_pass);
- newConn.setAutoCommit(true);
- return newConn;
- }
-
- protected String dbTypeString()
- {
- return ((this.databaseType.equals(Type.SQLITE)) ? "sqlite" : "mysql");
- }
-
- protected void logSevereException(String exDesc, Exception exDetail)
- {
- plugin.log.severe("[" + plugin.name + "]: " + exDesc + ": " + exDetail);
- }
-
- protected void logSevereException(String exDesc)
- {
- plugin.log.severe("[" + plugin.name + "]: " + exDesc);
- }
-
- protected boolean checkTable(String tableSuffix)
- {
- SQLHandler myQuery = new SQLHandler(this);
-
- boolean bool;
- bool = myQuery.checkTable(tableName+tableSuffix);
- myQuery.close();
- return bool;
- }
-
- protected boolean checkTable()
- {
- return checkTable("");
- }
-
- protected abstract boolean createTable(String tableSuffix);
-
- protected boolean createTable()
- {
- return createTable("");
- }
- /*
- {
- //SQLHandler myQuery = new SQLHandler(this);
- //if (this.database.equals(Type.SQLITE))
- // myQuery.executeStatement("CREATE TABLE " + tableName+shopLabel + " ( id INT ( 255 ) PRIMARY KEY , item INT ( 255 ) NOT NULL, type INT ( 255 ) NOT NULL, buy INT ( 255 ) NOT NULL, sell INT ( 255 ) NOT NULL, per INT ( 255 ) NOT NULL);CREATE INDEX itemIndex on balances (item);CREATE INDEX typeIndex on balances (type);CREATE INDEX buyIndex on iBalances (buy);CREATE INDEX sellIndex on iBalances (sell);CREATE INDEX perIndex on iBalances (per);");
- //else
- // myQuery.executeStatement("CREATE TABLE " + tableName+shopLabel + " ( id INT( 255 ) NOT NULL AUTO_INCREMENT, item INT( 255 ) NOT NULL, type INT( 255 ) NOT NULL, buy INT( 255 ) NOT NULL, sell INT( 255 ) NOT NULL, per INT( 255 ) NOT NULL ,PRIMARY KEY ( id ), INDEX ( item, type, buy, sell, per )) ENGINE = MYISAM;");
- //myQuery.close();
- //return myQuery.isOK;
- return false;
- }
- */
-
- public abstract boolean add(Object newObject);
- /*
- {
-
- SQLHandler myQuery = new SQLHandler(this);
- myQuery.inputList.add(newItem.itemId);
- myQuery.inputList.add(newItem.subType);
- myQuery.inputList.add(newItem.buy);
- myQuery.inputList.add(newItem.sell);
- myQuery.inputList.add(newItem.count);
- myQuery.prepareStatement("INSERT INTO " + tableName + " (item,type,buy,sell,per) VALUES (?,?,?,?,?)");
- myQuery.executeUpdate();
-
- myQuery.close();
- return (myQuery.isOK);
-
- return false;
- }
- */
-
- public abstract boolean update(Object updateRef);
- /*
- {
- //CHANGED: Shouldn't need to alter item subtypes in existing records. New item+type records should be added instead.
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(updated.buy);
- myQuery.inputList.add(updated.sell);
- myQuery.inputList.add(updated.count);
- myQuery.inputList.add(updated.itemId);
- myQuery.inputList.add(updated.subType);
- myQuery.prepareStatement("UPDATE " + tableName + " SET buy = ?, sell = ?, per = ? WHERE item = ? AND type = ?" + ((this.database.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
-
- myQuery.executeUpdate();
-
- myQuery.close();
- return (myQuery.isOK);
- }
- */
-
- public abstract boolean remove(ItemClump removed);
- /*
- {
- // CHANGED: Now accepts an itemType (through use of the ItemClump class).
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(removed.itemId);
- myQuery.inputList.add(removed.subType);
- myQuery.prepareStatement("DELETE FROM " + tableName + " WHERE item = ? AND type = ?" + ((this.database.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
-
- myQuery.executeUpdate();
-
- myQuery.close();
- return myQuery.isOK;
- }
- */
-
-
-
- public abstract ArrayList> list(int pageNum);
- /*
- {
- //CHANGED: This now spits out a list of ShopItems, instead of a list of arrays of ints.
- //If pageNum=0, return the entire list.
-
- //TODO: After incorporating items list into database, do text-matching.
- SQLHandler myQuery = new SQLHandler(this);
- ArrayList data = new ArrayList();
- int startItem = 0;
- int numItems = 9999999;
- if (pageNum > 0)
- {
- startItem = (pageNum - 1) * 8;
- numItems = 8;
- }
-
- myQuery.inputList.add(startItem);
- myQuery.inputList.add(numItems);
- myQuery.prepareStatement("SELECT * FROM " + tableName + " ORDER BY item ASC, type ASC LIMIT ?, ?");
-
- myQuery.executeQuery();
-
- if (myQuery.isOK)
- try {
- while (myQuery.rs.next())
- data.add(new ShopItem(myQuery.rs.getInt("item"),myQuery.rs.getInt("type"), myQuery.rs.getInt("buy"), myQuery.rs.getInt("sell"), myQuery.rs.getInt("per") ));
- } catch (SQLException ex) {
- logSevereException("SQL Error during ArrayList fetch: " + dbTypeString(), ex);
- }
-
- myQuery.close();
-
- return data;
- }
- */
-
-
- public abstract Object data(ItemClump thisItem);
- /*
- {
- //CHANGED: Returns ShopItems now.
- SQLHandler myQuery = new SQLHandler(this);
- ShopItem data = null;
-
- myQuery.inputList.add(thisItem.itemId);
- myQuery.inputList.add(thisItem.subType);
- myQuery.prepareStatement("SELECT * FROM " + tableName + " WHERE item = ? AND type = ? LIMIT 1");
-
- myQuery.executeQuery();
-
- try {
- if (myQuery.rs != null)
- if (myQuery.rs.next())
- data = new ShopItem(myQuery.rs.getInt("item"), myQuery.rs.getInt("type"), myQuery.rs.getInt("buy"), myQuery.rs.getInt("sell"), myQuery.rs.getInt("per"));
- } catch (SQLException ex) {
- logSevereException("Error retrieving shop item data with " + dbTypeString(), ex);
- data = null;
- }
-
- myQuery.close();
-
- if (data == null) { data = new ShopItem(); }
- return data;
- }
- */
-
- public static enum Type
- {
- SQLITE, MYSQL, FLATFILE;
- }
+public abstract class DatabaseCore {
+
+ public Type databaseType = null;
+ public String tableName; // default: SimpleMarket
+ public DynamicMarket plugin = null;
+ public String engine = "MyISAM";
+ private static Connection conn = null;
+
+ public DatabaseCore(Type databaseType, String tableAccessed, String thisEngine, DynamicMarket thisPlugin) {
+ this.databaseType = databaseType;
+ this.tableName = tableAccessed;
+ if (thisEngine != null)
+ engine = thisEngine;
+ plugin = thisPlugin;
+ initialize();
+ }
+
+ protected boolean initialize() {
+ return initialize("");
+ }
+
+ protected boolean initialize(String tableSuffix) {
+ if (!(checkTable(tableSuffix))) {
+ DynamicMarket.log.info("[" + DynamicMarket.name + "] Creating database.");
+ if (createTable(tableSuffix)) {
+ DynamicMarket.log.info("[" + DynamicMarket.name + "] Database Created.");
+ return true;
+ } else {
+ DynamicMarket.log.severe("[" + DynamicMarket.name + "] Database creation *failed*.");
+ return false;
+ }
+ }
+ return false;
+ }
+
+ protected boolean deleteDatabase() {
+ return deleteDatabase("");
+ }
+
+ protected boolean deleteDatabase(String tableSuffix) {
+ SQLHandler myQuery = new SQLHandler(this);
+ myQuery.executeStatement("DROP TABLE " + tableName + tableSuffix + ";");
+ myQuery.close();
+
+ if (myQuery.isOK) {
+ DynamicMarket.log.info("[" + DynamicMarket.name + "] Database table successfully deleted.");
+ } else {
+ DynamicMarket.log.severe("[" + DynamicMarket.name + "] Database table could not be deleted.");
+ }
+
+ return myQuery.isOK;
+ }
+
+ public boolean resetDatabase() {
+ return resetDatabase("");
+ }
+
+ public boolean resetDatabase(String tableSuffix) {
+ deleteDatabase(tableSuffix);
+ return initialize(tableSuffix);
+ }
+
+ protected Connection connection() throws ClassNotFoundException, SQLException {
+// DynamicMarket.log.info("connection: " +
+// "null? " + ((DatabaseCore.conn == null)?"true":"false") +
+// " isClosed? " + (((DatabaseCore.conn != null) && DatabaseCore.conn.isClosed())?"true":"false"));
+// new Throwable().printStackTrace();
+
+ if ( DynamicMarket.debug ) DynamicMarket.log.info("DatabaseCore:connection() called");
+
+ if ( (DatabaseCore.conn != null) && (!DatabaseCore.conn.isClosed()) ){
+ boolean bad = false;
+ SQLWarning sw = conn.getWarnings();
+ while ( sw != null ) {
+ bad = true;
+ DynamicMarket.log.info("leftover warning: "+sw.getMessage());
+ sw = sw.getNextWarning();
+ }
+ if ( bad ) {
+ if ( DynamicMarket.debug ) DynamicMarket.log.info("DatabaseCore:connection() not re-using connection");
+ conn = null;
+ } else {
+ if ( DynamicMarket.debug ) DynamicMarket.log.info("DatabaseCore:connection() returning last connection");
+ return DatabaseCore.conn;
+ }
+ }
+
+ if ( DynamicMarket.debug ) DynamicMarket.log.info("DatabaseCore:connection() new connection");
+
+ // CHANGED: Sets connections to auto-commit, rather than emergency
+ // commit-on-close behaviour.
+ Connection newConn;
+
+ if (this.databaseType.equals(Type.SQLITE)) {
+ Class.forName("org.sqlite.JDBC");
+ newConn = DriverManager.getConnection(DynamicMarket.sqlite);
+ newConn.setAutoCommit(true);
+ DatabaseCore.conn = newConn;
+ return DatabaseCore.conn;
+ }
+
+ Class.forName("com.mysql.jdbc.Driver");
+ newConn = DriverManager.getConnection(DynamicMarket.mysql, DynamicMarket.mysql_user, DynamicMarket.mysql_pass);
+ newConn.setAutoCommit(false);
+ DatabaseCore.conn = newConn;
+ return DatabaseCore.conn;
+ }
+
+ protected String dbTypeString() {
+ return ((this.databaseType.equals(Type.SQLITE)) ? "sqlite" : "mysql");
+ }
+
+ protected void logSevereException(String exDesc, Exception exDetail) {
+ DynamicMarket.log.severe("[" + DynamicMarket.name + "]: " + exDesc + ": " + exDetail);
+ }
+
+ protected void logSevereException(String exDesc) {
+ DynamicMarket.log.severe("[" + DynamicMarket.name + "]: " + exDesc);
+ }
+
+ protected boolean checkTable(String tableSuffix) {
+ boolean bool;
+ SQLHandler myQuery = new SQLHandler(this);
+
+ bool = myQuery.checkTable(tableName + tableSuffix);
+ myQuery.close();
+ return bool;
+ }
+
+ protected boolean checkTable() {
+ return checkTable("");
+ }
+
+ protected abstract boolean createTable(String tableSuffix);
+
+ protected boolean createTable() {
+ return createTable("");
+ }
+
+ public abstract boolean add(Object newObject);
+
+ public abstract boolean update(Object updateRef);
+
+ public abstract boolean remove(ItemClump removed);
+
+ public abstract ArrayList> list(int pageNum);
+
+ public abstract Object data(ItemClump thisItem);
+
+ public static enum Type {
+
+ SQLITE, MYSQL, FLATFILE;
+ }
}
-
-/* Location: C:\Program Files\eclipse\Bukkit\SimpleShop.jar
- * Qualified Name: com.nijikokun.bukkit.SimpleShop.Database
- * Java Class Version: 5 (49.0)
- * JD-Core Version: 0.5.3
- */
\ No newline at end of file
diff --git a/src/com/gmail/haloinverse/DynamicMarket/DatabaseMarket.java b/src/com/gmail/haloinverse/DynamicMarket/DatabaseMarket.java
index 3e7d915..64047fd 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/DatabaseMarket.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/DatabaseMarket.java
@@ -9,1083 +9,1145 @@
import java.sql.SQLException;
import java.util.ArrayList;
-
-public class DatabaseMarket extends DatabaseCore
-{
- //public Type database = null;
- public Items itemsReference = null;
-
- public DatabaseMarket(Type database, String tableAccessed, Items itemsRef, String thisEngine, DynamicMarket pluginRef)
- {
- super(database, tableAccessed, thisEngine, pluginRef); // default table name: "Market"
- checkNewFields();
- this.itemsReference = itemsRef;
- }
-
- @Deprecated
- public DatabaseMarket(Type database, String tableAccessed, String thisEngine, DynamicMarket pluginRef)
- {
- super(database, tableAccessed, thisEngine, pluginRef);
- this.itemsReference = null;
- }
-
- protected void checkColumn(String columnName, String columnDef)
- {
- SQLHandler myQuery = new SQLHandler(this);
- if (!myQuery.checkColumnExists(tableName, columnName))
- {
- myQuery.prepareStatement("ALTER TABLE " + tableName + " ADD " + columnName + " " + columnDef);
- myQuery.executeUpdates();
- }
- myQuery.close();
- }
-
- protected void checkNewFields()
- {
- checkColumn("shoplabel", (this.databaseType.equals(Type.SQLITE)?
- "TEXT NOT NULL DEFAULT ''; CREATE INDEX shoplabelIndex ON Market (shoplabel)"
- : "CHAR(20) NOT NULL DEFAULT ''; CREATE INDEX shopLabelIndex ON Market (shopLabel)"));
- }
-
- protected boolean createTable(String shopLabel)
- {
- SQLHandler myQuery = new SQLHandler(this);
- if (!myQuery.checkTable(tableName))
- createTable();
- else
- return false;
- return add(new MarketItem("-1,-1 n:Default", null, this, shopLabel));
- }
-
- protected boolean createTable() {
- SQLHandler myQuery = new SQLHandler(this);
- if (this.databaseType.equals(Type.SQLITE))
- myQuery.executeStatement("CREATE TABLE " + tableName + " ( id INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "item INT NOT NULL, " +
- "subtype INT NOT NULL, " +
- "name TEXT NOT NULL, " +
- "count INT NOT NULL, " +
- "baseprice INT NOT NULL, " +
- "canbuy INT NOT NULL, " +
- "cansell INT NOT NULL, " +
- "stock INT NOT NULL, " +
- "volatility INT NOT NULL, " +
- "salestax INT NOT NULL, " +
- "stockhighest INT NOT NULL, " +
- "stocklowest INT NOT NULL, " +
- "stockfloor INT NOT NULL, " +
- "stockceil INT NOT NULL, " +
- "pricefloor INT NOT NULL, " +
- "priceceil INT NOT NULL, " +
- "jitterperc INT NOT NULL, " +
- "driftout INT NOT NULL, " +
- "driftin INT NOT NULL, " +
- "avgstock INT NOT NULL, " +
- "class INT NOT NULL, " +
- "shoplabel TEXT NOT NULL DEFAULT '');" +
- "CREATE INDEX itemIndex ON Market (item);" +
- "CREATE INDEX subtypeIndex ON Market (subtype);" +
- "CREATE INDEX nameIndex ON Market (name);" +
- "CREATE INDEX shoplabelIndex ON Market (shoplabel)");
- else
- myQuery.executeStatement("CREATE TABLE " + tableName + " ( id INT( 255 ) NOT NULL AUTO_INCREMENT, " +
- "item INT NOT NULL, " +
- "subtype INT NOT NULL, " +
- "name CHAR(20) NOT NULL, " +
- "count INT NOT NULL, " +
- "baseprice INT NOT NULL, " +
- "stock INT NOT NULL, " +
- "canbuy INT NOT NULL, " +
- "cansell INT NOT NULL, " +
- "volatility INT NOT NULL, " +
- "salestax INT NOT NULL, " +
- "stocklowest INT NOT NULL, " +
- "stockhighest INT NOT NULL, " +
- "stockfloor INT NOT NULL, " +
- "stockceil INT NOT NULL, " +
- "pricefloor INT NOT NULL, " +
- "priceceil INT NOT NULL, " +
- "jitterperc INT NOT NULL, " +
- "driftout INT NOT NULL, " +
- "driftin INT NOT NULL, " +
- "avgstock INT NOT NULL, " +
- "class INT NOT NULL, " +
- "shoplabel CHAR(20) NOT NULL DEFAULT '', " +
- "PRIMARY KEY ( id ), INDEX ( item, subtype, name, shoplabel )) ENGINE = "+ engine + ";");
- myQuery.close();
-
- if (!myQuery.isOK)
- return false;
-
- // Add default record.
-
- return add(new MarketItem("-1,-1 n:Default", null, this, ""));
- }
-
- public boolean add(Object newItem)
- {
- if (newItem instanceof MarketItem)
- return add((MarketItem)newItem);
- return false;
- }
-
- public boolean add(MarketItem newItem) {
- if (hasRecord(newItem, newItem.shopLabel))
- return false; // Don't add if a record already exists.
-
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(newItem.itemId);
- myQuery.inputList.add(newItem.subType);
- myQuery.inputList.add(newItem.count);
- myQuery.inputList.add(newItem.getName());
- myQuery.inputList.add(newItem.basePrice);
- myQuery.inputList.add(newItem.stock);
- myQuery.inputList.add(newItem.canBuy? 1 : 0);
- myQuery.inputList.add(newItem.canSell? 1 : 0);
- myQuery.inputList.add(newItem.getVolatility());
- myQuery.inputList.add(newItem.salesTax);
- myQuery.inputList.add(newItem.stockLowest);
- myQuery.inputList.add(newItem.stockHighest);
- myQuery.inputList.add(newItem.stockFloor);
- myQuery.inputList.add(newItem.stockCeil);
- myQuery.inputList.add(newItem.priceFloor);
- myQuery.inputList.add(newItem.priceCeil);
- myQuery.inputList.add(newItem.shopLabel);
-
- myQuery.prepareStatement("INSERT INTO " + tableName + " (item, subtype, count, name, baseprice, stock, canbuy, cansell, volatility, " +
- "salestax, stocklowest, stockhighest, stockfloor, stockceil, pricefloor, priceceil, class, jitterperc, driftin, driftout, avgstock, shoplabel) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,0,0,0,0,?)");
-
- myQuery.executeUpdates();
-
- myQuery.close();
- return (myQuery.isOK);
- }
-
- public boolean update(MarketItem updated) {
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(updated.count);
- myQuery.inputList.add(updated.getName());
- myQuery.inputList.add(updated.basePrice);
- myQuery.inputList.add(updated.stock);
- myQuery.inputList.add(updated.canBuy? 1 : 0);
- myQuery.inputList.add(updated.canSell? 1 : 0);
- myQuery.inputList.add(updated.getVolatility());
- myQuery.inputList.add(updated.salesTax);
- myQuery.inputList.add(updated.stockLowest);
- myQuery.inputList.add(updated.stockHighest);
- myQuery.inputList.add(updated.stockFloor);
- myQuery.inputList.add(updated.stockCeil);
- myQuery.inputList.add(updated.priceFloor);
- myQuery.inputList.add(updated.priceCeil);
-
- myQuery.inputList.add(updated.itemId);
- myQuery.inputList.add(updated.subType);
- myQuery.inputList.add(updated.shopLabel);
-
- myQuery.prepareStatement("UPDATE " + tableName + " SET count = ?, name = ?, baseprice = ?, stock = ?, canbuy = ?, cansell = ?, volatility = ?, " +
- "salestax = ?, stocklowest = ?, stockhighest = ?, stockfloor = ?, stockceil = ?, pricefloor = ?, priceceil = ? WHERE item = ? AND subtype = ? AND shoplabel = ? " + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
-
- myQuery.executeUpdates();
-
- myQuery.close();
- return (myQuery.isOK);
- }
-
- @Deprecated
- public boolean update(Object updateRef)
- {
- if (updateRef instanceof MarketItem)
- return update((MarketItem)updateRef);
- return false;
- }
-
- @Deprecated
- public ArrayList list(int pageNum)
- {
- return list(pageNum, null, "");
- }
-
- public ArrayList list(int pageNum, String nameFilter, String shopLabel) {
- //CHANGED: This now spits out a list of MarketItems, instead of a list of arrays of ints.
- //If pageNum=0, return the entire list.
- // Optionally filters by partial-string matching of names.
-
- //TODO: Add option for name-sorting.
- SQLHandler myQuery = new SQLHandler(this);
- ArrayList data = new ArrayList();
- int startItem = 0;
- int numItems = 9999999;
- MarketItem newItem;
- if (pageNum > 0)
- {
- startItem = (pageNum - 1) * 8;
- numItems = 8;
- }
-
- if ((nameFilter == null) || (nameFilter.isEmpty()))
- {
- myQuery.inputList.add(shopLabel);
- myQuery.inputList.add(startItem);
- myQuery.inputList.add(numItems);
- myQuery.prepareStatement("SELECT * FROM " + tableName + " WHERE (item >= 0 AND shoplabel = ?) ORDER BY item ASC, subtype ASC LIMIT ?, ?");
- }
- else
- {
- myQuery.inputList.add("%" + nameFilter + "%");
- myQuery.inputList.add(shopLabel);
- myQuery.inputList.add(startItem);
- myQuery.inputList.add(numItems);
- myQuery.prepareStatement("SELECT * FROM " + tableName + " WHERE (item >= 0 AND name LIKE ? AND shoplabel = ?) ORDER BY item ASC, subtype ASC LIMIT ?, ?");
- }
-
- myQuery.executeQuery();
-
- if (myQuery.isOK)
- try {
- while (myQuery.rs.next())
- {
- //data.add(new ShopItem(myQuery.rs.getInt("item"),myQuery.rs.getInt("type"), myQuery.rs.getInt("buy"), myQuery.rs.getInt("sell"), myQuery.rs.getInt("per") ));
- newItem = new MarketItem(myQuery);
- newItem.thisDatabase = this;
- data.add(newItem);
- }
- } catch (SQLException ex) {
- logSevereException("SQL Error during ArrayList fetch: " + dbTypeString(), ex);
- }
-
- myQuery.close();
-
- return data;
- }
-
- @Deprecated
- public MarketItem data(ItemClump thisItem)
- {
- return data(thisItem, "");
- }
-
- public MarketItem data(ItemClump thisItem, String shopLabel) {
- //CHANGED: Returns MarketItems now.
- SQLHandler myQuery = new SQLHandler(this);
- MarketItem fetchedData = null;
-
- myQuery.inputList.add(thisItem.itemId);
- myQuery.inputList.add(thisItem.subType);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("SELECT * FROM " + tableName + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
-
- myQuery.executeQuery();
-
- try {
- if (myQuery.rs != null)
- if (myQuery.rs.next())
- {
- //data = new ShopItem(myQuery.rs.getInt("item"), myQuery.rs.getInt("type"), myQuery.rs.getInt("buy"), myQuery.rs.getInt("sell"), myQuery.rs.getInt("per"));
- fetchedData = new MarketItem(myQuery);
- if (fetchedData == null)
- {
- logSevereException("MarketItem creation from query failed. " + dbTypeString());
- myQuery.close();
- return null;
- }
- fetchedData.thisDatabase = this;
- // TODO: Change constructor to take a ResultSet and throw SQLExceptions.
- }
- } catch (SQLException ex) {
- logSevereException("Error retrieving shop item data with " + dbTypeString(), ex);
- fetchedData = null;
- }
-
- // Temp until constructor throws SQLExceptions
- if (!(myQuery.isOK))
- fetchedData = null;
-
- myQuery.close();
-
- //if (data == null) { data = new MarketItem(); }
- //Return null if no matching data found.
-
- return fetchedData;
- }
-
- public boolean hasRecord(MarketItem thisItem)
- {
- return hasRecord((ItemClump)thisItem, thisItem.shopLabel);
- }
-
- public boolean hasRecord(ItemClump thisItem, String shopLabel)
- {
- // Checks if a given ItemClump has a database entry.
- SQLHandler myQuery = new SQLHandler(this);
- boolean returnVal = false;
-
- myQuery.inputList.add(thisItem.itemId);
- myQuery.inputList.add(thisItem.subType);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("SELECT * FROM " + tableName + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
-
- myQuery.executeQuery();
-
- try {
- if (myQuery.rs != null)
- if (myQuery.rs.next())
- returnVal = true;
- } catch (SQLException ex) {
- logSevereException("Error retrieving shop item data with " + dbTypeString(), ex);
- }
-
- return returnVal;
- }
-
- public boolean addStock(ItemClump thisItem, String shopLabel)
- {
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(thisItem.count);
- myQuery.inputList.add(thisItem.itemId);
- myQuery.inputList.add(thisItem.subType);
- myQuery.inputList.add(shopLabel);
- if (this.databaseType.equals(Type.SQLITE))
- myQuery.prepareStatement("UPDATE " + tableName + " SET stock = min(stock + ?, stockceil) WHERE (item = ? AND subtype = ? AND shoplabel = ?) " + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
- else
- myQuery.prepareStatement("UPDATE " + tableName + " SET stock = LEAST(stock + ?, stockceil) WHERE (item = ? AND subtype = ? AND shoplabel = ?) " + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
-
-
- myQuery.executeUpdates();
-
- myQuery.close();
-
- return myQuery.isOK;
- }
-
- public boolean removeStock(ItemClump thisItem, String shopLabel)
- {
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(thisItem.count);
- myQuery.inputList.add(thisItem.itemId);
- myQuery.inputList.add(thisItem.subType);
- myQuery.inputList.add(shopLabel);
- //if (this.databaseType.equals(Type.SQLITE))
- // myQuery.prepareStatement("UPDATE " + tableName + " SET stock = max(stock - ?, stockfloor) WHERE (item = ? AND subtype = ? AND shoplabel = ?))");
- //else
- myQuery.prepareStatement("UPDATE " + tableName + " SET stock = GREATEST(stock - ?, stockfloor) WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
-
- myQuery.executeUpdates();
-
- myQuery.close();
-
- return myQuery.isOK;
- }
-
- public MarketItem getDefault(String shopLabel)
- {
- return data(new ItemClump(-1, -1), shopLabel);
- }
-
- public ItemClump nameLookup(String searchName, String shopLabel)
- {
- // Parses a name string into an ItemClump with referenced itemId, subtype
- // If name lookup fails, returns null
- // Tries market database names, and if it fails, tries itemsReference.
- ItemClump returnData = null;
-
- if (searchName.equalsIgnoreCase("default"))
- return (new ItemClump(-1,-1));
-
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(searchName);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("SELECT item, subtype FROM " + tableName + " WHERE (name = ? AND shopLabel = ?) LIMIT 1");
-
- myQuery.executeQuery();
-
- try
- {
- if (myQuery.rs != null)
- if (myQuery.rs.next())
- returnData = new ItemClump(myQuery.rs.getInt("item"), myQuery.rs.getInt("subtype"));
- } catch (SQLException ex) {
- logSevereException("Error retrieving item name with " + dbTypeString(), ex);
- returnData = null;
- }
-
- // Temp until constructor throws SQLExceptions
- if (!(myQuery.isOK))
- returnData = null;
-
- myQuery.close();
-
- if (returnData != null)
- return returnData;
-
- // If straight lookup failed, try partial lookup.
- myQuery = new SQLHandler(this);
-
- myQuery.inputList.add("%" + searchName + "%");
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("SELECT item, subtype FROM " + tableName + " WHERE (name LIKE ? AND shoplabel = ?) LIMIT 1");
-
- myQuery.executeQuery();
-
- try
- {
- if (myQuery.rs != null)
- if (myQuery.rs.next())
- returnData = new ItemClump(myQuery.rs.getInt("item"), myQuery.rs.getInt("subtype"));
- } catch (SQLException ex) {
- logSevereException("Error retrieving item name with " + dbTypeString(), ex);
- returnData = null;
- }
-
- // Temp until constructor throws SQLExceptions
- if (!(myQuery.isOK))
- returnData = null;
-
- myQuery.close();
-
- // On lookup failure, try the Items flatfile.
- if (returnData == null)
- if (itemsReference != null)
- returnData = itemsReference.nameLookup(searchName);
-
- return returnData;
- }
-
- public String getName(ItemClump itemData, String shopLabel)
- {
- String returnedName = null;
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(itemData.itemId);
- myQuery.inputList.add(itemData.subType);
- myQuery.inputList.add(shopLabel);
-
- myQuery.prepareStatement("SELECT name FROM " + tableName + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
- myQuery.executeQuery();
-
- try
- {
- if (myQuery.rs != null)
- if (myQuery.rs.next())
- returnedName = myQuery.getString("name");
- } catch (SQLException ex) {
- logSevereException("Error retrieving item name with " + dbTypeString(), ex);
- returnedName = null;
- }
-
- myQuery.close();
-
- if (returnedName == null)
- returnedName = itemsReference.name(itemData);
-
- if ((returnedName == null) && (itemData.isDefault()))
- returnedName = "DEFAULT";
-
- if (returnedName == null)
- return "UNKNOWN";
-
- return returnedName;
-
- }
-
- @Deprecated
- public boolean remove(ItemClump removed)
- {
- return remove(removed, "");
- }
-
- public boolean remove(ItemClump removed, String shopLabel) {
- // CHANGED: Now accepts an itemType (through use of the ItemClump class).
- SQLHandler myQuery = new SQLHandler(this);
-
- myQuery.inputList.add(removed.itemId);
- myQuery.inputList.add(removed.subType);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("DELETE FROM " + tableName + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) " + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
-
- myQuery.executeUpdates();
-
- myQuery.close();
- return myQuery.isOK;
- }
-
- public boolean dumpToCSV(String fileName, String shopLabel)
- {
- // Dumps this database into a .csv file.
- BufferedWriter writer;
- try {
- writer = new BufferedWriter(new FileWriter(fileName, false));
- } catch (IOException ex) {
- logSevereException("Error opening .csv for writing: " + fileName, ex);
- return false;
- }
-
- String line;
-
- line = MarketItem.csvHeaderLine();
- try {
- writer.write(line);
- } catch (IOException ex) {
- logSevereException("I/O error writing .csv header:" + fileName, ex);
- return false;
- }
-
- ArrayList itemsToWrite = list(0, null, shopLabel);
-
- for (MarketItem thisItem : itemsToWrite)
- {
- // Write a line.
- line = thisItem.csvLine();
- try {
- writer.newLine();
- writer.write(line);
- } catch (IOException ex) {
- logSevereException("Error writing output line to .csv: " + fileName, ex);
- return false;
- }
- }
- try {
- writer.flush();
- } catch (IOException ex) {
- logSevereException("Error flushing output after writing .csv:" + fileName, ex);
- }
- try {
- writer.close();
- } catch (IOException ex) {
- logSevereException("Error closing file after writing .csv:" + fileName, ex);
- }
- return true;
- }
-
- public boolean inhaleFromCSV(String fileName, String shopLabel)
- {
- // Sucks a .csv file into this database.
- BufferedReader reader;
- MarketItem importItem;
- try {
- reader = new BufferedReader(new FileReader(fileName));
- } catch (FileNotFoundException ex) {
- logSevereException("File not found while importing .csv: " + fileName, ex);
- return false;
- }
-
- String line;
- try {
- line = reader.readLine();
- //if (!line.equalsIgnoreCase(MarketItem.csvHeaderLine()))
- //{
- // plugin.log.severe("[" + plugin.name + "]: Bad header line reading .csv: " + fileName);
- // return false;
- //}
- line = reader.readLine();
- } catch (IOException ex) {
- logSevereException("I/O error importing .csv:" + fileName, ex);
- return false;
- }
- while (line != null)
- {
- if (line.trim().length() == 0)
- {
- continue;
- }
- // Parse a line.
- //plugin.log.info(line);
- line = line.replace("'","").replace("\"","");
- importItem = new MarketItem(line, null, shopLabel, true);
- if (hasRecord(importItem, shopLabel))
- {
- importItem = new MarketItem(line, data(importItem, shopLabel), shopLabel, true);
- update(importItem);
- }
- else
- {
- add(importItem);
- }
- try {
- line = reader.readLine();
- } catch (IOException ex) {
- logSevereException("I/O error reading .csv:" + fileName, ex);
- break;
- }
- }
- try {
- reader.close();
- } catch (IOException ex) {
- logSevereException("Error closing file after importing .csv: " + fileName, ex);
- }
- return true;
- }
-
- private void updateAll(SQLHandler myQuery, String fieldName, Object newValue, String shopLabel)
- {
- // Update fieldName to newValue in all records matching shopLabel.
- myQuery.inputList.add(newValue);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE " + tableName + " SET " + fieldName + " = ? WHERE shoplabel = ?");
- }
-
- private void updateAllExpr(SQLHandler myQuery, String fieldName, String updExpr, String shopLabel)
- {
- // Update fieldName to expression updExpr in all records matching shopLabel.
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE " + tableName + " SET " + fieldName + " = " + updExpr + " WHERE shoplabel = ?");
- }
-
- private void updateAllExprWhere(SQLHandler myQuery, String fieldName, String updExpr, String whereClause, String shopLabel)
- {
- // Update fieldName to expression updExpr in all records matching whereClause and shopLabel.
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE " + tableName + " SET " + fieldName + " = " + updExpr + " WHERE (shoplabel = ? AND " + whereClause + ")");
- }
-
- public boolean updateAllFromTags(String initString, String shopLabel)
- {
- // Update table data from a list of tags.
- // Applies changes to every element of the table matching shopLabel.
- // Mirrors MarketItem.parseTags.
- // Element [0] is used only to extract count, if provided.
- String initData[] = initString.split(" ");
- String curTag;
- Integer curVal;
- String stringVal;
- String[] curParams;
- boolean setUntaggedBase = false;
- SQLHandler myQuery = new SQLHandler(this);
-
- if (initData[0].contains(":"))
- {
- // Count detected. Pull it out, if it's valid.
- ItemClump countCheck = new ItemClump(initData[0], null, "");
- // Update all counts, rescaling stock levels and base prices.
- //basePrice = Math.round((float)prev.basePrice * new.count / prev.count);
- //stockItems = stock * count;
- //new.stockItems = prev.stockItems;
- // new.stock * new.count = prev.stock * old.count;
- // new.stock = prev.stock * prev.count / new.count;
- updateAllExpr(myQuery, "baseprice", "ROUND(baseprice * " + countCheck.count + " / count, 0)", shopLabel);
- updateAllExpr(myQuery, "stock", "ROUND((stock * count / " + countCheck.count + ")-0.5,0)", shopLabel);
- updateAll(myQuery, "count", countCheck.count, shopLabel);
- }
-
- if (initData.length > 1)
- {
- for (int i = 1; i <= initData.length - 1; i++)
- {
- stringVal = null;
- // Get current tag and value
-
- if (initData[i].contains(":"))
- {
- curParams = initData[i].split(":");
- curTag = curParams[0];
- try
- {
- curVal = Integer.parseInt(curParams[1]);
- }
- catch (NumberFormatException ex)
- {
- if (curParams[1].equalsIgnoreCase("+INF"))
- curVal = Integer.MAX_VALUE;
- else if (curParams[1].equalsIgnoreCase("-INF"))
- curVal = Integer.MIN_VALUE;
- else
- {
- curVal = null;
- stringVal = curParams[1];
- }
- }
- }
- else
- {
- try
- { // Try to parse it as a plain integer.
- curTag = null;
- curVal = Integer.parseInt(initData[i]);
- }
- catch (NumberFormatException ex)
- { // Didn't work? Just use it as a string.
- curVal = null;
- curTag = initData[i];
- }
- }
-
- // If first param is an untagged value, make it the basePrice.
- if (i == 1)
- {
- if (curTag == null)
- {
- if (curVal != -1)
- {
- //this.basePrice = curVal;
- updateAll(myQuery, "baseprice", curVal, shopLabel);
- //maskData.basePrice = 1;
- }
- else
- {
- // Base price set to -1. Disable buying.
- //this.basePrice = 0;
- updateAll(myQuery, "baseprice", 0, shopLabel);
- //maskData.basePrice = 1;
- //this.canBuy = false;
- updateAll(myQuery, "canbuy", 0, shopLabel);
- }
- setUntaggedBase = true;
- continue;
- }
- }
-
- // If second param is an untagged value, make the sellPrice equal to it after sales tax is applied.
- if (i == 2)
- {
- if ((setUntaggedBase) && (curTag == null))
- {
- if (curVal != -1)
- {
- // if salePrice = basePrice * (1 - (salesTax / 100))
- // then (1 - (salePrice / basePrice)) * 100 = salesTax
- /*
- if (this.basePrice != 0)
- {
- this.salesTax = Math.round((1 - ((float)curVal / basePrice)) * 100);
- //maskData.salesTax = 1;
- }
- else
- {
- this.basePrice = curVal;
- this.salesTax = 0;
- //maskData.salesTax = 1;
- }
- */
- updateAllExprWhere(myQuery, "salestax", "ROUND((1 - (" + curVal + " / baseprice)) * 100)", "baseprice > 0", shopLabel);
- updateAllExprWhere(myQuery, "salestax", "0", "baseprice = 0", shopLabel);
- updateAllExprWhere(myQuery, "baseprice", curVal.toString(), "baseprice = 0", shopLabel);
- }
- else
- {
- // Sale price set to -1. Disable selling.
- //this.canSell = false;
- updateAll(myQuery, "cansell", 0, shopLabel);
- }
- continue;
- }
- }
-
- // Handle remaining items in split.
-
- if (curTag != null)
- {
- if (curVal != null)
- {
- if (curTag.equalsIgnoreCase("bp") || curTag.equalsIgnoreCase("baseprice"))
- {
- //this.basePrice = curVal;
- updateAll(myQuery, "baseprice", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("s") || curTag.equalsIgnoreCase("stock"))
- {
- //this.stock = curVal;
- updateAll(myQuery, "stock", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("v") || curTag.equalsIgnoreCase("volatility") || curTag.equalsIgnoreCase("vol"))
- {
- //this.setVolatility(curVal);
- updateAll(myQuery, "volatility", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("iv") || curTag.equalsIgnoreCase("invvolatility") || curTag.equalsIgnoreCase("ivol"))
- {
- //this.setInverseVolatility(curVal);
- updateAll(myQuery, "volatility", MarketItem.iVolToVol(curVal), shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("st") || curTag.equalsIgnoreCase("salestax"))
- {
- //this.salesTax = rangeCrop(curVal, 0, 100);
- updateAll(myQuery, "salestax", MarketItem.rangeCrop(curVal, 0, 100), shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("sl") || curTag.equalsIgnoreCase("stocklowest"))
- {
- //this.stockLowest = curVal;
- updateAll(myQuery, "stocklowest", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("sh") || curTag.equalsIgnoreCase("stockhighest"))
- {
- //this.stockHighest = curVal;
- updateAll(myQuery, "stockhighest", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("sf") || curTag.equalsIgnoreCase("stockfloor"))
- {
- //this.stockFloor = curVal;
- updateAll(myQuery, "stockfloor", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("sc") || curTag.equalsIgnoreCase("stockceiling"))
- {
- //this.stockCeil = curVal;
- updateAll(myQuery, "stockceil", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("pf") || curTag.equalsIgnoreCase("pricefloor"))
- {
- //this.priceFloor = curVal;
- updateAll(myQuery, "pricefloor", curVal, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("pc") || curTag.equalsIgnoreCase("priceceiling"))
- {
- //this.priceCeil = curVal;
- updateAll(myQuery, "priceceil", curVal, shopLabel);
- continue;
- }
- }
- }
- if (curTag.equalsIgnoreCase("flat"))
- {
- //this.stock = 0;
- updateAll(myQuery, "stock", 0, shopLabel);
- //this.stockLowest = Integer.MIN_VALUE;
- updateAll(myQuery, "stocklowest", Integer.MIN_VALUE, shopLabel);
- //this.stockHighest = Integer.MAX_VALUE;
- updateAll(myQuery, "stockhighest", Integer.MAX_VALUE, shopLabel);
- //this.stockFloor = Integer.MIN_VALUE;
- updateAll(myQuery, "stockfloor", Integer.MIN_VALUE, shopLabel);
- //this.stockCeil = Integer.MAX_VALUE;
- updateAll(myQuery, "stockceil", Integer.MAX_VALUE, shopLabel);
- //this.priceFloor = 0;
- updateAll(myQuery, "pricefloor", 0, shopLabel);
- //this.priceCeil = Integer.MAX_VALUE;
- updateAll(myQuery, "priceceil", Integer.MAX_VALUE, shopLabel);
- //this.volatility = 0;
- updateAll(myQuery, "volatility", 0, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("fixed"))
- {
- //this.stock = 0;
- updateAll(myQuery, "stock", 0, shopLabel);
- //this.stockLowest = Integer.MIN_VALUE;
- updateAll(myQuery, "stocklowest", Integer.MIN_VALUE, shopLabel);
- //this.stockHighest = Integer.MAX_VALUE;
- updateAll(myQuery, "stockhighest", Integer.MAX_VALUE, shopLabel);
- //this.stockFloor = 0;
- updateAll(myQuery, "stockfloor", 0, shopLabel);
- //this.stockCeil = 0;
- updateAll(myQuery, "stockceil", 0, shopLabel);
- //this.priceFloor = 0;
- updateAll(myQuery, "pricefloor", 0, shopLabel);
- //this.priceCeil = Integer.MAX_VALUE;
- updateAll(myQuery, "priceceil", Integer.MAX_VALUE, shopLabel);
- //this.volatility = 0;
- updateAll(myQuery, "volatility", 0, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("float"))
- {
- //this.stockFloor = Integer.MIN_VALUE;
- updateAll(myQuery, "stockfloor", Integer.MIN_VALUE, shopLabel);
- //this.stockCeil = Integer.MAX_VALUE;
- updateAll(myQuery, "stockceil", Integer.MAX_VALUE, shopLabel);
- //this.stockLowest = Integer.MIN_VALUE;
- updateAll(myQuery, "stocklowest", Integer.MIN_VALUE, shopLabel);
- //this.stockHighest = Integer.MAX_VALUE;
- updateAll(myQuery, "stockhighest", Integer.MAX_VALUE, shopLabel);
- //this.priceFloor = 0;
- updateAll(myQuery, "pricefloor", 0, shopLabel);
- //this.priceCeil = Integer.MAX_VALUE;
- updateAll(myQuery, "priceceil", Integer.MAX_VALUE, shopLabel);
- //if (this.volatility == 0)
- // this.volatility = 100;
- updateAllExprWhere(myQuery, "volatility", "100", "volatility = 0", shopLabel);
- }
- if (curTag.equalsIgnoreCase("finite"))
- {
- //this.stockFloor = Integer.MIN_VALUE;
- updateAll(myQuery, "stockfloor", Integer.MIN_VALUE, shopLabel);
- //this.stockCeil = Integer.MAX_VALUE;
- updateAll(myQuery, "stockceil", Integer.MAX_VALUE, shopLabel);
- //this.stockLowest = 0;
- updateAll(myQuery, "stocklowest", 0, shopLabel);
- //this.stockHighest = Integer.MAX_VALUE;
- updateAll(myQuery, "stockhighest", Integer.MAX_VALUE, shopLabel);
- }
- if ((curTag.equalsIgnoreCase("buyok")) || (curTag.equalsIgnoreCase("!nobuy")))
- {
- //this.canBuy = true;
- updateAll(myQuery, "canbuy", 1, shopLabel);
- continue;
- }
- if ((curTag.equalsIgnoreCase("sellok")) || (curTag.equalsIgnoreCase("!nosell")))
- {
- //this.canSell = true;
- updateAll(myQuery, "cansell", 1, shopLabel);
- continue;
- }
- if ((curTag.equalsIgnoreCase("!buyok")) || (curTag.equalsIgnoreCase("nobuy")) || (curTag.equalsIgnoreCase("!cb")))
- {
- //this.canBuy = false;
- updateAll(myQuery, "canbuy", 0, shopLabel);
- continue;
- }
- if ((curTag.equalsIgnoreCase("!sellok")) || (curTag.equalsIgnoreCase("nosell")) || (curTag.equalsIgnoreCase("!cs")))
- {
- //this.canSell = false;
- updateAll(myQuery, "cansell", 0, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("cb") || curTag.equalsIgnoreCase("canbuy"))
- {
- if ((stringVal != null) && (!(stringVal.isEmpty())))
- {
- //this.canBuy = ((stringVal.toLowerCase().startsWith("y")) || (stringVal.toLowerCase().startsWith("t")));
- if ((stringVal.toLowerCase().startsWith("y")) || (stringVal.toLowerCase().startsWith("t")))
- updateAll(myQuery, "canbuy", 1, shopLabel);
- else
- updateAll(myQuery, "canbuy", 0, shopLabel);
- }
- else
- //this.canBuy = true;
- updateAll(myQuery, "canbuy", 1, shopLabel);
- continue;
- }
- if (curTag.equalsIgnoreCase("cs") || curTag.equalsIgnoreCase("cansell"))
- {
- if ((stringVal != null) && (!(stringVal.isEmpty())))
- {
- //this.canSell = ((stringVal.toLowerCase().startsWith("y")) || (stringVal.toLowerCase().startsWith("t")));
- if ((stringVal.toLowerCase().startsWith("y")) || (stringVal.toLowerCase().startsWith("t")))
- updateAll(myQuery, "cansell", 1, shopLabel);
- else
- updateAll(myQuery, "cansell", 0, shopLabel);
- }
- else
- //this.canSell = true;
- updateAll(myQuery, "cansell", 1, shopLabel);
- continue;
- }
- /*
- // Renaming everything to the same value doesn't make sense.
- if ((curTag.equalsIgnoreCase("name")) || (curTag.equalsIgnoreCase("n")))
- {
- //setName(stringVal);
- updateAll("name", stringVal, shopLabel);
- continue;
- }
- */
- if (curTag.equalsIgnoreCase("renorm"))
- {
- //double oldBuyPrice = getStockPrice(this.stock);
- //getStockPrice(stockLevel) = rangeCrop(this.basePrice * Math.pow(getVolFactor(), -rangeCrop(stockLevel, stockFloor, stockCeil)), priceFloor, priceCeil)
- //getVolFactor = (1 + volatility/intScale)
- //rangeCrop(double value, double minVal, double maxVal) = (Math.min(Math.max(value, minVal), maxVal))
- // oldBuyPrice = LEAST(GREATEST(baseprice * POW((1 + volatility/INTSCALE), -LEAST(GREATEST(stock, stockfloor), stockceil)), pricefloor), priceceil)
- int newStock;
- if (curVal == null)
- newStock = 0;
- else
- newStock = curVal;
- //this.basePrice = ROUND(oldBuyPrice / POW(getVolFactor(), -rangeCrop(this.stock, stockFloor, stockCeil)));
- //this.basePrice = ROUND(oldBuyPrice / POW((1 + volatility/INTSCALE), -LEAST(GREATEST(stock, stockFloor), stockCeil)));
- //this.basePrice = ROUND(LEAST(GREATEST(baseprice * POW((1 + volatility/INTSCALE), -LEAST(GREATEST(stock, stockfloor), stockceil)), pricefloor), priceceil) / POW((1 + volatility/INTSCALE), -LEAST(GREATEST(stock, stockFloor), stockCeil)));
- //blerg! all this to do the update within a single MySQL statement!
- //And it's not even translatable to SQLite!
- //Maybe use this later. Simple & crude method for right now.
-
- // This is ugly and nasty, but necessary for SQLite compatibility.
- // SQLite doesn't understand ^, POW(), ln(), or EXP() without a tricky-to-install add-on.
- ArrayList itemsToEdit = list(0, null, shopLabel);
- if (!itemsToEdit.isEmpty())
- {
- myQuery.prepareBatchStatement("UPDATE " + tableName + " SET basePrice = ? WHERE (shoplabel = ? AND item = ? AND subtype = ?");
- for (MarketItem thisItem : itemsToEdit)
- {
- myQuery.inputList.add(Integer.toString(thisItem.getRenormedPrice(newStock)));
- myQuery.inputList.add(shopLabel);
- myQuery.inputList.add(thisItem.itemId);
- myQuery.inputList.add(thisItem.subType);
- myQuery.addToBatch();
- }
- updateAll(myQuery, "stock", newStock, shopLabel);
- }
- }
- }
- //TODO: Log and report invalid tags somehow.
- }
- // Finished parsing tags. Do the update.
-
- myQuery.executeUpdates();
-
- myQuery.close();
-
- sanityCheckAll(shopLabel);
-
- return myQuery.isOK;
-
- }
-
- private boolean sanityCheckAll(String shopLabel)
- {
- // Check and fix possible chaos-inducing data.
- // Mirrors marketItem.sanityCheck.
-
- SQLHandler myQuery = new SQLHandler(this);
-
- // Check range of salesTax
- //this.salesTax = rangeCrop(this.salesTax, 0, 100);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET salestax = LEAST(100, GREATEST(salestax, 0)) WHERE shoplabel = ?");
-
- //if (this.stockHighest < this.stock)
- // this.stockHighest = this.stock;
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET stockhighest = stock WHERE (shoplabel = ? AND stockhighest < stock)");
-
- //if (this.stockLowest > this.stock)
- // this.stockLowest = this.stock;
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET stocklowest = stock WHERE (shoplabel = ? AND stocklowest > stock)");
-
-
- //if (this.stockCeil < this.stock)
- // this.stockCeil = this.stock;
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET stockceil = stock WHERE (shoplabel = ? AND stockceil < stock)");
-
- //if (this.stockFloor > this.stock)
- // this.stockFloor = this.stock;
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET stockfloor = stock WHERE (shoplabel = ? AND stockfloor > stock)");
-
- //if (this.priceCeil < this.priceFloor)
- // this.priceCeil = this.priceFloor;
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET priceceil = pricefloor WHERE (shoplabel = ? AND priceceil < pricefloor)");
-
- // Check range of basePrice
- //this.basePrice = Math.max(0, this.basePrice);
- myQuery.inputList.add(shopLabel);
- myQuery.prepareStatement("UPDATE "+tableName+" SET baseprice = 0 WHERE (shoplabel = ? AND baseprice < 0)");
-
- myQuery.executeUpdates();
-
- myQuery.close();
-
- return myQuery.isOK;
- }
-
- /*
- private boolean updateAll(String[] fieldName, Object[] newValue, String shopLabel)
- {
- // Update several fieldNames to newValues in all records matching shopLabel.
- return false;
- }
- */
+public class DatabaseMarket extends DatabaseCore {
+ // public Type database = null;
+ public Items itemsReference = null;
+
+ public DatabaseMarket(Type database, String tableAccessed, Items itemsRef, String thisEngine, DynamicMarket pluginRef) {
+ super(database, tableAccessed, thisEngine, pluginRef); // default table name: "Market"
+ checkNewFields();
+ this.itemsReference = itemsRef;
+ }
+
+ @Deprecated
+ public DatabaseMarket(Type database, String tableAccessed, String thisEngine, DynamicMarket pluginRef) {
+ super(database, tableAccessed, thisEngine, pluginRef);
+ this.itemsReference = null;
+ }
+
+ protected void checkColumn(String columnName, String columnDef, String index) {
+ SQLHandler myQuery = new SQLHandler(this);
+ if (!myQuery.checkColumnExists(tableName, columnName)) {
+ myQuery.prepareStatement("ALTER TABLE " + tableName + " ADD " + columnName + " " + columnDef);
+ myQuery.prepareStatement(index);
+ myQuery.executeUpdates();
+ }
+ myQuery.close();
+ }
+
+ protected void checkColumn(String columnName, String columnDef) {
+ SQLHandler myQuery = new SQLHandler(this);
+ if (!myQuery.checkColumnExists(tableName, columnName)) {
+ myQuery.prepareStatement("ALTER TABLE " + tableName + " ADD " + columnName + " " + columnDef);
+ myQuery.executeUpdates();
+ }
+ myQuery.close();
+ }
+
+ protected void checkNewFields() {
+ checkColumn( "shoplabel",
+ (this.databaseType.equals(Type.SQLITE) ? "TEXT NOT NULL DEFAULT '';" : "CHAR(20) NOT NULL DEFAULT ''"),
+ "CREATE INDEX shoplabelIndex ON Market (shoplabel)");
+ }
+
+ protected boolean createTable(String shopLabel) {
+ SQLHandler myQuery = new SQLHandler(this);
+ if (!myQuery.checkTable(tableName)) {
+ myQuery.close();
+ return createTable();
+ } else {
+ myQuery.close();
+ return false;
+ }
+ }
+
+ protected boolean createTable() {
+ SQLHandler myQuery = new SQLHandler(this);
+ if (this.databaseType.equals(Type.SQLITE)) {
+ myQuery.executeStatement("CREATE TABLE " + tableName
+ + " ( id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "item INT NOT NULL, "
+ + "subtype INT NOT NULL, "
+ + "name TEXT NOT NULL, "
+ + "count INT NOT NULL, "
+ + "baseprice INT NOT NULL, "
+ + "canbuy INT NOT NULL, "
+ + "cansell INT NOT NULL, "
+ + "stock INT NOT NULL, "
+ + "volatility INT NOT NULL, "
+ + "salestax INT NOT NULL, "
+ + "stockhighest INT NOT NULL, "
+ + "stocklowest INT NOT NULL, "
+ + "stockfloor INT NOT NULL, "
+ + "stockceil INT NOT NULL, "
+ + "pricefloor INT NOT NULL, "
+ + "priceceil INT NOT NULL, "
+ + "jitterperc INT NOT NULL, "
+ + "driftout INT NOT NULL, "
+ + "driftin INT NOT NULL, "
+ + "avgstock INT NOT NULL, "
+ + "class INT NOT NULL, "
+ + "shoplabel TEXT NOT NULL DEFAULT '');"
+ + "CREATE INDEX itemIndex ON Market (item);"
+ + "CREATE INDEX subtypeIndex ON Market (subtype);"
+ + "CREATE INDEX nameIndex ON Market (name);"
+ + "CREATE INDEX shoplabelIndex ON Market (shoplabel)");
+
+ } else {
+ myQuery.executeStatement("CREATE TABLE "
+ + tableName
+ + " ( id INT( 255 ) NOT NULL AUTO_INCREMENT, "
+ + "item INT NOT NULL, "
+ + "subtype INT NOT NULL, "
+ + "name CHAR(20) NOT NULL, "
+ + "count INT NOT NULL, "
+ + "baseprice INT NOT NULL, "
+ + "stock INT NOT NULL, "
+ + "canbuy INT NOT NULL, "
+ + "cansell INT NOT NULL, "
+ + "volatility INT NOT NULL, "
+ + "salestax INT NOT NULL, "
+ + "stocklowest INT NOT NULL, "
+ + "stockhighest INT NOT NULL, "
+ + "stockfloor INT NOT NULL, "
+ + "stockceil INT NOT NULL, "
+ + "pricefloor INT NOT NULL, "
+ + "priceceil INT NOT NULL, "
+ + "jitterperc INT NOT NULL, "
+ + "driftout INT NOT NULL, "
+ + "driftin INT NOT NULL, "
+ + "avgstock INT NOT NULL, "
+ + "class INT NOT NULL, "
+ + "shoplabel CHAR(20) NOT NULL DEFAULT '', "
+ + "PRIMARY KEY ( id ), INDEX ( item, subtype, name, shoplabel )) ENGINE = "
+ + engine + ";");
+ }
+ myQuery.close();
+
+ if (!myQuery.isOK)
+ return false;
+
+ // Add default record.
+
+ return add(new MarketItem("-1,-1 n:Default", new MarketItem(), this, ""));
+ }
+
+ public boolean add(Object newItem) {
+ if (newItem instanceof MarketItem)
+ return add((MarketItem) newItem);
+ return false;
+ }
+
+ public boolean add(MarketItem newItem) {
+ if (hasRecord(newItem, newItem.shopLabel))
+ return false; // Don't add if a record already exists.
+
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(newItem.itemId);
+ myQuery.inputList.add(newItem.subType);
+ myQuery.inputList.add(newItem.count);
+ myQuery.inputList.add(newItem.getName());
+ myQuery.inputList.add(newItem.basePrice);
+ myQuery.inputList.add(newItem.stock);
+ myQuery.inputList.add(newItem.canBuy ? 1 : 0);
+ myQuery.inputList.add(newItem.canSell ? 1 : 0);
+ myQuery.inputList.add(newItem.getVolatility());
+ myQuery.inputList.add(newItem.salesTax);
+ myQuery.inputList.add(newItem.stockLowest);
+ myQuery.inputList.add(newItem.stockHighest);
+ myQuery.inputList.add(newItem.stockFloor);
+ myQuery.inputList.add(newItem.stockCeil);
+ myQuery.inputList.add(newItem.priceFloor);
+ myQuery.inputList.add(newItem.priceCeil);
+ myQuery.inputList.add(newItem.shopLabel);
+
+ myQuery.prepareStatement("INSERT INTO "
+ + tableName
+ + " (item, subtype, count, name, baseprice, stock, canbuy, cansell, volatility, "
+ + "salestax, stocklowest, stockhighest, stockfloor, stockceil, pricefloor, priceceil, class, jitterperc, driftin, driftout, avgstock, shoplabel) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,0,0,0,0,?)");
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+ return (myQuery.isOK);
+ }
+
+ public boolean update(MarketItem updated) {
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(updated.count);
+ myQuery.inputList.add(updated.getName());
+ myQuery.inputList.add(updated.basePrice);
+ myQuery.inputList.add(updated.stock);
+ myQuery.inputList.add(updated.canBuy ? 1 : 0);
+ myQuery.inputList.add(updated.canSell ? 1 : 0);
+ myQuery.inputList.add(updated.getVolatility());
+ myQuery.inputList.add(updated.salesTax);
+ myQuery.inputList.add(updated.stockLowest);
+ myQuery.inputList.add(updated.stockHighest);
+ myQuery.inputList.add(updated.stockFloor);
+ myQuery.inputList.add(updated.stockCeil);
+ myQuery.inputList.add(updated.priceFloor);
+ myQuery.inputList.add(updated.priceCeil);
+
+ myQuery.inputList.add(updated.itemId);
+ myQuery.inputList.add(updated.subType);
+ myQuery.inputList.add(updated.shopLabel);
+
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET count = ?, name = ?, baseprice = ?, stock = ?, canbuy = ?, cansell = ?, volatility = ?, "
+ + "salestax = ?, stocklowest = ?, stockhighest = ?, stockfloor = ?, stockceil = ?, pricefloor = ?, priceceil = ? WHERE item = ? AND subtype = ? AND shoplabel = ? "
+ + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+ return (myQuery.isOK);
+ }
+
+ @Deprecated
+ public boolean update(Object updateRef) {
+ if (updateRef instanceof MarketItem)
+ return update((MarketItem) updateRef);
+ return false;
+ }
+
+ @Deprecated
+ public ArrayList list(int pageNum) {
+ return list(pageNum, null, "");
+ }
+
+ public ArrayList list(int pageNum, String nameFilter, String shopLabel) {
+ //CHANGED: This now spits out a list of MarketItems, instead of a list of arrays of ints.
+ // If pageNum=0, return the entire list.
+ // Optionally filters by partial-string matching of names.
+
+ // TODO: Add option for name-sorting.
+ SQLHandler myQuery = new SQLHandler(this);
+ ArrayList data = new ArrayList();
+ int startItem = 0;
+ int numItems = 9999999;
+ MarketItem newItem;
+ if (pageNum > 0) {
+ startItem = (pageNum - 1) * 8;
+ numItems = 8;
+ }
+
+ if ((nameFilter == null) || (nameFilter.isEmpty())) {
+ myQuery.inputList.add(shopLabel);
+ myQuery.inputList.add(numItems);
+ myQuery.inputList.add(startItem);
+ myQuery.prepareStatement("SELECT * FROM "
+ + tableName
+ + " WHERE (item >= 0 AND shoplabel = ?) ORDER BY item ASC, subtype ASC LIMIT ? OFFSET ?");
+ } else {
+ myQuery.inputList.add("%" + nameFilter + "%");
+ myQuery.inputList.add(shopLabel);
+ myQuery.inputList.add(numItems);
+ myQuery.inputList.add(startItem);
+ myQuery.prepareStatement("SELECT * FROM "
+ + tableName
+ + " WHERE (item >= 0 AND name LIKE ? AND shoplabel = ?) ORDER BY item ASC, subtype ASC LIMIT ? OFFSET ?");
+ }
+
+ myQuery.executeQuery();
+
+ if (myQuery.isOK)
+ try {
+ while (myQuery.rs.next()) {
+ // data.add(new
+ // ShopItem(myQuery.rs.getInt("item"),myQuery.rs.getInt("type"),
+ // myQuery.rs.getInt("buy"), myQuery.rs.getInt("sell"),
+ // myQuery.rs.getInt("per") ));
+ newItem = new MarketItem(myQuery);
+ newItem.thisDatabase = this;
+ data.add(newItem);
+ }
+ } catch (SQLException ex) {
+ logSevereException("SQL Error during ArrayList fetch: " + dbTypeString(), ex);
+ }
+
+ myQuery.close();
+
+ return data;
+ }
+
+ @Deprecated
+ public MarketItem data(ItemClump thisItem) {
+ return data(thisItem, "");
+ }
+
+ public MarketItem data(ItemClump thisItem, String shopLabel) {
+ // CHANGED: Returns MarketItems now.
+ SQLHandler myQuery = new SQLHandler(this);
+ MarketItem fetchedData = null;
+
+ myQuery.inputList.add(thisItem.itemId);
+ myQuery.inputList.add(thisItem.subType);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("SELECT * FROM " + tableName
+ + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
+
+ myQuery.executeQuery();
+
+ try {
+ if (myQuery.rs != null)
+ if (myQuery.rs.next()) {
+ // data = new ShopItem(myQuery.rs.getInt("item"),
+ // myQuery.rs.getInt("type"), myQuery.rs.getInt("buy"),
+ // myQuery.rs.getInt("sell"), myQuery.rs.getInt("per"));
+ fetchedData = new MarketItem(myQuery);
+ if (fetchedData == null) {
+ logSevereException("MarketItem creation from query failed. "
+ + dbTypeString());
+ myQuery.close();
+ return null;
+ }
+ fetchedData.thisDatabase = this;
+ // TODO: Change constructor to take a ResultSet and throw
+ // SQLExceptions.
+ }
+ } catch (SQLException ex) {
+ logSevereException("Error retrieving shop item data with " + dbTypeString(), ex);
+ fetchedData = null;
+ }
+
+ // Temp until constructor throws SQLExceptions
+ if (!(myQuery.isOK))
+ fetchedData = null;
+
+ myQuery.close();
+
+ // if (data == null) { data = new MarketItem(); }
+ // Return null if no matching data found.
+
+ return fetchedData;
+ }
+
+ public boolean hasRecord(MarketItem thisItem) {
+ return hasRecord((ItemClump) thisItem, thisItem.shopLabel);
+ }
+
+ public boolean hasRecord(ItemClump thisItem, String shopLabel) {
+ // Checks if a given ItemClump has a database entry.
+ SQLHandler myQuery = new SQLHandler(this);
+ boolean returnVal = false;
+
+ myQuery.inputList.add(thisItem.itemId);
+ myQuery.inputList.add(thisItem.subType);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("SELECT * FROM " + tableName + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
+
+ myQuery.executeQuery();
+
+ try {
+ if (myQuery.rs != null)
+ if (myQuery.rs.next())
+ returnVal = true;
+ } catch (SQLException ex) {
+ logSevereException("Error retrieving shop item data with "
+ + dbTypeString(), ex);
+ }
+
+ myQuery.close();
+
+ return returnVal;
+ }
+
+ public boolean addStock(ItemClump thisItem, String shopLabel) {
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(thisItem.count);
+ myQuery.inputList.add(thisItem.itemId);
+ myQuery.inputList.add(thisItem.subType);
+ myQuery.inputList.add(shopLabel);
+ if (this.databaseType.equals(Type.SQLITE))
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stock = min(stock + ?, stockceil) WHERE (item = ? AND subtype = ? AND shoplabel = ?) "
+ + ((this.databaseType.equals(Type.SQLITE)) ? ""
+ : " LIMIT 1"));
+ else
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stock = LEAST(stock + ?, stockceil) WHERE (item = ? AND subtype = ? AND shoplabel = ?) "
+ + ((this.databaseType.equals(Type.SQLITE)) ? ""
+ : " LIMIT 1"));
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+
+ return myQuery.isOK;
+ }
+
+ public boolean removeStock(ItemClump thisItem, String shopLabel) {
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(thisItem.count);
+ myQuery.inputList.add(thisItem.itemId);
+ myQuery.inputList.add(thisItem.subType);
+ myQuery.inputList.add(shopLabel);
+ // if (this.databaseType.equals(Type.SQLITE))
+ // myQuery.prepareStatement("UPDATE " + tableName +
+ // " SET stock = max(stock - ?, stockfloor) WHERE (item = ? AND subtype = ? AND shoplabel = ?))");
+ // else
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stock = GREATEST(stock - ?, stockfloor) WHERE (item = ? AND subtype = ? AND shoplabel = ?)"
+ + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+
+ return myQuery.isOK;
+ }
+
+ public MarketItem getDefault(String shopLabel) {
+ return data(new ItemClump(-1, -1), shopLabel);
+ }
+
+ public ItemClump nameLookup(String searchName, String shopLabel) {
+ // Parses a name string into an ItemClump with referenced itemId,
+ // subtype
+ // If name lookup fails, returns null
+ // Tries market database names, and if it fails, tries itemsReference.
+ ItemClump returnData = null;
+
+ if (searchName.equalsIgnoreCase("default"))
+ return (new ItemClump(-1, -1));
+
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(searchName);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("SELECT item, subtype FROM " + tableName
+ + " WHERE (name = ? AND shopLabel = ?) LIMIT 1");
+
+ myQuery.executeQuery();
+
+ try {
+ if (myQuery.rs != null)
+ if (myQuery.rs.next())
+ returnData = new ItemClump(myQuery.rs.getInt("item"),
+ myQuery.rs.getInt("subtype"));
+ } catch (SQLException ex) {
+ logSevereException("Error retrieving item name with "
+ + dbTypeString(), ex);
+ returnData = null;
+ }
+
+ // Temp until constructor throws SQLExceptions
+ if (!(myQuery.isOK))
+ returnData = null;
+
+ myQuery.close();
+
+ if (returnData != null)
+ return returnData;
+
+ // If straight lookup failed, try partial lookup.
+ myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add("%" + searchName + "%");
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("SELECT item, subtype FROM " + tableName
+ + " WHERE (name LIKE ? AND shoplabel = ?) LIMIT 1");
+
+ myQuery.executeQuery();
+
+ try {
+ if (myQuery.rs != null)
+ if (myQuery.rs.next())
+ returnData = new ItemClump(myQuery.rs.getInt("item"),
+ myQuery.rs.getInt("subtype"));
+ } catch (SQLException ex) {
+ logSevereException("Error retrieving item name with "
+ + dbTypeString(), ex);
+ returnData = null;
+ }
+
+ // Temp until constructor throws SQLExceptions
+ if (!(myQuery.isOK))
+ returnData = null;
+
+ myQuery.close();
+
+ // On lookup failure, try the Items flatfile.
+ if (returnData == null)
+ if (itemsReference != null)
+ returnData = itemsReference.nameLookup(searchName);
+
+ return returnData;
+ }
+
+ public String getName(ItemClump itemData, String shopLabel) {
+ String returnedName = null;
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(itemData.itemId);
+ myQuery.inputList.add(itemData.subType);
+ myQuery.inputList.add(shopLabel);
+
+ myQuery.prepareStatement("SELECT name FROM " + tableName
+ + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) LIMIT 1");
+ myQuery.executeQuery();
+
+ try {
+ if (myQuery.rs != null)
+ if (myQuery.rs.next())
+ returnedName = myQuery.getString("name");
+ } catch (SQLException ex) {
+ logSevereException("Error retrieving item name with "
+ + dbTypeString(), ex);
+ returnedName = null;
+ }
+
+ myQuery.close();
+
+ if (returnedName == null)
+ returnedName = itemsReference.name(itemData);
+
+ if ((returnedName == null) && (itemData.isDefault()))
+ returnedName = "DEFAULT";
+
+ if (returnedName == null)
+ return "UNKNOWN";
+
+ return returnedName;
+
+ }
+
+ @Deprecated
+ public boolean remove(ItemClump removed) {
+ return remove(removed, "");
+ }
+
+ public boolean remove(ItemClump removed, String shopLabel) {
+ // CHANGED: Now accepts an itemType (through use of the ItemClump
+ // class).
+ SQLHandler myQuery = new SQLHandler(this);
+
+ myQuery.inputList.add(removed.itemId);
+ myQuery.inputList.add(removed.subType);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("DELETE FROM " + tableName
+ + " WHERE (item = ? AND subtype = ? AND shoplabel = ?) "
+ + ((this.databaseType.equals(Type.SQLITE)) ? "" : " LIMIT 1"));
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+ return myQuery.isOK;
+ }
+
+ public boolean dumpToCSV(String fileName, String shopLabel) {
+ // Dumps this database into a .csv file.
+ BufferedWriter writer;
+ try {
+ writer = new BufferedWriter(new FileWriter(fileName, false));
+ } catch (IOException ex) {
+ logSevereException("Error opening .csv for writing: " + fileName,
+ ex);
+ return false;
+ }
+
+ String line;
+
+ line = MarketItem.csvHeaderLine();
+ try {
+ writer.write(line);
+ } catch (IOException ex) {
+ logSevereException("I/O error writing .csv header:" + fileName, ex);
+ return false;
+ }
+
+ ArrayList itemsToWrite = list(0, null, shopLabel);
+
+ for (MarketItem thisItem : itemsToWrite) {
+ // Write a line.
+ line = thisItem.csvLine();
+ try {
+ writer.newLine();
+ writer.write(line);
+ } catch (IOException ex) {
+ logSevereException("Error writing output line to .csv: "
+ + fileName, ex);
+ return false;
+ }
+ }
+ try {
+ writer.flush();
+ } catch (IOException ex) {
+ logSevereException("Error flushing output after writing .csv:"
+ + fileName, ex);
+ }
+ try {
+ writer.close();
+ } catch (IOException ex) {
+ logSevereException("Error closing file after writing .csv:"
+ + fileName, ex);
+ }
+ return true;
+ }
+
+ public boolean inhaleFromCSV(String fileName, String shopLabel) {
+ // Sucks a .csv file into this database.
+ BufferedReader reader;
+ MarketItem importItem;
+ try {
+ reader = new BufferedReader(new FileReader(fileName));
+ } catch (FileNotFoundException ex) {
+ logSevereException("File not found while importing .csv: "
+ + fileName, ex);
+ return false;
+ }
+
+ String line;
+ try {
+ line = reader.readLine();
+ // if (!line.equalsIgnoreCase(MarketItem.csvHeaderLine()))
+ // {
+ // plugin.log.severe("[" + plugin.name +
+ // "]: Bad header line reading .csv: " + fileName);
+ // return false;
+ // }
+ line = reader.readLine();
+ } catch (IOException ex) {
+ logSevereException("I/O error importing .csv:" + fileName, ex);
+ return false;
+ }
+ while (line != null) {
+ if (line.trim().length() == 0) {
+ continue;
+ }
+ // Parse a line.
+ // plugin.log.info(line);
+ line = line.replace("'", "").replace("\"", "");
+ importItem = new MarketItem(line, null, shopLabel, true);
+ if (hasRecord(importItem, shopLabel)) {
+ importItem = new MarketItem(line, data(importItem, shopLabel),
+ shopLabel, true);
+ update(importItem);
+ } else {
+ add(importItem);
+ }
+ try {
+ line = reader.readLine();
+ } catch (IOException ex) {
+ logSevereException("I/O error reading .csv:" + fileName, ex);
+ break;
+ }
+ }
+ try {
+ reader.close();
+ } catch (IOException ex) {
+ logSevereException("Error closing file after importing .csv: "
+ + fileName, ex);
+ }
+ return true;
+ }
+
+ private void updateAll(SQLHandler myQuery, String fieldName,
+ Object newValue, String shopLabel) {
+ // Update fieldName to newValue in all records matching shopLabel.
+ myQuery.inputList.add(newValue);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE " + tableName + " SET " + fieldName
+ + " = ? WHERE shoplabel = ?");
+ }
+
+ private void updateAllExpr(SQLHandler myQuery, String fieldName,
+ String updExpr, String shopLabel) {
+ // Update fieldName to expression updExpr in all records matching
+ // shopLabel.
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE " + tableName + " SET " + fieldName
+ + " = " + updExpr + " WHERE shoplabel = ?");
+ }
+
+ private void updateAllExprWhere(SQLHandler myQuery, String fieldName,
+ String updExpr, String whereClause, String shopLabel) {
+ // Update fieldName to expression updExpr in all records matching
+ // whereClause and shopLabel.
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE " + tableName + " SET " + fieldName
+ + " = " + updExpr + " WHERE (shoplabel = ? AND " + whereClause
+ + ")");
+ }
+
+ public boolean updateAllFromTags(String initString, String shopLabel) {
+ // Update table data from a list of tags.
+ // Applies changes to every element of the table matching shopLabel.
+ // Mirrors MarketItem.parseTags.
+ // Element [0] is used only to extract count, if provided.
+ String initData[] = initString.split(" ");
+ String curTag;
+ Integer curVal;
+ String stringVal;
+ String[] curParams;
+ boolean setUntaggedBase = false;
+ SQLHandler myQuery = new SQLHandler(this);
+
+ if (initData[0].contains(":")) {
+ // Count detected. Pull it out, if it's valid.
+ ItemClump countCheck = new ItemClump(initData[0], null, "");
+ // Update all counts, rescaling stock levels and base prices.
+ // basePrice = Math.round((float)prev.basePrice * new.count /
+ // prev.count);
+ // stockItems = stock * count;
+ // new.stockItems = prev.stockItems;
+ // new.stock * new.count = prev.stock * old.count;
+ // new.stock = prev.stock * prev.count / new.count;
+ updateAllExpr(myQuery, "baseprice", "ROUND(baseprice * "
+ + countCheck.count + " / count, 0)", shopLabel);
+ updateAllExpr(myQuery, "stock", "ROUND((stock * count / "
+ + countCheck.count + ")-0.5,0)", shopLabel);
+ updateAll(myQuery, "count", countCheck.count, shopLabel);
+ }
+
+ if (initData.length > 1) {
+ for (int i = 1; i <= initData.length - 1; i++) {
+ stringVal = null;
+ // Get current tag and value
+
+ if (initData[i].contains(":")) {
+ curParams = initData[i].split(":");
+ curTag = curParams[0];
+ try {
+ curVal = Integer.parseInt(curParams[1]);
+ } catch (NumberFormatException ex) {
+ if (curParams[1].equalsIgnoreCase("+INF"))
+ curVal = Integer.MAX_VALUE;
+ else if (curParams[1].equalsIgnoreCase("-INF"))
+ curVal = Integer.MIN_VALUE;
+ else {
+ curVal = null;
+ stringVal = curParams[1];
+ }
+ }
+ } else {
+ try { // Try to parse it as a plain integer.
+ curTag = null;
+ curVal = Integer.parseInt(initData[i]);
+ } catch (NumberFormatException ex) { // Didn't work? Just
+ // use it as a string.
+ curVal = null;
+ curTag = initData[i];
+ }
+ }
+
+ // If first param is an untagged value, make it the basePrice.
+ if (i == 1) {
+ if (curTag == null) {
+ if (curVal != -1) {
+ // this.basePrice = curVal;
+ updateAll(myQuery, "baseprice", curVal, shopLabel);
+ // maskData.basePrice = 1;
+ } else {
+ // Base price set to -1. Disable buying.
+ // this.basePrice = 0;
+ updateAll(myQuery, "baseprice", 0, shopLabel);
+ // maskData.basePrice = 1;
+ // this.canBuy = false;
+ updateAll(myQuery, "canbuy", 0, shopLabel);
+ }
+ setUntaggedBase = true;
+ continue;
+ }
+ }
+
+ // If second param is an untagged value, make the sellPrice
+ // equal to it after sales tax is applied.
+ if (i == 2) {
+ if ((setUntaggedBase) && (curTag == null)) {
+ if (curVal != -1) {
+ // if salePrice = basePrice * (1 - (salesTax / 100))
+ // then (1 - (salePrice / basePrice)) * 100 =
+ // salesTax
+ /*
+ * if (this.basePrice != 0) { this.salesTax =
+ * Math.round((1 - ((float)curVal / basePrice)) *
+ * 100); //maskData.salesTax = 1; } else {
+ * this.basePrice = curVal; this.salesTax = 0;
+ * //maskData.salesTax = 1; }
+ */
+ updateAllExprWhere(myQuery, "salestax",
+ "ROUND((1 - (" + curVal
+ + " / baseprice)) * 100)",
+ "baseprice > 0", shopLabel);
+ updateAllExprWhere(myQuery, "salestax", "0",
+ "baseprice = 0", shopLabel);
+ updateAllExprWhere(myQuery, "baseprice",
+ curVal.toString(), "baseprice = 0",
+ shopLabel);
+ } else {
+ // Sale price set to -1. Disable selling.
+ // this.canSell = false;
+ updateAll(myQuery, "cansell", 0, shopLabel);
+ }
+ continue;
+ }
+ }
+
+ // Handle remaining items in split.
+
+ if (curTag != null) {
+ if (curVal != null) {
+ if (curTag.equalsIgnoreCase("bp")
+ || curTag.equalsIgnoreCase("baseprice")) {
+ // this.basePrice = curVal;
+ updateAll(myQuery, "baseprice", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("s")
+ || curTag.equalsIgnoreCase("stock")) {
+ // this.stock = curVal;
+ updateAll(myQuery, "stock", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("v")
+ || curTag.equalsIgnoreCase("volatility")
+ || curTag.equalsIgnoreCase("vol")) {
+ // this.setVolatility(curVal);
+ updateAll(myQuery, "volatility", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("iv")
+ || curTag.equalsIgnoreCase("invvolatility")
+ || curTag.equalsIgnoreCase("ivol")) {
+ // this.setInverseVolatility(curVal);
+ updateAll(myQuery, "volatility",
+ MarketItem.iVolToVol(curVal), shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("st")
+ || curTag.equalsIgnoreCase("salestax")) {
+ // this.salesTax = rangeCrop(curVal, 0, 100);
+ updateAll(myQuery, "salestax",
+ MarketItem.rangeCrop(curVal, 0, 100),
+ shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sl")
+ || curTag.equalsIgnoreCase("stocklowest")) {
+ // this.stockLowest = curVal;
+ updateAll(myQuery, "stocklowest", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sh")
+ || curTag.equalsIgnoreCase("stockhighest")) {
+ // this.stockHighest = curVal;
+ updateAll(myQuery, "stockhighest", curVal,
+ shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sf")
+ || curTag.equalsIgnoreCase("stockfloor")) {
+ // this.stockFloor = curVal;
+ updateAll(myQuery, "stockfloor", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sc")
+ || curTag.equalsIgnoreCase("stockceiling")) {
+ // this.stockCeil = curVal;
+ updateAll(myQuery, "stockceil", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("pf")
+ || curTag.equalsIgnoreCase("pricefloor")) {
+ // this.priceFloor = curVal;
+ updateAll(myQuery, "pricefloor", curVal, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("pc")
+ || curTag.equalsIgnoreCase("priceceiling")) {
+ // this.priceCeil = curVal;
+ updateAll(myQuery, "priceceil", curVal, shopLabel);
+ continue;
+ }
+ }
+ }
+ if (curTag.equalsIgnoreCase("flat")) {
+ // this.stock = 0;
+ updateAll(myQuery, "stock", 0, shopLabel);
+ // this.stockLowest = Integer.MIN_VALUE;
+ updateAll(myQuery, "stocklowest", Integer.MIN_VALUE,
+ shopLabel);
+ // this.stockHighest = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockhighest", Integer.MAX_VALUE,
+ shopLabel);
+ // this.stockFloor = Integer.MIN_VALUE;
+ updateAll(myQuery, "stockfloor", Integer.MIN_VALUE,
+ shopLabel);
+ // this.stockCeil = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockceil", Integer.MAX_VALUE,
+ shopLabel);
+ // this.priceFloor = 0;
+ updateAll(myQuery, "pricefloor", 0, shopLabel);
+ // this.priceCeil = Integer.MAX_VALUE;
+ updateAll(myQuery, "priceceil", Integer.MAX_VALUE,
+ shopLabel);
+ // this.volatility = 0;
+ updateAll(myQuery, "volatility", 0, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("fixed")) {
+ // this.stock = 0;
+ updateAll(myQuery, "stock", 0, shopLabel);
+ // this.stockLowest = Integer.MIN_VALUE;
+ updateAll(myQuery, "stocklowest", Integer.MIN_VALUE,
+ shopLabel);
+ // this.stockHighest = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockhighest", Integer.MAX_VALUE,
+ shopLabel);
+ // this.stockFloor = 0;
+ updateAll(myQuery, "stockfloor", 0, shopLabel);
+ // this.stockCeil = 0;
+ updateAll(myQuery, "stockceil", 0, shopLabel);
+ // this.priceFloor = 0;
+ updateAll(myQuery, "pricefloor", 0, shopLabel);
+ // this.priceCeil = Integer.MAX_VALUE;
+ updateAll(myQuery, "priceceil", Integer.MAX_VALUE,
+ shopLabel);
+ // this.volatility = 0;
+ updateAll(myQuery, "volatility", 0, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("float")) {
+ // this.stockFloor = Integer.MIN_VALUE;
+ updateAll(myQuery, "stockfloor", Integer.MIN_VALUE,
+ shopLabel);
+ // this.stockCeil = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockceil", Integer.MAX_VALUE,
+ shopLabel);
+ // this.stockLowest = Integer.MIN_VALUE;
+ updateAll(myQuery, "stocklowest", Integer.MIN_VALUE,
+ shopLabel);
+ // this.stockHighest = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockhighest", Integer.MAX_VALUE,
+ shopLabel);
+ // this.priceFloor = 0;
+ updateAll(myQuery, "pricefloor", 0, shopLabel);
+ // this.priceCeil = Integer.MAX_VALUE;
+ updateAll(myQuery, "priceceil", Integer.MAX_VALUE,
+ shopLabel);
+ // if (this.volatility == 0)
+ // this.volatility = 100;
+ updateAllExprWhere(myQuery, "volatility", "100",
+ "volatility = 0", shopLabel);
+ }
+ if (curTag.equalsIgnoreCase("finite")) {
+ // this.stockFloor = Integer.MIN_VALUE;
+ updateAll(myQuery, "stockfloor", Integer.MIN_VALUE,
+ shopLabel);
+ // this.stockCeil = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockceil", Integer.MAX_VALUE,
+ shopLabel);
+ // this.stockLowest = 0;
+ updateAll(myQuery, "stocklowest", 0, shopLabel);
+ // this.stockHighest = Integer.MAX_VALUE;
+ updateAll(myQuery, "stockhighest", Integer.MAX_VALUE,
+ shopLabel);
+ }
+ if ((curTag.equalsIgnoreCase("buyok"))
+ || (curTag.equalsIgnoreCase("!nobuy"))) {
+ // this.canBuy = true;
+ updateAll(myQuery, "canbuy", 1, shopLabel);
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("sellok"))
+ || (curTag.equalsIgnoreCase("!nosell"))) {
+ // this.canSell = true;
+ updateAll(myQuery, "cansell", 1, shopLabel);
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("!buyok"))
+ || (curTag.equalsIgnoreCase("nobuy"))
+ || (curTag.equalsIgnoreCase("!cb"))) {
+ // this.canBuy = false;
+ updateAll(myQuery, "canbuy", 0, shopLabel);
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("!sellok"))
+ || (curTag.equalsIgnoreCase("nosell"))
+ || (curTag.equalsIgnoreCase("!cs"))) {
+ // this.canSell = false;
+ updateAll(myQuery, "cansell", 0, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("cb")
+ || curTag.equalsIgnoreCase("canbuy")) {
+ if ((stringVal != null) && (!(stringVal.isEmpty()))) {
+ // this.canBuy =
+ // ((stringVal.toLowerCase().startsWith("y")) ||
+ // (stringVal.toLowerCase().startsWith("t")));
+ if ((stringVal.toLowerCase().startsWith("y"))
+ || (stringVal.toLowerCase().startsWith("t")))
+ updateAll(myQuery, "canbuy", 1, shopLabel);
+ else
+ updateAll(myQuery, "canbuy", 0, shopLabel);
+ } else
+ // this.canBuy = true;
+ updateAll(myQuery, "canbuy", 1, shopLabel);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("cs")
+ || curTag.equalsIgnoreCase("cansell")) {
+ if ((stringVal != null) && (!(stringVal.isEmpty()))) {
+ // this.canSell =
+ // ((stringVal.toLowerCase().startsWith("y")) ||
+ // (stringVal.toLowerCase().startsWith("t")));
+ if ((stringVal.toLowerCase().startsWith("y"))
+ || (stringVal.toLowerCase().startsWith("t")))
+ updateAll(myQuery, "cansell", 1, shopLabel);
+ else
+ updateAll(myQuery, "cansell", 0, shopLabel);
+ } else
+ // this.canSell = true;
+ updateAll(myQuery, "cansell", 1, shopLabel);
+ continue;
+ }
+ /*
+ * // Renaming everything to the same value doesn't make sense.
+ * if ((curTag.equalsIgnoreCase("name")) ||
+ * (curTag.equalsIgnoreCase("n"))) { //setName(stringVal);
+ * updateAll("name", stringVal, shopLabel); continue; }
+ */
+ if (curTag.equalsIgnoreCase("renorm")) {
+ // double oldBuyPrice = getStockPrice(this.stock);
+ // getStockPrice(stockLevel) = rangeCrop(this.basePrice *
+ // Math.pow(getVolFactor(), -rangeCrop(stockLevel,
+ // stockFloor, stockCeil)), priceFloor, priceCeil)
+ // getVolFactor = (1 + volatility/intScale)
+ // rangeCrop(double value, double minVal, double maxVal) =
+ // (Math.min(Math.max(value, minVal), maxVal))
+ // oldBuyPrice = LEAST(GREATEST(baseprice * POW((1 +
+ // volatility/INTSCALE), -LEAST(GREATEST(stock, stockfloor),
+ // stockceil)), pricefloor), priceceil)
+ int newStock;
+ if (curVal == null)
+ newStock = 0;
+ else
+ newStock = curVal;
+ // this.basePrice = ROUND(oldBuyPrice / POW(getVolFactor(),
+ // -rangeCrop(this.stock, stockFloor, stockCeil)));
+ // this.basePrice = ROUND(oldBuyPrice / POW((1 +
+ // volatility/INTSCALE), -LEAST(GREATEST(stock, stockFloor),
+ // stockCeil)));
+ // this.basePrice = ROUND(LEAST(GREATEST(baseprice * POW((1
+ // + volatility/INTSCALE), -LEAST(GREATEST(stock,
+ // stockfloor), stockceil)), pricefloor), priceceil) /
+ // POW((1 + volatility/INTSCALE), -LEAST(GREATEST(stock,
+ // stockFloor), stockCeil)));
+ // blerg! all this to do the update within a single MySQL
+ // statement!
+ // And it's not even translatable to SQLite!
+ // Maybe use this later. Simple & crude method for right
+ // now.
+
+ // This is ugly and nasty, but necessary for SQLite
+ // compatibility.
+ // SQLite doesn't understand ^, POW(), ln(), or EXP()
+ // without a tricky-to-install add-on.
+ ArrayList itemsToEdit = list(0, null, shopLabel);
+ if (!itemsToEdit.isEmpty()) {
+ myQuery.prepareBatchStatement("UPDATE "
+ + tableName
+ + " SET basePrice = ? WHERE (shoplabel = ? AND item = ? AND subtype = ?");
+ for (MarketItem thisItem : itemsToEdit) {
+ myQuery.inputList.add(Integer.toString(thisItem
+ .getRenormedPrice(newStock)));
+ myQuery.inputList.add(shopLabel);
+ myQuery.inputList.add(thisItem.itemId);
+ myQuery.inputList.add(thisItem.subType);
+ myQuery.addToBatch();
+ }
+ updateAll(myQuery, "stock", newStock, shopLabel);
+ }
+ }
+ }
+ // TODO: Log and report invalid tags somehow.
+ }
+ // Finished parsing tags. Do the update.
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+
+ sanityCheckAll(shopLabel);
+
+ return myQuery.isOK;
+
+ }
+
+ private boolean sanityCheckAll(String shopLabel) {
+ // Check and fix possible chaos-inducing data.
+ // Mirrors marketItem.sanityCheck.
+
+ SQLHandler myQuery = new SQLHandler(this);
+
+ // Check range of salesTax
+ // this.salesTax = rangeCrop(this.salesTax, 0, 100);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET salestax = LEAST(100, GREATEST(salestax, 0)) WHERE shoplabel = ?");
+
+ // if (this.stockHighest < this.stock)
+ // this.stockHighest = this.stock;
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stockhighest = stock WHERE (shoplabel = ? AND stockhighest < stock)");
+
+ // if (this.stockLowest > this.stock)
+ // this.stockLowest = this.stock;
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stocklowest = stock WHERE (shoplabel = ? AND stocklowest > stock)");
+
+ // if (this.stockCeil < this.stock)
+ // this.stockCeil = this.stock;
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stockceil = stock WHERE (shoplabel = ? AND stockceil < stock)");
+
+ // if (this.stockFloor > this.stock)
+ // this.stockFloor = this.stock;
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET stockfloor = stock WHERE (shoplabel = ? AND stockfloor > stock)");
+
+ // if (this.priceCeil < this.priceFloor)
+ // this.priceCeil = this.priceFloor;
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE "
+ + tableName
+ + " SET priceceil = pricefloor WHERE (shoplabel = ? AND priceceil < pricefloor)");
+
+ // Check range of basePrice
+ // this.basePrice = Math.max(0, this.basePrice);
+ myQuery.inputList.add(shopLabel);
+ myQuery.prepareStatement("UPDATE " + tableName
+ + " SET baseprice = 0 WHERE (shoplabel = ? AND baseprice < 0)");
+
+ myQuery.executeUpdates();
+
+ myQuery.close();
+
+ return myQuery.isOK;
+ }
+
+ /*
+ * private boolean updateAll(String[] fieldName, Object[] newValue, String
+ * shopLabel) { // Update several fieldNames to newValues in all records
+ * matching shopLabel. return false; }
+ */
}
diff --git a/src/com/gmail/haloinverse/DynamicMarket/DynamicMarket.java b/src/com/gmail/haloinverse/DynamicMarket/DynamicMarket.java
index 881b06d..3dffc5b 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/DynamicMarket.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/DynamicMarket.java
@@ -1,289 +1,288 @@
package com.gmail.haloinverse.DynamicMarket;
-
import com.nijikokun.bukkit.Permissions.Permissions;
-import com.nijikokun.bukkit.iConomy.iConomy;
-//import com.haloinverse.AnyConomy.AnyConomy;
+import com.nijiko.coelho.iConomy.iConomy;
+import com.nijiko.permissions.PermissionHandler;
+
import java.io.File;
+import java.util.LinkedList;
+import java.util.ListIterator;
import java.util.Timer;
import java.util.logging.Logger;
-//import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Event;
-import org.bukkit.event.server.PluginEvent;
-import org.bukkit.event.server.ServerListener;
+import org.bukkit.event.Event.Priority;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
-//import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
-
-public class DynamicMarket extends JavaPlugin
-{
- public final Logger log = Logger.getLogger("Minecraft");
-
- public String name; // = "SimpleMarket";
- public String codename = "Caribou";
- public String version; // = "0.4a";
-
- public iListen playerListener = new iListen(this);
- //public DMServerListener serverListener = new DMServerListener(this);
- public static Permissions Permissions;
- public static iProperty Settings;
- public static String directory; // = "DynamicMarket" + File.separator;
- public String shop_tag = "{BKT}[{}Shop{BKT}]{} ";
- protected String currency;// = "Coin";
- protected int max_per_purchase = 64;
- protected int max_per_sale = 64;
- public String defaultShopAccount = "";
- public boolean defaultShopAccountFree = true;
-
- protected String database_type = "sqlite";
- protected static String sqlite = "jdbc:sqlite:" + directory + "shop.db";
- protected static String mysql = "jdbc:mysql://localhost:3306/minecraft";
- protected static String mysql_user = "root";
- protected static String mysql_pass = "pass";
- protected static String mysql_dbEngine = "MyISAM";
- protected static Timer timer = null;
- protected static String csvFileName;
- protected static String csvFilePath;
- protected iConomy iC = null;
- //protected AnyConomy anyConomy = null;
- protected boolean econLoaded = false;
- protected EconType econType = EconType.NONE;
- protected Items items;
- protected String itemsPath = "";
- protected DatabaseMarket db = null;
- protected boolean wrapperMode = false;
- protected boolean wrapperPermissions = false;
- protected boolean simplePermissions = false;
- protected PermissionInterface permissionWrapper = null;
- protected TransactionLogger transLog = null;
- protected String transLogFile = "transactions.log";
- protected boolean transLogAutoFlush = true;
- private MyServerListener myServerListener = new MyServerListener(this);
- //public static YamlPropFile yamlPropTest;
-
- private class MyServerListener extends ServerListener {
-
- private DynamicMarket plugin;
- public MyServerListener(DynamicMarket thisPlugin)
- {
- this.plugin = thisPlugin;
- }
-
- @Override
- public void onPluginEnabled(PluginEvent event)
- {
- // This is called for plugins enabled AFTER this one.
- String thisPluginName = event.getPlugin().getDescription().getName();
- if(thisPluginName.equals("iConomy"))
- {
- plugin.connectEconomy(event.getPlugin());
- }
- }
- }
-
- public void onDisable() {
- log.info(Messaging.bracketize(name) + " version " + Messaging.bracketize(version) + " (" + codename + ") disabled");
- }
-
- @Override
- public void onEnable() {
- PluginDescriptionFile desc = getDescription();
- getDataFolder().mkdir();
+import org.bukkit.Server;
- name = desc.getName();
- version = desc.getVersion();
-
- directory = getDataFolder() + File.separator;
- sqlite = "jdbc:sqlite:" + directory + "shop.db";
-
- setup();
- //setupItems(); //CHANGED: Initialisation moved to Items constructor.
- setupEconomy();
- setupPermissions();
- registerEvents();
- log.info(Messaging.bracketize(name) + " version " + Messaging.bracketize(version) + " (" + codename + ") enabled");
- }
-
- private void registerEvents()
- {
- PluginManager thisPluginManager = getServer().getPluginManager();
- thisPluginManager.registerEvent(Event.Type.PLAYER_COMMAND, this.playerListener, Event.Priority.Normal, this);
- thisPluginManager.registerEvent(Event.Type.PLUGIN_ENABLE, this.myServerListener, Event.Priority.Monitor, this);
- }
+public class DynamicMarket extends JavaPlugin {
+ public static final Logger log = Logger.getLogger("Minecraft");
- @Override
- public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args)
- {
- if (!wrapperMode)
- {
- boolean thisReturn;
- thisReturn = this.playerListener.parseCommand(sender, cmd.getName(), args, "", defaultShopAccount, defaultShopAccountFree);
- return thisReturn;
- }
- else
- return true;
- }
-
- public boolean wrapperCommand(CommandSender sender, String cmd, String[] args, String shopLabel, String accountName, boolean freeAccount)
- {
- return this.playerListener.parseCommand(sender, cmd, args, (shopLabel == null ? "" : shopLabel), accountName, freeAccount);
- }
+ public static String name; // = "SimpleMarket";
+ public static String codename = "Shaniqua";
+ public static String version; // = "0.4a";
- public boolean wrapperCommand(CommandSender sender, String cmd, String[] args, String shopLabel)
- {
- return wrapperCommand(sender, cmd, args, (shopLabel == null ? "" : shopLabel), defaultShopAccount, defaultShopAccountFree);
- }
-
- public boolean wrapperCommand(CommandSender sender, String cmd, String[] args)
- {
- return wrapperCommand(sender, cmd, args, "");
- }
+ public iListen playerListener = new iListen(this);
-
- public void setup()
- {
- Settings = new iProperty(getDataFolder() + File.separator + name + ".settings");
-
- //ItemsFile = new iProperty("items.db");
- itemsPath = Settings.getString("items-db-path", getDataFolder() + File.separator);
- items = new Items(itemsPath + "items.db", this);
-
- shop_tag = Settings.getString("shop-tag", shop_tag);
- max_per_purchase = Settings.getInt("max-items-per-purchase", 64);
- max_per_sale = Settings.getInt("max-items-per-sale", 64);
-
- this.database_type = Settings.getString("database-type", "sqlite");
-
- mysql = Settings.getString("mysql-db", mysql);
- mysql_user = Settings.getString("mysql-user", mysql_user);
- mysql_pass = Settings.getString("mysql-pass", mysql_pass);
- mysql_dbEngine = Settings.getString("mysql-dbengine", mysql_dbEngine);
-
- if (this.database_type.equalsIgnoreCase("mysql"))
- db = new DatabaseMarket(DatabaseMarket.Type.MYSQL, "Market", items, mysql_dbEngine, this);
- else
- db = new DatabaseMarket(DatabaseMarket.Type.SQLITE, "Market", items, "", this);
-
- csvFileName = Settings.getString("csv-file", "shopDB.csv");
- csvFilePath = Settings.getString("csv-file-path", getDataFolder() + File.separator);
- wrapperMode = Settings.getBoolean("wrapper-mode", false);
- simplePermissions = Settings.getBoolean("simple-permissions", false);
- wrapperPermissions = Settings.getBoolean("wrapper-permissions", false);
-
- Messaging.colNormal = "&" + Settings.getString("text-colour-normal", "e");
- Messaging.colCmd = "&" + Settings.getString("text-colour-command", "f");
- Messaging.colBracket = "&" + Settings.getString("text-colour-bracket", "d");
- Messaging.colParam = "&" + Settings.getString("text-colour-param", "b");
- Messaging.colError = "&" + Settings.getString("text-colour-error", "c");
-
- defaultShopAccount = Settings.getString("default-shop-account", "");
- defaultShopAccountFree = Settings.getBoolean("default-shop-account-free", defaultShopAccountFree);
-
- transLogFile = Settings.getString("transaction-log-file", transLogFile);
- transLogAutoFlush = Settings.getBoolean("transaction-log-autoflush", transLogAutoFlush);
- if ((transLogFile != null) && (!transLogFile.isEmpty()))
- transLog = new TransactionLogger(this, getDataFolder() + File.separator + transLogFile, transLogAutoFlush);
- else
- transLog = new TransactionLogger(this, null, false);
-
- String econTypeString = Settings.getString("economy-plugin", "iconomy3");
- if (econTypeString.equalsIgnoreCase("iconomy3"))
- econType = EconType.ICONOMY3;
- else if (econTypeString.equalsIgnoreCase("anyconomy"))
- econType = EconType.ANYCONOMY;
- else
- {
- log.severe(Messaging.bracketize(name) + " Invalid economy setting for 'economy-plugin='.");
- econType = EconType.NONE;
- }
-
- //yamlPropTest = new YamlPropFile(getDataFolder() + File.separator + "SimpleMarket.yml");
- //yamlPropTest.load();
- }
-
- public void setupPermissions()
- {
- if (simplePermissions)
- {
- Permissions = null;
- log.info(Messaging.bracketize(name) + " Simple permission system active.");
- }
- else if (wrapperPermissions)
- log.info(Messaging.bracketize(name) + " Permissions will be delegated to wrapper plugin.");
- else
- {
- Plugin test = getServer().getPluginManager().getPlugin("Permissions");
+ public static Server server = null;
+ public static iConomy iC = null;
+ public static PermissionHandler Permissions = null;
+
+ public static iProperty Settings;
+ public static File directory = null;
+
+ protected static String currency;// = "Coin";
+ protected static boolean econLoaded = false;
+
+ public static boolean debug = false;
+
+// protected static boolean wrapperMode = false;
+ protected static boolean wrapperPermissions = false;
+ protected static LinkedList wrappers = new LinkedList();
+
+ protected static boolean simplePermissions = false;
+
+ public String shop_tag = "{BKT}[{}Shop{BKT}]{} ";
+ protected int max_per_purchase = 64;
+ protected int max_per_sale = 64;
+ public String defaultShopAccount = "";
+ public boolean defaultShopAccountFree = true;
+ protected static String database_type = "sqlite";
+ protected static String sqlite = "jdbc:sqlite:" + "plugins/DynamicMarket/shop.db";
+ protected static String mysql = "jdbc:mysql://localhost:3306/minecraft";
+ protected static String mysql_user = "root";
+ protected static String mysql_pass = "pass";
+ protected static String mysql_dbEngine = "MyISAM";
+ protected static Timer timer = null;
+ protected static String csvFileName;
+ protected static String csvFilePath;
+
+ protected EconType econType = EconType.NONE;
+ protected Items items;
+ protected String itemsPath = "";
+ protected DatabaseMarket db = null;
+
+ protected PermissionInterface permissionWrapper = null;
+ protected TransactionLogger transLog = null;
+ protected String transLogFile = "transactions.log";
+ protected boolean transLogAutoFlush = true;
+ private static iPluginListener pluginListener = null;
+
+
+
+
+ public void onDisable() {
+// db.uninitialize();
+ log.info(Messaging.bracketize(name) + " version " + Messaging.bracketize(version) + " (" + codename + ") disabled");
+ }
+
+ public File getDataFolder() {
+ if ( directory == null ) {
+ String pluginDirString = "plugins" + File.separator + "DynamicMarket";
+ if ( !super.getDataFolder().toString().equals(pluginDirString) ) {
+ log.warning("Jar is not named DynamicMarket.jar! Beware of multiple DynamicMarket instances being loaded!");
+ directory = new File(pluginDirString);
+ } else {
+ directory = super.getDataFolder();
+ }
+ }
+
+ return directory;
+ }
+
+ @Override
+ public void onEnable() {
+ PluginDescriptionFile desc = getDescription();
+ getDataFolder().mkdir();
+
+ server = getServer();
+
+ name = desc.getName();
+ version = desc.getVersion();
+
+ sqlite = "jdbc:sqlite:" + directory + File.separator + "shop.db";
+
+ PluginManager pm = getServer().getPluginManager();
+ if(pm.getPlugin("iConomy").isEnabled() && DynamicMarket.iC == null) {
+ Plugin iConomy = pm.getPlugin("iConomy");
+ //iConomyData();
+ setiConomy((iConomy)iConomy);
+ iC = (iConomy)iConomy;
+ }
+ if(pm.getPlugin("Permissions").isEnabled() && DynamicMarket.Permissions == null) {
+ setupPermissions();
+ System.out.println("[DynamicMarket] Successfully linked with Permissions.");
+ }
+ pluginListener = new iPluginListener();
+ pm.registerEvent(Event.Type.PLUGIN_ENABLE, pluginListener, Priority.Monitor, this);
- if (Permissions == null)
- if (test != null) {
- Permissions = (Permissions)test;
- log.info(Messaging.bracketize(name) + " Standard Permission plugin enabled.");
- } else {
- log.info(Messaging.bracketize(name) + " Permission system not enabled. Disabling plugin.");
- getServer().getPluginManager().disablePlugin(this);
- }
+
+ checkLibs();
+ setup();
+
+ log.info(Messaging.bracketize(name) + " version " + Messaging.bracketize(version) + " (" + codename + ") enabled");
+ }
+
+ public static Server getTheServer() {
+ return server;
+ }
+
+ public static iConomy getiConomy() {
+ return iC;
+ }
+
+ public static boolean setiConomy(iConomy plugin) {
+ if (iC == null) {
+ iC = plugin;
+ currency = iConomy.getBank().getCurrency();
+ econLoaded = true;
+ log.info(Messaging.bracketize(name) + " iConomy connected.");
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+
+ public static void setupPermissions() {
+ Plugin test = getTheServer().getPluginManager().getPlugin("Permissions");
+ if (Permissions == null)
+ if ( test != null )
+ DynamicMarket.Permissions = ((Permissions)test).getHandler();
+
+ }
+
+ private void checkLibs() {
+ boolean isok = false;
+ File a = new File(getDataFolder()+ "/sqlitejdbc-v056.jar");
+ if(!a.exists()) {
+ isok = FileDownloader.fileDownload("http://www.brisner.no/libs/sqlitejdbc-v056.jar", getDataFolder().toString());
+ if(isok)
+ System.out.println("[DynamicMarket] Downloaded SQLite Successfully.");
}
- }
-
- public void setupEconomy()
- {
- // Called with iConomy 2.1(Cookies wrapper).
- // This catches plugins enabled BEFORE this plugin.
- Plugin test = getServer().getPluginManager().getPlugin("iConomy");
- if (test != null) {
- connectEconomy(test);
- }
-
- test = getServer().getPluginManager().getPlugin("AnyConomy");
- if (test != null) {
- connectEconomy(test);
- }
-
- }
-
- public void connectEconomy(Plugin thisPlugin)
- {
- if(econType == EconType.ICONOMY3)
- {
- if(thisPlugin instanceof iConomy)
- connectToiConomy((iConomy)thisPlugin);
+ File b = new File(getDataFolder() + "/mysql-connector-java-5.1.15-bin.jar");
+ if(!b.exists()) {
+ isok = FileDownloader.fileDownload("http://www.brisner.no/libs/mysql-connector-java-5.1.15-bin.jar", getDataFolder().toString());
+ if(isok)
+ System.out.println("[DynamicMarket] Downloaded MySQL Successfully.");
}
-
- /*
- else if(econType == EconType.ANYCONOMY)
- {
- if(thisPlugin instanceof AnyConomy)
- connectToAnyConomy((AnyConomy)thisPlugin);
+ File c = new File(getDataFolder() + "/items.db");
+ if(!c.exists()) {
+ isok = FileDownloader.fileDownload("http://www.brisner.no/DynamicMarket/items.db", getDataFolder().toString());
+ if(isok)
+ System.out.println("[DynamicMarket] items.db downloaded successfully");
}
- */
-
- }
-
- /*
- public void connectToAnyConomy(AnyConomy thisPlugin)
- {
- anyConomy = thisPlugin;
- currency = "";
- econLoaded = true;
- log.info(Messaging.bracketize(name) + " AnyConomy connected.");
- }
- */
-
-
- public void connectToiConomy(iConomy thisPlugin)
- {
- iC = thisPlugin;
- currency = iConomy.currency;
- econLoaded = true;
- log.info(Messaging.bracketize(name) + " iConomy connected.");
- }
-
- public static enum EconType
- {
- NONE, ICONOMY2, ICONOMY3, ANYCONOMY;
}
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
+ ListIterator itr = DynamicMarket.wrappers.listIterator();
+ while(itr.hasNext()) {
+ JavaPlugin wrap = itr.next();
+ if ( wrap.onCommand(sender, cmd, commandLabel, args) ) return true;
+ }
+ return this.playerListener.parseCommand(sender, cmd.getName(), args, "", defaultShopAccount, defaultShopAccountFree);
+ }
+
+ public void hookWrapper(JavaPlugin wrap) {
+ DynamicMarket.wrappers.add(wrap);
+ log.info(Messaging.bracketize(name) + " wrapper mode enabled by " + wrap.getDescription().getName());
+ }
+
+ public boolean wrapperCommand(CommandSender sender, String cmd, String[] args, String shopLabel, String accountName, boolean freeAccount) {
+ return this.playerListener.parseCommand(sender, cmd, args, (shopLabel == null ? "" : shopLabel), accountName, freeAccount);
+ }
+
+ public boolean wrapperCommand(CommandSender sender, String cmd, String[] args, String shopLabel) {
+ return wrapperCommand(sender, cmd, args, (shopLabel == null ? "" : shopLabel), defaultShopAccount, defaultShopAccountFree);
+ }
+
+ public boolean wrapperCommand(CommandSender sender, String cmd, String[] args) {
+ return wrapperCommand(sender, cmd, args, "");
+ }
+
+ public void setup() {
+ Settings = new iProperty(getDataFolder() + File.separator + name + ".settings");
+
+ debug = Settings.getBoolean("debug", false);
+
+ // ItemsFile = new iProperty("items.db");
+ itemsPath = Settings.getString("items-db-path", getDataFolder() + File.separator);
+ items = new Items(itemsPath + "items.db", this);
+
+ shop_tag = Settings.getString("shop-tag", shop_tag);
+ max_per_purchase = Settings.getInt("max-items-per-purchase", 64);
+ max_per_sale = Settings.getInt("max-items-per-sale", 64);
+
+ DynamicMarket.database_type = Settings.getString("database-type", "sqlite");
+
+ mysql = Settings.getString("mysql-db", mysql);
+ mysql_user = Settings.getString("mysql-user", mysql_user);
+ mysql_pass = Settings.getString("mysql-pass", mysql_pass);
+ mysql_dbEngine = Settings.getString("mysql-dbengine", mysql_dbEngine);
+
+ if (DynamicMarket.database_type.equalsIgnoreCase("mysql")) {
+ try {
+ Class.forName("com.mysql.jdbc.Driver");
+ } catch(ClassNotFoundException ex) {
+ log.info("com.mysql.jdbc.Driver class not found!");
+ ex.printStackTrace();
+ }
+ db = new DatabaseMarket(DatabaseMarket.Type.MYSQL, "Market", items, mysql_dbEngine, this);
+ } else {
+ try {
+ Class.forName("org.sqlite.JDBC");
+ } catch(ClassNotFoundException ex) {
+ log.info("org.sqlite.JDBC class not found!");
+ ex.printStackTrace();
+ }
+ db = new DatabaseMarket(DatabaseMarket.Type.SQLITE, "Market", items, "", this);
+ }
+
+ csvFileName = Settings.getString("csv-file", "shopDB.csv");
+ csvFilePath = Settings.getString("csv-file-path", getDataFolder() + File.separator);
+// wrapperMode = Settings.getBoolean("wrapper-mode", false);
+ simplePermissions = Settings.getBoolean("simple-permissions", false);
+ wrapperPermissions = Settings.getBoolean("wrapper-permissions", false);
+
+ Messaging.colNormal = "&" + Settings.getString("text-colour-normal", "e");
+ Messaging.colCmd = "&" + Settings.getString("text-colour-command", "f");
+ Messaging.colBracket = "&" + Settings.getString("text-colour-bracket", "d");
+ Messaging.colParam = "&" + Settings.getString("text-colour-param", "b");
+ Messaging.colError = "&" + Settings.getString("text-colour-error", "c");
+
+ defaultShopAccount = Settings.getString("default-shop-account", "");
+ defaultShopAccountFree = Settings.getBoolean("default-shop-account-free", defaultShopAccountFree);
+
+ transLogFile = Settings.getString("transaction-log-file", transLogFile);
+ transLogAutoFlush = Settings.getBoolean("transaction-log-autoflush", transLogAutoFlush);
+ if ((transLogFile != null) && (!transLogFile.isEmpty())) {
+ transLog = new TransactionLogger(this, getDataFolder() + File.separator + transLogFile, transLogAutoFlush);
+ } else {
+ transLog = new TransactionLogger(this, null, false);
+ }
+
+ String econTypeString = Settings.getString("economy-plugin", "iconomy4");
+ if (econTypeString.equalsIgnoreCase("iconomy4")) {
+ econType = EconType.ICONOMY4;
+ } else {
+ log.severe(Messaging.bracketize(name) + " Invalid economy setting for 'economy-plugin='.");
+ econType = EconType.NONE;
+ }
+ }
+
+ public void InitializeEconomy() {
+ currency = iConomy.getBank().getCurrency();
+ econLoaded = true;
+ log.info(Messaging.bracketize(name) + " successfully hooked into iConomy.");
+ }
+
+ public static enum EconType {
+
+ NONE, ICONOMY4;
+ }
}
\ No newline at end of file
diff --git a/src/com/gmail/haloinverse/DynamicMarket/FileDownloader.java b/src/com/gmail/haloinverse/DynamicMarket/FileDownloader.java
new file mode 100644
index 0000000..0909971
--- /dev/null
+++ b/src/com/gmail/haloinverse/DynamicMarket/FileDownloader.java
@@ -0,0 +1,82 @@
+package com.gmail.haloinverse.DynamicMarket;
+
+import java.io.*;
+import java.net.*;
+
+public class FileDownloader {
+ final static int size=1024;
+
+ public static boolean FileDownload(String fileAddress, String localFileName, String destinationDir) {
+ OutputStream os = null;
+ URLConnection URLConn = null;
+
+ // URLConnection class represents a communication link between the
+ // application and a URL.
+
+ InputStream is = null;
+ try {
+ URL fileUrl;
+ byte[] buf;
+ int ByteRead,ByteWritten=0;
+ fileUrl= new URL(fileAddress);
+ os = new BufferedOutputStream(new FileOutputStream(destinationDir+"/"+localFileName));
+ //The URLConnection object is created by invoking the
+ // openConnection method on a URL.
+
+ URLConn = fileUrl.openConnection();
+ is = URLConn.getInputStream();
+ buf = new byte[size];
+ while ((ByteRead = is.read(buf)) != -1) {
+ os.write(buf, 0, ByteRead);
+ ByteWritten += ByteRead;
+ }
+
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ } finally {
+ try {
+ is.close();
+ os.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ public static boolean fileDownload(String fileAddress, String destinationDir) {
+ boolean isok;
+ // Find the index of last occurance of character ‘/’ and ‘.’.
+
+ int lastIndexOfSlash = fileAddress.lastIndexOf('/');
+ int lastIndexOfPeriod = fileAddress.lastIndexOf('.');
+
+ // Find the name of file to be downloaded from the address.
+
+ String fileName=fileAddress.substring
+ (lastIndexOfSlash + 1);
+
+ // Check whether path or file name is given correctly.
+ if (lastIndexOfPeriod >=1 && lastIndexOfSlash >= 0 && lastIndexOfSlash < fileAddress.length()) {
+ isok = FileDownload(fileAddress,fileName,destinationDir);
+ return isok;
+ } else {
+ return false;
+ }
+ }
+/* public static void main(String[] args)
+ {
+ // Check whether there are at least two arguments.
+ if(args.length==2)
+ {
+ for (int i = 1; i < args.length; i++) {
+ fileDownload(args[i],args[0]);
+ }
+ } else{
+ System.err.println("Provide Destination directory path and file names separated by space.");
+ }
+ }*/
+}
+
+
diff --git a/src/com/gmail/haloinverse/DynamicMarket/ItemClump.java b/src/com/gmail/haloinverse/DynamicMarket/ItemClump.java
index 2d98c75..6f5e91c 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/ItemClump.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/ItemClump.java
@@ -2,137 +2,120 @@
public class ItemClump {
- // Implemented because bukkit's ItemStack methods don't handle item subtypes consistently.
-
- // Added in to be a convenient package for grabbing entire items worth of shop data at once,
- // instead of one int at at time or in an easily-confused array.
- // Also factorizes in some redundant string-parsing code, making it easier to change standard input formats
- // if necessary (and shrinking the compiled .jar significantly)
- public int itemId; // id of item
- public int subType; // Subtype of item (i.e. dye colour); 0 if undamaged single-typed item.
- public int count; // Number of items in this clump.
-
- public ItemClump()
- {
- // Default constructor with no parameters.
- itemId = -1;
- subType = 0;
- count = 1;
- }
-
- public ItemClump(int newId, int newType, int newCount)
- {
- itemId = newId;
- subType = newType;
- count = newCount;
- }
-
- public ItemClump(int newId, int newType)
- {
- itemId = newId;
- subType = newType;
- count = 1;
- }
-
- public ItemClump(String initString, DatabaseMarket namesDB, String shopLabel)
- {
- //Valid input string formats:
- //"[ID(,Type)](:Count) (ignored)"
- //"[ItemName](:Count) (ignored)"
- //Pass null to namesDB to skip name lookup.
- itemId = -1;
- subType = 0;
- count = 1;
- String[] idData;
- String[] initData = initString.split(" ");
- boolean subtypeParsed = false;
-
- if (initData[0].contains(":"))
- {
- // Count detected. Pull it out, if it's valid.
- idData = initData[0].split(":");
- try
- {
- count = Integer.valueOf(idData[1]).intValue();
- }
- catch (NumberFormatException e)
- {
- count = 1;
- }
- initData[0] = idData[0];
- }
-
- if (initData[0].contains(","))
- {
- // Subtype detected. Pull it out, if it's valid.
- idData = initData[0].split(",");
- try
- {
- subType = Integer.valueOf(idData[1]).intValue();
- subtypeParsed = true;
- }
- catch (NumberFormatException e)
- {
- subType = 0;
- }
- initData[0] = idData[0];
- }
-
- // Parse stripped item name, if possible.
+ // Implemented because bukkit's ItemStack methods don't handle item subtypes consistently.
+ // Added in to be a convenient package for grabbing entire items worth of shop data at once,
+ // instead of one int at at time or in an easily-confused array.
+ // Also factorizes in some redundant string-parsing code, making it easier to change standard input formats
+ // if necessary (and shrinking the compiled .jar significantly)
+ public int itemId; // id of item
+ public int subType; // Subtype of item (i.e. dye colour); 0 if undamaged single-typed item.
+ public int count; // Number of items in this clump.
- try
- {
- itemId = Integer.valueOf(initData[0]).intValue();
- } catch (NumberFormatException ex) {
- // It's trying to be a name. Find it.
- if (initData[0].equalsIgnoreCase("default"))
- {
- itemId = -1;
- subType = -1;
- }
- else
- {
- if (namesDB != null)
- {
- ItemClump foundItem = namesDB.nameLookup(initData[0], shopLabel);
- if (foundItem != null)
- {
- itemId = foundItem.itemId;
- if (!subtypeParsed)
- subType = foundItem.subType;
- }
- }
- }
- }
-
- if (count < 1) count = 1;
- }
-
- public String idString() {
- return String.valueOf(itemId) + (subType == 0 ? "" : "," + String.valueOf(subType));
- }
-
- public String getName(DatabaseMarket namesDB, String shopLabel)
- {
- // Returns the name of this item.
- // Really ought to use DatabaseMarket for name lookups...
- return namesDB.getName(this, shopLabel);
- }
-
- public boolean isValid()
- {
- if ((itemId != -1) && (subType != -1))
- return true;
- if (isDefault())
- return true;
- return false;
- }
-
- public boolean isDefault()
- {
- if ((itemId == -1) && (subType == -1))
- return true;
- return false;
- }
-
- }
+ public ItemClump() {
+ // Default constructor with no parameters.
+ itemId = -1;
+ subType = 0;
+ count = 1;
+ }
+
+ public ItemClump(int newId, int newType, int newCount) {
+ itemId = newId;
+ subType = newType;
+ count = newCount;
+ }
+
+ public ItemClump(int newId, int newType) {
+ itemId = newId;
+ subType = newType;
+ count = 1;
+ }
+
+ public ItemClump(String initString, DatabaseMarket namesDB, String shopLabel) {
+ // Valid input string formats:
+ // "[ID(,Type)](:Count) (ignored)"
+ // "[ItemName](:Count) (ignored)"
+ // Pass null to namesDB to skip name lookup.
+ itemId = -1;
+ subType = 0;
+ count = 1;
+ String[] idData;
+ String[] initData = initString.split(" ");
+ boolean subtypeParsed = false;
+
+ if (initData[0].contains(":")) {
+ // Count detected. Pull it out, if it's valid.
+ idData = initData[0].split(":");
+ try {
+ count = Integer.valueOf(idData[1]).intValue();
+ } catch (NumberFormatException e) {
+ count = 1;
+ }
+ initData[0] = idData[0];
+ }
+
+ if (initData[0].contains(",")) {
+ // Subtype detected. Pull it out, if it's valid.
+ idData = initData[0].split(",");
+ try {
+ subType = Integer.valueOf(idData[1]).intValue();
+ subtypeParsed = true;
+ } catch (NumberFormatException e) {
+ subType = 0;
+ }
+ initData[0] = idData[0];
+ }
+
+ // Parse stripped item name, if possible.
+
+ try {
+ itemId = Integer.valueOf(initData[0]).intValue();
+ } catch (NumberFormatException ex) {
+ // It's trying to be a name. Find it.
+ if (initData[0].equalsIgnoreCase("default")) {
+ itemId = -1;
+ subType = -1;
+ } else {
+ if (namesDB != null) {
+ ItemClump foundItem = namesDB.nameLookup(initData[0], shopLabel);
+ if (foundItem != null) {
+ itemId = foundItem.itemId;
+ if (!subtypeParsed) {
+ subType = foundItem.subType;
+ }
+ }
+ }
+ }
+ }
+
+ if (count < 1) {
+ count = 1;
+ }
+ }
+
+ public String idString() {
+ return String.valueOf(itemId) + (subType == 0 ? "" : "," + String.valueOf(subType));
+ }
+
+ public String getName(DatabaseMarket namesDB, String shopLabel) {
+ // Returns the name of this item.
+ // Really ought to use DatabaseMarket for name lookups...
+ return namesDB.getName(this, shopLabel);
+ }
+
+ public boolean isValid() {
+ if ((itemId != -1) && (subType != -1)) {
+ return true;
+ }
+ if (isDefault()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isDefault() {
+ if ((itemId == -1) && (subType == -1)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/com/gmail/haloinverse/DynamicMarket/Items.java b/src/com/gmail/haloinverse/DynamicMarket/Items.java
index d70844e..097a663 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/Items.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/Items.java
@@ -1,234 +1,195 @@
package com.gmail.haloinverse.DynamicMarket;
-//CHANGED: This was changed into an instanced class.
-//CHANGED: Untyped items have a subtype (stored as damage) field = 0, NOT -1!
-// This was completely breaking attempts to support typed items, i.e. logs/dyes/wool.
-//TODO: Consider moving purely player-inventory-related methods into another class.
-//TODO: Change "validate*" methods to something more descriptive.
-//TODO: Add MySQL/SQLite support, with import from flat-file.
-
-/* */ //package com.nijikokun.bukkit.SimpleShop;
-/* */
-/* */ import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import org.bukkit.Material;
-/* */ import org.bukkit.entity.Player;
-/* */ import org.bukkit.inventory.ItemStack;
- import org.bukkit.inventory.PlayerInventory;
-/* */
-/* */ public class Items
-/* */ {
-
- private HashMap itemsData;
- private iProperty ItemsFile;
- private DynamicMarket plugin;
-
- public Items(String itemFileName, DynamicMarket thisPlugin)
- {
- //TODO: Handle cases where the plugin loads, but items.db doesn't.
- //TODO: Add user command for reloading items.db.
- //TODO: Make item file format more generic.
- this.plugin = thisPlugin;
- ItemsFile = new iProperty(itemFileName);
- // Following code originally in setupItems from SimpleShop
-/* 169 */ Map mappedItems = null;
-/* 170 */ itemsData = new HashMap();
-/* */ try
-/* */ {
-/* 173 */ mappedItems = ItemsFile.returnMap();
-/* */ } catch (Exception ex) {
-/* 175 */ plugin.log.info(Messaging.bracketize(new StringBuilder().append(plugin.name).append(" Flatfile").toString()) + " could not grab item list!");
-/* */ }
-/* */ Iterator i$;
-/* 178 */ if (mappedItems != null)
-/* 179 */ for (i$ = mappedItems.keySet().iterator(); i$.hasNext(); ) { Object item = i$.next();
-/* 180 */ String id = (String)item;
-/* 181 */ String itemName = mappedItems.get(item);
-/* 182 */ itemsData.put(id, itemName);
-/* */ }
-/* */ }
-
-/* */ public String name(String idString)
- // Fetches the item name given an id string.
- // Subtype, if present, is in the input format ("[id],[subtype]")
-/* */ {
-/* 22 */ if (itemsData.containsKey(idString)) {
-/* 23 */ return ((String)itemsData.get(idString));
-/* */ }
- if ((!(idString.contains(","))) && (itemsData.containsKey(idString+",0")))
- return((String)itemsData.get(idString+",0"));
-/* */ // Fallback: Fetch the name from the bukkit Material class.
-/* 26 */ //for (Material item : Material.values()) {
-/* 27 */ // if (item.getId() == id) {
-/* 28 */ // return item.toString();
-/* */ // }
-/* */ //}
-/* */
-/* 32 */ //return Misc.string(id);
- return ("UNKNOWN");
-/* */ }
-
- public String name(ItemClump itemData)
- {
- // Fetches the item name given an ItemClump.
- return name(Integer.toString(itemData.itemId) + (itemData.subType != 0 ? "," + Integer.toString(itemData.subType) : ""));
- }
-
-/* */
-/* */ public void setName(String id, String name)
-/* */ {
-/* 42 */ itemsData.put(id, name);
-/* 43 */ ItemsFile.setString(id, name);
-/* */ }
-/* */
-
- public static boolean has(Player player, ItemClump scanItem, int numBundles)
- {
- return (hasAmount(player, scanItem) >= (scanItem.count * numBundles));
- }
-
- public static int hasAmount(Player player, ItemClump scanItem)
- {
- PlayerInventory inventory = player.getInventory();
- ItemStack[] items = inventory.getContents();
- int amount = 0;
-
- for (ItemStack item : items) {
- if ((item != null) && (item.getTypeId() == scanItem.itemId) && (item.getDurability() == (byte)scanItem.subType)) {
- amount += item.getAmount();
- }
- }
- return amount;
- }
-
- public static boolean has(Player player, int itemId, int itemType, int amount)
- {
- return (hasAmount(player, new ItemClump(itemId, itemType)) >= amount);
- }
-
- public void remove(Player player, ItemClump item, int amount)
- {
- // TODO: Clean this up once Bukkit's inventory.removeItem(ItemStack[]) code handles subtypes.
- // Note that this removes (item.count * amount) items from the player's inventory.
- // This is to streamline removing multiples of bundle counts.
- PlayerInventory inventory = player.getInventory();
- ItemStack[] items = inventory.getContents();
- ItemStack thisItem;
- int toRemove = item.count*amount;
-
- for (int invSlot = 35; (invSlot >= 0) && (toRemove > 0); --invSlot)
- {
- thisItem = items[invSlot];
- if ((items[invSlot] != null) && (thisItem.getTypeId() == item.itemId) && (thisItem.getDurability() == (byte)item.subType))
- {
- toRemove -= thisItem.getAmount();
- inventory.clear(invSlot);
- }
- }
-
- if (toRemove < 0) // removed too many! put some back!
- inventory.addItem(new ItemStack[] { new ItemStack(item.itemId, -toRemove, (byte)item.subType) });
- }
-
- public ItemClump nameLookup(String item)
- {
- // Given an item name (with optional ",", returns an ItemClump loaded with the id and subtype.
- // If name is not found, returns null.
-
- int itemId = -1;
- int itemSubtype = 0;
- ItemClump returnedItem = null;
-
- for (String id : itemsData.keySet()) {
- if (((String)itemsData.get(id)).equalsIgnoreCase(item)) {
- if (id.contains(",")) {
- itemId = Integer.valueOf(id.split(",")[0]).intValue();
- itemSubtype = Integer.valueOf(id.split(",")[1]).intValue();
- }
- else {
- itemId = Integer.valueOf(id).intValue();
- itemSubtype = 0;
- }
- returnedItem = new ItemClump(itemId, itemSubtype);
- break;
- }
- }
-
- if (returnedItem != null)
- return returnedItem;
-
- // No exact match found: Try partial-name matching.
- String itemLower = item.toLowerCase();
- for (String id : itemsData.keySet()) {
- if (((String)itemsData.get(id)).toLowerCase().contains(itemLower)) {
- if (id.contains(",")) {
- itemId = Integer.valueOf(id.split(",")[0]).intValue();
- itemSubtype = Integer.valueOf(id.split(",")[1]).intValue();
- }
- else {
- itemId = Integer.valueOf(id).intValue();
- itemSubtype = 0;
- }
- returnedItem = new ItemClump(itemId, itemSubtype);
- break;
- }
- }
-
- return returnedItem;
- }
-
-
- public static boolean validateType(int id, int type)
- // Given an id and a subtype, confirms that the selected subtype is valid.
- //CHANGED: Rewritten as a switch block. Cleaner & faster.
- {
- if (type == 0)
- return true;
- if (type < 0)
- return false;
-
- switch (id)
- {
- case 35:
- case 63:
- case 351:
- return (type <= 15);
- case 17:
- return (type <= 2);
- case 53:
- case 64:
- case 67:
- case 71:
- case 77:
- case 86:
- case 91:
- return (type <= 3);
- case 66:
- return (type <= 9);
- case 68:
- return ((type >= 2) && (type <= 5));
- default:
- return false;
- }
- }
-
-
-/* */ public static boolean checkID(int id)
- // ? Confirms that the given id is known by bukkit as an item id.
-/* */ {
-/* 289 */ for (Material item : Material.values()) {
-/* 290 */ if (item.getId() == id) {
-/* 291 */ return true;
-/* */ }
-/* */ }
-/* */
-/* 295 */ return false;
-/* */ }
-/* */ }
-
-/* Location: C:\Program Files\eclipse\Bukkit\SimpleShop.jar
- * Qualified Name: com.nijikokun.bukkit.SimpleShop.Items
- * Java Class Version: 5 (49.0)
- * JD-Core Version: 0.5.3
- */
\ No newline at end of file
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.PlayerInventory;
+
+public class Items {
+
+ private HashMap itemsData;
+ private iProperty ItemsFile;
+
+ public Items(String itemFileName, DynamicMarket thisPlugin) {
+ // TODO: Handle cases where the plugin loads, but items.db doesn't.
+ // TODO: Add user command for reloading items.db.
+ // TODO: Make item file format more generic.
+ ItemsFile = new iProperty(itemFileName);
+ // Following code originally in setupItems from SimpleShop
+ Map mappedItems = null;
+ itemsData = new HashMap();
+
+ try {
+ mappedItems = ItemsFile.returnMap();
+ } catch (Exception ex) {
+ DynamicMarket.log.info(Messaging.bracketize(new StringBuilder().append(DynamicMarket.name).append(" Flatfile").toString()) + " could not grab item list!");
+ }
+
+ Iterator i$;
+
+ if (mappedItems != null) {
+ for (i$ = mappedItems.keySet().iterator(); i$.hasNext();) {
+ Object item = i$.next();
+ String id = (String) item;
+ String itemName = mappedItems.get(item);
+ itemsData.put(id, itemName);
+ }
+ }
+ }
+
+ public String name(String idString) {
+ if (itemsData.containsKey(idString)) {
+ return ((String) itemsData.get(idString));
+ }
+ if ((!(idString.contains(","))) && (itemsData.containsKey(idString + ",0"))) {
+ return ((String) itemsData.get(idString + ",0"));
+ }
+
+ return ("UNKNOWN");
+ }
+
+ public String name(ItemClump itemData) {
+ // Fetches the item name given an ItemClump.
+ return name(Integer.toString(itemData.itemId) + (itemData.subType != 0 ? "," + Integer.toString(itemData.subType) : ""));
+ }
+
+ public void setName(String id, String name) {
+ itemsData.put(id, name);
+ ItemsFile.setString(id, name);
+ }
+
+ public static boolean has(Player player, ItemClump scanItem, int numBundles) {
+ return (hasAmount(player, scanItem) >= (scanItem.count * numBundles));
+ }
+
+ public static int hasAmount(Player player, ItemClump scanItem) {
+ PlayerInventory inventory = player.getInventory();
+ ItemStack[] items = inventory.getContents();
+ int amount = 0;
+
+ for (ItemStack item : items) {
+ if ((item != null) && (item.getTypeId() == scanItem.itemId) && (item.getDurability() == (byte) scanItem.subType)) {
+ amount += item.getAmount();
+ }
+ }
+ return amount;
+ }
+
+ public static boolean has(Player player, int itemId, int itemType, int amount) {
+ return (hasAmount(player, new ItemClump(itemId, itemType)) >= amount);
+ }
+
+ public void remove(Player player, ItemClump item, int amount) {
+ // TODO: Clean this up once Bukkit's inventory.removeItem(ItemStack[]) code handles subtypes.
+ // Note that this removes (item.count * amount) items from the player's inventory.
+ // This is to streamline removing multiples of bundle counts.
+ PlayerInventory inventory = player.getInventory();
+ ItemStack[] items = inventory.getContents();
+ ItemStack thisItem;
+ int toRemove = item.count * amount;
+
+ for (int invSlot = 35; (invSlot >= 0) && (toRemove > 0); --invSlot) {
+ thisItem = items[invSlot];
+ if ((items[invSlot] != null) && (thisItem.getTypeId() == item.itemId) && (thisItem.getDurability() == (byte) item.subType)) {
+ toRemove -= thisItem.getAmount();
+ inventory.clear(invSlot);
+ }
+ }
+
+ if (toRemove < 0) // removed too many! put some back!
+ {
+ inventory.addItem(new ItemStack[]{new ItemStack(item.itemId, -toRemove, (byte) item.subType)});
+ }
+ }
+
+ public ItemClump nameLookup(String item) {
+ // Given an item name (with optional ",", returns an ItemClump loaded with the id and subtype.
+ // If name is not found, returns null.
+
+ int itemId = -1;
+ int itemSubtype = 0;
+ ItemClump returnedItem = null;
+
+ for (String id : itemsData.keySet()) {
+ if (((String) itemsData.get(id)).equalsIgnoreCase(item)) {
+ if (id.contains(",")) {
+ itemId = Integer.valueOf(id.split(",")[0]).intValue();
+ itemSubtype = Integer.valueOf(id.split(",")[1]).intValue();
+ } else {
+ itemId = Integer.valueOf(id).intValue();
+ itemSubtype = 0;
+ }
+ returnedItem = new ItemClump(itemId, itemSubtype);
+ break;
+ }
+ }
+
+ if (returnedItem != null) {
+ return returnedItem;
+ }
+
+ // No exact match found: Try partial-name matching.
+ String itemLower = item.toLowerCase();
+ for (String id : itemsData.keySet()) {
+ if (((String) itemsData.get(id)).toLowerCase().contains(itemLower)) {
+ if (id.contains(",")) {
+ itemId = Integer.valueOf(id.split(",")[0]).intValue();
+ itemSubtype = Integer.valueOf(id.split(",")[1]).intValue();
+ } else {
+ itemId = Integer.valueOf(id).intValue();
+ itemSubtype = 0;
+ }
+ returnedItem = new ItemClump(itemId, itemSubtype);
+ break;
+ }
+ }
+
+ return returnedItem;
+ }
+
+ public static boolean validateType(int id, int type) {
+ if (type == 0) {
+ return true;
+ }
+ if (type < 0) {
+ return false;
+ }
+
+ switch (id) {
+ case 35:
+ case 63:
+ case 351:
+ return (type <= 15);
+ case 17:
+ return (type <= 2);
+ case 53:
+ case 64:
+ case 67:
+ case 71:
+ case 77:
+ case 86:
+ case 91:
+ return (type <= 3);
+ case 66:
+ return (type <= 9);
+ case 68:
+ return ((type >= 2) && (type <= 5));
+ default:
+ return false;
+ }
+ }
+
+ public static boolean checkID(int id) // ? Confirms that the given id is known by bukkit as an item id.
+ {
+ for (Material item : Material.values()) {
+ if (item.getId() == id) {
+ return true;
+ }
+}
+
+ return false;
+ }
+}
diff --git a/src/com/gmail/haloinverse/DynamicMarket/MarketItem.java b/src/com/gmail/haloinverse/DynamicMarket/MarketItem.java
index 3186748..b004ee4 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/MarketItem.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/MarketItem.java
@@ -1,944 +1,902 @@
package com.gmail.haloinverse.DynamicMarket;
-import com.nijikokun.bukkit.iConomy.iConomy;
+import com.nijiko.coelho.iConomy.iConomy;
import java.lang.Math;
import java.util.ArrayList;
+
//import java.sql.ResultSet;
public class MarketItem extends ItemClump {
- private String name; //n | name // name used for item
- public int basePrice; //bp // base purchase price of item
- public int stock; //s // current stock level of item
- public boolean canBuy; //cb // true if can be purchased, false if not
- public boolean canSell; //cs // true if can be sold, false if not
- private int volatility; //v // % change in price per 1 stock bought/sold, * intScale
- //iv // inverse volatility; units bought/sold per doubling/halving of price
- public int salesTax; //st // basePrice * (1 - (salesTax/100)) = selling price
- public int stockLowest; //sl // minimum stock at which purchases will fail (hard limit)
- public int stockHighest; //sh // maximum stock at which sales will fail (hard limit)
- public int stockFloor; //sf // minimum stock level possible (soft limit)
- public int stockCeil; //sc // maximum stock level possible (soft limit)
- public int priceFloor; //pf // minimum price <- applies to basePrice, without salesTax
- public int priceCeil; //pc // maximum price
- public int jitterPerc;
- public int driftOut;
- public int driftIn;
- public int avgStock;
- public int itemClass;
- public String shopLabel = ""; // Shop DB table this is a member of.
- // Other input tags:
- //fixed // stock = 0
- // stockLowest = Integer.MIN_VALUE
- // stockHighest = Integer.MAX_VALUE
- // stockFloor = 0
- // stockCeil = 0
- // buyok // canBuy = 1
- // sellok // canSell = 1
- // !nobuy // canBuy = 1
- // !nosell // canSell = 1
- // !buyok // canBuy = 0
- // !sellok // canSell = 0
- // nobuy // canBuy = 0
- // nosell // canSell = 0
- public static int intScale = 10000; // Scale factor used in integerization of calculations.
- public DatabaseMarket thisDatabase = null; // Database object this item is a member of.
-
- /* diamond: 10 items -> 10% price change, 1 item -> 1% price change, 0.01 * 10000 = 1000
- *
- * cobble: 640 items -> 10% price change, 1 item -> 0.016% price change, 0.00016 * 10000 = 16
- *
- * ?inelastic?: v=1 -> 0.001% price change, 1000 items -> 1% price change
- *
- * ?elastic?: v=10000, 1 item -> +100% | -50% price change
- *
- * volatility: % change in price per unit bought/sold, * intScale / 100 (2% per item = 2 * intScale / 100)
- * inverse volatility: units bought/sold per doubling/halving of price
- *
- * ivol = ln(2) / ln(1+(vol/intScale))
- * vol = (2^(1/iVol)-1) * intScale
- *
- */
-
- public MarketItem(String thisShopLabel)
- {
- // Default constructor with no parameters.
- super();
- setBaseDefaults();
- shopLabel = thisShopLabel;
- }
-
- public MarketItem()
- {
- // Default constructor with no parameters.
- super();
- setBaseDefaults();
- }
-
- public MarketItem(String initString, MarketItem defaults, DatabaseMarket thisDB, String thisShopLabel)
- {
- //Valid input string formats:
- //"[ID(,Type)](:Count) (buyprice (sellPrice)) (field:val (field:val (...)))"
- //"[ItemName](:Count) (buyprice (sellPrice)) (field:val (field:val (...)))"
- //TODO: Add alternate input format for setting low/high ranges with a single tag.
-
- super(initString.split(" ",2)[0], thisDB, thisShopLabel); // Parse id/name, type, and count from first split.
-
- thisDatabase = thisDB;
- shopLabel = thisShopLabel;
-
- //SimpleMarket.log.info("[1] InitString: [" + initString + "]");
-
- String[] initData = initString.split(" ");
-
- // If 0th tag (name) does not contain ":", use count from defaults.
- if(!initData[0].contains(":"))
- this.count = defaults.count;
-
- // Load defaults, if available.
- if (defaults != null)
- {
- this.basePrice = Math.round((float)defaults.basePrice * this.count / defaults.count);
- this.stock = Math.round(((float)defaults.stock * defaults.count / this.count) - 0.5f);
- this.canBuy = defaults.canBuy;
- this.canSell = defaults.canSell;
- this.volatility = defaults.volatility;
- this.salesTax = defaults.salesTax;
- this.stockLowest = defaults.stockLowest;
- this.stockHighest = defaults.stockHighest;
- this.stockFloor = defaults.stockFloor;
- this.stockCeil = defaults.stockCeil;
- this.priceFloor = defaults.priceFloor;
- this.priceCeil = defaults.priceCeil;
- }
- else
- {
- setBaseDefaults();
- }
-
- //Load data from remaining items in split.
- //If first one or two items have no tag, assume they are the basePrice and the sellPrice.
-
- parseTags(initData);
-
- sanityCheck();
- }
-
- private void parseTags(String initData[])
- {
- // Load data from a list of tags.
- // Element [0] is ignored.
- String curTag;
- Integer curVal;
- String stringVal;
- String[] curParams;
- boolean setUntaggedBase = false;
-
- if (initData.length > 1)
- {
- for (int i = 1; i <= initData.length - 1; i++)
- {
- stringVal = null;
- // Get current tag and value
-
- if (initData[i].contains(":"))
- {
- curParams = initData[i].split(":");
- curTag = curParams[0];
- try
- {
- curVal = Integer.parseInt(curParams[1]);
- }
- catch (NumberFormatException ex)
- {
- if (curParams[1].equalsIgnoreCase("+INF"))
- curVal = Integer.MAX_VALUE;
- else if (curParams[1].equalsIgnoreCase("-INF"))
- curVal = Integer.MIN_VALUE;
- else
- {
- curVal = null;
- stringVal = curParams[1];
- }
- }
- }
- else
- {
- try
- { // Try to parse it as a plain integer.
- curTag = null;
- curVal = Integer.parseInt(initData[i]);
- }
- catch (NumberFormatException ex)
- { // Didn't work? Just use it as a string.
- curVal = null;
- curTag = initData[i];
- }
- }
-
- // If first param is an untagged value, make it the basePrice.
- if (i == 1)
- {
- if (curTag == null)
- {
- if (curVal != -1)
- {
- this.basePrice = curVal;
- //maskData.basePrice = 1;
- }
- else
- {
- // Base price set to -1. Disable buying.
- this.basePrice = 0;
- //maskData.basePrice = 1;
- this.canBuy = false;
- }
- setUntaggedBase = true;
- continue;
- }
- }
-
- // If second param is an untagged value, make the sellPrice equal to it after sales tax is applied.
- if (i == 2)
- {
- if ((setUntaggedBase) && (curTag == null))
- {
- if (curVal != -1)
- {
- // if salePrice = basePrice * (1 - (salesTax / 100))
- // then (1 - (salePrice / basePrice)) * 100 = salesTax
- if (this.basePrice != 0)
- {
- this.salesTax = Math.round((1 - ((float)curVal / basePrice)) * 100);
- //maskData.salesTax = 1;
- }
- else
- {
- this.basePrice = curVal;
- this.salesTax = 0;
- //maskData.salesTax = 1;
- }
- }
- else
- {
- // Sale price set to -1. Disable selling.
- this.canSell = false;
- }
- continue;
- }
- }
-
- // Handle remaining items in split.
-
- if (curTag != null)
- {
- if (curVal != null)
- {
- if (curTag.equalsIgnoreCase("bp") || curTag.equalsIgnoreCase("baseprice"))
- {
- this.basePrice = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("s") || curTag.equalsIgnoreCase("stock"))
- {
- this.stock = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("v") || curTag.equalsIgnoreCase("volatility") || curTag.equalsIgnoreCase("vol"))
- {
- this.setVolatility(curVal);
- continue;
- }
- if (curTag.equalsIgnoreCase("iv") || curTag.equalsIgnoreCase("invvolatility") || curTag.equalsIgnoreCase("ivol"))
- {
- this.setInverseVolatility(curVal);
- continue;
- }
- if (curTag.equalsIgnoreCase("st") || curTag.equalsIgnoreCase("salestax"))
- {
- this.salesTax = rangeCrop(curVal, 0, 100);
- continue;
- }
- if (curTag.equalsIgnoreCase("sl") || curTag.equalsIgnoreCase("stocklowest"))
- {
- this.stockLowest = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("sh") || curTag.equalsIgnoreCase("stockhighest"))
- {
- this.stockHighest = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("sf") || curTag.equalsIgnoreCase("stockfloor"))
- {
- this.stockFloor = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("sc") || curTag.equalsIgnoreCase("stockceiling"))
- {
- this.stockCeil = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("pf") || curTag.equalsIgnoreCase("pricefloor"))
- {
- this.priceFloor = curVal;
- continue;
- }
- if (curTag.equalsIgnoreCase("pc") || curTag.equalsIgnoreCase("priceceiling"))
- {
- this.priceCeil = curVal;
- continue;
- }
- }
- }
- if (curTag.equalsIgnoreCase("flat"))
- {
- this.stock = 0;
- this.stockLowest = Integer.MIN_VALUE;
- this.stockHighest = Integer.MAX_VALUE;
- this.stockFloor = Integer.MIN_VALUE;
- this.stockCeil = Integer.MAX_VALUE;
- this.priceFloor = 0;
- this.priceCeil = Integer.MAX_VALUE;
- this.volatility = 0;
- continue;
- }
- if (curTag.equalsIgnoreCase("fixed"))
- {
- this.stock = 0;
- this.stockLowest = Integer.MIN_VALUE;
- this.stockHighest = Integer.MAX_VALUE;
- this.stockFloor = 0;
- this.stockCeil = 0;
- this.priceFloor = 0;
- this.priceCeil = Integer.MAX_VALUE;
- this.volatility = 0;
- continue;
- }
- if (curTag.equalsIgnoreCase("float"))
- {
- this.stockFloor = Integer.MIN_VALUE;
- this.stockCeil = Integer.MAX_VALUE;
- this.stockLowest = Integer.MIN_VALUE;
- this.stockHighest = Integer.MAX_VALUE;
- this.priceFloor = 0;
- this.priceCeil = Integer.MAX_VALUE;
- if (this.volatility == 0)
- this.volatility = 100;
- }
- if (curTag.equalsIgnoreCase("finite"))
- {
- this.stockFloor = Integer.MIN_VALUE;
- this.stockCeil = Integer.MAX_VALUE;
- this.stockLowest = 0;
- this.stockHighest = Integer.MAX_VALUE;
- }
- if ((curTag.equalsIgnoreCase("buyok")) || (curTag.equalsIgnoreCase("!nobuy")))
- {
- this.canBuy = true;
- continue;
- }
- if ((curTag.equalsIgnoreCase("sellok")) || (curTag.equalsIgnoreCase("!nosell")))
- {
- this.canSell = true;
- continue;
- }
- if ((curTag.equalsIgnoreCase("!buyok")) || (curTag.equalsIgnoreCase("nobuy")) || (curTag.equalsIgnoreCase("!cb")))
- {
- this.canBuy = false;
- continue;
- }
- if ((curTag.equalsIgnoreCase("!sellok")) || (curTag.equalsIgnoreCase("nosell")) || (curTag.equalsIgnoreCase("!cs")))
- {
- this.canSell = false;
- continue;
- }
- if (curTag.equalsIgnoreCase("cb") || curTag.equalsIgnoreCase("canbuy"))
- {
- if ((stringVal != null) && (!(stringVal.isEmpty())))
- {
- this.canBuy = ((stringVal.toLowerCase().startsWith("y")) || (stringVal.toLowerCase().startsWith("t")));
- }
- else
- this.canBuy = true;
- continue;
- }
- if (curTag.equalsIgnoreCase("cs") || curTag.equalsIgnoreCase("cansell"))
- {
- if ((stringVal != null) && (!(stringVal.isEmpty())))
- {
- this.canSell = ((stringVal.toLowerCase().startsWith("y")) || (stringVal.toLowerCase().startsWith("t")));
- }
- else
- this.canSell = true;
- continue;
- }
- if ((curTag.equalsIgnoreCase("name")) || (curTag.equalsIgnoreCase("n")))
- {
- setName(stringVal);
- continue;
- }
- if (curTag.equalsIgnoreCase("renorm"))
- {
- //double oldBuyPrice = getStockPrice(this.stock);
- int newStock;
- if (curVal == null)
- newStock = 0;
- else
- newStock = curVal;
- this.basePrice = getRenormedPrice(newStock);
- this.stock = newStock;
- // basePrice = inverse of stockPrice = rangeCrop(this.basePrice * Math.pow(getVolFactor(), -rangeCrop(stockLevel, stockFloor, stockCeil)), priceFloor, priceCeil)
- /*
- * oldstockPrice = this.basePrice * (getVolFactor() ^ -stockLevel)
- * oldstockPrice / (getVolFactor() ^ -stockLevel) = basePrice
- */
- //this.basePrice = (int)Math.round(oldBuyPrice / Math.pow(getVolFactor(), -rangeCrop(this.stock, stockFloor, stockCeil)));
- }
- }
- //TODO: Log and report invalid tags somehow.
- }
- }
-
- public int getRenormedPrice(int newStock)
- {
- // Calculate what the renormalized base price would be when shifting from the current stock level to newStock.
- double oldBuyPrice = getStockPrice(this.stock);
- return (int)Math.round(oldBuyPrice / Math.pow(getVolFactor(), -rangeCrop(newStock, stockFloor, stockCeil)));
- }
-
- public MarketItem(SQLHandler myQuery)
- {
- // Initialize a new MarketItem from an SQLHandler ResultSet.
- super();
- //thisDatabase.plugin.log.info("Creating from SQL...");
- this.itemId = myQuery.getInt("item");
- this.subType = myQuery.getInt("subtype");
- this.name = myQuery.getString("name");
- this.count = myQuery.getInt("count");
- this.basePrice = myQuery.getInt("baseprice");
- this.canBuy = (myQuery.getInt("canbuy") == 1);
- this.canSell = (myQuery.getInt("cansell") == 1);
- this.stock = myQuery.getInt("stock");
- this.volatility = myQuery.getInt("volatility");
- this.salesTax = myQuery.getInt("salestax");
- this.stockHighest = myQuery.getInt("stockhighest");
- this.stockLowest = myQuery.getInt("stocklowest");
- this.stockFloor = myQuery.getInt("stockfloor");
- this.stockCeil = myQuery.getInt("stockceil");
- this.priceFloor = myQuery.getInt("pricefloor");
- this.priceCeil = myQuery.getInt("priceceil");
- this.shopLabel = myQuery.getString("shoplabel");
- sanityCheck();
- }
-
- private void sanityCheck()
- {
- // Check and fix possible chaos-inducing data.
- // Mirrors DatabaseMarket.sanityCheckAll.
-
- this.salesTax = rangeCrop(this.salesTax, 0, 100);
-
- if (this.stockHighest < this.stock)
- this.stockHighest = this.stock;
-
- if (this.stockLowest > this.stock)
- this.stockLowest = this.stock;
-
- if (this.stockCeil < this.stock)
- this.stockCeil = this.stock;
-
- if (this.stockFloor > this.stock)
- this.stockFloor = this.stock;
-
- if (this.priceCeil < this.priceFloor)
- this.priceCeil = this.priceFloor;
-
- this.basePrice = Math.max(0, this.basePrice);
- }
-
- private void setBaseDefaults()
- {
- name = null;
- basePrice = 0;
- stock = 0;
- canBuy = true;
- canSell = true;
- volatility = 1;
- salesTax = 0;
- stockLowest = Integer.MIN_VALUE;
- stockHighest = Integer.MAX_VALUE;
- stockFloor = 0;
- stockCeil = 0;
- priceFloor = 0;
- priceCeil = Integer.MAX_VALUE;
- }
-
- //public int sellPrice()
- //{
- // return (rangeCrop(Math.round(basePrice * (1 - (salesTax / 100))), priceFloor, priceCeil));
- //}
-
- public static int rangeCrop(int value, int minVal, int maxVal)
- {
- return (Math.min(Math.max(value, minVal), maxVal));
- }
-
- public static double rangeCrop(double value, double minVal, double maxVal)
- {
- return (Math.min(Math.max(value, minVal), maxVal));
- }
-
- public String getName()
- {
- if ((this.name == null) || (this.name.isEmpty()))
- this.name = super.getName(thisDatabase, shopLabel);
- return this.name;
- }
-
- public void setName(String newName)
- {
- if ((newName != null) && (!(newName.isEmpty())))
- {
- this.name = newName;
- }
- else
- {
- this.name = super.getName(thisDatabase, shopLabel);
- }
- }
-
- public double getBatchPrice(int startStock, int endStock)
- {
- // Gets the current base price for the items at stock levels from startStock to endStock.
- // NOTE: Does not check stockLowest/stockHighest transaction limits.
-
- int lowStock = Math.min(startStock, endStock);
- int highStock = Math.max(startStock, endStock);
- int numTerms = highStock - lowStock + 1;
- double lowStockPrice;
- double highStockPrice;
- int fixedStockLimit;
-
- // End calculation if volatility == 0. Price does not change, so all items are the same value.
- if (volatility == 0)
- return (numTerms * getStockPrice(stock));
-
- // End calculation if highStock <= stockFloor (All below floor)
- if (highStock <= stockFloor)
- return (numTerms * getStockPrice(stockFloor));
-
- // End calculation if lowStock >= stockCeil (All above ceiling)
- if (lowStock >= stockCeil)
- return (numTerms * getStockPrice(stockCeil));
-
- // Split calculation if stockFloor reached by lowStock (Some below floor)
- if (lowStock < stockFloor)
- return (((stockFloor-lowStock)*getStockPrice(stockFloor)) + getBatchPrice(stockFloor, highStock));
-
- // Split calculation if stockCeil reached by highStock (Some above ceiling)
- if (highStock > stockCeil)
- return (((highStock-stockCeil)*getStockPrice(stockCeil)) + getBatchPrice(lowStock, stockCeil));
-
- lowStockPrice = getStockPrice(lowStock); // highest price in range
- highStockPrice = getStockPrice(highStock); // lowest price in range
-
- // WARNING in this section: Highest stock level corresponds to lowest price,
- // and lowest stock level corresponds to highest price.
-
- // End calculation if lowStockPrice <= priceFloor (All below floor)
- if (lowStockPrice <= priceFloor)
- return (numTerms * priceFloor);
-
- // End calculation if highStockPrice >= priceCeil (All above ceiling)
- if (highStockPrice >= priceCeil)
- return (numTerms * priceCeil);
-
- // Split calculation if highStockPrice < priceFloor (Some below floor)
- if (highStockPrice < priceFloor)
- {
- fixedStockLimit = (int)Math.round(Math.floor(stockAtPrice(priceFloor)));
- return (((highStock - fixedStockLimit) * priceFloor) + getBatchPrice(lowStock, fixedStockLimit));
- }
-
- // Split calculation if lowStockPrice > priceCeil (Some above ceiling)
- if (lowStockPrice > priceCeil)
- {
- fixedStockLimit = (int)Math.round(Math.ceil(stockAtPrice(priceCeil)));
- return (((fixedStockLimit - lowStock) * priceCeil) + getBatchPrice(fixedStockLimit, highStock));
- }
-
-
- // All range limits handled? Find the sum of terms of a finite geometric series.
- //return Math.round(this.basePrice * Math.pow(getVolFactor(),-lowStock) * (Math.pow(getVolFactor(),numTerms) - 1) / (getVolFactor()-1));
- //return math.round(firstTerm * (1 - (ratio ^ terms)) / (1 - ratio));
- return Math.round(lowStockPrice * (1 - (Math.pow(1/getVolFactor(), numTerms))) / (1 - (1/getVolFactor())));
- }
-
- public int getBuyPrice(int numBundles)
- {
- // Return the purchase price of the given number of bundles.
- getBatchPrice(stock, stock + numBundles - 1);
- return (int)Math.round(Math.ceil(getBatchPrice(stock, stock - numBundles + 1)));
- }
-
- public int getSellPrice(int numBundles)
- {
- // Return the selling price of the given number of bundles.
- return (int)Math.round(Math.floor(deductTax(getBatchPrice(stock + numBundles, stock + 1))));
- }
-
- private double deductTax(double basePrice)
- {
- // Returns the given price minus the sales tax.
- return (basePrice * (1 - ((double)salesTax/100)));
- }
-
- private double getStockPrice(int stockLevel)
- {
- // Crops result to stockFloor/stockCeil/priceFloor/priceCeil.
- return rangeCrop(this.basePrice * Math.pow(getVolFactor(), -rangeCrop(stockLevel, stockFloor, stockCeil)), priceFloor, priceCeil);
- }
-
- public int getVolatility()
- {
- return this.volatility;
- }
-
- public double getVolFactor()
- {
- return (1 + (double)volatility/intScale);
- }
-
- public void setVolatility(int newVol)
- {
- this.volatility = rangeCrop(newVol, 0, intScale);
- }
-
- public void setVolatility(double newVol)
- {
- setVolatility((int)Math.round(newVol));
- }
-
- public int getInverseVolatility()
- {
- if(volatility == 0)
- return Integer.MAX_VALUE;
- else
- return (int)Math.round(Math.log(2) / Math.log(getVolFactor()));
- }
-
- public void setInverseVolatility(int newIVol)
- {
- //if (newIVol == Integer.MAX_VALUE)
- // setVolatility(0);
- //else
- // setVolatility((Math.pow(2,(1/(double)newIVol))-1) * intScale);
- setVolatility(iVolToVol(newIVol));
- }
-
- public static int iVolToVol(int invVol)
- {
- // Converts inverse volatility to volatility.
- if (invVol == Integer.MAX_VALUE)
- return 0;
- else
- return (int)Math.round((Math.pow(2,(1/(double)invVol))-1) * intScale);
- }
-
- private double stockAtPrice(int targPrice)
- {
- // Returns the stock level at which price == targPrice.
- if (volatility == 0)
- {
- // If price doesn't change, the stock level is effectively +/-INF.
- if (targPrice > basePrice)
- return Integer.MIN_VALUE;
- if (targPrice < basePrice)
- return Integer.MAX_VALUE;
- // targPrice == basePrice
- return stock;
- }
- return -(Math.log((double)targPrice/basePrice) / Math.log(getVolFactor()));
- }
-
- public String formatBundleCount(int numBundles)
- {
- if (numBundles == 1)
- return (Integer.toString(count));
- if (count == 1)
- return (Integer.toString(numBundles));
- return (Integer.toString(count) + "x" + Integer.toString(numBundles));
- }
-
- public String infoStringBuy(int numBundles)
- {
- if (!isValid())
- return ("{ERR}Invalid or uninitialized item.");
- if (!canBuy)
- return ("{PRM}"+getName() + "{ERR} is unavailable for purchase.");
- if (!getCanBuy(1))
- return ("{PRM}"+getName() + "{ERR} is out of stock: no more can be bought right now.");
- if (!getCanBuy(numBundles))
- return ("{PRM}"+getName() + "{ERR} has only {PRM}" + formatBundleCount(leftToBuy()) + " {ERR}left for sale.");
- // Display count as [(x)]
- return ("{}Buy: {BKT}[{PRM}" + formatBundleCount(numBundles) + "{BKT}]{} for {PRM}" + getBuyPrice(numBundles) + " " + iConomy.currency);
- //TODO: Abstract currency name from iConomy reference.
- }
-
- public String infoStringSell(int numBundles)
- {
- if (!isValid())
- return ("{ERR}Invalid or uninitialized item.");
- if (!canSell)
- return ("{PRM}"+getName() + "{ERR} is unavailable for purchase.");
- if (!getCanSell(1))
- return ("{PRM}"+getName() + "{ERR} is overstocked: no more can be sold right now.");
- if (!getCanSell(numBundles))
- return ("{PRM}"+getName() + "{ERR} is overstocked, only {PRM}" + formatBundleCount(leftToSell()) + " {ERR}can be sold.");
- // Display count as [(x)]
- return ("{}Sell: {BKT}[{PRM}" + formatBundleCount(numBundles) + "{BKT}]{} for {PRM}" + getSellPrice(numBundles) + " " + iConomy.currency);
- //TODO: Abstract currency name from iConomy reference.
- }
-
- public int leftToBuy()
- {
- return (stock - stockLowest);
- }
-
- public int leftToSell()
- {
- return (stockHighest - stock);
- }
-
- public String infoStringBuy()
- {
- return infoStringBuy(1);
- }
-
- public String infoStringSell()
- {
- return infoStringSell(1);
- }
-
- public boolean getCanBuy(int numBundles)
- {
- // Report if the requested number of bundles can be bought.
- if (canBuy == false)
- return false;
- if ((stock - numBundles) < stockLowest)
- return false;
- return true;
- }
-
- public boolean getCanSell(int numBundles)
- {
- // Report if the requested number of bundles can be sold.
- if (canSell == false)
- return false;
- if ((stock + numBundles) > stockHighest)
- return false;
- return true;
- }
-
- public String infoStringShort()
- {
- return("{BKT}[{}" + itemId + (subType != 0? ","+subType : "") + "{BKT}]{} " + getName() + "{BKT}[{}" + count + "{BKT}]{} Buy:{BKT}[{}" + (getCanBuy(1)? getBuyPrice(1) : "-") + "{BKT}]{} Sell:{BKT}[{}" + (getCanSell(1)? getSellPrice(1) : "-") + "{BKT}]");
- }
-
- public ArrayList infoStringFull()
- {
- // More detailed info, more useful to shop admins.
- // Switch to select line number?
- ArrayList returnList = new ArrayList();
- returnList.add("{}ID:{BKT}[{PRM}" + itemId + (subType != 0? ","+subType : "") + "{BKT}]{} Name:{PRM}" + getName() + "{} BundleSize:{BKT}[{PRM}" + count + "{BKT}]");
- returnList.add("{}BasePrice:{BKT}[{PRM}" + basePrice + "{BKT}]{} SalesTax:{BKT}[{PRM}" + salesTax + "{BKT}]{} Vol:{BKT}[{PRM}" + volatility + "{BKT}]{} IVol:{BKT}[{PRM}" + getInverseVolatility() + "{BKT}]");
- returnList.add("{}Stock:{BKT}[{PRM}" + stock + "{BKT}]{} CanBuy:{BKT}[{PRM}" + (getCanBuy(1)? getBuyPrice(1) : "-") + "{BKT}]{} CanSell:{BKT}[{PRM}" + (getCanSell(1)? getSellPrice(1) : "-") + "{BKT}]");
- returnList.add("{}StockLowest:{BKT}[{PRM}" + intFormat(stockLowest) + "{BKT}]{} StockHighest:{BKT}[{PRM}" + intFormat(stockHighest) + "{BKT}]");
- returnList.add("{}StockFloor:{BKT}[{PRM}" + intFormat(stockFloor) + "{BKT}]{} StockCeiling:{BKT}[{PRM}" + intFormat(stockCeil) + "{BKT}]");
- returnList.add("{}PriceFloor:{BKT}[{PRM}" + intFormat(priceFloor) + "{BKT}]{} PriceCeiling:{BKT}[{PRM}" + intFormat(priceCeil) + "{BKT}]");
- return returnList;
-
- /*
- return("&d[&f" + itemId + (subType != 0? ","+subType : "") + "&d]&f " + getName() + "&d[&f" + count + "&d]&f " +
- "bp:&d[&f" + basePrice + "&d]&f st:&d[&f" + salesTax + "&d]&f v:&d[&f" + volatility + "&d]&f " +
- "iv:&d[&f" + getInverseVolatility() + "&d]&f s:&d[&f" + stock + "&d]&f " +
- "cb:&d[&f" + (getCanBuy(1)? getBuyPrice(1) : "-") + "&d]&f cs:&d[&f" + (getCanSell(1)? getSellPrice(1) : "-") + "&d]&f " +
- "sl:&d[&f" + intFormat(stockLowest) + "&d]&f sh:&d[&f" + intFormat(stockHighest) + "&d]&f " +
- "sf:&d[&f" + intFormat(stockFloor) + "&d]&f sc:&d[&f" + intFormat(stockCeil) + "&d]&f " +
- "pf:&d[&f" + intFormat(priceFloor) + "&d]&f pc:&d[&f" + intFormat(priceCeil) + "&d]");
- */
- }
-
- public String intFormat(int thisInt)
- {
- // Returns the string value of an int, with Integer.MAX_VALUE and Integer.MIN_VALUE converted to shorthand.
- if (thisInt == Integer.MAX_VALUE)
- return "+INF";
- if (thisInt == Integer.MIN_VALUE)
- return "-INF";
- return Integer.toString(thisInt);
- }
-
- public String csvLine()
- {
- // Spits out a line corresponding to a line in a .csv file.
- return (itemId + "," + subType + "," + count + "," + name + "," + basePrice + "," + stock + "," + (canBuy? "Y" : "N") + "," + (canSell? "Y" : "N") + "," + volatility + "," + salesTax + "," + intFormat(stockLowest) + "," + intFormat(stockHighest) + "," + intFormat(stockFloor) + "," + intFormat(stockCeil) + "," + intFormat(priceFloor) + "," + intFormat(priceCeil) + "," + jitterPerc + "," + driftOut + "," + driftIn + "," + avgStock + "," + itemClass);
- }
-
- public static String csvHeaderLine()
- {
- // Spits out an appropriate header line for the output spreadsheet.
- return ("itemId,subType,count,name,basePrice,stock,canBuy,canSell,volatility,salesTax,stockLowest,stockHighest,stockFloor,stockCeil,priceFloor,priceCeil,jitterPerc,driftOut,driftIn,avgStock,itemClass");
- }
-
- private int quickParse(String intString)
- {
- // Parses strings into ints, throwing away errors and replacing them with 0s.
- if (intString.equalsIgnoreCase("-inf"))
- return Integer.MIN_VALUE;
- if (intString.equalsIgnoreCase("+inf"))
- return Integer.MAX_VALUE;
- try
- {
- return Integer.parseInt(intString);
- }
- catch (NumberFormatException ex)
- {
- return 0;
- }
- }
-
- public MarketItem(String csvString, MarketItem defaults, String shopLabel, boolean isCSV)
- {
- super();
-
- if (defaults != null)
- {
- this.itemId = defaults.itemId;
- this.subType = defaults.subType;
- this.count = defaults.count;
- this.basePrice = defaults.basePrice;
- this.stock = defaults.stock;
- this.canBuy = defaults.canBuy;
- this.canSell = defaults.canSell;
- this.volatility = defaults.volatility;
- this.salesTax = defaults.salesTax;
- this.stockLowest = defaults.stockLowest;
- this.stockHighest = defaults.stockHighest;
- this.stockFloor = defaults.stockFloor;
- this.stockCeil = defaults.stockCeil;
- this.priceFloor = defaults.priceFloor;
- this.priceCeil = defaults.priceCeil;
- this.jitterPerc = defaults.jitterPerc;
- this.driftOut = defaults.driftOut;
- this.driftIn = defaults.driftIn;
- this.avgStock = defaults.avgStock;
- this.itemClass = defaults.itemClass;
- }
- else
- setBaseDefaults();
-
- String[] inputParams = csvString.split(",");
-
- if (inputParams.length < 21)
- {
- return;
- }
-
- if (!inputParams[0].isEmpty())
- itemId = quickParse(inputParams[0]);
- if (!inputParams[1].isEmpty())
- subType = quickParse(inputParams[1]);
- if (!inputParams[2].isEmpty())
- count = quickParse(inputParams[2]);
- if (!inputParams[3].isEmpty())
- name = inputParams[3];
- if (!inputParams[4].isEmpty())
- basePrice = quickParse(inputParams[4]);
- if (!inputParams[5].isEmpty())
- stock = quickParse(inputParams[5]);
- if (!inputParams[6].isEmpty())
- canBuy = inputParams[6].equalsIgnoreCase("Y");
- if (!inputParams[7].isEmpty())
- canSell = inputParams[7].equalsIgnoreCase("Y");
- if (!inputParams[8].isEmpty())
- volatility = quickParse(inputParams[8]);
- if (!inputParams[9].isEmpty())
- salesTax = quickParse(inputParams[9]);
- if (!inputParams[10].isEmpty())
- stockLowest = quickParse(inputParams[10]);
- if (!inputParams[11].isEmpty())
- stockHighest = quickParse(inputParams[11]);
- if (!inputParams[12].isEmpty())
- stockFloor = quickParse(inputParams[12]);
- if (!inputParams[13].isEmpty())
- stockCeil = quickParse(inputParams[13]);
- if (!inputParams[14].isEmpty())
- priceFloor = quickParse(inputParams[14]);
- if (!inputParams[15].isEmpty())
- priceCeil = quickParse(inputParams[15]);
- if (!inputParams[16].isEmpty())
- jitterPerc = quickParse(inputParams[16]);
- if (!inputParams[17].isEmpty())
- driftOut = quickParse(inputParams[17]);
- if (!inputParams[18].isEmpty())
- driftIn = quickParse(inputParams[18]);
- if (!inputParams[19].isEmpty())
- avgStock = quickParse(inputParams[19]);
- if (!inputParams[20].isEmpty())
- itemClass = quickParse(inputParams[20]);
- this.shopLabel = shopLabel;
- sanityCheck();
- }
-
- public void setEmptyMask()
- {
- // Wipes all fields to prepare this MarketItem to be used as a data mask.
- this.name = null;
- this.basePrice = 0;
- this.stock = 0;
- this.canBuy = false;
- this.canSell = false;
- this.volatility = 0;
- this.salesTax = 0;
- this.stockLowest = 0;
- this.stockHighest = 0;
- this.stockFloor = 0;
- this.stockCeil = 0;
- this.priceFloor = 0;
- this.priceCeil = 0;
- this.jitterPerc = 0;
- this.driftOut = 0;
- this.driftIn = 0;
- this.avgStock = 0;
- this.itemClass = 0;
- this.shopLabel = null;
- }
-
- /*
- public void copyMasked(MarketItem data, MarketItem mask)
- {
- // Copies in the fields from data, for only the fields set non-zero/non-null/true in mask.
- if (mask.name != null) this.name = data.name;
- if (mask.basePrice != 0) this.basePrice = data.basePrice;
- if (mask.stock != 0) this.stock = data.stock;
- if (mask.canBuy) this.canBuy = data.canBuy;
- if (mask.canSell) this.canSell = data.canSell;
- if (mask.volatility != 0) this.volatility = data.volatility;
- if (mask.salesTax != 0) this.salesTax = data.salesTax;
- if (mask.stockLowest != 0) this.stockLowest = data.stockLowest;
- if (mask.stockHighest != 0) this.stockHighest = data.stockHighest;
- if (mask.stockFloor != 0) this.stockFloor = data.stockFloor;
- if (mask.stockCeil != 0) this.stockCeil = data.stockCeil;
- if (mask.priceFloor != 0) this.priceFloor = data.priceFloor;
- if (mask.priceCeil != 0) this.priceCeil = data.priceCeil;
- if (mask.jitterPerc != 0) this.jitterPerc = data.jitterPerc;
- if (mask.driftOut != 0) this.driftOut = data.driftOut;
- if (mask.driftIn != 0) this.driftIn = data.driftIn;
- if (mask.avgStock != 0) this.avgStock = data.avgStock;
- if (mask.itemClass != 0) this.itemClass = data.itemClass;
- if (mask.shopLabel != null) this.shopLabel = data.shopLabel;
- }
- */
+ private String name; // n | name // name used for item
+ public int basePrice; // bp // base purchase price of item
+ public int stock; // s // current stock level of item
+ public boolean canBuy; // cb // true if can be purchased, false if not
+ public boolean canSell; // cs // true if can be sold, false if not
+ private int volatility; // v // % change in price per 1 stock bought/sold, * intScale
+ // iv // inverse volatility; units bought/sold per doubling/halving of price
+ public int salesTax; // st // basePrice * (1 - (salesTax/100)) = selling price
+ public int stockLowest; // sl // minimum stock at which purchases will fail (hard limit)
+ public int stockHighest; // sh // maximum stock at which sales will fail (hard limit)
+ public int stockFloor; // sf // minimum stock level possible (soft limit)
+ public int stockCeil; // sc // maximum stock level possible (soft limit)
+ public int priceFloor; // pf // minimum price <- applies to basePrice, without salesTax
+ public int priceCeil; // pc // maximum price
+ public int jitterPerc;
+ public int driftOut;
+ public int driftIn;
+ public int avgStock;
+ public int itemClass;
+ public String shopLabel = ""; // Shop DB table this is a member of.
+ // Other input tags:
+ // fixed // stock = 0
+ // stockLowest = Integer.MIN_VALUE
+ // stockHighest = Integer.MAX_VALUE
+ // stockFloor = 0
+ // stockCeil = 0
+ // buyok // canBuy = 1
+ // sellok // canSell = 1
+ // !nobuy // canBuy = 1
+ // !nosell // canSell = 1
+ // !buyok // canBuy = 0
+ // !sellok // canSell = 0
+ // nobuy // canBuy = 0
+ // nosell // canSell = 0
+ public static int intScale = 10000; // Scale factor used in integerization of calculations.
+ public DatabaseMarket thisDatabase = null; // Database object this item is a member of.
+
+ /* diamond: 10 items -> 10% price change, 1 item -> 1% price change, 0.01 * 10000 = 1000
+ *
+ * cobble: 640 items -> 10% price change, 1 item -> 0.016% price change, 0.00016 * 10000 = 16
+ *
+ * ?inelastic?: v=1 -> 0.001% price change, 1000 items -> 1% price change
+ *
+ * ?elastic?: v=10000, 1 item -> +100% | -50% price change
+ *
+ * volatility: % change in price per unit bought/sold, * intScale / 100 (2% per item = 2 * intScale / 100)
+ * inverse volatility: units bought/sold per doubling/halving of price
+ *
+ * ivol = ln(2) / ln(1+(vol/intScale))
+ * vol = (2^(1/iVol)-1) * intScale
+ *
+ */
+ public MarketItem(String thisShopLabel) {
+ // Default constructor with no parameters.
+ super();
+ setBaseDefaults();
+ shopLabel = thisShopLabel;
+ }
+
+ public MarketItem() {
+ // Default constructor with no parameters.
+ super();
+ setBaseDefaults();
+ }
+
+ public MarketItem(String initString, MarketItem defaults, DatabaseMarket thisDB, String thisShopLabel) {
+ // Valid input string formats:
+ // "[ID(,Type)](:Count) (buyprice (sellPrice)) (field:val (field:val (...)))"
+ // "[ItemName](:Count) (buyprice (sellPrice)) (field:val (field:val (...)))"
+ //TODO: Add alternate input format for setting low/high ranges with a single tag.
+
+ super(initString.split(" ", 2)[0], thisDB, thisShopLabel); // Parse id/name, type, and count from first split.
+
+ thisDatabase = thisDB;
+ shopLabel = thisShopLabel;
+
+ // SimpleMarket.log.info("[1] InitString: [" + initString + "]");
+
+ String[] initData = initString.split(" ");
+
+ // If 0th tag (name) does not contain ":", use count from defaults.
+ if (!initData[0].contains(":")) {
+ this.count = defaults.count;
+ }
+
+ // Load defaults, if available.
+ if (defaults != null) {
+ this.basePrice = Math.round((float) defaults.basePrice * this.count / defaults.count);
+ this.stock = Math.round(((float) defaults.stock * defaults.count / this.count) - 0.5f);
+ this.canBuy = defaults.canBuy;
+ this.canSell = defaults.canSell;
+ this.volatility = defaults.volatility;
+ this.salesTax = defaults.salesTax;
+ this.stockLowest = defaults.stockLowest;
+ this.stockHighest = defaults.stockHighest;
+ this.stockFloor = defaults.stockFloor;
+ this.stockCeil = defaults.stockCeil;
+ this.priceFloor = defaults.priceFloor;
+ this.priceCeil = defaults.priceCeil;
+ } else {
+ setBaseDefaults();
+ }
+
+ // Load data from remaining items in split.
+ //If first one or two items have no tag, assume they are the basePrice and the sellPrice.
+
+ parseTags(initData);
+
+ sanityCheck();
+ }
+
+ private void parseTags(String initData[]) {
+ // Load data from a list of tags.
+ // Element [0] is ignored.
+ String curTag;
+ Integer curVal;
+ String stringVal;
+ String[] curParams;
+ boolean setUntaggedBase = false;
+
+ if (initData.length > 1) {
+ for (int i = 1; i <= initData.length - 1; i++) {
+ stringVal = null;
+ // Get current tag and value
+
+ if (initData[i].contains(":")) {
+ curParams = initData[i].split(":");
+ curTag = curParams[0];
+ try {
+ curVal = Integer.parseInt(curParams[1]);
+ } catch (NumberFormatException ex) {
+ if (curParams[1].equalsIgnoreCase("+INF")) {
+ curVal = Integer.MAX_VALUE;
+ } else if (curParams[1].equalsIgnoreCase("-INF")) {
+ curVal = Integer.MIN_VALUE;
+ } else {
+ curVal = null;
+ stringVal = curParams[1];
+ }
+ }
+ } else {
+ try { // Try to parse it as a plain integer.
+ curTag = null;
+ curVal = Integer.parseInt(initData[i]);
+ } catch (NumberFormatException ex) { // Didn't work? Just use it as a string.
+ curVal = null;
+ curTag = initData[i];
+ }
+ }
+
+ // If first param is an untagged value, make it the basePrice.
+ if (i == 1) {
+ if (curTag == null) {
+ if (curVal != -1) {
+ this.basePrice = curVal;
+ // maskData.basePrice = 1;
+ } else {
+ // Base price set to -1. Disable buying.
+ this.basePrice = 0;
+ // maskData.basePrice = 1;
+ this.canBuy = false;
+ }
+ setUntaggedBase = true;
+ continue;
+ }
+ }
+
+ // If second param is an untagged value, make the sellPrice equal to it after sales tax is applied.
+ if (i == 2) {
+ if ((setUntaggedBase) && (curTag == null)) {
+ if (curVal != -1) {
+ // if salePrice = basePrice * (1 - (salesTax / 100))
+ // then (1 - (salePrice / basePrice)) * 100 = salesTax
+ if (this.basePrice != 0) {
+ this.salesTax = Math.round((1 - ((float) curVal / basePrice)) * 100);
+ // maskData.salesTax = 1;
+ } else {
+ this.basePrice = curVal;
+ this.salesTax = 0;
+ // maskData.salesTax = 1;
+ }
+ } else {
+ // Sale price set to -1. Disable selling.
+ this.canSell = false;
+ }
+ continue;
+ }
+ }
+
+ // Handle remaining items in split.
+
+ if (curTag != null) {
+ if (curVal != null) {
+ if (curTag.equalsIgnoreCase("bp")
+ || curTag.equalsIgnoreCase("baseprice")) {
+ this.basePrice = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("s")
+ || curTag.equalsIgnoreCase("stock")) {
+ this.stock = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("v")
+ || curTag.equalsIgnoreCase("volatility")
+ || curTag.equalsIgnoreCase("vol")) {
+ this.setVolatility(curVal);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("iv")
+ || curTag.equalsIgnoreCase("invvolatility")
+ || curTag.equalsIgnoreCase("ivol")) {
+ this.setInverseVolatility(curVal);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("st")
+ || curTag.equalsIgnoreCase("salestax")) {
+ this.salesTax = rangeCrop(curVal, 0, 100);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sl")
+ || curTag.equalsIgnoreCase("stocklowest")) {
+ this.stockLowest = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sh")
+ || curTag.equalsIgnoreCase("stockhighest")) {
+ this.stockHighest = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sf")
+ || curTag.equalsIgnoreCase("stockfloor")) {
+ this.stockFloor = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("sc")
+ || curTag.equalsIgnoreCase("stockceiling")) {
+ this.stockCeil = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("pf")
+ || curTag.equalsIgnoreCase("pricefloor")) {
+ this.priceFloor = curVal;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("pc")
+ || curTag.equalsIgnoreCase("priceceiling")) {
+ this.priceCeil = curVal;
+ continue;
+ }
+ }
+ }
+ if (curTag.equalsIgnoreCase("flat")) {
+ this.stock = 0;
+ this.stockLowest = Integer.MIN_VALUE;
+ this.stockHighest = Integer.MAX_VALUE;
+ this.stockFloor = Integer.MIN_VALUE;
+ this.stockCeil = Integer.MAX_VALUE;
+ this.priceFloor = 0;
+ this.priceCeil = Integer.MAX_VALUE;
+ this.volatility = 0;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("fixed")) {
+ this.stock = 0;
+ this.stockLowest = Integer.MIN_VALUE;
+ this.stockHighest = Integer.MAX_VALUE;
+ this.stockFloor = 0;
+ this.stockCeil = 0;
+ this.priceFloor = 0;
+ this.priceCeil = Integer.MAX_VALUE;
+ this.volatility = 0;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("float")) {
+ this.stockFloor = Integer.MIN_VALUE;
+ this.stockCeil = Integer.MAX_VALUE;
+ this.stockLowest = Integer.MIN_VALUE;
+ this.stockHighest = Integer.MAX_VALUE;
+ this.priceFloor = 0;
+ this.priceCeil = Integer.MAX_VALUE;
+ if (this.volatility == 0) {
+ this.volatility = 100;
+ }
+ }
+ if (curTag.equalsIgnoreCase("finite")) {
+ this.stockFloor = Integer.MIN_VALUE;
+ this.stockCeil = Integer.MAX_VALUE;
+ this.stockLowest = 0;
+ this.stockHighest = Integer.MAX_VALUE;
+ }
+ if ((curTag.equalsIgnoreCase("buyok"))
+ || (curTag.equalsIgnoreCase("!nobuy"))) {
+ this.canBuy = true;
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("sellok"))
+ || (curTag.equalsIgnoreCase("!nosell"))) {
+ this.canSell = true;
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("!buyok"))
+ || (curTag.equalsIgnoreCase("nobuy"))
+ || (curTag.equalsIgnoreCase("!cb"))) {
+ this.canBuy = false;
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("!sellok"))
+ || (curTag.equalsIgnoreCase("nosell"))
+ || (curTag.equalsIgnoreCase("!cs"))) {
+ this.canSell = false;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("cb")
+ || curTag.equalsIgnoreCase("canbuy")) {
+ if ((stringVal != null) && (!(stringVal.isEmpty()))) {
+ this.canBuy = ((stringVal.toLowerCase().startsWith("y")) || (stringVal
+ .toLowerCase().startsWith("t")));
+ } else
+ this.canBuy = true;
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("cs")
+ || curTag.equalsIgnoreCase("cansell")) {
+ if ((stringVal != null) && (!(stringVal.isEmpty()))) {
+ this.canSell = ((stringVal.toLowerCase()
+ .startsWith("y")) || (stringVal.toLowerCase()
+ .startsWith("t")));
+ } else
+ this.canSell = true;
+ continue;
+ }
+ if ((curTag.equalsIgnoreCase("name"))
+ || (curTag.equalsIgnoreCase("n"))) {
+ setName(stringVal);
+ continue;
+ }
+ if (curTag.equalsIgnoreCase("renorm")) {
+ // double oldBuyPrice = getStockPrice(this.stock);
+ int newStock;
+ if (curVal == null) {
+ newStock = 0;
+ } else {
+ newStock = curVal;
+ }
+ this.basePrice = getRenormedPrice(newStock);
+ this.stock = newStock;
+ // basePrice = inverse of stockPrice = rangeCrop(this.basePrice * Math.pow(getVolFactor(), -rangeCrop(stockLevel, stockFloor, stockCeil)), priceFloor, priceCeil)
+ /*
+ * oldstockPrice = this.basePrice * (getVolFactor() ^ -stockLevel)
+ * oldstockPrice / (getVolFactor() ^ -stockLevel) = basePrice
+ */
+ //this.basePrice = (int)Math.round(oldBuyPrice / Math.pow(getVolFactor(), -rangeCrop(this.stock, stockFloor, stockCeil)));
+ }
+ }
+ // TODO: Log and report invalid tags somehow.
+ }
+ }
+
+ public int getRenormedPrice(int newStock) {
+ // Calculate what the renormalized base price would be when shifting from the current stock level to newStock.
+ double oldBuyPrice = getStockPrice(this.stock);
+ return (int) Math.round(oldBuyPrice / Math.pow(getVolFactor(), -rangeCrop(newStock, stockFloor, stockCeil)));
+ }
+
+ public MarketItem(SQLHandler myQuery) {
+ // Initialize a new MarketItem from an SQLHandler ResultSet.
+ super();
+ // thisDatabase.plugin.log.info("Creating from SQL...");
+ this.itemId = myQuery.getInt("item");
+ this.subType = myQuery.getInt("subtype");
+ this.name = myQuery.getString("name");
+ this.count = myQuery.getInt("count");
+ this.basePrice = myQuery.getInt("baseprice");
+ this.canBuy = (myQuery.getInt("canbuy") == 1);
+ this.canSell = (myQuery.getInt("cansell") == 1);
+ this.stock = myQuery.getInt("stock");
+ this.volatility = myQuery.getInt("volatility");
+ this.salesTax = myQuery.getInt("salestax");
+ this.stockHighest = myQuery.getInt("stockhighest");
+ this.stockLowest = myQuery.getInt("stocklowest");
+ this.stockFloor = myQuery.getInt("stockfloor");
+ this.stockCeil = myQuery.getInt("stockceil");
+ this.priceFloor = myQuery.getInt("pricefloor");
+ this.priceCeil = myQuery.getInt("priceceil");
+ this.shopLabel = myQuery.getString("shoplabel");
+ sanityCheck();
+ }
+
+ private void sanityCheck() {
+ // Check and fix possible chaos-inducing data.
+ // Mirrors DatabaseMarket.sanityCheckAll.
+
+ this.salesTax = rangeCrop(this.salesTax, 0, 100);
+
+ if (this.stockHighest < this.stock)
+ this.stockHighest = this.stock;
+
+ if (this.stockLowest > this.stock)
+ this.stockLowest = this.stock;
+
+ if (this.stockCeil < this.stock)
+ this.stockCeil = this.stock;
+
+ if (this.stockFloor > this.stock)
+ this.stockFloor = this.stock;
+
+ if (this.priceCeil < this.priceFloor)
+ this.priceCeil = this.priceFloor;
+
+ this.basePrice = Math.max(0, this.basePrice);
+ }
+
+ private void setBaseDefaults() {
+ name = null;
+ basePrice = 0;
+ stock = 0;
+ canBuy = true;
+ canSell = true;
+ volatility = 1;
+ salesTax = 0;
+ stockLowest = Integer.MIN_VALUE;
+ stockHighest = Integer.MAX_VALUE;
+ stockFloor = 0;
+ stockCeil = 0;
+ priceFloor = 0;
+ priceCeil = Integer.MAX_VALUE;
+ }
+
+ // public int sellPrice()
+ // {
+ // return (rangeCrop(Math.round(basePrice * (1 - (salesTax / 100))), priceFloor, priceCeil));
+ // }
+
+ public static int rangeCrop(int value, int minVal, int maxVal) {
+ return (Math.min(Math.max(value, minVal), maxVal));
+ }
+
+ public static double rangeCrop(double value, double minVal, double maxVal) {
+ return (Math.min(Math.max(value, minVal), maxVal));
+ }
+
+ public String getName() {
+ if ((this.name == null) || (this.name.isEmpty())) {
+ this.name = super.getName(thisDatabase, shopLabel);
+ }
+ return this.name;
+ }
+
+ public void setName(String newName) {
+ if ((newName != null) && (!(newName.isEmpty()))) {
+ this.name = newName;
+ } else {
+ this.name = super.getName(thisDatabase, shopLabel);
+ }
+ }
+
+ public double getBatchPrice(int startStock, int endStock) {
+ // Gets the current base price for the items at stock levels from startStock to endStock.
+ // NOTE: Does not check stockLowest/stockHighest transaction limits.
+
+ int lowStock = Math.min(startStock, endStock);
+ int highStock = Math.max(startStock, endStock);
+ int numTerms = highStock - lowStock + 1;
+ double lowStockPrice;
+ double highStockPrice;
+ int fixedStockLimit;
+
+ // End calculation if volatility == 0. Price does not change, so all items are the same value.
+ if (volatility == 0)
+ return (numTerms * getStockPrice(stock));
+
+ // End calculation if highStock <= stockFloor (All below floor)
+ if (highStock <= stockFloor)
+ return (numTerms * getStockPrice(stockFloor));
+
+ // End calculation if lowStock >= stockCeil (All above ceiling)
+ if (lowStock >= stockCeil)
+ return (numTerms * getStockPrice(stockCeil));
+
+ // Split calculation if stockFloor reached by lowStock (Some below floor)
+ if (lowStock < stockFloor)
+ return (((stockFloor - lowStock + 1) * getStockPrice(stockFloor)) + getBatchPrice(stockFloor + 1, highStock));
+
+ // Split calculation if stockCeil reached by highStock (Some above ceiling)
+ if (highStock > stockCeil)
+ return (((highStock - stockCeil + 1) * getStockPrice(stockCeil)) + getBatchPrice(lowStock, stockCeil - 1));
+
+ lowStockPrice = getStockPrice(lowStock); // highest price in range
+ highStockPrice = getStockPrice(highStock); // lowest price in range
+
+ // WARNING in this section: Highest stock level corresponds to lowest price,
+ // and lowest stock level corresponds to highest price.
+
+ // End calculation if lowStockPrice <= priceFloor (All below floor)
+ if (lowStockPrice <= priceFloor)
+ return (numTerms * priceFloor);
+
+ // End calculation if highStockPrice >= priceCeil (All above ceiling)
+ if (highStockPrice >= priceCeil)
+ return (numTerms * priceCeil);
+
+ // Split calculation if highStockPrice < priceFloor (Some below floor)
+ if (highStockPrice < priceFloor) {
+ fixedStockLimit = (int) Math.round(Math.floor(stockAtPrice(priceFloor)));
+ return (((highStock - fixedStockLimit + 1) * priceFloor) + getBatchPrice(lowStock, fixedStockLimit - 1));
+ }
+
+ // Split calculation if lowStockPrice > priceCeil (Some above ceiling)
+ if (lowStockPrice > priceCeil) {
+ fixedStockLimit = (int) Math.round(Math.ceil(stockAtPrice(priceCeil)));
+ return (((fixedStockLimit - lowStock + 1) * priceCeil) + getBatchPrice(fixedStockLimit + 1, highStock));
+ }
+
+
+ // All range limits handled? Find the sum of terms of a finite geometric series.
+ //return Math.round(this.basePrice * Math.pow(getVolFactor(),-lowStock) * (Math.pow(getVolFactor(),numTerms) - 1) / (getVolFactor()-1));
+ // return math.round(firstTerm * (1 - (ratio ^ terms)) / (1 - ratio));
+ return Math.round(lowStockPrice * (1 - (Math.pow(1 / getVolFactor(), numTerms))) / (1 - (1 / getVolFactor())));
+ }
+
+ public int getBuyPrice(int numBundles) {
+ // Return the purchase price of the given number of bundles.
+ return (int) Math.round(Math.ceil(getBatchPrice(stock, stock - numBundles + 1)));
+ }
+
+ public int getSellPrice(int numBundles) {
+ // Return the selling price of the given number of bundles.
+ return (int) Math.round(Math.floor(deductTax(getBatchPrice(stock, stock + numBundles - 1))));
+ }
+
+ private double deductTax(double basePrice) {
+ // Returns the given price minus the sales tax.
+ return (basePrice * (1 - ((double) salesTax / 100)));
+ }
+
+ private double getStockPrice(int stockLevel) {
+ // Crops result to stockFloor/stockCeil/priceFloor/priceCeil.
+ return rangeCrop(this.basePrice * Math.pow(getVolFactor(), -rangeCrop(stockLevel, stockFloor, stockCeil)), priceFloor, priceCeil);
+ }
+
+ public int getVolatility() {
+ return this.volatility;
+ }
+
+ public double getVolFactor() {
+ return (1 + (double) volatility / intScale);
+ }
+
+ public void setVolatility(int newVol) {
+ this.volatility = rangeCrop(newVol, 0, intScale);
+ }
+
+ public void setVolatility(double newVol) {
+ setVolatility((int) Math.round(newVol));
+ }
+
+ public int getInverseVolatility() {
+ if (volatility == 0) {
+ return Integer.MAX_VALUE;
+ } else {
+ return (int) Math.round(Math.log(2) / Math.log(getVolFactor()));
+ }
+ }
+
+ public void setInverseVolatility(int newIVol) {
+ // if (newIVol == Integer.MAX_VALUE)
+ // setVolatility(0);
+ // else
+ // setVolatility((Math.pow(2,(1/(double)newIVol))-1) * intScale);
+ setVolatility(iVolToVol(newIVol));
+ }
+
+ public static int iVolToVol(int invVol) {
+ // Converts inverse volatility to volatility.
+ if (invVol == Integer.MAX_VALUE) {
+ return 0;
+ } else {
+ return (int) Math.round((Math.pow(2, (1 / (double) invVol)) - 1) * intScale);
+ }
+ }
+
+ private double stockAtPrice(int targPrice) {
+ // Returns the stock level at which price == targPrice.
+ if (volatility == 0) {
+ // If price doesn't change, the stock level is effectively +/-INF.
+ if (targPrice > basePrice)
+ return Integer.MIN_VALUE;
+ if (targPrice < basePrice)
+ return Integer.MAX_VALUE;
+ // targPrice == basePrice
+ return stock;
+ }
+ return -(Math.log((double) targPrice / basePrice) / Math.log(getVolFactor()));
+ }
+
+ public String formatBundleCount(int numBundles) {
+ if (numBundles == 1)
+ return (Integer.toString(count));
+ if (count == 1)
+ return (Integer.toString(numBundles));
+ return (Integer.toString(count) + "x" + Integer.toString(numBundles));
+ }
+
+ public String infoStringBuy(int numBundles) {
+ if (!isValid())
+ return ("{ERR}Invalid or uninitialized item.");
+ if (!canBuy)
+ return ("{PRM}" + getName() + "{ERR} is unavailable for purchase.");
+ if (!getCanBuy(1))
+ return ("{PRM}" + getName() + "{ERR} is out of stock: no more can be bought right now.");
+ if (!getCanBuy(numBundles))
+ return ("{PRM}" + getName() + "{ERR} has only {PRM}"
+ + formatBundleCount(leftToBuy()) + " {ERR}left for sale.");
+ // Display count as [(x)]
+ return ("{}Buy: {BKT}[{PRM}" + formatBundleCount(numBundles) + "{BKT}]{} for {PRM}" + iConomy.getBank().format(getBuyPrice(numBundles)));
+ // TODO: Abstract currency name from iConomy reference.
+ }
+
+ public String infoStringSell(int numBundles) {
+ if (!isValid())
+ return ("{ERR}Invalid or uninitialized item.");
+ if (!canSell)
+ return ("{PRM}" + getName() + "{ERR} is unavailable for purchase.");
+ if (!getCanSell(1))
+ return ("{PRM}" + getName() + "{ERR} is overstocked: no more can be sold right now.");
+ if (!getCanSell(numBundles))
+ return ("{PRM}" + getName() + "{ERR} is overstocked, only {PRM}"
+ + formatBundleCount(leftToSell()) + " {ERR}can be sold.");
+ // Display count as [(x)]
+ return ("{}Sell: {BKT}[{PRM}" + formatBundleCount(numBundles)
+ + "{BKT}]{} for {PRM}" + getSellPrice(numBundles) + " " + iConomy
+ .getBank().getCurrency());
+ // TODO: Abstract currency name from iConomy reference.
+ }
+
+ public int leftToBuy() {
+ return (stock - stockLowest);
+ }
+
+ public int leftToSell() {
+ return (stockHighest - stock);
+ }
+
+ public String infoStringBuy() {
+ return infoStringBuy(1);
+ }
+
+ public String infoStringSell() {
+ return infoStringSell(1);
+ }
+
+ public boolean getCanBuy(int numBundles) {
+ // Report if the requested number of bundles can be bought.
+ if (canBuy == false)
+ return false;
+ if ((stock - numBundles) < stockLowest)
+ return false;
+ return true;
+ }
+
+ public boolean getCanSell(int numBundles) {
+ // Report if the requested number of bundles can be sold.
+ if (canSell == false)
+ return false;
+ if ((stock + numBundles) > stockHighest)
+ return false;
+ return true;
+ }
+
+ public String infoStringShort() {
+ return ("{BKT}[{}" + itemId + (subType != 0 ? "," + subType : "")
+ + "{BKT}]{} " + getName() + "{BKT}[{}" + count
+ + "{BKT}]{} Buy:{BKT}[{}"
+ + (getCanBuy(1) ? getBuyPrice(1) : "-")
+ + "{BKT}]{} Sell:{BKT}[{}"
+ + (getCanSell(1) ? getSellPrice(1) : "-") + "{BKT}]");
+ }
+
+ public ArrayList infoStringFull() {
+ // More detailed info, more useful to shop admins.
+ // Switch to select line number?
+ ArrayList returnList = new ArrayList();
+ returnList.add("{}ID:{BKT}[{PRM}" + itemId
+ + (subType != 0 ? "," + subType : "") + "{BKT}]{} Name:{PRM}"
+ + getName() + "{} BundleSize:{BKT}[{PRM}" + count + "{BKT}]");
+ returnList.add("{}BasePrice:{BKT}[{PRM}" + basePrice
+ + "{BKT}]{} SalesTax:{BKT}[{PRM}" + salesTax
+ + "{BKT}]{} Vol:{BKT}[{PRM}" + volatility
+ + "{BKT}]{} IVol:{BKT}[{PRM}" + getInverseVolatility()
+ + "{BKT}]");
+ returnList.add("{}Stock:{BKT}[{PRM}" + stock
+ + "{BKT}]{} CanBuy:{BKT}[{PRM}"
+ + (getCanBuy(1) ? getBuyPrice(1) : "-")
+ + "{BKT}]{} CanSell:{BKT}[{PRM}"
+ + (getCanSell(1) ? getSellPrice(1) : "-") + "{BKT}]");
+ returnList.add("{}StockLowest:{BKT}[{PRM}" + intFormat(stockLowest)
+ + "{BKT}]{} StockHighest:{BKT}[{PRM}" + intFormat(stockHighest)
+ + "{BKT}]");
+ returnList.add("{}StockFloor:{BKT}[{PRM}" + intFormat(stockFloor)
+ + "{BKT}]{} StockCeiling:{BKT}[{PRM}" + intFormat(stockCeil)
+ + "{BKT}]");
+ returnList.add("{}PriceFloor:{BKT}[{PRM}" + intFormat(priceFloor)
+ + "{BKT}]{} PriceCeiling:{BKT}[{PRM}" + intFormat(priceCeil)
+ + "{BKT}]");
+ return returnList;
+
+ /*
+ * return("&d[&f" + itemId + (subType != 0? ","+subType : "") + "&d]&f "
+ * + getName() + "&d[&f" + count + "&d]&f " + "bp:&d[&f" + basePrice +
+ * "&d]&f st:&d[&f" + salesTax + "&d]&f v:&d[&f" + volatility + "&d]&f "
+ * + "iv:&d[&f" + getInverseVolatility() + "&d]&f s:&d[&f" + stock +
+ * "&d]&f " + "cb:&d[&f" + (getCanBuy(1)? getBuyPrice(1) : "-") +
+ * "&d]&f cs:&d[&f" + (getCanSell(1)? getSellPrice(1) : "-") + "&d]&f "
+ * + "sl:&d[&f" + intFormat(stockLowest) + "&d]&f sh:&d[&f" +
+ * intFormat(stockHighest) + "&d]&f " + "sf:&d[&f" +
+ * intFormat(stockFloor) + "&d]&f sc:&d[&f" + intFormat(stockCeil) +
+ * "&d]&f " + "pf:&d[&f" + intFormat(priceFloor) + "&d]&f pc:&d[&f" +
+ * intFormat(priceCeil) + "&d]");
+ */
+ }
+
+ public String intFormat(int thisInt) {
+ // Returns the string value of an int, with Integer.MAX_VALUE and
+ // Integer.MIN_VALUE converted to shorthand.
+ if (thisInt == Integer.MAX_VALUE)
+ return "+INF";
+ if (thisInt == Integer.MIN_VALUE)
+ return "-INF";
+ return Integer.toString(thisInt);
+ }
+
+ public String csvLine() {
+ // Spits out a line corresponding to a line in a .csv file.
+ return (itemId + "," + subType + "," + count + "," + name + ","
+ + basePrice + "," + stock + "," + (canBuy ? "Y" : "N") + ","
+ + (canSell ? "Y" : "N") + "," + volatility + "," + salesTax
+ + "," + intFormat(stockLowest) + "," + intFormat(stockHighest)
+ + "," + intFormat(stockFloor) + "," + intFormat(stockCeil)
+ + "," + intFormat(priceFloor) + "," + intFormat(priceCeil)
+ + "," + jitterPerc + "," + driftOut + "," + driftIn + ","
+ + avgStock + "," + itemClass);
+ }
+
+ public static String csvHeaderLine() {
+ // Spits out an appropriate header line for the output spreadsheet.
+ return ("itemId,subType,count,name,basePrice,stock,canBuy,canSell,volatility,salesTax,stockLowest,stockHighest,stockFloor,stockCeil,priceFloor,priceCeil,jitterPerc,driftOut,driftIn,avgStock,itemClass");
+ }
+
+ private int quickParse(String intString) {
+ // Parses strings into ints, throwing away errors and replacing them
+ // with 0s.
+ if (intString.equalsIgnoreCase("-inf"))
+ return Integer.MIN_VALUE;
+ if (intString.equalsIgnoreCase("+inf"))
+ return Integer.MAX_VALUE;
+ try {
+ return Integer.parseInt(intString);
+ } catch (NumberFormatException ex) {
+ return 0;
+ }
+ }
+
+ public MarketItem(String csvString, MarketItem defaults, String shopLabel, boolean isCSV) {
+ super();
+
+ if (defaults != null) {
+ this.itemId = defaults.itemId;
+ this.subType = defaults.subType;
+ this.count = defaults.count;
+ this.basePrice = defaults.basePrice;
+ this.stock = defaults.stock;
+ this.canBuy = defaults.canBuy;
+ this.canSell = defaults.canSell;
+ this.volatility = defaults.volatility;
+ this.salesTax = defaults.salesTax;
+ this.stockLowest = defaults.stockLowest;
+ this.stockHighest = defaults.stockHighest;
+ this.stockFloor = defaults.stockFloor;
+ this.stockCeil = defaults.stockCeil;
+ this.priceFloor = defaults.priceFloor;
+ this.priceCeil = defaults.priceCeil;
+ this.jitterPerc = defaults.jitterPerc;
+ this.driftOut = defaults.driftOut;
+ this.driftIn = defaults.driftIn;
+ this.avgStock = defaults.avgStock;
+ this.itemClass = defaults.itemClass;
+ } else {
+ setBaseDefaults();
+ }
+
+ String[] inputParams = csvString.split(",");
+
+ if (inputParams.length < 21) {
+ return;
+ }
+
+ if (!inputParams[0].isEmpty())
+ itemId = quickParse(inputParams[0]);
+ if (!inputParams[1].isEmpty())
+ subType = quickParse(inputParams[1]);
+ if (!inputParams[2].isEmpty())
+ count = quickParse(inputParams[2]);
+ if (!inputParams[3].isEmpty())
+ name = inputParams[3];
+ if (!inputParams[4].isEmpty())
+ basePrice = quickParse(inputParams[4]);
+ if (!inputParams[5].isEmpty())
+ stock = quickParse(inputParams[5]);
+ if (!inputParams[6].isEmpty())
+ canBuy = inputParams[6].equalsIgnoreCase("Y");
+ if (!inputParams[7].isEmpty())
+ canSell = inputParams[7].equalsIgnoreCase("Y");
+ if (!inputParams[8].isEmpty())
+ volatility = quickParse(inputParams[8]);
+ if (!inputParams[9].isEmpty())
+ salesTax = quickParse(inputParams[9]);
+ if (!inputParams[10].isEmpty())
+ stockLowest = quickParse(inputParams[10]);
+ if (!inputParams[11].isEmpty())
+ stockHighest = quickParse(inputParams[11]);
+ if (!inputParams[12].isEmpty())
+ stockFloor = quickParse(inputParams[12]);
+ if (!inputParams[13].isEmpty())
+ stockCeil = quickParse(inputParams[13]);
+ if (!inputParams[14].isEmpty())
+ priceFloor = quickParse(inputParams[14]);
+ if (!inputParams[15].isEmpty())
+ priceCeil = quickParse(inputParams[15]);
+ if (!inputParams[16].isEmpty())
+ jitterPerc = quickParse(inputParams[16]);
+ if (!inputParams[17].isEmpty())
+ driftOut = quickParse(inputParams[17]);
+ if (!inputParams[18].isEmpty())
+ driftIn = quickParse(inputParams[18]);
+ if (!inputParams[19].isEmpty())
+ avgStock = quickParse(inputParams[19]);
+ if (!inputParams[20].isEmpty())
+ itemClass = quickParse(inputParams[20]);
+ this.shopLabel = shopLabel;
+ sanityCheck();
+ }
+
+ public void setEmptyMask() {
+ // Wipes all fields to prepare this MarketItem to be used as a data mask.
+ this.name = null;
+ this.basePrice = 0;
+ this.stock = 0;
+ this.canBuy = false;
+ this.canSell = false;
+ this.volatility = 0;
+ this.salesTax = 0;
+ this.stockLowest = 0;
+ this.stockHighest = 0;
+ this.stockFloor = 0;
+ this.stockCeil = 0;
+ this.priceFloor = 0;
+ this.priceCeil = 0;
+ this.jitterPerc = 0;
+ this.driftOut = 0;
+ this.driftIn = 0;
+ this.avgStock = 0;
+ this.itemClass = 0;
+ this.shopLabel = null;
+ }
+
+ /*
+ public void copyMasked(MarketItem data, MarketItem mask)
+ {
+ // Copies in the fields from data, for only the fields set non-zero/non-null/true in mask.
+ if (mask.name != null) this.name = data.name;
+ if (mask.basePrice != 0) this.basePrice = data.basePrice;
+ if (mask.stock != 0) this.stock = data.stock;
+ if (mask.canBuy) this.canBuy = data.canBuy;
+ if (mask.canSell) this.canSell = data.canSell;
+ if (mask.volatility != 0) this.volatility = data.volatility;
+ if (mask.salesTax != 0) this.salesTax = data.salesTax;
+ if (mask.stockLowest != 0) this.stockLowest = data.stockLowest;
+ if (mask.stockHighest != 0) this.stockHighest = data.stockHighest;
+ if (mask.stockFloor != 0) this.stockFloor = data.stockFloor;
+ if (mask.stockCeil != 0) this.stockCeil = data.stockCeil;
+ if (mask.priceFloor != 0) this.priceFloor = data.priceFloor;
+ if (mask.priceCeil != 0) this.priceCeil = data.priceCeil;
+ if (mask.jitterPerc != 0) this.jitterPerc = data.jitterPerc;
+ if (mask.driftOut != 0) this.driftOut = data.driftOut;
+ if (mask.driftIn != 0) this.driftIn = data.driftIn;
+ if (mask.avgStock != 0) this.avgStock = data.avgStock;
+ if (mask.itemClass != 0) this.itemClass = data.itemClass;
+ if (mask.shopLabel != null) this.shopLabel = data.shopLabel;
+ }
+ */
}
diff --git a/src/com/gmail/haloinverse/DynamicMarket/Messaging.java b/src/com/gmail/haloinverse/DynamicMarket/Messaging.java
index 4240243..560fa87 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/Messaging.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/Messaging.java
@@ -1,97 +1,77 @@
package com.gmail.haloinverse.DynamicMarket;
-/* */ //package com.nijikokun.bukkit.SimpleShop;
-/* */
-// CHANGED: Commented out imports that weren't being used.
-/* */ //import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-/* */
-/* */ public class Messaging
-/* */ {
-/* 32 */ public Player player = null;
- private CommandSender sender = null;
- public static String colNormal = "&e"; // Normal text colour {}
- public static String colCmd = "&f"; // Command highlight colour {CMD}
- public static String colBracket = "&d"; // Highlighting of brackets around params/data {PBK}
- public static String colParam = "&b"; // Highlighting of parameters.
- public static String colError = "&c"; // Highlighting for errors. {ERR}
-/* */
- public Messaging(CommandSender thisSender)
- {
- sender = thisSender;
- if (thisSender instanceof Player)
- player = (Player)thisSender;
- }
-
- public boolean isPlayer()
- {
- if (player == null)
- return false;
- return true;
- }
+public class Messaging {
- @Deprecated
-/* */ public static String argument(String original, String[] arguments, String[] points)
-/* */ {
-/* 44 */ for (int i = 0; i < arguments.length; ++i) {
-/* 45 */ if (arguments[i].contains(",")) {
-/* 46 */ for (String arg : arguments[i].split(","))
-/* 47 */ original = original.replace(arg, points[i]);
-/* */ }
-/* */ else {
-/* 50 */ original = original.replace(arguments[i], points[i]);
-/* */ }
-/* */ }
-/* */
-/* 54 */ return original;
-/* */ }
-/* */
- //TODO: Use Bukkit's colour enums.
- //TODO: Make highlight colours configurable.
-
- public static String parseHighlights(String original)
- {
- return original.replace("{}",colNormal).replace("{CMD}",colCmd).replace("{BKT}",colBracket).replace("{ERR}",colError).replace("{PRM}",colParam);
- }
-
- public static String stripHighlights(String original)
- {
- return original.replace("{}","").replace("{CMD}","").replace("{BKT}","").replace("{ERR}","").replace("{PRM}","");
- }
+ public Player player = null;
+ private CommandSender sender = null;
+ public static String colNormal = "&e"; // Normal text colour {}
+ public static String colCmd = "&f"; // Command highlight colour {CMD}
+ public static String colBracket = "&d"; // Highlighting of brackets around params/data {PBK}
+ public static String colParam = "&b"; // Highlighting of parameters.
+ public static String colError = "&c"; // Highlighting for errors. {ERR}
+ /* */
-/* */ public static String parse(String original)
-/* */ {
-/* 70 */ return parseHighlights(original).replaceAll("(&([a-z0-9]))", "§$2").replace("&&", "&");
-/* */ }
-/* */
-/* */ public static String colorize(String original)
-/* */ {
-/* 87 */ return original.replace("", "§0").replace("", "§1").replace("", "§2").replace("", "§3").replace("", "§4").replace("", "§5").replace("", "§6").replace("", "§7").replace("", "§8").replace("", "§9").replace("", "§a").replace("", "§b").replace("", "§c").replace("", "§d").replace("", "§e").replace("", "§f");
-/* */ }
-/* */
-/* */ public static String bracketize(String message)
-/* */ {
-/* 98 */ return "[" + message + "]";
-/* */ }
-/* */
-/* */
-/* */ public void send(String message)
-/* */ {
-/* 138 */ if (sender != null)
-/* 139 */ sender.sendMessage(parse(message));
-/* */ }
-/* */
-/* */ public static void broadcast(String message)
-/* */ {
-/* 148 */ for (Player p : iListen.plugin.getServer().getOnlinePlayers())
-/* 149 */ p.sendMessage(parse(message));
-/* */ }
-/* */ }
+ public Messaging(CommandSender thisSender) {
+ sender = thisSender;
+ if (thisSender instanceof Player) {
+ player = (Player) thisSender;
+ }
+ }
-/* Location: C:\Program Files\eclipse\Bukkit\SimpleShop.jar
- * Qualified Name: com.nijikokun.bukkit.SimpleShop.Messaging
- * Java Class Version: 5 (49.0)
- * JD-Core Version: 0.5.3
- */
\ No newline at end of file
+ public boolean isPlayer() {
+ if (player == null) {
+ return false;
+ }
+ return true;
+ }
+
+ @Deprecated
+ public static String argument(String original, String[] arguments, String[] points) {
+ for (int i = 0; i < arguments.length; ++i) {
+ if (arguments[i].contains(",")) {
+ for (String arg : arguments[i].split(",")) {
+ original = original.replace(arg, points[i]);
+ }
+ } else {
+ original = original.replace(arguments[i], points[i]);
+ }
+ }
+
+ return original;
+ }
+
+ public static String parseHighlights(String original) {
+ return original.replace("{}", colNormal).replace("{CMD}", colCmd).replace("{BKT}", colBracket).replace("{ERR}", colError).replace("{PRM}", colParam);
+ }
+
+ public static String stripHighlights(String original) {
+ return original.replace("{}", "").replace("{CMD}", "").replace("{BKT}", "").replace("{ERR}", "").replace("{PRM}", "");
+ }
+
+ public static String parse(String original) {
+ return parseHighlights(original).replaceAll("(&([a-z0-9]))", "\u00A7$2").replace("&&", "&");
+ }
+
+ public static String colorize(String original) {
+ return original.replace("", "&0").replace("", "&1").replace("", "&2").replace("", "&3").replace("", "&4").replace("", "&5").replace("", "&6").replace("", "&7").replace("", "&8").replace("", "&9").replace("", "&a").replace("", "&b").replace("", "&c").replace("", "&d").replace("", "&e").replace("", "&f");
+ }
+
+ public static String bracketize(String message) {
+ return "[" + message + "]";
+ }
+
+ public void send(String message) {
+ if (sender != null) {
+ sender.sendMessage(parse(message));
+ }
+ }
+
+ public static void broadcast(String message) {
+ for (Player p : iListen.plugin.getServer().getOnlinePlayers()) {
+ p.sendMessage(parse(message));
+ }
+ }
+}
diff --git a/src/com/gmail/haloinverse/DynamicMarket/Misc.java b/src/com/gmail/haloinverse/DynamicMarket/Misc.java
index 7fe9c7c..eae1f4a 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/Misc.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/Misc.java
@@ -1,147 +1,151 @@
package com.gmail.haloinverse.DynamicMarket;
-/* */ //package com.nijikokun.bukkit.SimpleShop;
-/* */
+/* *///package com.nijikokun.bukkit.SimpleShop;
+/* */
// CHANGED: Commented out imports that weren't being used.
-/* */ //import org.bukkit.Server;
-/* */ //import org.bukkit.entity.Player;
-/* */
-/* */ public class Misc
-/* */ {
- public static String headerify(String innerText)
- {
- //TODO: Catch cases where a colour code ends up at the end of the line.
- //This is capable of crashing the client!
- int extraLength = innerText.length() - (stripCodes(Messaging.stripHighlights(innerText))).length();
- String newString = "--" + innerText + "------------------------------------------------------------";
- return newString.substring(0,50+extraLength);
- // This is approximate, due to inability to get string width of the proportional font.
- }
-
- public static String stripCodes(String toStrip)
- // Removes color codes from the string.
- {
- return toStrip.replaceAll("&[a-z0-9]", "").replace("&&", "&");
- }
-
-/* */ public static boolean isEither(String text, String against, String or)
-/* */ {
-/* 76 */ return ((text.equalsIgnoreCase(against)) || (text.equalsIgnoreCase(or)));
-/* */ }
+/* *///import org.bukkit.Server;
+/* *///import org.bukkit.entity.Player;
+/* */
+/* */public class Misc
+/* */{
+ public static String headerify(String innerText) {
+ // TODO: Catch cases where a colour code ends up at the end of the line.
+ // This is capable of crashing the client!
+ int extraLength = innerText.length()
+ - (stripCodes(Messaging.stripHighlights(innerText))).length();
+ String newString = "--"
+ + innerText
+ + "------------------------------------------------------------";
+ return newString.substring(0, 50 + extraLength);
+ // This is approximate, due to inability to get string width of the proportional font.
+ }
- public static boolean isAny(String text, String[] against)
- {
- for(String thisAgainst : against)
- {
- if(text.equalsIgnoreCase(thisAgainst))
- return true;
- }
- return false;
- }
-/* */
- //@Deprecated
-/* */ //public static String formatCurrency(int Balance, String currency)
-/* */ //{
-/* 88 */ // return insertCommas(String.valueOf(Balance)) + " " + currency;
-/* */ //}
-/* */
- //@Deprecated
-/* */ //public static String insertCommas(String str)
-/* */ //{
-/* 99 */ // if (str.length() < 4) {
-/* 100 */ // return str;
-/* */ // }
-/* */
-/* 103 */ // return insertCommas(str.substring(0, str.length() - 3)) + "," + str.substring(str.length() - 3, str.length());
-/* */ //}
-/* */
- //@Deprecated
-/* */ //public static String string(int i)
-/* */ //{
-/* 112 */ // return String.valueOf(i);
-/* */ //}
-/* */
- //@Deprecated
-/* */ //public static boolean validate(String name) {
-/* 116 */ // return name.matches("([0-9a-zA-Z._-]+)");
-/* */ //}
-/* */
- //@Deprecated
-/* */ //public static String repeat(char c, int i) {
-/* 120 */ // String tst = "";
-/* 121 */ // for (int j = 0; j < i; ++j) {
-/* 122 */ // tst = tst + c;
-/* */ // }
-/* 124 */ // return tst;
-/* */ //}
-/* */
- //@Deprecated
-/* */ //public static Player player(String name)
-/* */ //{
-/* 131 */ // if (iListen.plugin.getServer().getOnlinePlayers().length < 1) {
-/* 132 */ // return null;
-/* */ // }
-/* */
-/* 135 */ // Player[] online = iListen.plugin.getServer().getOnlinePlayers();
-/* 136 */ // Player player = null;
-/* */
-/* 138 */ // for (Player needle : online) {
-/* 139 */ // if (needle.getName().equals(name)) {
-/* 140 */ // player = needle;
-/* 141 */ // break;
-/* */ // }
-/* */ // }
-/* */
-/* 145 */ // return player;
-/* */ //}
-/* */
- //@Deprecated
-/* */ //public static Player playerMatch(String name)
-/* */ //{
-/* 152 */ // if (iListen.plugin.getServer().getOnlinePlayers().length < 1) {
-/* 153 */ // return null;
-/* */ // }
-/* */
-/* 156 */ // Player[] online = iListen.plugin.getServer().getOnlinePlayers();
-/* 157 */ // Player lastPlayer = null;
-/* 158 */ // name = name.toLowerCase();
-/* */
-/* 160 */ // for (Player player : online) {
-/* 161 */ // String playerName = player.getName();
-/* */
-/* 163 */ // if (playerName.toLowerCase().equals(name)) {
-/* 164 */ // lastPlayer = player;
-/* 165 */ // break;
-/* */ // }
-/* */
-/* 168 */ // if (playerName.toLowerCase().indexOf(name.toLowerCase()) != -1) {
-/* 169 */ // if (lastPlayer != null) {
-/* 170 */ // return null;
-/* */ // }
-/* */
-/* 173 */ // lastPlayer = player;
-/* */ // }
-/* */ // }
-/* */
-/* 177 */ // return lastPlayer;
-/* */ //}
-/* */
+ public static String stripCodes(String toStrip)
+ // Removes color codes from the string.
+ {
+ return toStrip.replaceAll("&[a-z0-9]", "").replace("&&", "&");
+ }
-/* */ public static String combineSplit(int startIndex, String[] string, String seperator) {
-/* 181 */ StringBuilder builder = new StringBuilder();
-/* */
-/* 183 */ for (int i = startIndex; i < string.length; ++i) {
-/* 184 */ builder.append(string[i]);
-/* 185 */ builder.append(seperator);
-/* */ }
-/* */
-/* 188 */ builder.deleteCharAt(builder.length() - seperator.length());
-/* 189 */ return builder.toString();
-/* */ }
-/* */ }
+ /* */public static boolean isEither(String text, String against, String or)
+ /* */{
+ /* 76 */return ((text.equalsIgnoreCase(against)) || (text.equalsIgnoreCase(or)));
+ /* */}
-/* Location: C:\Program Files\eclipse\Bukkit\SimpleShop.jar
- * Qualified Name: com.nijikokun.bukkit.SimpleShop.Misc
- * Java Class Version: 5 (49.0)
- * JD-Core Version: 0.5.3
+ public static boolean isAny(String text, String[] against) {
+ for (String thisAgainst : against) {
+ if (text.equalsIgnoreCase(thisAgainst))
+ return true;
+ }
+ return false;
+ }
+
+ /* */
+ // @Deprecated
+ /* */// public static String formatCurrency(int Balance, String currency)
+ /* */// {
+ /* 88 */// return insertCommas(String.valueOf(Balance)) + " " + currency;
+ /* */// }
+ /* */
+ // @Deprecated
+ /* */// public static String insertCommas(String str)
+ /* */// {
+ /* 99 */// if (str.length() < 4) {
+ /* 100 */// return str;
+ /* */// }
+ /* */
+ /* 103 */// return insertCommas(str.substring(0, str.length() - 3)) + "," +
+ // str.substring(str.length() - 3, str.length());
+ /* */// }
+ /* */
+ // @Deprecated
+ /* */// public static String string(int i)
+ /* */// {
+ /* 112 */// return String.valueOf(i);
+ /* */// }
+ /* */
+ // @Deprecated
+ /* */// public static boolean validate(String name) {
+ /* 116 */// return name.matches("([0-9a-zA-Z._-]+)");
+ /* */// }
+ /* */
+ // @Deprecated
+ /* */// public static String repeat(char c, int i) {
+ /* 120 */// String tst = "";
+ /* 121 */// for (int j = 0; j < i; ++j) {
+ /* 122 */// tst = tst + c;
+ /* */// }
+ /* 124 */// return tst;
+ /* */// }
+ /* */
+ // @Deprecated
+ /* */// public static Player player(String name)
+ /* */// {
+ /* 131 */// if (iListen.plugin.getServer().getOnlinePlayers().length < 1) {
+ /* 132 */// return null;
+ /* */// }
+ /* */
+ /* 135 */// Player[] online = iListen.plugin.getServer().getOnlinePlayers();
+ /* 136 */// Player player = null;
+ /* */
+ /* 138 */// for (Player needle : online) {
+ /* 139 */// if (needle.getName().equals(name)) {
+ /* 140 */// player = needle;
+ /* 141 */// break;
+ /* */// }
+ /* */// }
+ /* */
+ /* 145 */// return player;
+ /* */// }
+ /* */
+ // @Deprecated
+ /* */// public static Player playerMatch(String name)
+ /* */// {
+ /* 152 */// if (iListen.plugin.getServer().getOnlinePlayers().length < 1) {
+ /* 153 */// return null;
+ /* */// }
+ /* */
+ /* 156 */// Player[] online = iListen.plugin.getServer().getOnlinePlayers();
+ /* 157 */// Player lastPlayer = null;
+ /* 158 */// name = name.toLowerCase();
+ /* */
+ /* 160 */// for (Player player : online) {
+ /* 161 */// String playerName = player.getName();
+ /* */
+ /* 163 */// if (playerName.toLowerCase().equals(name)) {
+ /* 164 */// lastPlayer = player;
+ /* 165 */// break;
+ /* */// }
+ /* */
+ /* 168 */// if (playerName.toLowerCase().indexOf(name.toLowerCase()) != -1)
+ // {
+ /* 169 */// if (lastPlayer != null) {
+ /* 170 */// return null;
+ /* */// }
+ /* */
+ /* 173 */// lastPlayer = player;
+ /* */// }
+ /* */// }
+ /* */
+ /* 177 */// return lastPlayer;
+ /* */// }
+ /* */
+
+ /* */public static String combineSplit(int startIndex, String[] string, String seperator) {
+ /* 181 */StringBuilder builder = new StringBuilder();
+ /* */
+ /* 183 */for (int i = startIndex; i < string.length; ++i) {
+ /* 184 */builder.append(string[i]);
+ /* 185 */builder.append(seperator);
+ /* */}
+ /* */
+ /* 188 */builder.deleteCharAt(builder.length() - seperator.length());
+ /* 189 */return builder.toString();
+ /* */}
+ /* */
+}
+
+/*
+ * Location: C:\Program Files\eclipse\Bukkit\SimpleShop.jar Qualified Name:
+ * com.nijikokun.bukkit.SimpleShop.Misc Java Class Version: 5 (49.0) JD-Core
+ * Version: 0.5.3
*/
\ No newline at end of file
diff --git a/src/com/gmail/haloinverse/DynamicMarket/PermissionInterface.java b/src/com/gmail/haloinverse/DynamicMarket/PermissionInterface.java
index 25a136e..5be17bd 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/PermissionInterface.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/PermissionInterface.java
@@ -3,5 +3,5 @@
import org.bukkit.command.CommandSender;
public interface PermissionInterface {
- public boolean permission(CommandSender thisSender, String permissionString);
+ public boolean permission(CommandSender thisSender, String permissionString);
}
diff --git a/src/com/gmail/haloinverse/DynamicMarket/SQLHandler.java b/src/com/gmail/haloinverse/DynamicMarket/SQLHandler.java
index 85757f9..b1fb76b 100644
--- a/src/com/gmail/haloinverse/DynamicMarket/SQLHandler.java
+++ b/src/com/gmail/haloinverse/DynamicMarket/SQLHandler.java
@@ -5,290 +5,314 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.SQLWarning;
import java.util.ArrayList;
import java.sql.Statement;
public class SQLHandler {
-
- // A wrapper class to handle the repeated grunt-work of SQL queries and the errors they throw.
- public Connection conn;
- public PreparedStatement ps;
- private ArrayList psList;
- public ResultSet rs;
- public DatabaseCore connDB;
- public ArrayList