It works
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
|
import org.gradle.api.tasks.bundling.Zip
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
}
|
}
|
||||||
@@ -14,4 +17,15 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.gotti.wurmunlimited:server-modlauncher:0.46")
|
implementation("org.gotti.wurmunlimited:server-modlauncher:0.46")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register<Zip>("dist") {
|
||||||
|
into("mods") {
|
||||||
|
into(project.name) {
|
||||||
|
from(tasks.named<Jar>("jar"))
|
||||||
|
}
|
||||||
|
from(fileTree("mods") { include("*") })
|
||||||
|
}
|
||||||
|
|
||||||
|
archiveFileName.set("${project.name}.zip")
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,18 @@ classname=mod.treestar.shopmod.ShopMod
|
|||||||
classpath=ShopMod.jar
|
classpath=ShopMod.jar
|
||||||
sharedClassLoader=true
|
sharedClassLoader=true
|
||||||
|
|
||||||
# Activates the json item provider and loads items from the given configuration
|
# Display name shown in the shop window
|
||||||
jsonItemProvider=true
|
shopName=Server Shop
|
||||||
jsonItemProviderItems=mods/shop_items.json
|
|
||||||
|
# Allow opening the shop from settlement tokens
|
||||||
|
enableTokenAccess=true
|
||||||
|
|
||||||
|
# Allow opening the shop from mailboxes
|
||||||
|
enableMailboxAccess=false
|
||||||
|
|
||||||
|
# JSON config files for categories and items
|
||||||
|
categoryJsonPath=mods/shop_categories.json
|
||||||
|
itemJsonPath=mods/shop_items.json
|
||||||
|
|
||||||
|
# java.util.logging level for this mod (e.g., INFO, FINE)
|
||||||
|
logLevel=INFO
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
rootProject.name = "SilverShop"
|
rootProject.name = "ShopMod"
|
||||||
@@ -6,13 +6,17 @@ import com.wurmonline.server.players.Player;
|
|||||||
import mod.treestar.shopmod.ShopService;
|
import mod.treestar.shopmod.ShopService;
|
||||||
import mod.treestar.shopmod.datamodels.ShopCategory;
|
import mod.treestar.shopmod.datamodels.ShopCategory;
|
||||||
import mod.treestar.shopmod.datamodels.ShopItem;
|
import mod.treestar.shopmod.datamodels.ShopItem;
|
||||||
|
import mod.treestar.shopmod.util.BmlForm;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ShopQuestion extends Question {
|
public class ShopQuestion extends Question {
|
||||||
private static final int SHOP_QUESTION_ID = 90001;
|
private static final int SHOP_QUESTION_ID = 90001;
|
||||||
|
private static final Logger logger = Logger.getLogger(ShopQuestion.class.getName());
|
||||||
|
|
||||||
private ShopService shopService;
|
private ShopService shopService;
|
||||||
private int selectedCategoryId = -1;
|
private int selectedCategoryId = -1;
|
||||||
@@ -28,49 +32,66 @@ public class ShopQuestion extends Question {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void answer(Properties properties) {
|
public void answer(Properties properties) {
|
||||||
super.answer(properties);
|
logger.log(Level.INFO, "ShopQuestion.answer: received properties {0}", properties);
|
||||||
List<ShopCategory> categories = shopService.getCategories();
|
List<ShopCategory> categories = shopService.getCategories();
|
||||||
|
|
||||||
// Update category selection if present
|
|
||||||
String categoryIndex = properties.getProperty("category");
|
String categoryIndex = properties.getProperty("category");
|
||||||
if (categoryIndex != null && !categories.isEmpty()) {
|
if (categoryIndex != null && !categories.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
int idx = Integer.parseInt(categoryIndex);
|
int idx = Integer.parseInt(categoryIndex);
|
||||||
if (idx >= 0 && idx < categories.size()) {
|
if (idx >= 0 && idx < categories.size()) {
|
||||||
selectedCategoryId = categories.get(idx).getId();
|
selectedCategoryId = categories.get(idx).getId();
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: category set to index {0}, id {1}", new Object[] { idx, selectedCategoryId });
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException ignored) { }
|
} catch (NumberFormatException ignored) {
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: invalid category index {0}", categoryIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If purchase not requested, refresh UI with selected category
|
String buyKey = properties.stringPropertyNames().stream()
|
||||||
if (!properties.containsKey("submit")) {
|
.filter(k -> k.startsWith("buy_"))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (properties.containsKey("close")) {
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: close requested");
|
||||||
|
return; // user closed the window
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.containsKey("refresh")) {
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: refresh requested");
|
||||||
sendQuestion();
|
sendQuestion();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String itemIdStr = properties.getProperty("itemid");
|
if (buyKey == null) { // category change or refresh
|
||||||
if (itemIdStr == null) {
|
logger.log(Level.INFO, "ShopQuestion.answer: no buy key present, refreshing UI");
|
||||||
getResponder().getCommunicator().sendNormalServerMessage("No item selected.");
|
sendQuestion();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int itemId;
|
|
||||||
try {
|
try {
|
||||||
itemId = Integer.parseInt(itemIdStr);
|
int itemId = Integer.parseInt(buyKey.substring("buy_".length()));
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: attempting purchase itemId={0}", itemId);
|
||||||
|
ShopService.PurchaseResult result = shopService.purchaseItem((Player) getResponder(), itemId);
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: purchase success itemId={0}", itemId);
|
||||||
|
getResponder().getCommunicator().sendSafeServerMessage(result.getMessage());
|
||||||
|
} else {
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: purchase failed itemId={0}, message={1}", new Object[] { itemId, result.getMessage() });
|
||||||
|
getResponder().getCommunicator().sendAlertServerMessage(result.getMessage());
|
||||||
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
logger.log(Level.INFO, "ShopQuestion.answer: invalid buy key {0}", buyKey);
|
||||||
getResponder().getCommunicator().sendNormalServerMessage("Invalid item selected.");
|
getResponder().getCommunicator().sendNormalServerMessage("Invalid item selected.");
|
||||||
return;
|
|
||||||
}
|
|
||||||
ShopService.PurchaseResult result = shopService.purchaseItem((Player)getResponder(), itemId);
|
|
||||||
if (result.isSuccess()) {
|
|
||||||
getResponder().getCommunicator().sendSafeServerMessage(result.getMessage());
|
|
||||||
} else {
|
|
||||||
getResponder().getCommunicator().sendNormalServerMessage(result.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendQuestion() {
|
public void sendQuestion() {
|
||||||
List<ShopCategory> categories = shopService.getCategories();
|
List<ShopCategory> categories = shopService.getCategories();
|
||||||
|
categories = categories.stream()
|
||||||
|
.filter(c -> shopService.getItems().stream().anyMatch(i -> i.getCategoryId() == c.getId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
if (categories.isEmpty()) {
|
if (categories.isEmpty()) {
|
||||||
getResponder().getCommunicator().sendNormalServerMessage("No shop categories are available.");
|
getResponder().getCommunicator().sendNormalServerMessage("No shop categories are available.");
|
||||||
return;
|
return;
|
||||||
@@ -78,13 +99,6 @@ public class ShopQuestion extends Question {
|
|||||||
if (selectedCategoryId == -1 || categories.stream().noneMatch(c -> c.getId() == selectedCategoryId)) {
|
if (selectedCategoryId == -1 || categories.stream().noneMatch(c -> c.getId() == selectedCategoryId)) {
|
||||||
selectedCategoryId = categories.get(0).getId();
|
selectedCategoryId = categories.get(0).getId();
|
||||||
}
|
}
|
||||||
int defaultCategoryIndex = 0;
|
|
||||||
for (int i = 0; i < categories.size(); i++) {
|
|
||||||
if (categories.get(i).getId() == selectedCategoryId) {
|
|
||||||
defaultCategoryIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ShopItem> items = shopService.getItems().stream()
|
List<ShopItem> items = shopService.getItems().stream()
|
||||||
.filter(i -> i.getCategoryId() == selectedCategoryId)
|
.filter(i -> i.getCategoryId() == selectedCategoryId)
|
||||||
@@ -93,24 +107,42 @@ public class ShopQuestion extends Question {
|
|||||||
getResponder().getCommunicator().sendNormalServerMessage("No shop items are available.");
|
getResponder().getCommunicator().sendNormalServerMessage("No shop items are available.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringBuilder bml = new StringBuilder();
|
BmlForm form = new BmlForm(title);
|
||||||
bml.append("border{center{heading{text=\"").append(escape(title)).append("\"}}");
|
form.addHidden("id", String.valueOf(this.id));
|
||||||
|
// Category selector with refresh button
|
||||||
if (categories.size() > 1) {
|
if (categories.size() > 1) {
|
||||||
bml.append("harray{label{text=\"Category\"};dropdown{id=\"category\";options=\"")
|
String options = categories.stream().map(c -> escape(c.getName())).collect(Collectors.joining(","));
|
||||||
.append(categories.stream().map(c -> escape(c.getName())).collect(Collectors.joining(",")))
|
int defaultIndex = 0;
|
||||||
.append("\";default=\"").append(defaultCategoryIndex).append("\"}}");
|
for (int i = 0; i < categories.size(); i++) {
|
||||||
|
if (categories.get(i).getId() == selectedCategoryId) {
|
||||||
|
defaultIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form.beginHorizontalFlow();
|
||||||
|
form.addLabel("Category");
|
||||||
|
form.addRaw("dropdown{id=\"" + escape("category") + "\";options=\"" + options + "\";default=\"" + defaultIndex + "\"}");
|
||||||
|
form.addButton("Show", "refresh");
|
||||||
|
form.endHorizontalFlow();
|
||||||
}
|
}
|
||||||
bml.append("center{scroll{table{rows=\"");
|
|
||||||
|
// Items list (one row per item)
|
||||||
for (ShopItem item : items) {
|
for (ShopItem item : items) {
|
||||||
bml.append("label{text=\"").append(escape(item.getName())).append("\"};");
|
form.beginHorizontalFlow();
|
||||||
bml.append("label{text=\"").append(escape(item.getDescription())).append("\"};");
|
form.addLabel(escape(item.getName()));
|
||||||
bml.append("label{text=\"").append(escape(item.getPriceDisplay())).append("\"};");
|
form.addLabel(escape(item.getDescription()));
|
||||||
bml.append("radio{group=\"itemid\";id=\"").append(item.getId()).append("\"};");
|
form.addLabel(escape(item.getPriceDisplay()));
|
||||||
|
form.addButton("+1", "buy_" + item.getId());
|
||||||
|
form.endHorizontalFlow();
|
||||||
}
|
}
|
||||||
bml.append("\"}}}");
|
|
||||||
bml.append("harray{button{id=\"submit\";text=\"Purchase\"};button{id=\"cancel\";text=\"Cancel\"}}");
|
form.beginHorizontalFlow();
|
||||||
bml.append("}");
|
form.addButton("Close", "close");
|
||||||
getResponder().getCommunicator().sendBml(400, 400, true, true, bml.toString(), 200, 200, 200, title);
|
form.endHorizontalFlow();
|
||||||
|
|
||||||
|
String bml = form.toString();
|
||||||
|
logger.log(Level.INFO, "ShopQuestion BML: {0}", bml);
|
||||||
|
getResponder().getCommunicator().sendBml(400, 400, true, true, bml, 200, 200, 200, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShopService getShopService() {
|
public ShopService getShopService() {
|
||||||
@@ -122,6 +154,9 @@ public class ShopQuestion extends Question {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String escape(String value) {
|
private String escape(String value) {
|
||||||
return value == null ? "" : value.replace("\"", "''");
|
if (value == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return value.replace("\"", "''").replace("'", "''");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import mod.treestar.shopmod.itemprovider.JsonShopItemProvider;
|
|||||||
import mod.treestar.shopmod.ShopOpenAction;
|
import mod.treestar.shopmod.ShopOpenAction;
|
||||||
import org.gotti.wurmunlimited.modloader.interfaces.Configurable;
|
import org.gotti.wurmunlimited.modloader.interfaces.Configurable;
|
||||||
import org.gotti.wurmunlimited.modloader.interfaces.Initable;
|
import org.gotti.wurmunlimited.modloader.interfaces.Initable;
|
||||||
|
import org.gotti.wurmunlimited.modloader.interfaces.ServerStartedListener;
|
||||||
import org.gotti.wurmunlimited.modloader.interfaces.WurmServerMod;
|
import org.gotti.wurmunlimited.modloader.interfaces.WurmServerMod;
|
||||||
import org.gotti.wurmunlimited.modsupport.actions.ModActions;
|
import org.gotti.wurmunlimited.modsupport.actions.ModActions;
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ import java.util.Properties;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class ShopMod implements WurmServerMod, Initable, Configurable {
|
public class ShopMod implements WurmServerMod, Initable, Configurable, ServerStartedListener {
|
||||||
private static final Logger logger = Logger.getLogger(ShopMod.class.getName());
|
private static final Logger logger = Logger.getLogger(ShopMod.class.getName());
|
||||||
|
|
||||||
private String shopName = "Server Shop";
|
private String shopName = "Server Shop";
|
||||||
@@ -21,6 +22,7 @@ public class ShopMod implements WurmServerMod, Initable, Configurable {
|
|||||||
private String categoryJsonPath = "mods/shop/categories.json";
|
private String categoryJsonPath = "mods/shop/categories.json";
|
||||||
private String itemJsonPath = "mods/shop/items.json";
|
private String itemJsonPath = "mods/shop/items.json";
|
||||||
private Level logLevel = Level.INFO;
|
private Level logLevel = Level.INFO;
|
||||||
|
private ShopService shopService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Properties properties) {
|
public void configure(Properties properties) {
|
||||||
@@ -37,11 +39,13 @@ public class ShopMod implements WurmServerMod, Initable, Configurable {
|
|||||||
public void init() {
|
public void init() {
|
||||||
ModActions.init();
|
ModActions.init();
|
||||||
|
|
||||||
ShopService shopService = ShopService.getInstance();
|
shopService = ShopService.getInstance();
|
||||||
|
|
||||||
shopService.registerCategoryProvider(new JsonShopCategoryProvider(categoryJsonPath));
|
shopService.registerCategoryProvider(new JsonShopCategoryProvider(categoryJsonPath));
|
||||||
shopService.registerItemProvider(new JsonShopItemProvider(itemJsonPath));
|
shopService.registerItemProvider(new JsonShopItemProvider(itemJsonPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServerStarted() {
|
||||||
new ShopOpenAction(shopService, shopName, enableTokenAccess, enableMailboxAccess);
|
new ShopOpenAction(shopService, shopName, enableTokenAccess, enableMailboxAccess);
|
||||||
|
|
||||||
logger.log(Level.INFO, String.format("Initialized shop '%s' (token access: %s, mailbox access: %s)", shopName, enableTokenAccess, enableMailboxAccess));
|
logger.log(Level.INFO, String.format("Initialized shop '%s' (token access: %s, mailbox access: %s)", shopName, enableTokenAccess, enableMailboxAccess));
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ public class ShopOpenAction implements ActionPerformer, BehaviourProvider {
|
|||||||
return false; // not supported
|
return false; // not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean action(Action action, Creature performer, Item source, Item target, short actionId, float counter) {
|
||||||
|
return action(action, performer, target, actionId, counter);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ActionEntry> getBehavioursFor(Creature performer, Item target) {
|
public List<ActionEntry> getBehavioursFor(Creature performer, Item target) {
|
||||||
if (isValidTarget(target)) {
|
if (isValidTarget(target)) {
|
||||||
@@ -74,6 +79,11 @@ public class ShopOpenAction implements ActionPerformer, BehaviourProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ActionEntry> getBehavioursFor(Creature performer, Item source, Item target) {
|
||||||
|
return getBehavioursFor(performer, target);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ActionEntry> getBehavioursFor(Creature performer, Creature target) {
|
public List<ActionEntry> getBehavioursFor(Creature performer, Creature target) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -32,9 +32,13 @@ public class ShopService {
|
|||||||
public List<ShopCategory> getCategories() {
|
public List<ShopCategory> getCategories() {
|
||||||
List<ShopCategory> categories = new ArrayList<>();
|
List<ShopCategory> categories = new ArrayList<>();
|
||||||
for (ShopCategoryProvider provider : categoryProviders) {
|
for (ShopCategoryProvider provider : categoryProviders) {
|
||||||
List<ShopCategory> provided = provider.getCategories();
|
try {
|
||||||
if (provided != null) {
|
List<ShopCategory> provided = provider.getCategories();
|
||||||
categories.addAll(provided);
|
if (provided != null) {
|
||||||
|
categories.addAll(provided);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Category provider threw an exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return categories;
|
return categories;
|
||||||
@@ -43,9 +47,13 @@ public class ShopService {
|
|||||||
public List<ShopItem> getItems() {
|
public List<ShopItem> getItems() {
|
||||||
List<ShopItem> items = new ArrayList<>();
|
List<ShopItem> items = new ArrayList<>();
|
||||||
for (ShopItemProvider provider : itemProviders) {
|
for (ShopItemProvider provider : itemProviders) {
|
||||||
List<ShopItem> provided = provider.getItems();
|
try {
|
||||||
if (provided != null) {
|
List<ShopItem> provided = provider.getItems();
|
||||||
items.addAll(provided);
|
if (provided != null) {
|
||||||
|
items.addAll(provided);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Item provider threw an exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
@@ -66,12 +74,17 @@ public class ShopService {
|
|||||||
if (item.getPurchaseHandler() == null) {
|
if (item.getPurchaseHandler() == null) {
|
||||||
return PurchaseResult.failure("Item has no purchase handler configured.");
|
return PurchaseResult.failure("Item has no purchase handler configured.");
|
||||||
}
|
}
|
||||||
if (!item.getCurrency().canPlayerAfford(player)) {
|
try {
|
||||||
return PurchaseResult.failure("You cannot afford this item.");
|
if (!item.getCurrency().canPlayerAfford(player)) {
|
||||||
}
|
return PurchaseResult.failure("You cannot afford this item.");
|
||||||
boolean charged = item.getCurrency().chargePlayer(player);
|
}
|
||||||
if (!charged) {
|
boolean charged = item.getCurrency().chargePlayer(player);
|
||||||
return PurchaseResult.failure("Charging failed; purchase canceled.");
|
if (!charged) {
|
||||||
|
return PurchaseResult.failure("Charging failed; purchase canceled.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Currency check/charge failed for item " + itemId + " for player " + player.getName(), e);
|
||||||
|
return PurchaseResult.failure("Payment failed; purchase canceled.");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
item.getPurchaseHandler().onPurchase(player);
|
item.getPurchaseHandler().onPurchase(player);
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public class JsonShopCategoryProvider implements ShopCategoryProvider {
|
|||||||
JSONArray typeArray = new JSONArray(tokenizer);
|
JSONArray typeArray = new JSONArray(tokenizer);
|
||||||
cachedCategories = parseCategories(typeArray);
|
cachedCategories = parseCategories(typeArray);
|
||||||
lastModified = file.lastModified();
|
lastModified = file.lastModified();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Failed to parse categories JSON; keeping previous categories", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ public class JsonShopItemProvider implements ShopItemProvider {
|
|||||||
JSONArray typeArray = new JSONArray(tokenizer);
|
JSONArray typeArray = new JSONArray(tokenizer);
|
||||||
cachedItems = parseItems(typeArray);
|
cachedItems = parseItems(typeArray);
|
||||||
lastModified = file.lastModified();
|
lastModified = file.lastModified();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Failed to parse items JSON; keeping previous items", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +97,9 @@ public class JsonShopItemProvider implements ShopItemProvider {
|
|||||||
logger.log(Level.WARNING, "Item at index " + index + " missing currency; item will be unusable");
|
logger.log(Level.WARNING, "Item at index " + index + " missing currency; item will be unusable");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String type = currencyObj.optString("type", "");
|
String type = currencyObj.optString("type", "").toLowerCase(Locale.ROOT);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "WurmBankCurrency":
|
case "wurmbankcurrency":
|
||||||
long ironAmount = currencyObj.optLong("ironAmount", currencyObj.optLong("priceIron", 0L));
|
long ironAmount = currencyObj.optLong("ironAmount", currencyObj.optLong("priceIron", 0L));
|
||||||
return new WurmBankCurrency(ironAmount);
|
return new WurmBankCurrency(ironAmount);
|
||||||
default:
|
default:
|
||||||
@@ -111,23 +113,23 @@ public class JsonShopItemProvider implements ShopItemProvider {
|
|||||||
logger.log(Level.WARNING, "Item at index " + index + " missing handler; item will be unusable");
|
logger.log(Level.WARNING, "Item at index " + index + " missing handler; item will be unusable");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String type = handlerObj.optString("type", "");
|
String type = handlerObj.optString("type", "").toLowerCase(Locale.ROOT);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "ShopWurmItemPurchaseEffect":
|
case "shopwurmitempurchaseeffect":
|
||||||
int templateId = handlerObj.optInt("itemTemplateId", -1);
|
int templateId = handlerObj.optInt("itemTemplateId", -1);
|
||||||
if (templateId <= 0) {
|
if (templateId <= 0) {
|
||||||
logger.log(Level.WARNING, "Handler for item at index " + index + " missing valid itemTemplateId");
|
logger.log(Level.WARNING, "Handler for item at index " + index + " missing valid itemTemplateId");
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ShopWurmItemPurchaseEffect effect = new ShopWurmItemPurchaseEffect();
|
|
||||||
effect.setItemTemplateId(templateId);
|
|
||||||
effect.setQl((float) handlerObj.optDouble("ql", 50));
|
|
||||||
effect.setRandomQl(handlerObj.optBoolean("randomQl", false));
|
|
||||||
effect.setRarity((byte) handlerObj.optInt("rarity", 0));
|
|
||||||
return effect;
|
|
||||||
default:
|
|
||||||
logger.log(Level.WARNING, "Unknown handler type '" + type + "' for item at index " + index);
|
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
ShopWurmItemPurchaseEffect effect = new ShopWurmItemPurchaseEffect();
|
||||||
|
effect.setItemTemplateId(templateId);
|
||||||
|
effect.setQl((float) handlerObj.optDouble("ql", 50));
|
||||||
|
effect.setRandomQl(handlerObj.optBoolean("randomQl", false));
|
||||||
|
effect.setRarity((byte) handlerObj.optInt("rarity", 0));
|
||||||
|
return effect;
|
||||||
|
default:
|
||||||
|
logger.log(Level.WARNING, "Unknown handler type '" + type + "' for item at index " + index);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
226
src/main/java/mod/treestar/shopmod/util/BmlForm.java
Normal file
226
src/main/java/mod/treestar/shopmod/util/BmlForm.java
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
package mod.treestar.shopmod.util;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class BmlForm {
|
||||||
|
private static Logger logger = Logger.getLogger(BmlForm.class.getName());
|
||||||
|
private final StringBuffer buf = new StringBuffer();
|
||||||
|
private int openBorders = 0;
|
||||||
|
private int openCenters = 0;
|
||||||
|
private int openVarrays = 0;
|
||||||
|
private int openScrolls = 0;
|
||||||
|
private int openHarrays = 0;
|
||||||
|
private int openTrees = 0;
|
||||||
|
private int openRows = 0;
|
||||||
|
private int openColumns = 0;
|
||||||
|
private int openTables = 0;
|
||||||
|
private int indentNum = 0;
|
||||||
|
private boolean beautify = false;
|
||||||
|
private boolean closeDefault = false;
|
||||||
|
|
||||||
|
public BmlForm() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BmlForm(String formTitle) {
|
||||||
|
this.addDefaultHeader(formTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDefaultHeader(String formTitle) {
|
||||||
|
if (this.closeDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.beginBorder();
|
||||||
|
this.beginCenter();
|
||||||
|
this.addBoldText(formTitle, new String[0]);
|
||||||
|
this.endCenter();
|
||||||
|
this.beginScroll();
|
||||||
|
this.beginVerticalFlow();
|
||||||
|
this.closeDefault = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void beginBorder() {
|
||||||
|
this.buf.append(this.indent("border{"));
|
||||||
|
++this.indentNum;
|
||||||
|
++this.openBorders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endBorder() {
|
||||||
|
--this.indentNum;
|
||||||
|
this.buf.append(this.indent("}"));
|
||||||
|
--this.openBorders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void beginCenter() {
|
||||||
|
this.buf.append(this.indent("center{"));
|
||||||
|
++this.indentNum;
|
||||||
|
++this.openCenters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endCenter() {
|
||||||
|
--this.indentNum;
|
||||||
|
this.buf.append(this.indent("};null;"));
|
||||||
|
--this.openCenters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void beginVerticalFlow() {
|
||||||
|
this.buf.append(this.indent("varray{rescale=\"true\";"));
|
||||||
|
++this.indentNum;
|
||||||
|
++this.openVarrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endVerticalFlow() {
|
||||||
|
--this.indentNum;
|
||||||
|
this.buf.append(this.indent("}"));
|
||||||
|
--this.openVarrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void beginScroll() {
|
||||||
|
this.buf.append(this.indent("scroll{vertical=\"true\";horizontal=\"false\";"));
|
||||||
|
++this.indentNum;
|
||||||
|
++this.openScrolls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endScroll() {
|
||||||
|
--this.indentNum;
|
||||||
|
this.buf.append(this.indent("};null;null;"));
|
||||||
|
--this.openScrolls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void beginHorizontalFlow() {
|
||||||
|
this.buf.append(this.indent("harray {"));
|
||||||
|
++this.indentNum;
|
||||||
|
++this.openHarrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endHorizontalFlow() {
|
||||||
|
--this.indentNum;
|
||||||
|
this.buf.append(this.indent("}"));
|
||||||
|
--this.openHarrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void beginTable(int rowCount, String[] columns) {
|
||||||
|
this.buf.append(this.indent("table {rows=\"" + rowCount + "\"; cols=\"" + columns.length + "\";"));
|
||||||
|
++this.indentNum;
|
||||||
|
String[] arrstring = columns;
|
||||||
|
int n = arrstring.length;
|
||||||
|
int n2 = 0;
|
||||||
|
while (n2 < n) {
|
||||||
|
String c = arrstring[n2];
|
||||||
|
this.addLabel(c);
|
||||||
|
++n2;
|
||||||
|
}
|
||||||
|
--this.indentNum;
|
||||||
|
++this.indentNum;
|
||||||
|
++this.openTables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endTable() {
|
||||||
|
--this.indentNum;
|
||||||
|
this.buf.append(this.indent("}"));
|
||||||
|
--this.openTables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHidden(String name, String val) {
|
||||||
|
this.buf.append(this.indent("passthrough{id=\"" + name + "\";text=\"" + val + "\"}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String indent(String s) {
|
||||||
|
return this.beautify ? String.valueOf(this.getIndentation()) + s + "\r\n" : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getIndentation() {
|
||||||
|
if (this.indentNum > 0) {
|
||||||
|
return "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t".substring(0, this.indentNum);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRaw(String s) {
|
||||||
|
this.buf.append(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addImage(String url, int height, int width) {
|
||||||
|
this.addImage(url, height, width, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addImage(String url, int height, int width, String tooltip) {
|
||||||
|
this.buf.append("image{src=\"");
|
||||||
|
this.buf.append(url);
|
||||||
|
this.buf.append("\";size=\"");
|
||||||
|
this.buf.append(String.valueOf(height) + "," + width);
|
||||||
|
this.buf.append("\";text=\"" + tooltip + "\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLabel(String text) {
|
||||||
|
this.buf.append("label{text='" + text + "'};");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInput(String id, int maxChars, String defaultText) {
|
||||||
|
this.buf.append("input{id='" + id + "';maxchars='" + maxChars + "';text=\"" + defaultText + "\"};");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addColoredText(String text, int r, int g, int b, String ... args){
|
||||||
|
this.addText(text, "", r, g, b, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBoldText(String text, String ... args) {
|
||||||
|
this.addText(text, "bold", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBoldColoredText(String text, int r, int g, int b, String ... args){
|
||||||
|
this.addText(text, "bold", r, g, b, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addText(String text, String ... args) {
|
||||||
|
this.addText(text, "", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addText(String text, String type, String ... args){
|
||||||
|
this.addText(text, type, -10, -10, -10, args);
|
||||||
|
}
|
||||||
|
private void addText(String text, String type, int r, int g, int b, String ... args) {
|
||||||
|
String[] lines;
|
||||||
|
String[] arrstring = lines = text.split("\n");
|
||||||
|
int n = arrstring.length;
|
||||||
|
int n2 = 0;
|
||||||
|
while (n2 < n) {
|
||||||
|
String l = arrstring[n2];
|
||||||
|
if (this.beautify) {
|
||||||
|
this.buf.append(this.getIndentation());
|
||||||
|
}
|
||||||
|
this.buf.append("text{");
|
||||||
|
if (!type.equals("")) {
|
||||||
|
this.buf.append("type='").append(type).append("';");
|
||||||
|
}
|
||||||
|
if(r >= 0 && g >= 0 && b >= 0 && r <= 255 && g <= 255 && b <= 255){
|
||||||
|
this.buf.append("color='").append(r).append(",").append(g).append(",").append(b).append("';");
|
||||||
|
}
|
||||||
|
this.buf.append("text=\"");
|
||||||
|
this.buf.append(String.format(l, (Object[]) args));
|
||||||
|
this.buf.append("\"}");
|
||||||
|
if (this.beautify) {
|
||||||
|
this.buf.append("\r\n");
|
||||||
|
}
|
||||||
|
++n2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addButton(String name, String id) {
|
||||||
|
this.buf.append(this.indent("button{text=' " + name + " ';id='" + id + "'}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (this.closeDefault) {
|
||||||
|
this.endVerticalFlow();
|
||||||
|
this.endScroll();
|
||||||
|
this.endBorder();
|
||||||
|
this.closeDefault = false;
|
||||||
|
}
|
||||||
|
if (this.openCenters != 0 || this.openVarrays != 0 || this.openScrolls != 0 || this.openHarrays != 0 || this.openBorders != 0 || this.openTrees != 0 || this.openRows != 0 || this.openColumns != 0 || this.openTables != 0) {
|
||||||
|
logger.log(Level.SEVERE, "While finalizing BML unclosed (or too many closed) blocks were found (this will likely mean the BML will not work!): center: " + this.openCenters + " vert-flows: " + this.openVarrays + " scroll: " + this.openScrolls + " horiz-flows: " + this.openHarrays + " border: " + this.openBorders + " trees: " + this.openTrees + " rows: " + this.openRows + " columns: " + this.openColumns + " tables: " + this.openTables);
|
||||||
|
}
|
||||||
|
return this.buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user