I'm writing something like SRM, and everything is fine until server reset. When I'm writing a sign and trying to buy it (region assigned to sign) it should send me a message that I can't, and it does, but after a server reset it doesn't, and in both cases variables are the same... This is my code:
package pl.maccraft.regs;
import java.util.logging.Logger;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import com.sk89q.worldguard.bukkit.RegionContainer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.plugin.Plugin;
public final class egs extends JavaPlugin implements Listener {
private static final Logger log = Logger.getLogger("Minecraft");
public static Economy econ = null;
#Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
getWorldGuard();
if (!setupEconomy() ) {
log.severe(String.format("[%s] - Disabled due to no Vault dependency found!", getDescription().getName()));
getServer().getPluginManager().disablePlugin(this);
return;
}
}
private WorldGuardPlugin getWorldGuard() {
Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard");
// WorldGuard may not be loaded
if (plugin == null || !(plugin instanceof WorldGuardPlugin)) {
return null; // Maybe you want throw an exception instead
}
return (WorldGuardPlugin) plugin;
}
private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return false;
}
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
econ = rsp.getProvider();
return econ != null;
}
#EventHandler
public void playerInteract(PlayerInteractEvent event){
Player player = event.getPlayer();
if(event.getAction() == org.bukkit.event.block.Action.LEFT_CLICK_BLOCK){
Block b = event.getClickedBlock();
if (b.getType() == (Material.SIGN) || b.getType() == (Material.SIGN_POST) || b.getType() == (Material.WALL_SIGN)){
Sign sign = (Sign) b.getState();
if (sign.getLine(0).equals("[sell]")){
if (!sign.getLine(1).isEmpty()){
RegionContainer container = getWorldGuard().getRegionContainer();
RegionManager regions = container.get(player.getWorld());
if (regions != null) {
ProtectedRegion region = regions.getRegion(sign.getLine(1));
if (region != null) {
DefaultDomain owners = region.getOwners();
if(owners.contains(player.getUniqueId())){
if (!sign.getLine(2).isEmpty()){
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say stan:" + econ.getBalance(player));
event.setCancelled(true);
player.sendMessage("To jest twój region");
sign.setLine(0, ChatColor.DARK_RED + "[sprzedam]");
sign.setLine(3, sign.getLine(1));
sign.setLine(1, player.getName());
sign.update(true);
}else{
player.sendMessage("Podaj cenę w trzeciej linii!");
}
}else{
player.sendMessage("To nie jest twój region!");
};
} else {
player.sendMessage("Taki region nie istnieje!");
}
} else {
player.sendMessage("Wystąpił błąd, który nie powinien się zdarzyć, powiadom o tym administrację!");
}
}else{
player.sendMessage("Podaj nazwę regionu w drugiej linii!");
}
}
}
}
if(event.getAction() == org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK){
Block b = event.getClickedBlock();
if (b.getType() == (Material.SIGN) || b.getType() == (Material.SIGN_POST) || b.getType() == (Material.WALL_SIGN)){
Sign sign = (Sign) b.getState();
if (sign.getLine(0).equals(ChatColor.DARK_RED + "[sprzedam]")){
if (event.getPlayer().getName() == sign.getLine(1)){
player.sendMessage("nie możesz kupić własnej działki");
player.sendMessage(event.getPlayer().getName() + " " + sign.getLine(1));
}else{
player.sendMessage(event.getPlayer().getName() + " " + sign.getLine(1));
Double si = Double.valueOf(sign.getLine(2));
if(si <= econ.getBalance(player)){//TO POWINNO BYĆ WIĘKSZE LUB RÓWNE A NIE TAKIE SAMO!!!
RegionContainer container = getWorldGuard().getRegionContainer();
RegionManager regions = container.get(player.getWorld());
if (regions != null) {
ProtectedRegion region = regions.getRegion(sign.getLine(3));
if (region != null) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "eco take " + player.getName() + " " + si);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "eco give " + sign.getLine(1) + " " + si);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "rg removeowner " + sign.getLine(3) + " " + sign.getLine(1));
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "rg addowner " + sign.getLine(3) + " " + player.getName());
sign.setLine(0, ChatColor.DARK_RED + "[sprzedane]");
player.sendMessage("kupiono działkę " + sign.getLine(3) + " za " + si);
sign.setLine(1, event.getPlayer().getName());
sign.setLine(2, "");
sign.setLine(3, "");
sign.update(true);
}
}else{
player.sendMessage("wystąpił błąd");
}
}else{
player.sendMessage("Nie masz wystarczająco dużo kasy!");
}
}
}
}
}
}
}
and console returns only this:
[12:27:42] [Server thread/INFO]: [0;35;1m[Server[0;35;1m] stan:1000.0[m
[12:28:17] [Server thread/INFO]: CONSOLE issued server command: /eco take 10anat10 1000.0
[12:28:17] [Server thread/INFO]: [0;32;1m$1000 zostalo pobrane z [0;31;22m10anat10[m[0;32;1m konta. Nowy stan konta: $0[m
[12:28:17] [Server thread/INFO]: CONSOLE issued server command: /eco give 10anat10 1000.0
[12:28:17] [Server thread/INFO]: [0;32;1m$1000 zostalo dodane do konta [0;31;22m10anat10[m§. Nowy stan konta: $1000.[m
[12:28:17] [Server thread/INFO]: [0;31;1mPlease specify the world with -w world_name.[m
[12:28:17] [Server thread/INFO]: [0;31;1mPlease specify the world with -w world_name.[m
I know that I don't specify world for rg addowner and removeovner, but this isn't it and there are no more errors in the logs... Please help me.
When I change
if(event.getPlayer().getName() == sign.getLine(1)){
to
RegionContainer container = getWorldGuard().getRegionContainer();
RegionManager regions = container.get(player.getWorld());
if(regions != null){
ProtectedRegion region = regions.getRegion(sign.getLine(3));
DefaultDomain owners = region.getOwners();
if(owners.contains(player.getUniqueId())){
It acts as intended.
You need to compare strings rather then checking if the objects are equal.
string1.equals(string2)/string1.equalsIgnoreCase(string2) compares strings while string1 == string2 doesn't.
You could try this:
if (event.getPlayer().getName().equals(sign.getLine(1)))
or if you don't want it case sensitive
if (event.getPlayer().getName().equalsIgnoreCase(sign.getLine(1)))
Related
I'm trying to make it so when someone with the role "Owner" types the mute command, it takes the person they #mentioned and gives them the "Muted" role.
The rest of the code works on it's own, the only part that is not working is the line
event.getGuild().addRoleToMember(member,event.getGuild().getRoleById(0)).complete();
and the variable "member" is defined by
Member member = event.getGuild().getMemberById(mentionid);
The full chunk of code is:
package radishmouse.FoodWorld.Events;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import radishmouse.FoodWorld.FoodWorld;
public class GuildMessageReceived extends ListenerAdapter {
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
String[] args = event.getMessage().getContentRaw().split("\\s+");
if (args[0].equalsIgnoreCase(FoodWorld.prefix + "mute")) {
if (hasRole("Owner", event)) {
if (args.length == 2) {
String mentionid = args[1].replace("<#!", "").replace(">", "");
Member member = event.getGuild().getMemberById(mentionid);
event.getGuild().addRoleToMember(member, event.getGuild().getRoleById(0)).complete();
EmbedBuilder msg = FoodWorld.sendMessage(null, "idk " + mentionid + member, "Blue");
event.getChannel().sendMessageEmbeds(msg.build()).queue();
}
else {
EmbedBuilder msg = FoodWorld.sendMessage("Specify Who To Mute", "Usage: " + FoodWorld.prefix + "mute [#mention who to mute]", "Blue");
event.getChannel().sendMessageEmbeds(msg.build()).queue();
}
}
}
/* If the bot ever sends a message, then add a ❌ reaction so users can delete that message */
if (event.getAuthor().equals(event.getJDA().getSelfUser())) {
event.getMessage().addReaction("❌").queue();
}
}
private boolean hasRole(String string, GuildMessageReceivedEvent event) {
Boolean toReturn = false;
for(int i=0; i < event.getMember().getRoles().size(); i++){
if("Owner".equals(event.getMember().getRoles().get(i).getName())){
toReturn = true;
}
}
return toReturn;
}
For reference, I'm following this tutorial on youtube: tutorial.
I'm not the most familiar with JDA and don't know how this would be done in an easier way.
Instead of parsing the string:
String mentionid = args[1].replace("<#!", "").replace(">", "");
Member member = event.getGuild().getMemberById(mentionid);
Use getMentionedMembers:
List<Member> mentions = event.getMessage().getMentionedMembers();
if (mentions.isEmpty()) {
EmbedBuilder msg = FoodWorld.sendMessage("Specify Who To Mute", "Usage: " + FoodWorld.prefix + "mute [#mention who to mute]", "Blue");
event.getChannel().sendMessageEmbeds(msg.build()).queue();
} else {
Member member = mentions.get(0);
event.getGuild().addRoleToMember(member, event.getGuild().getRoleById(0)).queue();
EmbedBuilder msg = FoodWorld.sendMessage(null, "idk " + member.getId() + member, "Blue");
event.getChannel().sendMessageEmbeds(msg.build()).queue();
}
Is there any way to purge IBM MQ Queue programmatically? I have few messages lying in the Queue but when I read the messages using Consumer code , the messages are still present in the queue. I am assuming there are some uncommitted messages present in queue. I do not have access to MQ explorer so I want to clear the queue programmatically. (either through JMS code or IBM MQ implementation way)
Currently my consumer has jar file com.ibm.mq-6.0.2.1.jar So I prefer to use WMQ classes rather than JMS.
Here is a fully functioning Java/MQ program called 'EmptyQ.java' that will delete all messages on a queue until the queue is empty. Note: It is one of the sample MQ/Java programs that I posted here.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import com.ibm.mq.MQException;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
/**
* Program Name:
* EmptyQ
*
* Description:
* This java class will connect to a remote queue manager with the
* MQ setting stored in a HashTable, loop to retrieve (delete) all messages from
* a queue then close and disconnect.
*
* Sample Command Line Parameters:
* bindings mode:
* -m MQA1 -q TEST.Q1
*
* client mode:
* -m MQA1 -q TEST.Q1 -h 127.0.0.1 -p 1414 -c TEST.CHL -u UserID -x Password
*
* #author Roger Lacroix
*/
public class EmptyQ
{
private static final SimpleDateFormat LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
private Hashtable<String, String> params;
private Hashtable<String, Object> mqht;
/**
* The constructor
*/
public EmptyQ()
{
super();
params = new Hashtable<String, String>();
mqht = new Hashtable<String, Object>();
}
/**
* Make sure the required parameters are present.
*
* #return true/false
*/
private boolean allParamsPresent()
{
boolean b = params.containsKey("-m") && params.containsKey("-q");
if (params.containsKey("-c"))
{
b = b && params.containsKey("-c") && params.containsKey("-h") && params.containsKey("-p");
}
if (b)
{
try
{
if (params.containsKey("-p"))
Integer.parseInt((String) params.get("-p"));
}
catch (NumberFormatException e)
{
b = false;
}
}
return b;
}
/**
* Extract the command-line parameters and initialize the MQ HashTable.
*
* #param args
* #throws IllegalArgumentException
*/
private void init(String[] args) throws IllegalArgumentException
{
int port = 1414;
if (args.length > 0 && (args.length % 2) == 0)
{
for (int i = 0; i < args.length; i += 2)
{
params.put(args[i], args[i + 1]);
}
}
else
{
throw new IllegalArgumentException();
}
if (allParamsPresent())
{
if (params.containsKey("-c"))
{
try
{
port = Integer.parseInt((String) params.get("-p"));
}
catch (NumberFormatException e)
{
port = 1414;
}
mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
if (params.containsKey("-u"))
mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
if (params.containsKey("-x"))
mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));
}
// I don't want to see MQ exceptions at the console.
MQException.log = null;
}
else
{
throw new IllegalArgumentException();
}
}
/**
* Connect, open queue, loop and get all messages then close queue and
* disconnect.
*
*/
private void receive()
{
String qMgrName = (String) params.get("-m");
String inputQName = (String) params.get("-q");
MQQueueManager qMgr = null;
MQQueue queue = null;
int openOptions = CMQC.MQOO_INPUT_AS_Q_DEF + CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_ACCEPT_TRUNCATED_MSG;
MQMessage receiveMsg = null;
int msgCount = 0;
boolean getMore = true;
try
{
if (params.containsKey("-c"))
qMgr = new MQQueueManager(qMgrName, mqht);
else
qMgr = new MQQueueManager(qMgrName);
EmptyQ.logger("successfully connected to " + qMgrName);
queue = qMgr.accessQueue(inputQName, openOptions);
EmptyQ.logger("successfully opened " + inputQName);
while (getMore)
{
receiveMsg = new MQMessage();
try
{
// get the message on the queue - request only 1 byte - make it go as fast as possible.
queue.get(receiveMsg, gmo, 1);
msgCount++;
}
catch (MQException e)
{
if ( (e.completionCode == CMQC.MQCC_FAILED) &&
(e.reasonCode == CMQC.MQRC_NO_MSG_AVAILABLE) )
{
// All messages read.
getMore = false;
break;
}
else if ( (e.completionCode == CMQC.MQCC_WARNING) &&
(e.reasonCode == CMQC.MQRC_TRUNCATED_MSG_ACCEPTED) )
{
msgCount++;
}
else
{
EmptyQ.logger("MQException: " + e.getLocalizedMessage());
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
getMore = false;
break;
}
}
}
}
catch (MQException e)
{
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
}
finally
{
EmptyQ.logger("deleted " + msgCount + " messages");
try
{
if (queue != null)
{
queue.close();
EmptyQ.logger("closed: " + inputQName);
}
}
catch (MQException e)
{
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
}
try
{
if (qMgr != null)
{
qMgr.disconnect();
EmptyQ.logger("disconnected from " + qMgrName);
}
}
catch (MQException e)
{
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
}
}
}
/**
* A simple logger method
*
* #param data
*/
public static void logger(String data)
{
String className = Thread.currentThread().getStackTrace()[2].getClassName();
// Remove the package info.
if ((className != null) && (className.lastIndexOf('.') != -1))
className = className.substring(className.lastIndexOf('.') + 1);
System.out.println(LOGGER_TIMESTAMP.format(new Date()) + " " + className + ": " + Thread.currentThread().getStackTrace()[2].getMethodName() + ": " + data);
}
/**
* main line
*
* #param args
*/
public static void main(String[] args)
{
EmptyQ write = new EmptyQ();
try
{
write.init(args);
write.receive();
}
catch (IllegalArgumentException e)
{
System.err.println("Usage: java EmptyQ -m QueueManagerName -q QueueName [-h host -p port -c channel] [-u UserID] [-x Password]");
System.exit(1);
}
System.exit(0);
}
}
I implemented this in my project recently.
USING WMQ
browse the queue , consume the messages destructively from the queue.
Use CMQC.MQGMO_MSG_UNDER_CURSOR in MQMessageoptions to remove message destructively from the queue.
https://www.ibm.com/docs/en/ibm-mq/9.0?topic=java-mqc
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = CMQC.MQGMO_MSG_UNDER_CURSOR + CMQC.MQGMO_NO_WAIT
+ CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_ACCEPT_TRUNCATED_MSG;
How about something simple like this ?
import java.io.IOException;
import com.ibm.mq.MQException;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;
import com.ibm.msg.client.wmq.WMQConstants;
public class MQClear {
private static final String qManager = "QM1";
private static final String qName = "Q1";
public static void main(String args[]) {
try {
MQQueueManager qMgr = new MQQueueManager(qManager);
int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF;
MQQueue queue = qMgr.accessQueue(qName, openOptions);
// not great: while (queue.getCurrentDepth()>0) {
boolean hasMore = true;
while (hasMore) {
try {
MQMessage mqMsg = new MQMessage();
queue.get(mqMsg);
}
catch (MQException ex) {
hasMore = false;
if( ex.reasonCode!=2033 ) throw ex; // if this was something other than NO_MSG_AVAILABLE, rethrow
}
}
queue.close();
qMgr.disconnect();
}
catch (MQException ex) {
System.out.println("A WebSphere MQ Error occured : Completion Code " + ex.completionCode
+ " Reason Code " + ex.reasonCode);
ex.printStackTrace();
}
}
}
I would like to know how to send a player a list of their shops when they type /shoplist. Also, I would like to know how to change the name of a shop depending on what they type so if they use /shopname Shop1 Pie it would change the name of Shop1 to pie. Or if they do not have a shop called shop1 then it would say a message if they don't have any shops when they make a shop then it builds a new section in the config for them.
Here is my main file:
public class Shops extends JavaPlugin implements Listener {
public void onEnable() {
Bukkit.getServer().getLogger().info("************************");
Bukkit.getServer().getLogger().info("*Shops Plugin Enabled *");
Bukkit.getServer().getLogger().info("*Shops by McMatt *");
Bukkit.getServer().getLogger().info("************************");
Bukkit.getServer().getPluginManager().registerEvents(new Signs(), this);
getConfig().options().copyDefaults(true);
saveConfig();
}
public void onDisable() {
Bukkit.getServer().getLogger().info("************************");
Bukkit.getServer().getLogger().info("*Shops Plugin Disabled *");
Bukkit.getServer().getLogger().info("*Shops by McMatt *");
Bukkit.getServer().getLogger().info("************************");
}
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (cmd.getName().equalsIgnoreCase("shops")) {
if (!(sender instanceof Player)) {
sender.sendMessage("You must be a player to run this command");
return true;
}
Player player = (Player) sender;
if (!player.hasPermission("shops.shops")) {
player.sendMessage(ChatColor.RED + "You do not have to permission (shops.shops)");
return true;
} else {
player.sendMessage(ChatColor.GOLD + "Shops:");
player.sendMessage(ChatColor.RED + "---" + ChatColor.GOLD + "Commands" + ChatColor.RED + "---");
player.sendMessage(ChatColor.DARK_GREEN + "/shops" + ChatColor.GREEN + " Displays this");
player.sendMessage(ChatColor.DARK_GREEN + "/shopslist" + ChatColor.GREEN + " Used to list shops");
player.sendMessage(ChatColor.RED + "---" + ChatColor.GOLD + "Signs" + "---");
player.sendMessage(ChatColor.DARK_GREEN + "First line:" + ChatColor.GREEN + " [shop]");
player.sendMessage(ChatColor.DARK_GREEN + "Second line:" + ChatColor.GREEN + " {Open or Closed}");
}
}
return true;
}
public boolean onCommand1(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (cmd.getName().equalsIgnoreCase("shopslist")) {
sender.sendMessage("Getting shops info!");
sender.sendMessage(getConfig().getString("" + sender.getName()));
return true;
}
return false;
}
}
Here's my listener file
public class Signs implements Listener {
#EventHandler
public void onSignChange(SignChangeEvent e) {
if (e.getLine(0).equalsIgnoreCase("[shop]")) {
Block attached = e.getBlock().getRelative(0, -1, 0);
String name = e.getPlayer().getDisplayName();
if (!(attached.getType() == Material.CHEST))
e.getPlayer().sendMessage(ChatColor.RED + "Please place the shop on a chest!");
else {
if (!e.getPlayer().hasPermission("shops.create"))
e.getPlayer().sendMessage(ChatColor.RED + "You don't have permission to create a shop! (shops.create)");
else {
if (!Arrays.asList("open", "closed").contains(e.getLine(1).toLowerCase())) {
e.getPlayer().sendMessage(ChatColor.RED + "You must specify if the shop is open or closed on the second line!");
} else {
boolean closed = true;
if ("open".equalsIgnoreCase(e.getLine(1))) {
closed = false;
}
String lineThree = closed ? "§cClosed" : "§aOpen";
e.setLine(3, lineThree);
e.setLine(0, "§9[Shop]");
e.setLine(1, "§b" + name + "'s");
e.setLine(2, "§bShop");
e.getPlayer().sendMessage(ChatColor.GREEN + "Shop Created!");
e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.LEVEL_UP, 10, 10);
//if(getConfig().equals(null)){
//int shopAmount = 0;
//shopAmount = shopAmount + 1;
//getConfig().createSection(name);
//getConfig().addDefault(name + ":.Shops:", "Shop" + shopAmount);
}
}
}
}
}
#EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
Player p = e.getPlayer();
Block b = e.getClickedBlock();
Material m = b.getType();
if (!(m == Material.SIGN_POST)) {
return;
} else {
Sign sign = (Sign) e.getClickedBlock().getState();
if ((sign.getLine(0).equalsIgnoreCase("§9[Shop]"))) {
if ((sign.getLine(3).equalsIgnoreCase("§aOpen"))) {
p.sendMessage("I opened the shop!");
}
}
}
}
}
}
And here's my configuration file
McMatt:
- Shop1
You could get the List<String> of all of the player's shops by using
config.getStringList(playerName);
So, for example, if your config looked like this:
McMatt:
- "Shop1"
- "Awesome Shop"
jojodmo:
- "Jojo Shop"
using
config.getStringList("McMatt");
Would return a List<String> containing the strings Shop1 and Awesome Shop.
Also, to avoid a NullPointerException, you should make sure the player has shops in the config by using
if(config.contains(playerName))
and send the player a message telling them that they have no shops.
So, your code could look something like this:
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
if(cmd.getName().equalsIgnoreCase("shops")){
//your code
if(sender instanceof Player){
Player player = (Player) sender;
String name = player.getName();
if(config.contains(name)){
List<String> shops = config.getStringList(name);
for(String shop : shops){
//do something with the shop
}
}
else{
//the user has no shops
}
}
//...
}
}
As I was coding, I tested my plugin and this seemed to happen:
basically, when a player kills another player, his kill count goes up by one. However, when a player has for instance 5 kills, so will all the other players. Here is my code:
public class KillDeathCounter extends JavaPlugin {
public void onEnable() {
new PlayerListener(this);
getLogger().info("Players will not be able to kit spam.");
this.getConfig().addDefault("playerkills", 0);
this.getConfig().addDefault("playerdeaths", 0);
this.getConfig().options().copyDefaults(true);
saveConfig();
}
public void onDisable() {
getLogger().info("Kill Death Counter has been disabled.");
saveConfig();
}
public boolean onCommand(CommandSender sender, Command cmd, String label,
String[] args) {
if (cmd.getName().equalsIgnoreCase("digipvp")) {
Player p = (Player) sender;
p.sendMessage(ChatColor.AQUA
+ "Our PVP plugin was developed by Pierre Lichtlé, the owner, also known as Master Digi."
+ " If you would like to contact him for a plugin, send him an email at developer.petlamb#gmail.com."
+ " Thanks for playing on our server!");
return true;
}
return false;
}
}
package me.katsunicalis.plugin;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
public class PlayerListener implements Listener {
KillDeathCounter kdc;
public PlayerListener(KillDeathCounter plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
kdc = plugin;
}
#EventHandler
public void playerKillsPlayer(EntityDeathEvent e) {
Entity deade = e.getEntity();
Entity killer = e.getEntity().getKiller();
if (killer instanceof Player && deade instanceof Player){
int kills = kdc.getConfig().getInt("playerkills");
int deaths = kdc.getConfig().getInt("playerdeaths");
kdc.getConfig().set("playerkills", kills += 1);
kdc.getConfig().set("playerdeaths", deaths += 1);
killer.sendMessage("You now have " + kills + " kills!");
deade.sendMessage("You now have " + deaths + " deaths!");
}
}
}
Thanks very much guys! :)
The problem is that you're increasing the same variable for every time a player kills another player. To fix this, you should use a different variable for each player, for example "kills.playerUUIDHere" and "deaths.playerUUIDHere".
To get a player's UUID, you can use player.getUniqueId(), then to get the String representation of the UUID, you could use uuid.toString(). So, you could do something like this to change a player's kills:
String uuid = player.getUniqueId().toString();
int kills = kdc.getConfig().getInt("playerkills." + uuid);
kdc.getConfig().set("playerkills." + uuid, kills += 1);
The same logic can be used for deaths, so, you could use something like this for your playerKillsPlayer() method:
#EventHandler
public void playerKillsPlayer(EntityDeathEvent e) {
Entity dead = e.getEntity();
Entity killer = e.getEntity().getKiller();
if(killer instanceof Player && dead instanceof Player){
String killerUUID = ((Player) killer).getUniqueId().toString();
String deadUUID = ((Player) dead).getUniqueId().toString();
int kills = kdc.getConfig().getInt("playerkills." + killerUUID);
int deaths = kdc.getConfig().getInt("playerdeaths." + deadUUID);
kdc.getConfig().set("playerkills." + killerUUID + , kills += 1);
kdc.getConfig().set("playerdeaths." + deadUUID, deaths += 1);
killer.sendMessage("You now have " + kills + " kills!");
dead.sendMessage("You now have " + deaths + " deaths!");
}
}
I am constructing object out of configuration using jaxb.
Until now I wrote custom function for validation but I would like to move into annotations.
e.g.:
#XmlElement
public void setNumber(Integer i){
if (i<10 || i>20) throw new IllegalArgumentException(...);
this.number=i;
}
The exceptions from this above approach were descriptive and gave me the position of the error in the xml.
I want to move into this:
#XmlElement
#Min(10)
#Max(20)
public void setNumber(Integer i){
this.number=i;
}
I can verify this by reading annotations in afterMarshal and running validation functions according to property annotations, but then I lose the actual place (in the xml) where the error occurred.
Do you have any though, should I use a different approach/framework for this problem?
EDIT: just to clarify, I must use annotation approach because I need the properties constraints metadata for the configuration editor I am writing
Here is a XJC plugin that I have used to solve this problem myself (in my case I needed annotations to do validation independant of XML schema, as I also have JMS endpoints):
What it does:
-It generates #valid annotation for objects that are not in the xs default schema (so annotations are cascaded)
-It generates #NotNull annotation for objects that has a MinOccur value >= 1 or for attributes with required use
-It generates #Size for lists that have minOccurs > 1
-It generates #Size if there is a maxLength or minLength restriction
-#DecimalMax for maxInclusive restriction
-#DecimalMin for minInclusive restriction
-#Digits if there is a totalDigits or fractionDigits restriction.
-#Pattern if there is a Pattern restriction
Please note that minExclusive and maxExclusive restrictions are excluded.
To use it, you have to package the class file along a META-INF/services/com.sun.tools.xjc.Plugin file with the content "com.sun.tools.xjc.addon.jaxb.JaxbValidationsPlugins" (that is, the fully qualified name of the class) and call XJC with the -XValidate switch.
It's not really difficult to implement, but I hope it will be useful for someone. The source code is attached as a TXT file. Enjoy!
package com.sun.tools.xjc.addon.jaxb;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.xml.sax.ErrorHandler;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JFieldVar;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.Plugin;
import com.sun.tools.xjc.model.CAttributePropertyInfo;
import com.sun.tools.xjc.model.CElementPropertyInfo;
import com.sun.tools.xjc.model.CPropertyInfo;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.FieldOutline;
import com.sun.tools.xjc.outline.Outline;
import com.sun.xml.xsom.XSComponent;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.impl.AttributeUseImpl;
import com.sun.xml.xsom.impl.ElementDecl;
import com.sun.xml.xsom.impl.ParticleImpl;
public class JaxbValidationsPlugins extends Plugin {
public String getOptionName() {
return "Xvalidate";
}
public List<String> getCustomizationURIs() {
return Collections.singletonList(namespace);
}
private String namespace = "http://jaxb.dev.java.net/plugin/code-injector";
public boolean isCustomizationTagName(String nsUri, String localName) {
return nsUri.equals(namespace) && localName.equals("code");
}
public String getUsage() {
return " -Xvalidate : inject Bean validation annotations (JSR 303)";
}
public boolean run(Outline model, Options opt, ErrorHandler errorHandler) {
try {
for (ClassOutline co : model.getClasses()) {
for (CPropertyInfo property : co.target.getProperties()) {
if (property instanceof CElementPropertyInfo) {
recorrePropiedad((CElementPropertyInfo) property, co, model);
} else if (property instanceof CAttributePropertyInfo) {
recorrePropiedad((CAttributePropertyInfo) property, co, model);
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
static int i = 0;
/**
* XS:Element
*
* #param property
* #param clase
* #param model
*/
public void recorrePropiedad(CElementPropertyInfo property, ClassOutline clase, Outline model) {
FieldOutline field = model.getField(property);
XSComponent definicion = property.getSchemaComponent();
ParticleImpl particle = (ParticleImpl) definicion;
int maxOccurs = ((BigInteger) getField("maxOccurs", particle)).intValue();
int minOccurs = ((BigInteger) getField("minOccurs", particle)).intValue();
JFieldVar var = (JFieldVar) clase.implClass.fields().get(getField("privateName", property));
if (minOccurs < 0 || minOccurs >= 1) {
if (!hasAnnotation(var, NotNull.class)) {
System.out.println("#NotNull: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(NotNull.class);
}
}
if(maxOccurs>1){
if (!hasAnnotation(var, Size.class)) {
System.out.println("#Size ("+minOccurs+","+maxOccurs+") " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(Size.class).param("min", minOccurs).param("max", maxOccurs);
}
}
ElementDecl declaracion = (ElementDecl) getField("term", particle);
if (declaracion.getType().getTargetNamespace().startsWith("http://hotelbeds.com")) {
if (!hasAnnotation(var, Valid.class)) {
System.out.println("#Valid: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(Valid.class);
}
}
if (declaracion.getType() instanceof XSSimpleType) {
procesaType((XSSimpleType) declaracion.getType(), var, property.getName(), clase.implClass.name());
} else if (declaracion.getType().getBaseType() instanceof XSSimpleType) {
procesaType((XSSimpleType) declaracion.getType().getBaseType(), var, property.getName(), clase.implClass.name());
}
// if(declaracion.getType() instanceof
// if(declaracion.getType().ge)
// procesaType(declaracion.getType().getBaseType(),var);
}
/**
* XS:Attribute
*
* #param property
* #param clase
* #param model
*/
public void recorrePropiedad(CAttributePropertyInfo property, ClassOutline clase, Outline model) {
FieldOutline field = model.getField(property);
System.out.println("Tratando attributo " + property.getName() + " de la clase " + clase.implClass.name());
XSComponent definicion = property.getSchemaComponent();
AttributeUseImpl particle = (AttributeUseImpl) definicion;
JFieldVar var = (JFieldVar) clase.implClass.fields().get(getField("privateName", property));
if (particle.isRequired()) {
if (!hasAnnotation(var, NotNull.class)) {
System.out.println("#NotNull: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(NotNull.class);
}
}
if (particle.getDecl().getType().getTargetNamespace().startsWith("http://hotelbeds.com")) {
if (!hasAnnotation(var, Valid.class)) {
System.out.println("#Valid: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(Valid.class);
}
}
procesaType(particle.getDecl().getType(), var, property.getName(), clase.implClass.name());
}
public void procesaType(XSSimpleType tipo, JFieldVar field, String campo, String clase) {
if (tipo.getFacet("maxLength") != null || tipo.getFacet("minLength") != null) {
Integer maxLength = tipo.getFacet("maxLength") == null ? null : parseInt(tipo.getFacet("maxLength").getValue().value);
Integer minLength = tipo.getFacet("minLength") == null ? null : parseInt(tipo.getFacet("minLength").getValue().value);
if (!hasAnnotation(field, Size.class)) {
System.out.println("#Size(" + minLength + "," + maxLength + "): " + campo + " de la clase " + clase);
field.annotate(Size.class).param("min", minLength).param("max", maxLength);
}
}
/*
* <bindings multiple="true" node=
* "//xs:complexType/.//xs:element[contains(#type,'IntPercentRestriction')]"
* > <annox:annotate> <annox:annotate
* annox:class="javax.validation.constraints.Digits" integer="3"
* fraction="2" /> <annox:annotate
* annox:class="javax.validation.constraints.Min" value="-100" />
* value="100" /> </annox:annotate> </bindings>
*//*
* <xs:restriction base="xs:decimal"> <xs:fractionDigits value="2"/>
* <xs:maxInclusive value="100.00"/> <xs:minInclusive
* value="-100.00"/> <xs:totalDigits value="5"/> </xs:restriction>
*/
if (tipo.getFacet("maxInclusive") != null && tipo.getFacet("maxInclusive").getValue().value != null && !hasAnnotation(field,DecimalMax.class)){
System.out.println("#DecimalMax(" + tipo.getFacet("maxInclusive").getValue().value + "): " + campo + " de la clase " + clase);
field.annotate(DecimalMax.class).param("value", tipo.getFacet("maxInclusive").getValue().value);
}
if (tipo.getFacet("minInclusive") != null && tipo.getFacet("minInclusive").getValue().value != null && !hasAnnotation(field,DecimalMin.class)){
System.out.println("#DecimalMin(" + tipo.getFacet("minInclusive").getValue().value + "): " + campo + " de la clase " + clase);
field.annotate(DecimalMin.class).param("value", tipo.getFacet("minInclusive").getValue().value);
}
if (tipo.getFacet("totalDigits") != null) {
Integer totalDigits = tipo.getFacet("totalDigits") == null ? null : parseInt(tipo.getFacet("totalDigits").getValue().value);
int fractionDigits = tipo.getFacet("fractionDigits") == null ? 0 : parseInt(tipo.getFacet("fractionDigits").getValue().value);
if (!hasAnnotation(field, Digits.class)) {
System.out.println("#Digits(" + totalDigits + "," + fractionDigits + "): " + campo + " de la clase " + clase);
JAnnotationUse annox = field.annotate(Digits.class).param("integer", (totalDigits - fractionDigits));
if (tipo.getFacet("fractionDigits") != null) {
annox.param("fraction", fractionDigits);
}
}
}
/**
* <annox:annotate annox:class="javax.validation.constraints.Pattern"
message="Name can only contain capital letters, numbers and the simbols '-', '_', '/', ' '"
regexp="^[A-Z0-9_\s//-]*" />
*/
if(tipo.getFacet("pattern")!=null){
System.out.println("#Pattern(" +tipo.getFacet("pattern").getValue().value+ "): " + campo + " de la clase " + clase);
if (!hasAnnotation(field, Pattern.class)) {
field.annotate(Pattern.class).param("regexp", tipo.getFacet("pattern").getValue().value);
}
}
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public boolean hasAnnotation(JFieldVar var, Class anotacion) {
List<JAnnotationUse> lista = (List<JAnnotationUse>) getField("annotations", var);
if (lista != null) {
for (JAnnotationUse uso : lista) {
if (((Class) getField("clazz._class", uso)).getCanonicalName().equals(anotacion.getCanonicalName())) {
return true;
}
}
}
return false;
}
private Integer parseInt(String valor) {
try {
Integer i = Integer.parseInt(valor);
if (i < 2147483647 && i > -2147483648) {
return i;
}
} catch (Exception e) {
try{
return (int)Math.round(Double.parseDouble(valor));
}catch(Exception ex){
;
}
}
return null;
}
/*
private Long parseLong(String valor) {
try {
Long i = Long.parseLong(valor);
if (i < 2147483647 && i > -2147483648) {
return i;
}
} catch (Exception e) {
return Math.round(Double.parseDouble(valor));
}
return null;
}
*/
private Object getField(String path, Object oo) {
try {
if (path.contains(".")) {
String field = path.substring(0, path.indexOf("."));
Field campo = oo.getClass().getDeclaredField(field);
campo.setAccessible(true);
Object result = campo.get(oo);
return getField(path.substring(path.indexOf(".") + 1), result);
} else {
Field campo = getSimpleField(path, oo.getClass());
campo.setAccessible(true);
return campo.get(oo);
}
} catch (Exception e) {
System.out.println("Field " + path + " not found on " + oo.getClass().getName());
}
return null;
}
private static Field getSimpleField(String fieldName, Class<?> clazz) {
Class<?> tmpClass = clazz;
try {
do {
for (Field field : tmpClass.getDeclaredFields()) {
String candidateName = field.getName();
if (!candidateName.equals(fieldName)) {
continue;
}
field.setAccessible(true);
return field;
}
tmpClass = tmpClass.getSuperclass();
} while (clazz != null);
} catch (Exception e) {
System.out.println("Field '" + fieldName + "' not found on class " + clazz);
}
return null;
}
}
You should look at https://github.com/krasa/krasa-jaxb-tools
which is improved and mavenized version of Vicente's code.
This depends on how are you reading the file and how do you plan to show errors. Using IAE is better if you also plan to construct the class programatically. Using JSR-303 is better when you also use it with JavaEE 6. Also, you must think if your user needs to know the error line number.
And remember: the first (pure-POJO) way ensures that no object will ever be inconsistent (marshalling or unmarshalling), while JSR-303 requires someone to call the validation functions (as well as requiring the framework classes in classpath).