Formated sources, fixed commands losing case

This commit is contained in:
Boosik 2014-08-01 20:57:33 +02:00
parent bf47381423
commit b72aaf3df5
10 changed files with 736 additions and 703 deletions

View File

@ -74,12 +74,10 @@ public class BoosConfigManager {
*/
public static void clearSomething(String co, UUID uuid) {
ConfigurationSection userSection = confusers
.getConfigurationSection("users."
+ uuid + "." + co);
.getConfigurationSection("users." + uuid + "." + co);
if (userSection == null)
return;
confusers.set("users." + uuid + "." + co,
null);
confusers.set("users." + uuid + "." + co, null);
saveConfusers();
loadConfusers();
}
@ -97,8 +95,7 @@ public class BoosConfigManager {
*/
static void clearSomething(String co, UUID uuid, String command) {
int pre2 = command.toLowerCase().hashCode();
confusers.set("users." + uuid + "." + co
+ "." + pre2, 0);
confusers.set("users." + uuid + "." + co + "." + pre2, 0);
saveConfusers();
loadConfusers();
}
@ -119,6 +116,15 @@ public class BoosConfigManager {
.getKeys(false);
return aliases;
}
/**
* @return
*/
static Set<String> getAliasesKeys() {
Set<String> aliases = conf.getConfigurationSection("commands.aliases")
.getKeys(true);
return aliases;
}
/**
* @return
@ -725,10 +731,12 @@ public class BoosConfigManager {
try {
value2 = Integer.parseInt(value);
reload();
conf.set("commands.groups." + group + "." + command + "." + what, value2);
conf.set("commands.groups." + group + "." + command + "." + what,
value2);
} catch (NumberFormatException e1) {
reload();
conf.set("commands.groups." + group + "." + command + "." + what, value);
conf.set("commands.groups." + group + "." + command + "." + what,
value);
}
try {
conf.save(confFile);

View File

@ -11,10 +11,9 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import util.boosChat;
/**
* Hlavn<EFBFBD> poslucha<EFBFBD>, kter<EFBFBD> naslouch<EFBFBD> ud<EFBFBD>losti pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu
* hr<EFBFBD><EFBFBD>em. Kontroluje, jestli jsou pro p<EFBFBD><EFBFBD>kaz nastaveny omezen<EFBFBD> a na
* z<EFBFBD>klad<EFBFBD> tohoto spou<EFBFBD>t<EFBFBD> <EFBFBD>asova<EFBFBD>e a vol<EFBFBD> metody spojen<EFBFBD> s
* poplatky a limity.
* Hlavn<EFBFBD> poslucha<EFBFBD>, kter<EFBFBD> naslouch<EFBFBD> ud<EFBFBD>losti pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu hr<EFBFBD><EFBFBD>em.
* Kontroluje, jestli jsou pro p<EFBFBD><EFBFBD>kaz nastaveny omezen<EFBFBD> a na z<EFBFBD>klad<EFBFBD> tohoto
* spou<EFBFBD>t<EFBFBD> <EFBFBD>asova<EFBFBD>e a vol<EFBFBD> metody spojen<EFBFBD> s poplatky a limity.
*
* @author Jakub Kol<EFBFBD><EFBFBD>
*
@ -30,18 +29,17 @@ public class BoosCoolDownListener implements Listener {
}
/**
* Metoda zkontroluje pomoc<EFBFBD> vol<EFBFBD>n<EFBFBD> dal<EFBFBD><EFBFBD>ch metod, jestli p<EFBFBD>ikaz
* kter<EFBFBD> hr<EFBFBD><EFBFBD> pou<EFBFBD>il je n<EFBFBD>jak<EFBFBD>m zp<EFBFBD>sobem omezen<EFBFBD> a na
* z<EFBFBD>klad<EFBFBD> toho je bu<EFBFBD> ud<EFBFBD>lost pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu stornov<EFBFBD>na,
* nebo ne.
* Metoda zkontroluje pomoc<EFBFBD> vol<EFBFBD>n<EFBFBD> dal<EFBFBD><EFBFBD>ch metod, jestli p<EFBFBD>ikaz kter<EFBFBD> hr<EFBFBD><EFBFBD>
* pou<EFBFBD>il je n<EFBFBD>jak<EFBFBD>m zp<EFBFBD>sobem omezen<EFBFBD> a na z<EFBFBD>klad<EFBFBD> toho je bu<EFBFBD> ud<EFBFBD>lost
* pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu stornov<EFBFBD>na, nebo ne.
*
* @param event
* ud<EFBFBD>lost PlayerCommandPreprocessEvent
* @param player
* hr<EFBFBD><EFBFBD> kter<EFBFBD> spustil tuto ud<EFBFBD>lost
* @param regexCommad
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje
* origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz kter<EFBFBD> hr<EFBFBD><EFBFBD> pou<EFBFBD>il
* @param warmupTime
@ -105,8 +103,8 @@ public class BoosCoolDownListener implements Listener {
BoosConfigManager.getInsufficientFundsMessage(),
(price + " " + unit),
BoosCoolDown.getEconomy().format(
BoosCoolDown.getEconomy().getBalance(
player)));
BoosCoolDown.getEconomy()
.getBalance(player)));
msg = msg.replaceAll("&command&", originalCommand);
boosChat.sendMessageToPlayer(player, msg);
}
@ -154,14 +152,12 @@ public class BoosCoolDownListener implements Listener {
}
/**
* Poslucha<EFBFBD>, kter<EFBFBD> naslouch<EFBFBD> ud<EFBFBD>losti pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu a
* spou<EFBFBD>t<EFBFBD> se je<EFBFBD>t<EFBFBD> p<EFBFBD>ed t<EFBFBD>m, ne<EFBFBD> je vykon<EFBFBD>n efekt tohto
* p<EFBFBD><EFBFBD>kazu. Metoda zji<EFBFBD><EFBFBD>uje, jestli p<EFBFBD><EFBFBD>kaz nen<EFBFBD> alias jin<EFBFBD>ho
* p<EFBFBD><EFBFBD>kazu a tak<EFBFBD> jestli se p<EFBFBD><EFBFBD>kaz kter<EFBFBD> hr<EFBFBD><EFBFBD> pou<EFBFBD>il
* shoduje s p<EFBFBD><EFBFBD>kazem nastaven<EFBFBD>m v konfiguraci. Pokud se shoduje, pak
* jsou na<EFBFBD>teny informace o warmup dob<EFBFBD>, cooldown dob<EFBFBD>, poplatku a
* limitu. Tyto hodnoty jsou pot<EFBFBD> p<EFBFBD>ed<EFBFBD>ny metod<EFBFBD>
* checkRestrictions();.
* Poslucha<EFBFBD>, kter<EFBFBD> naslouch<EFBFBD> ud<EFBFBD>losti pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu a spou<EFBFBD>t<EFBFBD> se je<EFBFBD>t<EFBFBD>
* p<EFBFBD>ed t<EFBFBD>m, ne<EFBFBD> je vykon<EFBFBD>n efekt tohto p<EFBFBD><EFBFBD>kazu. Metoda zji<EFBFBD><EFBFBD>uje, jestli
* p<EFBFBD><EFBFBD>kaz nen<EFBFBD> alias jin<EFBFBD>ho p<EFBFBD><EFBFBD>kazu a tak<EFBFBD> jestli se p<EFBFBD><EFBFBD>kaz kter<EFBFBD> hr<EFBFBD><EFBFBD>
* pou<EFBFBD>il shoduje s p<EFBFBD><EFBFBD>kazem nastaven<EFBFBD>m v konfiguraci. Pokud se shoduje, pak
* jsou na<EFBFBD>teny informace o warmup dob<EFBFBD>, cooldown dob<EFBFBD>, poplatku a limitu.
* Tyto hodnoty jsou pot<EFBFBD> p<EFBFBD>ed<EFBFBD>ny metod<EFBFBD> checkRestrictions();.
*
* @param event
* ud<EFBFBD>lost PlayerCommandPreprocessEvent
@ -171,17 +167,16 @@ public class BoosCoolDownListener implements Listener {
Player player = event.getPlayer();
String originalCommand = event.getMessage().replace("\\", "\\\\");
originalCommand = originalCommand.replace("$", "S");
originalCommand = originalCommand.trim().replaceAll(" +", " ")
.toLowerCase();
originalCommand = originalCommand.trim().replaceAll(" +", " ");
String regexCommad = "";
Set<String> aliases = null;
try {
aliases = BoosConfigManager.getAliases();
} catch (Exception e1) {
BoosCoolDown
.getLog()
.warning(
"Aliases section in config.yml is missing! Please delete your config.yml, restart server and set it again!");
.getLog()
.warning(
"Aliases section in config.yml is missing! Please delete your config.yml, restart server and set it again!");
}
Set<String> commands = BoosConfigManager.getCommands(player);
boolean on = true;
@ -214,7 +209,7 @@ public class BoosCoolDownListener implements Listener {
if (on) {
for (String group : commands) {
String group2 = group.replace("*", ".+");
if (originalCommand.matches(group2)) {
if (originalCommand.matches("(?i)"+group2)) {
regexCommad = group;
if (BoosConfigManager.getWarmupEnabled()) {
warmupTime = BoosConfigManager.getWarmUp(regexCommad,
@ -250,16 +245,16 @@ public class BoosCoolDownListener implements Listener {
}
/**
* Metoda spou<EFBFBD>t<EFBFBD> warmup a cooldown <EFBFBD>asova<EFBFBD>e, p<EFBFBD><EFBFBD>padn<EFBFBD> je
* ukon<EFBFBD>uje, pokud ji<EFBFBD> tyto <EFBFBD>asova<EFBFBD>e skon<EFBFBD>ili.
* Metoda spou<EFBFBD>t<EFBFBD> warmup a cooldown <EFBFBD>asova<EFBFBD>e, p<EFBFBD><EFBFBD>padn<EFBFBD> je ukon<EFBFBD>uje, pokud
* ji<EFBFBD> tyto <EFBFBD>asova<EFBFBD>e skon<EFBFBD>ili.
*
* @param event
* ud<EFBFBD>lost PlayerCommandPreprocessEvent
* @param player
* hr<EFBFBD><EFBFBD> kter<EFBFBD> spustil tuto ud<EFBFBD>lost
* @param regexCommad
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje
* origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz kter<EFBFBD> hr<EFBFBD><EFBFBD> pou<EFBFBD>il
* @param warmupTime

View File

@ -11,42 +11,41 @@ import org.bukkit.entity.Player;
import util.boosChat;
/**
* Třída obsahuje veškeré metody potřebné k řízení cooldown časovačů. Spouštění,
* ukončování, zjišťování zda je cooldown časovač již aktivní.
* T<EFBFBD><EFBFBD>da obsahuje ve<EFBFBD>ker<EFBFBD> metody pot<EFBFBD>ebn<EFBFBD> k <EFBFBD><EFBFBD>zen<EFBFBD> cooldown <EFBFBD>asova<EFBFBD><EFBFBD>. Spou<EFBFBD>t<EFBFBD>n<EFBFBD>,
* ukon<EFBFBD>ov<EFBFBD>n<EFBFBD>, zji<EFBFBD><EFBFBD>ov<EFBFBD>n<EFBFBD> zda je cooldown <EFBFBD>asova<EFBFBD> ji<EFBFBD> aktivn<EFBFBD>.
*
* @author Jakub Kolář
* @author Jakub Kol<EFBFBD><EFBFBD>
*
*/
public class BoosCoolDownManager {
/**
* Metoda ukončuje specifikovaný cooldown časovač pro specifikovaného hráče.
* Metoda ukon<EFBFBD>uje specifikovan<EFBFBD> cooldown <EFBFBD>asova<EFBFBD> pro specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
*/
static void cancelCooldown(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
BoosConfigManager.getConfusers().set(
"users." + player.getUniqueId() + ".cooldown."
+ pre2, null);
"users." + player.getUniqueId() + ".cooldown." + pre2, null);
}
/**
* Metoda vrací hodnotu boolean na základě toho, jestli specifikovaný
* příkaz aktivní cooldown časovač.
* Metoda vrac<EFBFBD> hodnotu boolean na z<EFBFBD>klad<EFBFBD> toho, jestli m<EFBFBD> specifikovan<EFBFBD>
* p<EFBFBD><EFBFBD>kaz aktivn<EFBFBD> cooldown <EFBFBD>asova<EFBFBD>.
*
* @param player
* specifikovaný hráč
* specifikovan<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param coolDownSeconds
* cooldown doba v sekundách, nastavená pro regexCommand v
* cooldown doba v sekund<EFBFBD>ch, nastaven<EFBFBD> pro regexCommand v
* konfiguraci
* @return true pokud je příkaz na cooldown časovači, jinak false
* @return true pokud je p<EFBFBD><EFBFBD>kaz na cooldown <EFBFBD>asova<EFBFBD>i, jinak false
*/
static boolean cd(Player player, String regexCommand,
String originalCommand, int coolDownSeconds) {
@ -110,21 +109,21 @@ public class BoosCoolDownManager {
}
/**
* Metoda kontroluje, jestli hráč nedisponuje oprávněními, která obcházejí
* cooldown časovače. Pokud těmito oprávněními hráč disponuje, pak metoda
* vrací false. Pokud hráč nedisponuje těmito oprávněními, vrací hodnotu
* vrácenou metodou cd();.
* Metoda kontroluje, jestli hr<EFBFBD><EFBFBD> nedisponuje opr<EFBFBD>vn<EFBFBD>n<EFBFBD>mi, kter<EFBFBD> obch<EFBFBD>zej<EFBFBD>
* cooldown <EFBFBD>asova<EFBFBD>e. Pokud t<EFBFBD>mito opr<EFBFBD>vn<EFBFBD>n<EFBFBD>mi hr<EFBFBD><EFBFBD> disponuje, pak metoda
* vrac<EFBFBD> false. Pokud hr<EFBFBD><EFBFBD> nedisponuje t<EFBFBD>mito opr<EFBFBD>vn<EFBFBD>n<EFBFBD>mi, vrac<EFBFBD> hodnotu
* vr<EFBFBD>cenou metodou cd();.
*
* @param player
* specifikovaný hráč
* specifikovan<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param time
* cooldown doba v sekundách, nastavená pro regexCommand v
* cooldown doba v sekund<EFBFBD>ch, nastaven<EFBFBD> pro regexCommand v
* konfiguraci
* @return false pokud hráč disponuje oprávněními, jinak hodnotu vrácenou
* @return false pokud hr<EFBFBD><EFBFBD> disponuje opr<EFBFBD>vn<EFBFBD>n<EFBFBD>mi, jinak hodnotu vr<EFBFBD>cenou
* metodou cd();.
*/
static boolean coolDown(Player player, String regexCommand,
@ -140,9 +139,9 @@ public class BoosCoolDownManager {
}
/**
* Metoda vrací současný přesný datum a čas.
* Metoda vrac<EFBFBD> sou<EFBFBD>asn<EFBFBD> p<EFBFBD>esn<EFBFBD> datum a <EFBFBD>as.
*
* @return současný čas a datum
* @return sou<EFBFBD>asn<EFBFBD> <EFBFBD>as a datum
*/
static Date getCurrTime() {
String currTime = "";
@ -160,13 +159,13 @@ public class BoosCoolDownManager {
}
/**
* Metoda vrací datum a čas, kdy hráč naposledy použil daný příkaz.
* Metoda vrac<EFBFBD> datum a <EFBFBD>as, kdy hr<EFBFBD><EFBFBD> naposledy pou<EFBFBD>il dan<EFBFBD> p<EFBFBD><EFBFBD>kaz.
*
* @param player
* specifikovaný hráč
* specifikovan<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* @return datum a čas kdy hráč naposledy použil daný příkaz
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @return datum a <EFBFBD>as kdy hr<EFBFBD><EFBFBD> naposledy pou<EFBFBD>il dan<EFBFBD> p<EFBFBD><EFBFBD>kaz
*/
static Date getTime(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
@ -190,19 +189,19 @@ public class BoosCoolDownManager {
}
/**
* Metoda vrací hodnotu boolean na základě toho, jestli specifikovaný
* příkaz aktivní cooldown časovač.
* Metoda vrac<EFBFBD> hodnotu boolean na z<EFBFBD>klad<EFBFBD> toho, jestli m<EFBFBD> specifikovan<EFBFBD>
* p<EFBFBD><EFBFBD>kaz aktivn<EFBFBD> cooldown <EFBFBD>asova<EFBFBD>.
*
* @param player
* specifikovaný hráč
* specifikovan<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param time
* cooldown doba v sekundách, nastavená pro regexCommand v
* cooldown doba v sekund<EFBFBD>ch, nastaven<EFBFBD> pro regexCommand v
* konfiguraci
* @return false pokud má příkaz aktivní cooldown časovač, jinak false
* @return false pokud m<EFBFBD> p<EFBFBD><EFBFBD>kaz aktivn<EFBFBD> cooldown <EFBFBD>asova<EFBFBD>, jinak false
*/
static boolean checkCoolDownOK(Player player, String regexCommand,
String originalCommand, int time) {
@ -250,12 +249,12 @@ public class BoosCoolDownManager {
}
/**
* Metoda vrací hodnotu rozdílu v sekundách mezi dvěmi hodnotami datumu a
* času.
* Metoda vrac<EFBFBD> hodnotu rozd<EFBFBD>lu v sekund<EFBFBD>ch mezi dv<EFBFBD>mi hodnotami datumu a
* <EFBFBD>asu.
*
* @param startDate
* @param endDate
* @return rozdíl v sekundách mezi startDate a endDate
* @return rozd<EFBFBD>l v sekund<EFBFBD>ch mezi startDate a endDate
*/
static long secondsBetween(Calendar startDate, Calendar endDate) {
long secondsBetween = 0;
@ -268,13 +267,13 @@ public class BoosCoolDownManager {
}
/**
* Metoda ukládá do databáze datum a čas kdy hráč naposledy použil daný
* příkaz.
* Metoda ukl<EFBFBD>d<EFBFBD> do datab<EFBFBD>ze datum a <EFBFBD>as kdy hr<EFBFBD><EFBFBD> naposledy pou<EFBFBD>il dan<EFBFBD>
* p<EFBFBD><EFBFBD>kaz.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
*/
static void setTime(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
@ -288,10 +287,10 @@ public class BoosCoolDownManager {
}
/**
* Metoda spouští veškeré cooldown časovače pro specifického hráče.
* Metoda spou<EFBFBD>t<EFBFBD> ve<EFBFBD>ker<EFBFBD> cooldown <EFBFBD>asova<EFBFBD>e pro specifick<EFBFBD>ho hr<EFBFBD><EFBFBD>e.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param message
*/
public static void startAllCooldowns(Player player, String message) {

View File

@ -9,32 +9,32 @@ import org.bukkit.inventory.ItemStack;
import util.boosChat;
/**
* Třída obsahuje veškeré metody potřebné k řízení poplatků za příkazy.
* T<EFBFBD><EFBFBD>da obsahuje ve<EFBFBD>ker<EFBFBD> metody pot<EFBFBD>ebn<EFBFBD> k <EFBFBD><EFBFBD>zen<EFBFBD> poplatk<EFBFBD> za p<EFBFBD><EFBFBD>kazy.
*
* @author Jakub Kolář
* @author Jakub Kol<EFBFBD><EFBFBD>
*
*/
public class BoosItemCostManager {
private static String msg = "";
/**
* Metoda zajišťuje funkci platby za příkaz. Vrací hodnotu v vislosti na
* úspěšnosti platby.
* Metoda zaji<EFBFBD><EFBFBD>uje funkci platby za p<EFBFBD><EFBFBD>kaz. Vrac<EFBFBD> hodnotu v z<EFBFBD>vislosti na
* <EFBFBD>sp<EFBFBD>nosti platby.
*
* @param player
* specifikovaný hráč
* specifikovan<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param item
* @param price
* cena použití příkazu
* cena pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu
* @param name
* jméno specifického hráče
* @return true pokud byl úspěšně zaplacen poplatek, nebo pokud nebyl
* nalezen ekonomický plugin; false pokud došlo k chybě nebo hráč
* neměl dostatek financí
* jm<EFBFBD>no specifick<EFBFBD>ho hr<EFBFBD><EFBFBD>e
* @return true pokud byl <EFBFBD>sp<EFBFBD>n<EFBFBD> zaplacen poplatek, nebo pokud nebyl nalezen
* ekonomick<EFBFBD> plugin; false pokud do<EFBFBD>lo k chyb<EFBFBD> nebo hr<EFBFBD><EFBFBD> nem<EFBFBD>l
* dostatek financ<EFBFBD>
*/
static boolean payItemForCommand(Player player, String regexCommand,
String originalCommand, String item, int count, String name) {
@ -64,21 +64,21 @@ public class BoosItemCostManager {
}
/**
* Metoda ukončuje/neukončuje událost použití příkazu v vislosti na tom,
* jakou hodnotu vrátila metoda payForCommand(Player player, String
* Metoda ukon<EFBFBD>uje/neukon<EFBFBD>uje ud<EFBFBD>lost pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu v z<EFBFBD>vislosti na tom,
* jakou hodnotu vr<EFBFBD>tila metoda payForCommand(Player player, String
* regexCommand, String originalCommand, double price, String name);.
*
* @param event
* událost PlayerCommandPreprocessEvent
* ud<EFBFBD>lost PlayerCommandPreprocessEvent
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfigurace vyhovující originálnímu příkazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param item
* @param price
* cena použití příkazu
* cena pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu
*/
static void payItemForCommand(PlayerCommandPreprocessEvent event,
Player player, String regexCommand, String originalCommand,

View File

@ -5,27 +5,27 @@ import org.bukkit.entity.Player;
import util.boosChat;
/**
* Třída obsahuje veškeré metody potřebné k řízení limitů.
* T<EFBFBD><EFBFBD>da obsahuje ve<EFBFBD>ker<EFBFBD> metody pot<EFBFBD>ebn<EFBFBD> k <EFBFBD><EFBFBD>zen<EFBFBD> limit<EFBFBD>.
*
* @author Jakub Kolář
* @author Jakub Kol<EFBFBD><EFBFBD>
*
*/
public class BoosLimitManager {
/**
* Metoda kontroluje zda je možné použít příkaz, nebo zda je příkaz již
* zablokovaný.
* Metoda kontroluje zda je mo<EFBFBD>n<EFBFBD> pou<EFBFBD><EFBFBD>t p<EFBFBD><EFBFBD>kaz, nebo zda je p<EFBFBD><EFBFBD>kaz ji<EFBFBD>
* zablokovan<EFBFBD>.
*
* @param player
* specifická hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param limit
* limit nastavený pro regexCommand
* @return false pokud příkaz je možné použít, true pokud příkaz není možné
* použít
* limit nastaven<EFBFBD> pro regexCommand
* @return false pokud p<EFBFBD><EFBFBD>kaz je mo<EFBFBD>n<EFBFBD> pou<EFBFBD><EFBFBD>t, true pokud p<EFBFBD><EFBFBD>kaz nen<EFBFBD> mo<EFBFBD>n<EFBFBD>
* pou<EFBFBD><EFBFBD>t
*/
static boolean blocked(Player player, String regexCommand,
String originalCommand, int limit) {
@ -44,37 +44,37 @@ public class BoosLimitManager {
}
/**
* Metoda vrací hodnotu, která je určena tím, kolikrát již hráč použil
* specifikovaný příkaz.
* Metoda vrac<EFBFBD> hodnotu, kter<EFBFBD> je ur<EFBFBD>ena t<EFBFBD>m, kolikr<EFBFBD>t ji<EFBFBD> hr<EFBFBD><EFBFBD> pou<EFBFBD>il
* specifikovan<EFBFBD> p<EFBFBD><EFBFBD>kaz.
*
* @param player
* specifická hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* @return hodnota představujíci počet použití specifikovaného příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @return hodnota p<EFBFBD>edstavuj<EFBFBD>ci po<EFBFBD>et pou<EFBFBD>it<EFBFBD> specifikovan<EFBFBD>ho p<EFBFBD><EFBFBD>kazu
*/
static int getUses(Player player, String regexCommand) {
int regexCommand2 = regexCommand.toLowerCase().hashCode();
int uses = 0;
uses = BoosConfigManager.getConfusers().getInt(
"users." + player.getUniqueId() + ".uses."
+ regexCommand2, uses);
"users." + player.getUniqueId() + ".uses." + regexCommand2,
uses);
return uses;
}
/**
* Metoda nastavuje počet použití příkazu o jedna větší po každém použití
* příkazu hráčem. Nastevení hodnoty probíhá jen pro příkazy, které jsou
* definovány v konfiguraci.
* Metoda nastavuje po<EFBFBD>et pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu o jedna v<EFBFBD>t<EFBFBD><EFBFBD> po ka<EFBFBD>d<EFBFBD>m pou<EFBFBD>it<EFBFBD>
* p<EFBFBD><EFBFBD>kazu hr<EFBFBD><EFBFBD>em. Nasteven<EFBFBD> hodnoty prob<EFBFBD>h<EFBFBD> jen pro p<EFBFBD><EFBFBD>kazy, kter<EFBFBD> jsou
* definov<EFBFBD>ny v konfiguraci.
*
* @param player
* specifická hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
*/
static void setUses(Player player, String regexCommand,
String originalCommand) {
@ -103,15 +103,15 @@ public class BoosLimitManager {
}
/**
* Metoda odesílá hráči zprávu o limitovaném příkazu, hodnotu tohoto limitu
* a kolikrát je ještě možné limitovaný příkaz použít.
* Metoda odes<EFBFBD>l<EFBFBD> hr<EFBFBD><EFBFBD>i zpr<EFBFBD>vu o limitovan<EFBFBD>m p<EFBFBD><EFBFBD>kazu, hodnotu tohoto limitu
* a kolikr<EFBFBD>t je je<EFBFBD>t<EFBFBD> mo<EFBFBD>n<EFBFBD> limitovan<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD><EFBFBD>t.
*
* @param send
* hráč kterému bude odeslán seznam
* hr<EFBFBD><EFBFBD> kter<EFBFBD>mu bude odesl<EFBFBD>n seznam
* @param comm
* příkaz o kterém si hráč vyžádal informace
* p<EFBFBD><EFBFBD>kaz o kter<EFBFBD>m si hr<EFBFBD><EFBFBD> vy<EFBFBD><EFBFBD>dal informace
* @param lim
* hodnota limitu na příkazu
* hodnota limitu na p<EFBFBD><EFBFBD>kazu
*/
static void getLimitListMessages(Player send, String comm, int lim) {
if (lim != -1) {

View File

@ -9,8 +9,8 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import util.boosChat;
/**
* T<EFBFBD><EFBFBD>da obsahuje ve<EFBFBD>ker<EFBFBD> metody pot<EFBFBD>ebn<EFBFBD> k <EFBFBD><EFBFBD>zen<EFBFBD> poplatk<EFBFBD>
* pomoc<EFBFBD> v<EFBFBD>c<EFBFBD> za p<EFBFBD><EFBFBD>kazy.
* T<EFBFBD><EFBFBD>da obsahuje ve<EFBFBD>ker<EFBFBD> metody pot<EFBFBD>ebn<EFBFBD> k <EFBFBD><EFBFBD>zen<EFBFBD> poplatk<EFBFBD> pomoc<EFBFBD> v<EFBFBD>c<EFBFBD> za
* p<EFBFBD><EFBFBD>kazy.
*
* @author Jakub Kol<EFBFBD><EFBFBD>
*
@ -20,23 +20,22 @@ public class BoosPriceManager {
private static String msg = "";
/**
* Metoda zaji<EFBFBD><EFBFBD>uje funkci platby za p<EFBFBD><EFBFBD>kaz. Vrac<EFBFBD> hodnotu v
* z<EFBFBD>vislosti na <EFBFBD>sp<EFBFBD>nosti platby.
* Metoda zaji<EFBFBD><EFBFBD>uje funkci platby za p<EFBFBD><EFBFBD>kaz. Vrac<EFBFBD> hodnotu v z<EFBFBD>vislosti na
* <EFBFBD>sp<EFBFBD>nosti platby.
*
* @param player
* specifikovan<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param price
* cena pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu
* @param name
* jm<EFBFBD>no specifick<EFBFBD>ho hr<EFBFBD><EFBFBD>e
* @return true pokud byl <EFBFBD>sp<EFBFBD>n<EFBFBD> zaplacen poplatek, nebo pokud nebyl
* nalezen ekonomick<EFBFBD> plugin; false pokud do<EFBFBD>lo k chyb<EFBFBD> nebo
* hr<EFBFBD><EFBFBD> nem<EFBFBD>l dostatek financ<EFBFBD>
* @return true pokud byl <EFBFBD>sp<EFBFBD>n<EFBFBD> zaplacen poplatek, nebo pokud nebyl nalezen
* ekonomick<EFBFBD> plugin; false pokud do<EFBFBD>lo k chyb<EFBFBD> nebo hr<EFBFBD><EFBFBD> nem<EFBFBD>l
* dostatek financ<EFBFBD>
*/
static boolean payForCommand(Player player, String regexCommand,
String originalCommand, double price, String name) {
@ -72,18 +71,16 @@ public class BoosPriceManager {
}
/**
* Metoda ukon<EFBFBD>uje/neukon<EFBFBD>uje ud<EFBFBD>lost pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu v
* z<EFBFBD>vislosti na tom, jakou hodnotu vr<EFBFBD>tila metoda payForCommand(Player
* player, String regexCommand, String originalCommand, double price, String
* name);.
* Metoda ukon<EFBFBD>uje/neukon<EFBFBD>uje ud<EFBFBD>lost pou<EFBFBD>it<EFBFBD> p<EFBFBD><EFBFBD>kazu v z<EFBFBD>vislosti na tom,
* jakou hodnotu vr<EFBFBD>tila metoda payForCommand(Player player, String
* regexCommand, String originalCommand, double price, String name);.
*
* @param event
* ud<EFBFBD>lost PlayerCommandPreprocessEvent
* @param player
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* p<EFBFBD><EFBFBD>kaz z konfigurace vyhovuj<EFBFBD>c<EFBFBD> origin<EFBFBD>ln<EFBFBD>mu p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param price

View File

@ -11,10 +11,10 @@ import org.bukkit.potion.PotionEffectType;
import util.boosChat;
/**
* Třída obsahuje veškeré metody potřebné k řízení warmup časovačů. Spouštění,
* ukončování a zjišťování zda je warmup časovač již aktivní.
* T<EFBFBD><EFBFBD>da obsahuje ve<EFBFBD>ker<EFBFBD> metody pot<EFBFBD>ebn<EFBFBD> k <EFBFBD><EFBFBD>zen<EFBFBD> warmup <EFBFBD>asova<EFBFBD><EFBFBD>. Spou<EFBFBD>t<EFBFBD>n<EFBFBD>,
* ukon<EFBFBD>ov<EFBFBD>n<EFBFBD> a zji<EFBFBD><EFBFBD>ov<EFBFBD>n<EFBFBD> zda je warmup <EFBFBD>asova<EFBFBD> ji<EFBFBD> aktivn<EFBFBD>.
*
* @author Jakub Kolář
* @author Jakub Kol<EFBFBD><EFBFBD>
*
*/
public class BoosWarmUpManager {
@ -26,16 +26,16 @@ public class BoosWarmUpManager {
private static Timer scheduler;
/**
* Metoda aplikuje na hráče magický efekt na dobu určenou parametrem
* Metoda aplikuje na hr<EFBFBD><EFBFBD>e magick<EFBFBD> efekt na dobu ur<EFBFBD>enou parametrem
* warmUpSeconds.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param warmUpSeconds
* doba warmup v sekundách, nastavená pro regexCommand v
* doba warmup v sekund<EFBFBD>ch, nastaven<EFBFBD> pro regexCommand v
* konfiguraci
*/
static void applyPotionEffect(Player player, String regexCommand,
@ -56,10 +56,10 @@ public class BoosWarmUpManager {
}
/**
* Metoda stornuje veškeré probíhající warmup časovače specifického hráče.
* Metoda stornuje ve<EFBFBD>ker<EFBFBD> prob<EFBFBD>haj<EFBFBD>c<EFBFBD> warmup <EFBFBD>asova<EFBFBD>e specifick<EFBFBD>ho hr<EFBFBD><EFBFBD>e.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
*/
public static void cancelWarmUps(Player player) {
Iterator<String> iter = playercommands.keySet().iterator();
@ -72,10 +72,10 @@ public class BoosWarmUpManager {
}
/**
* Metoda pro specifického hráče vymaže uloženou pozici a svět.
* Metoda pro specifick<EFBFBD>ho hr<EFBFBD><EFBFBD>e vyma<EFBFBD>e ulo<EFBFBD>enou pozici a sv<EFBFBD>t.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
*/
public static void clearLocWorld(Player player) {
BoosWarmUpManager.playerloc.remove(player);
@ -83,12 +83,12 @@ public class BoosWarmUpManager {
}
/**
* Metoda vrací boolean hodnotu v závislosti na tom jestli specifikovaný
* hráč aktivní warmup časovače nebo ne.
* Metoda vrac<EFBFBD> boolean hodnotu v z<EFBFBD>vislosti na tom jestli specifikovan<EFBFBD>
* hr<EFBFBD><EFBFBD> m<EFBFBD> aktivn<EFBFBD> warmup <EFBFBD>asova<EFBFBD>e nebo ne.
*
* @param player
* specifický hráč
* @return true pokud hráč aktivní warmup časovače, jinak false
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @return true pokud hr<EFBFBD><EFBFBD> m<EFBFBD> aktivn<EFBFBD> warmup <EFBFBD>asova<EFBFBD>e, jinak false
*/
public static boolean hasWarmUps(Player player) {
for (String key : playercommands.keySet()) {
@ -100,23 +100,22 @@ public class BoosWarmUpManager {
}
/**
* Metoda zjišťuje, jestli je daný warmup časovač označený jako již proběhlý
* Metoda zji<EFBFBD><EFBFBD>uje, jestli je dan<EFBFBD> warmup <EFBFBD>asova<EFBFBD> ozna<EFBFBD>en<EFBFBD> jako ji<EFBFBD> prob<EFBFBD>hl<EFBFBD>
* nebo ne.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* @return true pokud je warmup časovač označen jako již proběhlý, jinak
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @return true pokud je warmup <EFBFBD>asova<EFBFBD> ozna<EFBFBD>en jako ji<EFBFBD> prob<EFBFBD>hl<EFBFBD>, jinak
* false
*/
static boolean checkWarmUpOK(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
int ok = 0;
ok = BoosConfigManager.getConfusers().getInt(
"users." + player.getUniqueId()
+ ".warmup." + pre2, ok);
"users." + player.getUniqueId() + ".warmup." + pre2, ok);
if (ok == 1) {
return true;
}
@ -124,29 +123,30 @@ public class BoosWarmUpManager {
}
/**
* Metoda vrací boolean hodnotu na základě toho jestli je pro specifikovaný
* příkaz specifikovaného hráče aktivní warmup časovač.
* Metoda vrac<EFBFBD> boolean hodnotu na z<EFBFBD>klad<EFBFBD> toho jestli je pro specifikovan<EFBFBD>
* p<EFBFBD><EFBFBD>kaz specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e aktivn<EFBFBD> warmup <EFBFBD>asova<EFBFBD>.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* @return true pokud je warmup časovač aktivní, jinak false
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @return true pokud je warmup <EFBFBD>asova<EFBFBD> aktivn<EFBFBD>, jinak false
*/
static boolean isWarmUpProcess(Player player, String regexCommand) {
regexCommand = regexCommand.toLowerCase();
if (playercommands.containsKey(player.getUniqueId() + "@" + regexCommand)) {
if (playercommands.containsKey(player.getUniqueId() + "@"
+ regexCommand)) {
return true;
}
return false;
}
/**
* Metoda odstraní všechny časovače specifikovaného hráče
* Metoda odstran<EFBFBD> v<EFBFBD>echny <EFBFBD>asova<EFBFBD>e specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
*/
static void killTimer(Player player) {
for (String key : playercommands.keySet()) {
@ -157,80 +157,77 @@ public class BoosWarmUpManager {
}
/**
* Metoda odstraní časovače na specifikovaném příkazu specifikovaného hráče
* Metoda odstran<EFBFBD> <EFBFBD>asova<EFBFBD>e na specifikovan<EFBFBD>m p<EFBFBD><EFBFBD>kazu specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
*/
static void removeWarmUp(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
BoosConfigManager.getConfusers().set(
"users." + player.getUniqueId()
+ ".warmup." + pre2, null);
"users." + player.getUniqueId() + ".warmup." + pre2, null);
}
/**
* Metoda odstraní ukončené časovače na specifikovaném příkazu
* specifikovaného hráče
* Metoda odstran<EFBFBD> ukon<EFBFBD>en<EFBFBD> <EFBFBD>asova<EFBFBD>e na specifikovan<EFBFBD>m p<EFBFBD><EFBFBD>kazu
* specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
*/
static void removeWarmUpOK(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
BoosConfigManager.getConfusers().set(
"users." + player.getUniqueId()
+ ".warmup." + pre2, null);
"users." + player.getUniqueId() + ".warmup." + pre2, null);
}
/**
* Metoda odstraňuje daný řetězec z Hashmapy
* Metoda odstra<EFBFBD>uje dan<EFBFBD> <EFBFBD>et<EFBFBD>zec z Hashmapy
*
* @param tag
* řetězec, který se odstranit z Hasmapy
* <EFBFBD>et<EFBFBD>zec, kter<EFBFBD> se m<EFBFBD> odstranit z Hasmapy
*/
static void removeWarmUpProcess(String tag) {
BoosWarmUpManager.playercommands.remove(tag);
}
/**
* Metoda označuje warmup časovač specifikovaného příkazu specifikovaného
* hráče jako již ukončený.
* Metoda ozna<EFBFBD>uje warmup <EFBFBD>asova<EFBFBD> specifikovan<EFBFBD>ho p<EFBFBD><EFBFBD>kazu specifikovan<EFBFBD>ho
* hr<EFBFBD><EFBFBD>e jako ji<EFBFBD> ukon<EFBFBD>en<EFBFBD>.
*
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
*/
static void setWarmUpOK(Player player, String regexCommand) {
int pre2 = regexCommand.toLowerCase().hashCode();
BoosConfigManager.getConfusers().set(
"users." + player.getUniqueId()
+ ".warmup." + pre2, 1);
"users." + player.getUniqueId() + ".warmup." + pre2, 1);
}
/**
* Metoda spouští warmup časovač na základě parametrů pomocí Timer(). Pokud
* je již warmup aktivní, odešle hráči zprávu která ho o tom informuje.
* Metoda spou<EFBFBD>t<EFBFBD> warmup <EFBFBD>asova<EFBFBD> na z<EFBFBD>klad<EFBFBD> parametr<EFBFBD> pomoc<EFBFBD> Timer(). Pokud
* je ji<EFBFBD> warmup aktivn<EFBFBD>, ode<EFBFBD>le hr<EFBFBD><EFBFBD>i zpr<EFBFBD>vu kter<EFBFBD> ho o tom informuje.
*
* @param bCoolDown
* instance třídy BoosCooldown
* instance t<EFBFBD><EFBFBD>dy BoosCooldown
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz použitý hráčem
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz pou<EFBFBD>it<EFBFBD> hr<EFBFBD><EFBFBD>em
* @param warmUpSeconds
* warmup doba nastavená pro příkaz v sekundách
* warmup doba nastaven<EFBFBD> pro p<EFBFBD><EFBFBD>kaz v sekund<EFBFBD>ch
*/
static void startWarmUp(BoosCoolDown bCoolDown, Player player,
String regexCommand, String originalCommand, int warmUpSeconds) {

View File

@ -6,9 +6,9 @@ import java.util.TimerTask;
import org.bukkit.entity.Player;
/**
* Třída starající se o samotné časovače warmupů pomocí TimerTask
* T<EFBFBD><EFBFBD>da staraj<EFBFBD>c<EFBFBD> se o samotn<EFBFBD> <EFBFBD>asova<EFBFBD>e warmup<EFBFBD> pomoc<EFBFBD> TimerTask
*
* @author Jakub Kolář
* @author Jakub Kol<EFBFBD><EFBFBD>
*
*/
public class BoosWarmUpTimer extends TimerTask {
@ -20,15 +20,15 @@ public class BoosWarmUpTimer extends TimerTask {
/**
* @param bCoolDown
* instance třídy BoosCoolDown
* instance t<EFBFBD><EFBFBD>dy BoosCoolDown
* @param timer
* @param player
* specifický hráč
* specifick<EFBFBD> hr<EFBFBD><EFBFBD>
* @param regexCommand
* příkaz z konfiguračního souboru, který vyhovuje originálnímu
* příkazu
* p<EFBFBD><EFBFBD>kaz z konfigura<EFBFBD>n<EFBFBD>ho souboru, kter<EFBFBD> vyhovuje origin<EFBFBD>ln<EFBFBD>mu
* p<EFBFBD><EFBFBD>kazu
* @param originalCommand
* originální příkaz který hráč použil
* origin<EFBFBD>ln<EFBFBD> p<EFBFBD><EFBFBD>kaz kter<EFBFBD> hr<EFBFBD><EFBFBD> pou<EFBFBD>il
*/
public BoosWarmUpTimer(BoosCoolDown bCoolDown, Timer timer, Player player,
String regexCommand, String originalCommand) {
@ -60,21 +60,21 @@ public class BoosWarmUpTimer extends TimerTask {
if (player.isOnline() && !player.isDead()
&& BoosWarmUpManager.hasWarmUps(player)) {
BoosWarmUpManager.setWarmUpOK(player, regexCommand);
BoosWarmUpManager.removeWarmUpProcess(player.getUniqueId() + "@"
+ regexCommand);
BoosWarmUpManager.removeWarmUpProcess(player.getUniqueId()
+ "@" + regexCommand);
BoosWarmUpManager.clearLocWorld(player);
player.chat(originalCommand);
} else if (player.isOnline() && player.isDead()
&& BoosWarmUpManager.hasWarmUps(player)) {
BoosWarmUpManager.removeWarmUp(player, regexCommand);
BoosWarmUpManager.removeWarmUpProcess(player.getUniqueId() + "@"
+ regexCommand);
BoosWarmUpManager.removeWarmUpProcess(player.getUniqueId()
+ "@" + regexCommand);
BoosWarmUpManager.clearLocWorld(player);
} else if (!player.isOnline()
&& BoosWarmUpManager.hasWarmUps(player)) {
BoosWarmUpManager.removeWarmUp(player, regexCommand);
BoosWarmUpManager.removeWarmUpProcess(player.getUniqueId() + "@"
+ regexCommand);
BoosWarmUpManager.removeWarmUpProcess(player.getUniqueId()
+ "@" + regexCommand);
BoosWarmUpManager.clearLocWorld(player);
}
}

View File

@ -11,23 +11,23 @@ import cz.boosik.boosCooldown.BoosConfigManager;
import cz.boosik.boosCooldown.BoosCoolDownManager;
/**
* Posluchač naslouchající události, která se spouští v okamžiku kdy hráč zemře.
* V závislosti na konfiguraci pluginu a oprávněních hráče mohou nastat i
* různé aktivity. Cooldown časovače mohou být po smrti vymazány, nebo naopak
* mohou být znovu spuštěny veškeré cooldown časovače pro veškeré nastavené
* příkazy. Také mohou být vymazány záznamy o použitích příkazu a hráč bude opět
* schopen používat limitované příkazy po hodnotu limitu.
* Poslucha<EFBFBD> naslouchaj<EFBFBD>c<EFBFBD> ud<EFBFBD>losti, kter<EFBFBD> se spou<EFBFBD>t<EFBFBD> v okam<EFBFBD>iku kdy hr<EFBFBD><EFBFBD> zem<EFBFBD>e.
* V z<EFBFBD>vislosti na konfiguraci pluginu a opr<EFBFBD>vn<EFBFBD>n<EFBFBD>ch hr<EFBFBD><EFBFBD>e mohou nastat t<EFBFBD>i
* r<EFBFBD>zn<EFBFBD> aktivity. Cooldown <EFBFBD>asova<EFBFBD>e mohou b<EFBFBD>t po smrti vymaz<EFBFBD>ny, nebo naopak
* mohou b<EFBFBD>t znovu spu<EFBFBD>t<EFBFBD>ny ve<EFBFBD>ker<EFBFBD> cooldown <EFBFBD>asova<EFBFBD>e pro ve<EFBFBD>ker<EFBFBD> nastaven<EFBFBD>
* p<EFBFBD><EFBFBD>kazy. Tak<EFBFBD> mohou b<EFBFBD>t vymaz<EFBFBD>ny z<EFBFBD>znamy o pou<EFBFBD>it<EFBFBD>ch p<EFBFBD><EFBFBD>kazu a hr<EFBFBD><EFBFBD> bude op<EFBFBD>t
* schopen pou<EFBFBD><EFBFBD>vat limitovan<EFBFBD> p<EFBFBD><EFBFBD>kazy a<EFBFBD> po hodnotu limitu.
*
* @author Jakub Kolář
* @author Jakub Kol<EFBFBD><EFBFBD>
*
*/
public class BoosPlayerDeathListener implements Listener {
/**
* Metoda zjišťuje jestli je entita která spustila tuto událost hráč a
* jestli není null. Na základě toho spouští další metody.
* Metoda zji<EFBFBD><EFBFBD>uje jestli je entita kter<EFBFBD> spustila tuto ud<EFBFBD>lost hr<EFBFBD><EFBFBD> a
* jestli nen<EFBFBD> null. Na z<EFBFBD>klad<EFBFBD> toho spou<EFBFBD>t<EFBFBD> dal<EFBFBD><EFBFBD> metody.
*
* @param event
* událost PlayerDeathEvent
* ud<EFBFBD>lost PlayerDeathEvent
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
private void onPlayerDeath(PlayerDeathEvent event) {
@ -41,11 +41,11 @@ public class BoosPlayerDeathListener implements Listener {
}
/**
* Na základě konfigurace metoda spouští všechny cooldown časovače
* specifikovaného hráče tím že spustí medotu startAllCooldowns();.
* Na z<EFBFBD>klad<EFBFBD> konfigurace metoda spou<EFBFBD>t<EFBFBD> v<EFBFBD>echny cooldown <EFBFBD>asova<EFBFBD>e
* specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e t<EFBFBD>m <EFBFBD>e spust<EFBFBD> medotu startAllCooldowns();.
*
* @param player
* hráč, který spustil událost PlayerDeathEvent
* hr<EFBFBD><EFBFBD>, kter<EFBFBD> spustil ud<EFBFBD>lost PlayerDeathEvent
*/
private void startCooldownsOnDeath(Player player) {
if (player != null) {
@ -56,13 +56,13 @@ public class BoosPlayerDeathListener implements Listener {
}
/**
* Na základě konfigurace a toho jestli hráč disponuje oprávněním
* booscooldowns.clear.uses.death metoda vymaže všechny záznamy o spuštění
* všech příkazů specifikovaného hráče tím že spustí metodu
* Na z<EFBFBD>klad<EFBFBD> konfigurace a toho jestli hr<EFBFBD><EFBFBD> disponuje opr<EFBFBD>vn<EFBFBD>n<EFBFBD>m
* booscooldowns.clear.uses.death metoda vyma<EFBFBD>e v<EFBFBD>echny z<EFBFBD>znamy o spu<EFBFBD>t<EFBFBD>n<EFBFBD>
* v<EFBFBD>ech p<EFBFBD><EFBFBD>kaz<EFBFBD> specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e t<EFBFBD>m <EFBFBD>e spust<EFBFBD> metodu
* clearSomething();.
*
* @param player
* hráč, který spustil událost PlayerDeathEvent
* hr<EFBFBD><EFBFBD>, kter<EFBFBD> spustil ud<EFBFBD>lost PlayerDeathEvent
*/
private void clearUsesOnDeath(Player player) {
if (player != null
@ -74,19 +74,20 @@ public class BoosPlayerDeathListener implements Listener {
}
/**
* Na základě konfigurace a toho jestli hráč disponuje oprávněním
* booscooldowns.clear.cooldowns.death metoda vymaže echny cooldown
* časovače všech příkazů specifikovaného hráče tím že spustí metodu
* Na z<EFBFBD>klad<EFBFBD> konfigurace a toho jestli hr<EFBFBD><EFBFBD> disponuje opr<EFBFBD>vn<EFBFBD>n<EFBFBD>m
* booscooldowns.clear.cooldowns.death metoda vyma<EFBFBD>e v<EFBFBD>echny cooldown
* <EFBFBD>asova<EFBFBD>e v<EFBFBD>ech p<EFBFBD><EFBFBD>kaz<EFBFBD> specifikovan<EFBFBD>ho hr<EFBFBD><EFBFBD>e t<EFBFBD>m <EFBFBD>e spust<EFBFBD> metodu
* clearSomething();.
*
* @param player
* hráč, který spustil událost PlayerDeathEvent
* hr<EFBFBD><EFBFBD>, kter<EFBFBD> spustil ud<EFBFBD>lost PlayerDeathEvent
*/
private void clearCooldownsOnDeath(Player player) {
if (player != null
&& player.hasPermission("booscooldowns.clear.cooldowns.death")) {
if (BoosConfigManager.getCleanCooldownsOnDeath()) {
BoosConfigManager.clearSomething("cooldown", player.getUniqueId());
BoosConfigManager.clearSomething("cooldown",
player.getUniqueId());
}
}
}

View File

@ -52,462 +52,498 @@ import java.util.zip.GZIPOutputStream;
public class MetricsLite {
/**
* The current revision number
*/
private final static int REVISION = 7;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://report.mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/plugin/%s";
/**
* Interval of time to ping (in minutes)
*/
private final static int PING_INTERVAL = 15;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* Id of the scheduled task
*/
private volatile BukkitTask task = null;
public MetricsLite(Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
this.plugin = plugin;
// load the config
configurationFile = getConfigFile();
configuration = YamlConfiguration.loadConfiguration(configurationFile);
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
configuration.addDefault("debug", false);
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
configuration.options().header("http://mcstats.org").copyDefaults(true);
configuration.save(configurationFile);
}
// Load the guid then
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
}
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send
* the initial data to the metrics backend, and then after that it will post in increments of
* PING_INTERVAL * 1200 ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
public void run() {
try {
// This has to be synchronized or it can collide with the disable method.
synchronized (optOutLock) {
// Disable Task, if it is running and the server owner decided to opt-out
if (isOptOut() && task != null) {
task.cancel();
task = null;
}
}
// We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin(!firstPost);
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
return true;
}
}
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return configuration.getBoolean("opt-out", false);
}
}
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (!isOptOut()) {
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (task != null) {
task.cancel();
task = null;
}
}
}
/**
* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
*
* @return the File object for the config file
*/
public File getConfigFile() {
// I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use
// is to abuse the plugin object we already have
// plugin.getDataFolder() => base/plugins/PluginA/
// pluginsFolder => base/plugins/
// The base is not necessarily relative to the startup directory.
File pluginsFolder = plugin.getDataFolder().getParentFile();
// return => base/plugins/PluginMetrics/config.yml
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(boolean isPing) throws IOException {
// Server software specific section
PluginDescriptionFile description = plugin.getDescription();
String pluginName = description.getName();
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion();
int playersOnline = Bukkit.getServer().getOnlinePlayers().size();
// END server software specific section -- all code below does not use any code outside of this class / Java
// Construct the post data
StringBuilder json = new StringBuilder(1024);
json.append('{');
// The plugin's description file containg all of the plugin data such as name, version, author, etc
appendJSONPair(json, "guid", guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
// New data as of R6
String osname = System.getProperty("os.name");
String osarch = System.getProperty("os.arch");
String osversion = System.getProperty("os.version");
String java_version = System.getProperty("java.version");
int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
osarch = "x86_64";
}
appendJSONPair(json, "osname", osname);
appendJSONPair(json, "osarch", osarch);
appendJSONPair(json, "osversion", osversion);
appendJSONPair(json, "cores", Integer.toString(coreCount));
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
appendJSONPair(json, "ping", "1");
}
// close json
json.append('}');
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
// Connect to the website
URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
byte[] uncompressed = json.toString().getBytes();
byte[] compressed = gzip(json.toString());
// Headers
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", Integer.toString(compressed.length));
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (debug) {
System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
// Write the data
OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if (response == null || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
response = response.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
}
}
/**
* GZip compress a string of bytes
*
* @param input
* @return
*/
public static byte[] gzip(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = null;
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (gzos != null) try {
gzos.close();
} catch (IOException ignore) {
}
}
return baos.toByteArray();
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
return false;
}
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
}
}
/**
* Escape a string to create a valid JSON string
*
* @param text
* @return
*/
private static String escapeJSON(String text) {
StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
char chr = text.charAt(index);
switch (chr) {
case '"':
case '\\':
builder.append('\\');
builder.append(chr);
break;
case '\b':
builder.append("\\b");
break;
case '\t':
builder.append("\\t");
break;
case '\n':
builder.append("\\n");
break;
case '\r':
builder.append("\\r");
break;
default:
if (chr < ' ') {
String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
builder.append(chr);
}
break;
}
}
builder.append('"');
return builder.toString();
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
private static String urlEncode(final String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
/**
* The current revision number
*/
private final static int REVISION = 7;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://report.mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/plugin/%s";
/**
* Interval of time to ping (in minutes)
*/
private final static int PING_INTERVAL = 15;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* Id of the scheduled task
*/
private volatile BukkitTask task = null;
public MetricsLite(Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
this.plugin = plugin;
// load the config
configurationFile = getConfigFile();
configuration = YamlConfiguration.loadConfiguration(configurationFile);
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
configuration.addDefault("debug", false);
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
configuration.options().header("http://mcstats.org")
.copyDefaults(true);
configuration.save(configurationFile);
}
// Load the guid then
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
}
/**
* Start measuring statistics. This will immediately create an async
* repeating task as the plugin and send the initial data to the metrics
* backend, and then after that it will post in increments of PING_INTERVAL
* * 1200 ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
task = plugin.getServer().getScheduler()
.runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
public void run() {
try {
// This has to be synchronized or it can collide
// with the disable method.
synchronized (optOutLock) {
// Disable Task, if it is running and the
// server owner decided to opt-out
if (isOptOut() && task != null) {
task.cancel();
task = null;
}
}
// We use the inverse of firstPost because if it
// is the first time we are posting,
// it is not a interval ping, so it evaluates to
// FALSE
// Each time thereafter it will evaluate to
// TRUE, i.e PING!
postPlugin(!firstPost);
// After the first post we set firstPost to
// false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
if (debug) {
Bukkit.getLogger().log(Level.INFO,
"[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
return true;
}
}
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO,
"[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO,
"[Metrics] " + ex.getMessage());
}
return true;
}
return configuration.getBoolean("opt-out", false);
}
}
/**
* Enables metrics for the server by setting "opt-out" to false in the
* config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the
// task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set
// it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the
* config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the
// task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set
// it.
if (!isOptOut()) {
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (task != null) {
task.cancel();
task = null;
}
}
}
/**
* Gets the File object of the config file that should be used to store data
* such as the GUID and opt-out status
*
* @return the File object for the config file
*/
public File getConfigFile() {
// I believe the easiest way to get the base folder (e.g craftbukkit set
// via -P) for plugins to use
// is to abuse the plugin object we already have
// plugin.getDataFolder() => base/plugins/PluginA/
// pluginsFolder => base/plugins/
// The base is not necessarily relative to the startup directory.
File pluginsFolder = plugin.getDataFolder().getParentFile();
// return => base/plugins/PluginMetrics/config.yml
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(boolean isPing) throws IOException {
// Server software specific section
PluginDescriptionFile description = plugin.getDescription();
String pluginName = description.getName();
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if
// online
// mode is
// enabled
String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion();
int playersOnline = Bukkit.getServer().getOnlinePlayers().size();
// END server software specific section -- all code below does not use
// any code outside of this class / Java
// Construct the post data
StringBuilder json = new StringBuilder(1024);
json.append('{');
// The plugin's description file containg all of the plugin data such as
// name, version, author, etc
appendJSONPair(json, "guid", guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
// New data as of R6
String osname = System.getProperty("os.name");
String osarch = System.getProperty("os.arch");
String osversion = System.getProperty("os.version");
String java_version = System.getProperty("java.version");
int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
osarch = "x86_64";
}
appendJSONPair(json, "osname", osname);
appendJSONPair(json, "osarch", osarch);
appendJSONPair(json, "osversion", osversion);
appendJSONPair(json, "cores", Integer.toString(coreCount));
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
appendJSONPair(json, "ping", "1");
}
// close json
json.append('}');
// Create the url
URL url = new URL(BASE_URL
+ String.format(REPORT_URL, urlEncode(pluginName)));
// Connect to the website
URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
byte[] uncompressed = json.toString().getBytes();
byte[] compressed = gzip(json.toString());
// Headers
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length",
Integer.toString(compressed.length));
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (debug) {
System.out.println("[Metrics] Prepared request for " + pluginName
+ " uncompressed=" + uncompressed.length + " compressed="
+ compressed.length);
}
// Write the data
OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if (response == null || response.startsWith("ERR")
|| response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
response = response
.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
}
}
/**
* GZip compress a string of bytes
*
* @param input
* @return
*/
public static byte[] gzip(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = null;
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (gzos != null)
try {
gzos.close();
} catch (IOException ignore) {
}
}
return baos.toByteArray();
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send
* POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
return false;
}
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(StringBuilder json, String key,
String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
}
}
/**
* Escape a string to create a valid JSON string
*
* @param text
* @return
*/
private static String escapeJSON(String text) {
StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
char chr = text.charAt(index);
switch (chr) {
case '"':
case '\\':
builder.append('\\');
builder.append(chr);
break;
case '\b':
builder.append("\\b");
break;
case '\t':
builder.append("\\t");
break;
case '\n':
builder.append("\\n");
break;
case '\r':
builder.append("\\r");
break;
default:
if (chr < ' ') {
String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
builder.append(chr);
}
break;
}
}
builder.append('"');
return builder.toString();
}
/**
* Encode text as UTF-8
*
* @param text
* the text to encode
* @return the encoded text, as UTF-8
*/
private static String urlEncode(final String text)
throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
}