forked from LogBlock/LogBlock
Compare commits
20 Commits
add_postgr
...
master
Author | SHA1 | Date | |
---|---|---|---|
63f9d16891 | |||
c14b17a522 | |||
0a685bca27 | |||
8c024532b2 | |||
ecb281ccaa | |||
dc9774b7c6 | |||
d1ecbe0efc | |||
73c221e8d0 | |||
0d04823ae1 | |||
10b5bc8913 | |||
d9a4d31509 | |||
dd70021979 | |||
00bcb6ba99 | |||
659095a214 | |||
aa206f0c7b | |||
1965d5f985 | |||
5f56f1677f | |||
20e70f91cd | |||
82e6d5bf38 | |||
d2ec428381 |
8
pom.xml
8
pom.xml
@ -44,7 +44,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
<version>1.21.5-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -125,9 +125,9 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.12.1</version>
|
<version>3.13.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<release>17</release>
|
<release>21</release>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -153,7 +153,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.5.1</version>
|
<version>3.5.3</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
|
@ -12,6 +12,7 @@ import static de.diddiz.LogBlock.util.TypeColor.DEFAULT;
|
|||||||
|
|
||||||
import de.diddiz.LogBlock.blockstate.BlockStateCodecs;
|
import de.diddiz.LogBlock.blockstate.BlockStateCodecs;
|
||||||
import de.diddiz.LogBlock.util.BukkitUtils;
|
import de.diddiz.LogBlock.util.BukkitUtils;
|
||||||
|
import de.diddiz.LogBlock.util.ItemStackAndAmount;
|
||||||
import de.diddiz.LogBlock.util.Utils;
|
import de.diddiz.LogBlock.util.Utils;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -35,7 +36,6 @@ import org.bukkit.block.data.type.Repeater;
|
|||||||
import org.bukkit.block.data.type.Sign;
|
import org.bukkit.block.data.type.Sign;
|
||||||
import org.bukkit.block.data.type.Switch;
|
import org.bukkit.block.data.type.Switch;
|
||||||
import org.bukkit.block.data.type.WallSign;
|
import org.bukkit.block.data.type.WallSign;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
public class BlockChange implements LookupCacheElement {
|
public class BlockChange implements LookupCacheElement {
|
||||||
public final long id, date;
|
public final long id, date;
|
||||||
@ -75,7 +75,7 @@ public class BlockChange implements LookupCacheElement {
|
|||||||
typeState = p.needType ? rs.getBytes("typeState") : null;
|
typeState = p.needType ? rs.getBytes("typeState") : null;
|
||||||
ChestAccess catemp = null;
|
ChestAccess catemp = null;
|
||||||
if (p.needChestAccess) {
|
if (p.needChestAccess) {
|
||||||
ItemStack stack = Utils.loadItemStack(rs.getBytes("item"));
|
ItemStackAndAmount stack = Utils.loadItemStack(rs.getBytes("item"));
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
catemp = new ChestAccess(stack, rs.getBoolean("itemremove"), rs.getInt("itemtype"));
|
catemp = new ChestAccess(stack, rs.getBoolean("itemremove"), rs.getInt("itemtype"));
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ public class BlockChange implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
TextComponent msg = new TextComponent();
|
TextComponent msg = new TextComponent();
|
||||||
if (date > 0) {
|
if (date > 0) {
|
||||||
msg.addExtra(prettyDate(date));
|
msg.addExtra(prettyDate(date));
|
||||||
@ -127,7 +127,7 @@ public class BlockChange implements LookupCacheElement {
|
|||||||
BlockData replaced = getBlockReplaced();
|
BlockData replaced = getBlockReplaced();
|
||||||
if (type == null || replaced == null) {
|
if (type == null || replaced == null) {
|
||||||
msg.addExtra("did an unknown block modification");
|
msg.addExtra("did an unknown block modification");
|
||||||
return new BaseComponent[] { msg };
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process type details once for later use.
|
// Process type details once for later use.
|
||||||
@ -254,7 +254,7 @@ public class BlockChange implements LookupCacheElement {
|
|||||||
msg.addExtra(" at ");
|
msg.addExtra(" at ");
|
||||||
msg.addExtra(prettyLocation(loc, entry));
|
msg.addExtra(prettyLocation(loc, entry));
|
||||||
}
|
}
|
||||||
return new BaseComponent[] { msg };
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockData getBlockReplaced() {
|
public BlockData getBlockReplaced() {
|
||||||
|
@ -39,7 +39,7 @@ public class ChatMessage implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
TextComponent msg = new TextComponent();
|
TextComponent msg = new TextComponent();
|
||||||
if (date > 0) {
|
if (date > 0) {
|
||||||
msg.addExtra(prettyDate(date));
|
msg.addExtra(prettyDate(date));
|
||||||
@ -50,10 +50,8 @@ public class ChatMessage implements LookupCacheElement {
|
|||||||
msg.addExtra(" ");
|
msg.addExtra(" ");
|
||||||
}
|
}
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
for (BaseComponent messageComponent : TextComponent.fromLegacyText(message)) {
|
msg.addExtra(TextComponent.fromLegacy(message));
|
||||||
msg.addExtra(messageComponent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new BaseComponent[] { msg };
|
return msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package de.diddiz.LogBlock;
|
package de.diddiz.LogBlock;
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import de.diddiz.LogBlock.util.ItemStackAndAmount;
|
||||||
|
|
||||||
public class ChestAccess {
|
public class ChestAccess {
|
||||||
public final ItemStack itemStack;
|
public final ItemStackAndAmount itemStack;
|
||||||
public final boolean remove;
|
public final boolean remove;
|
||||||
public final int itemType;
|
public final int itemType;
|
||||||
|
|
||||||
public ChestAccess(ItemStack itemStack, boolean remove, int itemType) {
|
public ChestAccess(ItemStackAndAmount itemStack, boolean remove, int itemType) {
|
||||||
this.itemStack = itemStack;
|
this.itemStack = itemStack;
|
||||||
this.remove = remove;
|
this.remove = remove;
|
||||||
this.itemType = itemType;
|
this.itemType = itemType;
|
||||||
|
@ -443,9 +443,7 @@ public class CommandsHandler implements CommandExecutor {
|
|||||||
if (lookupElements[i].getLocation() != null) {
|
if (lookupElements[i].getLocation() != null) {
|
||||||
message.addExtra(new TextComponent("(" + (i + 1) + ") "));
|
message.addExtra(new TextComponent("(" + (i + 1) + ") "));
|
||||||
}
|
}
|
||||||
for (BaseComponent component : lookupElements[i].getLogMessage(i + 1)) {
|
message.addExtra(lookupElements[i].getLogMessage(i + 1));
|
||||||
message.addExtra(component);
|
|
||||||
}
|
|
||||||
sender.spigot().sendMessage(message);
|
sender.spigot().sendMessage(message);
|
||||||
}
|
}
|
||||||
if (setSessionPage) {
|
if (setSessionPage) {
|
||||||
|
@ -19,6 +19,7 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -52,6 +53,7 @@ import de.diddiz.LogBlock.config.Config;
|
|||||||
import de.diddiz.LogBlock.events.BlockChangePreLogEvent;
|
import de.diddiz.LogBlock.events.BlockChangePreLogEvent;
|
||||||
import de.diddiz.LogBlock.events.EntityChangePreLogEvent;
|
import de.diddiz.LogBlock.events.EntityChangePreLogEvent;
|
||||||
import de.diddiz.LogBlock.util.BukkitUtils;
|
import de.diddiz.LogBlock.util.BukkitUtils;
|
||||||
|
import de.diddiz.LogBlock.util.ItemStackAndAmount;
|
||||||
import de.diddiz.LogBlock.util.Utils;
|
import de.diddiz.LogBlock.util.Utils;
|
||||||
|
|
||||||
public class Consumer extends Thread {
|
public class Consumer extends Thread {
|
||||||
@ -208,7 +210,7 @@ public class Consumer extends Thread {
|
|||||||
* @param remove
|
* @param remove
|
||||||
* true if the item was removed
|
* true if the item was removed
|
||||||
*/
|
*/
|
||||||
public void queueChestAccess(Actor actor, BlockState container, ItemStack itemStack, boolean remove) {
|
public void queueChestAccess(Actor actor, BlockState container, ItemStackAndAmount itemStack, boolean remove) {
|
||||||
if (!(container instanceof InventoryHolder)) {
|
if (!(container instanceof InventoryHolder)) {
|
||||||
throw new IllegalArgumentException("Container must be instanceof InventoryHolder");
|
throw new IllegalArgumentException("Container must be instanceof InventoryHolder");
|
||||||
}
|
}
|
||||||
@ -229,8 +231,8 @@ public class Consumer extends Thread {
|
|||||||
* @param remove
|
* @param remove
|
||||||
* true if the item was removed
|
* true if the item was removed
|
||||||
*/
|
*/
|
||||||
public void queueChestAccess(Actor actor, Location loc, BlockData type, ItemStack itemStack, boolean remove) {
|
public void queueChestAccess(Actor actor, Location loc, BlockData type, ItemStackAndAmount itemStack, boolean remove) {
|
||||||
queueBlock(actor, loc, type, type, null, null, new ChestAccess(itemStack, remove, MaterialConverter.getOrAddMaterialId(itemStack.getType())));
|
queueBlock(actor, loc, type, type, null, null, new ChestAccess(itemStack, remove, MaterialConverter.getOrAddMaterialId(itemStack.stack().getType())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,8 +263,8 @@ public class Consumer extends Thread {
|
|||||||
* The inventory of the container block
|
* The inventory of the container block
|
||||||
*/
|
*/
|
||||||
public void queueContainerBreak(Actor actor, Location loc, BlockData type, Inventory inv) {
|
public void queueContainerBreak(Actor actor, Location loc, BlockData type, Inventory inv) {
|
||||||
final ItemStack[] items = compressInventory(inv.getContents());
|
final Collection<ItemStackAndAmount> items = compressInventory(inv.getContents());
|
||||||
for (final ItemStack item : items) {
|
for (final ItemStackAndAmount item : items) {
|
||||||
queueChestAccess(actor, loc, type, item, true);
|
queueChestAccess(actor, loc, type, item, true);
|
||||||
}
|
}
|
||||||
queueBlockBreak(actor, loc, type);
|
queueBlockBreak(actor, loc, type);
|
||||||
|
@ -77,7 +77,7 @@ public class EntityChange implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
TextComponent msg = new TextComponent();
|
TextComponent msg = new TextComponent();
|
||||||
if (date > 0) {
|
if (date > 0) {
|
||||||
msg.addExtra(prettyDate(date));
|
msg.addExtra(prettyDate(date));
|
||||||
@ -128,7 +128,7 @@ public class EntityChange implements LookupCacheElement {
|
|||||||
msg.addExtra(" at ");
|
msg.addExtra(" at ");
|
||||||
msg.addExtra(prettyLocation(loc, entry));
|
msg.addExtra(prettyLocation(loc, entry));
|
||||||
}
|
}
|
||||||
return new BaseComponent[] { msg };
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,7 +49,7 @@ public class Kill implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
TextComponent msg = new TextComponent();
|
TextComponent msg = new TextComponent();
|
||||||
if (date > 0) {
|
if (date > 0) {
|
||||||
msg.addExtra(prettyDate(date));
|
msg.addExtra(prettyDate(date));
|
||||||
@ -65,7 +65,7 @@ public class Kill implements LookupCacheElement {
|
|||||||
msg.addExtra(" with ");
|
msg.addExtra(" with ");
|
||||||
msg.addExtra(prettyItemName(MaterialConverter.getMaterial(weapon)));
|
msg.addExtra(prettyItemName(MaterialConverter.getMaterial(weapon)));
|
||||||
}
|
}
|
||||||
return new BaseComponent[] { msg };
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextComponent prettyItemName(Material t) {
|
public TextComponent prettyItemName(Material t) {
|
||||||
|
@ -101,19 +101,11 @@ public class LogBlock extends JavaPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Statement st = conn.createStatement();
|
final Statement st = conn.createStatement();
|
||||||
try {
|
final ResultSet rs = st.executeQuery("SHOW CHARACTER SET where charset='utf8mb4';");
|
||||||
final ResultSet rs = st.executeQuery("SHOW CHARACTER SET where charset='utf8mb4';");
|
if (rs.next()) {
|
||||||
if (rs.next()) {
|
Config.mb4 = true;
|
||||||
Config.mb4 = true;
|
// Allegedly JDBC driver since 2010 hasn't needed this. I did.
|
||||||
// Allegedly JDBC driver since 2010 hasn't needed this. I did.
|
st.executeUpdate("SET NAMES utf8mb4;");
|
||||||
try {
|
|
||||||
st.executeUpdate("SET NAMES utf8mb4;");
|
|
||||||
} catch (Exception ex) {
|
|
||||||
getLogger().severe("could not set names to utf8mb4: " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
getLogger().severe("could not verify character set: " + ex.getMessage());
|
|
||||||
}
|
}
|
||||||
conn.close();
|
conn.close();
|
||||||
Updater updater = new Updater(this);
|
Updater updater = new Updater(this);
|
||||||
@ -213,11 +205,8 @@ public class LogBlock extends JavaPlugin {
|
|||||||
if (isLogging(Logging.CHAT) || isLogging(Logging.PLAYER_COMMANDS) || isLogging(Logging.CONSOLE_COMMANDS) || isLogging(Logging.COMMANDBLOCK_COMMANDS)) {
|
if (isLogging(Logging.CHAT) || isLogging(Logging.PLAYER_COMMANDS) || isLogging(Logging.CONSOLE_COMMANDS) || isLogging(Logging.COMMANDBLOCK_COMMANDS)) {
|
||||||
pm.registerEvents(new ChatLogging(this), this);
|
pm.registerEvents(new ChatLogging(this), this);
|
||||||
}
|
}
|
||||||
if (isLogging(Logging.ENDERMEN)) {
|
if (isLogging(Logging.WITHER) || isLogging(Logging.ENDERMEN)) {
|
||||||
pm.registerEvents(new EndermenLogging(this), this);
|
pm.registerEvents(new EntityChangeBlockLogging(this), this);
|
||||||
}
|
|
||||||
if (isLogging(Logging.WITHER)) {
|
|
||||||
pm.registerEvents(new WitherLogging(this), this);
|
|
||||||
}
|
}
|
||||||
if (isLogging(Logging.NATURALSTRUCTUREGROW)) {
|
if (isLogging(Logging.NATURALSTRUCTUREGROW)) {
|
||||||
pm.registerEvents(new StructureGrowLogging(this), this);
|
pm.registerEvents(new StructureGrowLogging(this), this);
|
||||||
|
@ -39,6 +39,8 @@ public enum Logging {
|
|||||||
BAMBOOGROWTH,
|
BAMBOOGROWTH,
|
||||||
WITHER(true),
|
WITHER(true),
|
||||||
WITHER_SKULL(true),
|
WITHER_SKULL(true),
|
||||||
|
GRASS_EAT,
|
||||||
|
MISCENTITYCHANGEBLOCK(true),
|
||||||
BONEMEALSTRUCTUREGROW,
|
BONEMEALSTRUCTUREGROW,
|
||||||
WORLDEDIT,
|
WORLDEDIT,
|
||||||
TNTMINECARTEXPLOSION(true),
|
TNTMINECARTEXPLOSION(true),
|
||||||
|
@ -6,11 +6,11 @@ import org.bukkit.Location;
|
|||||||
public interface LookupCacheElement {
|
public interface LookupCacheElement {
|
||||||
public Location getLocation();
|
public Location getLocation();
|
||||||
|
|
||||||
public default BaseComponent[] getLogMessage() {
|
public default BaseComponent getLogMessage() {
|
||||||
return getLogMessage(-1);
|
return getLogMessage(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseComponent[] getLogMessage(int entry);
|
public BaseComponent getLogMessage(int entry);
|
||||||
|
|
||||||
public default int getNumChanges() {
|
public default int getNumChanges() {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -32,7 +32,7 @@ public class SummedBlockChanges implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
return MessagingUtil.formatSummarizedChanges(created, destroyed, actor != null ? new TextComponent(actor.getName()) : prettyMaterial(Objects.toString(MaterialConverter.getMaterial(type))), 10, 10, spaceFactor);
|
return MessagingUtil.formatSummarizedChanges(created, destroyed, actor != null ? new TextComponent(actor.getName()) : prettyMaterial(Objects.toString(MaterialConverter.getMaterial(type))), 10, 10, spaceFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class SummedEntityChanges implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
return MessagingUtil.formatSummarizedChanges(created, destroyed, actor != null ? new TextComponent(actor.getName()) : prettyMaterial(Objects.toString(EntityTypeConverter.getEntityType(type))), 10, 10, spaceFactor);
|
return MessagingUtil.formatSummarizedChanges(created, destroyed, actor != null ? new TextComponent(actor.getName()) : prettyMaterial(Objects.toString(EntityTypeConverter.getEntityType(type))), 10, 10, spaceFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public class SummedKills implements LookupCacheElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
return MessagingUtil.formatSummarizedChanges(kills, killed, new TextComponent(player.getName()), 6, 7, spaceFactor);
|
return MessagingUtil.formatSummarizedChanges(kills, killed, new TextComponent(player.getName()), 6, 7, spaceFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import de.diddiz.LogBlock.blockstate.BlockStateCodecSign;
|
|||||||
import de.diddiz.LogBlock.config.Config;
|
import de.diddiz.LogBlock.config.Config;
|
||||||
import de.diddiz.LogBlock.config.WorldConfig;
|
import de.diddiz.LogBlock.config.WorldConfig;
|
||||||
import de.diddiz.LogBlock.util.ComparableVersion;
|
import de.diddiz.LogBlock.util.ComparableVersion;
|
||||||
|
import de.diddiz.LogBlock.util.ItemStackAndAmount;
|
||||||
import de.diddiz.LogBlock.util.UUIDFetcher;
|
import de.diddiz.LogBlock.util.UUIDFetcher;
|
||||||
import de.diddiz.LogBlock.util.Utils;
|
import de.diddiz.LogBlock.util.Utils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -534,7 +535,7 @@ class Updater {
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
ItemStack stack = weaponMaterial.getMaxDurability() > 0 ? new ItemStack(weaponMaterial, Math.abs(amount), (short) itemdata) : new ItemStack(weaponMaterial, Math.abs(amount));
|
ItemStack stack = weaponMaterial.getMaxDurability() > 0 ? new ItemStack(weaponMaterial, Math.abs(amount), (short) itemdata) : new ItemStack(weaponMaterial, Math.abs(amount));
|
||||||
insertChestData.setLong(1, id);
|
insertChestData.setLong(1, id);
|
||||||
insertChestData.setBytes(2, Utils.saveItemStack(stack));
|
insertChestData.setBytes(2, Utils.saveItemStack(ItemStackAndAmount.fromStack(stack)));
|
||||||
insertChestData.setInt(3, amount >= 0 ? 0 : 1);
|
insertChestData.setInt(3, amount >= 0 ? 0 : 1);
|
||||||
insertChestData.setInt(4, MaterialConverter.getOrAddMaterialId(weaponMaterial));
|
insertChestData.setInt(4, MaterialConverter.getOrAddMaterialId(weaponMaterial));
|
||||||
insertChestData.addBatch();
|
insertChestData.addBatch();
|
||||||
@ -869,150 +870,49 @@ class Updater {
|
|||||||
}
|
}
|
||||||
final Statement state = conn.createStatement();
|
final Statement state = conn.createStatement();
|
||||||
conn.setAutoCommit(true);
|
conn.setAutoCommit(true);
|
||||||
createTable(state, "lb-players",
|
createTable(state, "lb-players", "(playerid INT UNSIGNED NOT NULL AUTO_INCREMENT, UUID varchar(36) NOT NULL, playername varchar(32) NOT NULL, firstlogin DATETIME NOT NULL, lastlogin DATETIME NOT NULL, onlinetime INT UNSIGNED NOT NULL, ip varchar(255) NOT NULL, PRIMARY KEY (playerid), INDEX (UUID), INDEX (playername)) DEFAULT CHARSET " + charset);
|
||||||
"playerid INT UNSIGNED NOT NULL AUTO_INCREMENT, \n" +
|
|
||||||
"UUID varchar(36) NOT NULL, \n" +
|
|
||||||
"playername varchar(32) NOT NULL, \n" +
|
|
||||||
"firstlogin DATETIME NOT NULL, \n" +
|
|
||||||
"lastlogin DATETIME NOT NULL, \n" +
|
|
||||||
"onlinetime INT UNSIGNED NOT NULL, \n" +
|
|
||||||
"ip varchar(255) NOT NULL, \n" +
|
|
||||||
"PRIMARY KEY (playerid)\n",
|
|
||||||
//"INDEX (UUID), " +
|
|
||||||
//"INDEX (playername)",
|
|
||||||
"DEFAULT CHARSET " + charset
|
|
||||||
);
|
|
||||||
// Players table must not be empty or inserts won't work - bug #492
|
// Players table must not be empty or inserts won't work - bug #492
|
||||||
final ResultSet rs = state.executeQuery("SELECT NULL FROM \"lb-players\" LIMIT 1;");
|
final ResultSet rs = state.executeQuery("SELECT NULL FROM `lb-players` LIMIT 1;");
|
||||||
if (!rs.next()) {
|
if (!rs.next()) {
|
||||||
state.execute("INSERT INTO \"lb-players\" (UUID, playername) VALUES ('log_dummy_record','dummy_record') ON CONFLICT DO NOTHING");
|
state.execute("INSERT IGNORE INTO `lb-players` (UUID,playername) VALUES ('log_dummy_record','dummy_record')");
|
||||||
}
|
}
|
||||||
if (isLogging(Logging.CHAT) || isLogging(Logging.PLAYER_COMMANDS) || isLogging(Logging.CONSOLE_COMMANDS) || isLogging(Logging.COMMANDBLOCK_COMMANDS)) {
|
if (isLogging(Logging.CHAT) || isLogging(Logging.PLAYER_COMMANDS) || isLogging(Logging.CONSOLE_COMMANDS) || isLogging(Logging.COMMANDBLOCK_COMMANDS)) {
|
||||||
try {
|
try {
|
||||||
createTable(state, "lb-chat",
|
createTable(state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, message VARCHAR(256) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) DEFAULT CHARSET " + charset);
|
||||||
"id INT UNSIGNED NOT NULL AUTO_INCREMENT, " +
|
|
||||||
"date DATETIME NOT NULL, " +
|
|
||||||
"playerid INT UNSIGNED NOT NULL, " +
|
|
||||||
"message VARCHAR(256) NOT NULL, " +
|
|
||||||
"PRIMARY KEY (id), ",
|
|
||||||
// "KEY playerid (playerid), " +
|
|
||||||
// "FULLTEXT message (message)",
|
|
||||||
"DEFAULT CHARSET " + charset);
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
createTable(state, "lb-chat",
|
createTable(state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, message VARCHAR(256) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid)) DEFAULT CHARSET " + charset);
|
||||||
"id INT UNSIGNED NOT NULL AUTO_INCREMENT," +
|
|
||||||
"date DATETIME NOT NULL," +
|
|
||||||
"playerid INT UNSIGNED NOT NULL," +
|
|
||||||
"message VARCHAR(256) NOT NULL," +
|
|
||||||
"PRIMARY KEY (id)," +
|
|
||||||
"KEY playerid (playerid)",
|
|
||||||
"DEFAULT CHARSET " + charset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createTable(state, "lb-materials",
|
createTable(state, "lb-materials", "(id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARSET " + charset);
|
||||||
"id INT UNSIGNED NOT NULL, " +
|
createTable(state, "lb-blockstates", "(id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARSET " + charset);
|
||||||
"name VARCHAR(255) NOT NULL, " +
|
createTable(state, "lb-entitytypes", "(id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARSET " + charset);
|
||||||
"PRIMARY KEY (id)",
|
|
||||||
"DEFAULT CHARSET " + charset);
|
|
||||||
createTable(state, "lb-blockstates",
|
|
||||||
"id INT UNSIGNED NOT NULL, " +
|
|
||||||
"name VARCHAR(255) NOT NULL, " +
|
|
||||||
"PRIMARY KEY (id)",
|
|
||||||
"DEFAULT CHARSET " + charset);
|
|
||||||
createTable(state, "lb-entitytypes",
|
|
||||||
"id INT UNSIGNED NOT NULL, " +
|
|
||||||
"name VARCHAR(255) NOT NULL, " +
|
|
||||||
"PRIMARY KEY (id)",
|
|
||||||
"DEFAULT CHARSET " + charset);
|
|
||||||
|
|
||||||
for (final WorldConfig wcfg : getLoggedWorlds()) {
|
for (final WorldConfig wcfg : getLoggedWorlds()) {
|
||||||
createTable(state, wcfg.table + "-blocks",
|
createTable(state, wcfg.table + "-blocks", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, replaced SMALLINT UNSIGNED NOT NULL, replacedData SMALLINT NOT NULL, type SMALLINT UNSIGNED NOT NULL, typeData SMALLINT NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT NOT NULL, z MEDIUMINT NOT NULL, PRIMARY KEY (id), KEY coords (x, z, y), KEY date (date), KEY playerid (playerid))");
|
||||||
"id INT UNSIGNED NOT NULL AUTO_INCREMENT, " +
|
createTable(state, wcfg.table + "-chestdata", "(id INT UNSIGNED NOT NULL, item MEDIUMBLOB, itemremove TINYINT, itemtype SMALLINT NOT NULL DEFAULT '0', PRIMARY KEY (id))");
|
||||||
"date DATETIME NOT NULL, " +
|
createTable(state, wcfg.table + "-state", "(id INT UNSIGNED NOT NULL, replacedState MEDIUMBLOB NULL, typeState MEDIUMBLOB NULL, PRIMARY KEY (id))");
|
||||||
"playerid INT UNSIGNED NOT NULL, " +
|
|
||||||
"replaced SMALLINT UNSIGNED NOT NULL, " +
|
|
||||||
"replacedData SMALLINT NOT NULL, " +
|
|
||||||
"type SMALLINT UNSIGNED NOT NULL, " +
|
|
||||||
"typeData SMALLINT NOT NULL, " +
|
|
||||||
"x MEDIUMINT NOT NULL, " +
|
|
||||||
"y SMALLINT NOT NULL, " +
|
|
||||||
"z MEDIUMINT NOT NULL, " +
|
|
||||||
"PRIMARY KEY (id), " +
|
|
||||||
"KEY coords (x, z, y), " +
|
|
||||||
"KEY date (date), " +
|
|
||||||
"KEY playerid (playerid)",
|
|
||||||
"");
|
|
||||||
createTable(state, wcfg.table + "-chestdata",
|
|
||||||
"id INT UNSIGNED NOT NULL, " +
|
|
||||||
"item MEDIUMBLOB, " +
|
|
||||||
"itemremove TINYINT, " +
|
|
||||||
"itemtype SMALLINT NOT NULL DEFAULT '0', " +
|
|
||||||
"PRIMARY KEY (id)",
|
|
||||||
"");
|
|
||||||
createTable(state, wcfg.table + "-state",
|
|
||||||
"id INT UNSIGNED NOT NULL, " +
|
|
||||||
"replacedState MEDIUMBLOB NULL, " +
|
|
||||||
"typeState MEDIUMBLOB NULL, " +
|
|
||||||
"PRIMARY KEY (id)",
|
|
||||||
"");
|
|
||||||
if (wcfg.isLogging(Logging.KILL)) {
|
if (wcfg.isLogging(Logging.KILL)) {
|
||||||
createTable(state, wcfg.table + "-kills",
|
createTable(state, wcfg.table + "-kills", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, killer INT UNSIGNED, victim INT UNSIGNED NOT NULL, weapon SMALLINT UNSIGNED NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT NOT NULL, z MEDIUMINT NOT NULL, PRIMARY KEY (id))");
|
||||||
"id INT UNSIGNED NOT NULL AUTO_INCREMENT, " +
|
|
||||||
"date DATETIME NOT NULL, " +
|
|
||||||
"killer INT UNSIGNED, " +
|
|
||||||
"victim INT UNSIGNED NOT NULL, " +
|
|
||||||
"weapon SMALLINT UNSIGNED NOT NULL, " +
|
|
||||||
"x MEDIUMINT NOT NULL, " +
|
|
||||||
"y SMALLINT NOT NULL, " +
|
|
||||||
"z MEDIUMINT NOT NULL, " +
|
|
||||||
"PRIMARY KEY (id)",
|
|
||||||
"");
|
|
||||||
}
|
}
|
||||||
createTable(state, wcfg.table + "-entityids",
|
createTable(state, wcfg.table + "-entityids", "(entityid INT UNSIGNED NOT NULL AUTO_INCREMENT, entityuuid VARCHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, PRIMARY KEY (entityid), UNIQUE KEY (entityuuid))");
|
||||||
"entityid INT UNSIGNED NOT NULL AUTO_INCREMENT, " +
|
createTable(state, wcfg.table + "-entities", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, entityid INT UNSIGNED NOT NULL, entitytypeid INT UNSIGNED NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT NOT NULL, z MEDIUMINT NOT NULL, action TINYINT UNSIGNED NOT NULL, data MEDIUMBLOB NULL, PRIMARY KEY (id), KEY coords (x, z, y), KEY date (date), KEY playerid (playerid), KEY entityid (entityid))");
|
||||||
"entityuuid VARCHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, " +
|
|
||||||
"PRIMARY KEY (entityid), " +
|
|
||||||
"UNIQUE KEY (entityuuid)",
|
|
||||||
"");
|
|
||||||
createTable(state, wcfg.table + "-entities",
|
|
||||||
"id INT UNSIGNED NOT NULL AUTO_INCREMENT, " +
|
|
||||||
"date DATETIME NOT NULL, " +
|
|
||||||
"playerid INT UNSIGNED NOT NULL, " +
|
|
||||||
"entityid INT UNSIGNED NOT NULL, " +
|
|
||||||
"entitytypeid INT UNSIGNED NOT NULL, " +
|
|
||||||
"x MEDIUMINT NOT NULL, " +
|
|
||||||
"y SMALLINT NOT NULL, " +
|
|
||||||
"z MEDIUMINT NOT NULL, " +
|
|
||||||
"action TINYINT UNSIGNED NOT NULL, " +
|
|
||||||
"data MEDIUMBLOB NULL, " +
|
|
||||||
"PRIMARY KEY (id), " +
|
|
||||||
"KEY coords (x, z, y), " +
|
|
||||||
"KEY date (date), " +
|
|
||||||
"KEY playerid (playerid), " +
|
|
||||||
"KEY entityid (entityid)",
|
|
||||||
"");
|
|
||||||
}
|
}
|
||||||
state.close();
|
state.close();
|
||||||
conn.close();
|
conn.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTable(Statement state, String table, String columns, String additional) throws SQLException {
|
private void createTable(Statement state, String table, String query) throws SQLException {
|
||||||
logblock.getLogger().log(Level.INFO, "Creating table " + table + ".");
|
try (ResultSet tableResult = state.executeQuery("SHOW TABLES LIKE '" + table + "'")) {
|
||||||
String sql = "CREATE TABLE IF NOT EXISTS \"" + table + "\" (" +
|
if (!tableResult.next()) {
|
||||||
(
|
logblock.getLogger().log(Level.INFO, "Creating table " + table + ".");
|
||||||
columns
|
state.execute("CREATE TABLE `" + table + "` " + query);
|
||||||
.replace("INT UNSIGNED NOT NULL AUTO_INCREMENT", "SERIAL NOT NULL")
|
try (ResultSet tableResultNew = state.executeQuery("SHOW TABLES LIKE '" + table + "'")) {
|
||||||
.replace("INT UNSIGNED", "INT")
|
if (!tableResultNew.next()) {
|
||||||
.replace("DATETIME", "TIMESTAMP")
|
throw new SQLException("Table " + table + " not found and failed to create");
|
||||||
)
|
}
|
||||||
+ ") " /* + additional */ ;
|
}
|
||||||
logblock.getLogger().info("sql=" + sql);
|
}
|
||||||
state.execute(sql);
|
}
|
||||||
//try (ResultSet tableResultNew = state.executeQuery("SHOW TABLES LIKE '" + table + "'")) {
|
|
||||||
// if (!tableResultNew.next()) {
|
|
||||||
// throw new SQLException("Table " + table + " not found and failed to create");
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,7 @@ import org.bukkit.entity.Bee;
|
|||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.ItemFrame;
|
import org.bukkit.entity.ItemFrame;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import de.diddiz.LogBlock.QueryParams.Order;
|
import de.diddiz.LogBlock.QueryParams.Order;
|
||||||
@ -35,6 +36,7 @@ import java.io.File;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -53,6 +55,8 @@ import static de.diddiz.LogBlock.util.BukkitUtils.*;
|
|||||||
public class WorldEditor implements Runnable {
|
public class WorldEditor implements Runnable {
|
||||||
private final LogBlock logblock;
|
private final LogBlock logblock;
|
||||||
private final ArrayList<Edit> edits = new ArrayList<>();
|
private final ArrayList<Edit> edits = new ArrayList<>();
|
||||||
|
private int rowsCompleted;
|
||||||
|
private int totalRows;
|
||||||
private final World world;
|
private final World world;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,6 +139,7 @@ public class WorldEditor implements Runnable {
|
|||||||
}
|
}
|
||||||
started = true;
|
started = true;
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
|
totalRows = edits.size();
|
||||||
taskID = logblock.getServer().getScheduler().scheduleSyncRepeatingTask(logblock, this, 0, 1);
|
taskID = logblock.getServer().getScheduler().scheduleSyncRepeatingTask(logblock, this, 0, 1);
|
||||||
if (taskID == -1) {
|
if (taskID == -1) {
|
||||||
throw new Exception("Failed to schedule task");
|
throw new Exception("Failed to schedule task");
|
||||||
@ -151,8 +156,9 @@ public class WorldEditor implements Runnable {
|
|||||||
public synchronized void run() {
|
public synchronized void run() {
|
||||||
final List<WorldEditorException> errorList = new ArrayList<>();
|
final List<WorldEditorException> errorList = new ArrayList<>();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
float size = edits.size();
|
long t0 = System.nanoTime();
|
||||||
while (!edits.isEmpty() && counter < 100) {
|
long maxEditTime = 5_000_000; // 5 ms
|
||||||
|
while (!edits.isEmpty() && counter < 10000 && (counter < 100 || counter % 10 != 0 || System.nanoTime() - t0 < maxEditTime)) {
|
||||||
try {
|
try {
|
||||||
switch (edits.remove(edits.size() - 1).perform()) {
|
switch (edits.remove(edits.size() - 1).perform()) {
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
@ -169,11 +175,12 @@ public class WorldEditor implements Runnable {
|
|||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
logblock.getLogger().log(Level.WARNING, "[WorldEditor] Exeption: ", ex);
|
logblock.getLogger().log(Level.WARNING, "[WorldEditor] Exeption: ", ex);
|
||||||
}
|
}
|
||||||
|
rowsCompleted++;
|
||||||
counter++;
|
counter++;
|
||||||
if (sender != null) {
|
if (sender != null) {
|
||||||
float percentage = ((size - edits.size()) / size) * 100.0F;
|
float percentage = rowsCompleted * 100.0f / totalRows;
|
||||||
if (percentage % 20 == 0) {
|
if (rowsCompleted % 10000 == 0) {
|
||||||
sender.sendMessage(ChatColor.GOLD + "[LogBlock]" + ChatColor.YELLOW + " Rollback progress: " + percentage + "%" +
|
sender.sendMessage(ChatColor.GOLD + "[LogBlock]" + ChatColor.YELLOW + " Rollback progress: " + NumberFormat.getNumberInstance().format(percentage) + "%" +
|
||||||
" Blocks edited: " + counter);
|
" Blocks edited: " + counter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,10 +375,10 @@ public class WorldEditor implements Runnable {
|
|||||||
BlockState state = block.getState();
|
BlockState state = block.getState();
|
||||||
if (setBlock.equals(replacedBlock)) {
|
if (setBlock.equals(replacedBlock)) {
|
||||||
if (ca != null) {
|
if (ca != null) {
|
||||||
if (state instanceof Container && state.getType() == replacedBlock.getMaterial()) {
|
if (state instanceof InventoryHolder && state.getType() == replacedBlock.getMaterial()) {
|
||||||
int leftover;
|
int leftover;
|
||||||
try {
|
try {
|
||||||
leftover = modifyContainer(state, new ItemStack(ca.itemStack), !ca.remove);
|
leftover = modifyContainer(state, ca.itemStack, !ca.remove);
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
throw new WorldEditorException(ex.getMessage(), block.getLocation());
|
throw new WorldEditorException(ex.getMessage(), block.getLocation());
|
||||||
}
|
}
|
||||||
@ -486,8 +493,8 @@ public class WorldEditor implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseComponent[] getLogMessage(int entry) {
|
public BaseComponent getLogMessage(int entry) {
|
||||||
return TextComponent.fromLegacyText(getMessage());
|
return TextComponent.fromLegacy(getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@ package de.diddiz.LogBlock;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import de.diddiz.LogBlock.QueryParams.BlockChangeType;
|
import de.diddiz.LogBlock.QueryParams.BlockChangeType;
|
||||||
|
import de.diddiz.LogBlock.util.ItemStackAndAmount;
|
||||||
import de.diddiz.LogBlock.util.Utils;
|
import de.diddiz.LogBlock.util.Utils;
|
||||||
|
|
||||||
public class WorldEditorEditFactory {
|
public class WorldEditorEditFactory {
|
||||||
@ -25,7 +24,7 @@ public class WorldEditorEditFactory {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ChestAccess chestaccess = null;
|
ChestAccess chestaccess = null;
|
||||||
ItemStack stack = Utils.loadItemStack(rs.getBytes("item"));
|
ItemStackAndAmount stack = Utils.loadItemStack(rs.getBytes("item"));
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
chestaccess = new ChestAccess(stack, rs.getBoolean("itemremove") == rollback, rs.getInt("itemtype"));
|
chestaccess = new ChestAccess(stack, rs.getBoolean("itemremove") == rollback, rs.getInt("itemtype"));
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package de.diddiz.LogBlock.blockstate;
|
package de.diddiz.LogBlock.blockstate;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.Registry;
|
||||||
import org.bukkit.block.Banner;
|
import org.bukkit.block.Banner;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.banner.Pattern;
|
import org.bukkit.block.banner.Pattern;
|
||||||
@ -30,10 +33,13 @@ public class BlockStateCodecBanner implements BlockStateCodec {
|
|||||||
YamlConfiguration conf = new YamlConfiguration();
|
YamlConfiguration conf = new YamlConfiguration();
|
||||||
ConfigurationSection patternsSection = conf.createSection("patterns");
|
ConfigurationSection patternsSection = conf.createSection("patterns");
|
||||||
for (Pattern pattern : patterns) {
|
for (Pattern pattern : patterns) {
|
||||||
ConfigurationSection section = patternsSection.createSection(Integer.toString(nr));
|
NamespacedKey key = pattern.getPattern().getKey();
|
||||||
section.set("color", pattern.getColor().name());
|
if (key != null) {
|
||||||
section.set("pattern", pattern.getPattern().name());
|
ConfigurationSection section = patternsSection.createSection(Integer.toString(nr));
|
||||||
nr++;
|
section.set("color", pattern.getColor().name());
|
||||||
|
section.set("pattern", key.toString());
|
||||||
|
nr++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
@ -55,8 +61,13 @@ public class BlockStateCodecBanner implements BlockStateCodec {
|
|||||||
ConfigurationSection section = patternsSection.getConfigurationSection(key);
|
ConfigurationSection section = patternsSection.getConfigurationSection(key);
|
||||||
if (section != null) {
|
if (section != null) {
|
||||||
DyeColor color = DyeColor.valueOf(section.getString("color"));
|
DyeColor color = DyeColor.valueOf(section.getString("color"));
|
||||||
PatternType type = PatternType.valueOf(section.getString("pattern"));
|
NamespacedKey patternKey = NamespacedKey.fromString(section.getString("pattern").toLowerCase(Locale.ROOT));
|
||||||
banner.addPattern(new Pattern(color, type));
|
if (patternKey != null) {
|
||||||
|
PatternType type = Registry.BANNER_PATTERN.get(patternKey);
|
||||||
|
if (type != null) {
|
||||||
|
banner.addPattern(new Pattern(color, type));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ public class BlockStateCodecSign implements BlockStateCodec {
|
|||||||
}
|
}
|
||||||
tc.addExtra("[");
|
tc.addExtra("[");
|
||||||
if (line != null && !line.isEmpty()) {
|
if (line != null && !line.isEmpty()) {
|
||||||
tc.addExtra(new TextComponent(TextComponent.fromLegacyText(line)));
|
tc.addExtra(TextComponent.fromLegacy(line));
|
||||||
}
|
}
|
||||||
tc.addExtra("]");
|
tc.addExtra("]");
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import java.util.List;
|
|||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
public enum EntityLogging {
|
public enum EntityLogging {
|
||||||
SPAWN(new String[] { EntityType.ARMOR_STAND.name(), EntityType.ITEM_FRAME.name(), EntityType.SNOWMAN.name() }),
|
SPAWN(new String[] { EntityType.ARMOR_STAND.name(), EntityType.ITEM_FRAME.name(), EntityType.SNOW_GOLEM.name() }),
|
||||||
DESTROY(new String[] { EntityType.ARMOR_STAND.name(), EntityType.ITEM_FRAME.name(), EntityType.VILLAGER.name(), EntityType.SNOWMAN.name(), "ANIMAL" }),
|
DESTROY(new String[] { EntityType.ARMOR_STAND.name(), EntityType.ITEM_FRAME.name(), EntityType.VILLAGER.name(), EntityType.SNOW_GOLEM.name(), "ANIMAL" }),
|
||||||
MODIFY(new String[] { "ALL" });
|
MODIFY(new String[] { "ALL" });
|
||||||
|
|
||||||
public static final int length = EntityLogging.values().length;
|
public static final int length = EntityLogging.values().length;
|
||||||
|
@ -2,6 +2,7 @@ package de.diddiz.LogBlock.listeners;
|
|||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.ArmorStand;
|
import org.bukkit.entity.ArmorStand;
|
||||||
@ -192,18 +193,17 @@ public class AdvancedEntityLogging extends LoggingListener {
|
|||||||
LivingEntity entity = event.getEntity();
|
LivingEntity entity = event.getEntity();
|
||||||
if (Config.isLogging(entity.getWorld(), EntityLogging.DESTROY, entity)) {
|
if (Config.isLogging(entity.getWorld(), EntityLogging.DESTROY, entity)) {
|
||||||
Actor actor = null;
|
Actor actor = null;
|
||||||
EntityDamageEvent lastDamage = entity.getLastDamageCause();
|
Entity cause = event.getDamageSource().getCausingEntity();
|
||||||
if (lastDamage instanceof EntityDamageByEntityEvent) {
|
Entity damager = LoggingUtil.getRealDamager(cause);
|
||||||
Entity damager = LoggingUtil.getRealDamager(((EntityDamageByEntityEvent) lastDamage).getDamager());
|
if (damager != null) {
|
||||||
if (damager != null) {
|
actor = Actor.actorFromEntity(damager);
|
||||||
actor = Actor.actorFromEntity(damager);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (actor == null && entity.getKiller() != null) {
|
if (actor == null && entity.getKiller() != null) {
|
||||||
actor = Actor.actorFromEntity(entity.getKiller());
|
actor = Actor.actorFromEntity(entity.getKiller());
|
||||||
}
|
}
|
||||||
if (actor == null) {
|
if (actor == null) {
|
||||||
actor = new Actor(lastDamage == null ? "UNKNOWN" : lastDamage.getCause().toString());
|
NamespacedKey key = event.getDamageSource().getDamageType().getKey();
|
||||||
|
actor = new Actor(key == null ? "unknown" : key.getKey().toUpperCase());
|
||||||
}
|
}
|
||||||
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.KILL);
|
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.KILL);
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,31 @@ package de.diddiz.LogBlock.listeners;
|
|||||||
import de.diddiz.LogBlock.Actor;
|
import de.diddiz.LogBlock.Actor;
|
||||||
import de.diddiz.LogBlock.LogBlock;
|
import de.diddiz.LogBlock.LogBlock;
|
||||||
import de.diddiz.LogBlock.Logging;
|
import de.diddiz.LogBlock.Logging;
|
||||||
|
import de.diddiz.LogBlock.util.ItemStackAndAmount;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Tag;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.block.DecoratedPot;
|
||||||
import org.bukkit.block.DoubleChest;
|
import org.bukkit.block.DoubleChest;
|
||||||
|
import org.bukkit.block.data.type.ChiseledBookshelf;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -69,9 +79,10 @@ public class ChestAccessLogging extends LoggingListener {
|
|||||||
for (Entry<ItemStack, Integer> e : modifications.entrySet()) {
|
for (Entry<ItemStack, Integer> e : modifications.entrySet()) {
|
||||||
ItemStack stack = e.getKey();
|
ItemStack stack = e.getKey();
|
||||||
int amount = e.getValue();
|
int amount = e.getValue();
|
||||||
stack.setAmount(Math.abs(amount));
|
if (amount != 0) {
|
||||||
// consumer.getLogblock().getLogger().info("Store container: " + stack + " take: " + (amount < 0));
|
// consumer.getLogblock().getLogger().info("Store container: " + stack + " take: " + (amount < 0));
|
||||||
consumer.queueChestAccess(Actor.actorFromEntity(actor), location, location.getWorld().getBlockAt(location).getBlockData(), stack, amount < 0);
|
consumer.queueChestAccess(Actor.actorFromEntity(actor), location, location.getWorld().getBlockAt(location).getBlockData(), new ItemStackAndAmount(stack, Math.abs(amount)), amount < 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
modifications.clear();
|
modifications.clear();
|
||||||
}
|
}
|
||||||
@ -300,4 +311,62 @@ public class ChestAccessLogging extends LoggingListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
final Block clicked = event.getClickedBlock();
|
||||||
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getHand() != EquipmentSlot.HAND || !event.hasBlock() || clicked == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
if (!isLogging(player.getWorld(), Logging.CHESTACCESS)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Material type = clicked.getType();
|
||||||
|
if (type == Material.DECORATED_POT) {
|
||||||
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
||||||
|
if (mainHand != null && mainHand.getType() != Material.AIR && clicked.getState() instanceof DecoratedPot pot) {
|
||||||
|
ItemStack currentInPot = pot.getSnapshotInventory().getItem();
|
||||||
|
if (currentInPot == null || currentInPot.getType() == Material.AIR || currentInPot.isSimilar(mainHand) && currentInPot.getAmount() < currentInPot.getMaxStackSize()) {
|
||||||
|
ItemStack stack = mainHand.clone();
|
||||||
|
stack.setAmount(1);
|
||||||
|
consumer.queueChestAccess(Actor.actorFromEntity(player), clicked.getLocation(), clicked.getBlockData(), ItemStackAndAmount.fromStack(stack), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type == Material.CHISELED_BOOKSHELF) {
|
||||||
|
if (clicked.getBlockData() instanceof ChiseledBookshelf blockData && blockData.getFacing() == event.getBlockFace() && clicked.getState() instanceof org.bukkit.block.ChiseledBookshelf bookshelf) {
|
||||||
|
// calculate the slot the same way as minecraft does it
|
||||||
|
Vector pos = event.getClickedPosition();
|
||||||
|
if (pos == null) {
|
||||||
|
return; // some plugins create this event without a clicked pos
|
||||||
|
}
|
||||||
|
double clickx = switch (blockData.getFacing()) {
|
||||||
|
case NORTH -> 1 - pos.getX();
|
||||||
|
case SOUTH -> pos.getX();
|
||||||
|
case EAST -> 1 - pos.getZ();
|
||||||
|
case WEST -> pos.getZ();
|
||||||
|
default -> throw new IllegalArgumentException("Unexpected facing for chiseled bookshelf: " + blockData.getFacing());
|
||||||
|
};
|
||||||
|
int col = clickx < 0.375 ? 0 : (clickx < 0.6875 ? 1 : 2); // 6/16 ; 11/16
|
||||||
|
int row = pos.getY() >= 0.5 ? 0 : 1;
|
||||||
|
int slot = col + row * 3;
|
||||||
|
|
||||||
|
ItemStack currentInSlot = bookshelf.getSnapshotInventory().getItem(slot);
|
||||||
|
if (blockData.isSlotOccupied(slot)) {
|
||||||
|
// not empty: always take
|
||||||
|
if (currentInSlot != null && currentInSlot.getType() != Material.AIR) {
|
||||||
|
consumer.queueChestAccess(Actor.actorFromEntity(player), clicked.getLocation(), clicked.getBlockData(), ItemStackAndAmount.fromStack(currentInSlot), true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// empty: put if has tag BOOKSHELF_BOOKS
|
||||||
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
||||||
|
if (mainHand != null && mainHand.getType() != Material.AIR && Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(mainHand.getType())) {
|
||||||
|
ItemStack stack = mainHand.clone();
|
||||||
|
stack.setAmount(1);
|
||||||
|
consumer.queueChestAccess(Actor.actorFromEntity(player), clicked.getLocation(), clicked.getBlockData(), ItemStackAndAmount.fromStack(stack), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package de.diddiz.LogBlock.listeners;
|
|
||||||
|
|
||||||
import de.diddiz.LogBlock.Actor;
|
|
||||||
import de.diddiz.LogBlock.LogBlock;
|
|
||||||
import de.diddiz.LogBlock.Logging;
|
|
||||||
import org.bukkit.entity.Enderman;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
|
||||||
|
|
||||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
|
||||||
|
|
||||||
public class EndermenLogging extends LoggingListener {
|
|
||||||
public EndermenLogging(LogBlock lb) {
|
|
||||||
super(lb);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
|
||||||
if (event.getEntity() instanceof Enderman && isLogging(event.getBlock().getWorld(), Logging.ENDERMEN)) {
|
|
||||||
consumer.queueBlockReplace(new Actor("Enderman"), event.getBlock().getState(), event.getBlockData()); // Figure out how to get the data of the placed block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,46 @@
|
|||||||
|
package de.diddiz.LogBlock.listeners;
|
||||||
|
|
||||||
|
import de.diddiz.LogBlock.Actor;
|
||||||
|
import de.diddiz.LogBlock.LogBlock;
|
||||||
|
import de.diddiz.LogBlock.Logging;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Enderman;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Sheep;
|
||||||
|
import org.bukkit.entity.Wither;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||||
|
|
||||||
|
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||||
|
|
||||||
|
public class EntityChangeBlockLogging extends LoggingListener {
|
||||||
|
public EntityChangeBlockLogging(LogBlock lb) {
|
||||||
|
super(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
||||||
|
Material oldType = event.getBlock().getType();
|
||||||
|
if ((oldType == Material.REDSTONE_ORE || oldType == Material.DEEPSLATE_REDSTONE_ORE) && event.getBlockData().getMaterial() == oldType) {
|
||||||
|
return; // ignore redstone ore activation by stepping on it
|
||||||
|
}
|
||||||
|
if (event.getEntity() instanceof Wither) {
|
||||||
|
if (isLogging(event.getBlock().getWorld(), Logging.WITHER)) {
|
||||||
|
consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getBlockData());
|
||||||
|
}
|
||||||
|
} else if (event.getEntity() instanceof Enderman) {
|
||||||
|
if (isLogging(event.getBlock().getWorld(), Logging.ENDERMEN)) {
|
||||||
|
consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getBlockData());
|
||||||
|
}
|
||||||
|
} else if (event.getEntity() instanceof Sheep) {
|
||||||
|
if (isLogging(event.getBlock().getWorld(), Logging.GRASS_EAT)) {
|
||||||
|
consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getBlockData());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isLogging(event.getBlock().getWorld(), event.getEntity() instanceof Player ? Logging.BLOCKPLACE : Logging.MISCENTITYCHANGEBLOCK)) {
|
||||||
|
consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getBlockData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ import de.diddiz.LogBlock.config.Config;
|
|||||||
import de.diddiz.LogBlock.config.WorldConfig;
|
import de.diddiz.LogBlock.config.WorldConfig;
|
||||||
import de.diddiz.LogBlock.util.BukkitUtils;
|
import de.diddiz.LogBlock.util.BukkitUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ExplosionResult;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -41,6 +42,9 @@ public class ExplosionLogging extends LoggingListener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onEntityExplode(EntityExplodeEvent event) {
|
public void onEntityExplode(EntityExplodeEvent event) {
|
||||||
|
if (event.getExplosionResult() == ExplosionResult.KEEP || event.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final WorldConfig wcfg = getWorldConfig(event.getLocation().getWorld());
|
final WorldConfig wcfg = getWorldConfig(event.getLocation().getWorld());
|
||||||
if (wcfg != null) {
|
if (wcfg != null) {
|
||||||
Actor actor = new Actor("Explosion");
|
Actor actor = new Actor("Explosion");
|
||||||
@ -174,6 +178,9 @@ public class ExplosionLogging extends LoggingListener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockExplode(BlockExplodeEvent event) {
|
public void onBlockExplode(BlockExplodeEvent event) {
|
||||||
|
if (event.getExplosionResult() == ExplosionResult.KEEP || event.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Player bedCause = null;
|
Player bedCause = null;
|
||||||
if (lastBedInteractionPlayer != null && lastBedInteractionLocation != null) {
|
if (lastBedInteractionPlayer != null && lastBedInteractionLocation != null) {
|
||||||
Location block = event.getBlock().getLocation();
|
Location block = event.getBlock().getLocation();
|
||||||
|
@ -4,14 +4,13 @@ import de.diddiz.LogBlock.Actor;
|
|||||||
import de.diddiz.LogBlock.LogBlock;
|
import de.diddiz.LogBlock.LogBlock;
|
||||||
import de.diddiz.LogBlock.Logging;
|
import de.diddiz.LogBlock.Logging;
|
||||||
import de.diddiz.LogBlock.config.Config.*;
|
import de.diddiz.LogBlock.config.Config.*;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Monster;
|
import org.bukkit.entity.Monster;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
|
|
||||||
import static de.diddiz.LogBlock.config.Config.*;
|
import static de.diddiz.LogBlock.config.Config.*;
|
||||||
@ -24,27 +23,26 @@ public class KillLogging extends LoggingListener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onEntityDeath(EntityDeathEvent deathEvent) {
|
public void onEntityDeath(EntityDeathEvent deathEvent) {
|
||||||
EntityDamageEvent event = deathEvent.getEntity().getLastDamageCause();
|
if (isLogging(deathEvent.getEntity().getWorld(), Logging.KILL)) {
|
||||||
// For a death event, there should always be a damage event and it should not be cancelled. Check anyway.
|
LivingEntity victim = deathEvent.getEntity();
|
||||||
if (event != null && event.isCancelled() == false && isLogging(event.getEntity().getWorld(), Logging.KILL) && event.getEntity() instanceof LivingEntity) {
|
Entity killer = deathEvent.getDamageSource().getCausingEntity();
|
||||||
final LivingEntity victim = (LivingEntity) event.getEntity();
|
if (killer != null) {
|
||||||
if (event instanceof EntityDamageByEntityEvent) {
|
|
||||||
final Entity killer = ((EntityDamageByEntityEvent) event).getDamager();
|
|
||||||
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player && killer instanceof Player)) {
|
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player && killer instanceof Player)) {
|
||||||
return;
|
return;
|
||||||
} else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster) && killer instanceof Player || killer instanceof Monster)) {
|
} else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster) && killer instanceof Player || killer instanceof Monster)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
consumer.queueKill(killer, victim);
|
consumer.queueKill(killer, victim);
|
||||||
} else if (deathEvent.getEntity().getKiller() != null) {
|
|
||||||
consumer.queueKill(deathEvent.getEntity().getKiller(), victim);
|
|
||||||
} else if (logEnvironmentalKills) {
|
} else if (logEnvironmentalKills) {
|
||||||
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player)) {
|
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player)) {
|
||||||
return;
|
return;
|
||||||
} else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster))) {
|
} else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
consumer.queueKill(new Actor(event.getCause().toString()), victim);
|
NamespacedKey key = deathEvent.getDamageSource().getDamageType().getKey();
|
||||||
|
Actor actor = new Actor(key == null ? "unknown" : key.getKey().toUpperCase());
|
||||||
|
|
||||||
|
consumer.queueKill(actor, victim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,24 @@
|
|||||||
package de.diddiz.LogBlock.listeners;
|
package de.diddiz.LogBlock.listeners;
|
||||||
|
|
||||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||||
|
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||||
|
|
||||||
import de.diddiz.LogBlock.Actor;
|
import de.diddiz.LogBlock.Actor;
|
||||||
import de.diddiz.LogBlock.LogBlock;
|
import de.diddiz.LogBlock.LogBlock;
|
||||||
import de.diddiz.LogBlock.Logging;
|
import de.diddiz.LogBlock.Logging;
|
||||||
import de.diddiz.LogBlock.config.WorldConfig;
|
import de.diddiz.LogBlock.config.WorldConfig;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.Tag;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.Lectern;
|
import org.bukkit.block.Lectern;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
|
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public class LecternLogging extends LoggingListener {
|
public class LecternLogging extends LoggingListener {
|
||||||
@ -21,25 +27,31 @@ public class LecternLogging extends LoggingListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockPlace(BlockPlaceEvent event) {
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
final WorldConfig wcfg = getWorldConfig(event.getPlayer().getWorld());
|
final Block clicked = event.getClickedBlock();
|
||||||
if (wcfg != null && wcfg.isLogging(Logging.LECTERNBOOKCHANGE)) {
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getHand() != EquipmentSlot.HAND || !event.hasBlock() || clicked == null) {
|
||||||
final BlockState before = event.getBlockReplacedState();
|
return;
|
||||||
final BlockState after = event.getBlockPlaced().getState();
|
}
|
||||||
if (before.getType() == Material.LECTERN && after.getType() == Material.LECTERN) {
|
final Player player = event.getPlayer();
|
||||||
Lectern lecternBefore = (Lectern) before.getBlock().getState();
|
if (!isLogging(player.getWorld(), Logging.LECTERNBOOKCHANGE)) {
|
||||||
ItemStack book = lecternBefore.getSnapshotInventory().getItem(0);
|
return;
|
||||||
try {
|
}
|
||||||
lecternBefore.getSnapshotInventory().setItem(0, null);
|
final Material type = clicked.getType();
|
||||||
} catch (NullPointerException e) {
|
if (type == Material.LECTERN) {
|
||||||
//ignored
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
||||||
}
|
if (mainHand != null && mainHand.getType() != Material.AIR && Tag.ITEMS_LECTERN_BOOKS.isTagged(mainHand.getType()) && clicked.getState() instanceof Lectern lectern) {
|
||||||
lecternBefore.setBlockData(before.getBlockData());
|
ItemStack currentInLectern = lectern.getSnapshotInventory().getItem(0);
|
||||||
consumer.queueBlockReplace(Actor.actorFromEntity(event.getPlayer()), lecternBefore, after);
|
if (currentInLectern == null || currentInLectern.getType() == Material.AIR) {
|
||||||
try {
|
ItemStack stack = mainHand.clone();
|
||||||
lecternBefore.getSnapshotInventory().setItem(0, book);
|
stack.setAmount(1);
|
||||||
} catch (NullPointerException e) {
|
Lectern newLectern = (Lectern) clicked.getState();
|
||||||
//ignored
|
newLectern.getSnapshotInventory().setItem(0, stack);
|
||||||
|
org.bukkit.block.data.type.Lectern blockDataOld = (org.bukkit.block.data.type.Lectern) newLectern.getBlockData();
|
||||||
|
org.bukkit.block.data.type.Lectern blockDataWithBook = (org.bukkit.block.data.type.Lectern) Bukkit.createBlockData("lectern[has_book=true]");
|
||||||
|
blockDataWithBook.setFacing(blockDataOld.getFacing());
|
||||||
|
blockDataWithBook.setPowered(blockDataOld.isPowered());
|
||||||
|
newLectern.setBlockData(blockDataWithBook);
|
||||||
|
consumer.queueBlockReplace(Actor.actorFromEntity(event.getPlayer()), lectern, newLectern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package de.diddiz.LogBlock.listeners;
|
|
||||||
|
|
||||||
import de.diddiz.LogBlock.Actor;
|
|
||||||
import de.diddiz.LogBlock.LogBlock;
|
|
||||||
import de.diddiz.LogBlock.Logging;
|
|
||||||
import org.bukkit.entity.Wither;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
|
||||||
|
|
||||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
|
||||||
|
|
||||||
public class WitherLogging extends LoggingListener {
|
|
||||||
public WitherLogging(LogBlock lb) {
|
|
||||||
super(lb);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
|
||||||
if (event.getEntity() instanceof Wither && isLogging(event.getBlock().getWorld(), Logging.WITHER)) {
|
|
||||||
consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getBlockData()); // Wither walked through a block.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,13 +4,14 @@ import static de.diddiz.LogBlock.util.MessagingUtil.prettyMaterial;
|
|||||||
|
|
||||||
import de.diddiz.LogBlock.LogBlock;
|
import de.diddiz.LogBlock.LogBlock;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -147,8 +148,11 @@ public class BukkitUtils {
|
|||||||
// https://minecraft.fandom.com/wiki/Tag#blocks_small_flowers
|
// https://minecraft.fandom.com/wiki/Tag#blocks_small_flowers
|
||||||
Set<Material> smallFlowers = Tag.SMALL_FLOWERS.getValues();
|
Set<Material> smallFlowers = Tag.SMALL_FLOWERS.getValues();
|
||||||
|
|
||||||
// https://minecraft.fandom.com/wiki/Tag#blocks_tall_flowers
|
Set<Material> tallFlowers = Set.of(Material.SUNFLOWER,
|
||||||
Set<Material> tallFlowers = Tag.TALL_FLOWERS.getValues();
|
Material.LILAC,
|
||||||
|
Material.PEONY,
|
||||||
|
Material.ROSE_BUSH,
|
||||||
|
Material.PITCHER_PLANT);
|
||||||
|
|
||||||
Set<Material> bannerStanding = Set.of(Material.WHITE_BANNER,
|
Set<Material> bannerStanding = Set.of(Material.WHITE_BANNER,
|
||||||
Material.ORANGE_BANNER,
|
Material.ORANGE_BANNER,
|
||||||
@ -331,6 +335,7 @@ public class BukkitUtils {
|
|||||||
containerBlocks.add(Material.BLAST_FURNACE);
|
containerBlocks.add(Material.BLAST_FURNACE);
|
||||||
containerBlocks.add(Material.SMOKER);
|
containerBlocks.add(Material.SMOKER);
|
||||||
containerBlocks.add(Material.CHISELED_BOOKSHELF);
|
containerBlocks.add(Material.CHISELED_BOOKSHELF);
|
||||||
|
containerBlocks.add(Material.DECORATED_POT);
|
||||||
// Doesn't actually have a block inventory
|
// Doesn't actually have a block inventory
|
||||||
// containerBlocks.add(Material.ENDER_CHEST);
|
// containerBlocks.add(Material.ENDER_CHEST);
|
||||||
|
|
||||||
@ -341,12 +346,13 @@ public class BukkitUtils {
|
|||||||
projectileItems.put(EntityType.ENDER_PEARL, Material.ENDER_PEARL);
|
projectileItems.put(EntityType.ENDER_PEARL, Material.ENDER_PEARL);
|
||||||
projectileItems.put(EntityType.SMALL_FIREBALL, Material.FIRE_CHARGE); // Fire charge
|
projectileItems.put(EntityType.SMALL_FIREBALL, Material.FIRE_CHARGE); // Fire charge
|
||||||
projectileItems.put(EntityType.FIREBALL, Material.FIRE_CHARGE); // Fire charge
|
projectileItems.put(EntityType.FIREBALL, Material.FIRE_CHARGE); // Fire charge
|
||||||
projectileItems.put(EntityType.FISHING_HOOK, Material.FISHING_ROD);
|
projectileItems.put(EntityType.FISHING_BOBBER, Material.FISHING_ROD);
|
||||||
projectileItems.put(EntityType.SNOWBALL, Material.SNOWBALL);
|
projectileItems.put(EntityType.SNOWBALL, Material.SNOWBALL);
|
||||||
projectileItems.put(EntityType.SPLASH_POTION, Material.SPLASH_POTION);
|
projectileItems.put(EntityType.SPLASH_POTION, Material.SPLASH_POTION);
|
||||||
projectileItems.put(EntityType.THROWN_EXP_BOTTLE, Material.EXPERIENCE_BOTTLE);
|
projectileItems.put(EntityType.LINGERING_POTION, Material.LINGERING_POTION);
|
||||||
|
projectileItems.put(EntityType.EXPERIENCE_BOTTLE, Material.EXPERIENCE_BOTTLE);
|
||||||
projectileItems.put(EntityType.WITHER_SKULL, Material.WITHER_SKELETON_SKULL);
|
projectileItems.put(EntityType.WITHER_SKULL, Material.WITHER_SKELETON_SKULL);
|
||||||
projectileItems.put(EntityType.FIREWORK, Material.FIREWORK_ROCKET);
|
projectileItems.put(EntityType.FIREWORK_ROCKET, Material.FIREWORK_ROCKET);
|
||||||
|
|
||||||
nonFluidProofBlocks = new HashSet<>();
|
nonFluidProofBlocks = new HashSet<>();
|
||||||
nonFluidProofBlocks.addAll(carpets);
|
nonFluidProofBlocks.addAll(carpets);
|
||||||
@ -498,24 +504,22 @@ public class BukkitUtils {
|
|||||||
return diff.toArray(new ItemStack[diff.size()]);
|
return diff.toArray(new ItemStack[diff.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemStack[] compressInventory(ItemStack[] items) {
|
public static Collection<ItemStackAndAmount> compressInventory(ItemStack[] items) {
|
||||||
final ArrayList<ItemStack> compressed = new ArrayList<>();
|
final HashMap<ItemStack, Integer> compressed = new HashMap<>();
|
||||||
for (final ItemStack item : items) {
|
for (final ItemStack item : items) {
|
||||||
if (item != null) {
|
if (item != null && item.getType() != Material.AIR && item.getAmount() > 0) {
|
||||||
boolean found = false;
|
int amount = item.getAmount();
|
||||||
for (final ItemStack item2 : compressed) {
|
ItemStack stack = item.clone();
|
||||||
if (item2.isSimilar(item)) {
|
stack.setAmount(1);
|
||||||
item2.setAmount(item2.getAmount() + item.getAmount());
|
Integer old = compressed.get(stack);
|
||||||
found = true;
|
compressed.put(stack, (old == null ? 0 : old) + amount);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
compressed.add(item.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return compressed.toArray(new ItemStack[compressed.size()]);
|
ArrayList<ItemStackAndAmount> result = new ArrayList<>();
|
||||||
|
for (Entry<ItemStack, Integer> e : compressed.entrySet()) {
|
||||||
|
result.add(new ItemStackAndAmount(e.getKey(), e.getValue()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String friendlyWorldname(String worldName) {
|
public static String friendlyWorldname(String worldName) {
|
||||||
@ -602,15 +606,13 @@ public class BukkitUtils {
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int modifyContainer(BlockState b, ItemStack item, boolean remove) {
|
public static int modifyContainer(BlockState b, ItemStackAndAmount item, boolean remove) {
|
||||||
if (b instanceof InventoryHolder) {
|
if (item.amount() > 0 && b instanceof InventoryHolder c) {
|
||||||
final Inventory inv = ((InventoryHolder) b).getInventory();
|
final Inventory inv = c.getInventory();
|
||||||
if (remove) {
|
if (remove) {
|
||||||
final ItemStack tmp = inv.removeItem(item).get(0);
|
return InventoryUtils.removeFromInventory(inv, item);
|
||||||
return tmp != null ? tmp.getAmount() : 0;
|
} else {
|
||||||
} else if (item.getAmount() > 0) {
|
return InventoryUtils.addToInventory(inv, item);
|
||||||
final ItemStack tmp = inv.addItem(item).get(0);
|
|
||||||
return tmp != null ? tmp.getAmount() : 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -656,16 +658,16 @@ public class BukkitUtils {
|
|||||||
return m == Material.AIR || m == Material.CAVE_AIR || m == Material.VOID_AIR;
|
return m == Material.AIR || m == Material.CAVE_AIR || m == Material.VOID_AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextComponent toString(ItemStack stack) {
|
public static TextComponent toString(ItemStackAndAmount stack) {
|
||||||
if (stack == null || stack.getAmount() == 0 || isEmpty(stack.getType())) {
|
if (stack == null || stack.stack() == null || stack.amount() == 0 || isEmpty(stack.stack().getType())) {
|
||||||
return prettyMaterial("nothing");
|
return prettyMaterial("nothing");
|
||||||
}
|
}
|
||||||
TextComponent msg = MessagingUtil.createTextComponentWithColor(stack.getAmount() + "x ", TypeColor.DEFAULT.getColor());
|
TextComponent msg = MessagingUtil.createTextComponentWithColor(stack.amount() + "x ", TypeColor.DEFAULT.getColor());
|
||||||
msg.addExtra(prettyMaterial(stack.getType()));
|
msg.addExtra(prettyMaterial(stack.stack().getType()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String itemTag = getItemTag(stack);
|
String itemTag = stack.stack().getItemMeta().getAsString();
|
||||||
msg.setHoverEvent(new HoverEvent(Action.SHOW_ITEM, new Item(stack.getType().getKey().toString(), 1, itemTag != null ? ItemTag.ofNbt(itemTag) : null)));
|
msg.setHoverEvent(new HoverEvent(Action.SHOW_ITEM, new Item(stack.stack().getType().getKey().toString(), 1, itemTag != null ? ItemTag.ofNbt(itemTag) : null)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogBlock.getInstance().getLogger().log(Level.SEVERE, "Failed to convert Itemstack to JSON", e);
|
LogBlock.getInstance().getLogger().log(Level.SEVERE, "Failed to convert Itemstack to JSON", e);
|
||||||
msg.setHoverEvent(new HoverEvent(Action.SHOW_TEXT, new Text(new BaseComponent[] { MessagingUtil.createTextComponentWithColor("Error", TypeColor.ERROR.getColor()) })));
|
msg.setHoverEvent(new HoverEvent(Action.SHOW_TEXT, new Text(new BaseComponent[] { MessagingUtil.createTextComponentWithColor("Error", TypeColor.ERROR.getColor()) })));
|
||||||
@ -674,20 +676,6 @@ public class BukkitUtils {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getItemTag(ItemStack itemStack) throws ReflectiveOperationException {
|
|
||||||
Class<?> craftItemStackClazz = ReflectionUtil.getCraftBukkitClass("inventory.CraftItemStack");
|
|
||||||
Method asNMSCopyMethod = craftItemStackClazz.getMethod("asNMSCopy", ItemStack.class);
|
|
||||||
|
|
||||||
Class<?> nmsItemStackClazz = ReflectionUtil.getMinecraftClass("world.item.ItemStack");
|
|
||||||
Method getTagMethod = nmsItemStackClazz.getDeclaredMethod("getTagClone");
|
|
||||||
getTagMethod.setAccessible(true);
|
|
||||||
|
|
||||||
Object nmsItemStack = asNMSCopyMethod.invoke(null, itemStack);
|
|
||||||
Object itemTag = getTagMethod.invoke(nmsItemStack);
|
|
||||||
|
|
||||||
return itemTag != null ? itemTag.toString() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String formatMinecraftKey(String s) {
|
public static String formatMinecraftKey(String s) {
|
||||||
char[] cap = s.toCharArray();
|
char[] cap = s.toCharArray();
|
||||||
boolean lastSpace = true;
|
boolean lastSpace = true;
|
||||||
|
113
src/main/java/de/diddiz/LogBlock/util/InventoryUtils.java
Normal file
113
src/main/java/de/diddiz/LogBlock/util/InventoryUtils.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package de.diddiz.LogBlock.util;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class InventoryUtils {
|
||||||
|
|
||||||
|
public static int addToInventory(Inventory inventory, ItemStackAndAmount item) {
|
||||||
|
if (item == null || item.stack() == null || item.stack().getType() == Material.AIR) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int maxStackSize = Math.max(Math.min(inventory.getMaxStackSize(), item.stack().getMaxStackSize()), 1);
|
||||||
|
|
||||||
|
ItemStack[] contents = inventory.getStorageContents();
|
||||||
|
|
||||||
|
int remaining = item.amount();
|
||||||
|
int initialRemaining = remaining;
|
||||||
|
|
||||||
|
// fill partial stacks
|
||||||
|
int firstPartial = -1;
|
||||||
|
while (remaining > 0) {
|
||||||
|
firstPartial = getFirstPartial(item.stack(), maxStackSize, contents, firstPartial + 1);
|
||||||
|
if (firstPartial < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ItemStack content = contents[firstPartial];
|
||||||
|
int add = Math.min(maxStackSize - content.getAmount(), remaining);
|
||||||
|
content.setAmount(content.getAmount() + add);
|
||||||
|
remaining -= add;
|
||||||
|
}
|
||||||
|
// create new stacks
|
||||||
|
int firstFree = -1;
|
||||||
|
while (remaining > 0) {
|
||||||
|
firstFree = getFirstFree(contents, firstFree + 1);
|
||||||
|
if (firstFree < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ItemStack content = item.stack().clone();
|
||||||
|
contents[firstFree] = content;
|
||||||
|
int add = Math.min(maxStackSize, remaining);
|
||||||
|
content.setAmount(add);
|
||||||
|
remaining -= add;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining < initialRemaining) {
|
||||||
|
inventory.setStorageContents(contents);
|
||||||
|
}
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int removeFromInventory(Inventory inventory, ItemStackAndAmount item) {
|
||||||
|
if (item == null || item.stack() == null || item.stack().getType() == Material.AIR) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack[] contents = inventory.getStorageContents();
|
||||||
|
int remaining = item.amount();
|
||||||
|
int initialRemaining = remaining;
|
||||||
|
|
||||||
|
int firstSimilar = -1;
|
||||||
|
while (remaining > 0) {
|
||||||
|
firstSimilar = getFirstSimilar(item.stack(), contents, firstSimilar + 1);
|
||||||
|
if (firstSimilar < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ItemStack content = contents[firstSimilar];
|
||||||
|
int here = content.getAmount();
|
||||||
|
if (here > remaining) {
|
||||||
|
content.setAmount(here - remaining);
|
||||||
|
remaining = 0;
|
||||||
|
} else {
|
||||||
|
contents[firstSimilar] = null;
|
||||||
|
remaining -= here;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining < initialRemaining) {
|
||||||
|
inventory.setStorageContents(contents);
|
||||||
|
}
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getFirstSimilar(ItemStack item, ItemStack[] contents, int start) {
|
||||||
|
for (int i = start; i < contents.length; i++) {
|
||||||
|
ItemStack content = contents[i];
|
||||||
|
if (content != null && content.isSimilar(item)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getFirstPartial(ItemStack item, int maxStackSize, ItemStack[] contents, int start) {
|
||||||
|
for (int i = start; i < contents.length; i++) {
|
||||||
|
ItemStack content = contents[i];
|
||||||
|
if (content != null && content.isSimilar(item) && content.getAmount() < maxStackSize) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getFirstFree(ItemStack[] contents, int start) {
|
||||||
|
for (int i = start; i < contents.length; i++) {
|
||||||
|
ItemStack content = contents[i];
|
||||||
|
if (content == null || content.getAmount() == 0 || content.getType() == Material.AIR) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package de.diddiz.LogBlock.util;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public record ItemStackAndAmount(ItemStack stack, int amount) {
|
||||||
|
|
||||||
|
public static ItemStackAndAmount fromStack(ItemStack stack) {
|
||||||
|
int amount = stack.getAmount();
|
||||||
|
if (amount > 1) {
|
||||||
|
stack = stack.clone();
|
||||||
|
stack.setAmount(1);
|
||||||
|
}
|
||||||
|
return new ItemStackAndAmount(stack, amount);
|
||||||
|
}
|
||||||
|
}
|
@ -18,10 +18,14 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
public class MessagingUtil {
|
public class MessagingUtil {
|
||||||
public static BaseComponent[] formatSummarizedChanges(int created, int destroyed, BaseComponent actor, int createdWidth, int destroyedWidth, float spaceFactor) {
|
public static BaseComponent formatSummarizedChanges(int created, int destroyed, BaseComponent actor, int createdWidth, int destroyedWidth, float spaceFactor) {
|
||||||
TextComponent textCreated = createTextComponentWithColor(created + spaces((int) ((10 - String.valueOf(created).length()) / spaceFactor)), CREATE.getColor());
|
TextComponent textCreated = createTextComponentWithColor(created + spaces((int) ((10 - String.valueOf(created).length()) / spaceFactor)), CREATE.getColor());
|
||||||
TextComponent textDestroyed = createTextComponentWithColor(destroyed + spaces((int) ((10 - String.valueOf(destroyed).length()) / spaceFactor)), DESTROY.getColor());
|
TextComponent textDestroyed = createTextComponentWithColor(destroyed + spaces((int) ((10 - String.valueOf(destroyed).length()) / spaceFactor)), DESTROY.getColor());
|
||||||
return new BaseComponent[] { textCreated, textDestroyed, actor };
|
TextComponent result = new TextComponent();
|
||||||
|
result.addExtra(textCreated);
|
||||||
|
result.addExtra(textDestroyed);
|
||||||
|
result.addExtra(actor);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextComponent createTextComponentWithColor(String text, ChatColor color) {
|
public static TextComponent createTextComponentWithColor(String text, ChatColor color) {
|
||||||
|
@ -8,6 +8,7 @@ import com.google.gson.JsonObject;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -45,7 +46,7 @@ public class UUIDFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static HttpURLConnection createConnection() throws Exception {
|
private static HttpURLConnection createConnection() throws Exception {
|
||||||
URL url = new URL(PROFILE_URL);
|
URL url = new URI(PROFILE_URL).toURL();
|
||||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("Content-Type", "application/json");
|
connection.setRequestProperty("Content-Type", "application/json");
|
||||||
|
@ -231,20 +231,35 @@ public class Utils {
|
|||||||
return untrusted.replace("\\", "\\\\").replace("'", "\\'");
|
return untrusted.replace("\\", "\\\\").replace("'", "\\'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemStack loadItemStack(byte[] data) {
|
public static ItemStackAndAmount loadItemStack(byte[] data) {
|
||||||
if (data == null || data.length == 0) {
|
if (data == null || data.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
YamlConfiguration conf = deserializeYamlConfiguration(data);
|
YamlConfiguration conf = deserializeYamlConfiguration(data);
|
||||||
return conf == null ? null : conf.getItemStack("stack");
|
if (conf == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ItemStack stack = conf.getItemStack("stack");
|
||||||
|
if (stack == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int amount = conf.contains("amount") ? conf.getInt("amount") : stack.getAmount();
|
||||||
|
stack.setAmount(1);
|
||||||
|
return new ItemStackAndAmount(stack, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] saveItemStack(ItemStack stack) {
|
public static byte[] saveItemStack(ItemStackAndAmount stack) {
|
||||||
if (stack == null || BukkitUtils.isEmpty(stack.getType())) {
|
if (stack == null || stack.stack() == null || BukkitUtils.isEmpty(stack.stack().getType())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
YamlConfiguration conf = new YamlConfiguration();
|
YamlConfiguration conf = new YamlConfiguration();
|
||||||
conf.set("stack", stack);
|
ItemStack itemStack = stack.stack();
|
||||||
|
if (itemStack.getAmount() > 1) {
|
||||||
|
itemStack = itemStack.clone();
|
||||||
|
itemStack.setAmount(1);
|
||||||
|
}
|
||||||
|
conf.set("stack", itemStack);
|
||||||
|
conf.set("amount", stack.amount());
|
||||||
return serializeYamlConfiguration(conf);
|
return serializeYamlConfiguration(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ package de.diddiz.LogBlock.worldedit;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@ -17,15 +17,15 @@ import org.bukkit.entity.EntityType;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import org.enginehub.linbus.stream.LinBinaryIO;
|
||||||
import com.sk89q.jnbt.DoubleTag;
|
import org.enginehub.linbus.stream.LinStream;
|
||||||
import com.sk89q.jnbt.FloatTag;
|
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import org.enginehub.linbus.tree.LinDoubleTag;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import org.enginehub.linbus.tree.LinIntArrayTag;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import org.enginehub.linbus.tree.LinListTag;
|
||||||
import com.sk89q.jnbt.NamedTag;
|
import org.enginehub.linbus.tree.LinLongTag;
|
||||||
import com.sk89q.jnbt.ShortTag;
|
import org.enginehub.linbus.tree.LinRootEntry;
|
||||||
import com.sk89q.jnbt.Tag;
|
import org.enginehub.linbus.tree.LinTagType;
|
||||||
import com.sk89q.worldedit.IncompleteRegionException;
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
@ -33,6 +33,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
|||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||||
import de.diddiz.LogBlock.LogBlock;
|
import de.diddiz.LogBlock.LogBlock;
|
||||||
import de.diddiz.LogBlock.util.CuboidRegion;
|
import de.diddiz.LogBlock.util.CuboidRegion;
|
||||||
|
|
||||||
@ -107,21 +108,25 @@ public class WorldEditHelper {
|
|||||||
com.sk89q.worldedit.world.entity.EntityType weType = BukkitAdapter.adapt(type);
|
com.sk89q.worldedit.world.entity.EntityType weType = BukkitAdapter.adapt(type);
|
||||||
com.sk89q.worldedit.util.Location weLocation = BukkitAdapter.adapt(location);
|
com.sk89q.worldedit.util.Location weLocation = BukkitAdapter.adapt(location);
|
||||||
try {
|
try {
|
||||||
NBTInputStream nbtis = new NBTInputStream(new ByteArrayInputStream(serialized));
|
LinStream stream = LinBinaryIO.read(new DataInputStream(new ByteArrayInputStream(serialized)));
|
||||||
NamedTag namedTag = nbtis.readNamedTag();
|
LinRootEntry namedTag = LinRootEntry.readFrom(stream);
|
||||||
nbtis.close();
|
|
||||||
UUID newUUID = null;
|
UUID newUUID = null;
|
||||||
if (namedTag.getName().equals("entity") && namedTag.getTag() instanceof CompoundTag) {
|
if (namedTag.name().equals("entity")) {
|
||||||
CompoundTag serializedState = (CompoundTag) namedTag.getTag();
|
LinCompoundTag serializedState = namedTag.value();
|
||||||
BaseEntity state = new BaseEntity(weType, serializedState);
|
BaseEntity state = new BaseEntity(weType, LazyReference.computed(serializedState));
|
||||||
com.sk89q.worldedit.entity.Entity weEntity = weLocation.getExtent().createEntity(weLocation, state);
|
com.sk89q.worldedit.entity.Entity weEntity = weLocation.getExtent().createEntity(weLocation, state);
|
||||||
if (weEntity != null) {
|
if (weEntity != null) {
|
||||||
CompoundTag newNbt = weEntity.getState().getNbtData();
|
LinCompoundTag newNbt = weEntity.getState().getNbt();
|
||||||
int[] uuidInts = newNbt.getIntArray("UUID");
|
LinIntArrayTag uuidTag = newNbt.findTag("UUID", LinTagType.intArrayTag());
|
||||||
|
int[] uuidInts = uuidTag == null ? null : uuidTag.value();
|
||||||
if (uuidInts != null && uuidInts.length >= 4) {
|
if (uuidInts != null && uuidInts.length >= 4) {
|
||||||
newUUID = new UUID(((long) uuidInts[0] << 32) | (uuidInts[1] & 0xFFFFFFFFL), ((long) uuidInts[2] << 32) | (uuidInts[3] & 0xFFFFFFFFL));
|
newUUID = new UUID(((long) uuidInts[0] << 32) | (uuidInts[1] & 0xFFFFFFFFL), ((long) uuidInts[2] << 32) | (uuidInts[3] & 0xFFFFFFFFL));
|
||||||
} else {
|
} else {
|
||||||
newUUID = new UUID(newNbt.getLong("UUIDMost"), newNbt.getLong("UUIDLeast")); // pre 1.16
|
LinLongTag uuidMostTag = newNbt.findTag("UUIDMost", LinTagType.longTag());
|
||||||
|
LinLongTag uuidLeastTag = newNbt.findTag("UUIDLeast", LinTagType.longTag());
|
||||||
|
if (uuidMostTag != null && uuidLeastTag != null) {
|
||||||
|
newUUID = new UUID(uuidMostTag.valueAsLong(), uuidLeastTag.valueAsLong()); // pre 1.16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,16 +141,18 @@ public class WorldEditHelper {
|
|||||||
BaseEntity state = weEntity.getState();
|
BaseEntity state = weEntity.getState();
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
try {
|
try {
|
||||||
|
LinCompoundTag.Builder nbt = state.getNbt().toBuilder();
|
||||||
|
nbt.putFloat("Health", 20.0f);
|
||||||
|
nbt.put("Motion", LinListTag.builder(LinTagType.doubleTag()).add(LinDoubleTag.of(0)).add(LinDoubleTag.of(0)).add(LinDoubleTag.of(0)).build());
|
||||||
|
nbt.putShort("Fire", (short) -20);
|
||||||
|
nbt.putShort("HurtTime", (short) 0);
|
||||||
|
|
||||||
|
LinRootEntry root = new LinRootEntry("entity", nbt.build());
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
NBTOutputStream nbtos = new NBTOutputStream(baos);
|
try (DataOutputStream dos = new DataOutputStream(baos)) {
|
||||||
CompoundTag nbt = state.getNbtData();
|
LinBinaryIO.write(dos, root);
|
||||||
LinkedHashMap<String, Tag<?, ?>> value = new LinkedHashMap<>(nbt.getValue());
|
}
|
||||||
value.put("Health", new FloatTag(20.0f));
|
|
||||||
value.put("Motion", new ListTag(DoubleTag.class, Arrays.asList(new DoubleTag[] { new DoubleTag(0), new DoubleTag(0), new DoubleTag(0) })));
|
|
||||||
value.put("Fire", new ShortTag((short) -20));
|
|
||||||
value.put("HurtTime", new ShortTag((short) 0));
|
|
||||||
nbtos.writeNamedTag("entity", new CompoundTag(value));
|
|
||||||
nbtos.close();
|
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("This IOException should be impossible", e);
|
throw new RuntimeException("This IOException should be impossible", e);
|
||||||
@ -175,7 +182,7 @@ public class WorldEditHelper {
|
|||||||
}
|
}
|
||||||
BlockVector3 min = selection.getMinimumPoint();
|
BlockVector3 min = selection.getMinimumPoint();
|
||||||
BlockVector3 max = selection.getMaximumPoint();
|
BlockVector3 max = selection.getMaximumPoint();
|
||||||
return new CuboidRegion(world, new BlockVector(min.getBlockX(), min.getBlockY(), min.getBlockZ()), new BlockVector(max.getBlockX(), max.getBlockY(), max.getBlockZ()));
|
return new CuboidRegion(world, new BlockVector(min.x(), min.y(), min.z()), new BlockVector(max.x(), max.y(), max.z()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user