Compare commits

...
56 Commits
Author SHA1 Message Date
MD ff7569c77d Refactor tpaccept world permission checks for clarity
When mdcfe in `world_nether` sends a `/tpa` to mdcfe3 in `world` and mdcfe3 accepts:
```
[13:57:02 INFO]: mdcfe3 issued server command: /tpaccept
[...]
[13:57:02 INFO]: [Essentials] checking if mdcfe3 has essentials.tpaccept - true
[...]
[13:57:02 INFO]: [Essentials] checking if mdcfe has essentials.tpa - true
[13:57:02 INFO]: [Essentials] checking if mdcfe has essentials.worlds.world - true
```

When mdcfe in `world` sends a `/tpahere` to mdcfe3 in `world_nether` and mdcfe3 accepts:
```
[14:02:36 INFO]: mdcfe3 issued server command: /tpaccept
[...]
[14:02:36 INFO]: [Essentials] checking if mdcfe3 has essentials.tpaccept - true
[...]
[14:02:36 INFO]: [Essentials] checking if mdcfe has essentials.tpahere - true
[14:02:36 INFO]: [Essentials] checking if mdcfe3 has essentials.worlds.world - true
```
2023-04-11 14:04:52 +01:00
Kees Monshouwer f0cdada4a9 Fix tpaccept world teleport permissions 2023-04-10 23:31:48 +02:00
diademiemiandJosh Roy 384f63bf92 Allow configuring Discord webhook name (#5159)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
2023-04-10 00:27:36 +00:00
Joel OteroandJosh Roy 77dc87bb8e Add /bottom command (#5292)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
2023-04-09 21:05:53 +00:00
MD c716fc8236 Bump runServer task to Paper 1.19.4 (#5269) 2023-04-06 00:15:15 +00:00
Flask Bot c52c1fea9d New Crowdin updates (#5244) 2023-04-04 21:49:43 -07:00
Josh Roy e7c56b32a4 Fix sulk sensors detecting vanished players (#5262) 2023-04-02 22:29:29 +00:00
Josh Roy 11e6d3ca7b Fix /mail sendall not working (#5263) 2023-04-02 22:12:04 +00:00
Josh Roy 75481925f7 Update display names before formatting chat messages (#5282) 2023-04-02 22:08:38 +00:00
Josh Roy ecb1850451 Add message for unknown last location for /tpo (#5290) 2023-04-02 22:04:36 +00:00
Josh Roy 0f4af9e735 Use strict comparison for potions in trade signs (#5260) 2023-04-02 21:45:46 +00:00
Josh RoyandMD bf14b88600 Bump to 1.19.4 (#5273)
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
2023-03-17 18:54:33 +00:00
Josh Roy 43d84de2b2 Move feature requests back to issues (#5251)
* Create request-a-feature.yml

* Update config.yml
2023-02-17 12:11:21 +00:00
25ad8ac9bd Add per-command command cooldown bypass permissions (#4759)
Adds the permission `essentials.commandcooldowns.bypass.<command name>` to bypass the cooldown for a specific command.

Closes #4747.

Co-authored-by: pop4959 <pop4959@gmail.com>
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
2023-02-13 23:19:52 +00:00
17051eab73 Add separate events for local and global chat (#4683)
This commit adds two new events: GlobalChatEvent and LocalChatEvent,
which allow other plugin developers to know whether the message sent is
a global or local one and act accordingly. If either of those events is
cancelled, then the source event is cancelled too.

Since all chat-related events share the same structure, a new abstract
class ChatEvent is created with change made for LocalChatSpyEvent to use
it without breaking its API.

Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
2023-02-13 23:15:15 +00:00
Flask Bot 4dc994df3c New Crowdin updates (#5051) 2023-02-05 04:58:49 -08:00
Warrior 996285c0e3 Fix doubles not working in console for /tppos (#5231)
Closes https://github.com/EssentialsX/Essentials/issues/5230
2023-01-22 16:32:47 -05:00
Josh Roy 312d1699a8 Use metadata for tnt from /nuke (#5222)
Fixes https://github.com/EssentialsX/Essentials/issues/5219
2023-01-12 10:51:13 -05:00
Josh Roy b3238605cc Fix inventory size for 1.8.8 servers (#5212) 2023-01-05 19:13:16 +00:00
Josh Roy b7a4bea52e Revert dual hand behavior from /hat (#5205)
Fixes https://github.com/EssentialsX/Essentials/issues/5202
2022-12-30 18:30:52 -05:00
Josh Roy ca71d93963 Fix discord permission issues with link module (#5197) 2022-12-27 21:07:47 +00:00
Josh Roy 0936fe80bd Discord Link Module 2022-12-26 01:24:17 +00:00
Josh Roy 520e8f991f Add DiscordService#getInviteUrl 2022-12-26 01:24:17 +00:00
Josh Roy 3131cadf65 Add UserMailEvent 2022-12-26 01:24:17 +00:00
Josh Roy bfae6c5c69 Add IPermissionsHandler#addToGroup & IPermissionsHandler#removeFromGroup 2022-12-26 01:24:17 +00:00
Josh Roy 52c500ee6d Add InteractionRole#getAsMention + InteractionRole#canInteract 2022-12-26 01:24:17 +00:00
Josh Roy ba5a8becfc Add support for role arguments in slash commands 2022-12-26 01:24:17 +00:00
Josh Roy 2a1957229f Add InteractionMember#hasRole convince methods 2022-12-26 01:24:17 +00:00
Josh Roy e6af246170 Add IPermissionsHandler#getGroups to fetch all groups 2022-12-26 01:24:17 +00:00
Josh Roy 939e5c5a55 Add InteractionRole#isPublicRole 2022-12-26 01:24:17 +00:00
Josh Roy 80bbf8c55b Add DiscordService#getRole & DiscordService#modifyMemberRoles 2022-12-26 01:24:17 +00:00
Josh Roy 376abc4aab Add DiscordService#getMemberById 2022-12-26 01:24:17 +00:00
Josh Roy a7f4d6b16b Add InteractionMember#getAsMention 2022-12-26 01:24:17 +00:00
Josh Roy e0d6040662 Add IUser#isFreeze & IUser#setFreeze 2022-12-26 01:24:17 +00:00
Josh Roy 6ec4c97ddd Rewrite Inventory Handling (#5021)
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>

Complete refactor of inventory handling across the plugin. This simplifies various commands, and aims to resolve issues aon various different MC versions and inconsistencies between parts of the plugin.

Fixes https://github.com/EssentialsX/Essentials/issues/3810
Fixes https://github.com/EssentialsX/Essentials/issues/4248
2022-12-24 17:58:51 +00:00
diademiemiandJosh Roy db10678095 Add first join message type for Discord (#5160)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>

Add a new message type for when a player has joined for the first time.
2022-12-24 14:59:00 +00:00
Josh Roy 582a357752 Bump to 1.19.3 (#5179) 2022-12-07 21:47:13 -05:00
Bobcat00andBobcat00 8a1e7019a7 Fix incorect play time in /whois (#5177)
Co-authored-by: Bobcat00 <Bobcat00@users.noreply.github.com>
2022-12-06 09:02:20 -05:00
Josh Roy 4414eea513 Close discord webhook clients on shutdown (#5165) 2022-11-27 19:29:36 +00:00
Josh Roy 6e931b2b3b Fix ConsoleInjector not getting reinjecting on reload (#5149) 2022-11-11 15:28:55 -08:00
Warrior 22a0d53cf2 Improve uuid cache load times (#5143) 2022-11-03 20:14:18 -04:00
20011b9996 Added permission node for Nickname Prefix bypass (#4995)
Allow a permission to determine whether the nickname prefix gets applied to a group or user. It also removes a statement that is not true in the essentials config, the nickname prefix is NOT included in the nickname max length.

Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
2022-10-25 07:44:05 +01:00
879e70fb6b Ignore NPCs in JailListener (#5130)
Co-authored-by: pop4959 <pop4959@gmail.com>
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>

Citizens NPCs cannot be jailed. This change prevents unnecessary lookups of NPC users.
2022-10-20 14:19:22 -04:00
Josh Royandpop4959 f91dfed5b4 Improve PlayerTarget code (#5131)
Co-authored-by: pop4959 <pop4959@gmail.com>
2022-10-15 00:41:21 +00:00
Josh Roy 767185ec32 Auto complete /mail clear indices (#5132) 2022-10-15 00:32:47 +00:00
Noah van der AaandJosh Roy 4aa93a43db Add mutable "viewers" list to DiscordRelayEvent (#5080)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
2022-10-14 22:26:01 +00:00
Lax 57529c4b7d Update Bukkit wiki links in config (#5094) 2022-10-14 22:15:35 +00:00
MDandJosh Roy dc7fb91939 Make usermap non-player warnings configurable (#5125)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
2022-10-11 01:06:54 +00:00
Josh Roy e91ce0c44c Fix Essentials#getUser not caching newly created NPC users (#5129) 2022-10-11 00:36:33 +00:00
Nassim Jahnke f7cbc7b0d3 Add renamehome command (#5121) 2022-10-04 08:40:18 -04:00
MD 28d7abe642 Close any open inventories before showing shapeless recipes (#5122) 2022-10-02 18:43:13 -04:00
0ca58ce4ba Rewrite User storage and UUID cache (#4581)
Co-authored-by: triagonal <10545540+triagonal@users.noreply.github.com>
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
2022-09-09 15:49:43 -04:00
Josh Roy d75d3cd001 Bump to 2.20 dev
Fourth time's a charm
2022-09-09 15:49:40 -04:00
MD 1eb5d8a459 Use Netlify CLI directly to deploy Javadocs 2022-09-05 18:46:09 +01:00
Josh Roy b808511efe Update discord bot authorization tutorial (#5098) 2022-09-02 09:43:09 -04:00
MD 0897ef71f2 Bump to 2.19.8 dev (#5085) 2022-08-22 10:17:33 -04:00
172 changed files with 8571 additions and 1901 deletions

No files matched your search

+1 -4
View File
@@ -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
+26 -5
View File
@@ -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 }}
+2
View File
@@ -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,7 +1073,12 @@ 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);
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 {
user.update(base);
}
@@ -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();
@@ -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();
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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,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,96 @@
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 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"));
}
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);
@@ -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
@@ -8,6 +8,7 @@ import net.essentialsx.api.v2.events.TeleportRequestResponseEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.ArrayList;
@@ -87,12 +88,15 @@ public class Commandtpaccept extends EssentialsCommand {
throw new Exception(tl("noPendingRequest"));
}
if (request.isHere() && ((!requester.isAuthorized("essentials.tpahere") && !requester.isAuthorized("essentials.tpaall")) || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + user.getWorld().getName())))) {
throw new Exception(tl("noPendingRequest"));
}
if (!request.isHere() && (!requester.isAuthorized("essentials.tpa") || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + requester.getWorld().getName())))) {
throw new Exception(tl("noPendingRequest"));
if (request.isHere()) {
final boolean isRequesterAuthorized = requester.isAuthorized("essentials.tpahere") || requester.isAuthorized("essentials.tpaall");
if (!isRequesterAuthorized || !canTeleportToWorld(user, requester.getWorld())) {
throw new Exception(tl("noPendingRequest"));
}
} else {
if (!requester.isAuthorized("essentials.tpa") || !canTeleportToWorld(requester, user.getWorld())) {
throw new Exception(tl("noPendingRequest"));
}
}
final TeleportRequestResponseEvent event = new TeleportRequestResponseEvent(user, requester, request, true);
@@ -129,4 +133,8 @@ public class Commandtpaccept extends EssentialsCommand {
}
user.removeTpaRequest(request.getName());
}
private boolean canTeleportToWorld(final User user, final World destination) {
return user.getWorld() == destination || !ess.getSettings().isWorldTeleportPermissions() || user.isAuthorized("essentials.worlds." + destination.getName());
}
}
@@ -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)));
@@ -32,9 +32,9 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
final User matchedUser = ess.getUser(uuid);
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);
userConsumer.accept(user);
}
} else if (matchWildcards && searchTerm.contentEquals("*")) {
final boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
@@ -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;
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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);
@@ -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,210 @@
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.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 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())
.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");
this.debugMaxWarnsPerType = NumberUtil.isLong(maxWarnProperty) ? Long.parseLong(maxWarnProperty) : -1;
this.debugPrintStackWithWarn = Boolean.parseBoolean(printStackProperty);
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);
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) {
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);
}
@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 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,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;
}
}
+5 -3
View File
@@ -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}
@@ -215,7 +215,7 @@ delkitCommandDescription=Изтрива посочен кит.
delkitCommandUsage=/<command> <kit>
delkitCommandUsage1=/<command> <kit>
delkitCommandUsage1Description=Изтрива кит с дадено име
delwarpCommandDescription=Изтрива посочен warp.
delwarpCommandDescription=Изтрива посочен уарп.
delwarpCommandUsage=/<command> <warp>
delwarpCommandUsage1=/<command> <warp>
delwarpCommandUsage1Description=Изтрива уарп с дадено име
@@ -450,6 +450,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 +522,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 +913,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=Тази функция я няма на тази версия на сървъра.
@@ -240,6 +240,10 @@ 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í
discordCommandAccountResponseLinked=Tvůj účet je propojen s Minecraft účtem\: **{0}**
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 +252,16 @@ 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\!
discordCommandLinkArgumentCode=Kód uvedený ve hře pro propojení tvého Minecraft účtu
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.
@@ -267,6 +275,7 @@ discordErrorNoToken=Nebyl zadán žádný token\! Chcete-li nastavit zásuvný m
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“.
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 +335,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 +491,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 +544,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 +595,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 +670,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 +1023,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 +1040,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.
@@ -1229,6 +1250,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 +1267,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 +1415,8 @@ 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
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
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 +1437,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,53 @@ 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}.
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 +105,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 +128,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 +155,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 +175,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 +193,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 +212,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 +274,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 +312,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 +334,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 +356,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 +408,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 +422,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 +472,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 +488,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 +509,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 +530,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 +564,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 +583,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 +611,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 +663,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 +705,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 +729,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 +741,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 +781,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
@@ -240,6 +240,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 +254,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 +279,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 +318,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 +405,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 +415,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 +427,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 +438,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 +454,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 +503,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 +525,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 +561,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 +576,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 +618,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 +660,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 +672,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 +682,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 +711,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 +742,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 +762,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 +770,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 +780,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 +803,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 +866,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 +877,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 +892,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 +906,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 +926,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 +963,33 @@ 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|*]
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.
@@ -898,6 +1020,8 @@ 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,15 +1032,24 @@ 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]
removeCommandUsage2=/<command> <mob type> <radius> [world]
removed=§c{0} §6Einheiten entfernt.
renamehomeCommandDescription=Benennt ein Haus um.
renamehomeCommandUsage1=/<command> <name> <neuer name>
renamehomeCommandUsage1Description=Bennt dein Home in den gegebenen Namen um
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
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.
@@ -930,6 +1063,7 @@ 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.
@@ -953,13 +1087,16 @@ 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.
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\!
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 +1104,31 @@ 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>
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>
sheepMalformedColor=§4Ungültige Farbe.
shoutDisabled=§6Rufmodus §cdeaktiviert§6.
shoutDisabledFor=§6Rufmodus §cdeaktiviert §6für §c{0}§6.
@@ -991,13 +1140,18 @@ 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.
editsignPaste=§6Schild eingefügt\!
editsignPasteLine=§6Zeile §c{0} §6vom Schild eigefügt\!
editsignCommandUsage1=/<command> set <zeilennummer> <text>
editsignCommandUsage1Description=Setzt die angegebene Linie des Ziel-Schilds auf den angegebenen Text
editsignCommandUsage2Description=Leert die angegebene Zeile von dem Zielschild
signFormatFail=§4[{0}]
signFormatSuccess=§1[{0}]
signFormatTemplate=[{0}]
@@ -1010,7 +1164,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 +1188,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,21 +1227,26 @@ 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.
@@ -1104,20 +1267,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 +1298,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 +1346,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 +1355,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 +1393,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 +1404,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 +1421,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 +1439,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,6 +1465,9 @@ 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]
@@ -272,6 +272,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 +326,8 @@ tpdenyCommandUsage1=/<command>
tprCommandUsage=/<command>
tprCommandUsage1=/<command>
tptoggleCommandUsage1=/<command> [παίκτης]
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
vanishCommandUsage1=/<command> [παίκτης]
walking=περπάτημα
warpCommandUsage1=/<command> [σελίδα]
@@ -253,7 +253,7 @@ 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.
@@ -314,6 +314,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 +482,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 +535,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 +592,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 +661,8 @@ lightningCommandUsage2=/<command> <player> <power>
lightningCommandUsage2Description=Strikes lighting at the target player with the given power
lightningSmited=§6Thou hast been smitten\!
lightningUse=§6Smiting§c {0}
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
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 +1012,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 +1029,6 @@ 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}`
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 +1086,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 +1402,8 @@ 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
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
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 +1424,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}
@@ -253,7 +253,6 @@ 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\!
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.
@@ -589,7 +588,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 +657,8 @@ lightningCommandUsage2=/<command> <player> <power>
lightningCommandUsage2Description=Strikes lighting at the target player with the given power
lightningSmited=§6Thou hast been smitten\!
lightningUse=§6Smiting§c {0}
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
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.
@@ -1018,7 +1019,6 @@ 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}`
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.
@@ -1390,6 +1390,8 @@ 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
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
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.
@@ -240,6 +240,12 @@ 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\!
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 el enlace de invitación a Discord al jugador.
discordCommandLink=§6¡Únete a nuestro servidor de Discord en §c{0}§6\!
discordCommandUsage=/<command>
@@ -248,12 +254,20 @@ discordCommandUsage1Description=Envía el enlace de invitación a Discord al jug
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 +279,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 +314,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 +508,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 +561,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.
@@ -590,7 +618,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 +687,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.
@@ -1008,6 +1040,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 +1057,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.
@@ -1229,6 +1267,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}
@@ -1393,6 +1432,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 +1456,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}
@@ -253,13 +253,13 @@ discordCommandListArgumentGroup=Konkreetne rühm, mille järgi otsingut piirata
discordCommandMessageDescription=Saadab sõnumeid Minecrafti serveris olevale mängijale.
discordCommandMessageArgumentUsername=Mängija, kellele sõnum saata
discordCommandMessageArgumentMessage=Sõnum, mis tuleb mängijale saata
discordErrorCommand=Lisasite oma roboti oma serverisse valesti. Järgige konfiguratsioonis toodud õpetust ja lisage oma robot, kasutades https\://essentialsx.net/discord.html\!
discordErrorCommandDisabled=See käsklus on keelatud\!
discordErrorLogin=Discordi sisselogimisel ilmnes viga, mis põhjustas pistikprogrammi enda keelamise\:\n{0}
discordErrorLoggerInvalidChannel=Discordi konsooli logimine on keelatud kanali definitsiooni tõttu\! Kui kavatsete selle keelata, määrake kanali ID-ks "puudub"; muul juhul kontrollige, kas teie kanali ID on õige.
discordErrorLoggerNoPerms=Discordi konsooli logija on ebapiisavate õiguste tõttu keelatud\! Veenduge, et teie robotil on serveris õigused "Halda veebihaake". Pärast selle parandamist käivitage "/ess reload".
discordLoggingIn=Proovin logida Discordi...
discordLoggingInDone=Edukalt sisse logitud kui {0}
discordMailLine=**Uus kiri mängijalt {0}\:** {1}
disposal=Prügišaht
disposalCommandDescription=Avab kaasaskantava hävitusmenüü.
disposalCommandUsage=/<käsklus>
@@ -642,6 +642,8 @@ lightningCommandUsage2=/<käsklus> <mängija> <võim>
lightningCommandUsage2Description=Lööb välku mängija suunas etteantud jõuga
lightningSmited=§6Sind on löönud välk\!
lightningUse=§6Lööd välgunoole mängijasse§c {0}
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
listAfkTag=§7[Eemal]§r
listAmount=§6Võrgus on §c{0}§6/§c{1}§6 mängijat.
listAmountHidden=§6Võrgus on §c{0}§6 (§c{1}§6)/§c{2}§6 mängijat.
@@ -653,6 +655,7 @@ listGroupTag=§6{0}§r\:
listHiddenTag=§7[PEIDETUD]§r
listRealName=({0})
loadWarpError=§4Koolu {0} laadimisel esines viga.
localFormat=§3[L] §r<{0}> {1}
loomCommandDescription=Avab kangasteljed.
loomCommandUsage=/<käsklus>
mailClear=§6Postkasti tühjendamiseks kirjuta§c /mail clear§6.
@@ -812,6 +815,7 @@ noPlacePermission=§4Sul puudub luba selle sildi juurde ploki asetamiseks.
noPotionEffectPerm=§4Sul puudub luba sellele võlujoogile efekti §c{0} §4 rakendamiseks.
noPowerTools=§6Sul puuduvad võimutööriistad.
notAcceptingPay=§4Mängija §4{0} §4ei võta makseid vastu.
notAllowedToLocal=§4Sul puudub luba kohalikus vestluses rääkimiseks.
notEnoughExperience=§4Sul pole piisavalt kogemuspunkte.
notEnoughMoney=§4Sul pole piisavalt raha.
notFlying=ei lenda
@@ -992,7 +996,6 @@ repairCommandUsage2Description=Parandab sinu seljakotis kõik esemed
repairEnchanted=§4Sul puudub loitsitud esemete parandamiseks luba.
repairInvalidType=§4Seda eset ei saa parandada.
repairNone=§4Polnud ühtegi eset, mis vajaksid parandamist.
replyFromDiscord=**Vastus mängijalt {0}\:** `{1}`
replyLastRecipientDisabled=§6Viimasele sõnumisaatjale vastamine on §ckeelatud§6.
replyLastRecipientDisabledFor=§6Viimasele sõnumisaatjale vastamine on §ckeelatud §6mängijale §c{0}§6.
replyLastRecipientEnabled=§6Viimasele sõnumisaatjale vastamine on §clubatud§6.
@@ -1346,6 +1349,8 @@ unlimitedCommandUsage3=/<käsklus> clear [mängija]
unlimitedCommandUsage3Description=Puhastab kõik lõpmatud asjad sinult või teiselt mängijalt kui on täpsustatud
unlimitedItemPermission=§4Sul puudub luba lõpmatu eseme §c{0}§4 jaoks.
unlimitedItems=§6Lõpmatud esemed\:§r
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
unmutedPlayer=§6Mängija§c {0} §6vaigistus eemaldatud.
unsafeTeleportDestination=§5Teleporteerutav sihtpunkt on ohtlik ning teleporteerimise-ohutus on keelatud.
unsupportedBrand=§4Käitatav serveriplatvorm ei paku selle funktsiooni jaoks kasutusvõimalusi.
@@ -126,6 +126,7 @@ cantReadGeoIpDB=Ei pystytty lukemaan GeoIP tietokantaa\!
cantSpawnItem=§4Sinulla ei ole oikeutta luoda tavaraa§c {0}§4.
cartographytableCommandDescription=Avaa karttapöydän.
cartographytableCommandUsage=/<command>
chatTypeLocal=§[L]
chatTypeSpy=[Vakoilu]
cleaned=Käyttäjätiedot on poistettu.
cleaning=Poistetaan käyttäjätietoja.
@@ -142,6 +143,7 @@ clearinventoryCommandUsage3Description=Poistaa kaiken (tai tietyn määrän) ann
clearinventoryconfirmtoggleCommandDescription=Vaihdettavissa, pyydetäänkö sinua vahvistamaan tavaraluettelon tyhjennys vai ei.
clearinventoryconfirmtoggleCommandUsage=/<command>
commandArgumentOptional=§7
commandArgumentOr=§c
commandArgumentRequired=§e
commandCooldown=§cEt voi kirjoittaa tätä komentoa ajassa {0}.
commandDisabled=§cKomento§6 {0}§c on poistettu käytöstä.
@@ -150,13 +152,18 @@ commandHelpFailedForPlugin=Virhe haettaessa apua lisäosasta\: {0}
commandHelpLine1=§6Komentoapu\: §f/{0}
commandHelpLine2=§6Kuvaus\: §f{0}
commandHelpLine3=§7Käyttö;
commandHelpLine4=§6Myös\: §f{0}
commandHelpLineUsage={0} §6- {1}
commandNotLoaded=§4Komento {0} on väärin ladattu.
compassBearing=§6Osoittaa\: {0} ({1} astetta).
compassCommandDescription=Kuvailee nykyistä katsomiskulmaasi.
compassCommandUsage=/<command>
condenseCommandDescription=Tiivistää esineet pienemmiksi kappaleiksi.
condenseCommandUsage=/<command> [item]
condenseCommandUsage1=/<command>
condenseCommandUsage1Description=Tyhjentää tavaraluottelosi
condenseCommandUsage2=/<command> <item>
condenseCommandUsage2Description=Poistaa tietyn tavaran tavaraluettelostasi
configFileMoveError=Virhe siirrettäessä tiedostoa config.yml varmuuskopio sijaintiin.
configFileRenameError=Virhe nimettäessä tiedostoa temp tiedostoon config.yml
confirmClear=§7§lVAHVISTAAKSESI§7 tavaraluettelon tyhjennyksen, suorita uudellen komento\: §6{0}
@@ -171,9 +178,11 @@ createdKit=§6Luotu paketti §c{0}, §c{1} §6merkinnällä ja viiveellä §c{2}
createkitCommandDescription=Luo kitin pelissä\!
createkitCommandUsage=/<command> <kitname> <delay>
createkitCommandUsage1=/<command> <kitname> <delay>
createkitCommandUsage1Description=Luo kitin annetulla nimellä ja ajalla
createKitFailed=§4Pakkauksen luomisessa tapahtui virhe {0}.
createKitSeparator=§m-----------------------
createKitSuccess=§6Luotu paketti\: §f{0}\n§6Viive\: §f{1}\n§6Osoite\: §f{2}\n§6Kopioi yllä olevan linkin sisältö kits.yml tiedostoon.
createKitUnsupported=§4NBT-tavaroiden sarjoitus on otettu käyttöön, mutta tämä palvelin ei käytä versiota Paper 1.15.2+. Palataan takaisin tavalliseen sarjoitukseen.
creatingConfigFromTemplate=Luodaan config tiedostoa mallista\: {0}
creatingEmptyConfig=Luodaan tyhjää config tiedostoa\: {0}
creative=luova
@@ -184,22 +193,33 @@ customtextCommandUsage=/<alias> - Määritä bukkit.yml-tiedostossa
day=päivä
days=päivää
defaultBanReason=Bannivasara on puhunut\!
deletedHomes=Kaikki kodit poistettu.
deletedHomesWorld=Kaikki kodit kohteessa {0} poistettu.
deleteFileError=Ei voida poistaa tiedostoa\: {0}
deleteHome=§6Koti§c {0} §6on poistettu.
deleteJail=§6Vankila§c {0} §6on poistettu.
deleteKit=§6Pakki§c {0} §6on poistettu.
deleteWarp=§6Warp§c {0} §6on poistettu.
deletingHomes=Poistetaan kaikkia koteja...
deletingHomesWorld=Poistetaan kaikkia koteja kohteessa {0}...
delhomeCommandDescription=Poistaa kodin.
delhomeCommandUsage=/<command> [pelaaja\:]<name>
delhomeCommandUsage1=/<command> <name>
delhomeCommandUsage1Description=Poistaa kotisi annetulla nimellä
delhomeCommandUsage2=/<command> <player>\:<name>
delhomeCommandUsage2Description=Poistaa tietyn pelaajan kodin annetulla nimellä
deljailCommandDescription=Poistaa vankilan.
deljailCommandUsage=/<command> <jailname>
deljailCommandUsage1=/<command> <jailname>
deljailCommandUsage1Description=Poistaa vankilan annetulla nimellä
delkitCommandDescription=Poistaa määritetyn kitin.
delkitCommandUsage=/<command> <kit>
delkitCommandUsage1=/<command> <kit>
delkitCommandUsage1Description=Poistaa kitin annetulla nimellä
delwarpCommandDescription=Poistaa määritetyn warpin.
delwarpCommandUsage=/<command> <warp>
delwarpCommandUsage1=/<command> <warp>
delwarpCommandUsage1Description=Poistaa warpin annetulla nimellä
deniedAccessCommand=§4Pelaajan §c{0} §4pääsy komentoon evättiin.
denyBookEdit=§4Et voi avata tätä kirjaa.
denyChangeAuthor=§4Et voi vaihtaa tämän kirjan kirjoittajaa.
@@ -213,6 +233,15 @@ destinationNotSet=Sijaintia ei ole määritetty\!
disabled=poistettu käytöstä
disabledToSpawnMob=§4Tämän mobin luominen on poistettu käytöstä config tiedostossa.
disableUnlimited=§6Poistettiin käytöstä loputon asettaminen tavaralle§c {0} §6pelaajalta§c {1}§6.
discordbroadcastCommandDescription=Lähettää viestin tietylle Discord-kanavalle.
discordbroadcastCommandUsage=/<command> <channel> <msg>
discordbroadcastCommandUsage1=/<command> <channel> <msg>
discordbroadcastInvalidChannel=§4Discord-kanavaa §c{0}§4 ei ole olemassa.
discordbroadcastPermission=§4Sinulla ei ole oikeuttaa lähettää viestejä kanavalle §c{0}§4.
discordbroadcastSent=§6Viesti lähetettiin kanavalle §c{0}§6\!
discordCommandAccountArgumentUser=Etsittävä Discord-tili
discordCommandAccountDescription=Etsii linkitettyjä Minecraft-tilejä itsellesi tai toiselle Discord-käyttäjälle
discordCommandAccountResponseLinked=Tilisi on yhdistetty Minecraft-tiliin **{0}**
discordCommandUsage=/<command>
discordCommandUsage1=/<command>
discordCommandExecuteReply=Suoritetaan komento\: "/{0}"
@@ -353,6 +382,8 @@ holdPotion=§4Sinulla täytyy olla taikajuoma kädessäsi lisätäksesi siihen e
holeInFloor=§4Reikä lattiassa\!
homeCommandDescription=Teleporttaa sinut kotiisi.
homeCommandUsage=/<command> [pelaaja\:][name]
homeCommandUsage1=/<command> <name>
homeCommandUsage2=/<command> <player>\:<name>
homes=§6Kodit\:§r {0}
homeConfirmation=§6Sinulla on jo koti nimeltä §c{0}§6\!\nKorvataksesi edellisen kotisi, kirjoita komento uudelleen.
homeSet=§6Koti asetettu nykyiseen sijaintiin.
@@ -419,6 +450,7 @@ itemnameClear=§6Olet puhdistanut tämän kohteen nimen.
itemnameCommandDescription=Nimeää tavaran.
itemnameCommandUsage=/<command> [name]
itemnameCommandUsage1=/<command>
itemnameCommandUsage2=/<command> <name>
itemnameInvalidItem=§cSinun täytyy pitää esinettä kädessäsi nimetäksesi sen.
itemnameSuccess=§6Olet nimennyt tavaran kädessäsi\: "§c{0}§6".
itemNotEnough1=§4Sinulla ei ole tarpeeksi tavaroita myytäväksi.
@@ -495,6 +527,8 @@ lightningCommandUsage=/<command> [player] [power]
lightningCommandUsage1=/<command> [pelaaja]
lightningSmited=§6Sinut on salamoitu\!
lightningUse=§6Salamoidaan pelaaja§c {0}
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
listAfkTag=§7[AFK]§f
listAmount=§6Pelaajia palvelimella §c{0}§6 / §c{1}§6.
listAmountHidden=§6Pelaajia palvelimella §c{0}§6/§c{1}§6 maksimi määrästä §c{2}§6.
@@ -811,6 +845,8 @@ setBalOthers=§aAsetit pelaajan {0}§a rahatilanteen arvoon {1}.
setSpawner=§6Vaihdettiin spawnerin tyypiksi§c {0}§6.
sethomeCommandDescription=Asettaa kodin nykyiseen sijaintiisi.
sethomeCommandUsage=/<command> [[pelaaja\:]nimi]
sethomeCommandUsage1=/<command> <name>
sethomeCommandUsage2=/<command> <player>\:<name>
setjailCommandDescription=Luo vankilan tietyllä nimellä [jailname].
setjailCommandUsage=/<command> <jailname>
setjailCommandUsage1=/<command> <jailname>
@@ -1026,6 +1062,8 @@ unlimitedCommandDescription=Antaa sinulle luvan asettaa tavaroita loputtomasti.
unlimitedCommandUsage=/<command> <list|item|clear> [player]
unlimitedItemPermission=§4Ei lupaa rajoittamattomille tavaroille §c{0}§4.
unlimitedItems=§6Loputtomat tavarat\:§r
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
unmutedPlayer=§6Pelaajalta§c {0} §6on poistettu hiljennys.
unsafeTeleportDestination=§4Teleporttikohde ei ole turvallinen ja teleporttiturvallisuus on poistettu käytöstä.
unsupportedBrand=§4Palvelinalusta joka on parhaillaan käytössä, ei tarjoa ominaisuuksia tälle ominaisuudelle.
@@ -526,6 +526,7 @@ kill=§6Pinatay si§c {0}§6.
killCommandDescription=Ipapatay ang tinutukoy na manlalaro.
killCommandUsage=/<command> <manlalaro>
killCommandUsage1=/<command> <manlalaro>
killCommandUsage1Description=Ipapatay yung tinutukoy na manlalaro
killExempt=§4Hindi maaaring patayin si §c{0}§4.
kitCommandDescription=Magkakaroon ng tinutukoy na kit o ititingin ang lahat ng mga kit na pwedeng gamitin.
kitCommandUsage=/<command> [kit] [manlalaro]
@@ -558,6 +559,8 @@ lightningCommandUsage=/<command> [manlalaro] [lakas]
lightningCommandUsage1=/<command> [manlalaro]
lightningSmited=§6Nawelga ka ng kidlat\!
lightningUse=§6Winewelga si§c {0}
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
listAfkTag=§7[AFK]§r
listAmount=§6Mayroong §c{0}§6 ng yung pinakamataas na §c{1}§6 manlalaro na online.
listAmountHidden=§6Mayroong §c{0}§6/§c{1}§6 ng yung pinakamataas na §c{2}§6 manlalaro na online.
@@ -566,13 +569,22 @@ listCommandUsage=/<command> <grupo>
listCommandUsage1=/<command> <grupo>
listGroupTag=§6{0}§r\:
listHiddenTag=§7[NAKATAGO]§r
listRealName=({0})
loadWarpError=§4Nabigong mag-load ng pagkiwal na {0}.
localFormat=§3[L] §r<{0}> {1}
loomCommandDescription=Magbubukas ng habihan.
loomCommandUsage=/<command>
mailClear=§6Upang ibura ang iyong mail, sulatin mo ang§c /mail clear§6.
mailCleared=§6Ang iyong mail ay binura\!
mailCommandDescription=I-papamahalaan ang inter-player at ang intra-server mail.
mailCommandUsage1=/<command> basahin [pahina]
mailCommandUsage2=/<command> burahin [numero]
mailCommandUsage3=/<command> ipadala <manlalaro> <mensahe>
mailDelay=Masyadong madaming mail ang nadala sa huling minuto. Pinakamataas\: {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=§6Matagumpay na dinala ang meyl\!
@@ -631,36 +643,58 @@ nearCommandUsage=/<command> [pangalan-ng-manlalaro] [radyus]
nearCommandUsage1=/<command>
nearCommandUsage3=/<command> <manlalaro>
nearbyPlayers=§6Manlalaro na malapit\:§r {0}
nearbyPlayersList={0}§f(§c{1}m§f)
negativeBalanceError=§4Hindi pinapayagan ang manlalaro upang magkaroon ng negatibong pitaka.
nickChanged=§6Binago ang Nickname.
nickCommandDescription=Ibago ang iyong nickname o ang ng iba-pang manlalaro na iyon.
nickCommandUsage=/<command> [manlalaro] <nickname|OFF>
nickCommandUsage1=/<command> <nickname>
nickCommandUsage2=/<command> OFF
noBreakBedrock=§6Hindi ka pinapayagang magsira ng batong matigas.
northEast=NE
north=N
northWest=NW
noGodWorldWarning=§4Babala\! Ang diyos na kapangyarihan sa ditong mundo ay di-napagana.
none=wala
notFlying=hindi lumilipad
nothingInHand=§4Wala kang bagay sa iyong kamay.
now=ngayon
nukeCommandUsage=/<command> [manlalaro]
nukeCommandUsage1=/<command> [mga manlalaro...]
passengerTeleportFail=§4Ikaw ay hindi maaaring malipat habang dumadala ka ng mga tao.
payCommandUsage=/<command> <manlalaro> <halaga>
payCommandUsage1=/<command> <manlalaro> <halaga>
payconfirmtoggleCommandUsage=/<command>
paytoggleCommandUsage=/<command> [manlalaro]
paytoggleCommandUsage1=/<command> [manlalaro]
pingCommandDescription=Pong\!
pingCommandUsage=/<command>
playtimeCommandUsage=/<command> [manlalaro]
playtimeCommandUsage1=/<command>
playtimeCommandUsage2=/<command> <manlalaro>
pong=Pong\!
potionCommandUsage=/<command> <clear|apply|effect\:<epekto> power\:<lakas> duration\:<durasyon>>
potionCommandUsage1=/<command> clear
powertoolCommandUsage=/<command> [l\:|a\:|r\:|c\:|d\:][utos] [mga argumento] - {player} maaaring palitan ng pangalan ng manlalarong pumindot
powertoolCommandUsage1=/<command> l\:
powertoolCommandUsage2=/<command> d\:
powertoolCommandUsage3=/<command> r\:<cmd>
powertoolCommandUsage4=/<command> <cmd>
powertoolCommandUsage5=/<command> a\:<cmd>
powertooltoggleCommandUsage=/<command>
ptimeCommandUsage=/<command> [list|reset|day|night|dawn|17\:30|4pm|4000ticks] [manlalaro|*]
pweatherCommandUsage=/<command> [list|reset|storm|sun|clear] [manlalaro|*]
pTimeCurrent=§6Ang oras ni §c{0}§6 ay§c {1}§6.
questionFormat=§2[Tanong]§r {0}
rCommandUsage=/<command> <mensahe>
rCommandUsage1=/<command> <mensahe>
realName=§f{0}§r§6 is §f{1}
realnameCommandUsage=/<command> <nickname>
realnameCommandUsage1=/<command> <nickname>
recentlyForeverAlone=§4Naging offline lang si {0}.
recipeCommandUsage=/<command> <item> [numero]
recipeCommandUsage1=/<command> <item> [pahina]
recipeNothing=wala
removeCommandUsage=<command><all|tamed|named|drops|arrows|boats|minecarts|xp|paintings|itemframes|endercrystals|monsters|animals|ambient|mobs|[uri ng mundo]> [radyus|mundo]
repairCommandUsage=/<command> [hand|all]
repairCommandUsage1=/<command>
@@ -756,6 +790,8 @@ unbanipCommandUsage=/<command> <address>
unbanipCommandUsage1=/<command> <address>
unknownItemName=§4Hindi malamang pangalan ng bagay\: {0}.
unlimitedCommandUsage=/<command> <list|item|clear> [manlalaro]
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
userdataMoveBackError=Nabigong maglipat mula sa userdata/{0}.tmp sa userdata/{1}\!
userdataMoveError=Nabigong maglipat mula sa userdata/{0} sa userdata{1}.tmp\!
vanishCommandUsage=/<command> [manlalaro] [ON|OFF]
@@ -240,7 +240,13 @@ discordbroadcastCommandUsage1Description=Envoie le message donné au salon Disco
discordbroadcastInvalidChannel=§4Le salon Discord §c{0}§4 n''existe pas.
discordbroadcastPermission=§4Vous n''avez pas la permission d''envoyer des messages dans le salon §c{0}§4.
discordbroadcastSent=§6Message envoyé à §c{0}§6\!
discordCommandDescription=Envoie le lien d''invitation discord au joueur.
discordCommandAccountArgumentUser=Le compte Discord à rechercher
discordCommandAccountDescription=Recherche le compte Minecraft lié à vous ou à un autre utilisateur Discord
discordCommandAccountResponseLinked=Votre compte est lié au compte Minecraft \: **{0}**
discordCommandAccountResponseLinkedOther=Le compte de {0} est lié au compte Minecraft \: **{1}**
discordCommandAccountResponseNotLinked=Vous n''avez pas de compte Minecraft lié.
discordCommandAccountResponseNotLinkedOther={0} n''a pas de compte Minecraft lié.
discordCommandDescription=Envoie le lien d''invitation Discord au joueur.
discordCommandLink=§6Rejoignez notre serveur Discord à §c{0}§6\!
discordCommandUsage=/<command>
discordCommandUsage1=/<command>
@@ -248,12 +254,20 @@ discordCommandUsage1Description=Envoie le lien d''invitation Discord au joueur
discordCommandExecuteDescription=Exécute une commande console depuis le serveur Minecraft.
discordCommandExecuteArgumentCommand=La commande qui doit être exécutée
discordCommandExecuteReply=Exécution de la commande\: "/{0}"
discordCommandUnlinkDescription=Dissocie le compte Minecraft actuellement lié à votre compte Discord
discordCommandUnlinkInvalidCode=Vous n''avez pas de compte Minecraft lié à Discord \!
discordCommandUnlinkUnlinked=Votre compte Discord a été dissocié de tous les comptes Minecraft associés.
discordCommandLinkArgumentCode=Le code fourni en jeu pour lier votre compte Minecraft
discordCommandLinkDescription=Liez votre compte Discord à votre compte Minecraft en utilisant un code de la commande en jeu /link
discordCommandLinkHasAccount=Vous avez déjà un compte lié \! Pour dissocier votre compte actuel, tapez /unlink.
discordCommandLinkInvalidCode=Code de liaison non valide \! Assurez-vous d''avoir exécuté /link en jeu et d''avoir copié le code correctement.
discordCommandLinkLinked=Votre compte a été lié avec succès \!
discordCommandListDescription=Obtenir la liste des joueurs connectés.
discordCommandListArgumentGroup=Un groupe spécifique auquel limiter vos recherches
discordCommandMessageDescription=Envoie un message à un joueur sur le serveur Minecraft.
discordCommandMessageArgumentUsername=Le joueur à qui envoyer le message
discordCommandMessageArgumentMessage=Le message à envoyer au joueur
discordErrorCommand=Vous avez incorrectement ajouté votre bot à votre serveur. Veuillez suivre le tutoriel dans la configuration et ajouter votre bot en utilisant https\://essentialsx.net/discord.html \!
discordErrorCommand=Vous avez ajouté votre bot à votre serveur de manière incorrecte \! Veuillez suivre le tutoriel dans la configuration et ajouter votre bot en utilisant https\://essentialsx.net/discord.html
discordErrorCommandDisabled=Cette commande est désactivée \!
discordErrorLogin=Une erreur s''est produite lors de la connexion à Discord, ce qui a causé la désactivation du plugin \: \n{0}
discordErrorLoggerInvalidChannel=La connexion à la console Discord a été désactivée en raison d''une définition de canal invalide \! Si vous avez l''intention de le désactiver, définissez l''ID du canal à "none", sinon vérifiez que votre ID de canal est correct.
@@ -265,8 +279,20 @@ discordErrorNoPrimary=Vous n''avez pas défini de salon principal ou votre salon
discordErrorNoPrimaryPerms=Votre bot ne peut pas parler dans votre salon principal, \#{0}. Assurez-vous que votre bot a les permissions de lecture et d''écriture dans tous les salons que vous souhaitez utiliser.
discordErrorNoToken=Aucun jeton fourni\! Veuillez suivre le tutoriel dans la configuration afin de configurer le plugin.
discordErrorWebhook=Une erreur s''est produite lors de l''envoi de messages à votre canal console \! Cela a probablement été causé par la suppression accidentelle de votre webhook console. Cela peut généralement être corrigé en s''assurant que votre bot a la permission "Gérer les Webhooks" et en exécutant "/ess reload".
discordLinkInvalidGroup=Le groupe {0} non valide a été fourni pour le rôle {1}. Les groupes suivants sont disponibles \: {2}
discordLinkInvalidRole=Un identifiant de rôle non valide, {0}, a été fourni pour le groupe\: {1}. Vous pouvez voir l''ID des rôles avec la commande /roleinfo dans Discord.
discordLinkInvalidRoleInteract=Le rôle, {0} ({1}), ne peut pas être utilisé pour la synchronisation de groupe vers rôle, car il est au-dessus du rôle le plus élevé de votre bot. Déplacez le rôle de votre bot au-dessus de "{0}" ou déplacez "{0}" sous le rôle de votre bot.
discordLinkInvalidRoleManaged=Le rôle, {0} ({1}), ne peut pas être utilisé pour la synchronisation de groupe vers rôle car il est géré par un autre bot ou intégration.
discordLinkLinked=§6Pour lier votre compte Minecraft à Discord, tapez §c{0} §6dans le serveur Discord.
discordLinkLinkedAlready=§6Vous avez déjà lié votre compte Discord \! Si vous souhaitez dissocier votre compte Discord, utilisez §c/unlink§6.
discordLinkLoginKick=§6Vous devez lier compte Discord avant de pouvoir rejoindre ce serveur.\n§6Pour lier votre compte Minecraft à Discord, tapez \:\n§c{0}\n§6dans le serveur Discord de ce serveur \:\n§c{1}
discordLinkLoginPrompt=§6Tu dois lier ton compte Discord avant de pouvoir te déplacer, discuter ou interagir avec ce serveur. Pour lier ton compte Minecraft à Discord, tape §c{0} §6dans le serveur Discord de ce serveur \: §c{1}
discordLinkNoAccount=§6Vous n''avez pas de compte Discord lié à votre compte Minecraft.
discordLinkPending=§6Vous avez déjà un code de d''association. Pour terminer la liaison de votre compte Minecraft à Discord, tapez §c{0} §6dans le serveur Discord.
discordLinkUnlinked=§6Vous avez dissocié votre compte Minecraft de tous les comptes Discord associés.
discordLoggingIn=Tentative de connexion à Discord...
discordLoggingInDone=Connexion réussie en tant que {0}
discordMailLine=**Nouveau message de {0}\:** {1}
discordNoSendPermission=Impossible d''envoyer un message dans le salon \: \#{0} Veuillez vous assurer que le bot a la permission "Envoyer des Messages" dans ce salon \!
discordReloadInvalid=Tentative de recharger la configuration de Discord EssentialsX alors que le plugin est en état invalide \! Si vous avez modifié votre configuration, redémarrez votre serveur.
disposal=Poubelle
@@ -314,6 +340,7 @@ enderchestCommandUsage2=/<command> <joueur>
enderchestCommandUsage2Description=Ouvre le coffre de l''Ender du joueur ciblé
errorCallingCommand=Erreur en appelant la commande /{0}
errorWithMessage=§cErreur \:§4 {0}
essChatNoSecureMsg=EssentialsX Chat version {0} ne prend pas en charge le chat sécurisé sur ce logiciel serveur. Mettez à jour EssentialsX, et si ce problème persiste, informez-en les développeurs.
essentialsCommandDescription=Recharge EssentialsX.
essentialsCommandUsage=/<command>
essentialsCommandUsage1=/<command> reload
@@ -481,6 +508,7 @@ homeCommandUsage2=/<command> <joueur>\:<nom>
homeCommandUsage2Description=Vous téléporte à la résidence du joueur spécifié avec le nom donné
homes=§6Résidences \:§r {0}
homeConfirmation=§6Vous avez déjà une résidence nommée §c{0} §6\!\nPour écraser votre résidence existante, tapez la commande à nouveau.
homeRenamed=§6Le home §c{0} §6a été renommée en §c{1}§6.
homeSet=§7Résidence définie.
hour=heure
hours=heures
@@ -533,6 +561,7 @@ invseeCommandDescription=Voir l''inventaire des autres joueurs.
invseeCommandUsage=/<command> <joueur>
invseeCommandUsage1=/<command> <joueur>
invseeCommandUsage1Description=Ouvre l''inventaire du joueur spécifié
invseeNoSelf=§cVous ne pouvez voir que les inventaires des autres joueurs.
is=est
isIpBanned=§6L''adresse IP §c{0} §6est bannie.
internalError=§cUne erreur interne est survenue lors de l''exécution de cette commande.
@@ -658,6 +687,10 @@ lightningCommandUsage2=/<command> <joueur> <puissance>
lightningCommandUsage2Description=La foudre frappe le joueur ciblé avec la puissance donnée
lightningSmited=§7Vous venez d''être foudroyé(e) \!
lightningUse=§c{0} §6s''est fait(e) foudroyer
linkCommandDescription=Génère un code pour lier votre compte Minecraft à Discord.
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
linkCommandUsage1Description=Génère un code pour la commande /link sur Discord
listAfkTag=§7[AFK]§r
listAmount=§9Il y a §c{0}§9 joueurs en ligne sur §c{1}§9 au total.
listAmountHidden=§6Il y a §c{0}§6/§c{1}§6 joueurs en ligne sur un maximum de §c{2}§6.
@@ -1007,6 +1040,12 @@ removeCommandUsage1Description=Supprime tous les mobs du type donné dans le mon
removeCommandUsage2=/<command> <type d’entité> <rayon> [monde]
removeCommandUsage2Description=Supprime tous les mobs du type donné dans le rayon donné dans le monde actuel ou dans un autre monde si spécifié
removed=§7{0} entités supprimées.
renamehomeCommandDescription=Renomme un home.
renamehomeCommandUsage=/<command> <[joueur\:]nom> <new name>
renamehomeCommandUsage1=/<command> <nom> <nouveau nom>
renamehomeCommandUsage1Description=Renomme la résidence avec le nom donné
renamehomeCommandUsage2=/<command> <player>\:<name> <new name>
renamehomeCommandUsage2Description=Renomme la résidence du joueur spécifié avec le nom donné
repair=§6Vous avez réparé votre \: §c{0}§6.
repairAlreadyFixed=§7Cet objet n''a pas besoin de réparation.
repairCommandDescription=Répare la durabilité d''un ou de tous les objets.
@@ -1018,7 +1057,7 @@ repairCommandUsage2Description=Répare tous les objets dans votre inventaire
repairEnchanted=§7Vous n''êtes pas autorisé à réparer les objets enchantés.
repairInvalidType=§4Cet objet ne peut pas être réparé.
repairNone=§4Aucun objet ne nécessite de réparation.
replyFromDiscord=**Réponse de {0}\:** `{1}`
replyFromDiscord=**Réponse de {0}\:** {1}
replyLastRecipientDisabled=§6Répondre au dernier destinataire du message \: §cdésactivé§6.
replyLastRecipientDisabledFor=§6Répondre au dernier destinataire du message §cdésactivé §6pour §c{0}§6.
replyLastRecipientEnabled=§6Répondre au dernier destinataire du message \: §cactivé§6.
@@ -1076,7 +1115,9 @@ serverTotal=§6Total du serveur \: §c{0}
serverUnsupported=Vous utilisez une version de serveur non prise en charge \!
serverUnsupportedClass=Classe déterminant le statut \: {0}
serverUnsupportedCleanroom=Vous exécutez un serveur qui ne prend pas correctement en charge les plugins Bukkit qui dépendent du code interne de Mojang. Envisagez d''utiliser un équivalant à Essentials compatible avec votre logiciel serveur.
serverUnsupportedDangerous=Vous utilisez un fork de serveur qui est connu pour être extrêmement dangereux et qui entraîne une perte de données. Il est fortement recommandé de passer à un logiciel serveur plus stable comme Paper.
serverUnsupportedLimitedApi=Vous exécutez un serveur avec des fonctionnalités API limitées. EssentialsX continuera de fonctionner, mais certaines fonctionnalités seront désactivées.
serverUnsupportedDumbPlugins=Vous utilisez des plugins connus pour causer de graves problèmes avec EssentialsX et d''autres plugins.
serverUnsupportedMods=Vous exécutez un serveur qui ne prend pas correctement en charge les plugins Bukkit. Les plugins Bukkit ne devraient pas être utilisés avec les mods Forge/Fabric \! Envisagez d''utiliser ForgeEssentials ou SpongeForge + Nucleus.
setBal=§aVotre solde a été modifié à {0}.
setBalOthers=§aVous avez modifià le solde de {0} à {1}.
@@ -1226,6 +1267,7 @@ teleportRequestTimeoutInfo=§6Cette demande de téléportation expirera dans§c
teleportTop=§6Téléportation vers le haut.
teleportToPlayer=§6Téléportation vers §c{0}§6.
teleportOffline=§6Le joueur §c{0}§6 est actuellement hors-ligne. Vous pouvez vous téléporter à lui en utilisant /otp.
teleportOfflineUnknown=§6Impossible de trouver la dernière position connue de §c{0}§6.
tempbanExempt=§4Vous ne pouvez pas bannir temporairement ce joueur.
tempbanExemptOffline=§4Vous ne pouvez pas bannir temporairement les joueurs déconnectés.
tempbanJoin=Vous êtes banni(e) de ce serveur pendant {0}. Raison \: {1}
@@ -1390,6 +1432,10 @@ unlimitedCommandUsage3=/<command> clear [joueur]
unlimitedCommandUsage3Description=Efface tous les objets illimités pour vous ou pour un autre joueur si spécifié
unlimitedItemPermission=§4Pas de permission pour l''objet illimité §c{0}§4.
unlimitedItems=§6Objets illimités \:§r
unlinkCommandDescription=Déconnecte votre compte Minecraft du compte Discord actuellement lié.
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
unlinkCommandUsage1Description=Déconnecte votre compte Minecraft du compte Discord actuellement lié.
unmutedPlayer=§6Le joueur§c {0} §6a de nouveau la parole.
unsafeTeleportDestination=§4La destination est dangereuse et la téléportation sans risque est désactivée.
unsupportedBrand=§4La plateforme de serveur que vous utilisez actuellement ne possède pas les prérequis nécessaires à cette fonctionnalité.
@@ -1410,6 +1456,9 @@ userIsAwaySelf=§7Vous êtes maintenant AFK.
userIsAwaySelfWithMessage=§7Vous êtes maintenant AFK.
userIsNotAwaySelf=§7Vous n''êtes plus AFK.
userJailed=§6Vous avez été emprisonné(e) \!
usermapEntry=§c{0} §6est associé à §c{1}§6.
usermapPurge=§6Vérification des fichiers dans les données utilisateur qui ne sont pas associés, les résultats seront enregistrés dans la console. Mode destructif\: {0}
usermapSize=§6Les utilisateurs actuellement mis en cache dans la carte de l''utilisateur sont §c{0}§6/§c{1}§6/§c{2}§6.
userUnknown=§4Attention \: l''utilisateur "§c{0}§4" n''est jamais venu sur ce serveur.
usingTempFolderForTesting=Utilise un fichier temporaire pour un test.
vanish=§6Invisibilité pour {0}§6 \: {1}
@@ -1422,6 +1471,7 @@ versionCheckDisabled=§6Vérification des mises à jour désactivée dans la con
versionCustom=§6Impossible de vérifier votre version \! S’agit-il d’une version auto-générée ? Informations de la build \: §c{0}§6.
versionDevBehind=§4Vous êtes en retard de §c{0} §4version(s) de développement d‘EssentialsX \!
versionDevDiverged=§6Vous utilisez une version expérimentale d''EssentialsX qui est §c{0} §6builds en retard de la dernière version de développement \!
versionDevDivergedBranch=§6Branche vedette \: §c{0}§6.
versionDevDivergedLatest=§6Vous utilisez une version expérimentale à jour d''EssentialsX \!
versionDevLatest=§6Vous utilisez la dernière version de développement d''EssentialsX \!
versionError=§4Erreur lors de la récupération des informations sur la version d''EssentialsX \! Informations sur la build \: §c{0}§6.
@@ -239,6 +239,11 @@ discordbroadcastCommandUsage1Description=שולח את ההודעה הנתונה
discordbroadcastInvalidChannel=ערוץ §4דיסקורד §c{0}§4 אינו קיים.
discordbroadcastPermission=§4אין לך הרשאה לשלוח הודעות לערוץ הזה §c{0}§4.
discordbroadcastSent=§6ההודעה נשלחה אל §c{0}§6\!
discordCommandAccountDescription=מחפש את משתמש המיינקראפט המחובר בשבילך או בשביל משתמש דיסקורד אחר
discordCommandAccountResponseLinked=המשתמש שלך מחובר למשתמש המיינקראפט\: **{0}**
discordCommandAccountResponseLinkedOther=המשתמש של {0} מחובר למשתמש המיינקראפט\: **{1}**
discordCommandAccountResponseNotLinked=אין לך משתמש מיינקראפט מחובר.
discordCommandAccountResponseNotLinkedOther=ל{0} אין משתמש מיינקראפט מחובר.
discordCommandDescription=שולח את קישור הזמנת הדיסקורד לשחקן.
discordCommandLink=§בואו לשרת דיסקורד שלנו בקישור-§c{0}§6\!
discordCommandUsage=/<command>
@@ -247,12 +252,20 @@ discordCommandUsage1Description=שולח את קישור הזמנה לדיסקר
discordCommandExecuteDescription=מבצע פקודת קונסולה בשרת מיינקראפט.
discordCommandExecuteArgumentCommand=הפקודה שיש לבצע
discordCommandExecuteReply=מבצע פקודה\: "\\{0}"
discordCommandUnlinkDescription=מנתק את משתמש המיינקראפט שכרגע מחובר למשתמש הדיסקורד שלך
discordCommandUnlinkInvalidCode=אין לך משתמש מיינקראפט מחובר לדיסקורד\!
discordCommandUnlinkUnlinked=משתמש הדיסקורד שלך התנתק מכל משתמשי המיינקראפט המשויכים.
discordCommandLinkArgumentCode=הקוד המסופק בתוך המשחק בכדי לחבר את משתמש המיינקראפט שלך
discordCommandLinkDescription=מחבר את משתמש הדיסקורד שלך עם משתמש המיינקראפט שלך בעזרת הקוד מתוך הפקודה link/ בתוך המשחק
discordCommandLinkHasAccount=כבר יש לך משתמש מחובר\! כדי לנתק את המשתמש הנוכחי, כתוב unlink/.
discordCommandLinkInvalidCode=קוד קישור לא אמיתי\! אנא וודא/י שהרצת את הפקודה link/ בתוך המשחק והעתקת את הקוד כמו שצריך.
discordCommandLinkLinked=חיבר את המשתמש שלך בהצלחה\!
discordCommandListDescription=מקבל רשימה של כל החשקנים המחוברים.
discordCommandListArgumentGroup=קבוצה ספציפית בשביל להגביל את החיפוש השחקנים לפיה
discordCommandMessageDescription=שולח הודעות לשחקן בשרת המיינקראפט.
discordCommandMessageArgumentUsername=השחקן שאליו יש לשלוח את ההודעה
discordCommandMessageArgumentMessage=ההודעה שיש לשלוח לשחקן
discordErrorCommand=הוספתם את הבוט שלכם לשרת שלכם בצורה שגויה. אנא עקובו אחר המדריך ההגדרה והוסיפו את הבוט שלכם באמצעות https\://essentialsx.net/discord.html\!
discordErrorCommand=אתה הוספת את הבוט שלך לשרת שלך בצורה לא נכונה\! בבקשה עקוב אחר המדריך ב"קונפיג" וצרף את הבוט שלך בעזרת https\://essentialsx.net/discord.html
discordErrorCommandDisabled=הפקודה הזו מושבתת\!
discordErrorLogin=אירעה שגיאה בעת הכניסה לדיסקורד, שגרמה לפלאגין לבטל את עצמו\:\n{0}
discordErrorLoggerInvalidChannel=העתקת קונסולה לדיסקרוד הושבת עקב הגדרת ערוץ לא חוקית\! אם אתם מתכוונים להשבית אותו, הגדירו את channel ID ל"none"; אחרת בידוקו שמזהה הערוץ שלכם נכון.
@@ -266,6 +279,7 @@ discordErrorNoToken=אין לבוט token\! אנא עקובו אחר המדרי
discordErrorWebhook=אירעה שגיאה בעת שליחת הודעות לערוץ הקונסולה שלכם\! זה כנראה נגרם על ידי מחיקה בטעות של ה-webhook של הקונסולה שלכם. אפשר לתקן את זה, פשוט מאוד הגדירו מחדש את ההרשאות "Manage Webhooks" והריצו את הפקודה "\\ess reload".
discordLoggingIn=מנסה להיכנס לדיסקורד...
discordLoggingInDone=נכנס בהצלחה בתור {0}
discordMailLine=**אימייל חדש מ{0}\:** {1}
discordNoSendPermission=לא ניתן לשלוח הודעה בערוץ\: \#{0} אנא ודאו שלבוט יש הרשאת "Send Messages" בערוץ זה\!
discordReloadInvalid=ניסיתי לטעון מחדש את תצורת EssentialsX Discord בזמן שהפלאגין במצב לא חוקי\! אם שיניתם את ההגדרות, הפעילו מחדש את השרת שלכם.
disposal=פח זבל
@@ -425,19 +439,35 @@ helpopCommandUsage=\\<command> <message>
helpopCommandUsage1=\\<command> <message>
holdBook=אתה לא מחזיק בספר כתיבה.
holeInFloor=חור ברצפה \!
homeCommandDescription=השתגר לבית שלך.
homeCommandUsage=\\<command> [player\:][name]
homeCommandUsage1=\\<command> <name>
homeCommandUsage2=\\<command> <player>\:<name>
homeCommandUsage2Description=משגר אותך לבית של השחקן הספציפי עם השם הניתן
homes=§6בתים\:§r {0}
homeConfirmation=§6כבר יש לך בית בשם §c{0}§6\!\nכדי להחליף את הבית הנוכחי שלך, הקלד את הפקודה בשנית.
homeSet=הבית הוגדר.
hour=שעה
hours=שעות
ice=§6אתה מרגיש שקר לך יותר...
iceCommandDescription=מקרר את השחקן.
iceCommandUsage=שחקן
iceCommandUsage1=/<command>
iceCommandUsage1Description=מקרר אותך
iceCommandUsage2=\\<command> <player>
iceCommandUsage2Description=מקרר את השחקן שניתן
iceCommandUsage3=/<command> *
iceCommandUsage3Description=מקרר את כל השחקנים המחוברים
iceOther=§6מקרר§c {0}§6.
ignoreCommandDescription=מתעלם או מבטל התעלמות משחקן.
ignoreCommandUsage=\\<command> <player>
ignoreCommandUsage1=\\<command> <player>
ignoreCommandUsage1Description=מתעלם או מבטל התעלמות של השחקן הניתן
ignoredList=§6מתעלם מהם\:§r {0}
ignoreExempt=§4אתה לא יכול להתעלם מהשחקן הזה.
ignorePlayer=§6אתה מתעלם מהשחקן §c {0} §6מעכשיו on.
illegalDate=תבנית תאריך לא חוקית.
infoAfterDeath=§6אתה נהרגת ב §e{0} §6במיקום §e{1}, {2}, {3}§6.
infoChapter=§6בחר פרק\:
infoCommandUsage=\\<command> [chapter] [page]
infoUnknownChapter=\n§4נתון לא ידוע.\n
@@ -462,6 +492,7 @@ itemloreCommandUsage2=\\<command> set <line number> <text>
itemloreCommandUsage3=\\<command> clear
itemMustBeStacked=\n§4החפץ חייב לעבור בכמויות. כמות של 2s יהיה שתי סטאקים, וכו''.\n
itemNames=\n§6שמות קצרים של החפץ\:§r {0}\n
itemnameCommandDescription=מונה את הפריט.
itemnameCommandUsage=\\<command> [name]
itemnameCommandUsage1=/<command>
itemnameCommandUsage2=\\<command> <name>
@@ -474,35 +505,59 @@ itemdbCommandUsage1=\\<command> <item>
jailAlreadyIncarcerated=\n§4השחקן כבר בכלא\:§c {0}\n
jailMessage=\n§4אתה עושה את הפשע, אתה עושה את הזמן.\n
jailNotExist=הכלא הזה לא קיים.
jailNotifySentenceExtended=§6זמן השחקן של §c{0} §6הוארך ל- §c{1} §6על ידי §c{2}§6.
jailReleased=השחקן x שוחרר מהכלא.
jailReleasedPlayerNotify=\n§6אתה שוחררת מהכלא\!\n
jailSentenceExtended=\n§6זמן בכלא עומד על §c{0}§6.\n
jailSet=\n§6כלא§c {0} §6נוצר.\n
jailWorldNotExist=הכלא הזה לא קיים.
jumpEasterDisable=§6מצב המכשף המעופף בוטל.
jumpEasterEnable=§6מצב המכשף המעופף הופעל.
jailsCommandDescription=מונה את כל בתי הכלא.
jailsCommandUsage=/<command>
jumpCommandDescription=קופץ לבלוק הקרוב ביותר בקו הראייה.
jumpCommandUsage=/<command>
jumpError=\n§4זה יכאב למוח של המחשב שלך.\n
kickCommandDescription=מעיף את השחקן הניתן ללא סיבה.
kickCommandUsage=/<command> <player> [reason]
kickCommandUsage1=/<command> <player> [reason]
kickCommandUsage1Description=מרחיק את השחקן הניתן עם סיבה אפשרית
kickDefault=הוציאו אותך מהשרת.
kickedAll=\n§4כל שחקני השרת נותקוr.\n
kickExempt=אתה לא יכול לעשות kick לשחקן הזה.
kickallCommandDescription=מעיף את כל השחקנים מהשרת מלבד מבצע הפקודה.
kickallCommandUsage=\\<command> [reason]
kickallCommandUsage1=\\<command> [reason]
kickallCommandUsage1Description=מעיף את כל השחקנים עם סיבה אפשרית
kill=הרג
killCommandDescription=הורג שחקן שניתן.
killCommandUsage=\\<command> <player>
killCommandUsage1=\\<command> <player>
killCommandUsage1Description=הורג את השחקן שניתן
killExempt=אתה לא יכול להרוג x
kitCommandDescription=משיג את הקיט הניתן או מראה את כל הקיטים הזמינים.
kitCommandUsage=\\<command> [kit] [player]
kitCommandUsage1=/<command>
kitCommandUsage1Description=מונה את כל הקיטים הזמינים
kitCommandUsage2=/<command> <kit> [player]
kitCommandUsage2Description=נותן את הקיט שניתן לך או לשחקן אחר אם פורט
kitContains=§6קיט §c{0} §6מכיל\:
kitCost=\ §7§o({0})§r
kitDelay=§m{0}§r
kitError=\n§4אין ערכות שנמצאו.\n
kitError2=\n§4הערכה מוגדרת לא כראוי. צור קשר עם מנהל.\n
kitError3=לא יכול לתת את פריט הקיט "{0}" לשחקן {1} מאחר והפריט מחייב Paper 1.15.2+ כדי לפרש.
kitGiveTo=מביא kit ל x
kitInvFull=\n§4התיק שלך היה מלא, ערכה נזרקה לרצפה.\n
kitInvFullNoDrop=§4אין מספיק מקום באינוונטורי שלך לקיט הזה.
kitItem=§6- §f{0}
kitNotFound=\n§4ערכה זאת אינה קיימת.\n
kitOnce=\n§4אינך יכול להשתמש בערכה זאת שוב.\n
kitReceive=\n§6נותן ערכה§c {0}§6.\n
kitReset=§6 מאפשר את זמני ההמתנה לקיט §c{0}§6.
kitresetCommandDescription=מאפס את זמני ההמתנה לקיט שניתן.
kitresetCommandUsage=/<command> <kit> [player]
kitresetCommandUsage1=/<command> <kit> [player]
kits=\n§6ערכות\:§r {0}\n
kittycannonCommandUsage=/<command>
kitTimed=\n§4תוכל להשתמש בערכה זאת רק בעוד§c {0}§4.\n
@@ -511,6 +566,8 @@ lightningCommandUsage1=שחקן
lightningCommandUsage2=\\<command> <player> <power>
lightningSmited=\n§6ברק נורה\!\n
lightningUse=\n§6פוגע עם ברק ב§c {0}\n
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
listAfkTag=§7[רחוק מהמקלדת]§r
listAmount=\n§6יש כרגע §c{0}§6 מתוך מקסימום שחקנים של §c{1}§6 שחקנים מחוברים.\n
listCommandUsage=\\<command> [group]
@@ -830,6 +887,8 @@ unlimitedCommandUsage=\\<command> <list|item|clear> [player]
unlimitedCommandUsage1=\\<command> list [player]
unlimitedCommandUsage2=\\<command> <item> [player]
unlimitedCommandUsage3=\\<command> clear [player]
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
vanishCommandUsage=\\<command> [player] [on|off]
vanishCommandUsage1=שחקן
warpCommandUsage=\\<command> <pagenumber|warp> [player]
@@ -248,6 +248,8 @@ kittycannonCommandUsage=/<command>
kitTimed=§4Ti ne mozes koristiti taj kit ponovno za jos§c {0}§4.
lightningSmited=&7Thor ga je pogodio grmljavinom\!
lightningUse=&7Grmimo na &3{0}&7
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
listAfkTag=&7[AFK]&r
listAmount=§6Online su §c{0}§6 od maksimalno §c{1}§6 igrača online.
listHiddenTag=&7[Ne Vidljiv]&r
@@ -435,6 +437,8 @@ tps=&7Trenutacni TPS \= &3{0}
typeTpaccept=§6Za teleport, kucaj §c/tpaccept§6.
typeTpdeny=§6Za odbiti ovaj zahtjev, kucaj §c/tpdeny§6.
unignorePlayer=&7Ti neignoriras igrace &3{0} &7vise.
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
unmutedPlayer=§6Igrac§c {0} §6unmutan.
unvanishedReload=&7Reload je, zato si sada vidljiv, login se.
userAFK=&3{0} &7je trenutno AFK i mozda nece vam odgovoriti.
@@ -253,7 +253,7 @@ discordCommandListArgumentGroup=Egy adott csoport, amelyre korlátozza a keresé
discordCommandMessageDescription=Üzenetet küld egy játékosnak a Minecraft szerveren.
discordCommandMessageArgumentUsername=A játékos, akinek az üzenetet küldi
discordCommandMessageArgumentMessage=Az üzenet amit a játékosnak küld
discordErrorCommand=Helytelenül adta hozzá BOTját a szerveréhez. Kérjük, kövesse a konfigurációs útmutatót, és adja hozzá BOTját a https\://essentialsx.net/discord.html használatával\!
discordErrorCommand=Rosszul adtad hozzá a botodat a szerveredhez\! Kérjük, kövesd a configban található útmutatót, és add hozzá a botodat a https\://essentialsx.net/discord.html segítségével
discordErrorCommandDisabled=Ez a parancs le van tiltva\!
discordErrorLogin=Hiba történt a Discordba való bejelentkezéskor, ami miatt a plugin letiltotta magát\:\n{0}
discordErrorLoggerInvalidChannel=A Discord konzol naplózása érvénytelen csatorna -definíció miatt le van tiltva\! Ha letiltani kívánja, állítsa a csatornaazonosítót "nincs" értékre; Ellenkező esetben ellenőrizze, hogy a csatornaazonosító helyes -e.
@@ -262,6 +262,7 @@ discordErrorNoGuild=Érvénytelen vagy hiányzó szerver -azonosító\! Kérjük
discordErrorNoGuildSize=A BOTja nincs a szervereken\! Kérjük, kövesse a konfigurációs útmutatót a Plugin beállításához.\n\n
discordErrorNoPerms=A BOTja nem látja vagy nem tud beszélni egyetlen csatornán sem\! Kérjük, győződjön meg arról, hogy a BOT olvasási és írási jogosultsággal rendelkezik minden használni kívánt csatornán.
discordErrorNoPrimary=Nem adott meg elsődleges csatornát, vagy a megadott elsődleges csatorna érvénytelen. Visszatérés az alapértelmezett csatornára\: \#{0}.
discordErrorNoPrimaryPerms=A botod nem tud beszélni az elsődleges csatornádon, a(z) \#{0} csatornán. Kérjük, győződjön meg róla, hogy botja rendelkezik olvasási és írási jogosultsággal minden olyan csatornán, amelyet használni kíván.
discordErrorNoToken=Token nincs megadva\! Kérjük, kövesse a konfigurációs útmutatót a Plugin beállításához.
discordErrorWebhook=Hiba történt üzenetek küldése közben a konzol csatornájára\! Ezt valószínűleg a konzol webhookjának véletlen törlése okozta. Ez általában javítható úgy, hogy a BOT rendelkezik a "Webhooks kezelése" jogosultsággal és ez után futtassa le a "/ess reload" parancsot.
discordLoggingIn=Belépés a Discordba...
@@ -313,6 +314,7 @@ enderchestCommandUsage2=/<command> <játékos>
enderchestCommandUsage2Description=Megnyitja a megadott játékos végzetládáját
errorCallingCommand=Hiba a parancs meghívásakor /{0}
errorWithMessage=§cHiba\:§4 {0}
essChatNoSecureMsg=Az EssentialsX Chat {0} verziója nem támogatja a biztonságos csevegést ezen a kiszolgálószoftveren. Frissítse az EssentialsX-et, és ha a probléma továbbra is fennáll, értesítse a fejlesztőket.
essentialsCommandDescription=Essentials újratöltése.
essentialsCommandUsage=/<command>
essentialsCommandUsage1=/<command> újratöltés
@@ -371,6 +373,7 @@ fireballCommandUsage2=/<command> <fireball|small|large|arrow|skull|egg|snowball|
fireworkColor=§4Érvénytelen tűzijáték-töltési paramétereket adtál meg, először a színt kell beállítani.
fireworkCommandDescription=Lehetővé teszi a tűzijáték-halom módosítását.
fireworkCommandUsage=/<command> <<meta param>|power [mennyiség]|clear|fire [mennyiség]>
fireworkCommandUsage4=/<command> <meta>
fireworkCommandUsage4Description=A kezedben tartott tüzijátékhoz hozzáadja a megadott effektet
fireworkEffectsCleared=§6Az összes effekt eltávolítva a tartott halomról.
fireworkSyntax=§6Tűzijáték paraméterek\:§c color\:<color> [fade\:<color>] [shape\:<shape>] [effect\:<effect>]\n§6Több szín/effektus használatához vesszővel kell elválasztani az értékeket. pl.\: §cred,blue,pink\n§6Alakzatok\:§c star, ball, large, creeper, burst §6Effektek\:§c trail, twinkle.
@@ -389,6 +392,7 @@ gameModeInvalid=§4Meg kell adnod egy érvényes játékost/módot.
gamemodeCommandDescription=Játékmód megváltoztatása.
gamemodeCommandUsage=/<command> <survival|creative|adventure|spectator> [játékos]
gamemodeCommandUsage1=/<command> <survival|creative|adventure|spectator> [játékos]
gamemodeCommandUsage1Description=Beállítja a saját vagy egy másik játékos játékmódját, ha meg van adva
gcCommandDescription=Kiírja a memória, üzemidő és tick infót.
gcCommandUsage=/<command>
gcfree=§6Szabad memória\:§c {0} MB.
@@ -403,6 +407,7 @@ getposCommandUsage1Description=Megmutatja a koordinátádat vagy egy másik ját
giveCommandDescription=Egy tárgyat ad a játékosnak.
giveCommandUsage=/<command> <játékos> <tárgy|numerikus> [mennyiség [tárgymeta...]]
giveCommandUsage1=/<command> <játékos> <tárgy> [mennyiség]
giveCommandUsage2=/<command> <játékos> <tárgy> <összeg> <meta>
geoipCantFind=§c{0}§a ismeretlen országból§6 jött.
geoIpErrorOnJoin=Nem sikerült letölteni a(z) {0} GeoIP adatait. Kérjük, ellenőrizd, hogy a licenckulcs és a konfiguráció helyes-e.
geoIpLicenseMissing=Nem található licenckulcs\! Kérjük látogass el az https\://essentialsx.net/geoip webhelyre az első telepítési utasításokért.
@@ -457,12 +462,16 @@ holeInFloor=§4Lyuk a padlóban\!
homeCommandDescription=Teleportál az otthonodhoz.
homeCommandUsage=/<command> [játékos\:][név]
homeCommandUsage1=/<command> <név>
homeCommandUsage1Description=Teleportál a megadott nevű otthonodba
homeCommandUsage2=/<command> <játékos>\:<név>
homeCommandUsage2Description=A megadott nevű játékos otthonába teleportál a megadott névvel
homes=§6Otthonok\:§r {0}
homeConfirmation=§6Már van egy ilyen nevű otthonod §c{0}§6\!\nA meglévő otthon felülírásához írd be újra a parancsot.
homeRenamed=§6Home §c{0} §6 át lett nevezve §c{1}§6-ra.
homeSet=§6Beállítva otthonnak ez a hely.
hour=óra
hours=óra
ice=§6Sokkal hidegebbnek érzed magad...
iceCommandUsage=/<command> [játékos]
iceCommandUsage1=/<command>
iceCommandUsage2=/<command> <játékos>
@@ -607,6 +616,8 @@ lightningCommandUsage=/<command> [játékos] [erő]
lightningCommandUsage1=/<command> [játékos]
lightningSmited=§6A villám lesújtott rád\!
lightningUse=§6Villám lesujtása§c {0}§6-ra/re.
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
listAfkTag=§7[Nincs gépnél]§r
listAmount=§6Jelenleg §c{0}§6 játékos online a maximális §c{1}§6 játékosból.
listAmountHidden=§6Jelenleg §c{0}§6/§c{1}§6 játékos online a maximális §c{2}§6 játékosból.
@@ -1153,6 +1164,8 @@ unlimitedCommandDescription=Lehetővé teszi a tárgyak korlátlan lehelyezésé
unlimitedCommandUsage=/<command> <list|item|clear> [játékos]
unlimitedItemPermission=§4Nincs jogod a végtelenségre a következő tárgynál\: §c{0}§4.
unlimitedItems=§6Végtelen tárgyak\:§r
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
unmutedPlayer=§c{0}§6-nak/-nek fel lett oldva a némítása.
unsafeTeleportDestination=§4A teleport cél nem biztonságos, és a teleport-safety le van tiltva.
unsupportedBrand=§4A jelenleg futtatott szerverplatform nem biztosítja ehhez a funkcióhoz az adottságokat.
@@ -240,6 +240,12 @@ discordbroadcastCommandUsage1Description=Invia il messaggio dato al canale Disco
discordbroadcastInvalidChannel=§4Il canale Discord §c{0}§4 non esiste.
discordbroadcastPermission=§4Non hai il permesso di inviare messaggi al canale §c{0}§4.
discordbroadcastSent=§6Messaggio inviato a §c{0}§6\!
discordCommandAccountArgumentUser=Account Discord da cercare
discordCommandAccountDescription=Cerca l''account Minecraft collegato per te stesso o per un altro utente Discord
discordCommandAccountResponseLinked=Il tuo account è collegato all''account Minecraft\: **{0}**
discordCommandAccountResponseLinkedOther=Accaunt di {0} è collegato all''account Minecraft\: **{1}**
discordCommandAccountResponseNotLinked=Non hai un account di Minecraft collegato.
discordCommandAccountResponseNotLinkedOther={0} non ha un account di Minecraft collegato.
discordCommandDescription=Invia link di invito per Discord al giocatore.
discordCommandLink=§6Unisciti al nostro server Discord a §c{0}§6\!
discordCommandUsage=/<command>
@@ -248,12 +254,20 @@ discordCommandUsage1Description=Invia link di invito per Discord al giocatore
discordCommandExecuteDescription=Esegue un comando console sul server di Minecraft.
discordCommandExecuteArgumentCommand=Il comando da eseguire
discordCommandExecuteReply=Esecuzione comando\: "/{0}"
discordCommandUnlinkDescription=Scollega l''account Minecraft attualmente collegato al tuo account Discord
discordCommandUnlinkInvalidCode=Al momento non hai un account Minecraft collegato a Discord\!
discordCommandUnlinkUnlinked=Il tuo account Discord è stato scollegato da tutti gli account di Minecraft associati.
discordCommandLinkArgumentCode=Il codice fornito nel gioco per collegare il tuo account Minecraft
discordCommandLinkDescription=Collega il tuo account Discord con il tuo account Minecraft utilizzando un codice dal comando in-game /link
discordCommandLinkHasAccount=Hai già un account collegato\! Per scollegare il tuo account corrente, digita /unlink.
discordCommandLinkInvalidCode=Codice di collegamento non valido\! Assicurati di aver eseguito /link nel gioco e copiato correttamente il codice.
discordCommandLinkLinked=Collegato con successo al tuo account\!
discordCommandListDescription=Ottiene un elenco di giocatori online.
discordCommandListArgumentGroup=Un gruppo specifico per limitare la ricerca di
discordCommandMessageDescription=Messaggi di un giocatore sul server di Minecraft.
discordCommandMessageArgumentUsername=Il giocatore a cui inviare il messaggio
discordCommandMessageArgumentMessage=Il messaggio da inviare al giocatore
discordErrorCommand=Hai aggiunto il tuo bot al server in modo errato. Segui il tutorial nella configurazione e aggiungi il tuo bot usando https\://essentialsx.net/discord.html\!
discordErrorCommand=Hai aggiunto il tuo bot al tuo server in modo errato\! Segui il tutorial nella configurazione e aggiungi il tuo bot usando https\://essentialsx.net/discord.html
discordErrorCommandDisabled=Questo comando è disabilitato\!
discordErrorLogin=Si è verificato un errore durante l''accesso a Discord, che ha causato la disattivazione del plugin\: \n{0}
discordErrorLoggerInvalidChannel=Il log della console Discord è stato disabilitato a causa di una definizione di canale non valida\! Se hai intenzione di disattivarlo, imposta l''ID del canale su "none"; altrimenti controlla che l''ID del tuo canale sia corretto.
@@ -265,8 +279,20 @@ discordErrorNoPrimary=Non hai definito un canale primario o il canale primario d
discordErrorNoPrimaryPerms=Il tuo bot non può parlare nel tuo canale principale, \#{0}. Assicurati che il tuo bot abbia i permessi di lettura e scrittura in tutti i canali che desideri utilizzare.
discordErrorNoToken=Nessun token fornito\! Si prega di seguire il tutorial nella configurazione per configurare il plugin.
discordErrorWebhook=Si è verificato un errore durante l''invio dei messaggi al canale della console\! Probabilmente è stato causato dall''eliminazione accidentale del webhook della console. Questo di solito può essere risolto assicurando che il tuo bot abbia il permesso "Gestisci Webhooks" ed eseguendo "/ess reload".
discordLinkInvalidGroup=Il gruppo {0} non valido è stato fornito per il ruolo {1}. I seguenti gruppi sono disponibili\: {2}
discordLinkInvalidRole=Un ID ruolo non valido, {0}, è stato fornito per il gruppo\: {1}. È possibile vedere l''ID dei ruoli con il comando /roleinfo in Discord.
discordLinkInvalidRoleInteract=Il ruolo, {0} ({1}), non può essere utilizzato per la sincronizzazione di gruppo->ruolo perché sopra il ruolo più alto del tuo bot. O spostare il ruolo del bot sopra "{0}" o spostare "{0}" sotto il ruolo del bot.
discordLinkInvalidRoleManaged=Il ruolo, {0} ({1}), non può essere utilizzato per la sincronizzazione di gruppo->ruolo perché è gestito da un altro bot o integrazione.
discordLinkLinked=§6Per collegare il tuo account Minecraft a Discord, digita §c{0} §6nel server Discord.
discordLinkLinkedAlready=§6Hai già collegato il tuo account Discord\! Se desideri scollegare il tuo account discord usa §c/unlink§6.
discordLinkLoginKick=§6Devi collegare il tuo account Discord prima di entrare in questo server.\n§6Per collegare il tuo account Minecraft a Discord, digita\:\n§c{0}\n§6nel server Discord di questo server\:\n§c{1}
discordLinkLoginPrompt=§6Devi collegare il tuo account Discord prima di poter spostare, chattare o interagire con questo server. Per collegare il tuo account Minecraft a Discord, digita §c{0} §6nel server Discord di questo server\: §c{1}
discordLinkNoAccount=§6Al momento non hai un account Discord collegato al tuo account Minecraft.
discordLinkPending=§6Hai già un codice di collegamento. Per completare il collegamento del tuo account Minecraft a Discord, digita §c{0} §6nel server di Discord.
discordLinkUnlinked=§6Scollegato il tuo account Minecraft da tutti gli account di discordia associati.
discordLoggingIn=Tentativo di accedere a Discord...
discordLoggingInDone=Accesso effettuato con successo come {0}
discordMailLine=**Nuova posta da {0}\:** {1}
discordNoSendPermission=Impossibile inviare il messaggio nel canale\: \#{0} Assicurarsi che il bot abbia l''autorizzazione "Invia messaggi" in quel canale\!
discordReloadInvalid=Ha provato a ricaricare la configurazione di EssentialsX Discord mentre il plugin è in uno stato non valido\! Se hai modificato la configurazione, riavvia il server.
disposal=Cestino
@@ -482,6 +508,7 @@ homeCommandUsage2=/<command> <player> <name>
homeCommandUsage2Description=Ti teletrasporta nella casa del giocatore specificato con il nome dato
homes=Case\: {0}
homeConfirmation=§6Hai già una casa chiamata §c{0}§6\!\nPer sovrascrivere la tua casa esistente, digita nuovamente il comando.
homeRenamed=§6La casa §c{0} §6è stata rinominata in §c{1}§6.
homeSet=§7Casa impostata alla posizione corrente.
hour=ora
hours=ore
@@ -534,6 +561,7 @@ invseeCommandDescription=Vedi l''inventario degli altri giocatori.
invseeCommandUsage=/<command> <player>
invseeCommandUsage1=/<command> <player>
invseeCommandUsage1Description=Apre l''inventario del giocatore specificato
invseeNoSelf=§cPuoi visualizzare solo gli inventari degli altri giocatori.
is=è
isIpBanned=§6L''IP §c{0} §6è bannato.
internalError=§cSi è verificato un errore durante l''esecuzione di questo comando.
@@ -659,6 +687,10 @@ lightningCommandUsage2=/<command> <player> <power>
lightningCommandUsage2Description=Colpisce l''illuminazione al giocatore bersaglio con la potenza data
lightningSmited=§6Sei stato folgorato\!
lightningUse=§c {0} §6 è stato folgorato\!
linkCommandDescription=Genera un codice per collegare il tuo account Minecraft a Discord.
linkCommandUsage=/<command>
linkCommandUsage1=/<command>
linkCommandUsage1Description=Genera un codice per il comando /link su Discord
listAfkTag=§7[AFK]§r
listAmount=§6Ci sono §c{0}§6 giocatori online su un massimo di §c{1}§6.
listAmountHidden=§6Ci sono §c{0}§6/§c{1}§6 su un massimo di §c{2}§6 giocatori online.
@@ -1008,6 +1040,12 @@ removeCommandUsage1Description=Rimuove tutto il tipo di mob specificato nel mond
removeCommandUsage2=/<command> <mob type> <radius> [world]
removeCommandUsage2Description=Rimuove il tipo di mob specificato nel raggio indicato nel mondo corrente o in un altro se specificato
removed=§6Rimosse§c {0} §6entità.
renamehomeCommandDescription=Rinomina una casa.
renamehomeCommandUsage=/<command> <[giocatore\:]nome> <new name>
renamehomeCommandUsage1=/<command> <name> <new name>
renamehomeCommandUsage1Description=Rinomina la tua casa al nome specificato
renamehomeCommandUsage2=/<command> <player>\:<name> <new name>
renamehomeCommandUsage2Description=Rinomina la casa del giocatore specificato al nome specificato
repair=§6Hai riparato il tuo\: §c{0}§6.
repairAlreadyFixed=§4Questo oggetto non richiede riparazioni.
repairCommandDescription=Ripara la durata di uno o tutti gli oggetti.
@@ -1019,7 +1057,7 @@ repairCommandUsage2Description=Ripara tutti gli oggetti nel tuo inventario
repairEnchanted=§4Non hai il permesso di riparare oggetti incantati.
repairInvalidType=§4Questo oggetto non può essere riparato.
repairNone=§4Non ci sono oggetti da riparare.
replyFromDiscord=**Risposta da {0}\:** `{1}`
replyFromDiscord=**Risposta da {0}\:** {1}
replyLastRecipientDisabled=§6Risposta all''ultimo destinatario dei messaggi §cdisabilitata§6.
replyLastRecipientDisabledFor=§6Risposta all''ultimo destinatario dei messaggi §cdisabilitata §6per §c{0}§6.
replyLastRecipientEnabled=§6Risposta all''ultimo destinatario dei messaggi §cabilitata§6.
@@ -1228,6 +1266,7 @@ teleportRequestTimeoutInfo=§7Questa richiesta scadrà tra {0} secondi.
teleportTop=§7Teletrasportato in cima.
teleportToPlayer=§6Teletrasportato a §c{0}§6.
teleportOffline=§6Il giocatore §c{0}§6 è attualmente offline. Puoi teletrasportarti usando /otp.
teleportOfflineUnknown=§6Impossibile trovare l''ultima posizione conosciuta di §c{0}§6.
tempbanExempt=§7Non puoi bannare questo giocatore.
tempbanExemptOffline=§4Non puoi bannare temporaneamente un giocatore che è offline.
tempbanJoin=You are banned from this server for {0}. Reason\: {1}
@@ -1392,6 +1431,10 @@ unlimitedCommandUsage3=/<command> clear [player]
unlimitedCommandUsage3Description=Cancella tutti gli oggetti illimitati per te o per un altro giocatore se specificato
unlimitedItemPermission=§4Nessun permesso per oggetti illimitati §c{0}§4.
unlimitedItems=§6Oggetti illimitati\:§r
unlinkCommandDescription=Scollega il tuo account Minecraft dall''account Discord attualmente collegato.
unlinkCommandUsage=/<command>
unlinkCommandUsage1=/<command>
unlinkCommandUsage1Description=Scollega il tuo account Minecraft dall''account Discord attualmente collegato.
unmutedPlayer=§6Il giocatore§c {0} §6è stato smutato.
unsafeTeleportDestination=§4La destinazione del teletrasporto non è sicura e il teletrasporto sicuro è disabilitata.
unsupportedBrand=§4La piattaforma server attualmente in esecuzione non fornisce le funzionalità per questa funzionalità.
@@ -1412,6 +1455,9 @@ userIsAwaySelf=Ora sei AFK\!
userIsAwaySelfWithMessage=Ora sei AFK.
userIsNotAwaySelf=Non sei più AFK\!
userJailed=§6Sei stato incarcerato\!
usermapEntry=§c{0} §6è mappato a §c{1}§6.
usermapPurge=§6Controllo dei file nei dati utente che non sono mappati, i risultati saranno registrati alla console. Modalità Distruttiva\: {0}
usermapSize=§6Gli attuali utenti nella cache della mappa utente sono §c{0}§6/§c{1}§6/§c{2}§6.
userUnknown=§4Attenzione\: Il giocatore ''§c{0}§4'' non è mai entrato nel server.
usingTempFolderForTesting=Usando la cartella temporanea per il test\:
vanish=§6Invisibilità giocatore {0}§6\: {1}
Loaded 100 of 172 files, more files were not shown because too many files have changed in this diff. Show more