mirror of
https://github.com/EssentialsX/Essentials.git
synced 2026-11-04 16:50:08 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14cdde009c | ||
|
|
1883e6adbc | ||
|
|
2f9659e7fc | ||
|
|
1a4f63915f | ||
|
|
dd3f4c2921 | ||
|
|
7ebb6359e5 | ||
|
|
069ebfcd5b | ||
|
|
991bc61b0c | ||
|
|
8194d1f747 | ||
|
|
ee7ea2ae39 | ||
|
|
3d23916ad5 | ||
|
|
e5b0c4c855 | ||
|
|
84fd45bd09 | ||
|
|
01883a6b18 | ||
|
|
fd49b70a69 | ||
|
|
3a737480ec | ||
|
|
384f63bf92 | ||
|
|
77dc87bb8e | ||
|
|
c716fc8236 | ||
|
|
c52c1fea9d | ||
|
|
e7c56b32a4 | ||
|
|
11e6d3ca7b | ||
|
|
75481925f7 | ||
|
|
ecb1850451 | ||
|
|
0f4af9e735 | ||
|
|
bf14b88600 | ||
|
|
43d84de2b2 | ||
|
|
25ad8ac9bd | ||
|
|
17051eab73 | ||
|
|
4dc994df3c | ||
|
|
996285c0e3 | ||
|
|
312d1699a8 | ||
|
|
b3238605cc | ||
|
|
b7a4bea52e | ||
|
|
ca71d93963 | ||
|
|
0936fe80bd | ||
|
|
520e8f991f | ||
|
|
3131cadf65 | ||
|
|
bfae6c5c69 | ||
|
|
52c500ee6d | ||
|
|
ba5a8becfc | ||
|
|
2a1957229f | ||
|
|
e6af246170 | ||
|
|
939e5c5a55 | ||
|
|
80bbf8c55b | ||
|
|
376abc4aab | ||
|
|
a7f4d6b16b | ||
|
|
e0d6040662 | ||
|
|
6ec4c97ddd | ||
|
|
db10678095 | ||
|
|
582a357752 | ||
|
|
8a1e7019a7 | ||
|
|
4414eea513 | ||
|
|
6e931b2b3b | ||
|
|
22a0d53cf2 | ||
|
|
20011b9996 | ||
|
|
879e70fb6b | ||
|
|
f91dfed5b4 | ||
|
|
767185ec32 | ||
|
|
4aa93a43db | ||
|
|
57529c4b7d | ||
|
|
dc7fb91939 | ||
|
|
e91ce0c44c | ||
|
|
f7cbc7b0d3 | ||
|
|
28d7abe642 | ||
|
|
0ca58ce4ba | ||
|
|
d75d3cd001 | ||
|
|
1eb5d8a459 | ||
|
|
b808511efe | ||
|
|
0897ef71f2 |
No files matched your search
@@ -7,14 +7,11 @@ contact_links:
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/categories/q-a
|
||||
about: Visit the Q&A forum to search for previous help requests.
|
||||
- name: Check past feature suggestions
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/categories/ideas-and-feature-suggestions
|
||||
url: https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+label%3A%22type%3A+enhancement%22
|
||||
about: Visit the Feature Suggestions forum to view and discuss existing feature suggestions.
|
||||
- name: Create help request
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/new?category=q-a
|
||||
about: Create a support ticket to get help from developers.
|
||||
- name: Suggest a feature
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/new?category=ideas-and-feature-suggestions
|
||||
about: Suggest new features for EssentialsX!
|
||||
- name: Get help from the community on Discord
|
||||
url: https://discord.gg/casfFyh
|
||||
about: Join the MOSS Discord for community-powered EssentialsX support!
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Request a feature
|
||||
description: Suggest a feature you want to see in EssentialsX!
|
||||
labels: 'type: enhancement'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If you have a feature suggestion for EssentialsX, read the following tips:
|
||||
1. Fill out the template.
|
||||
This will help us understand what you're requesting and why you want us
|
||||
to add it.
|
||||
2. Keep it simple.
|
||||
Make sure it's easy to understand what you're requesting. A good way is
|
||||
to keep it to one request per GitHub issue, as we can then easily track
|
||||
feature requests.
|
||||
3. Check whether it has already been asked or added.
|
||||
You can search the issue tracker to see if your feature has already been
|
||||
requested at https://github.com/EssentialsX/Essentials/issues. You can
|
||||
also check the changelogs to see if the feature was recently added:
|
||||
https://github.com/EssentialsX/Essentials/releases
|
||||
4. Ask yourself: "Does this belong in EssentialsX?"
|
||||
There are lots of features that we reject because most servers won't
|
||||
need or use them. If your feature is very specific or already exists in
|
||||
another plugin, it might not be a good fit for EssentialsX.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: Explain what you should expect to happen.
|
||||
placeholder: |
|
||||
What feature are you suggesting?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: How the feature is useful
|
||||
description: Explain what actually happens.
|
||||
placeholder: |
|
||||
How is the feature useful to players, server owners and/or developers?
|
||||
validations:
|
||||
required: true
|
||||
@@ -54,22 +54,43 @@ jobs:
|
||||
./gradlew publish
|
||||
|
||||
- name: Prepare Javadocs
|
||||
if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
|
||||
run: |
|
||||
mv Essentials/build/docs/javadoc/ javadocs/
|
||||
cp -r EssentialsAntiBuild/build/docs/javadoc/ javadocs/EssentialsAntiBuild/
|
||||
cp -r EssentialsChat/build/docs/javadoc/ javadocs/EssentialsChat/
|
||||
cp -r EssentialsDiscord/build/docs/javadoc/ javadocs/EssentialsDiscord/
|
||||
cp -r EssentialsDiscordLink/build/docs/javadoc/ javadocs/EssentialsDiscordLink/
|
||||
cp -r EssentialsGeoIP/build/docs/javadoc/ javadocs/EssentialsGeoIP/
|
||||
cp -r EssentialsProtect/build/docs/javadoc/ javadocs/EssentialsProtect/
|
||||
cp -r EssentialsSpawn/build/docs/javadoc/ javadocs/EssentialsSpawn/
|
||||
cp -r EssentialsXMPP/build/docs/javadoc/ javadocs/EssentialsXMPP/
|
||||
|
||||
- name: Deploy Javadocs
|
||||
if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
|
||||
uses: netlify/actions/cli@master
|
||||
- name: Archive Javadocs
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
args: deploy --dir=javadocs/ --prod --message="GitHubActionsDeploy"
|
||||
name: javadocs
|
||||
path: javadocs/
|
||||
|
||||
publish-jd:
|
||||
name: Publish Javadocs
|
||||
needs: build
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Download Javadocs
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: javadocs
|
||||
path: javadocs/
|
||||
|
||||
- name: Deploy Javadocs
|
||||
run: npx netlify-cli deploy --dir=javadocs/ --prod --message="GitHubActionsDeploy"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_JD_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_JD_2X_SITE_ID }}
|
||||
@@ -15,6 +15,8 @@
|
||||
/Essentials/kits.yml
|
||||
/Essentials/userdata/testplayer1.yml
|
||||
/Essentials/usermap.csv
|
||||
/Essentials/usermap.bin
|
||||
/Essentials/uuids.bin
|
||||
|
||||
# Build files
|
||||
.gradle/
|
||||
|
||||
@@ -28,8 +28,8 @@ public class BalanceTopImpl implements BalanceTop {
|
||||
private void calculateBalanceTopMap() {
|
||||
final List<Entry> entries = new LinkedList<>();
|
||||
BigDecimal newTotal = BigDecimal.ZERO;
|
||||
for (UUID u : ess.getUserMap().getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
for (UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user != null) {
|
||||
if (!ess.getSettings().isNpcsInBalanceRanking() && user.isNPC()) {
|
||||
// Don't list NPCs in output
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.updatecheck.UpdateChecker;
|
||||
import com.earth2me.essentials.userstorage.ModernUserMap;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
@@ -143,7 +144,7 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private static final Logger BUKKIT_LOGGER = Logger.getLogger("Essentials");
|
||||
private static Logger LOGGER = null;
|
||||
private final transient TNTExplodeListener tntListener = new TNTExplodeListener(this);
|
||||
private final transient TNTExplodeListener tntListener = new TNTExplodeListener();
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient ISettings settings;
|
||||
private transient Jails jails;
|
||||
@@ -155,7 +156,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private transient CustomItemResolver customItemResolver;
|
||||
private transient PermissionsHandler permissionsHandler;
|
||||
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
||||
private transient UserMap userMap;
|
||||
@Deprecated
|
||||
private transient UserMap legacyUserMap;
|
||||
private transient ModernUserMap userMap;
|
||||
private transient BalanceTopImpl balanceTop;
|
||||
private transient ExecuteTimer execTimer;
|
||||
private transient MailService mail;
|
||||
@@ -222,7 +225,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
LOGGER.log(Level.INFO, dataFolder.toString());
|
||||
settings = new Settings(this);
|
||||
mail = new MailServiceImpl(this);
|
||||
userMap = new UserMap(this);
|
||||
userMap = new ModernUserMap(this);
|
||||
balanceTop = new BalanceTopImpl(this);
|
||||
permissionsHandler = new PermissionsHandler(this, false);
|
||||
Economy.setEss(this);
|
||||
@@ -301,11 +304,14 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
confList.add(settings);
|
||||
execTimer.mark("Settings");
|
||||
|
||||
upgrade.preModules();
|
||||
execTimer.mark("Upgrade2");
|
||||
|
||||
mail = new MailServiceImpl(this);
|
||||
execTimer.mark("Init(Mail)");
|
||||
|
||||
userMap = new UserMap(this);
|
||||
confList.add(userMap);
|
||||
userMap = new ModernUserMap(this);
|
||||
legacyUserMap = new UserMap(userMap);
|
||||
execTimer.mark("Init(Usermap)");
|
||||
|
||||
balanceTop = new BalanceTopImpl(this);
|
||||
@@ -317,7 +323,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
execTimer.mark("Kits");
|
||||
|
||||
upgrade.afterSettings();
|
||||
execTimer.mark("Upgrade2");
|
||||
execTimer.mark("Upgrade3");
|
||||
|
||||
warps = new Warps(this.getDataFolder());
|
||||
confList.add(warps);
|
||||
@@ -588,7 +594,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
Economy.setEss(null);
|
||||
Trade.closeLog();
|
||||
getUserMap().getUUIDMap().shutdown();
|
||||
getUsers().shutdown();
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
@@ -1067,8 +1073,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Constructing new userfile from base player " + base.getName());
|
||||
}
|
||||
user = new User(base, this);
|
||||
} else {
|
||||
user = userMap.loadUncachedUser(base);
|
||||
|
||||
// The above method will end up creating a new user, but it will not be added to the cache.
|
||||
// Since we already call UserMap#getUser() above, we are already okay with adding the user to the cache,
|
||||
// so we need to manually add the user to the cache in order to avoid a memory leak and maintain behavior.
|
||||
userMap.addCachedUser(user);
|
||||
} else if (base.getClass() != UUIDPlayer.class || user.getBase() == null) {
|
||||
user.update(base);
|
||||
}
|
||||
return user;
|
||||
@@ -1182,11 +1193,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
return this.getScheduler().scheduleSyncRepeatingTask(this, run, delay, period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TNTExplodeListener getTNTListener() {
|
||||
return tntListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionsHandler getPermissionsHandler() {
|
||||
return permissionsHandler;
|
||||
@@ -1203,7 +1209,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public UserMap getUserMap() {
|
||||
return legacyUserMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModernUserMap getUsers() {
|
||||
return userMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -45,7 +46,7 @@ public class EssentialsBlockListener implements Listener {
|
||||
if (is != null && is.getType() != null && !MaterialUtil.isAir(is.getType())) {
|
||||
final ItemStack cloneIs = is.clone();
|
||||
cloneIs.setAmount(1);
|
||||
user.getBase().getInventory().addItem(cloneIs);
|
||||
Inventories.addItem(user.getBase(), cloneIs);
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Location;
|
||||
@@ -52,12 +52,12 @@ public class EssentialsEntityListener implements Listener {
|
||||
if (eDefend instanceof Player) {
|
||||
onPlayerVsPlayerDamage(event, (Player) eDefend, attacker);
|
||||
} else if (eDefend instanceof Ageable) {
|
||||
final ItemStack hand = attacker.getBase().getItemInHand();
|
||||
final ItemStack hand = Inventories.getItemInMainHand(attacker.getBase());
|
||||
if (ess.getSettings().isMilkBucketEasterEggEnabled()
|
||||
&& hand != null && hand.getType() == Material.MILK_BUCKET) {
|
||||
((Ageable) eDefend).setBaby();
|
||||
hand.setType(Material.BUCKET);
|
||||
attacker.getBase().setItemInHand(hand);
|
||||
Inventories.setItemInMainHand(attacker.getBase(), hand);
|
||||
attacker.getBase().updateInventory();
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
}
|
||||
|
||||
private void onPlayerVsPlayerPowertool(final EntityDamageByEntityEvent event, final Player defender, final User attacker) {
|
||||
final List<String> commandList = attacker.getPowertool(attacker.getBase().getItemInHand());
|
||||
final List<String> commandList = attacker.getPowertool(Inventories.getItemInHand(attacker.getBase()));
|
||||
if (commandList != null && !commandList.isEmpty()) {
|
||||
for (final String tempCommand : commandList) {
|
||||
final String command = powertoolPlayer.matcher(tempCommand).replaceAll(defender.getName());
|
||||
@@ -196,73 +196,23 @@ public class EssentialsEntityListener implements Listener {
|
||||
final ISettings.KeepInvPolicy vanish = ess.getSettings().getVanishingItemsPolicy();
|
||||
final ISettings.KeepInvPolicy bind = ess.getSettings().getBindingItemsPolicy();
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01) && (vanish != ISettings.KeepInvPolicy.KEEP || bind != ISettings.KeepInvPolicy.KEEP)) {
|
||||
for (final ItemStack stack : event.getEntity().getInventory()) {
|
||||
if (stack != null && !MaterialUtil.isAir(stack.getType())) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getDrops().add(stack);
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
}
|
||||
}
|
||||
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
} else if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
Inventories.removeItems(user.getBase(), stack -> {
|
||||
if (vanish != ISettings.KeepInvPolicy.KEEP && stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getDrops().add(stack.clone());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now check armor
|
||||
final ItemStack[] armor = event.getEntity().getInventory().getArmorContents();
|
||||
for (int i = 0; i < armor.length; i++) {
|
||||
final ItemStack stack = armor[i];
|
||||
if (stack != null && !MaterialUtil.isAir(stack.getType())) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
armor[i] = null;
|
||||
}
|
||||
}
|
||||
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
} else if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
armor[i] = null;
|
||||
}
|
||||
if (bind != ISettings.KeepInvPolicy.KEEP && stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getDrops().add(stack.clone());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
event.getEntity().getInventory().setArmorContents(armor);
|
||||
|
||||
// Now check offhand
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) {
|
||||
final ItemStack stack = event.getEntity().getInventory().getItemInOffHand();
|
||||
//noinspection ConstantConditions
|
||||
if (stack != null && !MaterialUtil.isAir(stack.getType())) {
|
||||
final boolean isVanish = stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE);
|
||||
final boolean isBind = stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE);
|
||||
if (isVanish || isBind) {
|
||||
event.getEntity().getInventory().setItemInOffHand(null);
|
||||
if ((isVanish && vanish == ISettings.KeepInvPolicy.DROP) || (isBind && bind == ISettings.KeepInvPolicy.DROP)) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.Commandfireball;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.TextInput;
|
||||
@@ -120,6 +121,15 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isGameEventEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.block.BlockReceiveGameEvent");
|
||||
return true;
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
ess.getServer().getPluginManager().registerEvents(this, ess);
|
||||
|
||||
@@ -127,6 +137,10 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
ess.getServer().getPluginManager().registerEvents(new ArrowPickupListener(), ess);
|
||||
}
|
||||
|
||||
if (isGameEventEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new SculkListener1_17(), ess);
|
||||
}
|
||||
|
||||
if (isEntityPickupEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new PickupListener1_12(), ess);
|
||||
} else {
|
||||
@@ -192,17 +206,26 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ess.getSettings().cancelAfkOnMove() && !ess.getSettings().getFreezeAfkPlayers()) {
|
||||
event.getHandlers().unregister(this);
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Unregistering move listener");
|
||||
if (user.isFreeze()) {
|
||||
final Location from = event.getFrom();
|
||||
final Location to = event.getTo().clone();
|
||||
to.setX(from.getX());
|
||||
to.setY(from.getY());
|
||||
to.setZ(from.getZ());
|
||||
try {
|
||||
event.setTo(LocationUtil.getSafeDestination(ess, to));
|
||||
} catch (final Exception ex) {
|
||||
event.setTo(to);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (!ess.getSettings().cancelAfkOnMove() && !ess.getSettings().getFreezeAfkPlayers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.isAfk() && ess.getSettings().getFreezeAfkPlayers()) {
|
||||
final Location from = event.getFrom();
|
||||
final Location origTo = event.getTo();
|
||||
@@ -308,6 +331,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
|
||||
ess.getBackup().onPlayerJoin();
|
||||
final User dUser = ess.getUser(player);
|
||||
dUser.update(player);
|
||||
|
||||
dUser.startTransaction();
|
||||
if (dUser.isNPC()) {
|
||||
@@ -367,7 +391,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
} else if (ess.getSettings().isCustomJoinMessage()) {
|
||||
final String msg = (newUsername ? ess.getSettings().getCustomNewUsernameMessage() : ess.getSettings().getCustomJoinMessage())
|
||||
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
|
||||
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
|
||||
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUsers().getUserCount()))
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
|
||||
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()))
|
||||
.replace("{PREFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(player)))
|
||||
@@ -527,6 +551,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
public void onPlayerLogin(final PlayerLoginEvent event) {
|
||||
if (event.getResult() == Result.KICK_FULL) {
|
||||
final User kfuser = ess.getUser(event.getPlayer());
|
||||
kfuser.update(event.getPlayer());
|
||||
if (kfuser.isAuthorized("essentials.joinfullserver")) {
|
||||
event.allow();
|
||||
return;
|
||||
@@ -557,7 +582,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
final ItemStack stack = new ItemStack(Material.EGG, 1);
|
||||
if (user.hasUnlimited(stack)) {
|
||||
user.getBase().getInventory().addItem(stack);
|
||||
Inventories.addItem(user.getBase(), stack);
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
}
|
||||
@@ -650,7 +675,8 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
}
|
||||
|
||||
if (ess.getSettings().isCommandCooldownsEnabled()
|
||||
&& !user.isAuthorized("essentials.commandcooldowns.bypass")) {
|
||||
&& !user.isAuthorized("essentials.commandcooldowns.bypass")
|
||||
&& (pluginCommand == null || !user.isAuthorized("essentials.commandcooldowns.bypass." + pluginCommand.getName()))) {
|
||||
final int argStartIndex = effectiveCommand.indexOf(" ");
|
||||
final String args = argStartIndex == -1 ? "" // No arguments present
|
||||
: " " + effectiveCommand.substring(argStartIndex); // arguments start at argStartIndex; substring from there.
|
||||
@@ -988,6 +1014,15 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
private final class SculkListener1_17 implements Listener {
|
||||
@EventHandler
|
||||
public void onGameEvent(final org.bukkit.event.block.BlockReceiveGameEvent event) {
|
||||
if (event.getEntity() instanceof Player && ess.getUser((Player) event.getEntity()).isVanished()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class CommandSendFilter implements CommandSendListenerProvider.Filter {
|
||||
@Override
|
||||
public Predicate<String> apply(Player player) {
|
||||
|
||||
@@ -4,9 +4,9 @@ import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import com.earth2me.essentials.config.EssentialsConfiguration;
|
||||
import com.earth2me.essentials.config.EssentialsUserConfiguration;
|
||||
import com.earth2me.essentials.craftbukkit.BanLookup;
|
||||
import com.earth2me.essentials.userstorage.ModernUUIDCache;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import net.ess3.api.IEssentials;
|
||||
@@ -31,10 +31,10 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -47,13 +47,12 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class EssentialsUpgrade {
|
||||
private static final FileFilter YML_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
public static final FileFilter YML_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX);
|
||||
private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$";
|
||||
@@ -93,7 +92,6 @@ public class EssentialsUpgrade {
|
||||
final int showProgress = countFiles % 250;
|
||||
|
||||
if (showProgress == 0) {
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + userdir.list().length);
|
||||
}
|
||||
|
||||
@@ -103,7 +101,8 @@ public class EssentialsUpgrade {
|
||||
final EssentialsUserConfiguration config;
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(name);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
UUID.fromString(name);
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
final File file = new File(userdir, string);
|
||||
final EssentialsConfiguration conf = new EssentialsConfiguration(file);
|
||||
@@ -115,6 +114,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
final String uuidString = conf.getString(uuidConf, null);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
for (int i = 0; i < 4; i++) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidString);
|
||||
@@ -122,7 +122,7 @@ public class EssentialsUpgrade {
|
||||
break;
|
||||
} catch (final Exception ex2) {
|
||||
if (conf.getBoolean("npc", false)) {
|
||||
uuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
uuid = UUID.nameUUIDFromBytes(("NPC:" + (ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name)).getBytes(Charsets.UTF_8));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -130,23 +130,24 @@ public class EssentialsUpgrade {
|
||||
uuid = player.getUniqueId();
|
||||
}
|
||||
|
||||
//noinspection ConstantConditions
|
||||
if (uuid != null) {
|
||||
countBukkit++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection ConstantConditions
|
||||
if (uuid != null) {
|
||||
conf.blockingSave();
|
||||
config = new EssentialsUserConfiguration(name, uuid, new File(userdir, uuid + ".yml"));
|
||||
config.convertLegacyFile();
|
||||
ess.getUserMap().trackUUID(uuid, name, false);
|
||||
ess.getUsers().loadUncachedUser(uuid);
|
||||
continue;
|
||||
}
|
||||
countFails++;
|
||||
}
|
||||
}
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + countFiles + ". Conversion complete.");
|
||||
ess.getLogger().info("Converted via cache: " + countEssCache + " :: Converted via lookup: " + countBukkit + " :: Failed to convert: " + countFails);
|
||||
@@ -913,74 +914,76 @@ public class EssentialsUpgrade {
|
||||
Bukkit.getBanList(BanList.Type.NAME).addBan(playerName, banReason, banTimeout == 0 ? null : new Date(banTimeout), Console.NAME);
|
||||
}
|
||||
|
||||
private void repairUserMap() {
|
||||
if (doneFile.getBoolean("userMapRepaired", false)) {
|
||||
public void generateUidCache() {
|
||||
if (doneFile.getBoolean("newUidCacheBuilt", false)) {
|
||||
return;
|
||||
}
|
||||
ess.getLogger().info("Starting usermap repair");
|
||||
|
||||
final File usermapFile = new File(ess.getDataFolder(), "usermap.bin");
|
||||
final File uidsFile = new File(ess.getDataFolder(), "uuids.bin");
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.isDirectory()) {
|
||||
|
||||
if (!userdataFolder.isDirectory() || usermapFile.exists() || uidsFile.exists()) {
|
||||
ess.getLogger().warning("Missing userdata folder, aborting");
|
||||
doneFile.setProperty("newUidCacheBuilt", true);
|
||||
doneFile.save();
|
||||
return;
|
||||
}
|
||||
final File[] files = userdataFolder.listFiles(YML_FILTER);
|
||||
|
||||
final DecimalFormat format = new DecimalFormat("#0.00");
|
||||
final Map<String, UUID> names = Maps.newHashMap();
|
||||
|
||||
for (int index = 0; index < files.length; index++) {
|
||||
final File file = files[index];
|
||||
try {
|
||||
UUID uuid = null;
|
||||
final String filename = file.getName();
|
||||
final String configData = new String(java.nio.file.Files.readAllBytes(file.toPath()), Charsets.UTF_8);
|
||||
|
||||
if (filename.length() > 36) {
|
||||
try {
|
||||
// ".yml" ending has 4 chars...
|
||||
uuid = UUID.fromString(filename.substring(0, filename.length() - 4));
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
final Matcher uuidMatcher = PATTERN_CONFIG_UUID.matcher(configData);
|
||||
if (uuidMatcher.find()) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidMatcher.group(1));
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
// Don't import
|
||||
continue;
|
||||
}
|
||||
|
||||
final Matcher nameMatcher = PATTERN_CONFIG_NAME.matcher(configData);
|
||||
if (nameMatcher.find()) {
|
||||
final String username = nameMatcher.group(1);
|
||||
if (username != null && username.length() > 0) {
|
||||
names.put(StringUtil.safeString(username), uuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (index % 1000 == 0) {
|
||||
ess.getLogger().info("Reading: " + format.format((100d * (double) index) / files.length)
|
||||
+ "%");
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while reading file: ", e);
|
||||
try {
|
||||
if (!usermapFile.createNewFile() || !uidsFile.createNewFile()) {
|
||||
ess.getLogger().warning("Couldn't create usermap.bin or uuids.bin, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
final Map<UUID, Long> uuids = new HashMap<>();
|
||||
final Map<String, UUID> nameToUuidMap = new HashMap<>();
|
||||
|
||||
final File[] files = userdataFolder.listFiles(YML_FILTER);
|
||||
if (files != null) {
|
||||
for (final File file : files) {
|
||||
try {
|
||||
final String fileName = file.getName();
|
||||
final UUID uuid = UUID.fromString(fileName.substring(0, fileName.length() - 4));
|
||||
final EssentialsConfiguration config = new EssentialsConfiguration(file);
|
||||
config.load();
|
||||
String name = config.getString("last-account-name", null);
|
||||
name = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name;
|
||||
final long time = config.getLong("timestamps.logout", 0L);
|
||||
|
||||
if (name != null) {
|
||||
if (nameToUuidMap.containsKey(name)) {
|
||||
final UUID oldUuid = nameToUuidMap.get(name);
|
||||
if (oldUuid.version() < uuid.version() || (oldUuid.version() == uuid.version() && uuids.get(oldUuid) < time)) {
|
||||
ess.getLogger().warning("New UUID found for " + name + ": " + uuid + " (old: " + oldUuid + "). Replacing.");
|
||||
uuids.remove(oldUuid);
|
||||
} else {
|
||||
ess.getLogger().warning("Found UUID for " + name + ": " + uuid + " (old: " + oldUuid + "). Skipping.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
uuids.put(uuid, config.getLong("timestamps.logout", 0L));
|
||||
nameToUuidMap.put(name, uuid);
|
||||
}
|
||||
} catch (IllegalArgumentException | IndexOutOfBoundsException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!nameToUuidMap.isEmpty()) {
|
||||
ModernUUIDCache.writeNameUuidMap(usermapFile, nameToUuidMap);
|
||||
}
|
||||
|
||||
if (!uuids.isEmpty()) {
|
||||
ModernUUIDCache.writeUuidCache(uidsFile, uuids.keySet());
|
||||
}
|
||||
|
||||
doneFile.setProperty("newUidCacheBuilt", true);
|
||||
doneFile.save();
|
||||
} catch (final IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while generating initial uuids/names cache", e);
|
||||
}
|
||||
|
||||
ess.getUserMap().getNames().putAll(names);
|
||||
ess.getUserMap().reloadConfig();
|
||||
|
||||
doneFile.setProperty("userMapRepaired", true);
|
||||
doneFile.save();
|
||||
ess.getLogger().info("Completed usermap repair.");
|
||||
}
|
||||
|
||||
public void beforeSettings() {
|
||||
@@ -991,6 +994,10 @@ public class EssentialsUpgrade {
|
||||
moveMotdRulesToFile("rules");
|
||||
}
|
||||
|
||||
public void preModules() {
|
||||
generateUidCache();
|
||||
}
|
||||
|
||||
public void afterSettings() {
|
||||
sanitizeAllUserFilenames();
|
||||
updateUsersPowerToolsFormat();
|
||||
@@ -1001,7 +1008,6 @@ public class EssentialsUpgrade {
|
||||
uuidFileChange();
|
||||
banFormatChange();
|
||||
warnMetrics();
|
||||
repairUserMap();
|
||||
convertIgnoreList();
|
||||
convertStupidCamelCaseUserdataKeys();
|
||||
convertMailList();
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import com.earth2me.essentials.commands.PlayerNotFoundException;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.updatecheck.UpdateChecker;
|
||||
import com.earth2me.essentials.userstorage.IUserMap;
|
||||
import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
|
||||
import net.ess3.provider.ContainerProvider;
|
||||
import net.ess3.provider.FormattedCommandAliasProvider;
|
||||
@@ -109,8 +110,6 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
int scheduleSyncRepeatingTask(Runnable run, long delay, long period);
|
||||
|
||||
TNTExplodeListener getTNTListener();
|
||||
|
||||
PermissionsHandler getPermissionsHandler();
|
||||
|
||||
AlternativeCommandsHandler getAlternativeCommandsHandler();
|
||||
@@ -119,6 +118,9 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
IItemDb getItemDb();
|
||||
|
||||
IUserMap getUsers();
|
||||
|
||||
@Deprecated
|
||||
UserMap getUserMap();
|
||||
|
||||
BalanceTop getBalanceTop();
|
||||
|
||||
@@ -282,6 +282,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
int getMaxUserCacheCount();
|
||||
|
||||
long getMaxUserCacheValueExpiry();
|
||||
|
||||
boolean allowSilentJoinQuit();
|
||||
|
||||
boolean isCustomJoinMessage();
|
||||
|
||||
@@ -155,6 +155,8 @@ public interface IUser {
|
||||
|
||||
void delHome(String name) throws Exception;
|
||||
|
||||
void renameHome(String name, String newName) throws Exception;
|
||||
|
||||
boolean hasHome();
|
||||
|
||||
Location getLastLocation();
|
||||
@@ -330,4 +332,12 @@ public interface IUser {
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> getPastUsernames();
|
||||
|
||||
void addPastUsername(String username);
|
||||
|
||||
boolean isFreeze();
|
||||
|
||||
void setFreeze(boolean freeze);
|
||||
}
|
||||
@@ -203,6 +203,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
private class JailListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockBreak(final BlockBreakEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-break")) {
|
||||
event.setCancelled(true);
|
||||
@@ -211,6 +215,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockPlace(final BlockPlaceEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-place")) {
|
||||
event.setCancelled(true);
|
||||
@@ -219,6 +227,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockDamage(final BlockDamageEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-block-damage")) {
|
||||
event.setCancelled(true);
|
||||
@@ -232,6 +244,9 @@ public class Jails implements net.ess3.api.IJails {
|
||||
}
|
||||
final Entity damager = event.getDamager();
|
||||
if (damager.getType() == EntityType.PLAYER) {
|
||||
if (shouldIgnore((Player) damager)) {
|
||||
return;
|
||||
}
|
||||
final User user = ess.getUser((Player) damager);
|
||||
if (user != null && user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
@@ -241,6 +256,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerInteract(final PlayerInteractEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-interact")) {
|
||||
event.setCancelled(true);
|
||||
@@ -249,6 +268,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerGameModeChange(final PlayerGameModeChangeEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
@@ -257,6 +280,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onJailPlayerRespawn(final PlayerRespawnEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
||||
return;
|
||||
@@ -275,6 +302,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onJailPlayerTeleport(final PlayerTeleportEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
||||
return;
|
||||
@@ -294,6 +325,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onJailPlayerJoin(final PlayerJoinEvent event) {
|
||||
if (shouldIgnore(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
user.checkJailTimeout(currentTime);
|
||||
@@ -318,5 +353,10 @@ public class Jails implements net.ess3.api.IJails {
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldIgnore(final Player base) {
|
||||
// Ignore Citizens NPCs
|
||||
return base.getUniqueId().version() == 2 || base.hasMetadata("NPC");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,22 @@ package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.commands.NoChargeException;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.events.KitClaimEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
@@ -214,57 +213,34 @@ public class Kit {
|
||||
stack = metaStack.getItemStack();
|
||||
}
|
||||
|
||||
if (autoEquip) {
|
||||
final Material material = stack.getType();
|
||||
final PlayerInventory inventory = user.getBase().getInventory();
|
||||
if (MaterialUtil.isHelmet(material) && isEmptyStack(inventory.getHelmet())) {
|
||||
inventory.setHelmet(stack);
|
||||
continue;
|
||||
} else if (MaterialUtil.isChestplate(material) && isEmptyStack(inventory.getChestplate())) {
|
||||
inventory.setChestplate(stack);
|
||||
continue;
|
||||
} else if (MaterialUtil.isLeggings(material) && isEmptyStack(inventory.getLeggings())) {
|
||||
inventory.setLeggings(stack);
|
||||
continue;
|
||||
} else if (MaterialUtil.isBoots(material) && isEmptyStack(inventory.getBoots())) {
|
||||
inventory.setBoots(stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
itemList.add(stack);
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> overfilled;
|
||||
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
|
||||
final int maxStackSize = user.isAuthorized("essentials.oversizedstacks") ? ess.getSettings().getOversizedStackSize() : 0;
|
||||
final boolean isDropItemsIfFull = ess.getSettings().isDropItemsIfFull();
|
||||
if (isDropItemsIfFull) {
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
|
||||
|
||||
final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]);
|
||||
if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, itemArray)) {
|
||||
user.sendMessage(tl("kitInvFullNoDrop"));
|
||||
return false;
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> leftover = Inventories.addItem(user.getBase(), maxStackSize, autoEquip, itemArray);
|
||||
if (!isDropItemsIfFull && !leftover.isEmpty()) {
|
||||
// Inventories#hasSpace should prevent this state from EVER being reached; If it does, something has gone terribly wrong, and we should just give up and hope people report it :(
|
||||
throw new IllegalStateException("Something has gone terribly wrong while adding items to the user's inventory. Please report this to the EssentialsX developers. Items left over: " + leftover + ". Original items: " + Arrays.toString(itemArray));
|
||||
}
|
||||
|
||||
for (final ItemStack itemStack : leftover.values()) {
|
||||
int spillAmount = itemStack.getAmount();
|
||||
if (maxStackSize != 0) {
|
||||
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
|
||||
}
|
||||
for (final ItemStack itemStack : overfilled.values()) {
|
||||
int spillAmount = itemStack.getAmount();
|
||||
if (!allowOversizedStacks) {
|
||||
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
|
||||
}
|
||||
while (spillAmount > 0) {
|
||||
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
|
||||
spillAmount -= itemStack.getAmount();
|
||||
}
|
||||
spew = true;
|
||||
}
|
||||
} else {
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addAllOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addAllItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
|
||||
}
|
||||
if (overfilled != null) {
|
||||
user.sendMessage(tl("kitInvFullNoDrop"));
|
||||
return false;
|
||||
while (spillAmount > 0) {
|
||||
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
|
||||
spillAmount -= itemStack.getAmount();
|
||||
}
|
||||
spew = true;
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
|
||||
@@ -291,8 +267,4 @@ public class Kit {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isEmptyStack(ItemStack stack) {
|
||||
return stack == null || MaterialUtil.isAir(stack.getType());
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IUser;
|
||||
import net.essentialsx.api.v2.services.mail.MailService;
|
||||
import net.essentialsx.api.v2.events.UserMailEvent;
|
||||
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||
import net.essentialsx.api.v2.services.mail.MailSender;
|
||||
import net.essentialsx.api.v2.services.mail.MailService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -35,6 +37,12 @@ public class MailServiceImpl implements MailService {
|
||||
}
|
||||
|
||||
private void sendMail(IUser recipient, MailMessage message) {
|
||||
final UserMailEvent event = new UserMailEvent(recipient, message);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<MailMessage> messages = recipient.getMailMessages();
|
||||
messages.add(0, message);
|
||||
recipient.setMailList(messages);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
@@ -362,8 +362,8 @@ public enum MobData {
|
||||
((Horse) spawned).getInventory().setArmor(new ItemStack((Material) this.value, 1));
|
||||
} else if (this.type.equals(EntityType.ZOMBIE.getEntityClass()) || this.type.equals(EntityType.SKELETON)) {
|
||||
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack((Material) this.value, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
Inventories.setItemInMainHand(invent, new ItemStack((Material) this.value, 1));
|
||||
Inventories.setItemInMainHandDropChance(invent, 0.1f);
|
||||
}
|
||||
} else if (this.value.equals(Data.RAID_LEADER)) {
|
||||
((Raider) spawned).setPatrolLeader(true);
|
||||
|
||||
@@ -4,15 +4,17 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerTarget implements ITarget {
|
||||
private final String name;
|
||||
private final UUID uuid;
|
||||
|
||||
public PlayerTarget(final Player entity) {
|
||||
this.name = entity.getName();
|
||||
this.uuid = entity.getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return Bukkit.getServer().getPlayerExact(name).getLocation();
|
||||
return Bukkit.getPlayer(uuid).getLocation();
|
||||
}
|
||||
}
|
||||
@@ -1469,10 +1469,16 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
// #easteregg
|
||||
@Override
|
||||
public int getMaxUserCacheCount() {
|
||||
final long count = Runtime.getRuntime().maxMemory() / 1024 / 96;
|
||||
final long count = Runtime.getRuntime().maxMemory() / 1024 / 1024;
|
||||
return config.getInt("max-user-cache-count", (int) count);
|
||||
}
|
||||
|
||||
// #easteregg
|
||||
@Override
|
||||
public long getMaxUserCacheValueExpiry() {
|
||||
return config.getLong("max-user-cache-value-expiry", 600);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastMessageReplyRecipient() {
|
||||
return config.getBoolean("last-message-reply-recipient", false);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.Mob.MobException;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
@@ -251,8 +251,8 @@ public final class SpawnMob {
|
||||
private static void defaultMobData(final EntityType type, final Entity spawned) {
|
||||
if (type == EntityType.SKELETON) {
|
||||
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(Material.BOW, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
Inventories.setItemInMainHand(invent, new ItemStack(Material.BOW, 1));
|
||||
Inventories.setItemInMainHandDropChance(invent, 0.1f);
|
||||
}
|
||||
|
||||
if (type == MobCompat.ZOMBIFIED_PIGLIN) {
|
||||
@@ -260,8 +260,8 @@ public final class SpawnMob {
|
||||
setVillager(zombie, false);
|
||||
|
||||
final EntityEquipment invent = zombie.getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(GOLDEN_SWORD, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
Inventories.setItemInMainHand(invent, new ItemStack(GOLDEN_SWORD, 1));
|
||||
Inventories.setItemInMainHandDropChance(invent, 0.1f);
|
||||
}
|
||||
|
||||
if (type == EntityType.ZOMBIE) {
|
||||
|
||||
@@ -1,51 +1,22 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import com.earth2me.essentials.commands.Commandnuke;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
|
||||
public class TNTExplodeListener implements Listener, Runnable {
|
||||
private final transient IEssentials ess;
|
||||
private transient boolean enabled = false;
|
||||
private transient int timer = -1;
|
||||
|
||||
public TNTExplodeListener(final IEssentials ess) {
|
||||
super();
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
if (!enabled) {
|
||||
enabled = true;
|
||||
timer = ess.scheduleSyncDelayedTask(this, 200);
|
||||
return;
|
||||
}
|
||||
if (timer != -1) {
|
||||
ess.getScheduler().cancelTask(timer);
|
||||
timer = ess.scheduleSyncDelayedTask(this, 200);
|
||||
}
|
||||
}
|
||||
|
||||
public class TNTExplodeListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onEntityExplode(final EntityExplodeEvent event) {
|
||||
if (!enabled) {
|
||||
if (!(event.getEntity() instanceof TNTPrimed)) {
|
||||
return;
|
||||
}
|
||||
if (event.getEntity() instanceof LivingEntity) {
|
||||
return;
|
||||
}
|
||||
if (event.blockList().size() < 1) {
|
||||
if (!event.getEntity().hasMetadata(Commandnuke.NUKE_META_KEY)) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
event.getLocation().getWorld().createExplosion(event.getLocation(), 0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.craftbukkit.SetExpFix;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
@@ -8,7 +8,6 @@ import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
@@ -16,6 +15,7 @@ import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -197,7 +197,7 @@ public class Trade {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getItemStack() != null && !user.getBase().getInventory().containsAtLeast(itemStack, itemStack.getAmount())) {
|
||||
if (getItemStack() != null && !Inventories.containsAtLeast(user.getBase(), itemStack, itemStack.getAmount())) {
|
||||
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack()))));
|
||||
return;
|
||||
}
|
||||
@@ -225,52 +225,33 @@ public class Trade {
|
||||
user.giveMoney(getMoney());
|
||||
}
|
||||
if (getItemStack() != null) {
|
||||
// This stores the would be overflow
|
||||
final Map<Integer, ItemStack> overFlow = InventoryWorkaround.addAllItems(user.getBase().getInventory(), getItemStack());
|
||||
if (type == OverflowType.ABORT && !Inventories.hasSpace(user.getBase(), 0, false, getItemStack())) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "abort paying " + user.getName() + " itemstack " + getItemStack().toString() + " due to lack of inventory space ");
|
||||
}
|
||||
return Collections.singletonMap(0, getItemStack());
|
||||
}
|
||||
|
||||
if (overFlow != null) {
|
||||
switch (type) {
|
||||
case ABORT:
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "abort paying " + user.getName() + " itemstack " + getItemStack().toString() + " due to lack of inventory space ");
|
||||
final Map<Integer, ItemStack> leftover = Inventories.addItem(user.getBase(), getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
if (!leftover.isEmpty()) {
|
||||
if (type == OverflowType.RETURN) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " with overflow " + leftover.get(0).toString());
|
||||
}
|
||||
return leftover;
|
||||
} else {
|
||||
for (final ItemStack itemStack : leftover.values()) {
|
||||
int spillAmount = itemStack.getAmount();
|
||||
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
|
||||
while (spillAmount > 0) {
|
||||
user.getBase().getWorld().dropItemNaturally(user.getBase().getLocation(), itemStack);
|
||||
spillAmount -= itemStack.getAmount();
|
||||
}
|
||||
|
||||
return overFlow;
|
||||
|
||||
case RETURN:
|
||||
// Pay the user the items, and return overflow
|
||||
final Map<Integer, ItemStack> returnStack = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " with overflow " + returnStack.get(0).toString());
|
||||
}
|
||||
|
||||
return returnStack;
|
||||
case DROP:
|
||||
// Pay the users the items directly, and drop the rest, will always return no overflow.
|
||||
final Map<Integer, ItemStack> leftOver = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
|
||||
final Location loc = user.getBase().getLocation();
|
||||
for (final ItemStack loStack : leftOver.values()) {
|
||||
final int maxStackSize = loStack.getType().getMaxStackSize();
|
||||
final int stacks = loStack.getAmount() / maxStackSize;
|
||||
final int leftover = loStack.getAmount() % maxStackSize;
|
||||
final Item[] itemStacks = new Item[stacks + (leftover > 0 ? 1 : 0)];
|
||||
for (int i = 0; i < stacks; i++) {
|
||||
final ItemStack stack = loStack.clone();
|
||||
stack.setAmount(maxStackSize);
|
||||
itemStacks[i] = loc.getWorld().dropItem(loc, stack);
|
||||
}
|
||||
if (leftover > 0) {
|
||||
final ItemStack stack = loStack.clone();
|
||||
stack.setAmount(leftover);
|
||||
itemStacks[stacks] = loc.getWorld().dropItem(loc, stack);
|
||||
}
|
||||
}
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " and dropping overflow " + leftOver.get(0).toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " and dropping overflow " + leftover.get(0).toString());
|
||||
}
|
||||
}
|
||||
} else if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
@@ -315,11 +296,11 @@ public class Trade {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
}
|
||||
if (!user.getBase().getInventory().containsAtLeast(getItemStack(), getItemStack().getAmount())) {
|
||||
if (!Inventories.containsAtLeast(user.getBase(), getItemStack(), getItemStack().getAmount())) {
|
||||
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " "))));
|
||||
return;
|
||||
}
|
||||
user.getBase().getInventory().removeItem(getItemStack());
|
||||
Inventories.removeItemAmount(user.getBase(), getItemStack(), getItemStack().getAmount());
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
if (command != null) {
|
||||
|
||||
@@ -1,155 +1,19 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Deprecated
|
||||
public class UUIDMap {
|
||||
private static final ScheduledExecutorService writeScheduler = Executors.newScheduledThreadPool(1);
|
||||
private static boolean pendingWrite;
|
||||
private static boolean loading = false;
|
||||
private final transient net.ess3.api.IEssentials ess;
|
||||
private final File userList;
|
||||
private final transient Pattern splitPattern = Pattern.compile(",");
|
||||
private final Runnable writeTaskRunnable;
|
||||
|
||||
public UUIDMap(final net.ess3.api.IEssentials ess) {
|
||||
this.ess = ess;
|
||||
userList = new File(ess.getDataFolder(), "usermap.csv");
|
||||
pendingWrite = false;
|
||||
writeTaskRunnable = () -> {
|
||||
if (pendingWrite) {
|
||||
try {
|
||||
new WriteRunner(ess.getDataFolder(), userList, ess.getUserMap().getNames()).run();
|
||||
} catch (final Throwable t) { // bad code to prevent task from being suppressed
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
writeScheduler.scheduleWithFixedDelay(writeTaskRunnable, 5, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void loadAllUsers(final ConcurrentSkipListMap<String, UUID> names, final ConcurrentSkipListMap<UUID, ArrayList<String>> history) {
|
||||
try {
|
||||
if (!userList.exists()) {
|
||||
userList.createNewFile();
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Reading usermap from disk");
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
names.clear();
|
||||
history.clear();
|
||||
loading = true;
|
||||
|
||||
try (final BufferedReader reader = new BufferedReader(new FileReader(userList))) {
|
||||
while (true) {
|
||||
final String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
} else {
|
||||
final String[] values = splitPattern.split(line);
|
||||
if (values.length == 2) {
|
||||
final String name = values[0];
|
||||
final UUID uuid = UUID.fromString(values[1]);
|
||||
names.put(name, uuid);
|
||||
if (!history.containsKey(uuid)) {
|
||||
final ArrayList<String> list = new ArrayList<>();
|
||||
list.add(name);
|
||||
history.put(uuid, list);
|
||||
} else {
|
||||
final ArrayList<String> list = history.get(uuid);
|
||||
if (!list.contains(name)) {
|
||||
list.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loading = false;
|
||||
} catch (final IOException ex) {
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
public UUIDMap() {
|
||||
}
|
||||
|
||||
public void writeUUIDMap() {
|
||||
pendingWrite = true;
|
||||
//no-op
|
||||
}
|
||||
|
||||
public void forceWriteUUIDMap() {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Forcing usermap write to disk");
|
||||
}
|
||||
pendingWrite = true;
|
||||
writeTaskRunnable.run();
|
||||
//no-op
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
writeScheduler.submit(writeTaskRunnable);
|
||||
writeScheduler.shutdown();
|
||||
}
|
||||
|
||||
private static final class WriteRunner implements Runnable {
|
||||
private final File location;
|
||||
private final File endFile;
|
||||
private final Map<String, UUID> names;
|
||||
|
||||
private WriteRunner(final File location, final File endFile, final Map<String, UUID> names) {
|
||||
this.location = location;
|
||||
this.endFile = endFile;
|
||||
this.names = new HashMap<>(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
pendingWrite = false;
|
||||
if (loading || names.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
File configFile = null;
|
||||
|
||||
try {
|
||||
configFile = File.createTempFile("usermap", ".tmp.csv", location);
|
||||
|
||||
final BufferedWriter bWriter = new BufferedWriter(new FileWriter(configFile));
|
||||
for (final Map.Entry<String, UUID> entry : names.entrySet()) {
|
||||
bWriter.write(entry.getKey() + "," + entry.getValue().toString());
|
||||
bWriter.newLine();
|
||||
}
|
||||
|
||||
bWriter.close();
|
||||
Files.move(configFile, endFile);
|
||||
} catch (final IOException ex) {
|
||||
try {
|
||||
if (configFile != null && configFile.exists()) {
|
||||
Files.move(configFile, new File(endFile.getParentFile(), "usermap.bak.csv"));
|
||||
}
|
||||
} catch (final Exception ex2) {
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, ex2.getMessage(), ex2);
|
||||
}
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
//no-op
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.economy.EconomyLayer;
|
||||
import com.earth2me.essentials.economy.EconomyLayers;
|
||||
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||
@@ -27,7 +28,6 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
@@ -90,6 +90,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
private String lastHomeConfirmation;
|
||||
private long lastHomeConfirmationTimestamp;
|
||||
private Boolean toggleShout;
|
||||
private boolean freeze = false;
|
||||
private transient final List<String> signCopy = Lists.newArrayList("", "", "", "");
|
||||
private transient long lastVanishTime = System.currentTimeMillis();
|
||||
|
||||
@@ -106,7 +107,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
this.messageRecipient = new SimpleMessageRecipient(ess, this);
|
||||
}
|
||||
|
||||
void update(final Player base) {
|
||||
public void update(final Player base) {
|
||||
setBase(base);
|
||||
}
|
||||
|
||||
@@ -464,7 +465,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
} else if (nick.equalsIgnoreCase(getName())) {
|
||||
nickname = nick;
|
||||
} else {
|
||||
nickname = FormatUtil.replaceFormat(ess.getSettings().getNicknamePrefix()) + nick;
|
||||
if (isAuthorized("essentials.nick.hideprefix")) {
|
||||
nickname = nick;
|
||||
} else {
|
||||
nickname = FormatUtil.replaceFormat(ess.getSettings().getNicknamePrefix()) + nick;
|
||||
}
|
||||
suffix = "§r";
|
||||
}
|
||||
|
||||
@@ -1137,12 +1142,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
* Returns the {@link ItemStack} in the main hand or off-hand. If the main hand is empty then the offhand item is returned - also nullable.
|
||||
*/
|
||||
public ItemStack getItemInHand() {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
|
||||
return getBase().getInventory().getItemInHand();
|
||||
} else {
|
||||
final PlayerInventory inventory = getBase().getInventory();
|
||||
return inventory.getItemInMainHand() != null ? inventory.getItemInMainHand() : inventory.getItemInOffHand();
|
||||
}
|
||||
return Inventories.getItemInHand(getBase());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1192,6 +1192,16 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return signCopy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFreeze() {
|
||||
return freeze;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFreeze(boolean freeze) {
|
||||
this.freeze = freeze;
|
||||
}
|
||||
|
||||
public boolean isBaltopExempt() {
|
||||
if (getBase().isOnline()) {
|
||||
final boolean exempt = isAuthorized("essentials.balancetop.exclude");
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.config.EssentialsUserConfiguration;
|
||||
import com.earth2me.essentials.config.entities.CommandCooldown;
|
||||
import com.earth2me.essentials.config.entities.LazyLocation;
|
||||
import com.earth2me.essentials.config.holders.UserConfigHolder;
|
||||
import com.earth2me.essentials.userstorage.ModernUserMap;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
@@ -43,19 +44,14 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
super(base);
|
||||
this.ess = ess;
|
||||
final File folder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
if (!folder.exists() && !folder.mkdirs()) {
|
||||
throw new RuntimeException("Unable to create userdata folder!");
|
||||
}
|
||||
|
||||
String filename;
|
||||
try {
|
||||
filename = base.getUniqueId().toString();
|
||||
} catch (final Throwable ex) {
|
||||
ess.getLogger().warning("Falling back to old username system for " + base.getName());
|
||||
filename = base.getName();
|
||||
}
|
||||
|
||||
config = new EssentialsUserConfiguration(base.getName(), base.getUniqueId(), new File(folder, filename + ".yml"));
|
||||
config = new EssentialsUserConfiguration(base.getName(), base.getUniqueId(), new File(folder, base.getUniqueId() + ".yml"));
|
||||
config.setSaveHook(() -> {
|
||||
config.setRootHolder(UserConfigHolder.class, holder);
|
||||
});
|
||||
reloadConfig();
|
||||
|
||||
if (config.getUsername() == null) {
|
||||
@@ -65,12 +61,15 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
|
||||
public final void reset() {
|
||||
config.blockingSave();
|
||||
config.getFile().delete();
|
||||
if (!config.getFile().delete()) {
|
||||
ess.getLogger().warning("Unable to delete data file for " + config.getFile().getName());
|
||||
}
|
||||
if (config.getUsername() != null) {
|
||||
ess.getUserMap().removeUser(config.getUsername());
|
||||
final ModernUserMap users = (ModernUserMap) ess.getUsers();
|
||||
users.invalidate(config.getUuid());
|
||||
if (isNPC()) {
|
||||
final String uuid = UUID.nameUUIDFromBytes(("NPC:" + StringUtil.safeString(config.getUsername())).getBytes(Charsets.UTF_8)).toString();
|
||||
ess.getUserMap().removeUserUUID(uuid);
|
||||
final String name = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(config.getUsername()) : config.getUsername();
|
||||
users.invalidate(UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,14 +87,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while reading user config: " + config.getFile().getName(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
config.setSaveHook(() -> {
|
||||
try {
|
||||
config.getRootNode().set(UserConfigHolder.class, holder);
|
||||
} catch (SerializationException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while saving user config: " + config.getFile().getName(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
money = _getMoney();
|
||||
}
|
||||
|
||||
@@ -208,6 +199,16 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
}
|
||||
|
||||
public void renameHome(final String name, final String newName) throws Exception {
|
||||
final LazyLocation location = holder.homes().remove(name);
|
||||
if (location != null) {
|
||||
holder.homes().put(StringUtil.safeString(newName), location);
|
||||
config.save();
|
||||
} else {
|
||||
throw new Exception(tl("invalidHome", name));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasHome() {
|
||||
return !holder.homes().isEmpty();
|
||||
}
|
||||
@@ -589,9 +590,13 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
|
||||
public void setLastAccountName(final String lastAccountName) {
|
||||
if (getLastAccountName() != null && !getLastAccountName().equals(lastAccountName)) {
|
||||
final List<String> usernames = holder.pastUsernames();
|
||||
usernames.add(0, getLastAccountName());
|
||||
holder.pastUsernames(usernames);
|
||||
}
|
||||
holder.lastAccountName(lastAccountName);
|
||||
config.save();
|
||||
ess.getUserMap().trackUUID(getConfigUUID(), lastAccountName, true);
|
||||
}
|
||||
|
||||
public boolean arePowerToolsEnabled() {
|
||||
@@ -722,6 +727,17 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public List<String> getPastUsernames() {
|
||||
return holder.pastUsernames();
|
||||
}
|
||||
|
||||
public void addPastUsername(String username) {
|
||||
final List<String> usernames = holder.pastUsernames();
|
||||
usernames.add(0, username);
|
||||
holder.pastUsernames(usernames);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public boolean isShouting() {
|
||||
if (holder.shouting() == null) {
|
||||
holder.shouting(ess.getSettings().isShoutDefault());
|
||||
|
||||
@@ -1,383 +1,70 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.api.UserDoesNotExistException;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import com.earth2me.essentials.userstorage.ModernUserMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
private static boolean legacy = false;
|
||||
private static Method getLegacy;
|
||||
private final transient IEssentials ess;
|
||||
private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<>();
|
||||
private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<>();
|
||||
private final transient ConcurrentSkipListMap<UUID, ArrayList<String>> history = new ConcurrentSkipListMap<>();
|
||||
private final UUIDMap uuidMap;
|
||||
private final transient Cache<String, User> users;
|
||||
private final Pattern validUserPattern = Pattern.compile("^[a-zA-Z0-9_]{2,16}$");
|
||||
@Deprecated
|
||||
public class UserMap {
|
||||
private final transient ModernUserMap userMap;
|
||||
private final transient UUIDMap uuidMap;
|
||||
|
||||
private static final String WARN_UUID_NOT_REPLACE = "Found UUID {0} for player {1}, but player already has a UUID ({2}). Not replacing UUID in usermap.";
|
||||
|
||||
public UserMap(final IEssentials ess) {
|
||||
super();
|
||||
this.ess = ess;
|
||||
uuidMap = new UUIDMap(ess);
|
||||
//RemovalListener<UUID, User> remListener = new UserMapRemovalListener();
|
||||
//users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().removalListener(remListener).build(this);
|
||||
final CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
|
||||
final int maxCount = ess.getSettings().getMaxUserCacheCount();
|
||||
try {
|
||||
cacheBuilder.maximumSize(maxCount);
|
||||
} catch (final NoSuchMethodError nsme) {
|
||||
legacy = true;
|
||||
legacyMaximumSize(cacheBuilder, maxCount);
|
||||
}
|
||||
cacheBuilder.softValues();
|
||||
if (!legacy) {
|
||||
users = cacheBuilder.build(this);
|
||||
} else {
|
||||
users = legacyBuild(cacheBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAllUsersAsync(final IEssentials ess) {
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
synchronized (users) {
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
keys.clear();
|
||||
users.invalidateAll();
|
||||
for (final String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
try {
|
||||
keys.add(UUID.fromString(name));
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
//Ignore these users till they rejoin.
|
||||
}
|
||||
}
|
||||
uuidMap.loadAllUsers(names, history);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean userExists(final UUID uuid) {
|
||||
return keys.contains(uuid);
|
||||
public UserMap(final ModernUserMap userMap) {
|
||||
this.userMap = userMap;
|
||||
this.uuidMap = new UUIDMap();
|
||||
}
|
||||
|
||||
public User getUser(final String name) {
|
||||
final String sanitizedName = StringUtil.safeString(name);
|
||||
try {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().warning("Looking up username " + name + " (" + sanitizedName + ") ...");
|
||||
}
|
||||
|
||||
if (names.containsKey(sanitizedName)) {
|
||||
final UUID uuid = names.get(sanitizedName);
|
||||
return getUser(uuid);
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().warning(name + "(" + sanitizedName + ") has no known usermap entry");
|
||||
}
|
||||
|
||||
final File userFile = getUserFileFromString(sanitizedName);
|
||||
if (userFile.exists()) {
|
||||
ess.getLogger().info("Importing user " + name + " to usermap.");
|
||||
final User user = new User(new OfflinePlayer(sanitizedName, ess.getServer()), ess);
|
||||
trackUUID(user.getBase().getUniqueId(), user.getName(), true);
|
||||
return user;
|
||||
}
|
||||
return null;
|
||||
} catch (final UncheckedExecutionException ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.WARNING, ex, () -> String.format("Exception while getting user for %s (%s)", name, sanitizedName));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return userMap.getUser(name);
|
||||
}
|
||||
|
||||
public User getUser(final UUID uuid) {
|
||||
try {
|
||||
if (!legacy) {
|
||||
return ((LoadingCache<String, User>) users).get(uuid.toString());
|
||||
} else {
|
||||
return legacyCacheGet(uuid);
|
||||
}
|
||||
} catch (final ExecutionException | UncheckedExecutionException ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.WARNING, ex, () -> "Exception while getting user for " + uuid);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return userMap.getUser(uuid);
|
||||
}
|
||||
|
||||
public void trackUUID(final UUID uuid, final String name, final boolean replace) {
|
||||
if (uuid != null) {
|
||||
keys.add(uuid);
|
||||
if (name != null && name.length() > 0) {
|
||||
final String keyName = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name;
|
||||
if (!names.containsKey(keyName)) {
|
||||
names.put(keyName, uuid);
|
||||
uuidMap.writeUUIDMap();
|
||||
} else if (!isUUIDMatch(uuid, keyName)) {
|
||||
if (replace) {
|
||||
ess.getLogger().info("Found new UUID for " + name + ". Replacing " + names.get(keyName).toString() + " with " + uuid.toString());
|
||||
names.put(keyName, uuid);
|
||||
uuidMap.writeUUIDMap();
|
||||
} else {
|
||||
ess.getLogger().log(Level.INFO, MessageFormat.format(WARN_UUID_NOT_REPLACE, uuid.toString(), name, names.get(keyName).toString()), new RuntimeException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// no-op
|
||||
}
|
||||
|
||||
public boolean isUUIDMatch(final UUID uuid, final String name) {
|
||||
return names.containsKey(name) && names.get(name).equals(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User load(final String stringUUID) throws Exception {
|
||||
final UUID uuid = UUID.fromString(stringUUID);
|
||||
Player player = ess.getServer().getPlayer(uuid);
|
||||
if (player != null) {
|
||||
final User user = new User(player, ess);
|
||||
trackUUID(uuid, user.getName(), true);
|
||||
return user;
|
||||
}
|
||||
|
||||
final File userFile = getUserFileFromID(uuid);
|
||||
|
||||
if (userFile.exists()) {
|
||||
player = new OfflinePlayer(uuid, ess.getServer());
|
||||
final User user = new User(player, ess);
|
||||
((OfflinePlayer) player).setName(user.getLastAccountName());
|
||||
trackUUID(uuid, user.getName(), false);
|
||||
return user;
|
||||
}
|
||||
|
||||
throw new Exception("User not found!");
|
||||
return userMap.load(UUID.fromString(stringUUID));
|
||||
}
|
||||
|
||||
public User load(final org.bukkit.OfflinePlayer player) throws UserDoesNotExistException {
|
||||
if (player == null) {
|
||||
throw new IllegalArgumentException("Player cannot be null!");
|
||||
}
|
||||
|
||||
final Player userPlayer;
|
||||
if (player instanceof Player) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Loading online OfflinePlayer into user map...");
|
||||
}
|
||||
final User user = new User((Player) player, ess);
|
||||
trackUUID(player.getUniqueId(), player.getName(), true);
|
||||
return user;
|
||||
}
|
||||
|
||||
final File userFile = getUserFileFromID(player.getUniqueId());
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Loading OfflinePlayer into user map. Has data: " + userFile.exists() + " for " + player);
|
||||
}
|
||||
|
||||
final OfflinePlayer essPlayer = new OfflinePlayer(player.getUniqueId(), ess.getServer());
|
||||
final User user = new User(essPlayer, ess);
|
||||
if (userFile.exists()) {
|
||||
essPlayer.setName(user.getLastAccountName());
|
||||
userPlayer = (Player) player;
|
||||
} else {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("OfflinePlayer usermap load saving user data for " + player);
|
||||
}
|
||||
|
||||
// this code makes me sad
|
||||
user.startTransaction();
|
||||
try {
|
||||
user.setMoney(ess.getSettings().getStartingBalance());
|
||||
} catch (MaxMoneyException e) {
|
||||
// Shouldn't happen as it would be an illegal configuration state
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
user.setLastAccountName(user.getName());
|
||||
user.stopTransaction();
|
||||
final com.earth2me.essentials.OfflinePlayer essPlayer = new com.earth2me.essentials.OfflinePlayer(player.getUniqueId(), Bukkit.getServer());
|
||||
essPlayer.setName(player.getName());
|
||||
userPlayer = essPlayer;
|
||||
}
|
||||
|
||||
trackUUID(player.getUniqueId(), user.getName(), false);
|
||||
final User user = userMap.getUser(userPlayer);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException("User not found");
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
getUUIDMap().forceWriteUUIDMap();
|
||||
loadAllUsersAsync(ess);
|
||||
}
|
||||
|
||||
public void invalidateAll() {
|
||||
users.invalidateAll();
|
||||
}
|
||||
|
||||
public void removeUser(final String name) {
|
||||
if (names == null) {
|
||||
ess.getLogger().warning("Name collection is null, cannot remove user.");
|
||||
return;
|
||||
}
|
||||
final UUID uuid = names.get(name);
|
||||
if (uuid != null) {
|
||||
keys.remove(uuid);
|
||||
users.invalidate(uuid.toString());
|
||||
}
|
||||
names.remove(name);
|
||||
names.remove(StringUtil.safeString(name));
|
||||
}
|
||||
|
||||
public void removeUserUUID(final String uuid) {
|
||||
users.invalidate(uuid);
|
||||
}
|
||||
|
||||
public Set<UUID> getAllUniqueUsers() {
|
||||
return Collections.unmodifiableSet(keys);
|
||||
return userMap.getAllUserUUIDs();
|
||||
}
|
||||
|
||||
public int getUniqueUsers() {
|
||||
return keys.size();
|
||||
return userMap.getUserCount();
|
||||
}
|
||||
|
||||
protected ConcurrentSkipListMap<String, UUID> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
protected ConcurrentSkipListMap<UUID, ArrayList<String>> getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
public List<String> getUserHistory(final UUID uuid) {
|
||||
return history.get(uuid);
|
||||
return new ConcurrentSkipListMap<>(userMap.getNameCache());
|
||||
}
|
||||
|
||||
public UUIDMap getUUIDMap() {
|
||||
return uuidMap;
|
||||
}
|
||||
// class UserMapRemovalListener implements RemovalListener
|
||||
// {
|
||||
// @Override
|
||||
// public void onRemoval(final RemovalNotification notification)
|
||||
// {
|
||||
// Object value = notification.getValue();
|
||||
// if (value != null)
|
||||
// {
|
||||
// ((User)value).cleanup();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private File getUserFileFromID(final UUID uuid) {
|
||||
final File userFolder = new File(ess.getDataFolder(), "userdata");
|
||||
return new File(userFolder, uuid.toString() + ".yml");
|
||||
}
|
||||
|
||||
public File getUserFileFromString(final String name) {
|
||||
final File userFolder = new File(ess.getDataFolder(), "userdata");
|
||||
return new File(userFolder, StringUtil.sanitizeFileName(name) + ".yml");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public User getUserFromBukkit(String name) {
|
||||
name = StringUtil.safeString(name);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().warning("Using potentially blocking Bukkit UUID lookup for: " + name);
|
||||
}
|
||||
// Don't attempt to look up entirely invalid usernames
|
||||
if (name == null || !validUserPattern.matcher(name).matches()) {
|
||||
return null;
|
||||
}
|
||||
final org.bukkit.OfflinePlayer offlinePlayer = ess.getServer().getOfflinePlayer(name);
|
||||
if (offlinePlayer == null) {
|
||||
return null;
|
||||
}
|
||||
final UUID uuid;
|
||||
try {
|
||||
uuid = offlinePlayer.getUniqueId();
|
||||
} catch (final UnsupportedOperationException | NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
// This is how Bukkit generates fake UUIDs
|
||||
if (UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)).equals(uuid)) {
|
||||
return null;
|
||||
} else {
|
||||
names.put(name, uuid);
|
||||
return getUser(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private User legacyCacheGet(final UUID uuid) {
|
||||
if (getLegacy == null) {
|
||||
final Class<?> usersClass = users.getClass();
|
||||
for (final Method m : usersClass.getDeclaredMethods()) {
|
||||
if (m.getName().equals("get")) {
|
||||
getLegacy = m;
|
||||
getLegacy.setAccessible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
return (User) getLegacy.invoke(users, uuid.toString());
|
||||
} catch (final IllegalAccessException | InvocationTargetException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void legacyMaximumSize(final CacheBuilder builder, final int maxCount) {
|
||||
try {
|
||||
final Method maxSizeLegacy = builder.getClass().getDeclaredMethod("maximumSize", Integer.TYPE);
|
||||
maxSizeLegacy.setAccessible(true);
|
||||
maxSizeLegacy.invoke(builder, maxCount);
|
||||
} catch (final NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Cache<String, User> legacyBuild(final CacheBuilder builder) {
|
||||
Method build = null;
|
||||
for (final Method method : builder.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("build")) {
|
||||
build = method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Cache<String, User> legacyUsers;
|
||||
try {
|
||||
assert build != null;
|
||||
build.setAccessible(true);
|
||||
legacyUsers = (Cache<String, User>) build.invoke(builder, this);
|
||||
} catch (final IllegalAccessException | InvocationTargetException e) {
|
||||
legacyUsers = null;
|
||||
}
|
||||
return legacyUsers;
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
public final void reloadConfig() {
|
||||
warpPoints.clear();
|
||||
final File[] listOfFiles = warpsFolder.listFiles();
|
||||
if (listOfFiles.length >= 1) {
|
||||
if (listOfFiles != null) {
|
||||
for (final File listOfFile : listOfFiles) {
|
||||
final String filename = listOfFile.getName();
|
||||
if (listOfFile.isFile() && filename.endsWith(".yml")) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
|
||||
import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import com.earth2me.essentials.config.EssentialsConfiguration;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -101,7 +102,7 @@ public class Worth implements IConf {
|
||||
}
|
||||
|
||||
int max = 0;
|
||||
for (final ItemStack s : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack s : Inventories.getInventory(user.getBase(), false)) {
|
||||
if (s == null || !s.isSimilar(is)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.earth2me.essentials.api;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.config.EssentialsUserConfiguration;
|
||||
import com.earth2me.essentials.userstorage.ModernUserMap;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
@@ -41,9 +42,9 @@ public class Economy {
|
||||
ess = aEss;
|
||||
}
|
||||
|
||||
private static void createNPCFile(String name) {
|
||||
private static void createNPCFile(final String unsanitizedName) {
|
||||
final File folder = new File(ess.getDataFolder(), "userdata");
|
||||
name = StringUtil.safeString(name);
|
||||
final String name = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(unsanitizedName) : unsanitizedName;
|
||||
if (!folder.exists()) {
|
||||
if (!folder.mkdirs()) {
|
||||
throw new RuntimeException("Error while creating userdata directory!");
|
||||
@@ -59,9 +60,12 @@ public class Economy {
|
||||
npcConfig.load();
|
||||
npcConfig.setProperty("npc", true);
|
||||
npcConfig.setProperty("last-account-name", name);
|
||||
npcConfig.setProperty("npc-name", unsanitizedName);
|
||||
npcConfig.setProperty("money", ess.getSettings().getStartingBalance());
|
||||
npcConfig.blockingSave();
|
||||
ess.getUserMap().trackUUID(npcUUID, name, false);
|
||||
// This will load the NPC into the UserMap + UUID cache
|
||||
((ModernUserMap) ess.getUsers()).addCachedNpcName(npcUUID, name);
|
||||
ess.getUsers().getUser(npcUUID);
|
||||
}
|
||||
|
||||
private static void deleteNPC(final String name) {
|
||||
|
||||
@@ -64,8 +64,8 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
}
|
||||
|
||||
// If there are less than 50 users in our usermap, there is no need to display a warning as these calculations should be done quickly
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
||||
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
||||
if (ess.getUsers().getUserCount() > MINUSERS) {
|
||||
sender.sendMessage(tl("orderBalances", ess.getUsers().getUserCount()));
|
||||
}
|
||||
|
||||
ess.runTaskAsynchronously(new Viewer(sender, page, force));
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
@@ -52,7 +52,7 @@ public class Commandbook extends EssentialsCommand {
|
||||
if (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others")) {
|
||||
final ItemStack newItem = new ItemStack(WRITABLE_BOOK, item.getAmount());
|
||||
newItem.setItemMeta(bmeta);
|
||||
InventoryWorkaround.setItemInMainHand(user.getBase(), newItem);
|
||||
Inventories.setItemInMainHand(user.getBase(), newItem);
|
||||
user.sendMessage(tl("editBookContents"));
|
||||
} else {
|
||||
throw new Exception(tl("denyBookEdit"));
|
||||
@@ -65,7 +65,7 @@ public class Commandbook extends EssentialsCommand {
|
||||
}
|
||||
final ItemStack newItem = new ItemStack(Material.WRITTEN_BOOK, item.getAmount());
|
||||
newItem.setItemMeta(bmeta);
|
||||
InventoryWorkaround.setItemInMainHand(user.getBase(), newItem);
|
||||
Inventories.setItemInMainHand(user.getBase(), newItem);
|
||||
user.sendMessage(tl("bookLocked"));
|
||||
} else {
|
||||
throw new Exception(tl("holdBook"));
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandbottom extends EssentialsCommand {
|
||||
|
||||
public Commandbottom() {
|
||||
super("bottom");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final int bottomX = user.getLocation().getBlockX();
|
||||
final int bottomZ = user.getLocation().getBlockZ();
|
||||
final float pitch = user.getLocation().getPitch();
|
||||
final float yaw = user.getLocation().getYaw();
|
||||
final Location unsafe = new Location(user.getWorld(), bottomX, ess.getWorldInfoProvider().getMinHeight(user.getWorld()), bottomZ, yaw, pitch);
|
||||
final Location safe = LocationUtil.getSafeDestination(ess, unsafe);
|
||||
final CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
user.sendMessage(tl("teleportBottom", safe.getWorld().getName(), safe.getBlockX(), safe.getBlockY(), safe.getBlockZ()));
|
||||
}
|
||||
});
|
||||
user.getAsyncTeleport().teleport(safe, new Trade(this.getName(), ess), PlayerTeleportEvent.TeleportCause.COMMAND, future);
|
||||
}
|
||||
}
|
||||
+10
-20
@@ -2,7 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
@@ -22,8 +22,6 @@ import java.util.Set;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandclearinventory extends EssentialsCommand {
|
||||
|
||||
private static final int BASE_AMOUNT = 100000;
|
||||
private static final int EXTENDED_CAP = 8;
|
||||
|
||||
public Commandclearinventory() {
|
||||
@@ -114,38 +112,30 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
if (type == ClearHandlerType.ALL_EXCEPT_ARMOR) {
|
||||
if (type != ClearHandlerType.SPECIFIC_ITEM) {
|
||||
final boolean armor = type == ClearHandlerType.ALL_INCLUDING_ARMOR;
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingAllItems", player.getDisplayName()));
|
||||
sender.sendMessage(tl(armor ? "inventoryClearingAllArmor" : "inventoryClearingAllItems", player.getDisplayName()));
|
||||
}
|
||||
InventoryWorkaround.clearInventoryNoArmor(player.getInventory());
|
||||
InventoryWorkaround.setItemInOffHand(player, null);
|
||||
} else if (type == ClearHandlerType.ALL_INCLUDING_ARMOR) {
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingAllArmor", player.getDisplayName()));
|
||||
}
|
||||
InventoryWorkaround.clearInventoryNoArmor(player.getInventory());
|
||||
InventoryWorkaround.setItemInOffHand(player, null);
|
||||
player.getInventory().setArmorContents(null);
|
||||
Inventories.removeItems(player, item -> true, armor);
|
||||
} else {
|
||||
for (final Item item : items) {
|
||||
final ItemStack stack = new ItemStack(item.getMaterial());
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
//noinspection deprecation
|
||||
stack.setDurability(item.getData());
|
||||
}
|
||||
|
||||
// amount -1 means all items will be cleared
|
||||
if (amount == -1) {
|
||||
stack.setAmount(BASE_AMOUNT);
|
||||
final ItemStack removedStack = player.getInventory().removeItem(stack).get(0);
|
||||
final int removedAmount = BASE_AMOUNT - removedStack.getAmount() + InventoryWorkaround.clearItemInOffHand(player, stack);
|
||||
final int removedAmount = Inventories.removeItemSimilar(player, stack, true);
|
||||
if (removedAmount > 0 || showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
|
||||
}
|
||||
} else {
|
||||
stack.setAmount(amount < 0 ? 1 : amount);
|
||||
if (player.getInventory().containsAtLeast(stack, amount)) {
|
||||
if (Inventories.removeItemAmount(player, stack, amount)) {
|
||||
sender.sendMessage(tl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
|
||||
player.getInventory().removeItem(stack);
|
||||
} else {
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearFail", player.getDisplayName(), amount, stack.getType().toString().toLowerCase(Locale.ENGLISH)));
|
||||
@@ -203,7 +193,7 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
|
||||
private String formatCommand(final String commandLabel, final String[] args) {
|
||||
return "/" + commandLabel + " " + StringUtil.joinList(" ", args);
|
||||
return "/" + commandLabel + " " + StringUtil.joinList(" ", (Object[]) args);
|
||||
}
|
||||
|
||||
private enum ClearHandlerType {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.Material;
|
||||
@@ -39,7 +40,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
if (args.length > 0) {
|
||||
is = ess.getItemDb().getMatching(user, args);
|
||||
} else {
|
||||
for (final ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack stack : Inventories.getInventory(user.getBase(), false)) {
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
@@ -85,7 +86,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
|
||||
int amount = 0;
|
||||
|
||||
for (final ItemStack contents : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack contents : Inventories.getInventory(user.getBase(), false)) {
|
||||
if (contents != null && contents.isSimilar(stack)) {
|
||||
amount += contents.getAmount();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.PasteUtil;
|
||||
import org.bukkit.Material;
|
||||
@@ -37,7 +38,7 @@ public class Commandcreatekit extends EssentialsCommand {
|
||||
// Command handler will auto fail if this fails.
|
||||
final long delay = Long.parseLong(args[1]);
|
||||
final String kitname = args[0];
|
||||
final ItemStack[] items = user.getBase().getInventory().getContents();
|
||||
final ItemStack[] items = Inventories.getInventory(user.getBase(), true);
|
||||
final List<String> list = new ArrayList<>();
|
||||
|
||||
boolean useSerializationProvider = ess.getSettings().isUseBetterKits();
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.IUser;
|
||||
import com.earth2me.essentials.User;
|
||||
import net.essentialsx.api.v2.events.HomeModifyEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -37,18 +39,27 @@ public class Commanddelhome extends EssentialsCommand {
|
||||
|
||||
if (expandedArg.length > 1 && (user == null || user.isAuthorized("essentials.delhome.others"))) {
|
||||
user = getPlayer(server, expandedArg, 0, true, true);
|
||||
name = expandedArg[1];
|
||||
name = expandedArg[1].toLowerCase(Locale.ENGLISH);
|
||||
} else if (user == null) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
} else {
|
||||
name = expandedArg[0];
|
||||
name = expandedArg[0].toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
if (name.equalsIgnoreCase("bed")) {
|
||||
if (name.equals("bed")) {
|
||||
throw new Exception(tl("invalidHomeName"));
|
||||
}
|
||||
|
||||
user.delHome(name.toLowerCase(Locale.ENGLISH));
|
||||
final HomeModifyEvent event = new HomeModifyEvent(sender.getUser(ess), user, name, user.getHome(name), false);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("HomeModifyEvent canceled for /delhome execution by " + sender.getDisplayName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
user.delHome(name);
|
||||
sender.sendMessage(tl("deleteHome", name));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,13 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -32,45 +35,71 @@ public class Commandeditsign extends EssentialsCommand {
|
||||
final Sign sign = (Sign) target.getState();
|
||||
try {
|
||||
if (args[0].equalsIgnoreCase("set") && args.length > 2) {
|
||||
final String[] existingLines = sign.getLines();
|
||||
final int line = Integer.parseInt(args[1]) - 1;
|
||||
final String text = FormatUtil.formatString(user, "essentials.editsign", getFinalArg(args, 2)).trim();
|
||||
if (ChatColor.stripColor(text).length() > 15 && !user.isAuthorized("essentials.editsign.unlimited")) {
|
||||
throw new Exception(tl("editsignCommandLimit"));
|
||||
}
|
||||
sign.setLine(line, text);
|
||||
sign.update();
|
||||
existingLines[line] = text;
|
||||
if (callSignEvent(sign, user.getBase(), existingLines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
user.sendMessage(tl("editsignCommandSetSuccess", line + 1, text));
|
||||
} else if (args[0].equalsIgnoreCase("clear")) {
|
||||
if (args.length == 1) {
|
||||
final String[] existingLines = sign.getLines();
|
||||
for (int i = 0; i < 4; i++) { // A whole one line of line savings!
|
||||
sign.setLine(i, "");
|
||||
existingLines[i] = "";
|
||||
}
|
||||
sign.update();
|
||||
|
||||
if (callSignEvent(sign, user.getBase(), existingLines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
user.sendMessage(tl("editsignCommandClear"));
|
||||
} else {
|
||||
final String[] existingLines = sign.getLines();
|
||||
final int line = Integer.parseInt(args[1]) - 1;
|
||||
sign.setLine(line, "");
|
||||
sign.update();
|
||||
existingLines[line] = "";
|
||||
|
||||
if (callSignEvent(sign, user.getBase(), existingLines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
user.sendMessage(tl("editsignCommandClearLine", line + 1));
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("copy") || args[0].equalsIgnoreCase("paste")) {
|
||||
final boolean copy = args[0].equalsIgnoreCase("copy");
|
||||
final String tlPrefix = copy ? "editsignCopy" : "editsignPaste";
|
||||
} else if (args[0].equalsIgnoreCase("copy")) {
|
||||
final int line = args.length == 1 ? -1 : Integer.parseInt(args[1]) - 1;
|
||||
|
||||
if (line == -1) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
processSignCopyPaste(user, sign, i, copy);
|
||||
// We use unformat here to prevent players from copying signs with colors that they do not have permission to use.
|
||||
user.getSignCopy().set(i, FormatUtil.unformatString(user, "essentials.editsign", sign.getLine(i)));
|
||||
}
|
||||
user.sendMessage(tl(tlPrefix, commandLabel));
|
||||
user.sendMessage(tl("editsignCopy", commandLabel));
|
||||
} else {
|
||||
processSignCopyPaste(user, sign, line, copy);
|
||||
user.sendMessage(tl(tlPrefix + "Line", line + 1, commandLabel));
|
||||
// We use unformat here to prevent players from copying signs with colors that they do not have permission to use.
|
||||
user.getSignCopy().set(line, FormatUtil.unformatString(user, "essentials.editsign", sign.getLine(line)));
|
||||
user.sendMessage(tl("editsignCopyLine", line + 1, commandLabel));
|
||||
}
|
||||
|
||||
if (!copy) {
|
||||
sign.update();
|
||||
} else if (args[0].equalsIgnoreCase("paste")) {
|
||||
final int line = args.length == 1 ? -1 : Integer.parseInt(args[1]) - 1;
|
||||
|
||||
final String[] existingLines = sign.getLines();
|
||||
if (line == -1) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
existingLines[i] = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(i));
|
||||
}
|
||||
user.sendMessage(tl("editsignPaste", commandLabel));
|
||||
} else {
|
||||
existingLines[line] = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(line));
|
||||
user.sendMessage(tl("editsignPasteLine", line + 1, commandLabel));
|
||||
}
|
||||
|
||||
callSignEvent(sign, user.getBase(), existingLines);
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
@@ -79,15 +108,21 @@ public class Commandeditsign extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private void processSignCopyPaste(final User user, final Sign sign, final int index, final boolean copy) {
|
||||
if (copy) {
|
||||
// We use unformat here to prevent players from copying signs with colors that they do not have permission to use.
|
||||
user.getSignCopy().set(index, FormatUtil.unformatString(user, "essentials.editsign", sign.getLine(index)));
|
||||
return;
|
||||
private boolean callSignEvent(final Sign sign, final Player player, final String[] lines) {
|
||||
final SignChangeEvent event = new SignChangeEvent(sign.getBlock(), player, lines);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("SignChangeEvent canceled for /editsign execution by " + player.getName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
final String line = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(index));
|
||||
sign.setLine(index, line == null ? "" : line);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sign.setLine(i, lines[i]);
|
||||
}
|
||||
sign.update();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.Enchantments;
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
@@ -57,7 +57,7 @@ public class Commandenchant extends EssentialsCommand {
|
||||
final MetaItemStack metaStack = new MetaItemStack(stack);
|
||||
final Enchantment enchantment = metaStack.getEnchantment(user, args[0]);
|
||||
metaStack.addEnchantment(user.getSource(), ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchantments.allowunsafe"), enchantment, level);
|
||||
InventoryWorkaround.setItemInMainHand(user.getBase(), metaStack.getItemStack());
|
||||
Inventories.setItemInMainHand(user.getBase(), metaStack.getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
final String enchantName = enchantment.getName().toLowerCase(Locale.ENGLISH).replace('_', ' ');
|
||||
if (level == 0) {
|
||||
|
||||
@@ -3,9 +3,10 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.EssentialsUpgrade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.UserMap;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.economy.EconomyLayer;
|
||||
import com.earth2me.essentials.economy.EconomyLayers;
|
||||
import com.earth2me.essentials.userstorage.ModernUserMap;
|
||||
import com.earth2me.essentials.utils.CommandMapUtil;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
@@ -13,7 +14,6 @@ import com.earth2me.essentials.utils.FloatUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.PasteUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
@@ -23,16 +23,19 @@ import com.google.gson.JsonPrimitive;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -45,12 +48,15 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
@@ -90,6 +96,7 @@ public class Commandessentials extends EssentialsCommand {
|
||||
"EssentialsAntiBuild",
|
||||
"EssentialsChat",
|
||||
"EssentialsDiscord",
|
||||
"EssentialsDiscordLink",
|
||||
"EssentialsGeoIP",
|
||||
"EssentialsProtect",
|
||||
"EssentialsSpawn",
|
||||
@@ -147,11 +154,12 @@ public class Commandessentials extends EssentialsCommand {
|
||||
case "homes":
|
||||
runHomes(server, sender, commandLabel, args);
|
||||
break;
|
||||
case "uuidconvert":
|
||||
runUUIDConvert(server, sender, commandLabel, args);
|
||||
case "usermap":
|
||||
runUserMap(sender, args);
|
||||
break;
|
||||
case "uuidtest":
|
||||
runUUIDTest(server, sender, commandLabel, args);
|
||||
|
||||
case "itemtest":
|
||||
runItemTest(server, sender, commandLabel, args);
|
||||
break;
|
||||
|
||||
// "#EasterEgg"
|
||||
@@ -168,6 +176,56 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
public void runItemTest(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (!sender.isAuthorized("essentials.itemtest", ess) || args.length < 2 || !sender.isPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = sender.getPlayer();
|
||||
assert player != null;
|
||||
|
||||
switch (args[1]) {
|
||||
case "slot": {
|
||||
if (args.length < 3) {
|
||||
return;
|
||||
}
|
||||
player.getInventory().setItem(Integer.parseInt(args[2]), new ItemStack(Material.DIRT));
|
||||
break;
|
||||
}
|
||||
case "overfill": {
|
||||
sender.sendMessage(Inventories.addItem(player, 42, false, new ItemStack(Material.DIAMOND_SWORD, 1), new ItemStack(Material.DIRT, 32), new ItemStack(Material.DIRT, 32)).toString());
|
||||
break;
|
||||
}
|
||||
case "overfill2": {
|
||||
if (args.length < 4) {
|
||||
return;
|
||||
}
|
||||
final boolean armor = Boolean.parseBoolean(args[2]);
|
||||
final boolean add = Boolean.parseBoolean(args[3]);
|
||||
final ItemStack[] items = new ItemStack[]{new ItemStack(Material.DIAMOND_SWORD, 1), new ItemStack(Material.DIRT, 32), new ItemStack(Material.DIRT, 32), new ItemStack(Material.DIAMOND_HELMET, 4), new ItemStack(Material.CHAINMAIL_LEGGINGS, 1)};
|
||||
if (Inventories.hasSpace(player, 0, armor, items)) {
|
||||
if (add) {
|
||||
sender.sendMessage(Inventories.addItem(player, 0, armor, items).toString());
|
||||
}
|
||||
sender.sendMessage("SO MUCH SPACE!");
|
||||
} else {
|
||||
sender.sendMessage("No space!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "remove": {
|
||||
if (args.length < 3) {
|
||||
return;
|
||||
}
|
||||
Inventories.removeItemExact(player, new ItemStack(Material.PUMPKIN, 1), Boolean.parseBoolean(args[2]));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Displays the command's usage.
|
||||
private void showUsage(final CommandSource sender) throws Exception {
|
||||
throw new NotEnoughArgumentsException();
|
||||
@@ -473,12 +531,11 @@ public class Commandessentials extends EssentialsCommand {
|
||||
final long daysArg = Long.parseLong(args[1]);
|
||||
final double moneyArg = args.length >= 3 ? FloatUtil.parseDouble(args[2].replaceAll("[^0-9\\.]", "")) : 0;
|
||||
final int homesArg = args.length >= 4 && NumberUtil.isInt(args[3]) ? Integer.parseInt(args[3]) : 0;
|
||||
final UserMap userMap = ess.getUserMap();
|
||||
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
final long currTime = System.currentTimeMillis();
|
||||
for (final UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -523,13 +580,12 @@ public class Commandessentials extends EssentialsCommand {
|
||||
throw new Exception(HOMES_USAGE);
|
||||
}
|
||||
|
||||
final UserMap userMap = ess.getUserMap();
|
||||
switch (args[1]) {
|
||||
case "fix":
|
||||
sender.sendMessage(tl("fixingHomes"));
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
for (final UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -553,8 +609,8 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
sender.sendMessage(filterByWorld ? tl("deletingHomesWorld", args[2]) : tl("deletingHomes"));
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
for (final UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -577,52 +633,77 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// Forces a rerun of userdata UUID conversion.
|
||||
private void runUUIDConvert(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage("Starting Essentials UUID userdata conversion; this may lag the server.");
|
||||
|
||||
final Boolean ignoreUFCache = args.length > 2 && args[1].toLowerCase(Locale.ENGLISH).contains("ignore");
|
||||
EssentialsUpgrade.uuidFileConvert(ess, ignoreUFCache);
|
||||
|
||||
sender.sendMessage("UUID conversion complete. Check your server log for more information.");
|
||||
}
|
||||
|
||||
// Looks up various UUIDs for a user.
|
||||
private void runUUIDTest(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new Exception("/<command> uuidtest <name>");
|
||||
// Gets information about cached users
|
||||
private void runUserMap(final CommandSource sender, final String[] args) {
|
||||
if (!sender.isAuthorized("essentials.usermap", ess)) {
|
||||
return;
|
||||
}
|
||||
final String name = args[1];
|
||||
sender.sendMessage("Looking up UUID for " + name);
|
||||
|
||||
UUID onlineUUID = null;
|
||||
final ModernUserMap userMap = (ModernUserMap) ess.getUsers();
|
||||
sender.sendMessage(tl("usermapSize", userMap.getCachedCount(), userMap.getUserCount(), ess.getSettings().getMaxUserCacheCount()));
|
||||
if (args.length > 1) {
|
||||
if (args[1].equals("full")) {
|
||||
for (final Map.Entry<String, UUID> entry : userMap.getNameCache().entrySet()) {
|
||||
sender.sendMessage(tl("usermapEntry", entry.getKey(), entry.getValue().toString()));
|
||||
}
|
||||
} else if (args[1].equals("purge")) {
|
||||
final boolean seppuku = args.length > 2 && args[2].equals("iknowwhatimdoing");
|
||||
|
||||
for (final Player player : ess.getOnlinePlayers()) {
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
onlineUUID = player.getUniqueId();
|
||||
break;
|
||||
sender.sendMessage(tl("usermapPurge", String.valueOf(seppuku)));
|
||||
|
||||
final Set<UUID> uuids = new HashSet<>(ess.getUsers().getAllUserUUIDs());
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
final File backupFolder = new File(ess.getDataFolder(), "userdata-npc-backup-boogaloo-" + System.currentTimeMillis());
|
||||
|
||||
if (!userdataFolder.isDirectory()) {
|
||||
ess.getLogger().warning("Missing userdata folder, aborting usermap purge.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (seppuku && !backupFolder.mkdir()) {
|
||||
ess.getLogger().warning("Unable to create backup folder, aborting usermap purge.");
|
||||
return;
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
final File[] files = userdataFolder.listFiles(EssentialsUpgrade.YML_FILTER);
|
||||
if (files != null) {
|
||||
for (final File file : files) {
|
||||
try {
|
||||
final String fileName = file.getName();
|
||||
final UUID uuid = UUID.fromString(fileName.substring(0, fileName.length() - 4));
|
||||
if (!uuids.contains(uuid)) {
|
||||
total++;
|
||||
ess.getLogger().warning("Found orphaned userdata file: " + file.getName());
|
||||
if (seppuku) {
|
||||
try {
|
||||
com.google.common.io.Files.move(file, new File(backupFolder, file.getName()));
|
||||
} catch (IOException e) {
|
||||
ess.getLogger().log(Level.WARNING, "Unable to move orphaned userdata file: " + file.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ess.getLogger().info("Found " + total + " orphaned userdata files.");
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
final UUID uuid = UUID.fromString(args[1]);
|
||||
for (final Map.Entry<String, UUID> entry : userMap.getNameCache().entrySet()) {
|
||||
if (entry.getValue().equals(uuid)) {
|
||||
sender.sendMessage(tl("usermapEntry", entry.getKey(), args[1]));
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
final String sanitizedName = userMap.getSanitizedName(args[1]);
|
||||
sender.sendMessage(tl("usermapEntry", sanitizedName, userMap.getNameCache().get(sanitizedName).toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final UUID essUUID = ess.getUserMap().getUser(name).getConfigUUID();
|
||||
|
||||
final org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
|
||||
final UUID bukkituuid = player.getUniqueId();
|
||||
sender.sendMessage("Bukkit Lookup: " + bukkituuid.toString());
|
||||
|
||||
if (onlineUUID != null && onlineUUID != bukkituuid) {
|
||||
sender.sendMessage("Online player: " + onlineUUID.toString());
|
||||
}
|
||||
|
||||
if (essUUID != null && essUUID != bukkituuid) {
|
||||
sender.sendMessage("Essentials config: " + essUUID.toString());
|
||||
}
|
||||
|
||||
final UUID npcuuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
sender.sendMessage("NPC UUID: " + npcuuid.toString());
|
||||
|
||||
final UUID offlineuuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8));
|
||||
sender.sendMessage("Offline Mode UUID: " + offlineuuid.toString());
|
||||
}
|
||||
|
||||
// Displays versions of EssentialsX and related plugins.
|
||||
@@ -750,7 +831,6 @@ public class Commandessentials extends EssentialsCommand {
|
||||
options.add("cleanup");
|
||||
options.add("homes");
|
||||
//options.add("uuidconvert");
|
||||
//options.add("uuidtest");
|
||||
//options.add("nya");
|
||||
//options.add("moo");
|
||||
return options;
|
||||
@@ -763,7 +843,6 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
break;
|
||||
case "reset":
|
||||
case "uuidtest":
|
||||
if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
@@ -782,11 +861,6 @@ public class Commandessentials extends EssentialsCommand {
|
||||
return server.getWorlds().stream().map(World::getName).collect(Collectors.toList());
|
||||
}
|
||||
break;
|
||||
case "uuidconvert":
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("ignoreUFCache");
|
||||
}
|
||||
break;
|
||||
case "dump":
|
||||
final List<String> list = Lists.newArrayList("config", "kits", "log", "discord", "worth", "tpr", "spawns", "commands", "all");
|
||||
for (String arg : args) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -81,13 +81,8 @@ public class Commandgive extends EssentialsLoopCommand {
|
||||
final ItemStack finalStack = stack;
|
||||
loopOnlinePlayersConsumer(server, sender, false, true, args[0], player -> {
|
||||
sender.sendMessage(tl("giveSpawn", finalStack.getAmount(), itemName, player.getDisplayName()));
|
||||
final Map<Integer, ItemStack> leftovers;
|
||||
|
||||
if (player.isAuthorized("essentials.oversizedstacks")) {
|
||||
leftovers = InventoryWorkaround.addOversizedItems(player.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), finalStack);
|
||||
} else {
|
||||
leftovers = InventoryWorkaround.addItems(player.getBase().getInventory(), finalStack);
|
||||
}
|
||||
final Map<Integer, ItemStack> leftovers = Inventories.addItem(player.getBase(), player.isAuthorized("essentials.oversizedstacks") ? ess.getSettings().getOversizedStackSize() : 0, finalStack);
|
||||
|
||||
for (final ItemStack item : leftovers.values()) {
|
||||
if (isDropItemsIfFull) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -28,7 +28,7 @@ public class Commandhat extends EssentialsCommand {
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0 || (!args[0].contains("rem") && !args[0].contains("off") && !args[0].equalsIgnoreCase("0"))) {
|
||||
final ItemStack hand = user.getItemInHand();
|
||||
final ItemStack hand = Inventories.getItemInMainHand(user.getBase());
|
||||
if (hand == null || hand.getType() == Material.AIR) {
|
||||
user.sendMessage(tl("hatFail"));
|
||||
return;
|
||||
@@ -53,7 +53,7 @@ public class Commandhat extends EssentialsCommand {
|
||||
return;
|
||||
}
|
||||
inv.setHelmet(hand);
|
||||
inv.setItemInHand(head);
|
||||
Inventories.setItemInMainHand(user.getBase(), head);
|
||||
user.sendMessage(tl("hatPlaced"));
|
||||
return;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class Commandhat extends EssentialsCommand {
|
||||
} else {
|
||||
final ItemStack air = new ItemStack(Material.AIR);
|
||||
inv.setHelmet(air);
|
||||
InventoryWorkaround.addItems(user.getBase().getInventory(), head);
|
||||
Inventories.addItem(user.getBase(), head);
|
||||
user.sendMessage(tl("hatRemoved"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
@@ -63,11 +63,7 @@ public class Commanditem extends EssentialsCommand {
|
||||
|
||||
final String displayName = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace('_', ' ');
|
||||
user.sendMessage(tl("itemSpawn", stack.getAmount(), displayName));
|
||||
if (user.isAuthorized("essentials.oversizedstacks")) {
|
||||
InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), stack);
|
||||
} else {
|
||||
InventoryWorkaround.addItems(user.getBase().getInventory(), stack);
|
||||
}
|
||||
Inventories.addItem(user.getBase(), user.isAuthorized("essentials.oversizedstacks") ? ess.getSettings().getOversizedStackSize() : 0, stack);
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
@@ -24,8 +25,8 @@ public class Commanditemlore extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack item = user.getBase().getItemInHand();
|
||||
if (MaterialUtil.isAir(item.getType())) {
|
||||
final ItemStack item = Inventories.getItemInHand(user.getBase());
|
||||
if (item == null || MaterialUtil.isAir(item.getType())) {
|
||||
throw new Exception(tl("itemloreInvalidItem"));
|
||||
}
|
||||
|
||||
@@ -73,8 +74,8 @@ public class Commanditemlore extends EssentialsCommand {
|
||||
} else if (args.length == 2) {
|
||||
switch (args[0].toLowerCase(Locale.ENGLISH)) {
|
||||
case "set": {
|
||||
final ItemStack item = user.getBase().getItemInHand();
|
||||
if (!MaterialUtil.isAir(item.getType()) && item.hasItemMeta() && item.getItemMeta().hasLore()) {
|
||||
final ItemStack item = Inventories.getItemInHand(user.getBase());
|
||||
if (item != null && !MaterialUtil.isAir(item.getType()) && item.hasItemMeta() && item.getItemMeta().hasLore()) {
|
||||
final List<String> lineNumbers = new ArrayList<>();
|
||||
for (int i = 1; i <= item.getItemMeta().getLore().size(); i++) {
|
||||
lineNumbers.add(String.valueOf(i));
|
||||
@@ -92,8 +93,8 @@ public class Commanditemlore extends EssentialsCommand {
|
||||
} else if (args.length == 3) {
|
||||
if (args[0].equalsIgnoreCase("set") && NumberUtil.isInt(args[1])) {
|
||||
final int i = Integer.parseInt(args[1]);
|
||||
final ItemStack item = user.getBase().getItemInHand();
|
||||
if (!MaterialUtil.isAir(item.getType()) && item.hasItemMeta() && item.getItemMeta().hasLore() && item.getItemMeta().getLore().size() >= i) {
|
||||
final ItemStack item = Inventories.getItemInHand(user.getBase());
|
||||
if (item != null && !MaterialUtil.isAir(item.getType()) && item.hasItemMeta() && item.getItemMeta().hasLore() && item.getItemMeta().getLore().size() >= i) {
|
||||
return Lists.newArrayList(FormatUtil.unformatString(user, "essentials.itemlore", item.getItemMeta().getLore().get(i - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
@@ -23,8 +24,8 @@ public class Commanditemname extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack item = user.getBase().getItemInHand();
|
||||
if (MaterialUtil.isAir(item.getType())) {
|
||||
final ItemStack item = Inventories.getItemInHand(user.getBase());
|
||||
if (item == null || MaterialUtil.isAir(item.getType())) {
|
||||
user.sendMessage(tl("itemnameInvalidItem"));
|
||||
return;
|
||||
}
|
||||
@@ -50,8 +51,8 @@ public class Commanditemname extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
final ItemStack item = user.getBase().getItemInHand();
|
||||
if (!MaterialUtil.isAir(item.getType()) && item.hasItemMeta() && item.getItemMeta().hasDisplayName()) {
|
||||
final ItemStack item = Inventories.getItemInHand(user.getBase());
|
||||
if (item != null && !MaterialUtil.isAir(item.getType()) && item.hasItemMeta() && item.getItemMeta().hasDisplayName()) {
|
||||
return Lists.newArrayList(FormatUtil.unformatString(user, "essentials.itemname", item.getItemMeta().getDisplayName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,8 +261,8 @@ public class Commandmail extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (UUID userid : ess.getUserMap().getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(userid);
|
||||
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user != null) {
|
||||
user.sendMail(messageRecipient, message, dateDiff);
|
||||
}
|
||||
@@ -298,9 +298,21 @@ public class Commandmail extends EssentialsCommand {
|
||||
if (pages == 0) {
|
||||
return Lists.newArrayList("0");
|
||||
} else {
|
||||
final List<String> options = Lists.newArrayList("1");
|
||||
if (pages > 1) {
|
||||
options.add(String.valueOf(pages));
|
||||
final List<String> options = new ArrayList<>();
|
||||
for (int i = 0; i < pages; i++) {
|
||||
options.add(String.valueOf(i + 1));
|
||||
}
|
||||
return options;
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("clear")) {
|
||||
final ArrayList<MailMessage> mail = user.getMailMessages();
|
||||
// We show up to 9 mails on a page, we don't need to autocomplete more than that...
|
||||
if (mail.size() >= 9) {
|
||||
return Lists.newArrayList("1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
} else {
|
||||
final List<String> options = new ArrayList<>();
|
||||
for (int i = 0; i < mail.size(); i++) {
|
||||
options.add(String.valueOf(i + 1));
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -15,6 +16,9 @@ import java.util.List;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandnuke extends EssentialsCommand {
|
||||
|
||||
public static final String NUKE_META_KEY = "ess_tnt_proj";
|
||||
|
||||
public Commandnuke() {
|
||||
super("nuke");
|
||||
}
|
||||
@@ -30,7 +34,6 @@ public class Commandnuke extends EssentialsCommand {
|
||||
} else {
|
||||
targets = ess.getOnlinePlayers();
|
||||
}
|
||||
ess.getTNTListener().enable();
|
||||
for (final Player player : targets) {
|
||||
if (player == null) {
|
||||
continue;
|
||||
@@ -38,9 +41,12 @@ public class Commandnuke extends EssentialsCommand {
|
||||
player.sendMessage(tl("nuke"));
|
||||
final Location loc = player.getLocation();
|
||||
final World world = loc.getWorld();
|
||||
for (int x = -10; x <= 10; x += 5) {
|
||||
for (int z = -10; z <= 10; z += 5) {
|
||||
world.spawn(new Location(world, loc.getBlockX() + x, world.getHighestBlockYAt(loc) + 64, loc.getBlockZ() + z), TNTPrimed.class);
|
||||
if (world != null) {
|
||||
for (int x = -10; x <= 10; x += 5) {
|
||||
for (int z = -10; z <= 10; z += 5) {
|
||||
final TNTPrimed entity = world.spawn(new Location(world, loc.getBlockX() + x, world.getHighestBlockYAt(loc) + 64, loc.getBlockZ() + z), TNTPrimed.class);
|
||||
entity.setMetadata(NUKE_META_KEY, new FixedMetadataValue(ess, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
@@ -22,7 +23,7 @@ public class Commandpowertool extends EssentialsCommand {
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final String command = getFinalArg(args, 0);
|
||||
final ItemStack itemStack = user.getBase().getItemInHand();
|
||||
final ItemStack itemStack = Inventories.getItemInHand(user.getBase());
|
||||
powertool(user.getSource(), user, itemStack, command);
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ public class Commandpowertool extends EssentialsCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
final ItemStack itemStack = user.getBase().getItemInHand();
|
||||
final ItemStack itemStack = Inventories.getItemInHand(user.getBase());
|
||||
final List<String> powertools = user.getPowertool(itemStack);
|
||||
for (final String tool : powertools) {
|
||||
options.add("r:" + tool);
|
||||
|
||||
@@ -155,6 +155,7 @@ public class Commandrecipe extends EssentialsCommand {
|
||||
final List<ItemStack> ingredients = recipe.getIngredientList();
|
||||
if (showWindow) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
user.getBase().closeInventory();
|
||||
user.setRecipeSee(true);
|
||||
final InventoryView view = user.getBase().openWorkbench(null, true);
|
||||
for (int i = 0; i < ingredients.size(); i++) {
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IUser;
|
||||
import net.essentialsx.api.v2.events.HomeModifyEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandrenamehome extends EssentialsCommand {
|
||||
public Commandrenamehome() {
|
||||
super("renamehome");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
User usersHome = user;
|
||||
final String oldName;
|
||||
final String newName;
|
||||
|
||||
// Allowing both formats /renamehome jroy home1 home | /sethome jroy:home1 home
|
||||
if (args.length == 2) {
|
||||
final String[] nameParts = args[0].split(":", 2);
|
||||
newName = args[1].toLowerCase(Locale.ENGLISH);
|
||||
|
||||
if (nameParts.length == 2) {
|
||||
oldName = nameParts[1].toLowerCase(Locale.ENGLISH);
|
||||
if (user.isAuthorized("essentials.renamehome.others")) {
|
||||
usersHome = getPlayer(server, nameParts[0], true, true);
|
||||
if (usersHome == null) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
oldName = args[0].toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
} else if (args.length == 3) {
|
||||
if (!user.isAuthorized("essentials.renamehome.others")) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
usersHome = getPlayer(server, args[0], true, true);
|
||||
if (usersHome == null) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
|
||||
oldName = args[1].toLowerCase(Locale.ENGLISH);
|
||||
newName = args[2].toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
if ("bed".equals(newName) || NumberUtil.isInt(newName) || "bed".equals(oldName) || NumberUtil.isInt(oldName)) {
|
||||
throw new NoSuchFieldException(tl("invalidHomeName"));
|
||||
}
|
||||
|
||||
final HomeModifyEvent event = new HomeModifyEvent(user, usersHome, oldName, newName, usersHome.getHome(oldName));
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("HomeModifyEvent canceled for /renamehome execution by " + user.getDisplayName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
usersHome.renameHome(oldName, newName);
|
||||
user.sendMessage(tl("homeRenamed", oldName, newName));
|
||||
usersHome.setLastHomeConfirmation(null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
final IUser user = sender.getUser(ess);
|
||||
if (args.length != 1) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<String> homes = user == null ? new ArrayList<>() : user.getHomes();
|
||||
final boolean canRenameOthers = sender.isAuthorized("essentials.renamehome.others", ess);
|
||||
|
||||
if (canRenameOthers) {
|
||||
final int sepIndex = args[0].indexOf(':');
|
||||
if (sepIndex < 0) {
|
||||
getPlayers(server, sender).forEach(player -> homes.add(player + ":"));
|
||||
} else {
|
||||
final String namePart = args[0].substring(0, sepIndex);
|
||||
final User otherUser;
|
||||
try {
|
||||
otherUser = getPlayer(server, new String[]{namePart}, 0, true, true);
|
||||
} catch (final Exception ex) {
|
||||
return homes;
|
||||
}
|
||||
otherUser.getHomes().forEach(home -> homes.add(namePart + ":" + home));
|
||||
}
|
||||
}
|
||||
return homes;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
@@ -62,7 +63,7 @@ public class Commandrepair extends EssentialsCommand {
|
||||
|
||||
public void repairAll(final User user) throws Exception {
|
||||
final List<String> repaired = new ArrayList<>();
|
||||
repairItems(user.getBase().getInventory().getContents(), user, repaired);
|
||||
repairItems(Inventories.getInventory(user.getBase(), false), user, repaired);
|
||||
|
||||
if (user.isAuthorized("essentials.repair.armor")) {
|
||||
repairItems(user.getBase().getInventory().getArmorContents(), user, repaired);
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.UserMap;
|
||||
import com.earth2me.essentials.craftbukkit.BanLookup;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
@@ -63,7 +62,7 @@ public class Commandseen extends EssentialsCommand {
|
||||
ess.getScheduler().runTaskAsynchronously(ess, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final User userFromBukkit = ess.getUserMap().getUserFromBukkit(args[0]);
|
||||
final User userFromBukkit = ess.getUsers().getUser(args[0]);
|
||||
try {
|
||||
if (userFromBukkit != null) {
|
||||
showUserSeen(userFromBukkit);
|
||||
@@ -103,8 +102,8 @@ public class Commandseen extends EssentialsCommand {
|
||||
user.setDisplayNick();
|
||||
sender.sendMessage(tl("seenOnline", user.getDisplayName(), DateUtil.formatDateDiff(user.getLastLogin())));
|
||||
|
||||
final List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
if (history != null && history.size() > 1) {
|
||||
final List<String> history = user.getPastUsernames();
|
||||
if (history != null && !history.isEmpty()) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
|
||||
@@ -139,7 +138,7 @@ public class Commandseen extends EssentialsCommand {
|
||||
user.setDisplayNick();
|
||||
if (user.getLastLogout() > 0) {
|
||||
sender.sendMessage(tl("seenOffline", user.getName(), DateUtil.formatDateDiff(user.getLastLogout())));
|
||||
final List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
final List<String> history = user.getPastUsernames();
|
||||
if (history != null && history.size() > 1) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
@@ -192,14 +191,12 @@ public class Commandseen extends EssentialsCommand {
|
||||
}
|
||||
|
||||
private void seenIP(final CommandSource sender, final String ipAddress, final String display) {
|
||||
final UserMap userMap = ess.getUserMap();
|
||||
|
||||
sender.sendMessage(tl("runningPlayerMatch", display));
|
||||
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
final List<String> matches = new ArrayList<>();
|
||||
for (final UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
@@ -108,11 +109,11 @@ public class Commandsell extends EssentialsCommand {
|
||||
//TODO: Prices for Enchantments
|
||||
final ItemStack ris = is.clone();
|
||||
ris.setAmount(amount);
|
||||
if (!user.getBase().getInventory().containsAtLeast(ris, amount)) {
|
||||
if (!Inventories.containsAtLeast(user.getBase(), ris, amount)) {
|
||||
// This should never happen.
|
||||
throw new IllegalStateException("Trying to remove more items than are available.");
|
||||
}
|
||||
user.getBase().getInventory().removeItem(ris);
|
||||
Inventories.removeItemAmount(user.getBase(), ris, ris.getAmount());
|
||||
user.getBase().updateInventory();
|
||||
Trade.log("Command", "Sell", "Item", user.getName(), new Trade(ris, ess), user.getName(), new Trade(result, ess), user.getLocation(), user.getMoney(), ess);
|
||||
user.giveMoney(result, null, UserBalanceUpdateEvent.Cause.COMMAND_SELL);
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.essentialsx.api.v2.events.HomeModifyEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
|
||||
@@ -62,8 +64,25 @@ public class Commandsethome extends EssentialsCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
final Location prevHomeLoc = usersHome.getHome(name);
|
||||
|
||||
final HomeModifyEvent event;
|
||||
if (prevHomeLoc == null) {
|
||||
event = new HomeModifyEvent(user, usersHome, name, location, true);
|
||||
} else {
|
||||
event = new HomeModifyEvent(user, usersHome, name, prevHomeLoc, location);
|
||||
}
|
||||
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("HomeModifyEvent canceled for /sethome execution by " + user.getDisplayName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
usersHome.setHome(name, location);
|
||||
user.sendMessage(tl("homeSet", user.getLocation().getWorld().getName(), user.getLocation().getBlockX(), user.getLocation().getBlockY(), user.getLocation().getBlockZ(), name));
|
||||
user.sendMessage(tl("homeSet", location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), name));
|
||||
usersHome.setLastHomeConfirmation(null);
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Commandsetworth extends EssentialsCommand {
|
||||
final ItemStack stack;
|
||||
final String price;
|
||||
if (args.length == 1) {
|
||||
stack = user.getBase().getInventory().getItemInHand();
|
||||
stack = user.getItemInHand();
|
||||
price = args[0];
|
||||
} else {
|
||||
stack = ess.getItemDb().get(args[0]);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -9,7 +9,6 @@ import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -60,26 +59,21 @@ public class Commandskull extends EssentialsCommand {
|
||||
}
|
||||
|
||||
private void editSkull(final User user, final ItemStack stack, final SkullMeta skullMeta, final String owner, final boolean spawn) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Run this stuff async because SkullMeta#setOwner causes a http request.
|
||||
skullMeta.setDisplayName("§fSkull of " + owner);
|
||||
skullMeta.setOwner(owner);
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
stack.setItemMeta(skullMeta);
|
||||
if (spawn) {
|
||||
InventoryWorkaround.addItems(user.getBase().getInventory(), stack);
|
||||
user.sendMessage(tl("givenSkull", owner));
|
||||
return;
|
||||
}
|
||||
user.sendMessage(tl("skullChanged", owner));
|
||||
}
|
||||
}.runTask(ess);
|
||||
}
|
||||
}.runTaskAsynchronously(ess);
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
//Run this stuff async because SkullMeta#setOwner causes a http request.
|
||||
skullMeta.setDisplayName("§fSkull of " + owner);
|
||||
//noinspection deprecation
|
||||
skullMeta.setOwner(owner);
|
||||
ess.scheduleSyncDelayedTask(() -> {
|
||||
stack.setItemMeta(skullMeta);
|
||||
if (spawn) {
|
||||
Inventories.addItem(user.getBase(), stack);
|
||||
user.sendMessage(tl("givenSkull", owner));
|
||||
return;
|
||||
}
|
||||
user.sendMessage(tl("skullChanged", owner));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,12 +24,12 @@ public class Commandtop extends EssentialsCommand {
|
||||
final float yaw = user.getLocation().getYaw();
|
||||
final Location unsafe = new Location(user.getWorld(), topX, ess.getWorldInfoProvider().getMaxHeight(user.getWorld()), topZ, yaw, pitch);
|
||||
final Location safe = LocationUtil.getSafeDestination(ess, unsafe);
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
final CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
user.sendMessage(tl("teleportTop", safe.getWorld().getName(), safe.getBlockX(), safe.getBlockY(), safe.getBlockZ()));
|
||||
}
|
||||
});
|
||||
user.getAsyncTeleport().teleport(safe, new Trade(this.getName(), ess), TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
user.getAsyncTeleport().teleport(safe, new Trade(this.getName(), ess), TeleportCause.COMMAND, future);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,11 @@ public class Commandtpoffline extends EssentialsCommand {
|
||||
final User target = getPlayer(server, args, 0, true, true);
|
||||
final Location logout = target.getLogoutLocation();
|
||||
|
||||
if (logout == null) {
|
||||
user.sendMessage(tl("teleportOfflineUnknown", user.getDisplayName()));
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
if (user.getWorld() != logout.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + logout.getWorld().getName())) {
|
||||
throw new Exception(tl("noPerm", "essentials.worlds." + logout.getWorld().getName()));
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ public class Commandtppos extends EssentialsCommand {
|
||||
}
|
||||
|
||||
final User user = getPlayer(server, args, 0, true, false);
|
||||
final double x = args[1].startsWith("~") ? user.getLocation().getX() + (args[1].length() > 1 ? Integer.parseInt(args[1].substring(1)) : 0) : Integer.parseInt(args[1]);
|
||||
final double y = args[2].startsWith("~") ? user.getLocation().getY() + (args[2].length() > 1 ? Integer.parseInt(args[2].substring(1)) : 0) : Integer.parseInt(args[2]);
|
||||
final double z = args[3].startsWith("~") ? user.getLocation().getZ() + (args[3].length() > 1 ? Integer.parseInt(args[3].substring(1)) : 0) : Integer.parseInt(args[3]);
|
||||
final double x = args[1].startsWith("~") ? user.getLocation().getX() + (args[1].length() > 1 ? Double.parseDouble(args[1].substring(1)) : 0) : Double.parseDouble(args[1]);
|
||||
final double y = args[2].startsWith("~") ? user.getLocation().getY() + (args[2].length() > 1 ? Double.parseDouble(args[2].substring(1)) : 0) : Double.parseDouble(args[2]);
|
||||
final double z = args[3].startsWith("~") ? user.getLocation().getZ() + (args[3].length() > 1 ? Double.parseDouble(args[3].substring(1)) : 0) : Double.parseDouble(args[3]);
|
||||
final Location loc = new Location(user.getWorld(), x, y, z, user.getLocation().getYaw(), user.getLocation().getPitch());
|
||||
if (args.length == 5) {
|
||||
loc.setWorld(ess.getWorld(args[4]));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -75,8 +76,8 @@ public class Commandunlimited extends EssentialsCommand {
|
||||
if (!target.hasUnlimited(stack)) {
|
||||
message = "enableUnlimited";
|
||||
enableUnlimited = true;
|
||||
if (!target.getBase().getInventory().containsAtLeast(stack, stack.getAmount())) {
|
||||
target.getBase().getInventory().addItem(stack);
|
||||
if (!Inventories.containsAtLeast(target.getBase(), stack, stack.getAmount())) {
|
||||
Inventories.addItem(target.getBase(), stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class Commandwhois extends EssentialsCommand {
|
||||
sender.sendMessage(tl("whoisHunger", user.getBase().getFoodLevel(), user.getBase().getSaturation()));
|
||||
sender.sendMessage(tl("whoisExp", SetExpFix.getTotalExperience(user.getBase()), user.getBase().getLevel()));
|
||||
sender.sendMessage(tl("whoisLocation", user.getLocation().getWorld().getName(), user.getLocation().getBlockX(), user.getLocation().getBlockY(), user.getLocation().getBlockZ()));
|
||||
final long playtimeMs = System.currentTimeMillis() - (user.getBase().getStatistic(PLAY_ONE_TICK) * 50);
|
||||
final long playtimeMs = System.currentTimeMillis() - (user.getBase().getStatistic(PLAY_ONE_TICK) * 50L);
|
||||
sender.sendMessage(tl("whoisPlaytime", DateUtil.formatDateDiff(playtimeMs)));
|
||||
if (!ess.getSettings().isEcoDisabled()) {
|
||||
sender.sendMessage(tl("whoisMoney", NumberUtil.displayCurrency(user.getMoney(), ess)));
|
||||
|
||||
+8
-3
@@ -30,11 +30,16 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
|
||||
final UUID uuid = StringUtil.toUUID(searchTerm);
|
||||
if (uuid != null) {
|
||||
final User matchedUser = ess.getUser(uuid);
|
||||
if (matchedUser == null) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
userConsumer.accept(matchedUser);
|
||||
} else if (matchWildcards && searchTerm.contentEquals("**")) {
|
||||
for (final UUID sUser : ess.getUserMap().getAllUniqueUsers()) {
|
||||
final User matchedUser = ess.getUser(sUser);
|
||||
userConsumer.accept(matchedUser);
|
||||
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||
final User user = ess.getUsers().loadUncachedUser(u);
|
||||
if (user != null) {
|
||||
userConsumer.accept(user);
|
||||
}
|
||||
}
|
||||
} else if (matchWildcards && searchTerm.contentEquals("*")) {
|
||||
final boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
|
||||
+30
-2
@@ -33,7 +33,9 @@ import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -103,6 +105,15 @@ public class EssentialsConfiguration {
|
||||
return configurationNode;
|
||||
}
|
||||
|
||||
public void setRootHolder(final Class<?> holderClass, final Object holder) {
|
||||
try {
|
||||
getRootNode().set(holderClass, holder);
|
||||
} catch (SerializationException e) {
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "Error while saving user config: " + configFile.getName(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return configFile;
|
||||
}
|
||||
@@ -294,6 +305,19 @@ public class EssentialsConfiguration {
|
||||
return ConfigurateUtil.getMap(configurationNode);
|
||||
}
|
||||
|
||||
public Map<String, String> getStringMap(String path) {
|
||||
final CommentedConfigurationNode node = getInternal(path);
|
||||
if (node == null || !node.isMap()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final Map<String, String> map = new LinkedHashMap<>();
|
||||
for (Map.Entry<Object, CommentedConfigurationNode> entry : node.childrenMap().entrySet()) {
|
||||
map.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue().rawScalar()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public void removeProperty(String path) {
|
||||
final CommentedConfigurationNode node = getInternal(path);
|
||||
if (node != null) {
|
||||
@@ -366,10 +390,10 @@ public class EssentialsConfiguration {
|
||||
} catch (final ParsingException e) {
|
||||
final File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
|
||||
if (configFile.renameTo(broken)) {
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), e.getCause());
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "The file " + configFile + " is broken, it has been renamed to " + broken, e.getCause());
|
||||
return;
|
||||
}
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "The file " + configFile.toString() + " is broken. A backup file has failed to be created", e.getCause());
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "The file " + configFile + " is broken. A backup file has failed to be created", e.getCause());
|
||||
} catch (final ConfigurateException e) {
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
@@ -420,6 +444,10 @@ public class EssentialsConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTransaction() {
|
||||
return transaction.get();
|
||||
}
|
||||
|
||||
public void setSaveHook(Runnable saveHook) {
|
||||
this.saveHook = saveHook;
|
||||
}
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ public class EssentialsUserConfiguration extends EssentialsConfiguration {
|
||||
|
||||
private File getAltFile() {
|
||||
final UUID fn = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username.toLowerCase(Locale.ENGLISH)).getBytes(Charsets.UTF_8));
|
||||
return new File(configFile.getParentFile(), fn.toString() + ".yml");
|
||||
return new File(configFile.getParentFile(), fn + ".yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -262,6 +262,16 @@ public class UserConfigHolder {
|
||||
this.lastAccountName = value;
|
||||
}
|
||||
|
||||
private @MonotonicNonNull String npcName;
|
||||
|
||||
public String npcName() {
|
||||
return this.npcName;
|
||||
}
|
||||
|
||||
public void npcName(final String value) {
|
||||
this.npcName = value;
|
||||
}
|
||||
|
||||
private boolean powertoolsenabled = true;
|
||||
|
||||
public boolean powerToolsEnabled() {
|
||||
@@ -332,6 +342,20 @@ public class UserConfigHolder {
|
||||
this.shouting = value;
|
||||
}
|
||||
|
||||
@DeleteOnEmpty
|
||||
private @MonotonicNonNull List<String> pastUsernames;
|
||||
|
||||
public List<String> pastUsernames() {
|
||||
if (this.pastUsernames == null) {
|
||||
this.pastUsernames = new ArrayList<>();
|
||||
}
|
||||
return this.pastUsernames;
|
||||
}
|
||||
|
||||
public void pastUsernames(List<String> value) {
|
||||
this.pastUsernames = value;
|
||||
}
|
||||
|
||||
private @NonNull Timestamps timestamps = new Timestamps();
|
||||
|
||||
public Timestamps timestamps() {
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
package com.earth2me.essentials.craftbukkit;
|
||||
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public final class Inventories {
|
||||
private static final int HELM_SLOT = 39;
|
||||
private static final int CHEST_SLOT = 38;
|
||||
private static final int LEG_SLOT = 37;
|
||||
private static final int BOOT_SLOT = 36;
|
||||
private static final boolean HAS_OFFHAND = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01);
|
||||
private static final int INVENTORY_SIZE = HAS_OFFHAND ? 41 : 40;
|
||||
|
||||
private Inventories() {
|
||||
}
|
||||
|
||||
public static ItemStack getItemInHand(final Player player) {
|
||||
if (!HAS_OFFHAND) {
|
||||
//noinspection deprecation
|
||||
return player.getInventory().getItemInHand();
|
||||
}
|
||||
final PlayerInventory inventory = player.getInventory();
|
||||
final ItemStack main = inventory.getItemInMainHand();
|
||||
return !isEmpty(main) ? main : inventory.getItemInOffHand();
|
||||
}
|
||||
|
||||
public static ItemStack getItemInMainHand(final Player player) {
|
||||
if (!HAS_OFFHAND) {
|
||||
//noinspection deprecation
|
||||
return player.getInventory().getItemInHand();
|
||||
}
|
||||
return player.getInventory().getItemInMainHand();
|
||||
}
|
||||
|
||||
public static void setItemInMainHand(final Player player, final ItemStack stack) {
|
||||
if (HAS_OFFHAND) {
|
||||
player.getInventory().setItemInMainHand(stack);
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
player.setItemInHand(stack);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setItemInMainHand(final EntityEquipment entityEquipment, final ItemStack stack) {
|
||||
if (HAS_OFFHAND) {
|
||||
entityEquipment.setItemInMainHand(stack);
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
entityEquipment.setItemInHand(stack);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setItemInMainHandDropChance(final EntityEquipment entityEquipment, final float chance) {
|
||||
if (HAS_OFFHAND) {
|
||||
entityEquipment.setItemInMainHandDropChance(chance);
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
entityEquipment.setItemInHandDropChance(chance);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean containsAtLeast(final Player player, final ItemStack item, int amount) {
|
||||
for (final ItemStack invItem : player.getInventory().getContents()) {
|
||||
if (isEmpty(invItem)) {
|
||||
continue;
|
||||
}
|
||||
if (invItem.isSimilar(item)) {
|
||||
amount -= invItem.getAmount();
|
||||
if (amount <= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasSpace(final Player player, final int maxStack, final boolean includeArmor, ItemStack... items) {
|
||||
items = normalizeItems(cloneItems(items));
|
||||
final InventoryData inventoryData = parseInventoryData(player.getInventory(), items, maxStack, includeArmor);
|
||||
|
||||
final List<Integer> emptySlots = inventoryData.getEmptySlots();
|
||||
for (final ItemStack item : items) {
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int itemMax = Math.max(maxStack, item.getMaxStackSize());
|
||||
final List<Integer> partialSlots = inventoryData.getPartialSlots().get(item);
|
||||
while (true) {
|
||||
if (partialSlots == null || partialSlots.isEmpty()) {
|
||||
if (emptySlots.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
emptySlots.remove(0);
|
||||
if (item.getAmount() > itemMax) {
|
||||
item.setAmount(item.getAmount() - itemMax);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
final int slot = partialSlots.remove(0);
|
||||
ItemStack existing = player.getInventory().getItem(slot);
|
||||
if (isEmpty(existing)) {
|
||||
existing = item.clone();
|
||||
existing.setAmount(0);
|
||||
}
|
||||
|
||||
final int amount = item.getAmount();
|
||||
final int existingAmount = existing.getAmount();
|
||||
|
||||
if (amount + existingAmount <= itemMax) {
|
||||
break;
|
||||
} else {
|
||||
item.setAmount(amount + existingAmount - itemMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Map<Integer, ItemStack> addItem(final Player player, final ItemStack... items) {
|
||||
return addItem(player, 0, false, items);
|
||||
}
|
||||
|
||||
public static Map<Integer, ItemStack> addItem(final Player player, final int maxStack, final ItemStack... items) {
|
||||
return addItem(player, maxStack, false, items);
|
||||
}
|
||||
|
||||
public static Map<Integer, ItemStack> addItem(final Player player, final int maxStack, final boolean allowArmor, ItemStack... items) {
|
||||
items = normalizeItems(cloneItems(items));
|
||||
final Map<Integer, ItemStack> leftover = new HashMap<>();
|
||||
final InventoryData inventoryData = parseInventoryData(player.getInventory(), items, maxStack, allowArmor);
|
||||
|
||||
final List<Integer> emptySlots = inventoryData.getEmptySlots();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
final ItemStack item = items[i];
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int itemMax = Math.max(maxStack, item.getMaxStackSize());
|
||||
final List<Integer> partialSlots = inventoryData.getPartialSlots().get(item);
|
||||
while (true) {
|
||||
if (partialSlots == null || partialSlots.isEmpty()) {
|
||||
if (emptySlots.isEmpty()) {
|
||||
leftover.put(i, item);
|
||||
break;
|
||||
}
|
||||
|
||||
final int slot = emptySlots.remove(0);
|
||||
if (item.getAmount() > itemMax) {
|
||||
final ItemStack split = item.clone();
|
||||
split.setAmount(itemMax);
|
||||
player.getInventory().setItem(slot, split);
|
||||
item.setAmount(item.getAmount() - itemMax);
|
||||
} else {
|
||||
player.getInventory().setItem(slot, item);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
final int slot = partialSlots.remove(0);
|
||||
ItemStack existing = player.getInventory().getItem(slot);
|
||||
if (isEmpty(existing)) {
|
||||
existing = item.clone();
|
||||
existing.setAmount(0);
|
||||
}
|
||||
|
||||
final int amount = item.getAmount();
|
||||
final int existingAmount = existing.getAmount();
|
||||
|
||||
if (amount + existingAmount <= itemMax) {
|
||||
existing.setAmount(amount + existingAmount);
|
||||
player.getInventory().setItem(slot, existing);
|
||||
break;
|
||||
} else {
|
||||
existing.setAmount(itemMax);
|
||||
player.getInventory().setItem(slot, existing);
|
||||
item.setAmount(amount + existingAmount - itemMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return leftover;
|
||||
}
|
||||
|
||||
public static ItemStack[] getInventory(final Player player, final boolean includeArmor) {
|
||||
final ItemStack[] items = new ItemStack[INVENTORY_SIZE];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (!includeArmor && isArmorSlot(i)) {
|
||||
items[i] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
items[i] = player.getInventory().getItem(i);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static void removeItemExact(final Player player, final ItemStack toRemove, final boolean includeArmor) {
|
||||
removeItems(player, itemStack -> itemStack.equals(toRemove), includeArmor);
|
||||
}
|
||||
|
||||
public static int removeItemSimilar(final Player player, final ItemStack toRemove, final boolean includeArmor) {
|
||||
return removeItems(player, itemStack -> itemStack.isSimilar(toRemove), includeArmor);
|
||||
}
|
||||
|
||||
public static int removeItems(final Player player, final Predicate<ItemStack> removePredicate, final boolean includeArmor) {
|
||||
int removedAmount = 0;
|
||||
final ItemStack[] items = player.getInventory().getContents();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (!includeArmor && isArmorSlot(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ItemStack item = items[i];
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (removePredicate.test(item)) {
|
||||
removedAmount += item.getAmount();
|
||||
item.setAmount(0);
|
||||
player.getInventory().setItem(i, item);
|
||||
}
|
||||
}
|
||||
return removedAmount;
|
||||
}
|
||||
|
||||
public static boolean removeItemAmount(final Player player, final ItemStack toRemove, int amount) {
|
||||
final List<Integer> clearSlots = new ArrayList<>();
|
||||
final ItemStack[] items = player.getInventory().getContents();
|
||||
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
final ItemStack item = items[i];
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.isSimilar(toRemove)) {
|
||||
if (item.getAmount() >= amount) {
|
||||
item.setAmount(item.getAmount() - amount);
|
||||
player.getInventory().setItem(i, item);
|
||||
for (final int slot : clearSlots) {
|
||||
clearSlot(player, slot);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
amount -= item.getAmount();
|
||||
clearSlots.add(i);
|
||||
}
|
||||
|
||||
if (amount == 0) {
|
||||
for (final int slot : clearSlots) {
|
||||
clearSlot(player, slot);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void clearSlot(final Player player, final int slot) {
|
||||
final ItemStack item = player.getInventory().getItem(slot);
|
||||
if (!isEmpty(item)) {
|
||||
item.setAmount(0);
|
||||
player.getInventory().setItem(slot, item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setSlot(final Player inventory, final int slot, final ItemStack item) {
|
||||
inventory.getInventory().setItem(slot, item);
|
||||
}
|
||||
|
||||
private static ItemStack[] normalizeItems(final ItemStack[] items) {
|
||||
if (items.length <= 1) {
|
||||
return items;
|
||||
}
|
||||
|
||||
final ItemStack[] normalizedItems = new ItemStack[items.length];
|
||||
int nextNormalizedIndex = 0;
|
||||
inputLoop:
|
||||
for (final ItemStack item : items) {
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < nextNormalizedIndex; j++) {
|
||||
final ItemStack normalizedItem = normalizedItems[j];
|
||||
if (isEmpty(normalizedItem)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.isSimilar(normalizedItem)) {
|
||||
normalizedItem.setAmount(normalizedItem.getAmount() + item.getAmount());
|
||||
continue inputLoop;
|
||||
}
|
||||
}
|
||||
normalizedItems[nextNormalizedIndex++] = item;
|
||||
}
|
||||
|
||||
return normalizedItems;
|
||||
}
|
||||
|
||||
private static ItemStack[] cloneItems(final ItemStack[] items) {
|
||||
final ItemStack[] clonedItems = new ItemStack[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
final ItemStack item = items[i];
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
clonedItems[i] = item.clone();
|
||||
}
|
||||
|
||||
return clonedItems;
|
||||
}
|
||||
|
||||
private static InventoryData parseInventoryData(final Inventory inventory, final ItemStack[] items, final int maxStack, final boolean includeArmor) {
|
||||
final ItemStack[] inventoryContents = inventory.getContents();
|
||||
final List<Integer> emptySlots = new ArrayList<>();
|
||||
final HashMap<ItemStack, List<Integer>> partialSlots = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < inventoryContents.length; i++) {
|
||||
if (!includeArmor && isArmorSlot(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ItemStack invItem = inventoryContents[i];
|
||||
if (isEmpty(invItem)) {
|
||||
emptySlots.add(i);
|
||||
} else {
|
||||
for (final ItemStack newItem : items) {
|
||||
if (invItem.getAmount() < Math.max(maxStack, invItem.getMaxStackSize()) && invItem.isSimilar(newItem)) {
|
||||
partialSlots.computeIfAbsent(newItem, k -> new ArrayList<>()).add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert empty armor slots to partial slots if we have armor items in the inventory, otherwise remove them from the empty slots.
|
||||
if (includeArmor) {
|
||||
ItemStack helm = null;
|
||||
ItemStack chest = null;
|
||||
ItemStack legs = null;
|
||||
ItemStack boots = null;
|
||||
for (final ItemStack item : items) {
|
||||
if (isEmpty(item)) {
|
||||
continue;
|
||||
}
|
||||
if (helm == null && MaterialUtil.isHelmet(item.getType())) {
|
||||
helm = item;
|
||||
if (emptySlots.contains(HELM_SLOT)) {
|
||||
partialSlots.computeIfAbsent(helm, k -> new ArrayList<>()).add(HELM_SLOT);
|
||||
}
|
||||
} else if (chest == null && MaterialUtil.isChestplate(item.getType())) {
|
||||
chest = item;
|
||||
if (emptySlots.contains(CHEST_SLOT)) {
|
||||
partialSlots.computeIfAbsent(chest, k -> new ArrayList<>()).add(CHEST_SLOT);
|
||||
}
|
||||
} else if (legs == null && MaterialUtil.isLeggings(item.getType())) {
|
||||
legs = item;
|
||||
if (emptySlots.contains(LEG_SLOT)) {
|
||||
partialSlots.computeIfAbsent(legs, k -> new ArrayList<>()).add(LEG_SLOT);
|
||||
}
|
||||
} else if (boots == null && MaterialUtil.isBoots(item.getType())) {
|
||||
boots = item;
|
||||
if (emptySlots.contains(BOOT_SLOT)) {
|
||||
partialSlots.computeIfAbsent(boots, k -> new ArrayList<>()).add(BOOT_SLOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
emptySlots.remove((Object) HELM_SLOT);
|
||||
emptySlots.remove((Object) CHEST_SLOT);
|
||||
emptySlots.remove((Object) LEG_SLOT);
|
||||
emptySlots.remove((Object) BOOT_SLOT);
|
||||
}
|
||||
|
||||
return new InventoryData(emptySlots, partialSlots);
|
||||
}
|
||||
|
||||
private static boolean isEmpty(final ItemStack stack) {
|
||||
return stack == null || MaterialUtil.isAir(stack.getType());
|
||||
}
|
||||
|
||||
private static boolean isArmorSlot(final int slot) {
|
||||
return slot == HELM_SLOT || slot == CHEST_SLOT || slot == LEG_SLOT || slot == BOOT_SLOT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.earth2me.essentials.craftbukkit;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class InventoryData {
|
||||
private final List<Integer> emptySlots;
|
||||
private final HashMap<ItemStack, List<Integer>> partialSlots;
|
||||
|
||||
public InventoryData(List<Integer> emptySlots, HashMap<ItemStack, List<Integer>> partialSlots) {
|
||||
this.emptySlots = emptySlots;
|
||||
this.partialSlots = partialSlots;
|
||||
}
|
||||
|
||||
public List<Integer> getEmptySlots() {
|
||||
return emptySlots;
|
||||
}
|
||||
|
||||
public HashMap<ItemStack, List<Integer>> getPartialSlots() {
|
||||
return partialSlots;
|
||||
}
|
||||
}
|
||||
-245
@@ -1,245 +0,0 @@
|
||||
package com.earth2me.essentials.craftbukkit;
|
||||
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* This class can be removed when https://github.com/Bukkit/CraftBukkit/pull/193 is accepted to CraftBukkit
|
||||
*/
|
||||
public final class InventoryWorkaround {
|
||||
/*
|
||||
Spigot 1.9, for whatever reason, decided to merge the armor and main player inventories without providing a way
|
||||
to access the main inventory. There's lots of ugly code in here to work around that.
|
||||
*/
|
||||
private static final int USABLE_PLAYER_INV_SIZE = 36;
|
||||
private static final boolean IS_OFFHAND = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01);
|
||||
|
||||
private InventoryWorkaround() {
|
||||
}
|
||||
|
||||
private static int firstPartial(final Inventory inventory, final ItemStack item, final int maxAmount) {
|
||||
if (item == null) {
|
||||
return -1;
|
||||
}
|
||||
final ItemStack[] stacks = inventory.getContents();
|
||||
for (int i = 0; i < stacks.length; i++) {
|
||||
final ItemStack cItem = stacks[i];
|
||||
if (cItem != null && cItem.getAmount() < maxAmount && cItem.isSimilar(item)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static boolean isCombinedInventory(final Inventory inventory) {
|
||||
return inventory instanceof PlayerInventory && inventory.getContents().length > USABLE_PLAYER_INV_SIZE;
|
||||
}
|
||||
|
||||
// Clears inventory without clearing armor
|
||||
public static void clearInventoryNoArmor(final PlayerInventory inventory) {
|
||||
if (isCombinedInventory(inventory)) {
|
||||
for (int i = 0; i < USABLE_PLAYER_INV_SIZE; i++) {
|
||||
inventory.setItem(i, null);
|
||||
}
|
||||
} else {
|
||||
inventory.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static Inventory makeTruncatedPlayerInventory(final PlayerInventory playerInventory) {
|
||||
final Inventory fakeInventory = Bukkit.getServer().createInventory(null, USABLE_PLAYER_INV_SIZE);
|
||||
fakeInventory.setContents(Arrays.copyOf(playerInventory.getContents(), fakeInventory.getSize()));
|
||||
return fakeInventory;
|
||||
}
|
||||
|
||||
// Returns what it couldn't store
|
||||
// This will will abort if it couldn't store all items
|
||||
public static Map<Integer, ItemStack> addAllItems(final Inventory inventory, final ItemStack... items) {
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
final Inventory fakeInventory;
|
||||
if (isCombinedInventory(inventory)) {
|
||||
fakeInventory = makeTruncatedPlayerInventory((PlayerInventory) inventory);
|
||||
} else {
|
||||
fakeInventory = Bukkit.getServer().createInventory(null, inventory.getType());
|
||||
fakeInventory.setContents(contents);
|
||||
}
|
||||
final Map<Integer, ItemStack> overflow = addItems(fakeInventory, items);
|
||||
if (overflow.isEmpty()) {
|
||||
addItems(inventory, items);
|
||||
return null;
|
||||
}
|
||||
return addItems(fakeInventory, items);
|
||||
}
|
||||
|
||||
public static Map<Integer, ItemStack> addAllOversizedItems(final Inventory inventory, final int oversizedStacks, final ItemStack... items) {
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
final Inventory fakeInventory;
|
||||
if (isCombinedInventory(inventory)) {
|
||||
fakeInventory = makeTruncatedPlayerInventory((PlayerInventory) inventory);
|
||||
} else {
|
||||
fakeInventory = Bukkit.getServer().createInventory(null, inventory.getType());
|
||||
fakeInventory.setContents(contents);
|
||||
}
|
||||
final Map<Integer, ItemStack> overflow = addOversizedItems(fakeInventory, oversizedStacks, items);
|
||||
if (overflow.isEmpty()) {
|
||||
addOversizedItems(inventory, oversizedStacks, items);
|
||||
return null;
|
||||
}
|
||||
return overflow;
|
||||
}
|
||||
|
||||
// Returns what it couldn't store
|
||||
public static Map<Integer, ItemStack> addItems(final Inventory inventory, final ItemStack... items) {
|
||||
return addOversizedItems(inventory, 0, items);
|
||||
}
|
||||
|
||||
// Returns what it couldn't store
|
||||
// Set oversizedStack to below normal stack size to disable oversized stacks
|
||||
public static Map<Integer, ItemStack> addOversizedItems(final Inventory inventory, final int oversizedStacks, final ItemStack... items) {
|
||||
if (isCombinedInventory(inventory)) {
|
||||
final Inventory fakeInventory = makeTruncatedPlayerInventory((PlayerInventory) inventory);
|
||||
final Map<Integer, ItemStack> overflow = addOversizedItems(fakeInventory, oversizedStacks, items);
|
||||
for (int i = 0; i < fakeInventory.getContents().length; i++) {
|
||||
inventory.setItem(i, fakeInventory.getContents()[i]);
|
||||
}
|
||||
return overflow;
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> leftover = new HashMap<>();
|
||||
|
||||
/*
|
||||
* TODO: some optimization - Create a 'firstPartial' with a 'fromIndex' - Record the lastPartial per Material -
|
||||
* Cache firstEmpty result
|
||||
*/
|
||||
|
||||
// combine items
|
||||
|
||||
final ItemStack[] combined = new ItemStack[items.length];
|
||||
for (final ItemStack item : items) {
|
||||
if (item == null || item.getAmount() < 1) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < combined.length; j++) {
|
||||
if (combined[j] == null) {
|
||||
combined[j] = item.clone();
|
||||
break;
|
||||
}
|
||||
if (combined[j].isSimilar(item)) {
|
||||
combined[j].setAmount(combined[j].getAmount() + item.getAmount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < combined.length; i++) {
|
||||
final ItemStack item = combined[i];
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
// Do we already have a stack of it?
|
||||
final int maxAmount = Math.max(oversizedStacks, item.getType().getMaxStackSize());
|
||||
final int firstPartial = firstPartial(inventory, item, maxAmount);
|
||||
|
||||
// Drat! no partial stack
|
||||
if (firstPartial == -1) {
|
||||
// Find a free spot!
|
||||
final int firstFree = inventory.firstEmpty();
|
||||
|
||||
if (firstFree == -1) {
|
||||
// No space at all!
|
||||
leftover.put(i, item);
|
||||
break;
|
||||
} else {
|
||||
// More than a single stack!
|
||||
if (item.getAmount() > maxAmount) {
|
||||
final ItemStack stack = item.clone();
|
||||
stack.setAmount(maxAmount);
|
||||
inventory.setItem(firstFree, stack);
|
||||
item.setAmount(item.getAmount() - maxAmount);
|
||||
} else {
|
||||
// Just store it
|
||||
inventory.setItem(firstFree, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// So, apparently it might only partially fit, well lets do just that
|
||||
final ItemStack partialItem = inventory.getItem(firstPartial);
|
||||
|
||||
final int amount = item.getAmount();
|
||||
final int partialAmount = partialItem.getAmount();
|
||||
|
||||
// Check if it fully fits
|
||||
if (amount + partialAmount <= maxAmount) {
|
||||
partialItem.setAmount(amount + partialAmount);
|
||||
break;
|
||||
}
|
||||
|
||||
// It fits partially
|
||||
partialItem.setAmount(maxAmount);
|
||||
item.setAmount(amount + partialAmount - maxAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return leftover;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setItemInMainHand(final Player p, final ItemStack item) {
|
||||
if (IS_OFFHAND) {
|
||||
p.getInventory().setItemInMainHand(item);
|
||||
} else {
|
||||
p.setItemInHand(item);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setItemInMainHand(final EntityEquipment invent, final ItemStack item) {
|
||||
if (IS_OFFHAND) {
|
||||
invent.setItemInMainHand(item);
|
||||
} else {
|
||||
invent.setItemInHand(item);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setItemInMainHandDropChance(final EntityEquipment invent, final float chance) {
|
||||
if (IS_OFFHAND) {
|
||||
invent.setItemInMainHandDropChance(chance);
|
||||
} else {
|
||||
invent.setItemInHandDropChance(chance);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setItemInOffHand(final Player p, final ItemStack item) {
|
||||
if (IS_OFFHAND) {
|
||||
p.getInventory().setItemInOffHand(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static int clearItemInOffHand(final Player p, final ItemStack item) {
|
||||
if (IS_OFFHAND) {
|
||||
int removedAmount = 0;
|
||||
if (p.getInventory().getItemInOffHand().getType().equals(item.getType())) {
|
||||
removedAmount = p.getInventory().getItemInOffHand().getAmount();
|
||||
p.getInventory().setItemInOffHand(null);
|
||||
}
|
||||
return removedAmount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+17
-10
@@ -11,6 +11,7 @@ import net.ess3.api.MaxMoneyException;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
@@ -308,21 +309,27 @@ public class VaultEconomyProvider implements Economy {
|
||||
npcConfig.setProperty("last-account-name", player.getName());
|
||||
npcConfig.setProperty("money", ess.getSettings().getStartingBalance());
|
||||
npcConfig.blockingSave();
|
||||
ess.getUserMap().trackUUID(player.getUniqueId(), player.getName(), false);
|
||||
// This will load the NPC into the UserMap + UUID cache
|
||||
ess.getUsers().addCachedNpcName(player.getUniqueId(), player.getName());
|
||||
ess.getUsers().getUser(player.getUniqueId());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Loading a v4 UUID that we somehow didn't track, mark it as a normal player and hope for the best, vault sucks :/
|
||||
try {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Vault requested a player account creation for a v4 UUID: " + player);
|
||||
}
|
||||
ess.getUserMap().load(player);
|
||||
return true;
|
||||
} catch (UserDoesNotExistException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Vault requested a player account creation for a v4 UUID: " + player);
|
||||
}
|
||||
|
||||
final Player userPlayer;
|
||||
if (player instanceof Player) {
|
||||
userPlayer = (Player) player;
|
||||
} else {
|
||||
final com.earth2me.essentials.OfflinePlayer essPlayer = new com.earth2me.essentials.OfflinePlayer(player.getUniqueId(), ess.getServer());
|
||||
essPlayer.setName(player.getName());
|
||||
userPlayer = essPlayer;
|
||||
}
|
||||
ess.getUsers().getUser(userPlayer);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.earth2me.essentials.items;
|
||||
|
||||
import com.earth2me.essentials.IConf;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
@@ -156,14 +157,14 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
|
||||
} else if (args[0].equalsIgnoreCase("hand")) {
|
||||
is.add(user.getItemInHand().clone());
|
||||
} else if (args[0].equalsIgnoreCase("inventory") || args[0].equalsIgnoreCase("invent") || args[0].equalsIgnoreCase("all")) {
|
||||
for (final ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack stack : Inventories.getInventory(user.getBase(), true)) {
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
is.add(stack.clone());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("blocks")) {
|
||||
for (final ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack stack : Inventories.getInventory(user.getBase(), true)) {
|
||||
if (stack == null || stack.getType() == Material.AIR || !stack.getType().isBlock()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.earth2me.essentials.perm;
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@@ -10,9 +11,15 @@ import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface IPermissionsHandler {
|
||||
String getGroup(Player base);
|
||||
boolean addToGroup(OfflinePlayer base, String group);
|
||||
|
||||
List<String> getGroups(Player base);
|
||||
boolean removeFromGroup(OfflinePlayer base, String group);
|
||||
|
||||
String getGroup(OfflinePlayer base);
|
||||
|
||||
List<String> getGroups(OfflinePlayer base);
|
||||
|
||||
List<String> getGroups();
|
||||
|
||||
boolean canBuild(Player base, String group);
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@ import com.earth2me.essentials.perm.impl.ModernVaultHandler;
|
||||
import com.earth2me.essentials.perm.impl.SuperpermsHandler;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -34,7 +36,7 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup(final Player base) {
|
||||
public String getGroup(final OfflinePlayer base) {
|
||||
final long start = System.nanoTime();
|
||||
String group = handler.getGroup(base);
|
||||
if (group == null) {
|
||||
@@ -45,16 +47,42 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups(final Player base) {
|
||||
public List<String> getGroups(final OfflinePlayer base) {
|
||||
final long start = System.nanoTime();
|
||||
List<String> groups = handler.getGroups(base);
|
||||
final List<String> groups = new ArrayList<>();
|
||||
groups.add(defaultGroup);
|
||||
groups.addAll(handler.getGroups(base));
|
||||
checkPermLag(start, String.format("Getting groups for %s", base.getName()));
|
||||
return Collections.unmodifiableList(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
final long start = System.nanoTime();
|
||||
List<String> groups = handler.getGroups();
|
||||
if (groups == null || groups.isEmpty()) {
|
||||
groups = Collections.singletonList(defaultGroup);
|
||||
}
|
||||
checkPermLag(start, String.format("Getting groups for %s", base.getName()));
|
||||
checkPermLag(start, "Getting all groups");
|
||||
return Collections.unmodifiableList(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGroup(OfflinePlayer base, String group) {
|
||||
final long start = System.nanoTime();
|
||||
final boolean result = handler.addToGroup(base, group);
|
||||
checkPermLag(start, String.format("Adding group to %s", base.getName()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromGroup(OfflinePlayer base, String group) {
|
||||
final long start = System.nanoTime();
|
||||
final boolean result = handler.removeFromGroup(base, group);
|
||||
checkPermLag(start, String.format("Removing group from %s", base.getName()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(final Player base, final String group) {
|
||||
return handler.canBuild(base, group);
|
||||
|
||||
+26
-4
@@ -3,6 +3,7 @@ package com.earth2me.essentials.perm.impl;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@@ -32,13 +33,34 @@ public abstract class AbstractVaultHandler extends SuperpermsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup(final Player base) {
|
||||
return perms.getPrimaryGroup(base);
|
||||
public String getGroup(final OfflinePlayer base) {
|
||||
if (base.isOnline()) {
|
||||
return perms.getPrimaryGroup(base.getPlayer());
|
||||
}
|
||||
return perms.getPrimaryGroup(null, base);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups(final Player base) {
|
||||
return Arrays.asList(perms.getPlayerGroups(base));
|
||||
public List<String> getGroups(final OfflinePlayer base) {
|
||||
if (base.isOnline()) {
|
||||
return Arrays.asList(perms.getPlayerGroups(base.getPlayer()));
|
||||
}
|
||||
return Arrays.asList(perms.getPlayerGroups(null, base));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
return Arrays.asList(perms.getGroups());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGroup(OfflinePlayer base, String group) {
|
||||
return perms.playerAddGroup(null, base, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromGroup(OfflinePlayer base, String group) {
|
||||
return perms.playerRemoveGroup(null, base, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -70,11 +70,11 @@ public class LuckPermsHandler extends ModernVaultHandler {
|
||||
// If the player doesn't exist in the UserMap, just skip
|
||||
// Ess will cause performance problems for permissions checks if it attempts to
|
||||
// perform i/o to load the user data otherwise.
|
||||
if (!ess.getUserMap().userExists(target.getUniqueId())) {
|
||||
if (!ess.getUsers().getAllUserUUIDs().contains(target.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(target);
|
||||
final User user = ess.getUsers().loadUncachedUser(target.getUniqueId());
|
||||
for (Calculator calculator : this.calculators) {
|
||||
calculator.function.apply(user).forEach(value -> consumer.accept(calculator.id, value));
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.perm.IPermissionsHandler;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
@@ -21,12 +22,27 @@ public class SuperpermsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup(final Player base) {
|
||||
public boolean addToGroup(OfflinePlayer base, String group) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromGroup(OfflinePlayer base, String group) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup(final OfflinePlayer base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups(final Player base) {
|
||||
public List<String> getGroups(final OfflinePlayer base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.Enchantments;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.provider.MaterialTagProvider;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
@@ -66,7 +67,7 @@ public class SignEnchant extends EssentialsSign {
|
||||
|
||||
@Override
|
||||
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, ChargeException {
|
||||
final ItemStack playerHand = player.getBase().getItemInHand();
|
||||
final ItemStack playerHand = Inventories.getItemInHand(player.getBase());
|
||||
final MaterialTagProvider tagProvider = ess.getMaterialTagProvider();
|
||||
final String itemName = sign.getLine(1);
|
||||
final ItemStack search = itemName.equals("*") || itemName.equalsIgnoreCase("any") || (tagProvider != null && tagProvider.tagExists(itemName) && tagProvider.isTagged(itemName, playerHand.getType())) ? null : getItemStack(itemName, 1, ess);
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.Trade.TradeType;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.Inventories;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
@@ -84,10 +85,14 @@ public class SignTrade extends EssentialsSign {
|
||||
|
||||
private Trade rechargeSign(final ISign sign, final IEssentials ess, final User player) throws SignException, ChargeException {
|
||||
final Trade trade = getTrade(sign, 2, AmountType.COST, false, true, ess);
|
||||
if (trade.getItemStack() != null && player.getBase().getItemInHand() != null && trade.getItemStack().getType() == player.getBase().getItemInHand().getType() && MaterialUtil.getDamage(trade.getItemStack()) == MaterialUtil.getDamage(player.getBase().getItemInHand()) && trade.getItemStack().getEnchantments().equals(player.getBase().getItemInHand().getEnchantments())) {
|
||||
ItemStack stack = Inventories.getItemInHand(player.getBase());
|
||||
if (trade.getItemStack() != null && stack != null && !MaterialUtil.isAir(stack.getType()) && trade.getItemStack().getType() == stack.getType() && MaterialUtil.getDamage(trade.getItemStack()) == MaterialUtil.getDamage(stack) && trade.getItemStack().getEnchantments().equals(stack.getEnchantments())) {
|
||||
if (MaterialUtil.isPotion(trade.getItemStack().getType()) && !trade.getItemStack().isSimilar(stack)) {
|
||||
return null;
|
||||
}
|
||||
final int amount = trade.getItemStack().getAmount();
|
||||
if (player.getBase().getInventory().containsAtLeast(trade.getItemStack(), amount)) {
|
||||
final ItemStack stack = player.getBase().getItemInHand().clone();
|
||||
if (Inventories.containsAtLeast(player.getBase(), trade.getItemStack(), amount)) {
|
||||
stack = stack.clone();
|
||||
stack.setAmount(amount);
|
||||
final Trade store = new Trade(stack, ess);
|
||||
addAmount(sign, 2, store, ess);
|
||||
|
||||
@@ -253,7 +253,7 @@ public class KeywordReplacer implements IText {
|
||||
replacer = Integer.toString(ess.getOnlinePlayers().size() - playerHidden);
|
||||
break;
|
||||
case UNIQUE:
|
||||
replacer = NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers());
|
||||
replacer = NumberFormat.getInstance().format(ess.getUsers().getUserCount());
|
||||
break;
|
||||
case WORLDS:
|
||||
final StringBuilder worldsBuilder = new StringBuilder();
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.earth2me.essentials.userstorage;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface IUserMap {
|
||||
/**
|
||||
* Gets all the UUIDs of every User which has joined.
|
||||
* @return the UUIDs of all Users.
|
||||
*/
|
||||
Set<UUID> getAllUserUUIDs();
|
||||
|
||||
/**
|
||||
* Gets the current amount of users loaded into memory.
|
||||
* @return the amount of users loaded into memory.
|
||||
*/
|
||||
long getCachedCount();
|
||||
|
||||
/**
|
||||
* Gets the amount of users stored by Essentials.
|
||||
* @return the amount of users stored by Essentials.
|
||||
*/
|
||||
int getUserCount();
|
||||
|
||||
User getUser(final UUID uuid);
|
||||
|
||||
User getUser(final Player base);
|
||||
|
||||
User getUser(final String name);
|
||||
|
||||
User loadUncachedUser(final Player base);
|
||||
|
||||
/**
|
||||
* Gets a User by the given UUID in the cache, if present, otherwise loads the user without placing them in the cache.
|
||||
* Ideally to be used when running operations on all stored users.
|
||||
*
|
||||
* @param uuid the UUID of the user to get.
|
||||
* @return the User with the given UUID, or null if not found.
|
||||
*/
|
||||
User loadUncachedUser(final UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets the name to UUID cache.
|
||||
* @return the name to UUID cache.
|
||||
*/
|
||||
Map<String, UUID> getNameCache();
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
package com.earth2me.essentials.userstorage;
|
||||
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.io.Files;
|
||||
import net.ess3.api.IEssentials;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ModernUUIDCache {
|
||||
private final IEssentials ess;
|
||||
|
||||
/**
|
||||
* We use a name to uuid map for offline caching due to the following scenario:
|
||||
* * JRoy and mdcfeYT420 play on a server
|
||||
* * mdcfeYT420 changes his name to mdcfe
|
||||
* * mdcfe doesn't log in the server for 31 days
|
||||
* * JRoy changes his name to mdcfeYT420
|
||||
* * mdcfeYT420 (previously JRoy) logs in the server
|
||||
* In a UUID->Name based map, different uuids now point to the same name
|
||||
* preventing any command which allows for offline players from resolving a
|
||||
* given uuid from a given name.
|
||||
* <p>
|
||||
* This map is backed by a file-based cache. If this cache is missing, a new
|
||||
* one is populated by iterating over all files in the userdata folder and
|
||||
* caching the {@code last-account-name} value.
|
||||
*/
|
||||
private final ConcurrentHashMap<String, UUID> nameToUuidMap = new ConcurrentHashMap<>();
|
||||
private final Set<UUID> uuidCache = ConcurrentHashMap.newKeySet();
|
||||
|
||||
private final ScheduledExecutorService writeExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
private final AtomicBoolean pendingNameWrite = new AtomicBoolean(false);
|
||||
private final AtomicBoolean pendingUuidWrite = new AtomicBoolean(false);
|
||||
private final File nameToUuidFile;
|
||||
private final File uuidCacheFile;
|
||||
|
||||
public ModernUUIDCache(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
this.nameToUuidFile = new File(ess.getDataFolder(), "usermap.bin");
|
||||
this.uuidCacheFile = new File(ess.getDataFolder(), "uuids.bin");
|
||||
loadCache();
|
||||
writeExecutor.scheduleWithFixedDelay(() -> {
|
||||
if (pendingNameWrite.compareAndSet(true, false)) {
|
||||
saveNameToUuidCache();
|
||||
}
|
||||
|
||||
if (pendingUuidWrite.compareAndSet(true, false)) {
|
||||
saveUuidCache();
|
||||
}
|
||||
}, 5, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
protected UUID getCachedUUID(final String name) {
|
||||
return nameToUuidMap.get(getSanitizedName(name));
|
||||
}
|
||||
|
||||
protected Set<UUID> getCachedUUIDs() {
|
||||
return Collections.unmodifiableSet(uuidCache);
|
||||
}
|
||||
|
||||
protected Map<String, UUID> getNameCache() {
|
||||
return Collections.unmodifiableMap(nameToUuidMap);
|
||||
}
|
||||
|
||||
protected int getCacheSize() {
|
||||
return uuidCache.size();
|
||||
}
|
||||
|
||||
protected String getSanitizedName(final String name) {
|
||||
return ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name;
|
||||
}
|
||||
|
||||
protected void updateCache(final UUID uuid, final String name) {
|
||||
if (uuidCache.add(uuid)) {
|
||||
pendingUuidWrite.set(true);
|
||||
}
|
||||
if (name != null) {
|
||||
final String sanitizedName = getSanitizedName(name);
|
||||
final UUID replacedUuid = nameToUuidMap.put(sanitizedName, uuid);
|
||||
if (!uuid.equals(replacedUuid)) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.WARNING, "Replaced UUID during cache update for " + sanitizedName + ": " + replacedUuid + " -> " + uuid);
|
||||
}
|
||||
pendingNameWrite.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeCache(final UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (uuidCache.remove(uuid)) {
|
||||
pendingUuidWrite.set(true);
|
||||
}
|
||||
|
||||
final Set<String> toRemove = new HashSet<>();
|
||||
for (final Map.Entry<String, UUID> entry : nameToUuidMap.entrySet()) {
|
||||
if (uuid.equals(entry.getValue())) {
|
||||
toRemove.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for (final String name : toRemove) {
|
||||
nameToUuidMap.remove(name);
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
pendingNameWrite.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCache() {
|
||||
final boolean debug = ess.getSettings().isDebug();
|
||||
|
||||
try {
|
||||
if (!nameToUuidFile.exists()) {
|
||||
if (!nameToUuidFile.createNewFile()) {
|
||||
throw new RuntimeException("Error while creating usermap.bin");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
ess.getLogger().log(Level.INFO, "Loading Name->UUID cache from disk...");
|
||||
}
|
||||
|
||||
nameToUuidMap.clear();
|
||||
|
||||
try (final DataInputStream dis = new DataInputStream(new FileInputStream(nameToUuidFile))) {
|
||||
while (dis.available() > 0) {
|
||||
final String username = dis.readUTF();
|
||||
final UUID uuid = new UUID(dis.readLong(), dis.readLong());
|
||||
final UUID previous = nameToUuidMap.put(username, uuid);
|
||||
if (previous != null && debug) {
|
||||
ess.getLogger().log(Level.WARNING, "Replaced UUID during cache load for " + username + ": " + previous + " -> " + uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while loading Name->UUID cache", e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!uuidCacheFile.exists()) {
|
||||
if (!uuidCacheFile.createNewFile()) {
|
||||
throw new RuntimeException("Error while creating uuids.bin");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
ess.getLogger().log(Level.INFO, "Loading UUID cache from disk...");
|
||||
}
|
||||
|
||||
uuidCache.clear();
|
||||
|
||||
try (final DataInputStream dis = new DataInputStream(new FileInputStream(uuidCacheFile))) {
|
||||
while (dis.available() > 0) {
|
||||
final UUID uuid = new UUID(dis.readLong(), dis.readLong());
|
||||
if (uuidCache.contains(uuid) && debug) {
|
||||
ess.getLogger().log(Level.WARNING, "UUID " + uuid + " duplicated in cache");
|
||||
}
|
||||
uuidCache.add(uuid);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while loading UUID cache", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveUuidCache() {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Saving UUID cache to disk...");
|
||||
}
|
||||
|
||||
try {
|
||||
final File tmpMap = File.createTempFile("uuids", ".tmp.bin", ess.getDataFolder());
|
||||
|
||||
writeUuidCache(tmpMap, uuidCache);
|
||||
//noinspection UnstableApiUsage
|
||||
Files.move(tmpMap, uuidCacheFile);
|
||||
} catch (IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while saving UUID cache", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveNameToUuidCache() {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Saving Name->UUID cache to disk...");
|
||||
}
|
||||
|
||||
try {
|
||||
final File tmpMap = File.createTempFile("usermap", ".tmp.bin", ess.getDataFolder());
|
||||
|
||||
writeNameUuidMap(tmpMap, nameToUuidMap);
|
||||
//noinspection UnstableApiUsage
|
||||
Files.move(tmpMap, nameToUuidFile);
|
||||
} catch (IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while saving Name->UUID cache", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void blockingSave() {
|
||||
saveUuidCache();
|
||||
saveNameToUuidCache();
|
||||
}
|
||||
|
||||
public static void writeUuidCache(final File file, Set<UUID> uuids) throws IOException {
|
||||
try (final DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {
|
||||
for (final UUID uuid: uuids) {
|
||||
dos.writeLong(uuid.getMostSignificantBits());
|
||||
dos.writeLong(uuid.getLeastSignificantBits());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeNameUuidMap(final File file, final Map<String, UUID> nameToUuidMap) throws IOException {
|
||||
try (final DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {
|
||||
for (final Map.Entry<String, UUID> entry : nameToUuidMap.entrySet()) {
|
||||
dos.writeUTF(entry.getKey());
|
||||
final UUID uuid = entry.getValue();
|
||||
dos.writeLong(uuid.getMostSignificantBits());
|
||||
dos.writeLong(uuid.getLeastSignificantBits());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
writeExecutor.shutdownNow();
|
||||
blockingSave();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package com.earth2me.essentials.userstorage;
|
||||
|
||||
import com.earth2me.essentials.OfflinePlayer;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ModernUserMap extends CacheLoader<UUID, User> implements IUserMap {
|
||||
private final transient IEssentials ess;
|
||||
private final transient ModernUUIDCache uuidCache;
|
||||
private final transient LoadingCache<UUID, User> userCache;
|
||||
|
||||
private final boolean debugPrintStackWithWarn;
|
||||
private final long debugMaxWarnsPerType;
|
||||
private final boolean debugLogCache;
|
||||
private final ConcurrentMap<String, AtomicLong> debugNonPlayerWarnCounts;
|
||||
|
||||
public ModernUserMap(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
this.uuidCache = new ModernUUIDCache(ess);
|
||||
this.userCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(ess.getSettings().getMaxUserCacheCount())
|
||||
.expireAfterAccess(ess.getSettings().getMaxUserCacheValueExpiry(), TimeUnit.SECONDS)
|
||||
.softValues()
|
||||
.build(this);
|
||||
|
||||
// -Dnet.essentialsx.usermap.print-stack=true
|
||||
final String printStackProperty = System.getProperty("net.essentialsx.usermap.print-stack", "false");
|
||||
// -Dnet.essentialsx.usermap.max-warns=20
|
||||
final String maxWarnProperty = System.getProperty("net.essentialsx.usermap.max-warns", "100");
|
||||
// -Dnet.essentialsx.usermap.log-cache=true
|
||||
final String logCacheProperty = System.getProperty("net.essentialsx.usermap.log-cache", "false");
|
||||
|
||||
this.debugMaxWarnsPerType = NumberUtil.isLong(maxWarnProperty) ? Long.parseLong(maxWarnProperty) : -1;
|
||||
this.debugPrintStackWithWarn = Boolean.parseBoolean(printStackProperty);
|
||||
this.debugLogCache = Boolean.parseBoolean(logCacheProperty);
|
||||
this.debugNonPlayerWarnCounts = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getAllUserUUIDs() {
|
||||
return uuidCache.getCachedUUIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCachedCount() {
|
||||
return userCache.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUserCount() {
|
||||
return uuidCache.getCacheSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(final UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return userCache.get(uuid);
|
||||
} catch (ExecutionException e) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.WARNING, "Exception while getting user for " + uuid, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(final Player base) {
|
||||
final User user = loadUncachedUser(base);
|
||||
userCache.put(user.getUUID(), user);
|
||||
debugLogCache(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(final String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final User user = getUser(uuidCache.getCachedUUID(name));
|
||||
if (user != null && user.getBase() instanceof OfflinePlayer) {
|
||||
if (user.getLastAccountName() != null) {
|
||||
((OfflinePlayer) user.getBase()).setName(user.getLastAccountName());
|
||||
} else {
|
||||
((OfflinePlayer) user.getBase()).setName(name);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
public void addCachedNpcName(final UUID uuid, final String name) {
|
||||
if (uuid == null || name == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
uuidCache.updateCache(uuid, name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@Override
|
||||
public User load(final UUID uuid) throws Exception {
|
||||
final User user = loadUncachedUser(uuid);
|
||||
if (user != null) {
|
||||
debugLogCache(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
throw new Exception("User not found!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public User loadUncachedUser(final Player base) {
|
||||
if (base == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
User user = getUser(base.getUniqueId());
|
||||
if (user == null) {
|
||||
debugLogUncachedNonPlayer(base);
|
||||
user = new User(base, ess);
|
||||
} else if (!base.equals(user.getBase())) {
|
||||
ess.getLogger().log(Level.INFO, "Essentials updated the underlying Player object for " + user.getUUID());
|
||||
user.update(base);
|
||||
}
|
||||
uuidCache.updateCache(user.getUUID(), user.getName());
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User loadUncachedUser(final UUID uuid) {
|
||||
User user = userCache.getIfPresent(uuid);
|
||||
if (user != null) {
|
||||
return user;
|
||||
}
|
||||
|
||||
Player player = ess.getServer().getPlayer(uuid);
|
||||
if (player != null) {
|
||||
// This is a real player, cache their UUID.
|
||||
user = new User(player, ess);
|
||||
uuidCache.updateCache(uuid, player.getName());
|
||||
return user;
|
||||
}
|
||||
|
||||
final File userFile = getUserFile(uuid);
|
||||
if (userFile.exists()) {
|
||||
player = new OfflinePlayer(uuid, ess.getServer());
|
||||
user = new User(player, ess);
|
||||
((OfflinePlayer) player).setName(user.getLastAccountName());
|
||||
uuidCache.updateCache(uuid, null);
|
||||
return user;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addCachedUser(final User user) {
|
||||
userCache.put(user.getUUID(), user);
|
||||
debugLogCache(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, UUID> getNameCache() {
|
||||
return uuidCache.getNameCache();
|
||||
}
|
||||
|
||||
public String getSanitizedName(final String name) {
|
||||
return uuidCache.getSanitizedName(name);
|
||||
}
|
||||
|
||||
public void blockingSave() {
|
||||
uuidCache.blockingSave();
|
||||
}
|
||||
|
||||
public void invalidate(final UUID uuid) {
|
||||
userCache.invalidate(uuid);
|
||||
uuidCache.removeCache(uuid);
|
||||
}
|
||||
|
||||
private File getUserFile(final UUID uuid) {
|
||||
return new File(new File(ess.getDataFolder(), "userdata"), uuid.toString() + ".yml");
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
uuidCache.shutdown();
|
||||
}
|
||||
|
||||
private void debugLogCache(final User user) {
|
||||
if (!debugLogCache) {
|
||||
return;
|
||||
}
|
||||
final Throwable throwable = new Throwable();
|
||||
ess.getLogger().log(Level.INFO, String.format("Caching user %s (%s)", user.getName(), user.getUUID()), throwable);
|
||||
}
|
||||
|
||||
private void debugLogUncachedNonPlayer(final Player base) {
|
||||
final String typeName = base.getClass().getName();
|
||||
final long count = debugNonPlayerWarnCounts.computeIfAbsent(typeName, name -> new AtomicLong(0)).getAndIncrement();
|
||||
if (debugMaxWarnsPerType < 0 || count <= debugMaxWarnsPerType) {
|
||||
final Throwable throwable = debugPrintStackWithWarn ? new Throwable() : null;
|
||||
ess.getLogger().log(Level.INFO, "Created a User for " + base.getName() + " (" + base.getUniqueId() + ") for non Bukkit type: " + typeName, throwable);
|
||||
if (count == debugMaxWarnsPerType) {
|
||||
ess.getLogger().log(Level.WARNING, "Essentials will not log any more warnings for " + typeName + ". Please report this to the EssentialsX team.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,9 @@ public final class StringUtil {
|
||||
|
||||
//Used to clean strings/names before saving as filenames/permissions
|
||||
public static String safeString(final String string) {
|
||||
if (string == null) {
|
||||
return null;
|
||||
}
|
||||
return STRICTINVALIDCHARS.matcher(string.toLowerCase(Locale.ENGLISH)).replaceAll("_");
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,9 @@ public final class VersionUtil {
|
||||
public static final BukkitVersion v1_18_2_R01 = BukkitVersion.fromString("1.18.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_19_R01 = BukkitVersion.fromString("1.19-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_19_2_R01 = BukkitVersion.fromString("1.19.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_19_4_R01 = BukkitVersion.fromString("1.19.4-R0.1-SNAPSHOT");
|
||||
|
||||
private static final Set<BukkitVersion> supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_2_R01);
|
||||
private static final Set<BukkitVersion> supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_4_R01);
|
||||
|
||||
public static final boolean PRE_FLATTENING = VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01);
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package net.ess3.api.events;
|
||||
|
||||
import net.essentialsx.api.v2.ChatType;
|
||||
import net.essentialsx.api.v2.events.chat.ChatEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.IllegalFormatException;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
@@ -13,103 +12,17 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
/**
|
||||
* Fired when a player uses local chat.
|
||||
*/
|
||||
public class LocalChatSpyEvent extends Event implements Cancellable {
|
||||
public class LocalChatSpyEvent extends ChatEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player player;
|
||||
private final Set<Player> recipients;
|
||||
private boolean cancelled = false;
|
||||
private String message;
|
||||
private String format;
|
||||
|
||||
public LocalChatSpyEvent(final boolean async, final Player who, final String format, final String message, final Set<Player> players) {
|
||||
super(async);
|
||||
this.format = tl("chatTypeLocal").concat(tl("chatTypeSpy")).concat(format);
|
||||
this.message = message;
|
||||
recipients = players;
|
||||
player = who;
|
||||
public LocalChatSpyEvent(final boolean async, final Player player, final String format, final String message, final Set<Player> recipients) {
|
||||
super(async, ChatType.SPY, player, tl("chatTypeLocal").concat(tl("chatTypeSpy")).concat(format), message, recipients);
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message that the player is attempting to send. This message will be used with {@link #getFormat()}.
|
||||
*
|
||||
* @return Message the player is attempting to send
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message that the player will send. This message will be used with {@link #getFormat()}.
|
||||
*
|
||||
* @param message New message that the player will send
|
||||
*/
|
||||
public void setMessage(final String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the format to use to display this chat message to spy recipients. When this event finishes execution, the
|
||||
* first format parameter is the {@link Player#getDisplayName()} and the second parameter is {@link #getMessage()}
|
||||
*
|
||||
* @return {@link String#format(String, Object...)} compatible format string
|
||||
*/
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format to use to display this chat message to spy recipients. When this event finishes execution, the
|
||||
* first format parameter is the {@link Player#getDisplayName()} and the second parameter is {@link #getMessage()}
|
||||
*
|
||||
* @param format {@link String#format(String, Object...)} compatible format string
|
||||
* @throws IllegalFormatException if the underlying API throws the exception
|
||||
* @throws NullPointerException if format is null
|
||||
* @see String#format(String, Object...)
|
||||
*/
|
||||
public void setFormat(final String format) throws IllegalFormatException, NullPointerException {
|
||||
// Oh for a better way to do this!
|
||||
try {
|
||||
String.format(format, player, message);
|
||||
} catch (final RuntimeException ex) {
|
||||
ex.fillInStackTrace();
|
||||
throw ex;
|
||||
}
|
||||
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set of recipients that this chat message will be displayed to.
|
||||
*
|
||||
* @return All Players who will see this chat message
|
||||
*/
|
||||
public Set<Player> getRecipients() {
|
||||
return recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player involved in this event
|
||||
*
|
||||
* @return Player who is involved in this event
|
||||
*/
|
||||
public final Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package net.essentialsx.api.v2;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Represents chat type for a message
|
||||
*/
|
||||
public enum ChatType {
|
||||
/**
|
||||
* Message is being sent to global chat as a shout
|
||||
*/
|
||||
SHOUT,
|
||||
|
||||
/**
|
||||
* Message is being sent to global chat as a question
|
||||
*/
|
||||
QUESTION,
|
||||
|
||||
/**
|
||||
* Message is being sent locally
|
||||
*/
|
||||
LOCAL,
|
||||
|
||||
/**
|
||||
* Message is being sent to spy channel
|
||||
*/
|
||||
SPY,
|
||||
|
||||
/**
|
||||
* Chat type is not determined
|
||||
*
|
||||
* <p>This type used when local/global chat features are disabled
|
||||
*/
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
private final String key;
|
||||
|
||||
ChatType() {
|
||||
this.key = name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Lowercase name of the chat type.
|
||||
*/
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package net.essentialsx.api.v2.events;
|
||||
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a home is about to be modified.
|
||||
*/
|
||||
public class HomeModifyEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final IUser user;
|
||||
private final IUser homeOwner;
|
||||
private final Location newLocation;
|
||||
private final Location oldLocation;
|
||||
private final String newName;
|
||||
private final String oldName;
|
||||
private final HomeModifyCause cause;
|
||||
private boolean canceled = false;
|
||||
|
||||
public HomeModifyEvent(IUser user, IUser homeOwner, String name, Location location, boolean create) {
|
||||
this(user, homeOwner,
|
||||
create ? location : null, // newLocation
|
||||
create ? null : location, // oldLocation
|
||||
create ? name : null, // newName
|
||||
create ? null : name, // oldName
|
||||
create ? HomeModifyCause.CREATE : HomeModifyCause.DELETE);
|
||||
}
|
||||
|
||||
public HomeModifyEvent(IUser user, IUser homeOwner, String oldName, String newName, Location location) {
|
||||
this(user, homeOwner, location, location, newName, oldName, HomeModifyCause.RENAME);
|
||||
}
|
||||
|
||||
public HomeModifyEvent(IUser user, IUser homeOwner, String name, Location oldLocation, Location newLocation) {
|
||||
this(user, homeOwner, newLocation, oldLocation, name, name, HomeModifyCause.UPDATE);
|
||||
}
|
||||
|
||||
public HomeModifyEvent(IUser user, IUser homeOwner, Location newLocation, Location oldLocation, String newName, String oldName, HomeModifyCause cause) {
|
||||
this.user = user;
|
||||
this.homeOwner = homeOwner;
|
||||
this.newLocation = newLocation;
|
||||
this.oldLocation = oldLocation;
|
||||
this.newName = newName;
|
||||
this.oldName = oldName;
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user who modified the home or null if the console modified the home.
|
||||
* @return The user who modified the home or null.
|
||||
*/
|
||||
public IUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owner of the home being modified.
|
||||
* @return The user who owns the home.
|
||||
*/
|
||||
public IUser getHomeOwner() {
|
||||
return homeOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the home when {@link #getCause()} returns {@link HomeModifyCause#CREATE} or {@link HomeModifyCause#RENAME},
|
||||
* returns the updated location of the home if it returns {@link HomeModifyCause#UPDATE}, or returns null if it returns {@link HomeModifyCause#DELETE}.
|
||||
* @return The location of the home or null.
|
||||
*/
|
||||
public Location getNewLocation() {
|
||||
return newLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the home when {@link #getCause()} returns {@link HomeModifyCause#RENAME} or {@link HomeModifyCause#DELETE},
|
||||
* returns the previous location of the home if it returns {@link HomeModifyCause#UPDATE}, or returns null if it returns {@link HomeModifyCause#CREATE}.
|
||||
* @return The location of the home or null.
|
||||
*/
|
||||
public Location getOldLocation() {
|
||||
return oldLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the home when {@link #getCause()} returns {@link HomeModifyCause#CREATE} or {@link HomeModifyCause#UPDATE},
|
||||
* returns the updated name if it returns {@link HomeModifyCause#RENAME}, or returns null if it returns {@link HomeModifyCause#DELETE}.
|
||||
* @return The name of the home or null.
|
||||
*/
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the home when {@link #getCause()} returns {@link HomeModifyCause#UPDATE} or {@link HomeModifyCause#DELETE},
|
||||
* returns the previous name if it returns {@link HomeModifyCause#RENAME}, or returns null if it returns {@link HomeModifyCause#CREATE}.
|
||||
* @return The name of the home or null.
|
||||
*/
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying cause of this modification to a home.
|
||||
* @return The cause.
|
||||
*/
|
||||
public HomeModifyCause getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.canceled = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return canceled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* The cause of why a home was modified.
|
||||
* Used by {@link HomeModifyEvent}.
|
||||
*/
|
||||
public enum HomeModifyCause {
|
||||
CREATE, DELETE, RENAME, UPDATE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.essentialsx.api.v2.events;
|
||||
|
||||
import net.ess3.api.IUser;
|
||||
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when mail is sent to a {@link net.ess3.api.IUser IUser} by another player or the console.
|
||||
* <p>
|
||||
* Note: This event has no guarantee of the thread it is fired on, please use {@link #isAsynchronous()}} to see if this event is off the main Bukkit thread.
|
||||
*/
|
||||
public class UserMailEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final IUser recipient;
|
||||
private final MailMessage message;
|
||||
private boolean canceled;
|
||||
|
||||
public UserMailEvent(IUser recipient, MailMessage message) {
|
||||
super(!Bukkit.isPrimaryThread());
|
||||
this.recipient = recipient;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipient of this mail.
|
||||
* @return the recipient.
|
||||
*/
|
||||
public IUser getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link MailMessage} for this mail.
|
||||
* @return the message.
|
||||
*/
|
||||
public MailMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.canceled = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return canceled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package net.essentialsx.api.v2.events.chat;
|
||||
|
||||
import net.essentialsx.api.v2.ChatType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.IllegalFormatException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This handles common boilerplate for other ChatEvents
|
||||
*/
|
||||
public abstract class ChatEvent extends Event implements Cancellable {
|
||||
private final ChatType chatType;
|
||||
private final Player player;
|
||||
private final Set<Player> recipients;
|
||||
private String message;
|
||||
private String format;
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
public ChatEvent(final boolean async, final ChatType chatType, final Player player,
|
||||
final String format, final String message, final Set<Player> recipients) {
|
||||
super(async);
|
||||
|
||||
this.chatType = chatType;
|
||||
this.player = player;
|
||||
this.format = format;
|
||||
this.message = message;
|
||||
this.recipients = recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message that the player is attempting to send. This message will be used with
|
||||
* {@link #getFormat()}.
|
||||
*
|
||||
* @return Message the player is attempting to send
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message that the player will send. This message will be used with
|
||||
* {@link #getFormat()}.
|
||||
*
|
||||
* @param message New message that the player will send
|
||||
*/
|
||||
public void setMessage(final String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the format to use to display this chat message. When this event finishes execution, the
|
||||
* first format parameter is the {@link Player#getDisplayName()} and the second parameter is
|
||||
* {@link #getMessage()}
|
||||
*
|
||||
* @return {@link String#format(String, Object...)} compatible format string
|
||||
*/
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format to use to display this chat message. When this event finishes execution, the
|
||||
* first format parameter is the {@link Player#getDisplayName()} and the second parameter is
|
||||
* {@link #getMessage()}
|
||||
*
|
||||
* @param format {@link String#format(String, Object...)} compatible format string
|
||||
* @throws IllegalFormatException if the underlying API throws the exception
|
||||
* @throws NullPointerException if format is null
|
||||
* @see String#format(String, Object...)
|
||||
*/
|
||||
public void setFormat(final String format) throws IllegalFormatException, NullPointerException {
|
||||
// Oh for a better way to do this!
|
||||
try {
|
||||
String.format(format, player, message);
|
||||
} catch (final RuntimeException ex) {
|
||||
ex.fillInStackTrace();
|
||||
throw ex;
|
||||
}
|
||||
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set of recipients that this chat message will be displayed to.
|
||||
*
|
||||
* @return All Players who will see this chat message
|
||||
*/
|
||||
public Set<Player> getRecipients() {
|
||||
return recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player involved in this event
|
||||
*
|
||||
* @return Player who is involved in this event
|
||||
*/
|
||||
public final Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of chat this event is fired for
|
||||
*
|
||||
* @return Type of chat this event is fired for
|
||||
*/
|
||||
public ChatType getChatType() {
|
||||
return chatType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.essentialsx.api.v2.events.chat;
|
||||
|
||||
import net.essentialsx.api.v2.ChatType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Fired when a player uses global chat
|
||||
*/
|
||||
public class GlobalChatEvent extends ChatEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public GlobalChatEvent(final boolean async, final ChatType chatType, final Player player, final String format, final String message, final Set<Player> recipients) {
|
||||
super(async, chatType, player, format, message, recipients);
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package net.essentialsx.api.v2.events.chat;
|
||||
|
||||
import net.essentialsx.api.v2.ChatType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Fired when a player uses local chat
|
||||
*/
|
||||
public class LocalChatEvent extends ChatEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final long radius;
|
||||
|
||||
public LocalChatEvent(final boolean async, final Player player, final String format, final String message, final Set<Player> recipients, final long radius) {
|
||||
super(async, ChatType.LOCAL, player, format, message, recipients);
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns local chat radius used to calculate recipients of this message.
|
||||
* <p>
|
||||
* <p>This is not a radius between players: for that use {@link ChatEvent#getRecipients()} and calculate distance
|
||||
* to player who sent the message ({@link ChatEvent#getPlayer()}).
|
||||
* @return Non-squared local chat radius.
|
||||
*/
|
||||
public long getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,10 @@
|
||||
ops-name-color: '4'
|
||||
|
||||
# The character(s) to prefix all nicknames, so that you know they are not true usernames.
|
||||
# Users with essentials.nick.hideprefix will not be prefixed with the character(s)
|
||||
nickname-prefix: '~'
|
||||
|
||||
# The maximum length allowed in nicknames. The nickname prefix is included in this.
|
||||
# The maximum length allowed in nicknames. The nickname prefix is not included in this.
|
||||
max-nick-length: 15
|
||||
|
||||
# A list of phrases that cannot be used in nicknames. You can include regular expressions here.
|
||||
@@ -160,7 +161,7 @@ notify-player-of-mail-cooldown: 60
|
||||
#
|
||||
# If you have two plugin with the same command and you wish to force Essentials to take over, you need an alias.
|
||||
# To force essentials to take 'god' alias 'god' to 'egod'.
|
||||
# See http://wiki.bukkit.org/Commands.yml#aliases for more information.
|
||||
# See https://bukkit.fandom.com/wiki/Commands.yml#aliases for more information.
|
||||
|
||||
overridden-commands:
|
||||
# - god
|
||||
@@ -168,7 +169,7 @@ overridden-commands:
|
||||
|
||||
# Disabling commands here will prevent Essentials handling the command, this will not affect command conflicts.
|
||||
# You should not have to disable commands used in other plugins, they will automatically get priority.
|
||||
# See http://wiki.bukkit.org/Commands.yml#aliases to map commands to other plugins.
|
||||
# See https://bukkit.fandom.com/wiki/Commands.yml#aliases to map commands to other plugins.
|
||||
disabled-commands:
|
||||
# - nick
|
||||
# - clear
|
||||
@@ -283,6 +284,7 @@ player-commands:
|
||||
- protect
|
||||
- r
|
||||
- rules
|
||||
- renamehome
|
||||
- realname
|
||||
- seen
|
||||
- sell
|
||||
|
||||
@@ -100,6 +100,8 @@ bookCommandUsage3=/<command> title <title>
|
||||
bookCommandUsage3Description=Sets the title of a signed book
|
||||
bookLocked=\u00a76This book is now locked.
|
||||
bookTitleSet=\u00a76Title of the book set to {0}.
|
||||
bottomCommandDescription=Teleport to the lowest block at your current position.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Breaks the block you are looking at.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=\u00a76[\u00a74Broadcast\u00a76]\u00a7a {0}
|
||||
@@ -240,6 +242,12 @@ discordbroadcastCommandUsage1Description=Sends the given message to the specifie
|
||||
discordbroadcastInvalidChannel=\u00a74Discord channel \u00a7c{0}\u00a74 does not exist.
|
||||
discordbroadcastPermission=\u00a74You do not have permission to send messages to the \u00a7c{0}\u00a74 channel.
|
||||
discordbroadcastSent=\u00a76Message sent to \u00a7c{0}\u00a76!
|
||||
discordCommandAccountArgumentUser=The Discord account to look up
|
||||
discordCommandAccountDescription=Looks up the linked Minecraft account for either yourself or another Discord user
|
||||
discordCommandAccountResponseLinked=Your account is linked to the Minecraft account: **{0}**
|
||||
discordCommandAccountResponseLinkedOther={0}'s account is linked to the Minecraft account: **{1}**
|
||||
discordCommandAccountResponseNotLinked=You do not have a linked Minecraft account.
|
||||
discordCommandAccountResponseNotLinkedOther={0} does not have a linked Minecraft account.
|
||||
discordCommandDescription=Sends the discord invite link to the player.
|
||||
discordCommandLink=\u00a76Join our Discord server at \u00a7c{0}\u00a76!
|
||||
discordCommandUsage=/<command>
|
||||
@@ -248,6 +256,14 @@ discordCommandUsage1Description=Sends the discord invite link to the player
|
||||
discordCommandExecuteDescription=Executes a console command on the Minecraft server.
|
||||
discordCommandExecuteArgumentCommand=The command to be executed
|
||||
discordCommandExecuteReply=Executing command: "/{0}"
|
||||
discordCommandUnlinkDescription=Unlinks the Minecraft account currently linked to your Discord account
|
||||
discordCommandUnlinkInvalidCode=You do not currently have a Minecraft account linked to Discord!
|
||||
discordCommandUnlinkUnlinked=Your Discord account has been unlinked from all associated Minecraft accounts.
|
||||
discordCommandLinkArgumentCode=The code provided in-game to link your Minecraft account
|
||||
discordCommandLinkDescription=Links your Discord account with your Minecraft account using a code from the in-game /link command
|
||||
discordCommandLinkHasAccount=You already have an account linked! To unlink your current account, type /unlink.
|
||||
discordCommandLinkInvalidCode=Invalid linking code! Make sure you've run /link in-game and copied the code correctly.
|
||||
discordCommandLinkLinked=Successfully linked your account!
|
||||
discordCommandListDescription=Gets a list of online players.
|
||||
discordCommandListArgumentGroup=A specific group to limit your search by
|
||||
discordCommandMessageDescription=Messages a player on the Minecraft server.
|
||||
@@ -265,8 +281,20 @@ discordErrorNoPrimary=You did not define a primary channel or your defined prima
|
||||
discordErrorNoPrimaryPerms=Your bot cannot speak in your primary channel, #{0}. Please make sure your bot has read and write permissions in all channels you wish to use.
|
||||
discordErrorNoToken=No token provided! Please follow the tutorial in the config in order to setup the plugin.
|
||||
discordErrorWebhook=An error occurred while sending messages to your console channel\! This was likely caused by accidentally deleting your console webhook. This can usually by fixed by ensuring your bot has the "Manage Webhooks" permission and running "/ess reload".
|
||||
discordLinkInvalidGroup=Invalid group {0} was provided for role {1}. The following groups are available: {2}
|
||||
discordLinkInvalidRole=An invalid role ID, {0}, was provided for group: {1}. You can see the ID of roles with the /roleinfo command in Discord.
|
||||
discordLinkInvalidRoleInteract=The role, {0} ({1}), cannot be used for group->role synchronization because it above your bot''s upper most role. Either move your bot''s role above "{0}" or move "{0}" below your bot''s role.
|
||||
discordLinkInvalidRoleManaged=The role, {0} ({1}), cannot be used for group->role synchronization because it is managed by another bot or integration.
|
||||
discordLinkLinked=\u00a76To link your Minecraft account to Discord, type \u00a7c{0} \u00a76in the Discord server.
|
||||
discordLinkLinkedAlready=\u00a76You have already linked your Discord account! If you wish to unlink your discord account use \u00a7c/unlink\u00a76.
|
||||
discordLinkLoginKick=\u00a76You must link your Discord account before you can join this server.\n\u00a76To link your Minecraft account to Discord, type\:\n\u00a7c{0}\n\u00a76in this server''s Discord server\:\n\u00a7c{1}
|
||||
discordLinkLoginPrompt=\u00a76You must link your Discord account before you can move, chat on or interact with this server. To link your Minecraft account to Discord, type \u00a7c{0} \u00a76in this server''s Discord server\: \u00a7c{1}
|
||||
discordLinkNoAccount=\u00a76You do not currently have a Discord account linked to your Minecraft account.
|
||||
discordLinkPending=\u00a76You already have a link code. To complete linking your Minecraft account to Discord, type \u00a7c{0} \u00a76in the Discord server.
|
||||
discordLinkUnlinked=\u00a76Unlinked your Minecraft account from all associated discord accounts.
|
||||
discordLoggingIn=Attempting to login to Discord...
|
||||
discordLoggingInDone=Successfully logged in as {0}
|
||||
discordMailLine=**New mail from {0}:** {1}
|
||||
discordNoSendPermission=Cannot send message in channel: #{0} Please ensure the bot has "Send Messages" permission in that channel\!
|
||||
discordReloadInvalid=Tried to reload EssentialsX Discord config while the plugin is in an invalid state! If you've modified your config, restart your server.
|
||||
disposal=Disposal
|
||||
@@ -482,6 +510,7 @@ homeCommandUsage2=/<command> <player>:<name>
|
||||
homeCommandUsage2Description=Teleports you to the specified player's home with the given name
|
||||
homes=\u00a76Homes\:\u00a7r {0}
|
||||
homeConfirmation=\u00a76You already have a home named \u00a7c{0}\u00a76!\nTo overwrite your existing home, type the command again.
|
||||
homeRenamed=\u00a76Home \u00a7c{0} \u00a76has been renamed to \u00a7c{1}\u00a76.
|
||||
homeSet=\u00a76Home set to current location.
|
||||
hour=hour
|
||||
hours=hours
|
||||
@@ -660,6 +689,10 @@ lightningCommandUsage2=/<command> <player> <power>
|
||||
lightningCommandUsage2Description=Strikes lighting at the target player with the given power
|
||||
lightningSmited=\u00a76Thou hast been smitten\!
|
||||
lightningUse=\u00a76Smiting\u00a7c {0}
|
||||
linkCommandDescription=Generates a code to link your Minecraft account to Discord.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
linkCommandUsage1Description=Generates a code for the /link command on Discord
|
||||
listAfkTag=\u00a77[AFK]\u00a7r
|
||||
listAmount=\u00a76There are \u00a7c{0}\u00a76 out of maximum \u00a7c{1}\u00a76 players online.
|
||||
listAmountHidden=\u00a76There are \u00a7c{0}\u00a76/\u00a7c{1}\u00a76 out of maximum \u00a7c{2}\u00a76 players online.
|
||||
@@ -1010,6 +1043,12 @@ removeCommandUsage1Description=Removes all of the given mob type in the current
|
||||
removeCommandUsage2=/<command> <mob type> <radius> [world]
|
||||
removeCommandUsage2Description=Removes the given mob type within the given radius in the current world or another one if specified
|
||||
removed=\u00a76Removed\u00a7c {0} \u00a76entities.
|
||||
renamehomeCommandDescription=Renames a home.
|
||||
renamehomeCommandUsage=/<command> <[player:]name> <new name>
|
||||
renamehomeCommandUsage1=/<command> <name> <new name>
|
||||
renamehomeCommandUsage1Description=Renames your home to the given name
|
||||
renamehomeCommandUsage2=/<command> <player>:<name> <new name>
|
||||
renamehomeCommandUsage2Description=Renames the specified player's home to the given name
|
||||
repair=\u00a76You have successfully repaired your\: \u00a7c{0}\u00a76.
|
||||
repairAlreadyFixed=\u00a74This item does not need repairing.
|
||||
repairCommandDescription=Repairs the durability of one or all items.
|
||||
@@ -1021,7 +1060,7 @@ repairCommandUsage2Description=Repairs all items in your inventory
|
||||
repairEnchanted=\u00a74You are not allowed to repair enchanted items.
|
||||
repairInvalidType=\u00a74This item cannot be repaired.
|
||||
repairNone=\u00a74There were no items that needed repairing.
|
||||
replyFromDiscord=**Reply from {0}\:** `{1}`
|
||||
replyFromDiscord=**Reply from {0}\:** {1}
|
||||
replyLastRecipientDisabled=\u00a76Replying to last message recipient \u00a7cdisabled\u00a76.
|
||||
replyLastRecipientDisabledFor=\u00a76Replying to last message recipient \u00a7cdisabled \u00a76for \u00a7c{0}\u00a76.
|
||||
replyLastRecipientEnabled=\u00a76Replying to last message recipient \u00a7cenabled\u00a76.
|
||||
@@ -1216,6 +1255,7 @@ teleportationDisabledWarning=\u00a76You must enable teleportation before other p
|
||||
teleportationEnabled=\u00a76Teleportation \u00a7cenabled\u00a76.
|
||||
teleportationEnabledFor=\u00a76Teleportation \u00a7cenabled \u00a76for \u00a7c{0}\u00a76.
|
||||
teleportAtoB=\u00a7c{0}\u00a76 teleported you to \u00a7c{1}\u00a76.
|
||||
teleportBottom=\u00a76Teleporting to bottom.
|
||||
teleportDisabled=\u00a7c{0} \u00a74has teleportation disabled.
|
||||
teleportHereRequest=\u00a7c{0}\u00a76 has requested that you teleport to them.
|
||||
teleportHome=\u00a76Teleporting to \u00a7c{0}\u00a76.
|
||||
@@ -1231,6 +1271,7 @@ teleportRequestTimeoutInfo=\u00a76This request will timeout after\u00a7c {0} sec
|
||||
teleportTop=\u00a76Teleporting to top.
|
||||
teleportToPlayer=\u00a76Teleporting to \u00a7c{0}\u00a76.
|
||||
teleportOffline=\u00a76The player \u00a7c{0}\u00a76 is currently offline. You are able to teleport to them using /otp.
|
||||
teleportOfflineUnknown=\u00a76Unable to find the last known position of \u00a7c{0}\u00a76.
|
||||
tempbanExempt=\u00a74You may not tempban that player.
|
||||
tempbanExemptOffline=\u00a74You may not tempban offline players.
|
||||
tempbanJoin=You are banned from this server for {0}. Reason: {1}
|
||||
@@ -1395,6 +1436,10 @@ unlimitedCommandUsage3=/<command> clear [player]
|
||||
unlimitedCommandUsage3Description=Clears all unlimited items for yourself or another player if specified
|
||||
unlimitedItemPermission=\u00a74No permission for unlimited item \u00a7c{0}\u00a74.
|
||||
unlimitedItems=\u00a76Unlimited items\:\u00a7r
|
||||
unlinkCommandDescription=Unlinks your Minecraft account from the currently linked Discord account.
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unlinkCommandUsage1Description=Unlinks your Minecraft account from the currently linked Discord account.
|
||||
unmutedPlayer=\u00a76Player\u00a7c {0} \u00a76unmuted.
|
||||
unsafeTeleportDestination=\u00a74The teleport destination is unsafe and teleport-safety is disabled.
|
||||
unsupportedBrand=\u00a74The server platform you are currently running does not provide the capabilities for this feature.
|
||||
@@ -1415,6 +1460,9 @@ userIsAwaySelf=\u00a77You are now AFK.
|
||||
userIsAwaySelfWithMessage=\u00a77You are now AFK.
|
||||
userIsNotAwaySelf=\u00a77You are no longer AFK.
|
||||
userJailed=\u00a76You have been jailed\!
|
||||
usermapEntry=\u00a7c{0} \u00a76is mapped to \u00a7c{1}\u00a76.
|
||||
usermapPurge=\u00a76Checking for files in userdata that are not mapped, results will be logged to console. Destructive Mode: {0}
|
||||
usermapSize=\u00a76Current cached users in user map is \u00a7c{0}\u00a76/\u00a7c{1}\u00a76/\u00a7c{2}\u00a76.
|
||||
userUnknown=\u00a74Warning\: The user ''\u00a7c{0}\u00a74'' has never joined this server.
|
||||
usingTempFolderForTesting=Using temp folder for testing\:
|
||||
vanish=\u00a76Vanish for {0}\u00a76\: {1}
|
||||
|
||||
@@ -100,6 +100,7 @@ bookCommandUsage3=/<command> title <title>
|
||||
bookCommandUsage3Description=Задава заглавието на подписана книга
|
||||
bookLocked=§6Книгата е заключена.
|
||||
bookTitleSet=§6Заглавието на книгата е зададено на {0}.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Чупи блока към, който гледате.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§r§6[§4Съобщение§6]§a {0}
|
||||
@@ -215,7 +216,7 @@ delkitCommandDescription=Изтрива посочен кит.
|
||||
delkitCommandUsage=/<command> <kit>
|
||||
delkitCommandUsage1=/<command> <kit>
|
||||
delkitCommandUsage1Description=Изтрива кит с дадено име
|
||||
delwarpCommandDescription=Изтрива посочен warp.
|
||||
delwarpCommandDescription=Изтрива посочен уарп.
|
||||
delwarpCommandUsage=/<command> <warp>
|
||||
delwarpCommandUsage1=/<command> <warp>
|
||||
delwarpCommandUsage1Description=Изтрива уарп с дадено име
|
||||
@@ -450,6 +451,7 @@ inventoryClearingStack=e§6Премахнати са§c {0} §6броя§c {1}
|
||||
invseeCommandDescription=Вижте инвентарите на други играчи.
|
||||
invseeCommandUsage=/<command> <player>
|
||||
invseeCommandUsage1=/<command> <player>
|
||||
invseeNoSelf=§cМожете да преглеждате само инвентарите на други играчи.
|
||||
is=e
|
||||
isIpBanned=§6IP адресът §c{0} §6е ограничен.
|
||||
internalError=Възникна грешка докато се опитвахте да изпълните тази команда.
|
||||
@@ -521,6 +523,8 @@ leatherSyntax=§6Синтаксис за оцветяване на кожени
|
||||
lightningCommandUsage1=/<command> [player]
|
||||
lightningSmited=§6Бяхте покосени от мълния\!
|
||||
lightningUse=§6Ударихте§c {0}§6 с мълния.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
listAfkTag=§7[Неактивен]§r
|
||||
listAmount=§6Има §c{0}§6 от максимум §c{1}§6 играчи онлайн.
|
||||
listAmountHidden=§6Има §c{0}§6/§c{1}§6 от максимум §c{2}§6 онлайн играча.
|
||||
@@ -910,6 +914,8 @@ unknownItemInList=§4Неизвестен предмет {0} в списък {1}
|
||||
unknownItemName=§4Неизвестно име на предмет\: {0}.
|
||||
unlimitedItemPermission=§4Нямате право на безброй предмети§c {0}§4.
|
||||
unlimitedItems=§6Безбройни предмети\:§r
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unmutedPlayer=§6Играчът§c {0}§6 е отглушен.
|
||||
unsafeTeleportDestination=§4Дестинацията е опасна и защитата след телепортиране е изключена.
|
||||
unsupportedFeature=Тази функция я няма на тази версия на сървъра.
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
addedToAccount=§a{0} je dodano na vas racun.
|
||||
addedToOthersAccount=dodan §a {0} {1} §a račun. Novo ravnotežu\: {2}
|
||||
adventure=pustolovina
|
||||
afkCommandDescription=Označava da ste trenutno odsutni.
|
||||
afkCommandUsage=/<command> [Igrač/poruka...]
|
||||
afkCommandUsage1Description=Mijenja vaš afk status uz optimalan razlog
|
||||
afkCommandUsage2=/<command> igrač [Igrač/poruka]
|
||||
alertBroke=slomio\:
|
||||
alertFormat=§3[{0}] §r {1} §6 {2} u\: {3}
|
||||
alertPlaced=postavljen\:
|
||||
@@ -15,6 +19,7 @@ antiBuildDrop=§4Nemate pravo da padne§c {0}§4.
|
||||
antiBuildInteract=§4Nemate pravo da za interakciju sa §c {0}§4.
|
||||
antiBuildPlace=§4Nemate pravo da postavi§c {0} §4ovde.
|
||||
antiBuildUse=§4Nemate pravo da koriste§c {0}§4.
|
||||
anvilCommandDescription=Otvara nakovanj.
|
||||
autoAfkKickReason=Izbaceni ste za prazan hod vise od {0} minuta.
|
||||
backupDisabled=§7Jedna vanjska sigurnosna kopija nije konfigurirana.
|
||||
backupFinished=§7Backup je zavrsen.
|
||||
|
||||
@@ -100,6 +100,8 @@ bookCommandUsage3=/<command> title <název>
|
||||
bookCommandUsage3Description=Nastaví název podepsané knihy
|
||||
bookLocked=§6Tato kniha je nyní uzamčena.
|
||||
bookTitleSet=§6Kniha byla nazvána {0}.
|
||||
bottomCommandDescription=Teleportuje na nejnižší blok na tvé aktuální pozici.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Rozbije blok, na který se díváš.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Oznámení§6]§a {0}
|
||||
@@ -240,6 +242,12 @@ discordbroadcastCommandUsage1Description=Odešle zprávu na zadaný kanál na Di
|
||||
discordbroadcastInvalidChannel=§4Discord kanál §c{0}§4 neexistuje.
|
||||
discordbroadcastPermission=§4Nemáš oprávnění posílat zprávy do kanálu §c{0}§4.
|
||||
discordbroadcastSent=§6Zpráva odeslána do kanálu §c{0}§6\!
|
||||
discordCommandAccountArgumentUser=Discord účet pro hledání
|
||||
discordCommandAccountDescription=Vyhledá propojený Minecraft účet buď pro tebe, nebo jiného uživatele Discordu
|
||||
discordCommandAccountResponseLinked=Tvůj účet je propojen s Minecraft účtem\: **{0}**
|
||||
discordCommandAccountResponseLinkedOther=Účet uživatele {0} je propojen s Minecraftovým účtem\: **{1}**
|
||||
discordCommandAccountResponseNotLinked=Nemáš propojený Minecraft účet.
|
||||
discordCommandAccountResponseNotLinkedOther={0} nemá propojený Minecraft účet.
|
||||
discordCommandDescription=Zašle hráči pozvánku na Discord.
|
||||
discordCommandLink=§6Připoj se k našemu Discord serveru na §c{0}§6\!
|
||||
discordCommandUsage=/<command>
|
||||
@@ -248,12 +256,20 @@ discordCommandUsage1Description=Zašle hráči odkaz s pozvánkou na Discord
|
||||
discordCommandExecuteDescription=Provede příkaz konzole na Minecraft serveru.
|
||||
discordCommandExecuteArgumentCommand=Příkaz, který se má provést
|
||||
discordCommandExecuteReply=Provádění příkazu\: „/{0}“
|
||||
discordCommandUnlinkDescription=Odpojí aktuálně propojený Minecraft účet s tvým Discord účtem
|
||||
discordCommandUnlinkInvalidCode=Momentálně nemáš Minecraft účet, který je propojen s Discordem\!
|
||||
discordCommandUnlinkUnlinked=Tvůj Discord účet byl odpojen od všech přidružených Minecraft účtů.
|
||||
discordCommandLinkArgumentCode=Kód uvedený ve hře pro propojení tvého Minecraft účtu
|
||||
discordCommandLinkDescription=Propojí tvůj Discord účet s tvým Minecraft účtem pomocí kódu získaným ve hře příkazem /link
|
||||
discordCommandLinkHasAccount=Už máš připojený účet\! Pro odpojení tvého aktuálního účtu napiš /unlink.
|
||||
discordCommandLinkInvalidCode=Neplatný propojovací kód\! Ujisti se, že jsi použil ve hře /link a správně sis zkopíroval kód.
|
||||
discordCommandLinkLinked=Tvůj účet byl úspěšně propojen\!
|
||||
discordCommandListDescription=Seznam přihlášených uživatelů.
|
||||
discordCommandListArgumentGroup=Hledání omezit na skupinu
|
||||
discordCommandMessageDescription=Zašle zprávu hráči na Minecraft serveru.
|
||||
discordCommandMessageArgumentUsername=Hráč, kterému se má zaslat zpráva
|
||||
discordCommandMessageArgumentMessage=Zpráva, která se má zaslat hráči
|
||||
discordErrorCommand=Bota jste na server přidali nesprávně. Postupujte podle návodu v konfiguraci a přidejte svého bota pomocí https\://essentialsx.net/discord.html\!
|
||||
discordErrorCommand=Na server jsi bota přidal nesprávně. Postupuj podle návodu v konfiguraci a přidej svého bota pomocí https\://essentialsx.net/discord.html
|
||||
discordErrorCommandDisabled=Tento příkaz je vypnut\!
|
||||
discordErrorLogin=Při přihlášení k Discordu došlo k chybě, což způsobilo vypnutí samotného zásuvného modulu\: \n{0}
|
||||
discordErrorLoggerInvalidChannel=Protokolování konzole na Discordu bylo zakázáno kvůli neplatné definici kanálu\! Pokud jej zamýšlíte vypnout, nastavte ID kanálu na „none“; jinak zkontrolujte, zda je správné ID kanálu.
|
||||
@@ -265,8 +281,20 @@ discordErrorNoPrimary=Nedefinovali jste primární kanál nebo definovaný prim
|
||||
discordErrorNoPrimaryPerms=Váš bot nemůže mluvit ve vašem primárním kanálu \#{0}. Ujistěte se, že váš bot má oprávnění ke čtení a zápisu ve všech kanálech, které chcete používat.
|
||||
discordErrorNoToken=Nebyl zadán žádný token\! Chcete-li nastavit zásuvný modul, postupujte podle návodu v konfiguraci.
|
||||
discordErrorWebhook=Došlo k chybě při odesílání zpráv do kanálu konzole\! To bylo pravděpodobně způsobeno omylem smazáným webovým háčkem konzole. To lze obvykle opravit tak, že zajistíte, aby váš bot měl oprávnění „Správa háčků webhook“ a pak proveďte „/ess reload“.
|
||||
discordLinkInvalidGroup=Pro roli {1} byla uvedena neplatná skupina {0}. Jsou dostupné následující skupiny\: {2}
|
||||
discordLinkInvalidRole=Pro skupinu {1} bylo uvedeno neplatné ID role, {0}. Id rolí si můžeš zobrazit pomocí příkazu /roleinfo na Discordu.
|
||||
discordLinkInvalidRoleInteract=Role {0} ({1}) nemůže být použita pro synchronizaci skupina -> role, protože je výše, než je nejvyšší role tvého bota. Buď posuň roli tvého bota nad roli „{0}“, nebo posuň „{0}“ pod roli tvého bota.
|
||||
discordLinkInvalidRoleManaged=Role {0} ({1}) nemůže být použita pro synchronizaci skupina -> role, protože je spravována jiným botem nebo propojením.
|
||||
discordLinkLinked=§6Pro propojení tvého Minecraft účtu s Discordem napiš §c{0} §6na Discord serveru.
|
||||
discordLinkLinkedAlready=§6Už máš svůj Discord účet propojený\! Pokud chceš odpojit svůj Discord účet, použij §c/unlink§6.
|
||||
discordLinkLoginKick=§6Než se budeš moci připojit na tento server, musíš propojit svůj Discord účet.\n§6Pro připojení tvého Minecraft účtu k discordu napiš\:\n§c{0}\n§6na Discord serveru tohoto Minecraft serveru\:\n§c{1}
|
||||
discordLinkLoginPrompt=§6Než se budeš moci pohybovat, psát do chatu, nebo interagovat s tímto serverem, musíš si propojit svůj Discord účet. Pro propojení tvého Minecraft účtu s Discordem napiš §c{0} §6na Discord serveru tohoto Minecraft serveru\: §c{1}
|
||||
discordLinkNoAccount=§6Momentálně nemáš s tímto Minecraft účtem propojený Discord účet.
|
||||
discordLinkPending=§6Už máš propojovací kód. Pro dokončení propojení tvého Minecraft účtu s Discordem napiš §c{0} §6na Discord serveru.
|
||||
discordLinkUnlinked=§6Tvůj Minecraft účet byl odpojen ze všech spojených Discord účtů.
|
||||
discordLoggingIn=Pokouším se přihlásit do Discordu...
|
||||
discordLoggingInDone=Uspěšně přihlášen jako {0}
|
||||
discordMailLine=**Nový mail od {0}\:** {1}
|
||||
discordNoSendPermission=Nelze odeslat zprávu v kanálu\: \#{0}. Ujistěte se, že bot má v tomto kanálu oprávnění „Odesílat zprávy“.
|
||||
discordReloadInvalid=Opětovné načtení konfigurace EssentialsX Discord není možné, když je plugin v neplatném stavu\! Změnila-li se konfigurace, je třeba server restartovat.
|
||||
disposal=Odpadkový koš
|
||||
@@ -326,7 +354,7 @@ essentialsCommandUsage3Description=Informuje, které příkazy Essentials před
|
||||
essentialsCommandUsage4=/<command> debug
|
||||
essentialsCommandUsage4Description=Přepíná Essentials do režimu ladění
|
||||
essentialsCommandUsage5=/<command> reset <hráč>
|
||||
essentialsCommandUsage5Description=Resetuje hráčská data daného hráče
|
||||
essentialsCommandUsage5Description=Resetuje uživatelská data daného hráče
|
||||
essentialsCommandUsage6=/<command> cleanup
|
||||
essentialsCommandUsage6Description=Vyčistí stará uživatelská data
|
||||
essentialsCommandUsage7=/<command> homes
|
||||
@@ -482,6 +510,7 @@ homeCommandUsage2=/<command> <hráč>\:<název>
|
||||
homeCommandUsage2Description=Teleportuje tě do domova zadaného hráče se zadaným jménem
|
||||
homes=§6Domovy\:§r {0}
|
||||
homeConfirmation=§6Již máš domov s názvem §c{0}§6\!\nChceš-li přepsat svůj existující domov, napiš příkaz znovu.
|
||||
homeRenamed=§6Domov §c{0} §6byl přejmenován na §c{1}§6.
|
||||
homeSet=§6Domov nastaven na tomto místě.
|
||||
hour=hodina
|
||||
hours=hodin
|
||||
@@ -534,6 +563,7 @@ invseeCommandDescription=Zobrazí inventář jiných hráčů.
|
||||
invseeCommandUsage=/<command> <hráč>
|
||||
invseeCommandUsage1=/<command> <hráč>
|
||||
invseeCommandUsage1Description=Otevře inventář zadaného hráče
|
||||
invseeNoSelf=§cMůžeš vidět pouze inventář ostatních hráčů.
|
||||
is=je
|
||||
isIpBanned=§6IP adresa §c{0} §6je zablokovaná.
|
||||
internalError=§cPři pokusu o provedení tohoto příkazu došlo k vnitřní chybě.
|
||||
@@ -584,7 +614,7 @@ itemType=§6Předmět\:§c {0}
|
||||
itemdbCommandDescription=Vyhledá předmět.
|
||||
itemdbCommandUsage=/<command> <předmět>
|
||||
itemdbCommandUsage1=/<command> <předmět>
|
||||
itemdbCommandUsage1Description=Hledá daný předmět v databázi předmětů
|
||||
itemdbCommandUsage1Description=Vyhledá daný předmět v databázi předmětů
|
||||
jailAlreadyIncarcerated=§4Tento hráč již úpí ve vězení\:§c {0}
|
||||
jailList=§6Vězení\:§r {0}
|
||||
jailMessage=§4Provinil ses, tak teď musíš pykat.
|
||||
@@ -659,6 +689,10 @@ lightningCommandUsage2=/<command> <hráč> <síla>
|
||||
lightningCommandUsage2Description=Vrhne blesk po cílovém hráči se zadanou silou
|
||||
lightningSmited=§6Zasáhl tě blesk\!
|
||||
lightningUse=§6Hráč§c {0} §6byl zasažen bleskem
|
||||
linkCommandDescription=Vygeneruje kód pro propojení tvého Minecraft s Discord účty.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
linkCommandUsage1Description=Vygeneruje kód pro příkaz /link na Discordu
|
||||
listAfkTag=§7[AFK]§r
|
||||
listAmount=§6Je připojeno §c{0}§6 z maximálního počtu §c{1}§6 hráčů.
|
||||
listAmountHidden=§6Je připojeno §c{0}§6/§c{1}§6 z maximálního počtu §c{2}§6 hráčů.
|
||||
@@ -1008,6 +1042,12 @@ removeCommandUsage1Description=Odstraní všechny dané moby ze současného sv
|
||||
removeCommandUsage2=/<příkaz> <mob> <poloměr> [svět]
|
||||
removeCommandUsage2Description=Odstraní všechny dané moby v daném poloměru ze současného světa, nebo z jiného, pokud je specifikován
|
||||
removed=§6Odstraněno§c {0} §6entit.
|
||||
renamehomeCommandDescription=Přejmenuje domov.
|
||||
renamehomeCommandUsage=/<command> <[hráč\:]název> <nový název>
|
||||
renamehomeCommandUsage1=/<command> <název> <nový název>
|
||||
renamehomeCommandUsage1Description=Přejmenuje tvůj domov na zadaný název
|
||||
renamehomeCommandUsage2=/<command> <hráč>\:<název> <nový název>
|
||||
renamehomeCommandUsage2Description=Přejmenuje domov daného hráče na zadaný název
|
||||
repair=§6Úspěšně jsi opravil §c{0}§6.
|
||||
repairAlreadyFixed=§4Tento předmět nepotřebuje opravu.
|
||||
repairCommandDescription=Opraví životnost jednoho nebo všech předmětů.
|
||||
@@ -1019,7 +1059,7 @@ repairCommandUsage2Description=Opraví všechny předměty v inventáři
|
||||
repairEnchanted=§4Nemáš oprávnění opravovat očarované předměty.
|
||||
repairInvalidType=§4Tento předmět nelze opravit.
|
||||
repairNone=§4Nemáš žádné předměty, které potřebují opravit.
|
||||
replyFromDiscord=**{0} odpovídá\:** `{1}`
|
||||
replyFromDiscord=**Odpověď od {0}\:** {1}
|
||||
replyLastRecipientDisabled=§6Odpovídání poslednímu příjemci §cvypnuto§6.
|
||||
replyLastRecipientDisabledFor=§6Odpovídání poslednímu příjemci §cvypnuto §6pro hráče §c{0}§6.
|
||||
replyLastRecipientEnabled=§6Odpovídání poslednímu příjemci §czapnuto§6.
|
||||
@@ -1214,6 +1254,7 @@ teleportationDisabledWarning=§6Aby se mohli ostatní hráči k tobě teleportov
|
||||
teleportationEnabled=§6Teleportování §apovoleno§6.
|
||||
teleportationEnabledFor=§6Teleportování §apovoleno§6 pro hráče §c{0}§6.
|
||||
teleportAtoB=§6Hráč §c{0} §6tě teleportoval na pozici §c{1}§6.
|
||||
teleportBottom=§6Teleportuješ se na dno.
|
||||
teleportDisabled=Hráč §c{0} §4má teleportování vypnuto.
|
||||
teleportHereRequest=§6Hráč §c{0}§6 tě žádá, aby ses k němu teleportoval.
|
||||
teleportHome=§6Teleportuješ se na §c{0}§6.
|
||||
@@ -1229,6 +1270,7 @@ teleportRequestTimeoutInfo=§6Tato žádost vyprší za §c{0} sekund§6.
|
||||
teleportTop=§6Teleportuješ se na povrch.
|
||||
teleportToPlayer=§6Teleportuješ se k hráči §c{0}§6.
|
||||
teleportOffline=§6Hráč §c{0}§6 je momentálně offline. Můžeš se k němu teleportovat pomocí /otp.
|
||||
teleportOfflineUnknown=§6Nelze najít poslední známou polohu §c{0}§6.
|
||||
tempbanExempt=§4Tohoto hráče nemůžeš dočasně zablokovat.
|
||||
tempbanExemptOffline=§4Nemůžeš dočasně zablokovat nepřipojeného hráče.
|
||||
tempbanJoin=Na tomto serveru jsi zablokován na {0}. Důvod\: {1}
|
||||
@@ -1245,14 +1287,14 @@ thunder=§6Nastavil jsi bouřku v tomto světě na §c{0}§6.
|
||||
thunderCommandDescription=Zapne/vypne bouřku.
|
||||
thunderCommandUsage=/<command> <true/false> [trvání]
|
||||
thunderCommandUsage1=/<command> <true|false> [trvání]
|
||||
thunderCommandUsage1Description=Zapne/vypne bouřku na nepovinnou dobu
|
||||
thunderCommandUsage1Description=Povolí/zakáže bouře na volitelnou dobu
|
||||
thunderDuration=§6Nastavil jsi bouřku v tomto světě na §c{0}§6 na §c{1}§6 sekund.
|
||||
timeBeforeHeal=§4Čas do dalšího uzdravení\:§c {0}§4.
|
||||
timeBeforeTeleport=§4Čas do dalšího teleportování\:§c {0}§4.
|
||||
timeCommandDescription=Zobrazí/změní čas světa. Bez specifikace platí pro aktuální svět.
|
||||
timeCommandUsage=/<command> [set|add] [day|night|dawn|17\:30|4pm|4000ticks] [svět|all]
|
||||
timeCommandUsage1=/<command>
|
||||
timeCommandUsage1Description=Ukáže čas ve všech světech
|
||||
timeCommandUsage1Description=Zobrazí časy ve všech světech
|
||||
timeCommandUsage2=/<command> set <čas> [world|all]
|
||||
timeCommandUsage2Description=Nastaví čas v současném (nebo určitém) světě na daný čas
|
||||
timeCommandUsage3=/<command> add <čas> [world|all]
|
||||
@@ -1393,6 +1435,10 @@ unlimitedCommandUsage3=/<command> clear [hráč]
|
||||
unlimitedCommandUsage3Description=Vymaže všechny neomezené předměty pro tebe, nebo jiného hráče, pokud je uveden
|
||||
unlimitedItemPermission=§4Nemáš oprávnění na neomezené množství předmětu §c{0}§4.
|
||||
unlimitedItems=§6Neomezené předměty\:§r
|
||||
unlinkCommandDescription=Odpojí aktuálně propojený Minecraft účet s tvým Discord účtem.
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unlinkCommandUsage1Description=Odpojí aktuálně propojený Minecraft účet s tvým Discord účtem.
|
||||
unmutedPlayer=§6Hráč §c{0}§6 může znovu hovořit.
|
||||
unsafeTeleportDestination=§4Cíl teleportace je nebezpečný a teleport-safety je vypnuto.
|
||||
unsupportedBrand=§4Platforma, na které běží tvůj server, momentálně tuto funkci nepodporuje.
|
||||
@@ -1413,6 +1459,9 @@ userIsAwaySelf=§7Nyní jsi mimo počítač.
|
||||
userIsAwaySelfWithMessage=§7Nyní jsi mimo počítač.
|
||||
userIsNotAwaySelf=§7Už jsi zase u počítače.
|
||||
userJailed=§6Byl jsi uvězněn\!
|
||||
usermapEntry=§c{0} §6je namapováno jako §c{1}§6.
|
||||
usermapPurge=§6Kontrola souborů v uživatelských datech (userdata), které nejsou namapovány, výsledky se zaznamenají na konzoli. Destruktivní mód\: {0}
|
||||
usermapSize=§6Aktuální počet uživatelů v mezipaměti uživatelské mapy je §c{0}§6/§c{1}§6/§c{2}§6.
|
||||
userUnknown=§4Upozornění\: Hráč „§c{0}§4“ se k tomuto serveru ještě nikdy nepřipojil.
|
||||
usingTempFolderForTesting=Používá se dočasná složka na testování\:
|
||||
vanish=§6Neviditelnost pro hráče §c{0}§6\: {1}
|
||||
|
||||
@@ -6,6 +6,12 @@ action=§5* {0} §5{1}
|
||||
addedToAccount=§a{0} er blevet tilføjet til din konto.
|
||||
addedToOthersAccount=§a{0} tilføjet til {1}§a konto. Ny saldo\: {2}
|
||||
adventure=eventyr
|
||||
afkCommandDescription=Markerer dig som værende inaktiv.
|
||||
afkCommandUsage=/<command> [spiller/besked...]
|
||||
afkCommandUsage1=/<command> [message]
|
||||
afkCommandUsage1Description=Ændrer din aktivitets status med en eventuel oversag
|
||||
afkCommandUsage2=/<command> <player> [message]
|
||||
afkCommandUsage2Description=Ændrer aktivitets statussen for en specifik spiller med en eventuel oversag
|
||||
alertBroke=ødelagde\:
|
||||
alertFormat=§3[{0}] §r {1} §6 {2} ved\: {3}
|
||||
alertPlaced=placerede\:
|
||||
@@ -18,7 +24,9 @@ antiBuildInteract=§4Du har ikke tilladelse til at interagere med§c {0}§4.
|
||||
antiBuildPlace=§4Du har ikke tilladelse til at sætte§c {0} §4her.
|
||||
antiBuildUse=§4Du har ikke tilladelse til at bruge§c {0}§4.
|
||||
antiochCommandDescription=En lille overraskelse for operatørerne.
|
||||
antiochCommandUsage=/<command> [message]
|
||||
anvilCommandDescription=Åbner en ambolt.
|
||||
anvilCommandUsage=/<command>
|
||||
autoAfkKickReason=Du er blevet smidt ud, fordi du har været inaktiv i mere end {0} minutter.
|
||||
autoTeleportDisabled=§6Du accepterer ikke længere automatisk teleport anmodninger.
|
||||
autoTeleportDisabledFor=§c{0}§6 godkender ikke længere automatisk teleport anmodninger.
|
||||
@@ -26,8 +34,13 @@ autoTeleportEnabled=§6Du godkender nu automatisk teleport anmodninger.
|
||||
autoTeleportEnabledFor=§C{0}§6 godkender nu automatisk teleport anmodninger.
|
||||
backAfterDeath=§6Brug§c /back§6 kommandoen for at vende tilbage til der hvor du døde.
|
||||
backCommandDescription=Teleporterer dig til din placering før tp/spawn/warp.
|
||||
backCommandUsage=/<command> [player]
|
||||
backCommandUsage1=/<command>
|
||||
backCommandUsage1Description=Teleportere dig til din forhenværende lokation
|
||||
backCommandUsage2Description=Teleportere den specificerede spiller til deres forhenværende lokation
|
||||
backOther=§6Tilbagevendt§c {0}§6 til tidligere lokation.
|
||||
backupCommandDescription=Kører sikkerhedskopi hvis konfigureret.
|
||||
backupCommandUsage=/<command>
|
||||
backupDisabled=§4Et eksternt backup-script er ikke konfigureret.
|
||||
backupFinished=§6Backup afsluttet.
|
||||
backupStarted=§6Backup startet.
|
||||
@@ -35,36 +48,54 @@ backupInProgress=§6Et eksternt backup-script er i gang\! Stop plugin deaktivere
|
||||
backUsageMsg=§6Retunerer til tidligere lokation.
|
||||
balance=§aSaldo\:§c {0}
|
||||
balanceCommandDescription=Angiver den aktuelle balance for en spiller.
|
||||
balanceCommandUsage=/<command> [player]
|
||||
balanceCommandUsage1=/<command>
|
||||
balanceCommandUsage1Description=Viser din nuværende saldo
|
||||
balanceCommandUsage2Description=Viser den specificerede spillers saldo
|
||||
balanceOther=§aSaldo for {0}§a\:§c {1}
|
||||
balanceTop=§6Top saldi ({0})
|
||||
balanceTopLine={0}. {1}, {2}
|
||||
balancetopCommandDescription=Henter listen over top balanceværdier.
|
||||
balancetopCommandUsage=/<command> [page]
|
||||
balancetopCommandUsage1=/<command> [page]
|
||||
balancetopCommandUsage1Description=Viser den første (eller specificerede) side af de øverste saldoværdier
|
||||
banCommandDescription=Udelukker en spiller.
|
||||
banCommandUsage1Description=Udelukker den angivne spiller med en valgfri årsag
|
||||
banExempt=§4Du kan ikke bandlyse den spiller.
|
||||
banExemptOffline=§4Du kan ikke bandlyse offline spillere.
|
||||
banFormat=§4Bandlyst\:\n§r{0}
|
||||
banIpJoin=Your IP address is banned from this server. Reason\: {0}
|
||||
banJoin=You are banned from this server. Reason\: {0}
|
||||
banipCommandDescription=Udelukker en IP adresse.
|
||||
banipCommandUsage1Description=Udelukker den angivne IP adresse med en valgfri begrundelse
|
||||
bed=§obed§r
|
||||
bedMissing=§4Din seng er enten ikke sat, mangler eller også er den blokeret.
|
||||
bedNull=§mbed§r
|
||||
bedOffline=§4Kan ikke teleportere til offline spillere.
|
||||
bedSet=§6Seng-spawn er sat\!
|
||||
beezookaCommandDescription=Kast en eksploderende bi på din modstander.
|
||||
beezookaCommandUsage=/<command>
|
||||
bigTreeFailure=§4Fejl under generering af stort træ. Prøv igen på græs eller jord.
|
||||
bigTreeSuccess=§6Stort træ spawnet.
|
||||
bigtreeCommandDescription=Spawn et stort træ, hvor du kigger.
|
||||
bigtreeCommandUsage1Description=Spawner et stort træ af den angivne type
|
||||
blockList=§6EssentialsX giver følgende kommandoer videre til andre plugins\:
|
||||
blockListEmpty=§6EssentialsX giver ingen kommandoer videre til andre plugins.
|
||||
bookAuthorSet=§6Bogens forfatter er ændret til {0}.
|
||||
bookCommandDescription=Tillader genåbning og redigering af forseglede bøger.
|
||||
bookCommandUsage1=/<command>
|
||||
bookLocked=§6Denne bog er nu låst.
|
||||
bookTitleSet=§6Bogens titel er ændret til {0}.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Ødelægger den block du kigger på.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Meddelelse§6]§a {0}
|
||||
broadcastCommandDescription=Send en besked til hele serveren.
|
||||
broadcastCommandUsage1Description=Sender den givne besked til hele serveren
|
||||
broadcastworldCommandDescription=Sender en besked til verdenen.
|
||||
broadcastworldCommandUsage1Description=Sender den givne besked til den specifikke verden
|
||||
burnCommandDescription=Sæt en spiller i ild.
|
||||
burnCommandUsage1Description=Sætter ild den angivne spiller i det angivne antal sekunder
|
||||
burnMsg=§6Du satte ild til§c {0} §6 i §c {1} sekunder§6.
|
||||
cannotSellNamedItem=§6Det ikke tilladt at sælge de her navngivet genstande.
|
||||
cannotSellTheseNamedItems=§6Det er ikke tilladt at sælge de her navngivet genstande\: §4{0}
|
||||
@@ -75,12 +106,22 @@ cantGamemode=§4You do not have permission to change to gamemode {0}
|
||||
cantReadGeoIpDB=Fejl ved læsning af GeoIP databasen\!
|
||||
cantSpawnItem=§4Du har ikke tilladelse til at spawne denne ting§c {0}§4.
|
||||
cartographytableCommandDescription=Åbner en kartografisk tabel.
|
||||
cartographytableCommandUsage=/<command>
|
||||
chatTypeSpy=[Spion]
|
||||
cleaned=Brugerfiler blev renset.
|
||||
cleaning=Renser brugerfiler.
|
||||
clearInventoryConfirmToggleOff=§6You will no longer be prompted to confirm inventory clears.
|
||||
clearInventoryConfirmToggleOn=§6You will now be prompted to confirm inventory clears.
|
||||
clearinventoryCommandDescription=Ryd alle tingene i din inventar.
|
||||
clearinventoryCommandUsage1=/<command>
|
||||
clearinventoryCommandUsage1Description=Rydder alle tingene i dit inventar
|
||||
clearinventoryCommandUsage2Description=Rydder alle tingene i den specifikke spillers inventar
|
||||
clearinventoryCommandUsage3Description=Rydder alle (eller det angivne antal) af den givne ting fra den angivne spillers inventar
|
||||
clearinventoryconfirmtoggleCommandDescription=Skifter om du bliver vist en besked hvor du skal, godkende ryd inventar.
|
||||
clearinventoryconfirmtoggleCommandUsage=/<command>
|
||||
commandArgumentOptional=§7
|
||||
commandArgumentOr=§c
|
||||
commandArgumentRequired=§e
|
||||
commandCooldown=§cYou cannot type that command for {0}.
|
||||
commandDisabled=§cKommandoen§6 {0}§c er slået fra.
|
||||
commandFailed=Kommando {0} fejlede\:
|
||||
@@ -88,7 +129,9 @@ commandHelpFailedForPlugin=Fejl ved hentning af hjælp til pluginnet\: {0}
|
||||
commandNotLoaded=§4Kommandoen {0} er indlæst forkert.
|
||||
compassBearing=§6Pejling\: {0} ({1} degrees).
|
||||
compassCommandDescription=Beskriver din nuværende retning.
|
||||
compassCommandUsage=/<command>
|
||||
condenseCommandDescription=Kondenserer genstande i en mere kompakt block.
|
||||
condenseCommandUsage1=/<command>
|
||||
configFileMoveError=Kunne ikke flytte config.yml til backup-lokation.
|
||||
configFileRenameError=Kunne ikke omdøbe midlertidig fil til config.yml.
|
||||
confirmClear=§7To §lCONFIRM§7 inventory clear, please repeat command\: §6{0}
|
||||
@@ -113,6 +156,7 @@ customtextCommandDescription=Tillader dig at oprette brugerdefinerede tekstkomma
|
||||
day=dag
|
||||
days=dage
|
||||
defaultBanReason=Banhammeren har talt\!
|
||||
deletedHomes=Alle hjem er slettet.
|
||||
deleteFileError=Kunne ikke slette filen\: {0}
|
||||
deleteHome=§6Hjemmet§c {0} §6er blevet fjernet.
|
||||
deleteJail=§6Fængslet§c {0} §6er blevet fjernet.
|
||||
@@ -132,7 +176,10 @@ destinationNotSet=Destination er ikke sat\!
|
||||
disabled=deaktiveret
|
||||
disabledToSpawnMob=§4Spawning af dette mob er deaktiveret i konfigurationsfilen.
|
||||
disableUnlimited=§6Deaktiverede ubegrænset placering af§c {0} §6i§c {1}§6.
|
||||
discordCommandUsage=/<command>
|
||||
discordCommandUsage1=/<command>
|
||||
disposal=Bortskaffelse
|
||||
disposalCommandUsage=/<command>
|
||||
distance=§6Afstand\: {0}
|
||||
dontMoveMessage=§6Teleportering vil begynde om§c {0}§6. Bliv stående.
|
||||
downloadingGeoIp=Downloader GeoIP database... dette tager måske noget tid (land\: 1.7 MB, by\: 30MB)
|
||||
@@ -147,13 +194,18 @@ enchantmentNotFound=§4Fortryllelsen blev ikke fundet\!
|
||||
enchantmentPerm=§4Du har ikke tilladelse til§c {0}§4.
|
||||
enchantmentRemoved=§6Fortryllelsen§c {0} §6er blevet fjernet fra elementet i din hånd.
|
||||
enchantments=§6Fortryllelser\:§r {0}
|
||||
enderchestCommandUsage=/<command> [player]
|
||||
enderchestCommandUsage1=/<command>
|
||||
errorCallingCommand=Kunne ikke finde kommandoen /{0}
|
||||
errorWithMessage=§cFejl\:§4 {0}
|
||||
essentialsCommandUsage=/<command>
|
||||
essentialsHelp1=Filen er ødelagt, og Essentials kan ikke åbne den. Essentials er nu deaktiveret. Hvis du ikke selv kan fikse fejlen, så besøg http\://tiny.cc/EssentialsChat
|
||||
essentialsHelp2=Filen er ødelagt, og Essentials kan ikke åbne den. Essentials er nu deaktiveret. Hvis du ikke selv kan fikse fejlen, så skriv enten /essentialshelp i spillet eller besøg http\://tiny.cc/EssentialsChat
|
||||
essentialsReload=§6Essentials blev genindlæst§c {0}.
|
||||
exp=§c{0} §6har§c {1} §6exp (level§c {2}§6) og behøver§c {3} §6mere exp for at stige i level.
|
||||
expSet=§c{0} §6har nu§c {1} §6exp.
|
||||
extCommandUsage=/<command> [player]
|
||||
extCommandUsage1=/<command> [player]
|
||||
extinguish=§6Du slukkede selv.
|
||||
extinguishOthers=§6Du slukkede {0}§6.
|
||||
failedToCloseConfig=Kunne ikke lukke konfig {0}.
|
||||
@@ -161,40 +213,52 @@ failedToCreateConfig=Kunne ikke oprette konfig {0}.
|
||||
failedToWriteConfig=Kunne ikke skrive konfig {0}.
|
||||
false=§4falsk§r
|
||||
feed=§6Din appetit blev mættet.
|
||||
feedCommandUsage=/<command> [player]
|
||||
feedCommandUsage1=/<command> [player]
|
||||
feedOther=§6Du tilfredsstillede §c{0}s appetit§6.
|
||||
fileRenameError=Omdøbning af filen {0} fejlede\!
|
||||
fireballCommandUsage1=/<command>
|
||||
fireworkColor=§4Ugyldig fyrværkeriladningsparametre indsat. Der skal sættes en farve først.
|
||||
fireworkEffectsCleared=§6Fjernede alle effekter fra den holdte stak.
|
||||
fireworkSyntax=§6Fyrværkeri-parametre\:§c color\:<farve> [fade\:<farve>] [shape\:<form>] [effect\:<effekt>]\n§6For at bruge flere farver/effekter, separate da værdierne med kommaer\: §cred,blue,pink\n§6Former\:§c star, ball, large, creeper, burst §6Effekter\:§c trail, twinkle.
|
||||
flyCommandUsage1=/<command> [player]
|
||||
flying=flyve
|
||||
flyMode=§6Set flytilstand §c {0} §6for {1}§6.
|
||||
foreverAlone=§4Der er ingen, du kan sende et svar til.
|
||||
fullStack=§4Du har allerede en fuld stak.
|
||||
gameMode=§6Ændrede spiltilstand til§c {0} §6for §c{1}§6.
|
||||
gameModeInvalid=§4Du skal angive en gyldig spiller/tilstand.
|
||||
gcCommandUsage=/<command>
|
||||
gcfree=§6Fri hukommelse\:§c {0} MB.
|
||||
gcmax=§6Maksimum hukommelse\:§c {0} MB.
|
||||
gctotal=§6Allokeret hukommelse\:§c {0} MB.
|
||||
gcWorld=§6{0} "§c{1}§6"\: §c{2}§6 chunks, §c{3}§6 enheder, §c{4}§6 tiles.
|
||||
geoipJoinFormat=§6Spilleren §c{0} §6kommer fra §c{1}§6.
|
||||
getposCommandUsage=/<command> [player]
|
||||
getposCommandUsage1=/<command> [player]
|
||||
geoipCantFind=§6Spiller §c{0} §6kommer fra §aet ukendt land§6.
|
||||
geoIpUrlEmpty=GeoIP download url er tom.
|
||||
geoIpUrlInvalid=GeoIP download url er ugyldig.
|
||||
givenSkull=§6Du er blevet givet §c{0}§6s kranie.
|
||||
godCommandUsage1=/<command> [player]
|
||||
giveSpawn=§6Giver§c {0} §6af§c {1} §6til§c {2}§6.
|
||||
giveSpawnFailure=§4Ikke nok plads, §c{0} {1} §4blev tabt.
|
||||
godDisabledFor=§cdeaktiveret§6 for§c {0}
|
||||
godEnabledFor=§aaktiveret§6 for§c {0}
|
||||
godMode=§6Gudetilstand§c {0}§6.
|
||||
grindstoneCommandUsage=/<command>
|
||||
groupDoesNotExist=§4Der er ingen online i denne gruppe\!
|
||||
groupNumber=§c{0}§f online, for at se komplet liste\:§c /{1} {2}
|
||||
hatArmor=§4Du kan ikke bruge dette element som hat\!
|
||||
hatCommandUsage1=/<command>
|
||||
hatEmpty=§4Du bærer ikke en hat.
|
||||
hatFail=§4Du skal have noget at bære i din hånd.
|
||||
hatPlaced=§6Nyd din nye hat\!
|
||||
hatRemoved=§6Din hat er blevet fjernet.
|
||||
haveBeenReleased=§6Du er blevet frigjort.
|
||||
heal=§6Du er blevet helbredt.
|
||||
healCommandUsage=/<command> [player]
|
||||
healCommandUsage1=/<command> [player]
|
||||
healDead=§4Du kan ikke helbrede nogen, som er død\!
|
||||
healOther=§6Helbredt§c {0}§6.
|
||||
helpConsole=For at se hjælp fra konsollen, skriv ''?''.
|
||||
@@ -211,6 +275,8 @@ homes=§6Dine hjem\:§r {0}
|
||||
homeSet=§6Dit hjem blev sat.
|
||||
hour=time
|
||||
hours=timer
|
||||
iceCommandUsage=/<command> [player]
|
||||
iceCommandUsage1=/<command>
|
||||
ignoredList=§6Ignorerede\:§r {0}
|
||||
ignoreExempt=§4Du kan ikke ignorere den spiller.
|
||||
ignorePlayer=§6Du ignorerer spilleren§c {0} §6fra nu af.
|
||||
@@ -247,6 +313,7 @@ itemId=§6ID\:§c {0}
|
||||
itemMustBeStacked=§4Elementet skal forhandles i form at stakke. En mængde af 2s vil være 2 stakke, osv.
|
||||
itemNames=§6Elementforkortelser\:§r {0}
|
||||
itemnameClear=§6Du har fjernet dette element navn.
|
||||
itemnameCommandUsage1=/<command>
|
||||
itemnameInvalidItem=§cDu skal holde et element for at omdøbe det.
|
||||
itemnameSuccess=§6Du har omdøbt dit element til "§c{0}§6".
|
||||
itemNotEnough1=§4Du har ikke nok af det element til at sælge det.
|
||||
@@ -268,12 +335,15 @@ jailReleased=§6Spilleren §c{0}§6 er fjernet fra fængslet.
|
||||
jailReleasedPlayerNotify=§6Du er blevet frigjort\!
|
||||
jailSentenceExtended=§6Fændselstid forlænges til\: {0}
|
||||
jailSet=§6Fængslet§c {0} §6er sat.
|
||||
jailsCommandUsage=/<command>
|
||||
jumpCommandUsage=/<command>
|
||||
jumpError=§4Det ville såre din computers hjerne.
|
||||
kickDefault=Smidt ud fra serveren.
|
||||
kickedAll=§4Smed alle ud fra serveren.
|
||||
kickExempt=§4Du kan ikke smide den person ud.
|
||||
kill=§6Dræbte§c {0}§6.
|
||||
killExempt=§4Du kan ikke dræbe §c{0}§4.
|
||||
kitCommandUsage1=/<command>
|
||||
kitContains=§6Kit §c{0} §6contains\:
|
||||
kitCost=\ §7§o({0})§r
|
||||
kitDelay=§m{0}§r
|
||||
@@ -287,16 +357,21 @@ kitNotFound=§4Det kit eksisterer ikke.
|
||||
kitOnce=§4Du kan ikke benytte dig af det kit igen.
|
||||
kitReceive=§6Modtog kittet§c {0}§6.
|
||||
kits=§6Kits\:§r {0}
|
||||
kittycannonCommandUsage=/<command>
|
||||
kitTimed=§4Du kan ikke benytte dig af det kit igen før om§c {0}§4.
|
||||
leatherSyntax=§6Læderfarve Syntaks\:§c color\:<red>,<green>,<blue> fx\: color\:255,0,0§6 ELLER§c color\:<rgb int> fx\: color\:16777011
|
||||
lightningCommandUsage1=/<command> [player]
|
||||
lightningSmited=§6Thi er blevet ramt af lynet\!
|
||||
lightningUse=§6Rammer§c {0} §6med lyn.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
listAfkTag=§7[AFK]§r
|
||||
listAmount=§6Der er §c{0}§6 ud af maksimum §c{1}§6 spillere online.
|
||||
listAmountHidden=§6Der er §c{0}§6/§c{1}§6 ud af maksimum §c{2}§6 spillere online.
|
||||
listGroupTag=§6{0}§r\:
|
||||
listHiddenTag=§7[SKJULT]§r
|
||||
loadWarpError=§4Kunne ikke indlæse warp {0}.
|
||||
loomCommandUsage=/<command>
|
||||
mailClear=§6For at markere alt post som læst, skriv§c /mail clear§6.
|
||||
mailCleared=§6Mail Ryddet\!
|
||||
mailDelay=For mange mails er blevet sendt inden for det sidste minut. Maksimum\: {0}
|
||||
@@ -334,6 +409,7 @@ msgEnabled=§6Receiving messages §cenabled§6.
|
||||
msgEnabledFor=§6Receiving messages §cenabled §6for §c{0}§6.
|
||||
msgFormat=§6[§c{0}§6 -> §c{1}§6] §r{2}
|
||||
msgIgnore=§c{0} §4has messages disabled.
|
||||
msgtoggleCommandUsage1=/<command> [player]
|
||||
multipleCharges=§4Du kan ikke tilføje mere end én ladning til dette fyrværkeri.
|
||||
multiplePotionEffects=§4Du kan ikke tilføje mere end én effekt til denne eliksir.
|
||||
mutedPlayer=§6Spilleren§c {0} §6 er gjort tavs.
|
||||
@@ -347,6 +423,7 @@ muteNotify=§c{0} §6har gjort §c{1}§6 tavs.
|
||||
muteNotifyFor=§c{0} §6has muted player §c{1}§6 for§c {2}§6.
|
||||
muteNotifyForReason=§c{0} §6har dæmpet spiller §c{1}§6 for§c {2}§6. Grund\: §c{3}
|
||||
muteNotifyReason=§c{0} §6har dæmpet spiller §c{1}§6. Grund\: §c{2}
|
||||
nearCommandUsage1=/<command>
|
||||
nearbyPlayers=§6Spillere i nærheden\:§r {0}
|
||||
negativeBalanceError=§4Brugeren er ikke tilladt at have en negativ saldo.
|
||||
nickChanged=§6Kaldenavn ændret.
|
||||
@@ -396,6 +473,7 @@ nothingInHand=§4Du har intet i din hånd.
|
||||
now=nu
|
||||
noWarpsDefined=§6Ingen warps defineret.
|
||||
nuke=§5Lad døden regne over dem.
|
||||
nukeCommandUsage=/<command> [player]
|
||||
numberRequired=Der skal være et tal, dit fjollehoved.
|
||||
onlyDayNight=/time understøtter kun day/night.
|
||||
onlyPlayers=§4Kun spillere på serveren kan bruge §c{0}§4.
|
||||
@@ -411,8 +489,12 @@ payConfirmToggleOn=§6You will now be prompted to confirm payments.
|
||||
payMustBePositive=§4Amount to pay must be positive.
|
||||
payToggleOff=§6You are no longer accepting payments.
|
||||
payToggleOn=§6You are now accepting payments.
|
||||
payconfirmtoggleCommandUsage=/<command>
|
||||
paytoggleCommandUsage=/<command> [player]
|
||||
paytoggleCommandUsage1=/<command> [player]
|
||||
pendingTeleportCancelled=§4Afventende teleporteringsanmodning afvist.
|
||||
pingCommandDescription=Pong\!
|
||||
pingCommandUsage=/<command>
|
||||
playerBanIpAddress=§6Player§c {0} §6banned IP address§c {1} §6for\: §c{2}§6.
|
||||
playerBanned=§6Spilleren§c {0} blev §6bandlyst§c {1} §6i §c{2}§6.
|
||||
playerJailed=§6Spilleren§c {0} §6blev fængslet.
|
||||
@@ -428,6 +510,8 @@ playerTempBanned=§6Player §c{0}§6 temporarily banned §c{1}§6 for §c{2}§6\
|
||||
playerUnbanIpAddress=§6Spiller§c {0} §6fjernede IP udelukkelse\:§c {1}
|
||||
playerUnbanned=§6Spiller§c {0} §6fjernede udelukkelse§c {1}
|
||||
playerUnmuted=§6Du er har fået din stemme tilbage.
|
||||
playtimeCommandUsage=/<command> [player]
|
||||
playtimeCommandUsage1=/<command>
|
||||
pong=Pong\!
|
||||
posPitch=§6Pitch\: {0} (Hovedretning)
|
||||
possibleWorlds=§6Mulige verdener er tal fra §c0§6 til §c{0}§6.
|
||||
@@ -447,6 +531,7 @@ powerToolRemove=§6Kommando §c{0}§6 fjernet fra §c{1}§6.
|
||||
powerToolRemoveAll=§6Alle kommandoer fjernet fra §c{0}§6.
|
||||
powerToolsDisabled=§6Alle dine magtværktøjer er deaktiveret.
|
||||
powerToolsEnabled=§6Alle dine magtværktøjer er aktiveret.
|
||||
powertooltoggleCommandUsage=/<command>
|
||||
pTimeCurrent=§c{0}§6''s tid er§c {1}§6.
|
||||
pTimeCurrentFixed=§c{0}§6''s tid er fastsat til§c {1}§6.
|
||||
pTimeNormal=§c{0}§6''s tid er normal og matcher serverens tid.
|
||||
@@ -480,6 +565,7 @@ recipeWhere=§6Hvor\: {0}
|
||||
removed=§6Fjernede§c {0} §6enheder.
|
||||
repair=§6Du har succesfuldt repareret din\: §c{0}§6.
|
||||
repairAlreadyFixed=§4Dette element behøver ikke reparation.
|
||||
repairCommandUsage1=/<command>
|
||||
repairEnchanted=§4Du har ikke tilladelse til at reparere fortryllede elementer.
|
||||
repairInvalidType=§4Dette element kan ikke repareres.
|
||||
repairNone=§4Der var ingen elementer, der behøvede reparation.
|
||||
@@ -498,6 +584,8 @@ requestSentAlready=§4You have already sent {0}§4 a teleport request.
|
||||
requestTimedOut=§4Teleporteringsanmoding udløb.
|
||||
resetBal=§6Saldo er blevet nulstillet til §c{0} §6for alle online spillere.
|
||||
resetBalAll=§6Saldo er blevet nulstillet til §c{0} §6for alle spillere.
|
||||
restCommandUsage=/<command> [player]
|
||||
restCommandUsage1=/<command> [player]
|
||||
returnPlayerToJailError=§4Der opstod en fejl under forsøget på at returnere spilleren§c {0} §4til fængsel\: §c{1}§4\!
|
||||
runningPlayerMatch=§6Søger efter spillere, der matcher ''§c{0}§6'' (dette kan tage lidt tid)
|
||||
second=sekund
|
||||
@@ -524,17 +612,22 @@ southEast=SE
|
||||
south=S
|
||||
southWest=SW
|
||||
skullChanged=§6Kranie ændret til §c{0}§6.
|
||||
skullCommandUsage1=/<command>
|
||||
slimeMalformedSize=§4Forkert udformet størrelse.
|
||||
smithingtableCommandUsage=/<command>
|
||||
socialSpy=§6SocialSpy for §c{0}§6\: §c{1}
|
||||
socialSpyMsgFormat=§6[§c{0}§7 -> §c{1}§6] §7{2}
|
||||
socialSpyMutedPrefix=§f[§6SS§f] §7(muted) §r
|
||||
socialspyCommandUsage1=/<command> [player]
|
||||
socialSpyPrefix=§f[§6SS§f] §r
|
||||
soloMob=§4Det mob kan lide at være alene.
|
||||
spawned=spawnede
|
||||
spawnSet=§6Spawn lokation ændret for gruppen§c {0}§6.
|
||||
spectator=spectator
|
||||
stonecutterCommandUsage=/<command>
|
||||
sudoExempt=§4Du kan ikke sudo denne spiller.
|
||||
sudoRun=§6Forcing§c {0} §6to run\:§r /{1}
|
||||
suicideCommandUsage=/<command>
|
||||
suicideMessage=§6Farvel, grusomme verden...
|
||||
suicideSuccess=§6{0} §6tog sit eget liv.
|
||||
survival=overlevelse
|
||||
@@ -571,16 +664,31 @@ thunder=§6Du har§c {0} §6torden i din verden.
|
||||
thunderDuration=§6Du har§c {0} §6torden i din verden i§c {1} §6sekunder.
|
||||
timeBeforeHeal=§4Tid inden næste helbredelse\:§c {0}§4.
|
||||
timeBeforeTeleport=§4Tid inden næste teleport\:§c {0}§4.
|
||||
timeCommandUsage1=/<command>
|
||||
timeFormat=§c{0}§6 eller §c{1}§6 eller §c{2}§6
|
||||
timeSetPermission=§4Du er ikke autoriseret til at ændre tiden.
|
||||
timeSetWorldPermission=§4You are not authorized to set the time in world ''{0}''.
|
||||
timeWorldCurrent=§6Den nuværende tid i§c {0} §6er §c{1}§6.
|
||||
timeWorldSet=§6Tiden blev ændret til§c {0} §6i\: §c{1}§6.
|
||||
toggleshoutCommandUsage1=/<command> [player]
|
||||
topCommandUsage=/<command>
|
||||
totalSellableAll=§aDen totale værdi af alle salgbare elementer og blocks er §c{1}§a.
|
||||
totalSellableBlocks=§aDen totale værdi af alle salgbare blocks er §c{1}§a.
|
||||
totalWorthAll=§aSolgte alle elementer og blokke for en total værdi af §c{1}§a.
|
||||
totalWorthBlocks=§aSolgte alle blokke for en total værdi af §c{1}§a.
|
||||
tpacancelCommandUsage=/<command> [player]
|
||||
tpacancelCommandUsage1=/<command>
|
||||
tpacceptCommandUsage1=/<command>
|
||||
tpallCommandUsage=/<command> [player]
|
||||
tpallCommandUsage1=/<command> [player]
|
||||
tpautoCommandUsage=/<command> [player]
|
||||
tpautoCommandUsage1=/<command> [player]
|
||||
tpdenyCommandUsage=/<command>
|
||||
tpdenyCommandUsage1=/<command>
|
||||
tprCommandUsage=/<command>
|
||||
tprCommandUsage1=/<command>
|
||||
tps=§6Nuværende TPS \= {0}
|
||||
tptoggleCommandUsage1=/<command> [player]
|
||||
tradeSignEmpty=§4Handelsskiltet har ikke noget tilgængeligt til dig.
|
||||
tradeSignEmptyOwner=§4Der er ikke noget at hente fra dette handelsskilt.
|
||||
treeFailure=§4Fejl ved generering af træ. Prøv igen på græs eller jord.
|
||||
@@ -598,6 +706,8 @@ unknownItemInList=§4Ukendt element {0} i {1} list.
|
||||
unknownItemName=§4Ukendt elementnavn\: {0}.
|
||||
unlimitedItemPermission=§4Ingen tilladelse til ubegrænset element §c{0}§4.
|
||||
unlimitedItems=§6Ubegrænsede ting\:§r
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unmutedPlayer=§6Spilleren§c {0} §6har fået sin stemme tilbage.
|
||||
unsafeTeleportDestination=§4Teleport destinationen er usikker og teleport-safety er deaktiveret.
|
||||
unsupportedFeature=§4Denne funktionalitet er ikke understøttet på denne server version.
|
||||
@@ -620,6 +730,7 @@ userJailed=§6Du er blevet fængslet\!
|
||||
userUnknown=§4Advarsel\: Brugerem ''§c{0}§4'' har aldrig spillet på serveren.
|
||||
usingTempFolderForTesting=Bruger temp mappe til testning\:
|
||||
vanish=§6Vanish for {0}§6\: {1}
|
||||
vanishCommandUsage1=/<command> [player]
|
||||
vanished=§6Du er nu helt usynlig over for normale spillere, og er skjult fra in-game kommandoer.
|
||||
versionOutputVaultMissing=§4Vault er ikke installeret. Chat og tilladelser virker måske ikke.
|
||||
versionOutputFine=§6{0} version\: §a{1}
|
||||
@@ -631,6 +742,7 @@ versionMismatchAll=§4Version-uoverenstemmelse\! Opdater alle Essentials jar-fil
|
||||
voiceSilenced=§6Du er blevet gjort tavs\!
|
||||
voiceSilencedReason=§6Din stemme er blevet tavs\!\! Grund\: §c{0}
|
||||
walking=gå
|
||||
warpCommandUsage1=/<command> [page]
|
||||
warpDeleteError=§4Der var et problem med at slette warp-filen.
|
||||
warpingTo=§6Warper til§c {0}§6.
|
||||
warpList={0}
|
||||
@@ -670,6 +782,8 @@ whoisPlaytime=§6 - Playtime\:§r {0}
|
||||
whoisTempBanned=§6 - Ban expires\:§r {0}
|
||||
whoisTop=§6 \=\=\=\=\=\= WhoIs\:§c {0} §6\=\=\=\=\=\=
|
||||
whoisUuid=§6 - UUID\:§r {0}
|
||||
workbenchCommandUsage=/<command>
|
||||
worldCommandUsage1=/<command>
|
||||
worth=§aStak af {0} med en værdi af §c{1}§a ({2} ting á {3} hver)
|
||||
worthMeta=§aStak af {0} med metadata af {1} med en værdi af §c{2}§a ({3} element(er) á {4} hver)
|
||||
worthSet=§6Værdi ændret
|
||||
|
||||
@@ -100,6 +100,8 @@ bookCommandUsage3=/<command> Titel <title>
|
||||
bookCommandUsage3Description=Setzt den Titel eines signierten Buches fest
|
||||
bookLocked=§6Dieses Buch ist jetzt versiegelt.
|
||||
bookTitleSet=§6Buchtitel auf {0} geändert.
|
||||
bottomCommandDescription=Teleportiere zum niedrigsten Punkt an deiner aktuellen Position.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Zerstört den Block, den du anschaust.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Broadcast§6]§a {0}
|
||||
@@ -240,6 +242,12 @@ discordbroadcastCommandUsage1Description=Sendet eine Nachricht an den angegebene
|
||||
discordbroadcastInvalidChannel=§4Discord Kanal §c{0}§4 existiert nicht.
|
||||
discordbroadcastPermission=§4Du hast keine Berechtigung, Nachrichten an den angegebenen §c{0}§4 Kanal zu senden.
|
||||
discordbroadcastSent=§6Nachricht gesendet an §c{0}§6\!
|
||||
discordCommandAccountArgumentUser=Der nachzuschlagende Discord Account
|
||||
discordCommandAccountDescription=Sucht den verlinkten Minecraft Account für dich oder einen anderen Discord Benutzer
|
||||
discordCommandAccountResponseLinked=Dein Account ist mit dem Minecraft Account **{0}** verknüpft
|
||||
discordCommandAccountResponseLinkedOther={0}''s Account ist mit dem Minecraft Account **{1}** verknüpft
|
||||
discordCommandAccountResponseNotLinked=Du hast keinen verknüpften Minecraft Account.
|
||||
discordCommandAccountResponseNotLinkedOther={0} hat keinen verknüpften Minecraft Account.
|
||||
discordCommandDescription=Sendet die Discord Einladungslink an den Spieler.
|
||||
discordCommandLink=§6Trete unserem Discord Server bei §c{0}§\!
|
||||
discordCommandUsage=/<command>
|
||||
@@ -248,12 +256,20 @@ discordCommandUsage1Description=Sendet die Discord Einladungslink an den Spieler
|
||||
discordCommandExecuteDescription=Führt einen Konsolen-Befehl auf dem Minecraft-Server aus.
|
||||
discordCommandExecuteArgumentCommand=Der auszuführende Befehl
|
||||
discordCommandExecuteReply=Führe Befehl aus\: "/{0}"
|
||||
discordCommandUnlinkDescription=Löst die Verbindung zwischen dem Minecraft Account und dem derzeit verbundenen Discord Account auf
|
||||
discordCommandUnlinkInvalidCode=Du hast derzeit keinen Minecraft Account mit Discord verknüpft\!
|
||||
discordCommandUnlinkUnlinked=Dein Discord Account wurde von allen zugehörigen Minecraft-Konten entfernt.
|
||||
discordCommandLinkArgumentCode=Den Code, den du im Spiel erhalten hast, um deinen Minecraft Account zu verknüpfen
|
||||
discordCommandLinkDescription=Verwende Code vom /link Befehl in Minecraft und dein Discord Konto mit deinem Minecraft Konto zu verknüpfen
|
||||
discordCommandLinkHasAccount=Du hast bereits einen Account verknüpft\! Um die Verknüpfung mit dem derzeitigen Account aufzuheben, nutze "/unlink".
|
||||
discordCommandLinkInvalidCode=Ungültiger Link-Code\! Stell sicher, dass du "/link" im Spiel eingegeben hast und den richtigen Code kopiert hast.
|
||||
discordCommandLinkLinked=Dein Konto wurde erfolgreich verknüpft\!
|
||||
discordCommandListDescription=Ruft eine Liste der Online-Spieler auf.
|
||||
discordCommandListArgumentGroup=Eine bestimmte Gruppe, um Ihre Suche eingrenzen zu können
|
||||
discordCommandMessageDescription=Sendet eine Nachricht an einen Spieler auf dem Minecraft-Server.
|
||||
discordCommandMessageArgumentUsername=Der Spieler, an den die Nachricht gesendet werden soll
|
||||
discordCommandMessageArgumentMessage=Die Nachricht, die an den Spieler gesendet werden soll
|
||||
discordErrorCommand=Du hast deinen Bot falsch zu deinem Server hinzugefügt. Bitte folge dem Tutorial in der Konfiguration und füge deinen Bot mit https\://essentialsx.net/discord.html hinzu\!
|
||||
discordErrorCommand=Du hast deinen Bot nicht korrekt zu deinem Server hinzugefügt\! Bitte folge der Anleitung in der Konfiguration und füge deinen Bot mit https\://essentialsx.net/discord.html hinzu.
|
||||
discordErrorCommandDisabled=Dieser Befehl ist deaktiviert\!
|
||||
discordErrorLogin=Beim Anmelden in Discord ist ein Fehler aufgetreten, was dazu geführt hat, dass das Plugin sich selbst deaktiviert hat\: \n{0}
|
||||
discordErrorLoggerInvalidChannel=Discord Konsolen-Protokollierung wurde aufgrund einer ungültigen Kanaldbeschreibung deaktiviert\! Wenn du vorhast sie zu deaktivieren, setze die Kanal-ID auf "none". Andernfalls überprüfe, ob deine Kanal-ID korrekt ist.
|
||||
@@ -265,8 +281,20 @@ discordErrorNoPrimary=Sie haben keinen Primärkanal definiert oder Ihr Primärka
|
||||
discordErrorNoPrimaryPerms=Dein Bot kann nicht in deinem Primärkanal \#{0} sprechen. Bitte stelle sicher, dass dein Bot Lese- und Schreibrechte in allen Kanälen besitzt, die du verwenden möchtest.
|
||||
discordErrorNoToken=Kein Token bereitgestellt\! Bitte folgen Sie dem Tutorial in der Konfiguration, um das Plugin einzurichten.
|
||||
discordErrorWebhook=Beim Senden von Nachrichten an Ihren Konsolenkanal ist ein Fehler aufgetreten\! Dies wurde wahrscheinlich durch das versehentliche Löschen Ihres Webhook der Konsole verursacht. Dies kann üblicherweise durch das Überprüfen der "Manage Webhooks"-Berechtigung und dem Ausführen von "/ess reload" behoben werden.
|
||||
discordLinkInvalidGroup=Ungültige Gruppe {0} wurde für Rolle {1} bereitgestellt. Die folgenden Gruppen sind verfügbar\: {2}
|
||||
discordLinkInvalidRole=Eine ungültige Rollen-ID, {0}, wurde für die Gruppe {1} bereitgestellt. Du kannst die Rollen-ID mit dem /roleinfo Befehl in Discord sehen.
|
||||
discordLinkInvalidRoleInteract=Die Rolle, {0} ({1}), kann nicht für die Gruppen->Rollensynchronisierung verwendet werden, da sie über der obersten Rolle Ihres Bots liegt. Verschieben Sie entweder die Rolle Ihres Bots über "{0}" oder bewegen Sie sich "{0}" unter der Rolle Ihres Bots.
|
||||
discordLinkInvalidRoleManaged=Die Rolle, {0} ({1}), kann nicht für Gruppen->Rollensynchronisierung verwendet werden, da sie von einem anderen Bot oder einer anderen Integration verwaltet wird.
|
||||
discordLinkLinked=§6Um dein Minecraft-Konto mit Discord zu verknüpfen, tippe §c{0} §6in den Discord-Server.
|
||||
discordLinkLinkedAlready=§6Du hast deinen Discord Account bereits verlinkt\! Wenn du die Verknüpfung deines Discord Accounts aufheben möchtest, nutze §c/unlink§6.
|
||||
discordLinkLoginKick=§6Du musst deinen Discord Account verknüpfen, bevor du diesem Server beitreten kannst.\n§6Um dein Minecraft-Konto mit Discord zu verknüpfen, benutze\:\n§c{0}\n§6auf dem Discord-Server dieses Server''s\:\n§c{1}
|
||||
discordLinkLoginPrompt=§6Du musst deinen Discord Account verknüpfen, bevor du dich diesen Server bewegen oder chatten oder mit ihm interagieren kannst. Um dein Minecraft-Konto mit Discord zu verknüpfen, schreibe §c{0} §6in den Discord-Server dieses Servers\: §c{1}
|
||||
discordLinkNoAccount=§6Du hast derzeit kein Discord Konto mit deinem Minecraft-Account verknüpft.
|
||||
discordLinkPending=§6Du hast bereits einen code. Um die Verknüpfung fertigzustellen, tippe §c{0} §6in den Discord Server.
|
||||
discordLinkUnlinked=§6Dein Minecraft Account wurde von allen verbundenen Discord Accounts getrennt.
|
||||
discordLoggingIn=Versuche sich bei Discord anzumelden...
|
||||
discordLoggingInDone=Erfolgreich angemeldet als {0}
|
||||
discordMailLine=**Neue Mail von {0}\:** {1}
|
||||
discordNoSendPermission=Kann keine Nachricht im Kanal senden\: \#{0} Bitte stellen Sie sicher, dass der Bot die Berechtigung "Send Messages" in diesem Kanal hat\!
|
||||
discordReloadInvalid=Versucht die EssentialsX Discord Konfiguration neu zu laden, während das Plugin in einem ungültigen Zustand ist\! Wenn du deine Konfiguration geändert hast, starte deinen Server neu.
|
||||
disposal=Beseitigung
|
||||
@@ -292,7 +320,7 @@ ecoCommandUsage2=/<command> take <player> <amount>
|
||||
ecoCommandUsage2Description=Nimmt den angegebenen Geldbetrag vom angegebenen Spieler
|
||||
ecoCommandUsage3=<command> set <player><amount>
|
||||
ecoCommandUsage3Description=Setzt den angegebenen Spieler für die angegebene Anzahl von Sekunden in Brand
|
||||
ecoCommandUsage4=<command> set <player><amount>
|
||||
ecoCommandUsage4=/<command> reset <player> <amount>
|
||||
ecoCommandUsage4Description=Setzt den Guthaben des angegebenen Spielers auf den Startsaldo des Servers zurück
|
||||
editBookContents=§eDu darfst den Inhalt dieses Buches jetzt bearbeiten.
|
||||
enabled=aktiviert
|
||||
@@ -379,6 +407,7 @@ fireworkCommandUsage1Description=Löscht alle Effekte von deinem gehaltenen Feue
|
||||
fireworkCommandUsage2=/<command> power <amount>
|
||||
fireworkCommandUsage2Description=Ändert die Stärke des in der Hand gehaltenen Feuerwerks
|
||||
fireworkCommandUsage3=/<command> fire [amount]
|
||||
fireworkCommandUsage3Description=Startet entweder eine oder die angegebene Anzahl von Kopien des gehaltenen Feuerwerks
|
||||
fireworkCommandUsage4=/<command> <meta>
|
||||
fireworkCommandUsage4Description=Fügt den Effekt dem gerade in der Hand gehaltenen Feuerwerk hinzu
|
||||
fireworkEffectsCleared=§6Alle Effekte wurden vom Stapel, den du in der Hand hast, entfernt.
|
||||
@@ -388,6 +417,7 @@ fixingHomes=Ungültige homes werden gelöscht...
|
||||
flyCommandDescription=Abheben, in die Höhe\!
|
||||
flyCommandUsage=/<command> [spieler] [on|off]
|
||||
flyCommandUsage1=/<command> [spieler]
|
||||
flyCommandUsage1Description=Schaltet das Fliegen für sich selbst oder einen anderen Spieler ein, falls angegeben
|
||||
flying=fliegt
|
||||
flyMode=§6Du hast den Flugmodus bei §c{1} {0}§6.
|
||||
foreverAlone=§cDu hast niemanden, dem du antworten kannst.
|
||||
@@ -399,6 +429,7 @@ gameModeInvalid=§4Du müsst einen gültigen Spieler/Modus angeben.
|
||||
gamemodeCommandDescription=Spieler-Spielmodus ändern.
|
||||
gamemodeCommandUsage=/<command> <survival|creative|adventure|spectator> [spieler]
|
||||
gamemodeCommandUsage1=/<command> <survival|creative|adventure|spectator> [spieler]
|
||||
gamemodeCommandUsage1Description=Setzt den Spielmodus von dir oder einem anderen Spieler, falls angegeben
|
||||
gcCommandDescription=Meldet Speicher, Betriebszeit und Tick-Info.
|
||||
gcCommandUsage=/<command>
|
||||
gcfree=§6Freier Speicher\:§c {0} MB
|
||||
@@ -409,10 +440,13 @@ geoipJoinFormat=§c{0} §6kommt aus §c{1}§6.
|
||||
getposCommandDescription=Erfahre deine aktuellen Koordinaten oder die eines Spielers.
|
||||
getposCommandUsage=/<command> [spieler]
|
||||
getposCommandUsage1=/<command> [spieler]
|
||||
getposCommandUsage1Description=Ermittelt die Koordinaten von dir oder einem anderen Spieler, falls angegeben
|
||||
giveCommandDescription=Gebe einem Spieler einen Gegenstand.
|
||||
giveCommandUsage=/<command> <spieler> <gegenstand|numerisch> [anzahl [gegenstandsmeta...]]
|
||||
giveCommandUsage1=/<command> <player> <item> [amount]
|
||||
giveCommandUsage1Description=Gibt dem gewünschten Spieler 64 (oder die angegebene Menge) des angegebenen Gegenstands
|
||||
giveCommandUsage2=/<command> <player> <item> <amount> <meta>
|
||||
giveCommandUsage2Description=Gibt dem gewünschten Spieler die angegebene Menge des angegebenen Gegenstands mit den angegebenen Metadaten
|
||||
geoipCantFind=§6Spieler§c {0}§6 kommt aus§a einem unbekannten Land§6.
|
||||
geoIpErrorOnJoin=GeoIP-Daten für {0} konnten nicht abgerufen werden. Bitte stelle sicher, dass der Lizenzschlüssel und die Konfiguration korrekt sind.
|
||||
geoIpLicenseMissing=Kein Lizenzschlüssel gefunden\! Bitte besuche https\://essentialsx.net/geoip für Ersteinrichtungsanweisungen.
|
||||
@@ -422,6 +456,7 @@ givenSkull=§6Dir wurde der Kopf von §c{0}§6 gegeben.
|
||||
godCommandDescription=Aktiviert deine göttlichen Kräfte.
|
||||
godCommandUsage=/<command> [spieler] [on|off]
|
||||
godCommandUsage1=/<command> [spieler]
|
||||
godCommandUsage1Description=Schaltet den Godmode für dich oder einen anderen Spieler um, falls angegeben
|
||||
giveSpawn=§6Gebe§c {0} {1}§6 zu§c {2}§6.
|
||||
giveSpawnFailure=§4Nicht genug Platz, §c{0} {1} §4wurde verloren.
|
||||
godDisabledFor=§6für§c {0}§cdeaktiviert§6.
|
||||
@@ -470,9 +505,12 @@ holeInFloor=§4Wooops... Da ist ein Loch im Boden\!
|
||||
homeCommandDescription=Zu deinem Zuhause teleportieren.
|
||||
homeCommandUsage=/<command> [spieler\:][name]
|
||||
homeCommandUsage1=/<command> <name>
|
||||
homeCommandUsage1Description=Teleportiert dich zu deinem Home mit dem angegebenen Namen
|
||||
homeCommandUsage2=/<command> <player>\:<name>
|
||||
homeCommandUsage2Description=Teleportiert dich zum Home des angegebenen Spielers mit dem angegebenen Namen
|
||||
homes=§6Wohnorte\:§r {0}
|
||||
homeConfirmation=§6Du hast schon ein Zuhause mit dem Namen §c{0}§6\!\nUm dein existierendes Zuhause zu überschreiben, führe den Befehl erneut aus.
|
||||
homeRenamed=§6Dein Zuhause §c{0} §6wurde zu §c{1}§6umbenannt.
|
||||
homeSet=§6Zuhause auf aktuellen Standort gesetzt.
|
||||
hour=Stunde
|
||||
hours=Stunden
|
||||
@@ -489,6 +527,7 @@ iceOther=§6Erfriere§c {0}§6.
|
||||
ignoreCommandDescription=Andere Spieler nicht ignorieren oder ignorieren.
|
||||
ignoreCommandUsage=/<command> <spieler>
|
||||
ignoreCommandUsage1=/<command> <spieler>
|
||||
ignoreCommandUsage1Description=Ignoriert oder hebt die Ignorierung des angegebenen Spielers auf
|
||||
ignoredList=§6Ignoriert\:§r {0}
|
||||
ignoreExempt=§4Du kannst diesen Spieler nicht ignorieren.
|
||||
ignorePlayer=§6Du ignorierst ab jetzt§c {0}§6.
|
||||
@@ -524,6 +563,7 @@ invseeCommandDescription=Zeige das Inventar anderer Spieler an.
|
||||
invseeCommandUsage=/<command> <spieler>
|
||||
invseeCommandUsage1=/<command> <spieler>
|
||||
invseeCommandUsage1Description=Öffnet das Inventar des angegebenen Spielers
|
||||
invseeNoSelf=§cDu kannst nur die Inventare anderer Spieler einsehen.
|
||||
is=ist
|
||||
isIpBanned=§6IP §c{0} §6ist gesperrt.
|
||||
internalError=§cBeim ausführen des Befehls ist ein interner Fehler aufgetreten.
|
||||
@@ -538,7 +578,12 @@ itemId=§6ID\:§c {0}
|
||||
itemloreClear=§6Du hast die Beschreibung dieses Gegenstands geleert.
|
||||
itemloreCommandDescription=Die Beschreibung eines Gegenstand bearbeiten.
|
||||
itemloreCommandUsage=/<command> <add/set/clear> [text/zeile] [text]
|
||||
itemloreCommandUsage1=/<command> add [text]
|
||||
itemloreCommandUsage1Description=Fügt den angegebenen Text an das Ende der Lore des Gegenstands an
|
||||
itemloreCommandUsage2=/<command> set <zeilennummer> <text>
|
||||
itemloreCommandUsage2Description=Setzt die angegebene Zeile in der Lore des gehaltenen Gegenstandes zum angegebenen Text
|
||||
itemloreCommandUsage3=/<command> clear
|
||||
itemloreCommandUsage3Description=Löscht die Lore des gehaltenen Gegenstandes
|
||||
itemloreInvalidItem=§4Du must einen Gegenstand halten um seine Beschreibung zu bearbeiten.
|
||||
itemloreNoLine=§4Dein gehaltener Gegenstand hat keinen Beschreibungstect in Zeile §c{0}§4.
|
||||
itemloreNoLore=§4Dein gehaltener Gegenstand hat keinen Beschreibungstext.
|
||||
@@ -575,6 +620,8 @@ jailList=§6Gefängnisse\:§r {0}
|
||||
jailMessage=§4Du hast ein Verbrechen begangen, also musst du deine Zeit absitzen.
|
||||
jailNotExist=§4Dieses Gefängnis existiert nicht.
|
||||
jailNotifyJailed=§6Player§c {0} §6wurde in den Knast gesteckt von §c{1}.
|
||||
jailNotifyJailedFor=§6Spieler§c {0} §6verhaftet für§c {1}§6durch §c{2}§6.
|
||||
jailNotifySentenceExtended=§6Die Haftstrafe des Spielers §c{0} §6wurde auf §c{1} §6um §c{2}§6 verändert.
|
||||
jailReleased=§6Spieler §c{0}§6 wurde freigelassen.
|
||||
jailReleasedPlayerNotify=§6Du wurdest freigelassen\!
|
||||
jailSentenceExtended=§6Gefängniszeit erweitert auf\: {0}
|
||||
@@ -615,6 +662,7 @@ kitCost=\ §7§o({0})§r
|
||||
kitDelay=§m{0}§r
|
||||
kitError=§4Es gibt keine gültigen Kits.
|
||||
kitError2=§4Dieses Kit ist nicht korrekt definiert. Kontaktiere einen Administrator.
|
||||
kitError3=Es konnte kein Kit Item im Kit "{0}" an {1} gegeben werden, da dafür Paper 1.15.2+ benötigt wird.
|
||||
kitGiveTo=§6Du gibst §c{1}§6 §c{0}§6-Kit.
|
||||
kitInvFull=§4Dein Inventar ist voll. Das Kit wird auf den Boden gelegt.
|
||||
kitInvFullNoDrop=§4In deinem Inventar ist nicht genug Platz für dieses Kit.
|
||||
@@ -626,6 +674,8 @@ kitReset=§6Cooldown für kit §c{0}§6 zurücksetzen.
|
||||
kitresetCommandDescription=Setzt den Cooldown fpr das ausgewählte Kit zurück.
|
||||
kitresetCommandUsage=/<command> <kit> [player]
|
||||
kitresetCommandUsage1=/<command> <kit> [player]
|
||||
kitresetCommandUsage1Description=Setzt, falls angegeben, die Abklingzeit des bestimmten Kits für dich oder einen anderen Spieler zurück
|
||||
kitResetOther=§6Setze Kits §c{0} §6Abklingzeit für§c{1}§6 zurück.
|
||||
kits=§6Kits\: §r{0}
|
||||
kittycannonCommandDescription=Wirf ein explodierendes Kätzchen auf deinen Gegner.
|
||||
kittycannonCommandUsage=/<command>
|
||||
@@ -634,19 +684,27 @@ leatherSyntax=§6Lederfarben-Syntax\:§c color\:<rot>,<grün>,<blau>, z.B.\: col
|
||||
lightningCommandDescription=Die Kraft von Thor. Schlag auf den Cursor oder Spieler.
|
||||
lightningCommandUsage=/<command> [spieler] [kraft]
|
||||
lightningCommandUsage1=/<command> [spieler]
|
||||
lightningCommandUsage1Description=Erzeugt Blitzeinschlag am den Ort, auf den du schaust oder auf einen anderen Spieler, wenn angegeben
|
||||
lightningCommandUsage2=/<command> <player> <power>
|
||||
lightningCommandUsage2Description=Erzeugt Blitzeinschlag auf dem angebenen Spieler mit der angegebenen Stärke
|
||||
lightningSmited=§6Du wurdest gepeinigt.
|
||||
lightningUse=§6Peinige §c{0}
|
||||
linkCommandDescription=Erzeugt einen Code, um dein Minecraft-Konto mit Discord zu verknüpfen.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
linkCommandUsage1Description=Erzeugt einen Code für den /link Befehl auf Discord
|
||||
listAfkTag=§7[Abwesend]§r
|
||||
listAmount=§6Es sind §c{0}§6 von maximal §c{1}§6 Spielern online.
|
||||
listAmountHidden=§6Es sind§c {0}§6/§c{1}§6 von maximal§c {2}§6 Spielern online.
|
||||
listCommandDescription=Liste alle verfügbaren Spieler.
|
||||
listCommandUsage=/<command> [Gruppe]
|
||||
listCommandUsage1=/<command> [Gruppe]
|
||||
listCommandUsage1Description=Listet alle Spieler auf dem Server oder aus der gegebenen Gruppe auf, so fern angegeben
|
||||
listGroupTag=§6{0}§r\:
|
||||
listHiddenTag=§7[Versteckt]§r
|
||||
listRealName=({0})
|
||||
loadWarpError=§4Beim Laden von Warp-Punkt §c{0}§6 ist ein Fehler aufgetreten.
|
||||
localFormat=§3[L] §r<{0}> {1}
|
||||
loomCommandDescription=Öffnet einen Webstuhl.
|
||||
loomCommandUsage=/<command>
|
||||
mailClear=§6Um deine Nachrichten zu löschen, schreibe§c /mail clear.
|
||||
@@ -655,17 +713,27 @@ mailClearIndex=§4Du musst eine Zahl zwischen 1-{0} angeben.
|
||||
mailCommandDescription=Verwaltet inter-spieler, intra-server Nachrichten.
|
||||
mailCommandUsage=/<command> [read|clear|clear [number]|send [to] [message]|sendtemp [to] [expire time] [message]|sendall [message]]
|
||||
mailCommandUsage1=/<command> read [page]
|
||||
mailCommandUsage1Description=Liest die erste (oder eine bestimmte) Seite deiner Mail
|
||||
mailCommandUsage2=/<command> clear [number]
|
||||
mailCommandUsage2Description=Löscht entweder alle oder die angegebene(n) Mail(s)
|
||||
mailCommandUsage3=/<command> send <player> <message>
|
||||
mailCommandUsage3Description=Sendet dem angegebenen Spieler die gegebene Nachricht
|
||||
mailCommandUsage4=/<command> sendall <message>
|
||||
mailCommandUsage4Description=Sendet die Nachricht an alle Spieler
|
||||
mailCommandUsage5=/<command> sendtemp <player> <expire time> <message>
|
||||
mailCommandUsage5Description=Sendet dem angegebenen Spieler die eingestellte Nachricht, die in der angegebenen Zeit ablaufen wird
|
||||
mailCommandUsage6=/<command> sendtempall <expire time> <message>
|
||||
mailCommandUsage6Description=Sendet allen Spieler diese Nachricht, welche in der angegebenen Zeit ablaufen wird
|
||||
mailDelay=In der letzten Minute wurden zu viele Nachrichten gesendet. Maximum\: {0}
|
||||
mailFormatNew=§6[§r{0}§6] §6[§r{1}§6] §r{2}
|
||||
mailFormatNewTimed=§6[§e⚠§6] §6[§r{0}§6] §6[§r{1}§6] §r{2}
|
||||
mailFormatNewRead=§6[§r{0}§6] §6[§r{1}§6] §7§o{2}
|
||||
mailFormatNewReadTimed=§6[§e⚠§6] §6[§r{0}§6] §6[§r{1}§6] §7§o{2}
|
||||
mailFormat=§6[§r{0}§6] §r{1}
|
||||
mailMessage={0}
|
||||
mailSent=§6Nachricht gesendet\!
|
||||
mailSentTo=§c{0}§6 wurde diese Mail gesendet\:
|
||||
mailSentToExpire=§c{0}§6 wurde folgende Nachricht gesendet, die in §c{1}§6ablaufen wird\:
|
||||
mailTooLong=§4Die Nachricht ist zu lang. Benutze weniger als 1000 Zeichen.
|
||||
markMailAsRead=§6Um deine Nachrichten zu löschen, schreibe§c /mail clear.
|
||||
matchingIPAddress=\\u00a76Die folgenden Spieler haben sich vorher schonmal mit dieser IP-Adresse eingeloggt\:
|
||||
@@ -676,6 +744,7 @@ mayNotJailOffline=§4Du darfst abgemeldete Spieler nicht einsperren.
|
||||
meCommandDescription=Beschreibt eine Aktion im Kontext des Spielers.
|
||||
meCommandUsage=/<command> <Beschreibung>
|
||||
meCommandUsage1=/<command> <Beschreibung>
|
||||
meCommandUsage1Description=Beschreibt eine Aktion
|
||||
meSender=mir
|
||||
meRecipient=dir
|
||||
minimumBalanceError=§4Den Mindestkontostand, den ein Benutzer haben kann ist {0}.
|
||||
@@ -695,6 +764,7 @@ months=Monate
|
||||
moreCommandDescription=Füllt den Gegenstandsstapel in der Hand mit der angegebenen Anzahl, oder zu maximaler Größe falls keine angegeben ist.
|
||||
moreCommandUsage=/<command> [anzahl]
|
||||
moreCommandUsage1=/<command> [anzahl]
|
||||
moreCommandUsage1Description=Füllt den gehaltenen Gegenstand auf die angegebene Menge oder seine maximale Grösse, wenn keine angegeben ist
|
||||
moreThanZero=§4Anzahl muss größer als 0 sein.
|
||||
motdCommandDescription=Zeigt die Nachricht des Tages an.
|
||||
motdCommandUsage=/<command> [kapitel] [seite]
|
||||
@@ -702,6 +772,7 @@ moveSpeed=§c{0}§6'' Geschwindigkeit wurde für§c {2}§6 auf§c {1}§6 gesetzt
|
||||
msgCommandDescription=Sendet eine private Nachricht an den angegebenen Spieler.
|
||||
msgCommandUsage=/<command> <zu> <nachricht>
|
||||
msgCommandUsage1=/<command> <zu> <nachricht>
|
||||
msgCommandUsage1Description=Sendet die angegebene Nachricht privat an den angegebenen Spieler
|
||||
msgDisabled=§6Das Empfangen von Nachrichten wurde §cdeaktiviert§6.
|
||||
msgDisabledFor=§6Das Empfangen von Nachrichten wurde für §a{0} §cdeaktiviert§6.
|
||||
msgEnabled=§6Das Empfangen von Nachrichten wurde §caktiviert§6.
|
||||
@@ -711,11 +782,15 @@ msgIgnore=§c{0} §4hat Benachrichtigungen deaktiviert.
|
||||
msgtoggleCommandDescription=Blockiert das Erhalten aller privaten Nachrichten.
|
||||
msgtoggleCommandUsage=/<command> [spieler] [on|off]
|
||||
msgtoggleCommandUsage1=/<command> [spieler]
|
||||
msgtoggleCommandUsage1Description=Schaltet das Fliegen für sich selbst oder einen anderen Spieler ein, falls angegeben
|
||||
multipleCharges=§4Du kannst einem Feuerwerk nur einen Feuerwerksstern geben.
|
||||
multiplePotionEffects=§4Du kannst diesem Trank nur einen Effekt geben.
|
||||
muteCommandDescription=Stummschalten oder Aufhebung einer Stummschaltung eines Spielers.
|
||||
muteCommandUsage=/<command> <spieler> [datumsunterschied] [grund]
|
||||
muteCommandUsage1=/<command> <spieler>
|
||||
muteCommandUsage1Description=Stellt den angegebenen Spieler dauerhaft stumm oder hebt die Stummschaltung auf, wenn er bereits stummgeschaltet war
|
||||
muteCommandUsage2=/<command> <Spieler> <Länge> [Grund]
|
||||
muteCommandUsage2Description=Schaltet den angegebenen Spieler für die angegebene Zeit mit einem optionalen Grund stumm
|
||||
mutedPlayer=§6Spieler§c {0}§6 stummgeschaltet.
|
||||
mutedPlayerFor=§6Spieler§c {0}§6 ist für§c {1}§6 stummgeschaltet.
|
||||
mutedPlayerForReason=§6Spieler§c {0}§6 für§c {1}§6 stummgeschaltet. Grund\: §c{2}
|
||||
@@ -730,14 +805,27 @@ muteNotifyReason=§c{0} §6hat Spieler§c {1}§6 stummgeschaltet. Grund\: §c{2}
|
||||
nearCommandDescription=Listet die Spieler bei oder in der Nähe eines Spielers auf.
|
||||
nearCommandUsage=/<command> [Spielername] [Radius]
|
||||
nearCommandUsage1=/<command>
|
||||
nearCommandUsage1Description=Listet alle Spieler auf, die sich im standardmässigen Umkreis von dir befinden
|
||||
nearCommandUsage2=/<command> <Radius>
|
||||
nearCommandUsage2Description=Listet alle Spieler innerhalb des angegebenen Radius von dir
|
||||
nearCommandUsage3=/<command> <spieler>
|
||||
nearCommandUsage3Description=Listet alle Spieler auf, die sich innerhalb vom standardmässigen Umkreis des angegebenen Spielers befinden
|
||||
nearCommandUsage4=/<command> <Spieler> <Radius>
|
||||
nearCommandUsage4Description=Listet alle Spieler innerhalb des angegebenen Radius von dir auf
|
||||
nearbyPlayers=§6Spieler in der Nähe\:§r {0}
|
||||
nearbyPlayersList={0}§f(§c{1}m§f)
|
||||
negativeBalanceError=§4Spieler dürfen keine Schulden machen.
|
||||
nickChanged=§6Spitzname geändert.
|
||||
nickCommandDescription=Ändere deinen Nicknamen oder den eines anderen Spielers.
|
||||
nickCommandUsage=/<command> [spieler] <spitzname|off>
|
||||
nickCommandUsage1=/<command> <spitzname>
|
||||
nickCommandUsage1Description=Ändert deinen Nicknamen zu dem gegebenen Text
|
||||
nickCommandUsage2=/<command> aus
|
||||
nickCommandUsage2Description=Entfernt deinen Spitznamen
|
||||
nickCommandUsage3=/<command> <Spieler> <Spitzname>
|
||||
nickCommandUsage3Description=Ändert den Nicknamen des angegebenen Spielers
|
||||
nickCommandUsage4=/<command> <player> off
|
||||
nickCommandUsage4Description=Entfernt den Nicknamen des angegebenen Spielers
|
||||
nickDisplayName=§4Du musst change-displayname in der Essentials-Konfiguration aktivieren.
|
||||
nickInUse=§4Dieser Name wird bereits verwendet.
|
||||
nickNameBlacklist=§4Dieser Spitzname ist nicht erlaubt.
|
||||
@@ -780,6 +868,7 @@ noPotionEffectPerm=§4Du darfst den Zaubertrankeffekt §c{0} §4diesem Trank nic
|
||||
noPowerTools=§6Du hast keine Powertools zugewiesen.
|
||||
notAcceptingPay=§4{0} §4akzeptiert keine Zahlungen.
|
||||
notAllowedToLocal=§4Du hast keine Berechtigung, im lokalen Chat zu sprechen.
|
||||
notAllowedToQuestion=§4Du hast keine Berechtigung das Frage System zu benutzen.
|
||||
notAllowedToShout=§4Du hast nicht die Erlaubnis zu schreien.
|
||||
notEnoughExperience=§4Du hast nicht genug Erfahrung.
|
||||
notEnoughMoney=§4Du hast nicht genug Guthaben.
|
||||
@@ -790,6 +879,8 @@ noWarpsDefined=§6Es sind keine Warp-Punkte definiert.
|
||||
nuke=§5Möge der Tod auf Euch hernieder prasseln und euch vernichten \:>\!
|
||||
nukeCommandDescription=Möge der Tod auf sie hernieder prasseln.
|
||||
nukeCommandUsage=/<command> [spieler]
|
||||
nukeCommandUsage1=/<command> [players...]
|
||||
nukeCommandUsage1Description=Sendet einen Nuke über alle Spieler oder bestimmten Spieler(n), falls angegeben
|
||||
numberRequired=Du musst eine Zahl angeben.
|
||||
onlyDayNight=/time unterstützt nur day und night.
|
||||
onlyPlayers=§4Nur Ingame-Spieler können §c{0} §4benutzen.
|
||||
@@ -803,6 +894,7 @@ passengerTeleportFail=§4Du kannst nicht teleportiert werden, während du Passag
|
||||
payCommandDescription=Bezahlt einen anderen Spieler von deinem Kontostand.
|
||||
payCommandUsage=/<command> <Spieler> <Anzahl>
|
||||
payCommandUsage1=/<command> <Spieler> <Anzahl>
|
||||
payCommandUsage1Description=Gibt dem angegebenen Spieler den angegebenen Betrag an Geld
|
||||
payConfirmToggleOff=§6Du wirst nicht länger aufgefordert, Zahlungen zu bestätigen.
|
||||
payConfirmToggleOn=§6Du wirst ab jetzt aufgefordert, Zahlungen zu bestätigen.
|
||||
payDisabledFor=§6Deaktivierte die Annahme von Zahlungen für §c{0}§6.
|
||||
@@ -816,6 +908,7 @@ payconfirmtoggleCommandUsage=/<command>
|
||||
paytoggleCommandDescription=Bestimmt, ob du Zahlungen akzeptierst.
|
||||
paytoggleCommandUsage=/<command> [spieler]
|
||||
paytoggleCommandUsage1=/<command> [spieler]
|
||||
paytoggleCommandUsage1Description=Schalte um, ob du oder ein anderer Spieler wenn angegeben, Zahlungen akzeptieren
|
||||
pendingTeleportCancelled=§4Die laufende Teleportation wurde abgebrochen.
|
||||
pingCommandDescription=§b..\:\:§4Pông§b\:\:..\!
|
||||
pingCommandUsage=/<command>
|
||||
@@ -835,15 +928,25 @@ playerTempBanned=§6Spieler§c {0}§6 hat§c {1}§6 temporär für§c {2}§6 ges
|
||||
playerUnbanIpAddress=§6Spieler§c {0}§6 hat IP entsperrt\:§c {1}
|
||||
playerUnbanned=§6Spieler§c {0} §6hat§c {1}§6 entsperrt
|
||||
playerUnmuted=§6Du bist nicht mehr gemutet.
|
||||
playtimeCommandDescription=Zeigt die Spielzeit eines Spielers im Spiel
|
||||
playtimeCommandUsage=/<command> [spieler]
|
||||
playtimeCommandUsage1=/<command>
|
||||
playtimeCommandUsage1Description=Zeigt deine gespielte Zeit im Spiel
|
||||
playtimeCommandUsage2=/<command> <spieler>
|
||||
playtimeCommandUsage2Description=Zeigt die Spielzeit eines bestimmten Spielers im Spiel
|
||||
playtime=§6Spielzeit\:§c {0}
|
||||
playtimeOther=§6Spielzeit von {1}§6\:§c {0}
|
||||
pong=§b..\:\:§4Pông§b\:\:..\!
|
||||
posPitch=§6Pitch\: {0} (Neigewinkel)
|
||||
possibleWorlds=§6Mögliche Welten sind die Nummern §c0§6 bis §c{0}§6.
|
||||
potionCommandDescription=Fügt einem Trank benutzerdefinierte Effekte hinzu.
|
||||
potionCommandUsage=/<command> <clear|apply|effect\:<Effekt> power\:<Stärke> duration\:<Dauer>>
|
||||
potionCommandUsage1=/<command> clear
|
||||
potionCommandUsage1Description=Entfernt alle Effekte vom in der Hand gehaltenen Trank
|
||||
potionCommandUsage2=/<command> beantragen
|
||||
potionCommandUsage2Description=Wirkt alle Effekte, des in der Hand gehaltenen Trankes, auf dich ohne den Trank zu verbrauchen
|
||||
potionCommandUsage3=/<command> effect\:<effect> power\:<power> duration\:<duration>
|
||||
potionCommandUsage3Description=Wendet die gegebenen Trank Metadaten auf den in der Hand gehaltenen Trank an
|
||||
posX=§6X\: {0} (+Ost <-> -West)
|
||||
posY=§6Y\: {0} (+Hoch <-> -Runter)
|
||||
posYaw=§6Yaw\: {0} (Drehung)
|
||||
@@ -862,12 +965,34 @@ powerToolsDisabled=§6All deine Powertools wurden deaktiviert.
|
||||
powerToolsEnabled=§6All deine Powertools wurden aktiviert.
|
||||
powertoolCommandDescription=Weist einem Gegenstand in der Hand einen Befehl zu.
|
||||
powertoolCommandUsage=/<command> [l\:|a\:|r\:|c\:|d\:][befehl] [argumente] - {player} kanm mit sem Namen eines geklickten Spielers ersetzt werden.
|
||||
powertoolCommandUsage1=/<command> l\:
|
||||
powertoolCommandUsage1Description=Listet alle Powertools für den aktuellen Gegenstand auf
|
||||
powertoolCommandUsage2=/<command> d\:
|
||||
powertoolCommandUsage2Description=Löscht alle Powertools auf dem gehaltenden Item
|
||||
powertoolCommandUsage3=/<command> r\:<cmd>
|
||||
powertoolCommandUsage3Description=Entfernt den angegebenen Befehl aus dem gehaltenen Item
|
||||
powertoolCommandUsage4=/<command> <cmd>
|
||||
powertoolCommandUsage4Description=Setzt den Powertool-Befehl des gehaltenen Items auf den angegebenen Befehl
|
||||
powertoolCommandUsage5=/<command> a\:<cmd>
|
||||
powertoolCommandUsage5Description=Fügt den Befehl Powertool zum gehaltenen Item hinzu
|
||||
powertooltoggleCommandDescription=Aktiviert oder deaktiert alle Powertools.
|
||||
powertooltoggleCommandUsage=/<command>
|
||||
ptimeCommandDescription=Client-Zeit des Spielers anpassen. @-Präfix zum Korrigieren hinzufügen.
|
||||
ptimeCommandUsage=/<command> [list|reset|day|night|dawn|17\:30|4pm|4000ticks] [Spieler|*]
|
||||
ptimeCommandUsage1=/<command> list [player|*]
|
||||
ptimeCommandUsage1Description=Gibt die Spielzeit für dich oder einen oder mehrere angegebene Spieler an
|
||||
ptimeCommandUsage2=/<command> <zeit> [spieler|*]
|
||||
ptimeCommandUsage2Description=Legt die Zeit für dich oder einen oder mehrere angegebene Spieler fest
|
||||
ptimeCommandUsage3=/<command> reset [spieler|*]
|
||||
ptimeCommandUsage3Description=Setzt die Zeit für dich oder andere Spieler zurück (falls angegeben)
|
||||
pweatherCommandDescription=Wetter eines Spielers anpassen
|
||||
pweatherCommandUsage=/<command> [list|reset|storm|sun|clear] [spieler|*]
|
||||
pweatherCommandUsage1=/<command> list [player|*]
|
||||
pweatherCommandUsage1Description=Listet das Wetter für dich oder andere Spieler auf, falls diese angegeben wurden
|
||||
pweatherCommandUsage2=/<command> <storm|sun> [Spieler|*]
|
||||
pweatherCommandUsage2Description=Legt das Wetter für dich oder andere Spieler(e) fest, wenn das Wetter angegeben wurde
|
||||
pweatherCommandUsage3=/<command> reset [spieler|*]
|
||||
pweatherCommandUsage3Description=Setzt das Wetter für dich oder andere Spieler zurück (falls angegeben)
|
||||
pTimeCurrent=§6Die Zeit für§c {0} §6ist§c {1}§6.
|
||||
pTimeCurrentFixed=§6Die Zeit für §c{0}§6 wurde auf §c{1}§6 gesetzt.
|
||||
pTimeNormal=§6Die Zeit für §c{0}§6 ist normal und entspricht der Serverzeit.
|
||||
@@ -887,17 +1012,21 @@ questionFormat=§2[Frage]§r {0}
|
||||
rCommandDescription=Antworte schnell auf den letzten Spieler, der dich benachrichtigt.
|
||||
rCommandUsage=/<command> <nachricht>
|
||||
rCommandUsage1=/<command> <nachricht>
|
||||
rCommandUsage1Description=Antwortet dem letzten Spieler, der dir eine Nachricht geschrieben hat, mit angegebenem Text
|
||||
radiusTooBig=§4Radius ist zu groß\! Maxmialer Radius beträgt§c {0}§4.
|
||||
readNextPage=§6Tippe§c /{0} {1} §6für die nächste Seite.
|
||||
realName=§f{0}§r§6 ist §f{1}
|
||||
realnameCommandDescription=Zeigt den Benutzernamen eines Spielers basierend auf dem Nick an.
|
||||
realnameCommandUsage=/<command> <spitzname>
|
||||
realnameCommandUsage1=/<command> <spitzname>
|
||||
realnameCommandUsage1Description=Zeigt den Benutzernamen eines Benutzers basierend auf dem angegebenen Nicknamen an
|
||||
recentlyForeverAlone=§4{0} ging vor kurzem Offline.
|
||||
recipe=§6Rezept für §c{0}§5 (§c{1}§6 von §c{2}§6)
|
||||
recipeBadIndex=Es gibt kein Rezept mit dieser Nummer.
|
||||
recipeCommandDescription=Zeigt, wie man Gegenstände herstellt.
|
||||
recipeCommandUsage=/<command> <gegenstand> [nummer]
|
||||
recipeCommandUsage1=/<command> <Gegenstand> [Seite]
|
||||
recipeCommandUsage1Description=Zeigt an, wie der Gegenstand gecraftet werden kann
|
||||
recipeFurnace=§6Schmelzen\: §c{0}§6.
|
||||
recipeGrid=§c{0}X §6| §{1}X §6| §{2}X
|
||||
recipeGridItem=§c{0}X §6ist §c{1}
|
||||
@@ -908,34 +1037,52 @@ recipeShapeless=§6Kombiniere §c{0}
|
||||
recipeWhere=§6Wo\: {0}
|
||||
removeCommandDescription=Entfernt Objekte in deiner Welt.
|
||||
removeCommandUsage=/<command> <all|tamed|named|drops|arrows|boats|minecarts|xp|paintings|itemframes|endercrystals|monsters|animals|ambient|mobs|[monstertyp]> [radius|welt]
|
||||
removeCommandUsage1=/<command> <Mob-Typ> [Welt]
|
||||
removeCommandUsage1Description=Entfernt alle angegebenen Mob-Typen in der aktuellen oder in einer anderen Welt, falls angegeben
|
||||
removeCommandUsage2=/<command> <mob type> <radius> [world]
|
||||
removeCommandUsage2Description=Entfernt den angegebenen Mob-Typ innerhalb des angegebenen Radius in der aktuellen oder in einer anderen Welt, wenn angegeben
|
||||
removed=§c{0} §6Einheiten entfernt.
|
||||
renamehomeCommandDescription=Benennt ein Haus um.
|
||||
renamehomeCommandUsage=/<command> <[Spieler\:]Name> <new name>
|
||||
renamehomeCommandUsage1=/<command> <name> <neuer name>
|
||||
renamehomeCommandUsage1Description=Bennt dein Home in den gegebenen Namen um
|
||||
renamehomeCommandUsage2=/<command> <spieler>\:<name> <neuer name>
|
||||
renamehomeCommandUsage2Description=Benennt das Haus des angegebenen Spielers um
|
||||
repair=§6Dein §c{0}§6 wurde erfolgreich repariert.
|
||||
repairAlreadyFixed=§4Dieser Gegenstand benötigt keine Reparatur.
|
||||
repairCommandDescription=Repariert die Haltbarkeit eines oder aller Gegenstände.
|
||||
repairCommandUsage=/<command> [hand|all]
|
||||
repairCommandUsage1=/<command>
|
||||
repairCommandUsage1Description=Repariert den gehaltenen Gegenstand
|
||||
repairCommandUsage2=/<command> all
|
||||
repairCommandUsage2Description=Repariere alle Items aus deinem Inventar
|
||||
repairEnchanted=§4Du darfst keine verzauberten Gegenstände reparieren.
|
||||
repairInvalidType=§4Dieser Gegenstand kann nicht repariert werden.
|
||||
repairNone=§4Es sind keine Gegenstände vorhanden, die repariert werden können.
|
||||
replyFromDiscord=**Antwort von {0}\:** {1}
|
||||
replyLastRecipientDisabled=§6Auf letzen Nachrichtenempfänger antworten §cdeaktiviert§6.
|
||||
replyLastRecipientDisabledFor=§6Auf den letzen Nachrichtenempfänger antworten für §c{0} §cdeaktiviert§6.
|
||||
replyLastRecipientEnabled=§cAuf den letzen Nachrichtenempfänger antworten §caktiviert§6.
|
||||
replyLastRecipientEnabledFor=§6Auf den letzen Nachrichtenempfänger antworten für §c{0} §caktiviert§6.
|
||||
requestAccepted=§7Du hast die Teleportierungsanfrage §aangenommen.
|
||||
requestAcceptedAll=§c{0} §6ausstehende Teleportationsanfrage(n) akzeptiert.
|
||||
requestAcceptedAuto=§6Teleportationsanfrage von {0} automatisch akzeptiert.
|
||||
requestAcceptedFrom=§c{0} §6hat deine Teleportierungsanfrage angenommen.
|
||||
requestAcceptedFromAuto=§c{0} §6hat deine Teleportationsanfrage automatisch angenommen.
|
||||
requestDenied=§6Du hast die Teleportierungsanfrage §cabgelehnt.
|
||||
requestDeniedAll=§c{0} §6ausstehende Teleportationsanfrage(n) abgelehnt.
|
||||
requestDeniedFrom=§c{0} §6hat deine Teleportierungsanfrage abgelehnt.
|
||||
requestSent=§6Eine Anfrage wurde an§c {0}§6 gesendet.
|
||||
requestSentAlready=§4Du hast {0}§4 bereits eine Teleportierungsanfrage gesendet.
|
||||
requestTimedOut=§4Die Teleportierungsanfrage ist abgelaufen.
|
||||
requestTimedOutFrom=§4Die Teleportierungsanfrage von §c{0} §4ist ausgelaufen.
|
||||
resetBal=§6Du hast den Kontostand aller Spieler auf §a{0} §6gesetzt.
|
||||
resetBalAll=§6Guthaben wurde für alle Spieler auf §c{0} zurückgesetzt.
|
||||
rest=§6Du fühlst dich gut ausgeruht.
|
||||
restCommandDescription=Ruht dich oder den gegebenen Spieler aus.
|
||||
restCommandUsage=/<command> [spieler]
|
||||
restCommandUsage1=/<command> [spieler]
|
||||
restCommandUsage1Description=Setzt die Zeit seit dem letzten Ausruhen für dich oder andere Spieler, falls angegeben, zurück
|
||||
restOther=§6Ausruhen§c {0}§6.
|
||||
returnPlayerToJailError=§4Fehler beim zurücksetzen von§c {0} §4im Gefängis\: {1}\!
|
||||
rtoggleCommandDescription=Ändere, ob der Empfänger der Antwort der letzte Empfänger oder der letzte Absender ist
|
||||
@@ -949,17 +1096,30 @@ seenAccounts=§6Spieler ist auch bekannt als\:§c {0}
|
||||
seenCommandDescription=Zeigt die letzte Abmeldezeit eines Spielers.
|
||||
seenCommandUsage=/<command> <spielername>
|
||||
seenCommandUsage1=/<command> <spielername>
|
||||
seenCommandUsage1Description=Zeigt die Logout-Zeit, Sperrung, Stummschaltung und UUID-Information des angegebenen Spielers an
|
||||
seenOffline=§6Spieler§c {0} §6ist seit §c{1}§4 offline§6.
|
||||
seenOnline=§6Spieler§c {0} §6ist seit §c{1}§a online.
|
||||
sellBulkPermission=§6Du hast keine Berechtigung, in Massen zu verkaufen.
|
||||
sellCommandDescription=Verkauft den Gegenstand, der momentan in deiner Hand ist.
|
||||
sellCommandUsage=/<command> <<itemname>|<id>|hand|inventory|blocks> [menge]
|
||||
sellCommandUsage1=/<command> <itemname> [amount]
|
||||
sellCommandUsage1Description=Verkauft alle (oder die angegebene Anzahl) des ausgewählten Items in deinem Inventar
|
||||
sellCommandUsage2=/<command> hand [amount]
|
||||
sellCommandUsage2Description=Verkauft alle (oder die angegebene Anzahl) des gehaltenen Items
|
||||
sellCommandUsage3=/<command> all
|
||||
sellCommandUsage3Description=Verkauft alle verkäuflichen Gegenstände in deinem Inventar
|
||||
sellCommandUsage4=/<command> blocks [amount]
|
||||
sellCommandUsage4Description=Verkauft alle (oder die angegebene Zahl, wenn angegeben) Blöcke in deinem Inventar
|
||||
sellHandPermission=§6Du hast keine Berechtigung, einzeln zu verkaufen.
|
||||
serverFull=Server ist voll\!
|
||||
serverReloading=Es gibt eine gute Chance, dass du den Server gerade reloadest. Falls das der Fall ist, wieso hasst du dich selber? Erwarte keine Unterstützung des EssentialsX-Teams wenn du /reload verwendest.
|
||||
serverTotal=§6Server insgesamt\:§c {0}
|
||||
serverUnsupported=§cDu verwendest eine Serverversion, die nicht unterstützt wird\!
|
||||
serverUnsupportedClass=Status-bestimmende Klasse\: {0}
|
||||
serverUnsupportedCleanroom=Sie betreiben einen Server, der Bukkit-Plugins nicht richtig unterstützt, die auf internen Mojang-Code angewiesen sind. Überlegen Sie sich, einen Essentials Ersatz für Ihre Server-Software zu verwenden.
|
||||
serverUnsupportedDangerous=Sie betreiben einen Server Fork, der als extrem gefährlich bekannt ist und zu Datenverlust führt. Es wird dringend empfohlen, zu einer stabileren Server-Software wie Papier zu wechseln.
|
||||
serverUnsupportedLimitedApi=Sie verwenden einen Server mit eingeschränkter API-Funktionalität. EssentialsX wird weiterhin funktionieren, aber bestimmte Funktionen können deaktiviert sein.
|
||||
serverUnsupportedDumbPlugins=Du verwendest Plugins, wo bekannt ist, dass diese schwerwiegende Probleme mit EssentialsX und anderen Plugins verursachen.
|
||||
serverUnsupportedMods=Du verwendest einen Server der Bukkit Plugins nicht korrekt unterstützt. Bukkit Plugins sollten nicht mit Forge/Fabric mods verwendet werden. Für Forge\: Überlege ForgeEssentials, oder SpongeForge + Nucleus zu verwenden.
|
||||
setBal=§aDein Kontostand wurde auf §c{0} §agesetzt.
|
||||
setBalOthers=§aDu hast den Kontostand von §6{0}§a auf §c{1} §a gesetzt.
|
||||
@@ -967,19 +1127,33 @@ setSpawner=§6Mob-Spawner-Typ geändert zu §c{0}§6.
|
||||
sethomeCommandDescription=Setze dein Zuhause auf deinen momentanen Standort.
|
||||
sethomeCommandUsage=/<command> [[spieler\:]name]
|
||||
sethomeCommandUsage1=/<command> <name>
|
||||
sethomeCommandUsage1Description=Setzte dein Home mit dem gegebenen Namen und deiner aktuellen Location fest
|
||||
sethomeCommandUsage2=/<command> <player>\:<name>
|
||||
sethomeCommandUsage2Description=Legt das Zuhause des angegebenen Spielers mit dem angegebenen Namen an deinem Standort fest
|
||||
setjailCommandDescription=Erstellt ein Gefängnis mit dem angegebenen Namen [gefängnisname].
|
||||
setjailCommandUsage=/<command> <gefängnisname>
|
||||
setjailCommandUsage1=/<command> <gefängnisname>
|
||||
setjailCommandUsage1Description=Legt das Gefängnis mit dem angegebenen Namen an deinen Standort fest
|
||||
settprCommandDescription=Lege die Ort der zufälligen Teleportierung und die Parameter fest.
|
||||
settprCommandUsage=/<command> [center|minrange|maxrange] [wert]
|
||||
settprCommandUsage1=/<command> center
|
||||
settprCommandUsage1Description=Legt die Mitte des Zufalls-Teleport auf deinen Standort fest
|
||||
settprCommandUsage2=/<command> minrange <radius>
|
||||
settprCommandUsage2Description=Legt den minimalen zufälligen Teleportradius auf den angegebenen Wert
|
||||
settprCommandUsage3=/<command> maxrange <radius>
|
||||
settprCommandUsage3Description=Legt den maximalen Teleportations-Radius fest
|
||||
settpr=§6Setze Zufallsteleportierungszentrum.
|
||||
settprValue=§6Setzte Zufallsteleport §c{0}§6 zu §c{1}§6.
|
||||
setwarpCommandDescription=Erstellt einen neuen Warp-Punkt.
|
||||
setwarpCommandUsage=/<command> <warp-punkt>
|
||||
setwarpCommandUsage1=/<command> <warp-punkt>
|
||||
setwarpCommandUsage1Description=Legt den Warp-Punkt mit dem angegebenen Namen an deinem Standort fest
|
||||
setworthCommandDescription=Setze den Verkaufswert eines Gegenstands.
|
||||
setworthCommandUsage=/<command> [itemname|id] <preis>
|
||||
setworthCommandUsage1=/<command> <preis>
|
||||
setworthCommandUsage1Description=Legt den Wert des gehaltenen Gegenstandes auf den angegebenen Preis fest
|
||||
setworthCommandUsage2=/<command> <itemname> <preis>
|
||||
setworthCommandUsage2Description=Legt den Verkaufswert des angegebenen Items zum angegebenen Preis fest
|
||||
sheepMalformedColor=§4Ungültige Farbe.
|
||||
shoutDisabled=§6Rufmodus §cdeaktiviert§6.
|
||||
shoutDisabledFor=§6Rufmodus §cdeaktiviert §6für §c{0}§6.
|
||||
@@ -991,13 +1165,25 @@ editsignCommandClearLine=§6Zeile §c{0}§6 geleert.
|
||||
showkitCommandDescription=Zeige Inhalte eines Kits.
|
||||
showkitCommandUsage=/<command> <kitname>
|
||||
showkitCommandUsage1=/<command> <kitname>
|
||||
showkitCommandUsage1Description=Zeigt eine Zusammenfassung der Gegenstände im angegebenen Kit an
|
||||
editsignCommandDescription=Bearbeitet ein Schild in der Welt.
|
||||
editsignCommandLimit=§4Dein eingegebener Text ist zu groß, um auf das Zielschild zu passen.
|
||||
editsignCommandNoLine=§4Du musst eine Zeilennummer zwischen §c1-4§4 eingeben.
|
||||
editsignCommandSetSuccess=§6Setze Linie§c {0}§6 zu "§c{1}§6".
|
||||
editsignCommandTarget=§4Du musst ein Schild anschauen, um seinen Text bearbeiten.
|
||||
editsignCopy=§6Schild kopiert\! Du kannst es nun mit §c/{0} paste§6 wieder einfügen.
|
||||
editsignCopyLine=§6Zeile §c{0} §6des Schildes kopiert\! Füge sie mit §c/{1} paste {0} §6ein.
|
||||
editsignPaste=§6Schild eingefügt\!
|
||||
editsignPasteLine=§6Zeile §c{0} §6vom Schild eigefügt\!
|
||||
editsignCommandUsage=/<command> <set/clear/copy/paste> [zeilennummer] [text]
|
||||
editsignCommandUsage1=/<command> set <zeilennummer> <text>
|
||||
editsignCommandUsage1Description=Setzt die angegebene Linie des Ziel-Schilds auf den angegebenen Text
|
||||
editsignCommandUsage2=/<command> clear <zeilennummer>
|
||||
editsignCommandUsage2Description=Leert die angegebene Zeile von dem Zielschild
|
||||
editsignCommandUsage3=/<command> copy [zeilennummer]
|
||||
editsignCommandUsage3Description=Kopiert alle (oder die angegebene) Zeile(n) des anvisierten Schildes in die Zwischenablage
|
||||
editsignCommandUsage4=/<command> paste [zeilennummer]
|
||||
editsignCommandUsage4Description=Fügt die Zwischenablage komplett (oder in die angegebene Zeile) des anvisierten Schildes ein
|
||||
signFormatFail=§4[{0}]
|
||||
signFormatSuccess=§1[{0}]
|
||||
signFormatTemplate=[{0}]
|
||||
@@ -1010,7 +1196,9 @@ skullChanged=§6Kopf zu §c{0} §6geändert.
|
||||
skullCommandDescription=Setze den Besitzer eines Spielerkopfes
|
||||
skullCommandUsage=/<command> [besitzer]
|
||||
skullCommandUsage1=/<command>
|
||||
skullCommandUsage1Description=Ruft deinen eigenen Spielerkopf ab
|
||||
skullCommandUsage2=/<command> <spieler>
|
||||
skullCommandUsage2Description=Ruft den Kopf des angegebenen Spielers ab
|
||||
slimeMalformedSize=§4Ungültige Größe.
|
||||
smithingtableCommandDescription=Öffnet einen Schmiedetisch.
|
||||
smithingtableCommandUsage=/<command>
|
||||
@@ -1032,6 +1220,8 @@ spawnSet=§6Du hast denSpawn-Punkt für die Gruppe§c {0}§6 gesetzt.
|
||||
spectator=Zuschauermodus
|
||||
speedCommandDescription=Ändere deine Geschwindigkeitsbegrenzungen.
|
||||
speedCommandUsage=/<command> [typ] <geschwindigkeit> [spieler]
|
||||
speedCommandUsage1Description=Legt entweder deine Flug- oder Laufgeschwindigkeit auf den angegebenen Wert fest
|
||||
speedCommandUsage2Description=Setzt entweder den angegebenen Geschwindigkeittyp auf die angegebene Geschwindigkeit für dich oder einen anderen Spieler wenn angegeben
|
||||
stonecutterCommandDescription=Öffnet eine Steinsäge.
|
||||
stonecutterCommandUsage=/<command>
|
||||
sudoCommandDescription=Lasse einen anderen Benutzer einen Befehl ausführen.
|
||||
@@ -1069,26 +1259,32 @@ teleportRequestTimeoutInfo=§6Diese Anfrage wird nach§c {0} Sekunden§6 ungült
|
||||
teleportTop=§6Zum höchsten Punkt teleportieren.
|
||||
teleportToPlayer=§6Du teleportierst dich zu §c{0}§6.
|
||||
teleportOffline=§6Der Spieler §c{0}§6 ist gerade offline. Du kannst dich mit /otp zu ihm teleportieren.
|
||||
teleportOfflineUnknown=§6Die letzte bekannte Position von §c{0}§ 6 konnte nicht gefunden werden.
|
||||
tempbanExempt=§4Du kannst diesen Spieler nicht temporär bannen.
|
||||
tempbanExemptOffline=\\u00a74Du darfst Spieler, die offline sind, nicht tempor\\u00e4r bannen.
|
||||
tempbanJoin=§4Du bist auf diesem Server gesperrt. \nDauer\: {0}\nGrund\: {1}
|
||||
tempBanned=§cDu bist für§r {0}§c temporär gesperrt\:\n§r{2}
|
||||
tempbanCommandDescription=Temporäres Speeren eines Benutzers.
|
||||
tempbanCommandUsage1=/<command> <Spieler> <Länge> [Grund]
|
||||
tempbanCommandUsage1Description=Bannt den gegebenen Spieler für die angegebene Zeit mit einem optionalen Grund
|
||||
tempbanipCommandDescription=Temporäres Sperren einer IP-Adresse.
|
||||
thunder=§6Es donnert jetzt in deiner Welt §c{0}§6.
|
||||
thunderCommandDescription=Aktiviere/deaktiviere Thunder.
|
||||
thunderCommandUsage=/<command> <true/false> [länge]
|
||||
thunderCommandUsage1Description=Aktiviert/deaktiviert Donner (ggf. für eine bestimmte Zeit)
|
||||
thunderDuration=§6Es donnert jetzt für§c {1} §6Sekunden in der Welt§c {0}§6.
|
||||
timeBeforeHeal=§4Zeit bis zur nächsten Heilung\:§c {0}§4.
|
||||
timeBeforeTeleport=§4Zeit bis zum nächsten Teleport\:§c {0}§4.
|
||||
timeCommandDescription=Zeige/Ändere die Zeit der Welt. Standardmäßig die aktuelle Welt.
|
||||
timeCommandUsage=/<command> [set|add] [day|night|dawn|17\:30|4pm|4000ticks] [weltname|all]
|
||||
timeCommandUsage1=/<command>
|
||||
timeCommandUsage1Description=Zeigt die Zeit in allen Welten an
|
||||
timeFormat=§c{0}§6 oder §c{1}§6 oder §c{2}§6
|
||||
timeSetPermission=§4Du hast keine Berechtigung die Zeit zu ändern.
|
||||
timeSetWorldPermission=§4Du bist nicht berechtigt in der Welt §c''{0}''§4 die Zeit zu ändern.
|
||||
timeWorldAdd=§6Die Zeit wurde in §c{1}§6 um§c {0} §6verschoben.
|
||||
timeWorldCurrent=§6Die aktuelle Zeit in§c {0} §6ist §c{1}
|
||||
timeWorldCurrentSign=§6Gerade ist es §c{0}&6 Uhr.
|
||||
timeWorldSet=§6Die Zeit in §c{1}§6 wurde auf §c{0} §6gesetzt.
|
||||
togglejailCommandDescription=Nimmt einen Spieler gefangen oder lässt ihn frei, teleportiert ihn zu dem angegebenen Gefängnis.
|
||||
togglejailCommandUsage=/<command> <spieler> <gefängnisname> [datumsdifferenz]
|
||||
@@ -1104,20 +1300,28 @@ totalWorthBlocks=§aDu hast alle Blöcke für einen Gesamtwert von §c{1}§a ver
|
||||
tpCommandDescription=Zu einem Spieler teleportieren.
|
||||
tpCommandUsage=/<command> <spieler> [andererspieler]
|
||||
tpCommandUsage1=/<command> <spieler>
|
||||
tpCommandUsage1Description=Teleportiert dich zu dem angegebenen Spieler
|
||||
tpCommandUsage2Description=Teleportiert den ersten angegebenen Spieler zum zweiten
|
||||
tpaCommandDescription=Anfrage zu dem angegebenen Spieler zu Teleportieren.
|
||||
tpaCommandUsage=/<command> <spieler>
|
||||
tpaCommandUsage1=/<command> <spieler>
|
||||
tpaCommandUsage1Description=Fragt eine Teleportation zum angegebenen Spieler an
|
||||
tpaallCommandDescription=Fragt alle anwesenden Spieler, ob sie sich zu dir teleportieren wollen.
|
||||
tpaallCommandUsage=/<command> <spieler>
|
||||
tpaallCommandUsage1=/<command> <spieler>
|
||||
tpaallCommandUsage1Description=Fragt einen Teleport an alle Spieler an
|
||||
tpacancelCommandDescription=Alle ausstehenden Teleportierungsanfragen abbrechen. [player] spezifizieren um Anfragen mit ihm abzubrechen.
|
||||
tpacancelCommandUsage=/<command> [spieler]
|
||||
tpacancelCommandUsage1=/<command>
|
||||
tpacancelCommandUsage1Description=Bricht alle deine Teleport-Anfragen ab
|
||||
tpacancelCommandUsage2=/<command> <spieler>
|
||||
tpacancelCommandUsage2Description=Bricht die Teleport-Anfrage mit dem angegebenen Spieler ab
|
||||
tpacceptCommandDescription=Akteptiert Teleportationsanfragen.
|
||||
tpacceptCommandUsage=/<command> [andererspieler]
|
||||
tpacceptCommandUsage1=/<command>
|
||||
tpacceptCommandUsage2=/<command> <spieler>
|
||||
tpacceptCommandUsage3=/<command> *
|
||||
tpacceptCommandUsage3Description=Akzeptiert alle Teleportationsanfragen
|
||||
tpahereCommandDescription=Bittet den angegebenen Spieler, sich zu dir zu teleportieren.
|
||||
tpahereCommandUsage=/<command> <spieler>
|
||||
tpahereCommandUsage1=/<command> <spieler>
|
||||
@@ -1127,6 +1331,7 @@ tpallCommandUsage1=/<command> [spieler]
|
||||
tpautoCommandDescription=Akzeptiere Teleportationsanfragen automatisch.
|
||||
tpautoCommandUsage=/<command> [spieler]
|
||||
tpautoCommandUsage1=/<command> [spieler]
|
||||
tpdenyCommandDescription=Lehnt Teleportations-Anfragen ab.
|
||||
tpdenyCommandUsage=/<command>
|
||||
tpdenyCommandUsage1=/<command>
|
||||
tpdenyCommandUsage2=/<command> <spieler>
|
||||
@@ -1174,6 +1379,7 @@ unbanCommandUsage1=/<command> <spieler>
|
||||
unbanipCommandDescription=Enbannt die angegebene IP-Adresse.
|
||||
unbanipCommandUsage=/<command> <adresse>
|
||||
unbanipCommandUsage1=/<command> <adresse>
|
||||
unbanipCommandUsage1Description=Entbannt die angegebene IP-Adresse
|
||||
unignorePlayer=§6Du ignorierst §c{0} §6nicht mehr.
|
||||
unknownItemId=§4Unbekannte Gegenstandsnummer\:§r {0}§4.
|
||||
unknownItemInList=§4Unbekannter Gegenstand {0} in der Liste {1}.
|
||||
@@ -1182,6 +1388,10 @@ unlimitedCommandDescription=Erlaubt das unbegrenzte Platzieren von Gegenständen
|
||||
unlimitedCommandUsage=/<command> <list|item|clear> [spieler]
|
||||
unlimitedItemPermission=\\u00a74Keine Berechtigung f\\u00fcr unendliche Items \\u00a7c{0}\\u00a74.
|
||||
unlimitedItems=§6Unbegrenzte Objekte\:§r
|
||||
unlinkCommandDescription=Löscht die Verbindung deines Minecraft-Accounts zu deinem Discord-Account.
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unlinkCommandUsage1Description=Löscht die Verbindung deines Minecraft-Accounts zu deinem Discord-Account.
|
||||
unmutedPlayer=§6Spieler§c {0}§6 ist nicht mehr stummgeschaltet.
|
||||
unsafeTeleportDestination=§4Das Teleport-Ziel ist nicht sicher und der Teleportschutz ist nicht aktiv.
|
||||
unsupportedBrand=§4Die Server-Plattform, die die momentan verwendest, bietet die Möglichkeiten für diese Funktion nicht an.
|
||||
@@ -1216,6 +1426,8 @@ versionOutputUnsupported=§d{0} §6Version\: §d{1}
|
||||
versionOutputUnsupportedPlugins=§6Du verwendest Plugins, die§d nicht§6 unterstützt werden\!
|
||||
versionMismatch=§4Versionen sind nicht gleich\! Bitte aktualisiere {0}.
|
||||
versionMismatchAll=§4Versionen sind nicht gleich\! Bitte aktualisiere alle Essentials jar-Dateien auf die gleiche Version.
|
||||
versionReleaseLatest=§6Du nutzt die neuste stable Version von EssentialsX\!
|
||||
versionReleaseNew=§4Es steht eine neue Version von EssentialsX zum download\: §c{0}§4.
|
||||
versionReleaseNewLink=§4Hier herunterladen\:§c {0}
|
||||
voiceSilenced=§6Du bist nun stummgeschaltet\!
|
||||
voiceSilencedTime=§6Deine Stimme wurde für {0} zum Schweigen gebracht\!
|
||||
@@ -1225,11 +1437,14 @@ walking=gehend
|
||||
warpCommandDescription=Zeige alle Warp-Punkte an oder warpe zum angegebenen Ort.
|
||||
warpCommandUsage=/<command> <seitennummer|warp-punkt> [spieler]
|
||||
warpCommandUsage1=/<command> [page]
|
||||
warpCommandUsage2=/<command> <warp> [spieler]
|
||||
warpCommandUsage2Description=Teleportiert dich oder einen bestimmten Spieler zu dem angegebenen Warp
|
||||
warpDeleteError=§4Beim Löschen der Warp-Datei ist ein Fehler aufgetreten.
|
||||
warpInfo=§6Informationen für Warp§c {0}§6\:
|
||||
warpinfoCommandDescription=Findet Standortinformationen für einen bestimmten Warp.
|
||||
warpinfoCommandUsage=/<command> <warp-punkt>
|
||||
warpinfoCommandUsage1=/<command> <warp-punkt>
|
||||
warpinfoCommandUsage1Description=Gibt Informationen zum angegebenen Warp an
|
||||
warpingTo=§6Warpe zu§c {0}§6.
|
||||
warpList={0}
|
||||
warpListPermission=§4Du hast keine Rechte, die Warp-Punkte anzuzeigen.
|
||||
@@ -1239,9 +1454,13 @@ warps=§6Warp-Punkte\:§r {0}
|
||||
warpsCount=§6Es existieren§c {0}§6 Warp-Punkte. Zeige§c {1}§6 von§c {2}§6 an.
|
||||
weatherCommandDescription=Legt das Wetter fest.
|
||||
weatherCommandUsage=/<command> <storm/sun> [duration]
|
||||
weatherCommandUsage1=/<command> <storm|sun> [dauer]
|
||||
weatherCommandUsage1Description=Setzte das Wetter auf den gegebenen Typ für eine optionale Dauer
|
||||
warpSet=§6Warp§c {0}§6 wurde erstellt.
|
||||
warpUsePermission=\\u00a74Du hast f\\u00fcr diesen Warp keine Rechte.
|
||||
weatherInvalidWorld=Die Welt mit dem Namen {0} wurde nicht gefunden\!
|
||||
weatherSignStorm=§6Wetter\: §cstürmig§6.
|
||||
weatherSignSun=§6Wetter\: §csonnig§6.
|
||||
weatherStorm=§6In §c{0} §6stürmt es jetzt.
|
||||
weatherStormFor=§6Du hast das Wetter zu §cSturm§6 in§c {0}§6 für §c{1} Sekunden §6gesetzt.
|
||||
weatherSun=§6In §c{0}§6 scheint jetzt die §cSonne§6.
|
||||
@@ -1253,6 +1472,7 @@ whoisBanned=§6 - Gesperrt\:§r {0}
|
||||
whoisCommandDescription=Finde heraus, welcher Benutzername hinter einem Spitznamen steckt.
|
||||
whoisCommandUsage=/<command> <spitzname>
|
||||
whoisCommandUsage1=/<command> <spieler>
|
||||
whoisCommandUsage1Description=Gibt grundlegende Informationen über den angegebenen Spieler
|
||||
whoisExp=§6 - Erfahrung\:§r {0} (Level {1})
|
||||
whoisFly=§6 - Flugmodus\:§r {0} ({1})
|
||||
whoisSpeed=§6 - Geschwindigkeit\:§r {0}
|
||||
@@ -1278,9 +1498,16 @@ workbenchCommandUsage=/<command>
|
||||
worldCommandDescription=Zwischen Welten wechseln.
|
||||
worldCommandUsage=/<command> [world]
|
||||
worldCommandUsage1=/<command>
|
||||
worldCommandUsage1Description=Teleportiert dich an den entsprechenden Standort im Nether oder in der Oberwelt
|
||||
worldCommandUsage2=/<command> <welt>
|
||||
worldCommandUsage2Description=Teleportiert dich zu einer Location in der gegebenen Welt
|
||||
worth=§aEin Stapel {0} ist §c{1}§a wert. ({2} Stück je {3})
|
||||
worthCommandDescription=Berechnet den Wert der Gegenstände in der Hand oder wie angegeben.
|
||||
worthCommandUsage=/<command> <<gegenstandsname>|<id>|hand|inventory|blocks> [-][anzahl]
|
||||
worthCommandUsage1=/<command> <itemname> [amount]
|
||||
worthCommandUsage2=/<command> hand [amount]
|
||||
worthCommandUsage3=/<command> all
|
||||
worthCommandUsage4=/<command> blocks [amount]
|
||||
worthMeta=§aEin Stapel von {0} mit Metadaten {1} ist §c{2}§a wert. ({3} Stück je {4})
|
||||
worthSet=§6Wert des Gegenstands gesetzt.
|
||||
year=Jahr
|
||||
|
||||
@@ -83,6 +83,7 @@ bookCommandUsage3=/<command> title <title>
|
||||
bookCommandUsage3Description=Ορίζει τον τίτλο ενός υπογεγραμμένου βιβλίου
|
||||
bookLocked=§6Αυτό το βιβλίο είναι τώρα κλειδωμένο.
|
||||
bookTitleSet=§6Τίτλος του βιβλίου ορίστηκε σε {0}.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Σπάει το μπλοκ που κοιτάτε.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Ανακοίνωση§6]§a {0}
|
||||
@@ -272,6 +273,8 @@ kitReceive=§6Πήρες το kit§c {0}§6.
|
||||
kittycannonCommandUsage=/<command>
|
||||
kitTimed=§4Δεν μπορείς να ξανά χρησιμοποιήσεις αυτό το kit μέχρι§c {0}§4.
|
||||
lightningCommandUsage1=/<command> [παίκτης]
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
loomCommandUsage=/<command>
|
||||
minute=λεπτό
|
||||
minutes=λεπτά
|
||||
@@ -324,6 +327,8 @@ tpdenyCommandUsage1=/<command>
|
||||
tprCommandUsage=/<command>
|
||||
tprCommandUsage1=/<command>
|
||||
tptoggleCommandUsage1=/<command> [παίκτης]
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
vanishCommandUsage1=/<command> [παίκτης]
|
||||
walking=περπάτημα
|
||||
warpCommandUsage1=/<command> [σελίδα]
|
||||
|
||||
@@ -100,6 +100,8 @@ bookCommandUsage3=/<command> title <title>
|
||||
bookCommandUsage3Description=Sets the title of a signed book
|
||||
bookLocked=§6This book is now locked.
|
||||
bookTitleSet=§6Title of the book set to {0}.
|
||||
bottomCommandDescription=Teleport to the lowest block at your current position.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Breaks the block you are looking at.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Broadcast§6]§a {0}
|
||||
@@ -240,6 +242,12 @@ discordbroadcastCommandUsage1Description=Sends the given message to the specifie
|
||||
discordbroadcastInvalidChannel=§4Discord channel §c{0}§4 does not exist.
|
||||
discordbroadcastPermission=§4You do not have permission to send messages to the §c{0}§4 channel.
|
||||
discordbroadcastSent=§6Message sent to §c{0}§6\!
|
||||
discordCommandAccountArgumentUser=The Discord account to look up
|
||||
discordCommandAccountDescription=Looks up the linked Minecraft account for either yourself or another Discord user
|
||||
discordCommandAccountResponseLinked=Your account is linked to the Minecraft account\: **{0}**
|
||||
discordCommandAccountResponseLinkedOther={0}''s account is linked to the Minecraft account\: **{1}**
|
||||
discordCommandAccountResponseNotLinked=You do not have a linked Minecraft account.
|
||||
discordCommandAccountResponseNotLinkedOther={0} does not have a linked Minecraft account.
|
||||
discordCommandDescription=Sends the Discord invite link to the player.
|
||||
discordCommandLink=§6Join our Discord server at §c{0}§6\!
|
||||
discordCommandUsage=/<command>
|
||||
@@ -248,12 +256,20 @@ discordCommandUsage1Description=Sends the Discord invite link to the player
|
||||
discordCommandExecuteDescription=Executes a console command on the Minecraft server.
|
||||
discordCommandExecuteArgumentCommand=The command to be executed
|
||||
discordCommandExecuteReply=Executing command\: "/{0}"
|
||||
discordCommandUnlinkDescription=Unlinks the Minecraft account currently linked to your Discord account
|
||||
discordCommandUnlinkInvalidCode=You do not currently have a Minecraft account linked to Discord\!
|
||||
discordCommandUnlinkUnlinked=Your Discord account has been unlinked from all associated Minecraft accounts.
|
||||
discordCommandLinkArgumentCode=The code provided in-game to link your Minecraft account
|
||||
discordCommandLinkDescription=Links your Discord account with your Minecraft account using a code from the in-game /link command
|
||||
discordCommandLinkHasAccount=You already have an account linked\! To unlink your current account, type /unlink.
|
||||
discordCommandLinkInvalidCode=Invalid linking code\! Make sure you''ve run /link in-game and copied the code correctly.
|
||||
discordCommandLinkLinked=Successfully linked your account\!
|
||||
discordCommandListDescription=Gets a list of online players.
|
||||
discordCommandListArgumentGroup=A specific group to limit your search by
|
||||
discordCommandMessageDescription=Messages a player on the Minecraft server.
|
||||
discordCommandMessageArgumentUsername=The player to send the message to
|
||||
discordCommandMessageArgumentMessage=The message to send to the player
|
||||
discordErrorCommand=You added your bot to your server incorrectly. Please follow the tutorial in the config and add your bot using https\://essentialsx.net/discord.html\!
|
||||
discordErrorCommand=You added your bot to your server incorrectly\! Please follow the tutorial in the config and add your bot using https\://essentialsx.net/discord.html
|
||||
discordErrorCommandDisabled=That command is disabled\!
|
||||
discordErrorLogin=An error occurred while logging into Discord, which has caused the plugin to disable itself\: \n{0}
|
||||
discordErrorLoggerInvalidChannel=Discord console logging has been disabled due to an invalid channel definition\! If you intend to disable it, set the channel ID to "none"; otherwise check that your channel ID is correct.
|
||||
@@ -265,8 +281,20 @@ discordErrorNoPrimary=You did not define a primary channel or your defined prima
|
||||
discordErrorNoPrimaryPerms=Your bot cannot speak in your primary channel, \#{0}. Please make sure your bot has read and write permissions in all channels you wish to use.
|
||||
discordErrorNoToken=No token provided\! Please follow the tutorial in the config in order to setup the plugin.
|
||||
discordErrorWebhook=An error occurred while sending messages to your console channel\! This was likely caused by accidentally deleting your console webhook. This can usually by fixed by ensuring your bot has the "Manage Webhooks" permission and running "/ess reload".
|
||||
discordLinkInvalidGroup=Invalid group {0} was provided for role {1}. The following groups are available\: {2}
|
||||
discordLinkInvalidRole=An invalid role ID, {0}, was provided for group\: {1}. You can see the ID of roles with the /roleinfo command in Discord.
|
||||
discordLinkInvalidRoleInteract=The role, {0} ({1}), cannot be used for group->role synchronization because it above your bot''s uppermost role. Either move your bot''s role above "{0}" or move "{0}" below your bot''s role.
|
||||
discordLinkInvalidRoleManaged=The role, {0} ({1}), cannot be used for group->role synchronization because it is managed by another bot or integration.
|
||||
discordLinkLinked=§6To link your Minecraft account to Discord, type §c{0} §6in the Discord server.
|
||||
discordLinkLinkedAlready=§6You have already linked your Discord account\! If you wish to unlink your discord account use §c/unlink§6.
|
||||
discordLinkLoginKick=§6You must link your Discord account before you can join this server.\n§6To link your Minecraft account to Discord, type\:\n§c{0}\n§6in this server''s Discord server\:\n§c{1}
|
||||
discordLinkLoginPrompt=§6You must link your Discord account before you can move, chat on or interact with this server. To link your Minecraft account to Discord, type §c{0} §6in this server''s Discord server\: §c{1}
|
||||
discordLinkNoAccount=§6You do not currently have a Discord account linked to your Minecraft account.
|
||||
discordLinkPending=§6You already have a link code. To complete linking your Minecraft account to Discord, type §c{0} §6in the Discord server.
|
||||
discordLinkUnlinked=§6Unlinked your Minecraft account from all associated discord accounts.
|
||||
discordLoggingIn=Attempting to login to Discord...
|
||||
discordLoggingInDone=Successfully logged in as {0}
|
||||
discordMailLine=**New mail from {0}\:** {1}
|
||||
discordNoSendPermission=Cannot send message in channel\: \#{0} Please ensure the bot has "Send Messages" permission in that channel\!
|
||||
discordReloadInvalid=Tried to reload EssentialsX Discord config while the plugin is in an invalid state\! If you''ve modified your config, restart your server.
|
||||
disposal=Disposal
|
||||
@@ -314,6 +342,7 @@ enderchestCommandUsage2=/<command> <player>
|
||||
enderchestCommandUsage2Description=Opens the ender chest of the target player
|
||||
errorCallingCommand=Error calling the command /{0}
|
||||
errorWithMessage=§cError\:§4 {0}
|
||||
essChatNoSecureMsg=EssentialsX Chat version {0} does not support secure chat on this server software. Update EssentialsX, and if this issue persists, inform the developers.
|
||||
essentialsCommandDescription=Reloads essentials.
|
||||
essentialsCommandUsage=/<command>
|
||||
essentialsCommandUsage1=/<command> reload
|
||||
@@ -481,6 +510,7 @@ homeCommandUsage2=/<command> <player>\:<name>
|
||||
homeCommandUsage2Description=Teleports you to the specified player''s home with the given name
|
||||
homes=§6Homes\:§r {0}
|
||||
homeConfirmation=§6You already have a home named §c{0}§6\!\nTo overwrite your existing home, type the command again.
|
||||
homeRenamed=§6Home §c{0} §6has been renamed to §c{1}§6.
|
||||
homeSet=§6Home set to current location.
|
||||
hour=hour
|
||||
hours=hours
|
||||
@@ -533,6 +563,7 @@ invseeCommandDescription=See the inventory of other players.
|
||||
invseeCommandUsage=/<command> <player>
|
||||
invseeCommandUsage1=/<command> <player>
|
||||
invseeCommandUsage1Description=Opens the inventory of the specified player
|
||||
invseeNoSelf=§cYou can only view other players'' inventories.
|
||||
is=is
|
||||
isIpBanned=§6IP §c{0} §6is banned.
|
||||
internalError=§cAn internal error occurred while attempting to perform this command.
|
||||
@@ -589,7 +620,7 @@ jailList=§6Jails\:§r {0}
|
||||
jailMessage=§4You do the crime, you do the time.
|
||||
jailNotExist=§4That jail does not exist.
|
||||
jailNotifyJailed=§6Player§c {0} §6jailed by §c{1}.
|
||||
jailNotifyJailedFor=§6Player§c {0} §6jailed for§c {1}§6by §c{2}§6.
|
||||
jailNotifyJailedFor=§6Player§c {0} §6jailed for§c {1} §6by §c{2}§6.
|
||||
jailNotifySentenceExtended=§6Player§c{0}§6''s jail time extended to §c{1} §6by §c{2}§6.
|
||||
jailReleased=§6Player §c{0}§6 unjailed.
|
||||
jailReleasedPlayerNotify=§6You have been released\!
|
||||
@@ -658,6 +689,10 @@ lightningCommandUsage2=/<command> <player> <power>
|
||||
lightningCommandUsage2Description=Strikes lighting at the target player with the given power
|
||||
lightningSmited=§6Thou hast been smitten\!
|
||||
lightningUse=§6Smiting§c {0}
|
||||
linkCommandDescription=Generates a code to link your Minecraft account to Discord.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
linkCommandUsage1Description=Generates a code for the /link command on Discord
|
||||
listAfkTag=§7[AFK]§r
|
||||
listAmount=§6There are §c{0}§6 out of maximum §c{1}§6 players online.
|
||||
listAmountHidden=§6There are §c{0}§6/§c{1}§6 out of maximum §c{2}§6 players online.
|
||||
@@ -1007,6 +1042,12 @@ removeCommandUsage1Description=Removes all of the given mob type in the current
|
||||
removeCommandUsage2=/<command> <mob type> <radius> [world]
|
||||
removeCommandUsage2Description=Removes the given mob type within the given radius in the current world or another one if specified
|
||||
removed=§6Removed§c {0} §6entities.
|
||||
renamehomeCommandDescription=Renames a home.
|
||||
renamehomeCommandUsage=/<command> <[player\:]name> <new name>
|
||||
renamehomeCommandUsage1=/<command> <name> <new name>
|
||||
renamehomeCommandUsage1Description=Renames your home to the given name
|
||||
renamehomeCommandUsage2=/<command> <player>\:<name> <new name>
|
||||
renamehomeCommandUsage2Description=Renames the specified player''s home to the given name
|
||||
repair=§6You have successfully repaired your\: §c{0}§6.
|
||||
repairAlreadyFixed=§4This item does not need repairing.
|
||||
repairCommandDescription=Repairs the durability of one or all items.
|
||||
@@ -1018,7 +1059,7 @@ repairCommandUsage2Description=Repairs all items in your inventory
|
||||
repairEnchanted=§4You are not allowed to repair enchanted items.
|
||||
repairInvalidType=§4This item cannot be repaired.
|
||||
repairNone=§4There were no items that needed repairing.
|
||||
replyFromDiscord=**Reply from {0}\:** `{1}`
|
||||
replyFromDiscord=**Reply from {0}\:** {1}
|
||||
replyLastRecipientDisabled=§6Replying to last message recipient §cdisabled§6.
|
||||
replyLastRecipientDisabledFor=§6Replying to last message recipient §cdisabled §6for §c{0}§6.
|
||||
replyLastRecipientEnabled=§6Replying to last message recipient §cenabled§6.
|
||||
@@ -1076,7 +1117,9 @@ serverTotal=§6Server Total\:§c {0}
|
||||
serverUnsupported=You are running an unsupported server version\!
|
||||
serverUnsupportedClass=Status determining class\: {0}
|
||||
serverUnsupportedCleanroom=You are running a server that does not properly support Bukkit plugins that rely on internal Mojang code. Consider using an Essentials replacement for your server software.
|
||||
serverUnsupportedDangerous=You are running a server fork that is known to be extremely dangerous and lead to data loss. It is strongly recommended you switch to a more stable server software like Paper.
|
||||
serverUnsupportedLimitedApi=You are running a server with limited API functionality. EssentialsX will still work, but certain features may be disabled.
|
||||
serverUnsupportedDumbPlugins=You are using plugins known to cause severe issues with EssentialsX and other plugins.
|
||||
serverUnsupportedMods=You are running a server that does not properly support Bukkit plugins. Bukkit plugins should not be used with Forge/Fabric mods\! For Forge\: Consider using ForgeEssentials, or SpongeForge + Nucleus.
|
||||
setBal=§aYour balance was set to {0}.
|
||||
setBalOthers=§aYou set {0}§a''s balance to {1}.
|
||||
@@ -1211,6 +1254,7 @@ teleportationDisabledWarning=§6You must enable teleportation before other playe
|
||||
teleportationEnabled=§6Teleportation §cenabled§6.
|
||||
teleportationEnabledFor=§6Teleportation §cenabled §6for §c{0}§6.
|
||||
teleportAtoB=§c{0}§6 teleported you to §c{1}§6.
|
||||
teleportBottom=§6Teleporting to bottom.
|
||||
teleportDisabled=§c{0} §4has teleportation disabled.
|
||||
teleportHereRequest=§c{0}§6 has requested that you teleport to them.
|
||||
teleportHome=§6Teleporting to §c{0}§6.
|
||||
@@ -1226,6 +1270,7 @@ teleportRequestTimeoutInfo=§6This request will timeout after§c {0} seconds§6.
|
||||
teleportTop=§6Teleporting to top.
|
||||
teleportToPlayer=§6Teleporting to §c{0}§6.
|
||||
teleportOffline=§6The player §c{0}§6 is currently offline. You are able to teleport to them using /otp.
|
||||
teleportOfflineUnknown=§6Unable to find the last known position of §c{0}§6.
|
||||
tempbanExempt=§4You may not tempban that player.
|
||||
tempbanExemptOffline=§4You may not tempban offline players.
|
||||
tempbanJoin=You are banned from this server for {0}. Reason\: {1}
|
||||
@@ -1390,6 +1435,10 @@ unlimitedCommandUsage3=/<command> clear [player]
|
||||
unlimitedCommandUsage3Description=Clears all unlimited items for yourself or another player if specified
|
||||
unlimitedItemPermission=§4No permission for unlimited item §c{0}§4.
|
||||
unlimitedItems=§6Unlimited items\:§r
|
||||
unlinkCommandDescription=Unlinks your Minecraft account from the currently linked Discord account.
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unlinkCommandUsage1Description=Unlinks your Minecraft account from the currently linked Discord account.
|
||||
unmutedPlayer=§6Player§c {0} §6unmuted.
|
||||
unsafeTeleportDestination=§4The teleport destination is unsafe and teleport-safety is disabled.
|
||||
unsupportedBrand=§4The server platform you are currently running does not provide the capabilities for this feature.
|
||||
@@ -1410,6 +1459,9 @@ userIsAwaySelf=§7You are now AFK.
|
||||
userIsAwaySelfWithMessage=§7You are now AFK.
|
||||
userIsNotAwaySelf=§7You are no longer AFK.
|
||||
userJailed=§6You have been jailed\!
|
||||
usermapEntry=§c{0} §6is mapped to §c{1}§6.
|
||||
usermapPurge=§6Checking for files in userdata that are not mapped, results will be logged to console. Destructive Mode\: {0}
|
||||
usermapSize=§6Current cached users in user map is §c{0}§6/§c{1}§6/§c{2}§6.
|
||||
userUnknown=§4Warning\: The user ''§c{0}§4'' has never joined this server.
|
||||
usingTempFolderForTesting=Using temp folder for testing\:
|
||||
vanish=§6Vanish for {0}§6\: {1}
|
||||
|
||||
@@ -100,6 +100,8 @@ bookCommandUsage3=/<command> title <title>
|
||||
bookCommandUsage3Description=Sets the title of a signed book
|
||||
bookLocked=§6This book is now locked.
|
||||
bookTitleSet=§6Title of the book set to {0}.
|
||||
bottomCommandDescription=Teleport to the lowest block at your current position.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Breaks the block you are looking at.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Broadcast§6]§a {0}
|
||||
@@ -240,6 +242,12 @@ discordbroadcastCommandUsage1Description=Sends the given message to the specifie
|
||||
discordbroadcastInvalidChannel=§4Discord channel §c{0}§4 does not exist.
|
||||
discordbroadcastPermission=§4You do not have permission to send messages to the §c{0}§4 channel.
|
||||
discordbroadcastSent=§6Message sent to §c{0}§6\!
|
||||
discordCommandAccountArgumentUser=The Discord account to look up
|
||||
discordCommandAccountDescription=Looks up the linked Minecraft account for either yourself or another Discord user
|
||||
discordCommandAccountResponseLinked=Your account is linked to the Minecraft account\: **{0}**
|
||||
discordCommandAccountResponseLinkedOther={0}''s account is linked to the Minecraft account\: **{1}**
|
||||
discordCommandAccountResponseNotLinked=You do not have a linked Minecraft account.
|
||||
discordCommandAccountResponseNotLinkedOther={0} does not have a linked Minecraft account.
|
||||
discordCommandDescription=Sends the Discord invite link to the player.
|
||||
discordCommandLink=§6Join our Discord server at §c{0}§6\!
|
||||
discordCommandUsage=/<command>
|
||||
@@ -248,12 +256,20 @@ discordCommandUsage1Description=Sends the Discord invite link to the player
|
||||
discordCommandExecuteDescription=Executes a console command on the Minecraft server.
|
||||
discordCommandExecuteArgumentCommand=The command to be executed
|
||||
discordCommandExecuteReply=Executing command\: "/{0}"
|
||||
discordCommandUnlinkDescription=Unlinks the Minecraft account currently linked to your Discord account
|
||||
discordCommandUnlinkInvalidCode=You do not currently have a Minecraft account linked to Discord\!
|
||||
discordCommandUnlinkUnlinked=Your Discord account has been unlinked from all associated Minecraft accounts.
|
||||
discordCommandLinkArgumentCode=The code provided in-game to link your Minecraft account
|
||||
discordCommandLinkDescription=Links your Discord account with your Minecraft account using a code from the in-game /link command
|
||||
discordCommandLinkHasAccount=You already have an account linked\! To unlink your current account, type /unlink.
|
||||
discordCommandLinkInvalidCode=Invalid linking code\! Make sure you''ve run /link in-game and copied the code correctly.
|
||||
discordCommandLinkLinked=Successfully linked your account\!
|
||||
discordCommandListDescription=Gets a list of online players.
|
||||
discordCommandListArgumentGroup=A specific group to limit your search by
|
||||
discordCommandMessageDescription=Messages a player on the Minecraft server.
|
||||
discordCommandMessageArgumentUsername=The player to send the message to
|
||||
discordCommandMessageArgumentMessage=The message to send to the player
|
||||
discordErrorCommand=You added your bot to your server incorrectly. Please follow the tutorial in the config and add your bot using https\://essentialsx.net/discord.html\!
|
||||
discordErrorCommand=You added your bot to your server incorrectly\! Please follow the tutorial in the config and add your bot using https\://essentialsx.net/discord.html
|
||||
discordErrorCommandDisabled=That command is disabled\!
|
||||
discordErrorLogin=An error occurred while logging into Discord, which has caused the plugin to disable itself\: \n{0}
|
||||
discordErrorLoggerInvalidChannel=Discord console logging has been disabled due to an invalid channel definition\! If you intend to disable it, set the channel ID to "none"; otherwise check that your channel ID is correct.
|
||||
@@ -265,8 +281,20 @@ discordErrorNoPrimary=You did not define a primary channel or your defined prima
|
||||
discordErrorNoPrimaryPerms=Your bot cannot speak in your primary channel, \#{0}. Please make sure your bot has read and write permissions in all channels you wish to use.
|
||||
discordErrorNoToken=No token provided\! Please follow the tutorial in the config in order to setup the plugin.
|
||||
discordErrorWebhook=An error occurred while sending messages to your console channel\! This was likely caused by accidentally deleting your console webhook. This can usually by fixed by ensuring your bot has the "Manage Webhooks" permission and running "/ess reload".
|
||||
discordLinkInvalidGroup=Invalid group {0} was provided for role {1}. The following groups are available\: {2}
|
||||
discordLinkInvalidRole=An invalid role ID, {0}, was provided for group\: {1}. You can see the ID of roles with the /roleinfo command in Discord.
|
||||
discordLinkInvalidRoleInteract=The role, {0} ({1}), cannot be used for group->role synchronization because it above your bot''s uppermost role. Either move your bot''s role above "{0}" or move "{0}" below your bot''s role.
|
||||
discordLinkInvalidRoleManaged=The role, {0} ({1}), cannot be used for group->role synchronization because it is managed by another bot or integration.
|
||||
discordLinkLinked=§6To link your Minecraft account to Discord, type §c{0} §6in the Discord server.
|
||||
discordLinkLinkedAlready=§6You have already linked your Discord account\! If you wish to unlink your discord account use §c/unlink§6.
|
||||
discordLinkLoginKick=§6You must link your Discord account before you can join this server.\n§6To link your Minecraft account to Discord, type\:\n§c{0}\n§6in this server''s Discord server\:\n§c{1}
|
||||
discordLinkLoginPrompt=§6You must link your Discord account before you can move, chat on or interact with this server. To link your Minecraft account to Discord, type §c{0} §6in this server''s Discord server\: §c{1}
|
||||
discordLinkNoAccount=§6You do not currently have a Discord account linked to your Minecraft account.
|
||||
discordLinkPending=§6You already have a link code. To complete linking your Minecraft account to Discord, type §c{0} §6in the Discord server.
|
||||
discordLinkUnlinked=§6Unlinked your Minecraft account from all associated discord accounts.
|
||||
discordLoggingIn=Attempting to login to Discord...
|
||||
discordLoggingInDone=Successfully logged in as {0}
|
||||
discordMailLine=**New mail from {0}\:** {1}
|
||||
discordNoSendPermission=Cannot send message in channel\: \#{0} Please ensure the bot has "Send Messages" permission in that channel\!
|
||||
discordReloadInvalid=Tried to reload EssentialsX Discord config while the plugin is in an invalid state\! If you''ve modified your config, restart your server.
|
||||
disposal=Disposal
|
||||
@@ -314,6 +342,7 @@ enderchestCommandUsage2=/<command> <player>
|
||||
enderchestCommandUsage2Description=Opens the ender chest of the target player
|
||||
errorCallingCommand=Error calling the command /{0}
|
||||
errorWithMessage=§cError\:§4 {0}
|
||||
essChatNoSecureMsg=EssentialsX Chat version {0} does not support secure chat on this server software. Update EssentialsX, and if this issue persists, inform the developers.
|
||||
essentialsCommandDescription=Reloads essentials.
|
||||
essentialsCommandUsage=/<command>
|
||||
essentialsCommandUsage1=/<command> reload
|
||||
@@ -481,6 +510,7 @@ homeCommandUsage2=/<command> <player>\:<name>
|
||||
homeCommandUsage2Description=Teleports you to the specified player''s home with the given name
|
||||
homes=§6Homes\:§r {0}
|
||||
homeConfirmation=§6You already have a home named §c{0}§6\!\nTo overwrite your existing home, type the command again.
|
||||
homeRenamed=§6Home §c{0} §6has been renamed to §c{1}§6.
|
||||
homeSet=§6Home set to current location.
|
||||
hour=hour
|
||||
hours=hours
|
||||
@@ -533,6 +563,7 @@ invseeCommandDescription=See the inventory of other players.
|
||||
invseeCommandUsage=/<command> <player>
|
||||
invseeCommandUsage1=/<command> <player>
|
||||
invseeCommandUsage1Description=Opens the inventory of the specified player
|
||||
invseeNoSelf=§cYou can only view other players'' inventories.
|
||||
is=is
|
||||
isIpBanned=§6IP §c{0} §6is banned.
|
||||
internalError=§cAn internal error occurred while attempting to perform this command.
|
||||
@@ -589,7 +620,7 @@ jailList=§6Jails\:§r {0}
|
||||
jailMessage=§4You do the crime, you do the time.
|
||||
jailNotExist=§4That jail does not exist.
|
||||
jailNotifyJailed=§6Player§c {0} §6jailed by §c{1}.
|
||||
jailNotifyJailedFor=§6Player§c {0} §6jailed for§c {1}§6by §c{2}§6.
|
||||
jailNotifyJailedFor=§6Player§c {0} §6jailed for§c {1} §6by §c{2}§6.
|
||||
jailNotifySentenceExtended=§6Player§c{0}§6''s jail time extended to §c{1} §6by §c{2}§6.
|
||||
jailReleased=§6Player §c{0}§6 unjailed.
|
||||
jailReleasedPlayerNotify=§6You have been released\!
|
||||
@@ -658,6 +689,10 @@ lightningCommandUsage2=/<command> <player> <power>
|
||||
lightningCommandUsage2Description=Strikes lighting at the target player with the given power
|
||||
lightningSmited=§6Thou hast been smitten\!
|
||||
lightningUse=§6Smiting§c {0}
|
||||
linkCommandDescription=Generates a code to link your Minecraft account to Discord.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
linkCommandUsage1Description=Generates a code for the /link command on Discord
|
||||
listAfkTag=§7[AFK]§r
|
||||
listAmount=§6There are §c{0}§6 out of maximum §c{1}§6 players online.
|
||||
listAmountHidden=§6There are §c{0}§6/§c{1}§6 out of maximum §c{2}§6 players online.
|
||||
@@ -1007,6 +1042,12 @@ removeCommandUsage1Description=Removes all of the given mob type in the current
|
||||
removeCommandUsage2=/<command> <mob type> <radius> [world]
|
||||
removeCommandUsage2Description=Removes the given mob type within the given radius in the current world or another one if specified
|
||||
removed=§6Removed§c {0} §6entities.
|
||||
renamehomeCommandDescription=Renames a home.
|
||||
renamehomeCommandUsage=/<command> <[player\:]name> <new name>
|
||||
renamehomeCommandUsage1=/<command> <name> <new name>
|
||||
renamehomeCommandUsage1Description=Renames your home to the given name
|
||||
renamehomeCommandUsage2=/<command> <player>\:<name> <new name>
|
||||
renamehomeCommandUsage2Description=Renames the specified player''s home to the given name
|
||||
repair=§6You have successfully repaired your\: §c{0}§6.
|
||||
repairAlreadyFixed=§4This item does not need repairing.
|
||||
repairCommandDescription=Repairs the durability of one or all items.
|
||||
@@ -1018,7 +1059,7 @@ repairCommandUsage2Description=Repairs all items in your inventory
|
||||
repairEnchanted=§4You are not allowed to repair enchanted items.
|
||||
repairInvalidType=§4This item cannot be repaired.
|
||||
repairNone=§4There were no items that needed repairing.
|
||||
replyFromDiscord=**Reply from {0}\:** `{1}`
|
||||
replyFromDiscord=**Reply from {0}\:** {1}
|
||||
replyLastRecipientDisabled=§6Replying to last message recipient §cdisabled§6.
|
||||
replyLastRecipientDisabledFor=§6Replying to last message recipient §cdisabled §6for §c{0}§6.
|
||||
replyLastRecipientEnabled=§6Replying to last message recipient §cenabled§6.
|
||||
@@ -1076,7 +1117,9 @@ serverTotal=§6Server Total\:§c {0}
|
||||
serverUnsupported=You are running an unsupported server version\!
|
||||
serverUnsupportedClass=Status determining class\: {0}
|
||||
serverUnsupportedCleanroom=You are running a server that does not properly support Bukkit plugins that rely on internal Mojang code. Consider using an Essentials replacement for your server software.
|
||||
serverUnsupportedDangerous=You are running a server fork that is known to be extremely dangerous and lead to data loss. It is strongly recommended you switch to a more stable server software like Paper.
|
||||
serverUnsupportedLimitedApi=You are running a server with limited API functionality. EssentialsX will still work, but certain features may be disabled.
|
||||
serverUnsupportedDumbPlugins=You are using plugins known to cause severe issues with EssentialsX and other plugins.
|
||||
serverUnsupportedMods=You are running a server that does not properly support Bukkit plugins. Bukkit plugins should not be used with Forge/Fabric mods\! For Forge\: Consider using ForgeEssentials, or SpongeForge + Nucleus.
|
||||
setBal=§aYour balance was set to {0}.
|
||||
setBalOthers=§aYou set {0}§a''s balance to {1}.
|
||||
@@ -1390,6 +1433,10 @@ unlimitedCommandUsage3=/<command> clear [player]
|
||||
unlimitedCommandUsage3Description=Clears all unlimited items for yourself or another player if specified
|
||||
unlimitedItemPermission=§4No permission for unlimited item §c{0}§4.
|
||||
unlimitedItems=§6Unlimited items\:§r
|
||||
unlinkCommandDescription=Unlinks your Minecraft account from the currently linked Discord account.
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unlinkCommandUsage1Description=Unlinks your Minecraft account from the currently linked Discord account.
|
||||
unmutedPlayer=§6Player§c {0} §6unmuted.
|
||||
unsafeTeleportDestination=§4The teleport destination is unsafe and teleport-safety is disabled.
|
||||
unsupportedBrand=§4The server platform you are currently running does not provide the capabilities for this feature.
|
||||
|
||||
@@ -100,6 +100,8 @@ bookCommandUsage3=/<command> título <title>
|
||||
bookCommandUsage3Description=Establece el título de un libro firmado
|
||||
bookLocked=§6El libro ha sido bloqueado.
|
||||
bookTitleSet=§6Ahora el título del libro es {0}.
|
||||
bottomCommandDescription=Teletransportandote al bloque más bajo en su posición actual.
|
||||
bottomCommandUsage=/<command>
|
||||
breakCommandDescription=Rompe el bloque que estás mirando.
|
||||
breakCommandUsage=/<command>
|
||||
broadcast=§6[§4Aviso§6]§a {0}
|
||||
@@ -240,20 +242,34 @@ discordbroadcastCommandUsage1Description=Envía el mensaje dado al canal de Disc
|
||||
discordbroadcastInvalidChannel=§4El canal de Discord §c{0}§4 no existe.
|
||||
discordbroadcastPermission=§4No tienes permiso para enviar mensajes al canal §c{0}§4.
|
||||
discordbroadcastSent=§6Mensaje enviado a §c{0}§6\!
|
||||
discordCommandDescription=Envía el enlace de invitación a Discord al jugador.
|
||||
discordCommandAccountArgumentUser=La cuenta de Discord a buscar
|
||||
discordCommandAccountDescription=Busca la cuenta de Minecraft vinculada a ti mismo o a otro usuario de Discord
|
||||
discordCommandAccountResponseLinked=Tu cuenta está vinculada a la cuenta de Minecraft\: **{0}**
|
||||
discordCommandAccountResponseLinkedOther=La cuenta de {0} está vinculada a la cuenta de Minecraft\: **{1}**
|
||||
discordCommandAccountResponseNotLinked=No tienes una cuenta de Minecraft vinculada.
|
||||
discordCommandAccountResponseNotLinkedOther={0} no tiene una cuenta de Minecraft vinculada.
|
||||
discordCommandDescription=Envía un enlace de invitación de Discord a un jugador.
|
||||
discordCommandLink=§6¡Únete a nuestro servidor de Discord en §c{0}§6\!
|
||||
discordCommandUsage=/<command>
|
||||
discordCommandUsage1=/<command>
|
||||
discordCommandUsage1Description=Envía el enlace de invitación a Discord al jugador
|
||||
discordCommandUsage1Description=Envía un enlace de invitación de Discord a un jugador
|
||||
discordCommandExecuteDescription=Ejecuta un comando de consola en el servidor de Minecraft.
|
||||
discordCommandExecuteArgumentCommand=El comando a ejecutar
|
||||
discordCommandExecuteReply=Ejecutando comando\: "/{0}"
|
||||
discordCommandUnlinkDescription=Desvincula la cuenta de Minecraft actualmente vinculada a tu cuenta de Discord
|
||||
discordCommandUnlinkInvalidCode=¡Actualmente no tienes una cuenta de Minecraft vinculada a Discord\!
|
||||
discordCommandUnlinkUnlinked=Tu cuenta de Discord ha sido desvinculada de todas las cuentas de Minecraft asociadas.
|
||||
discordCommandLinkArgumentCode=El código proporcionado en el juego para vincular tu cuenta de Minecraft
|
||||
discordCommandLinkDescription=Vincula tu cuenta de Discord con tu cuenta de Minecraft usando un código del comando /link en el juego
|
||||
discordCommandLinkHasAccount=¡Ya tienes una cuenta vinculada\! Para desvincular tu cuenta actual, escribe /unlink.
|
||||
discordCommandLinkInvalidCode=¡Código de enlace no válido\! Asegúrese de que ha ejecutado /link en el juego y copiado el código correctamente.
|
||||
discordCommandLinkLinked=¡Se ha vinculado con éxito tu cuenta\!
|
||||
discordCommandListDescription=Genera una lista de jugadores en línea.
|
||||
discordCommandListArgumentGroup=Un grupo específico para limitar tu búsqueda
|
||||
discordCommandMessageDescription=Envía un mensaje a un jugador del servidor de Minecraft.
|
||||
discordCommandMessageArgumentUsername=El jugador al que enviar el mensaje
|
||||
discordCommandMessageArgumentMessage=El mensaje a enviar al jugador
|
||||
discordErrorCommand=El bot se ha añadido al servidor de forma incorrecta. ¡Sigue el tutorial de configuración y añade el bot usando https\://essentialsx.net/discord.html\!
|
||||
discordErrorCommand=¡Has añadido tu bot a tu servidor incorrectamente\! Por favor, sigue el tutorial en la configuración y añade tu bot usando https\://essentialsx.net/discord.html
|
||||
discordErrorCommandDisabled=¡Ese comando está desactivado\!
|
||||
discordErrorLogin=Error al iniciar sesión en Discord. El plugin se ha desactivado por sí mismo\: \n{0}
|
||||
discordErrorLoggerInvalidChannel=¡El inicio de sesión en la consola de Discord se ha desactivado por una definición del canal no válida\! Si quieres reactivarlo, establece la id. del canal en "none", de lo contrario comprueba que la identificación del canal es correcta.
|
||||
@@ -265,8 +281,20 @@ discordErrorNoPrimary=No has definido un canal principal o el que has definido n
|
||||
discordErrorNoPrimaryPerms=Tu bot no puede hablar en tu canal principal, \#{0}. Asegúrate de que tu bot tiene permisos de lectura y escritura en todos los canales que quieras que use.
|
||||
discordErrorNoToken=¡No hay token\! Sigue el tutorial de configuración para poner en marcha el plugin.
|
||||
discordErrorWebhook=¡Se ha producido un error al enviar mensajes al canal de la consola\! Esto puede deberse a que se haya eliminado accidentalmente tu webhook de consola. Esto se puede corregir asegurándote de que tu bot tiene permiso para "Administrar webhooks" y ejecutar "/ess reload".
|
||||
discordLinkInvalidGroup=Grupo inválido {0} proporcionado para el rol {1}. Los siguientes grupos están disponibles\: {2}
|
||||
discordLinkInvalidRole=Un ID de rol inválido, {0}, ha sido proporcionado para el grupo\: {1}. Puedes ver el ID de los roles con el comando /roleinfo en Discord.
|
||||
discordLinkInvalidRoleInteract=El rol, {0} ({1}), no se puede utilizar para la sincronización de roles debido a que está por encima del rol máximo de tu bot. Puedes mover el rol de tu bot encima de "{0}" o mover "{0}" debajo.
|
||||
discordLinkInvalidRoleManaged=El rol, {0} ({1}), no se puede utilizar para sincronizar de roles debido a que está controlado por otro bot o integración.
|
||||
discordLinkLinked=§6Para vincular tu cuenta de Minecraft a Discord, escribe §c{0} §6en el servidor de Discord.
|
||||
discordLinkLinkedAlready=§6Ya tienes vinculada tu cuenta de Discord\! Si deseas desvincularla usa §c/unlink§6.
|
||||
discordLinkLoginKick=§6Debes vincular tu cuenta de Discord para acceder a este servidor.\n§6Para vincular tu cuenta de Minecraft a Discord, escribe\:\n§c{0}\n§6en el Discord de este servidor\:\n§c{1}
|
||||
discordLinkLoginPrompt=§6Debes vincular tu cuenta de Discord para poder moverte, chatear o interactuar con el servidor. Para vincular tu cuenta de Minecraft a Discord, escribe§c{0} §6en el Discord de este servidor\: §c{1}
|
||||
discordLinkNoAccount=§6Actualmente no tienes una cuenta de Discord vinculada a tu cuenta de Minecraft.
|
||||
discordLinkPending=§6Ya tienes un código de vinculación. Para completar la vinculación de tu cuenta de Minecraft a Discord, escribe §c{0} §6en el servidor de Discord.
|
||||
discordLinkUnlinked=§6Has desvinculado tu cuenta de Minecraft de todas las cuentas de Discord asociadas.
|
||||
discordLoggingIn=Intentando iniciar sesión en Discord...
|
||||
discordLoggingInDone=Se ha iniciado sesión con éxito como {0}
|
||||
discordMailLine=**Nuevo mail de {0}\:** {1}
|
||||
discordNoSendPermission=Error al enviar el mensaje al canal\: \#{0}. ¡Asegúrate de que el bot tiene permisos para "Enviar mensajes" en ese canal\!
|
||||
discordReloadInvalid=¡Se ha intentado recargar la configuración de Discord de EssentialsX pero el plugin no era válido\! Si has modificado tu configuración, reinicia tu servidor.
|
||||
disposal=Basura
|
||||
@@ -288,9 +316,9 @@ ecoCommandDescription=Gestiona la economía del servidor.
|
||||
ecoCommandUsage=/<command> <give|take|set|reset> <player> <amount>
|
||||
ecoCommandUsage1=/<command> give <player> <amount>
|
||||
ecoCommandUsage1Description=Da al jugador especificado la cantidad de dinero especificada
|
||||
ecoCommandUsage2=/<command> take <jugador> <monto>
|
||||
ecoCommandUsage2=/<command> take <jugador> <cantidad>
|
||||
ecoCommandUsage2Description=Toma la cantidad especificada de dinero del jugador especificado
|
||||
ecoCommandUsage3=/<command> set <jugador> <monto>
|
||||
ecoCommandUsage3=/<command> set <jugador> <cantidad>
|
||||
ecoCommandUsage3Description=Establece el saldo del jugador especificado a la cantidad de dinero especificada
|
||||
ecoCommandUsage4=/<command> reset <jugador> <cantidad>
|
||||
ecoCommandUsage4Description=Restablece el saldo del jugador especificado al saldo inicial del servidor
|
||||
@@ -482,6 +510,7 @@ homeCommandUsage2=/<command> <player>\:<name>
|
||||
homeCommandUsage2Description=Te teletransporta a la casa del jugador especificado con el nombre dado
|
||||
homes=§6Hogares\:§r {0}
|
||||
homeConfirmation=§6Ya tienes una casa llamada §c{0}§6\!\nPara sobrescribir tu casa existente, escribe el comando de nuevo.
|
||||
homeRenamed=§6La casa §c{0} §6ha sido renombrada a §c{1}§6.
|
||||
homeSet=§7Hogar establecido.
|
||||
hour=hora
|
||||
hours=horas
|
||||
@@ -534,6 +563,7 @@ invseeCommandDescription=Ver el inventario de otros jugadores.
|
||||
invseeCommandUsage=/<command> <jugador>
|
||||
invseeCommandUsage1=/<command> <jugador>
|
||||
invseeCommandUsage1Description=Abre el inventario del jugador especificado
|
||||
invseeNoSelf=§cSolo puedes ver los inventarios de otros jugadores.
|
||||
is=es
|
||||
isIpBanned=§6IP §c{0} §6está baneada.
|
||||
internalError=§cAn internal error occurred while attempting to perform this command.
|
||||
@@ -571,7 +601,7 @@ itemnameCommandUsage2Description=Establece el nombre del item sostenido al texto
|
||||
itemnameInvalidItem=§cNecesitas tener un objeto en la mano para renombrarlo.
|
||||
itemnameSuccess=§6Has renombrado el objeto de tu mano a "§c{0}§6".
|
||||
itemNotEnough1=§4No tienes la suficiente cantidad del ítem para venderlo.
|
||||
itemNotEnough2=§6Si quieres vender todos tus objetos de ese tipo, escribe /sell nombredelobjeto (en inglés).
|
||||
itemNotEnough2=§6Si quieres vender todos tus objetos de ese tipo, escribe§c /sell nombredelobjeto§6.
|
||||
itemNotEnough3=§c/sell nombredeobjeto -1§6 venderá todos excepto un objeto, etc.
|
||||
itemsConverted=§6Todos los items han sido convertidos en bloques.
|
||||
itemsCsvNotLoaded=¡No se pudo cargar {0}\!
|
||||
@@ -590,7 +620,7 @@ jailList=§6Jails\:§r {0}
|
||||
jailMessage=§c¡Por el crimen hacer, a la cárcel irás\!
|
||||
jailNotExist=§4Esa cárcel no existe.
|
||||
jailNotifyJailed=§6El jugador§c {0} §6ha sido encarcelado por §c{1}.
|
||||
jailNotifyJailedFor=§6El jugador§c {0} §6ha sido encarcelado por§c {1}§6por §c{2}§6.
|
||||
jailNotifyJailedFor=§6El jugador§c {0} §6ha sido encarcelado por§c {1} §6por §c{2}§6.
|
||||
jailNotifySentenceExtended=§6El tiempo en cárcel §6del jugador§c{0} §6ha sido extendido a §c{1} §6por §c{2}§6.
|
||||
jailReleased=§6El jugador §c{0}§6 ha salido de la cárcel.
|
||||
jailReleasedPlayerNotify=§7¡Has sido liberado\!
|
||||
@@ -659,6 +689,10 @@ lightningCommandUsage2=/<command> <jugador> <poder>
|
||||
lightningCommandUsage2Description=Lanza un rayo al jugador objetivo con el poder elegido
|
||||
lightningSmited=§6¡Has sido golpeado mágicamente\!
|
||||
lightningUse=§6Golpeando al jugador§c {0}
|
||||
linkCommandDescription=Genera un código para vincular tu cuenta de Minecraft a Discord.
|
||||
linkCommandUsage=/<command>
|
||||
linkCommandUsage1=/<command>
|
||||
linkCommandUsage1Description=Genera un código para el comando /link en Discord
|
||||
listAfkTag=§8[Ausente]§r
|
||||
listAmount=§9Hay §c{0}§9 jugadores de un máximo de §c{1}§9 jugadores §2en linea§9.
|
||||
listAmountHidden=§6Hay§c{0}§6/§c{1}§6 de un máximo de §c{2}§6 jugadondo online.
|
||||
@@ -734,7 +768,7 @@ moreCommandUsage1Description=Llena el ítem retenido hasta el monto establecido,
|
||||
moreThanZero=Las cantidades deben ser mayores que 0.
|
||||
motdCommandDescription=Mira el Mensaje del Día.
|
||||
motdCommandUsage=/<command> [capítulo] [página]
|
||||
moveSpeed=§6Establecida velocidad de {0} a§c {1} §6durante §c{2}§6.
|
||||
moveSpeed=§6Velocidad establecida de§c {0} §6a§c {1} §6durante §c{2}§6.
|
||||
msgCommandDescription=Envía un mensaje privado al jugador especificado.
|
||||
msgCommandUsage=/<command> <hacia> <mensaje>
|
||||
msgCommandUsage1=/<command> <hacia> <mensaje>
|
||||
@@ -1008,6 +1042,12 @@ removeCommandUsage1Description=Elimina todos los mobs del tipo dado en el mundo
|
||||
removeCommandUsage2=/<comando> <tipo de mob> <radio> [mundo]
|
||||
removeCommandUsage2Description=Elimina el tipo de mob dado dentro del radio dado en el mundo actual u otro si se especifica
|
||||
removed=§6Eliminadas§c {0} §6entidades.
|
||||
renamehomeCommandDescription=Cambia el nombre de un hogar.
|
||||
renamehomeCommandUsage=/<command> <[player\:]name> <new name>
|
||||
renamehomeCommandUsage1=/<command> <name> <new name>
|
||||
renamehomeCommandUsage1Description=Renombra tu casa con el nombre dado
|
||||
renamehomeCommandUsage2=/<command> <player>\:<name> <new name>
|
||||
renamehomeCommandUsage2Description=Cambia el nombre de la casa del jugador especificado por el nombre dado
|
||||
repair=§6Has reparado exitósamente tu\: §c{0}§6.
|
||||
repairAlreadyFixed=§4Este ítem no necesita reparación.
|
||||
repairCommandDescription=Repara la durabilidad de uno o todos tus objetos.
|
||||
@@ -1019,7 +1059,7 @@ repairCommandUsage2Description=Repara todos los objetos en tu inventario
|
||||
repairEnchanted=§4No tienes permiso para reparar un ítem encantado.
|
||||
repairInvalidType=§4Ese ítem no puede ser reparado.
|
||||
repairNone=§4No hay ítems que necesiten ser reparados.
|
||||
replyFromDiscord=**Respuesta de {0}\:** «{1}»
|
||||
replyFromDiscord=**Respuesta de {0}\:** {1}
|
||||
replyLastRecipientDisabled=§6Respuesta al último mensaje recibido/enviado §cdesactivado§6.
|
||||
replyLastRecipientDisabledFor=§6Respuesta al último mensaje recibido/enviado §cdesactivado §6por §c{0}§6.
|
||||
replyLastRecipientEnabled=§6Respuesta al último mensaje recibido/enviado §cactivado§6.
|
||||
@@ -1214,6 +1254,7 @@ teleportationDisabledWarning=§6Debes activar la teletransportación antes de qu
|
||||
teleportationEnabled=§6Teletransporte §chabilitado§6.
|
||||
teleportationEnabledFor=§6Teletransporte §chabilitado §6para §c{0}§6.
|
||||
teleportAtoB=§c{0}§6 te ha teletransportado a §c{1}§6.
|
||||
teleportBottom=§6Teletransportandote hasta abajo.
|
||||
teleportDisabled=§c{0} §4tiene la teletransportación desactivada.
|
||||
teleportHereRequest=§c{0}§6te ha pedido que te teletransportes hasta él.
|
||||
teleportHome=§6Teletransportándose hacia §c{0}§6.
|
||||
@@ -1229,6 +1270,7 @@ teleportRequestTimeoutInfo=§6La solicitud será automáticamente cancelada desp
|
||||
teleportTop=§6Teletransportandote hasta la cima.
|
||||
teleportToPlayer=§6Teletransportándose a §c{0}§6.
|
||||
teleportOffline=§6El[la] jugador[a] §c{0}§6 está desconectado[a].Puedes teletransportarte a él[ella] usando /otp.
|
||||
teleportOfflineUnknown=§6No se ha podido encontrar la última posición conocida de §c{0}§6.
|
||||
tempbanExempt=§4No puedes banear temporalmente a ese usuario.
|
||||
tempbanExemptOffline=§4No puedes banear temporalmente a jugadores que no están conectados.
|
||||
tempbanJoin=You are banned from this server for {0}. Reason\: {1}
|
||||
@@ -1374,11 +1416,11 @@ unableToSpawnMob=§4No puedes generar criaturas.
|
||||
unbanCommandDescription=Desbanea el jugador especificado.
|
||||
unbanCommandUsage=/<command> <jugador>
|
||||
unbanCommandUsage1=/<command> <jugador>
|
||||
unbanCommandUsage1Description=Desbanea el jugador especificado
|
||||
unbanCommandUsage1Description=Desbanea un jugador específico
|
||||
unbanipCommandDescription=Desbanea la dirección IP especificada.
|
||||
unbanipCommandUsage=/<command> <dirección IP>
|
||||
unbanipCommandUsage1=/<command> <dirección IP>
|
||||
unbanipCommandUsage1Description=Desbanea la dirección IP especificada
|
||||
unbanipCommandUsage1Description=Desbanea una dirección IP especifica
|
||||
unignorePlayer=§6Ya no ignoras al jugador§c {0}§6.
|
||||
unknownItemId=§4ID de ítem desconocido\:§r {0}§4.
|
||||
unknownItemInList=§4Ítem desconocido {0} en {1} lista.
|
||||
@@ -1393,6 +1435,10 @@ unlimitedCommandUsage3=/<comando> limpiar [jugador]
|
||||
unlimitedCommandUsage3Description=Limpia todos los objetos ilimitados para ti u otro jugador si se especifica
|
||||
unlimitedItemPermission=§4Sin permiso para artículo ilimitado §c{0}§4.
|
||||
unlimitedItems=§6Ítems ilimitados\:§r
|
||||
unlinkCommandDescription=Desvincula tu cuenta de Minecraft de la cuenta de Discord actualmente vinculada.
|
||||
unlinkCommandUsage=/<command>
|
||||
unlinkCommandUsage1=/<command>
|
||||
unlinkCommandUsage1Description=Desvincula tu cuenta de Minecraft de la cuenta de Discord actualmente vinculada.
|
||||
unmutedPlayer=§6El jugador§c {0} §6ya no está silenciado.
|
||||
unsafeTeleportDestination=§4El destino es inseguro y el teletransporte seguro está desactivado.
|
||||
unsupportedBrand=§4La plataforma en la que se ejecuta el servidor no proporciona las capacidades para esta función.
|
||||
@@ -1413,6 +1459,9 @@ userIsAwaySelf=§7Ahora estás AFK.
|
||||
userIsAwaySelfWithMessage=§7Ahora estás AFK.
|
||||
userIsNotAwaySelf=§7Ya no estás AFK\!
|
||||
userJailed=§6¡Has sido encarcelado\!
|
||||
usermapEntry=§c{0} §6está mapeado en §c{1}§6.
|
||||
usermapPurge=§6Comprobando archivos en userdata que no estén mapeados, los resultados serán registrados en consola. Modo Destructivo\: {0}
|
||||
usermapSize=§6Usuarios actuales en cache en el mapeo del usuario §c{0}§6/§c{1}§6/§c{2}§6.
|
||||
userUnknown=§4Aviso\: §cel jugador §4{0} §cnunca ha visitado el servidor\!
|
||||
usingTempFolderForTesting=Usando carpeta temporal para pruebas\:
|
||||
vanish=§6Invisibilidad mágica para {0}§6\:§c {1}
|
||||
@@ -1444,7 +1493,7 @@ versionReleaseNew=§4Hay una nueva versión de EssentialsX disponible para desca
|
||||
versionReleaseNewLink=§4Descárgala aquí\:§c {0}
|
||||
voiceSilenced=§7Tu voz ha sido silenciada
|
||||
voiceSilencedTime=§6Tu voz ha sido silenciada por {0}\!
|
||||
voiceSilencedReason=§6Tu voz ha sido silenciada\! §6Motivo\: §c{0}
|
||||
voiceSilencedReason=§6Has sido silenciado\! §6Motivo\: §c{0}
|
||||
voiceSilencedReasonTime=§6Tu voz ha sido silenciada por {0}\! Razón\: §c{1}
|
||||
walking=caminando
|
||||
warpCommandDescription=Lista todos los warp o teletransporta al warp especificado.
|
||||
|
||||
Loaded 100 of 185 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user