mirror of
https://github.com/songoda/SongodaCore.git
synced 2024-12-03 15:33:32 +01:00
Merge branch 'development'
This commit is contained in:
commit
e57cd93629
3
.github/workflows/maven.yml
vendored
3
.github/workflows/maven.yml
vendored
@ -27,9 +27,8 @@ jobs:
|
||||
# Build remapped Spigot versions
|
||||
- uses: SpraxDev/Action-SpigotMC@v4
|
||||
with:
|
||||
versions: 1.18.2, 1.19, 1.19.2
|
||||
versions: 1.18, 1.18.2, 1.19, 1.19.2, 1.19.3
|
||||
remapped: true
|
||||
forceRun: true
|
||||
|
||||
# Build project
|
||||
- name: Build with Maven
|
||||
|
2
.github/workflows/sonarcloud.yml
vendored
2
.github/workflows/sonarcloud.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
||||
# Build remapped Spigot versions
|
||||
- uses: SpraxDev/Action-SpigotMC@v4
|
||||
with:
|
||||
versions: 1.18.2, 1.19
|
||||
versions: 1.18, 1.18.2, 1.19, 1.19.2, 1.19.3
|
||||
remapped: true
|
||||
|
||||
- name: Analyze project
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -47,6 +47,7 @@ public enum ClassMapping {
|
||||
CRAFT_PLAYER("entity", "CraftPlayer"),
|
||||
CRAFT_WORLD("CraftWorld"),
|
||||
|
||||
SINGLE_THREADED_RANDOM_SOURCE("world.level.levelgen", "SingleThreadedRandomSource"),
|
||||
RANDOM_SOURCE("util", "RandomSource"),
|
||||
MOJANGSON_PARSER("nbt", "MojangsonParser");
|
||||
|
||||
|
48
Core/pom.xml
48
Core/pom.xml
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@ -98,6 +98,18 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.intellectualsites.bom</groupId>
|
||||
<artifactId>bom-1.18.x</artifactId>
|
||||
<version>1.18</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
@ -116,7 +128,7 @@
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<version>2.11.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
@ -249,6 +261,12 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>SongodaCore-NMS-v1_19_R2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- End NMS -->
|
||||
|
||||
<!-- Start Plugin Hooks -->
|
||||
@ -311,7 +329,7 @@
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>UltimateStacker</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<version>2.3.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -371,6 +389,24 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.plotsquared</groupId>
|
||||
<artifactId>PlotSquared-Core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.plotsquared</groupId>
|
||||
<artifactId>PlotSquared-Bukkit</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>PlotSquared-Core</artifactId>
|
||||
<groupId>*</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>UltimateClaims</artifactId>
|
||||
@ -437,6 +473,12 @@
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>3.0.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
|
@ -8,6 +8,8 @@ import com.songoda.core.core.PluginInfo;
|
||||
import com.songoda.core.core.PluginInfoModule;
|
||||
import com.songoda.core.core.SongodaCoreCommand;
|
||||
import com.songoda.core.core.SongodaCoreDiagCommand;
|
||||
import com.songoda.core.core.SongodaCoreIPCommand;
|
||||
import com.songoda.core.core.SongodaCoreUUIDCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -53,7 +55,7 @@ public class SongodaCore {
|
||||
/**
|
||||
* @since coreRevision 6
|
||||
*/
|
||||
private final static String coreVersion = "2.6.16";
|
||||
private final static String coreVersion = "2.6.18";
|
||||
|
||||
/**
|
||||
* This is specific to the website api
|
||||
@ -172,7 +174,7 @@ public class SongodaCore {
|
||||
private void init() {
|
||||
shadingListener = new ShadedEventListener();
|
||||
commandManager.registerCommandDynamically(new SongodaCoreCommand())
|
||||
.addSubCommand(new SongodaCoreDiagCommand());
|
||||
.addSubCommands(new SongodaCoreDiagCommand(), new SongodaCoreIPCommand(), new SongodaCoreUUIDCommand());
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
|
||||
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.songoda.core.configuration.Config;
|
||||
import com.songoda.core.database.DataManagerAbstract;
|
||||
import com.songoda.core.locale.Locale;
|
||||
import com.songoda.core.utils.Metrics;
|
||||
import com.songoda.core.utils.SongodaAuth;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -90,6 +91,25 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
//Check plugin access, don't load plugin if user don't have access
|
||||
if (!SongodaAuth.isAuthorized(true)) {
|
||||
Thread thread = new Thread(() -> {
|
||||
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
console.sendMessage(ChatColor.RED + "You do not have access to this plugin.");
|
||||
console.sendMessage(ChatColor.YELLOW + "Please purchase a license at https://sngda.to/marketplace");
|
||||
console.sendMessage(ChatColor.YELLOW + "or set up your license at https://sngda.to/licenses");
|
||||
console.sendMessage(ChatColor.YELLOW + "License setup steps:");
|
||||
console.sendMessage(ChatColor.YELLOW + "Visit the link mentioned above and click the 'Create License button'");
|
||||
console.sendMessage(ChatColor.YELLOW + "Copy the following ip and uuid and click create.");
|
||||
console.sendMessage(ChatColor.YELLOW + "IP: " + SongodaAuth.getIP());
|
||||
console.sendMessage(ChatColor.YELLOW + "UUID: " + SongodaAuth.getUUID());
|
||||
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
});
|
||||
thread.start();
|
||||
emergencyStop();
|
||||
return;
|
||||
}
|
||||
|
||||
console.sendMessage(" "); // blank line to separate chatter
|
||||
console.sendMessage(ChatColor.GREEN + "=============================");
|
||||
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY,
|
||||
|
@ -20,7 +20,7 @@ public class SongodaCoreDiagCommand extends AbstractCommand {
|
||||
private Field tpsField;
|
||||
|
||||
public SongodaCoreDiagCommand() {
|
||||
super(false, "diag");
|
||||
super(CommandType.CONSOLE_OK, "diag");
|
||||
|
||||
try {
|
||||
serverInstance = ClassMapping.MINECRAFT_SERVER.getClazz().getMethod("getServer").invoke(null);
|
||||
|
@ -0,0 +1,73 @@
|
||||
package com.songoda.core.core;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.core.utils.SongodaAuth;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
public class SongodaCoreIPCommand extends AbstractCommand {
|
||||
|
||||
public SongodaCoreIPCommand() {
|
||||
super(CommandType.CONSOLE_OK, "myip");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
Thread thread = new Thread(() -> {
|
||||
String ip = SongodaAuth.getIP();
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("IP Information");
|
||||
sender.sendMessage("");
|
||||
if (sender instanceof Player) {
|
||||
TextComponent component = new TextComponent("Your public IP is: " + ip);
|
||||
component.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, ip));
|
||||
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[]{new TextComponent("Click to copy")}));
|
||||
sender.spigot().sendMessage(component);
|
||||
} else {
|
||||
sender.sendMessage("Your public IP is: " + ip);
|
||||
}
|
||||
sender.sendMessage("");
|
||||
});
|
||||
thread.start();
|
||||
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "songoda.admin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/songoda myip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Displays your public IP address.";
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.songoda.core.core;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.core.utils.SongodaAuth;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SongodaCoreUUIDCommand extends AbstractCommand {
|
||||
|
||||
public SongodaCoreUUIDCommand() {
|
||||
super(CommandType.CONSOLE_OK, "uuid");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
sender.sendMessage("");
|
||||
if (sender instanceof Player) {
|
||||
TextComponent component = new TextComponent("Your server UUID is: " + SongodaAuth.getUUID());
|
||||
component.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, SongodaAuth.getUUID().toString()));
|
||||
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[]{new TextComponent("Click to copy")}));
|
||||
sender.spigot().sendMessage(component);
|
||||
} else {
|
||||
sender.sendMessage("Your server UUID is: " + SongodaAuth.getUUID());
|
||||
}
|
||||
sender.sendMessage("");
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "songodacore.admin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/songodacore uuid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Returns your server's uuid";
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import java.util.function.Consumer;
|
||||
public class DataManagerAbstract {
|
||||
protected final DatabaseConnector databaseConnector;
|
||||
protected final Plugin plugin;
|
||||
protected final DatabaseType type;
|
||||
|
||||
protected final ExecutorService asyncPool = Executors.newSingleThreadExecutor();
|
||||
|
||||
@ -30,6 +31,7 @@ public class DataManagerAbstract {
|
||||
public DataManagerAbstract(DatabaseConnector databaseConnector, Plugin plugin) {
|
||||
this.databaseConnector = databaseConnector;
|
||||
this.plugin = plugin;
|
||||
this.type = databaseConnector.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,4 +198,11 @@ public class DataManagerAbstract {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public String getSyntax(String string, DatabaseType type) {
|
||||
if (this.type == type) {
|
||||
return string;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@ -31,4 +31,6 @@ public interface DatabaseConnector {
|
||||
}
|
||||
|
||||
Connection getConnection();
|
||||
|
||||
DatabaseType getType();
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.songoda.core.database;
|
||||
|
||||
public enum DatabaseType {
|
||||
|
||||
MARIADB,
|
||||
MYSQL,
|
||||
SQLITE
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.songoda.core.database;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MariaDBConnector implements DatabaseConnector {
|
||||
|
||||
private final Plugin plugin;
|
||||
private HikariDataSource hikari;
|
||||
private boolean initializedSuccessfully;
|
||||
|
||||
public MariaDBConnector(Plugin plugin, String hostname, int port, String database, String username, String password, boolean useSSL, int poolSize) {
|
||||
this.plugin = plugin;
|
||||
|
||||
plugin.getLogger().info("connecting to " + hostname + " : " + port);
|
||||
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl("jdbc:mariadb://" + hostname + ":" + port + "/" + database + "?useSSL=" + useSSL);
|
||||
config.setUsername(username);
|
||||
config.setPassword(password);
|
||||
config.setMaximumPoolSize(poolSize);
|
||||
|
||||
try {
|
||||
this.hikari = new HikariDataSource(config);
|
||||
this.initializedSuccessfully = true;
|
||||
} catch (Exception ex) {
|
||||
this.initializedSuccessfully = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return this.initializedSuccessfully;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection() {
|
||||
this.hikari.close();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void connect(DatabaseConnector.ConnectionCallback callback) {
|
||||
try (Connection connection = this.hikari.getConnection()) {
|
||||
callback.accept(connection);
|
||||
} catch (SQLException ex) {
|
||||
this.plugin.getLogger().severe("An error occurred executing a MySQL query: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
try {
|
||||
return this.hikari.getConnection();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseType getType() {
|
||||
return DatabaseType.MARIADB;
|
||||
}
|
||||
}
|
@ -61,4 +61,9 @@ public class MySQLConnector implements DatabaseConnector {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseType getType() {
|
||||
return DatabaseType.MYSQL;
|
||||
}
|
||||
}
|
||||
|
@ -42,16 +42,8 @@ public class SQLiteConnector implements DatabaseConnector {
|
||||
@Deprecated
|
||||
@Override
|
||||
public void connect(ConnectionCallback callback) {
|
||||
if (this.connection == null) {
|
||||
try {
|
||||
this.connection = DriverManager.getConnection(this.connectionString);
|
||||
} catch (SQLException ex) {
|
||||
this.plugin.getLogger().severe("An error occurred retrieving the SQLite database connection: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
callback.accept(this.connection);
|
||||
callback.accept(getConnection());
|
||||
} catch (Exception ex) {
|
||||
this.plugin.getLogger().severe("An error occurred executing an SQLite query: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
@ -73,4 +65,9 @@ public class SQLiteConnector implements DatabaseConnector {
|
||||
}
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseType getType() {
|
||||
return DatabaseType.SQLITE;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.songoda.core.hooks.protection;
|
||||
|
||||
import com.plotsquared.core.PlotAPI;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.plot.PlotArea;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class PlotSquaredProtection extends Protection {
|
||||
|
||||
PlotSquared plotSquared;
|
||||
|
||||
public PlotSquaredProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
plotSquared = PlotSquared.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PlotSquared";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return plotSquared != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlace(Player player, Location location) {
|
||||
return plotSquared.getPlotAreaManager().getApplicablePlotArea(com.plotsquared.core.location.Location.at(location.getWorld().getName(), (int) location.getX(), (int) location.getY(), (int) location.getZ())).getPlots().stream().anyMatch(p -> p.isAdded(player.getUniqueId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBreak(Player player, Location location) {
|
||||
return plotSquared.getPlotAreaManager().getApplicablePlotArea(com.plotsquared.core.location.Location.at(location.getWorld().getName(), (int) location.getX(), (int) location.getY(), (int) location.getZ())).getPlots().stream().anyMatch(p -> p.isAdded(player.getUniqueId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteract(Player player, Location location) {
|
||||
return plotSquared.getPlotAreaManager().getApplicablePlotArea(com.plotsquared.core.location.Location.at(location.getWorld().getName(), (int) location.getX(), (int) location.getY(), (int) location.getZ())).getPlots().stream().anyMatch(p -> p.isAdded(player.getUniqueId()));
|
||||
}
|
||||
}
|
@ -1,9 +1,17 @@
|
||||
package com.songoda.core.lootables.loot;
|
||||
|
||||
import com.bgsoftware.wildstacker.api.objects.StackedItem;
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.ultimatestacker.UltimateStacker;
|
||||
import com.songoda.ultimatestacker.settings.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.loot.LootTable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -63,12 +71,34 @@ public class DropUtils {
|
||||
}
|
||||
|
||||
private static void dropItems(List<ItemStack> items, EntityDeathEvent event) {
|
||||
if (SongodaCore.isRegistered("UltimateStacker")) {
|
||||
List<StackedItem> stacks = new ArrayList<>();
|
||||
int maxSize = Settings.MAX_STACK_ITEMS.getInt()-64;
|
||||
for (ItemStack item : items) {
|
||||
event.getDrops().add(item);
|
||||
StackedItem stack = stacks.stream().filter(stackedItem -> stackedItem.getItem().getType() == item.getType()).findFirst().orElse(null);
|
||||
if (stack == null) {
|
||||
stacks.add(new StackedItem(item, item.getAmount()));
|
||||
continue;
|
||||
}
|
||||
int newAmount = stack.getAmount() + item.getAmount();
|
||||
while (newAmount > maxSize) {
|
||||
newAmount -= maxSize;
|
||||
stacks.add(new StackedItem(item, maxSize));
|
||||
}
|
||||
stack.setamount(newAmount);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(UltimateStacker.getInstance(), () -> {
|
||||
for (StackedItem stack : stacks) {
|
||||
UltimateStacker.spawnStackedItem(stack.getItem(), stack.getAmount(), event.getEntity().getLocation());
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
event.getDrops().addAll(items);
|
||||
}
|
||||
|
||||
private static void runCommands(LivingEntity entity, List<String> commands) {
|
||||
Bukkit.getScheduler().runTask(SongodaCore.getHijackedPlugin(), () -> {
|
||||
for (String command : commands) {
|
||||
if (entity.getKiller() != null) {
|
||||
command = command.replace("%player%", entity.getKiller().getName());
|
||||
@ -78,5 +108,34 @@ public class DropUtils {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static class StackedItem {
|
||||
|
||||
private final ItemStack item;
|
||||
private int amount;
|
||||
|
||||
public StackedItem(ItemStack item, int amount) {
|
||||
this.item = item;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return item.getType();
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setamount(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,18 +129,24 @@ public class NmsManager {
|
||||
world = new com.songoda.core.nms.v1_18_R2.world.WorldCoreImpl();
|
||||
break;
|
||||
case "v1_19_R1":
|
||||
if (bukkitVersion.endsWith(".0")) {
|
||||
if (bukkitVersion.endsWith(".0") || bukkitVersion.equals("1.19")) {
|
||||
player = new com.songoda.core.nms.v1_19_R1.entity.NMSPlayerImpl();
|
||||
anvil = new com.songoda.core.nms.v1_19_R1.anvil.AnvilCore();
|
||||
nbt = new com.songoda.core.nms.v1_19_R1.nbt.NBTCoreImpl();
|
||||
world = new com.songoda.core.nms.v1_19_R1.world.WorldCoreImpl();
|
||||
}else{
|
||||
} else {
|
||||
player = new com.songoda.core.nms.v1_19_R1v2.entity.NMSPlayerImpl();
|
||||
anvil = new com.songoda.core.nms.v1_19_R1v2.anvil.AnvilCore();
|
||||
nbt = new com.songoda.core.nms.v1_19_R1v2.nbt.NBTCoreImpl();
|
||||
world = new com.songoda.core.nms.v1_19_R1v2.world.WorldCoreImpl();
|
||||
}
|
||||
break;
|
||||
case "v1_19_R2":
|
||||
player = new com.songoda.core.nms.v1_19_R2.entity.NMSPlayerImpl();
|
||||
anvil = new com.songoda.core.nms.v1_19_R2.anvil.AnvilCore();
|
||||
nbt = new com.songoda.core.nms.v1_19_R2.nbt.NBTCoreImpl();
|
||||
world = new com.songoda.core.nms.v1_19_R2.world.WorldCoreImpl();
|
||||
break;
|
||||
default:
|
||||
Logger.getLogger(NmsManager.class.getName()).log(Level.SEVERE, "Failed to load NMS for this server version: version {0} not found", serverPackageVersion);
|
||||
|
||||
|
@ -35,6 +35,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
@ -82,6 +83,7 @@ public class ItemUtils {
|
||||
}
|
||||
|
||||
private static Method methodAsBukkitCopy, methodAsNMSCopy, methodA;
|
||||
private static Object randomInstance;
|
||||
|
||||
static {
|
||||
try {
|
||||
@ -90,17 +92,20 @@ public class ItemUtils {
|
||||
Class<?> clazzCraftItemStack = ClassMapping.CRAFT_ITEM_STACK.getClazz();
|
||||
|
||||
methodAsBukkitCopy = clazzCraftItemStack.getMethod("asBukkitCopy", clazzItemStack);
|
||||
methodAsNMSCopy = clazzCraftItemStack.getMethod("asNMSCopy", ItemStack.class);
|
||||
methodAsNMSCopy = MethodMapping.CB_ITEM_STACK__AS_NMS_COPY.getMethod(clazzCraftItemStack);
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_19)) {
|
||||
Class<?> clazzRandomSource = ClassMapping.RANDOM_SOURCE.getClazz();
|
||||
methodA = clazzEnchantmentManager.getMethod("a", clazzRandomSource.getMethod("c").getReturnType(), clazzItemStack, int.class, boolean.class);
|
||||
}else if (ServerVersion.isServerVersion(ServerVersion.V1_8)) {
|
||||
randomInstance = ClassMapping.SINGLE_THREADED_RANDOM_SOURCE.getClazz().getConstructor(long.class).newInstance(ThreadLocalRandom.current().nextLong());
|
||||
} else if (ServerVersion.isServerVersion(ServerVersion.V1_8)) {
|
||||
methodA = clazzEnchantmentManager.getMethod("a", Random.class, clazzItemStack, int.class);
|
||||
randomInstance = new Random();
|
||||
} else {
|
||||
methodA = clazzEnchantmentManager.getMethod("a", Random.class, clazzItemStack, int.class, boolean.class);
|
||||
randomInstance = new Random();
|
||||
}
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -109,10 +114,12 @@ public class ItemUtils {
|
||||
try {
|
||||
Object nmsItemStack = methodAsNMSCopy.invoke(null, item);
|
||||
|
||||
if (ServerVersion.isServerVersion(ServerVersion.V1_8)) {
|
||||
nmsItemStack = methodA.invoke(null, new Random(), nmsItemStack, level);
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_19)) {
|
||||
nmsItemStack = methodA.invoke(null, randomInstance, nmsItemStack, level, false);
|
||||
} else if (ServerVersion.isServerVersion(ServerVersion.V1_8)) {
|
||||
nmsItemStack = methodA.invoke(null, randomInstance, nmsItemStack, level);
|
||||
} else {
|
||||
nmsItemStack = methodA.invoke(null, new Random(), nmsItemStack, level, false);
|
||||
nmsItemStack = methodA.invoke(null, randomInstance, nmsItemStack, level, false);
|
||||
}
|
||||
|
||||
item = (ItemStack) methodAsBukkitCopy.invoke(null, nmsItemStack);
|
||||
|
116
Core/src/main/java/com/songoda/core/utils/SongodaAuth.java
Normal file
116
Core/src/main/java/com/songoda/core/utils/SongodaAuth.java
Normal file
@ -0,0 +1,116 @@
|
||||
package com.songoda.core.utils;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SongodaAuth {
|
||||
|
||||
public static boolean isAuthorized(boolean allowOffline) {
|
||||
String productId = "%%__PLUGIN__%%";
|
||||
try {
|
||||
Integer.parseInt(productId);
|
||||
} catch (NumberFormatException e) {
|
||||
//Self compiled, return true
|
||||
return true;
|
||||
}
|
||||
UUID uuid = getUUID();
|
||||
try {
|
||||
URL url = new URL("https://marketplace.songoda.com/api/v2/products/license/validate");
|
||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
||||
con.setRequestMethod("POST");
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
con.setRequestProperty("Accept", "application/json");
|
||||
con.setDoOutput(true);
|
||||
String jsonInputString = "{\"product_id\":" + productId + ",\"license\":\"" + uuid + "\",\"user_id\":\"%%__USER__%%\"}";
|
||||
try(OutputStream os = con.getOutputStream()) {
|
||||
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
|
||||
os.write(input, 0, input.length);
|
||||
}
|
||||
|
||||
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
StringBuilder response = new StringBuilder();
|
||||
String responseLine = null;
|
||||
while ((responseLine = br.readLine()) != null) {
|
||||
response.append(responseLine.trim());
|
||||
}
|
||||
JSONObject jsonObject = (JSONObject) new JSONParser().parse(response.toString());
|
||||
if (jsonObject.get("error") != null) {
|
||||
//Got an error, return false and print error
|
||||
Bukkit.getLogger().warning("Error validating license: " + jsonObject.get("error"));
|
||||
return false;
|
||||
} else {
|
||||
return (boolean) jsonObject.get("valid");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return allowOffline;
|
||||
}
|
||||
}
|
||||
|
||||
public static UUID getUUID() {
|
||||
File serverProperties = new File(new File("."),"server.properties");
|
||||
Properties prop = new Properties();
|
||||
try {
|
||||
prop.load(new FileReader(serverProperties));
|
||||
String uuid = prop.getProperty("uuid");
|
||||
if (uuid == null || uuid.isEmpty()) {
|
||||
UUID newUUID = UUID.randomUUID();
|
||||
prop.setProperty("uuid", newUUID.toString());
|
||||
prop.store(new FileWriter(serverProperties), null);
|
||||
return newUUID;
|
||||
} else {
|
||||
return UUID.fromString(uuid);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Could not fetch UUID for server", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getIP() {
|
||||
try {
|
||||
URL url = new URL("https://marketplace.songoda.com/api/v2/products/license/ip");
|
||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("Accept", "application/json");
|
||||
con.setDoOutput(true);
|
||||
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
StringBuilder response = new StringBuilder();
|
||||
String responseLine = null;
|
||||
while ((responseLine = br.readLine()) != null) {
|
||||
response.append(responseLine.trim());
|
||||
}
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject jsonObject = (JSONObject) parser.parse(response.toString());
|
||||
return jsonObject.get("ip").toString();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Could not fetch IP address", ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -18,7 +18,7 @@ public interface WorldCore {
|
||||
|
||||
SWorld getWorld(World world);
|
||||
|
||||
BBaseSpawner getBaseSpawner(CreatureSpawner spawner) throws NoSuchFieldException, IllegalAccessException;
|
||||
BBaseSpawner getBaseSpawner(CreatureSpawner spawner) throws ReflectiveOperationException;
|
||||
|
||||
/**
|
||||
* Performs random ticks on a specific chunks.
|
||||
@ -28,7 +28,7 @@ public interface WorldCore {
|
||||
* @param bukkitChunk The chunk to tick
|
||||
* @param tickAmount The number of blocks to tick per ChunkSection, normally referred to as <code>randomTickSpeed</code>
|
||||
*/
|
||||
void randomTickChunk(Chunk bukkitChunk, int tickAmount) throws NoSuchFieldException, IllegalAccessException;
|
||||
void randomTickChunk(Chunk bukkitChunk, int tickAmount) throws ReflectiveOperationException;
|
||||
|
||||
/**
|
||||
* Ticks all inactive spawners in a specific chunk ignoring the minimum required players within a specific range.<br>
|
||||
@ -37,7 +37,7 @@ public interface WorldCore {
|
||||
* @param chunk The chunk to tick the spawners in
|
||||
* @param amount The amount of ticks to execute for each spawner
|
||||
*/
|
||||
default void tickInactiveSpawners(Chunk chunk, int amount) throws NoSuchFieldException, IllegalAccessException, InvocationTargetException {
|
||||
default void tickInactiveSpawners(Chunk chunk, int amount) throws ReflectiveOperationException {
|
||||
if (amount <= 0) return;
|
||||
|
||||
for (BlockState tileEntity : chunk.getTileEntities()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -21,6 +21,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
((CraftWorld) location.getWorld()).getHandle(),
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -22,6 +22,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
((CraftWorld) location.getWorld()).getHandle(),
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -22,6 +22,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
((CraftWorld) location.getWorld()).getHandle(),
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = Optional.ofNullable(EntityTypes.a(entityType)); // Changed since 1.13.2
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = Optional.ofNullable(EntityTypes.a(entityType)); // Changed since 1.13.2
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = EntityTypes.a(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = EntityTypes.a(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = EntityTypes.a(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = EntityTypes.a(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = EntityTypes.a(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -19,23 +19,31 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<java.release>17</java.release>
|
||||
|
||||
<nms.ver>1.18-R0.1-SNAPSHOT</nms.ver>
|
||||
</properties>
|
||||
|
||||
<artifactId>SongodaCore-NMS-v1_18_R1</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${nms.ver}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.18</version>
|
||||
<version>1.18-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityTypes<?>> optionalEntity = EntityTypes.a(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -60,7 +60,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityType<?>> optionalEntity = EntityType.byString(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -60,7 +60,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityType<?>> optionalEntity = EntityType.byString(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -23,7 +23,7 @@ public class SWorldImpl implements SWorld {
|
||||
List<LivingEntity> result = new ArrayList<>();
|
||||
|
||||
ServerLevel worldServer = ((CraftWorld) world).getHandle();
|
||||
LevelEntityGetter<Entity> entities = worldServer.entityManager.getEntityGetter();
|
||||
LevelEntityGetter<Entity> entities = worldServer.getEntities();
|
||||
|
||||
entities.getAll().forEach((mcEnt) -> {
|
||||
org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity();
|
||||
|
@ -60,7 +60,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityType<?>> optionalEntity = EntityType.byString(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
|
@ -23,7 +23,7 @@ public class SWorldImpl implements SWorld {
|
||||
List<LivingEntity> result = new ArrayList<>();
|
||||
|
||||
ServerLevel worldServer = ((CraftWorld) world).getHandle();
|
||||
LevelEntityGetter<Entity> entities = worldServer.entityManager.getEntityGetter();
|
||||
LevelEntityGetter<Entity> entities = worldServer.getEntities();
|
||||
|
||||
entities.getAll().forEach((mcEnt) -> {
|
||||
org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity();
|
||||
|
105
NMS/NMS-v1_19_R2/pom.xml
Normal file
105
NMS/NMS-v1_19_R2/pom.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
|
||||
<release>${java.release}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>1.2.4</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>remap-obf</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>remap</goal>
|
||||
</goals>
|
||||
|
||||
<configuration>
|
||||
<srgIn>org.spigotmc:minecraft-server:${nms.ver}:txt:maps-mojang</srgIn>
|
||||
<reverse>true</reverse>
|
||||
<remappedDependencies>org.spigotmc:spigot:${nms.ver}:jar:remapped-mojang</remappedDependencies>
|
||||
<remappedArtifactAttached>true</remappedArtifactAttached>
|
||||
<remappedClassifierName>remapped-obf</remappedClassifierName>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>remap-spigot</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>remap</goal>
|
||||
</goals>
|
||||
|
||||
<configuration>
|
||||
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
|
||||
<srgIn>org.spigotmc:minecraft-server:${nms.ver}:csrg:maps-spigot</srgIn>
|
||||
<remappedDependencies>org.spigotmc:spigot:${nms.ver}:jar:remapped-obf</remappedDependencies>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<java.release>17</java.release>
|
||||
|
||||
<nms.ver>1.19.3-R0.1-SNAPSHOT</nms.ver>
|
||||
</properties>
|
||||
|
||||
<artifactId>SongodaCore-NMS-v1_19_R2</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${nms.ver}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>${nms.ver}</version>
|
||||
<scope>provided</scope>
|
||||
<classifier>remapped-mojang</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>SongodaCore-NMS-API</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>SongodaCore-Compatibility</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,21 @@
|
||||
package com.songoda.core.nms.v1_19_R2.anvil;
|
||||
|
||||
import com.songoda.core.nms.anvil.CustomAnvil;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public class AnvilCore implements com.songoda.core.nms.anvil.AnvilCore {
|
||||
@Override
|
||||
public CustomAnvil createAnvil(Player player) {
|
||||
ServerPlayer p = ((CraftPlayer) player).getHandle();
|
||||
return new AnvilView(p.nextContainerCounter(), p, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomAnvil createAnvil(Player player, InventoryHolder holder) {
|
||||
ServerPlayer p = ((CraftPlayer) player).getHandle();
|
||||
return new AnvilView(p.nextContainerCounter(), p, holder);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.songoda.core.nms.v1_19_R2.anvil;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.AnvilMenu;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftInventoryAnvil;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public class AnvilInventoryCustom extends CraftInventoryAnvil {
|
||||
final InventoryHolder holder;
|
||||
|
||||
public AnvilInventoryCustom(InventoryHolder holder, Location location, Container inventory, Container resultInventory, AnvilMenu container) {
|
||||
super(location, inventory, resultInventory, container);
|
||||
|
||||
this.holder = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryHolder getHolder() {
|
||||
return holder;
|
||||
}
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
package com.songoda.core.nms.v1_19_R2.anvil;
|
||||
|
||||
import com.songoda.core.nms.anvil.CustomAnvil;
|
||||
import com.songoda.core.nms.anvil.methods.AnvilTextChange;
|
||||
import net.md_5.bungee.api.chat.TranslatableComponent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.AnvilMenu;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.ItemCombinerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftInventoryView;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class AnvilView extends AnvilMenu implements CustomAnvil {
|
||||
private final ServerPlayer entity;
|
||||
private final Inventory inventory;
|
||||
private String customTitle = "Repairing";
|
||||
private int cost = -1;
|
||||
private boolean canUse = true;
|
||||
private AnvilTextChange textChange;
|
||||
|
||||
// used for setting custom inventory
|
||||
static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result
|
||||
static Field mc_ContainerAnvil_resultInventory; // full inventory
|
||||
static Field mc_ContainerAnvil_bukkitEntity;
|
||||
|
||||
static {
|
||||
try {
|
||||
mc_ContainerAnvil_repairInventory = ItemCombinerMenu.class.getDeclaredField("p");
|
||||
mc_ContainerAnvil_repairInventory.setAccessible(true);
|
||||
|
||||
mc_ContainerAnvil_resultInventory = ItemCombinerMenu.class.getDeclaredField("o");
|
||||
mc_ContainerAnvil_resultInventory.setAccessible(true);
|
||||
|
||||
mc_ContainerAnvil_bukkitEntity = AnvilMenu.class.getDeclaredField("bukkitEntity");
|
||||
mc_ContainerAnvil_bukkitEntity.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Setup Error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// 1.14 also introduced a title field, also private, which can only be set once and can't be checked
|
||||
static Field mc_Container_title;
|
||||
|
||||
static {
|
||||
try {
|
||||
mc_Container_title = AbstractContainerMenu.class.getDeclaredField("title");
|
||||
mc_Container_title.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Setup Error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public AnvilView(int id, ServerPlayer entity, InventoryHolder holder) {
|
||||
super(entity.nextContainerCounter(), entity.getInventory(), ContainerLevelAccess.create(entity.level, new BlockPos(0, 0, 0)));
|
||||
|
||||
this.setTitle(MutableComponent.create(new TranslatableContents(customTitle != null ? customTitle : "")));
|
||||
this.checkReachable = false;
|
||||
this.entity = entity;
|
||||
|
||||
if (holder != null) {
|
||||
this.inventory = getBukkitView(entity, holder).getTopInventory();
|
||||
} else {
|
||||
this.inventory = getBukkitView().getTopInventory();
|
||||
}
|
||||
}
|
||||
|
||||
public CraftInventoryView getBukkitView(Player player, InventoryHolder holder) {
|
||||
try {
|
||||
AnvilInventoryCustom craftInventory = new AnvilInventoryCustom(holder,
|
||||
new Location(entity.level.getWorld(), 0, 0, 0),
|
||||
(Container) mc_ContainerAnvil_repairInventory.get(this),
|
||||
(Container) mc_ContainerAnvil_resultInventory.get(this), this);
|
||||
CraftInventoryView view = new CraftInventoryView(player.getBukkitEntity(), craftInventory, this);
|
||||
mc_ContainerAnvil_bukkitEntity.set(this, view);
|
||||
|
||||
return view;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Setup Error", ex);
|
||||
}
|
||||
|
||||
return getBukkitView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player entityHuman) {
|
||||
return canUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastFullState() {
|
||||
super.broadcastFullState();
|
||||
|
||||
if (cost >= 0) {
|
||||
this.setLevelCost(cost);
|
||||
}
|
||||
|
||||
textChange.onChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
broadcastFullState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenameText() {
|
||||
return this.itemName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenameText(String text) {
|
||||
this.setItemName(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnChange(AnvilTextChange handler) {
|
||||
textChange = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomTitle() {
|
||||
return customTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomTitle(String title) {
|
||||
this.customTitle = title;
|
||||
|
||||
try {
|
||||
mc_Container_title.set(this, MutableComponent.create(new TranslatableContents(customTitle != null ? customTitle : "")));
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLevelCost(int cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevelCost() {
|
||||
if (cost >= 0) {
|
||||
return cost;
|
||||
}
|
||||
|
||||
return this.getLevelCost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCanUse(boolean bool) {
|
||||
this.canUse = bool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getLeftInput() {
|
||||
return inventory.getItem(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRightInput() {
|
||||
return inventory.getItem(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getOutput() {
|
||||
return inventory.getItem(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeftInput(ItemStack item) {
|
||||
inventory.setItem(0, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRightInput(ItemStack item) {
|
||||
inventory.setItem(1, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOutput(ItemStack item) {
|
||||
inventory.setItem(2, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
// Send the packet
|
||||
entity.connection.send(new ClientboundOpenScreenPacket(super.containerId, MenuType.ANVIL, MutableComponent.create(new TranslatableContents(customTitle != null ? customTitle : ""))));
|
||||
|
||||
// Set their active container to this anvil
|
||||
entity.containerMenu = this;
|
||||
|
||||
// Add the slot listener
|
||||
entity.initMenu(entity.containerMenu);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.songoda.core.nms.v1_19_R2.entity;
|
||||
|
||||
import com.songoda.core.nms.entity.NMSPlayer;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class NMSPlayerImpl implements NMSPlayer {
|
||||
@Override
|
||||
public void sendPacket(Player p, Object packet) {
|
||||
((CraftPlayer) p).getHandle().connection.send((Packet<?>) packet);
|
||||
}
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
package com.songoda.core.nms.v1_19_R2.nbt;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTCompound;
|
||||
import com.songoda.core.nms.nbt.NBTObject;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NBTCompoundImpl implements NBTCompound {
|
||||
protected CompoundTag compound;
|
||||
|
||||
protected NBTCompoundImpl(CompoundTag compound) {
|
||||
this.compound = compound;
|
||||
}
|
||||
|
||||
public NBTCompoundImpl() {
|
||||
this.compound = new CompoundTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, String s) {
|
||||
compound.putString(tag, s);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, boolean b) {
|
||||
compound.putBoolean(tag, b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, int i) {
|
||||
compound.putInt(tag, i);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, double i) {
|
||||
compound.putDouble(tag, i);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, long l) {
|
||||
compound.putLong(tag, l);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, short s) {
|
||||
compound.putShort(tag, s);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, byte b) {
|
||||
compound.putByte(tag, b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, int[] i) {
|
||||
compound.putIntArray(tag, i);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, byte[] b) {
|
||||
compound.putByteArray(tag, b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound set(String tag, UUID u) {
|
||||
compound.putUUID(tag, u);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound remove(String tag) {
|
||||
compound.remove(tag);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String tag) {
|
||||
return compound.contains(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTObject getNBTObject(String tag) {
|
||||
return new NBTObjectImpl(compound, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String tag) {
|
||||
return getNBTObject(tag).asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String tag) {
|
||||
return getNBTObject(tag).asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String tag) {
|
||||
return getNBTObject(tag).asInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(String tag) {
|
||||
return getNBTObject(tag).asDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(String tag) {
|
||||
return getNBTObject(tag).asLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(String tag) {
|
||||
return getNBTObject(tag).asShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(String tag) {
|
||||
return getNBTObject(tag).asByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIntArray(String tag) {
|
||||
return getNBTObject(tag).asIntArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray(String tag) {
|
||||
return getNBTObject(tag).asByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound getCompound(String tag) {
|
||||
if (has(tag)) {
|
||||
return getNBTObject(tag).asCompound();
|
||||
}
|
||||
|
||||
CompoundTag newCompound = new CompoundTag();
|
||||
compound.put(tag, newCompound);
|
||||
return new NBTCompoundImpl(newCompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
return compound.getAllKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys(String tag) {
|
||||
return compound.getCompound(tag).getAllKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(String... exclusions) {
|
||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream dataOutput = new ObjectOutputStream(outputStream)) {
|
||||
addExtras();
|
||||
CompoundTag compound = this.compound.copy();
|
||||
|
||||
for (String exclusion : exclusions) {
|
||||
compound.remove(exclusion);
|
||||
}
|
||||
|
||||
NbtIo.writeCompressed(compound, dataOutput);
|
||||
|
||||
return outputStream.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deSerialize(byte[] serialized) {
|
||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(serialized);
|
||||
ObjectInputStream dataInput = new ObjectInputStream(inputStream)) {
|
||||
compound = NbtIo.readCompressed(dataInput);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras() {
|
||||
// None
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return compound.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.songoda.core.nms.v1_19_R2.nbt;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTCore;
|
||||
import com.songoda.core.nms.nbt.NBTEntity;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class NBTCoreImpl implements NBTCore {
|
||||
@Deprecated
|
||||
@Override
|
||||
public NBTItem of(ItemStack item) {
|
||||
return new NBTItemImpl(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public NBTItem newItem() {
|
||||
return new NBTItemImpl(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTEntity of(Entity entity) {
|
||||
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nmsEntity.saveWithoutId(nbt);
|
||||
|
||||
return new NBTEntityImpl(nbt, nmsEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTEntity newEntity() {
|
||||
return new NBTEntityImpl(new CompoundTag(), null);
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.songoda.core.nms.v1_19_R2.nbt;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
private Entity nmsEntity;
|
||||
|
||||
public NBTEntityImpl(CompoundTag entityNBT, Entity nmsEntity) {
|
||||
super(entityNBT);
|
||||
|
||||
this.nmsEntity = nmsEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Optional<EntityType<?>> optionalEntity = EntityType.byString(entityType);
|
||||
if (optionalEntity.isPresent()) {
|
||||
assert location.getWorld() != null;
|
||||
|
||||
Entity spawned = optionalEntity.get().spawn(
|
||||
((CraftWorld) location.getWorld()).getHandle(),
|
||||
compound,
|
||||
null,
|
||||
new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()),
|
||||
MobSpawnType.COMMAND,
|
||||
true,
|
||||
false
|
||||
);
|
||||
|
||||
if (spawned != null) {
|
||||
spawned.load(compound);
|
||||
org.bukkit.entity.Entity entity = spawned.getBukkitEntity();
|
||||
entity.teleport(location);
|
||||
nmsEntity = spawned;
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity reSpawn(Location location) {
|
||||
nmsEntity.discard();
|
||||
return spawn(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras() {
|
||||
compound.putString("entity_type", BuiltInRegistries.ENTITY_TYPE.getKey(nmsEntity.getType()).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.songoda.core.nms.v1_19_R2.nbt;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
||||
|
||||
public class NBTItemImpl extends NBTCompoundImpl implements NBTItem {
|
||||
private final ItemStack nmsItem;
|
||||
|
||||
public NBTItemImpl(ItemStack nmsItem) {
|
||||
super(nmsItem != null && nmsItem.hasTag() ? nmsItem.getTag() : new CompoundTag());
|
||||
|
||||
this.nmsItem = nmsItem;
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.ItemStack finish() {
|
||||
if (nmsItem == null) {
|
||||
return CraftItemStack.asBukkitCopy(ItemStack.of(compound));
|
||||
}
|
||||
|
||||
return CraftItemStack.asBukkitCopy(nmsItem);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.songoda.core.nms.v1_19_R2.nbt;
|
||||
|
||||
import com.songoda.core.nms.nbt.NBTCompound;
|
||||
import com.songoda.core.nms.nbt.NBTObject;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class NBTObjectImpl implements NBTObject {
|
||||
private final CompoundTag compound;
|
||||
private final String tag;
|
||||
|
||||
public NBTObjectImpl(CompoundTag compound, String tag) {
|
||||
this.compound = compound;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return compound.getString(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asBoolean() {
|
||||
return compound.getBoolean(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int asInt() {
|
||||
return compound.getInt(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double asDouble() {
|
||||
return compound.getDouble(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long asLong() {
|
||||
return compound.getLong(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short asShort() {
|
||||
return compound.getShort(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte asByte() {
|
||||
return compound.getByte(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] asIntArray() {
|
||||
return compound.getIntArray(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] asByteArray() {
|
||||
return compound.getByteArray(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTCompound asCompound() {
|
||||
return new NBTCompoundImpl(compound.getCompound(tag));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
return compound.getAllKeys();
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.songoda.core.nms.v1_19_R2.world;
|
||||
|
||||
import com.songoda.core.nms.world.SItemStack;
|
||||
import net.minecraft.core.particles.ItemParticleOption;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class SItemStackImpl implements SItemStack {
|
||||
private final ItemStack item;
|
||||
|
||||
public SItemStackImpl(ItemStack item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakItem(Player player, int amount) {
|
||||
ServerPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
Vec3 vec3d = new Vec3(((double) random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
|
||||
vec3d = vec3d.xRot(-entityPlayer.getXRot() * 0.017453292F);
|
||||
vec3d = vec3d.yRot(-entityPlayer.getYRot() * 0.017453292F);
|
||||
|
||||
double d0 = (double) (-random.nextFloat()) * 0.6D - 0.3D;
|
||||
|
||||
Vec3 vec3d1 = new Vec3(((double) random.nextFloat() - 0.5D) * 0.3D, d0, 0.6D);
|
||||
vec3d1 = vec3d1.xRot(-entityPlayer.getXRot() * 0.017453292F);
|
||||
vec3d1 = vec3d1.yRot(-entityPlayer.getYRot() * 0.017453292F);
|
||||
vec3d1 = vec3d1.add(entityPlayer.getX(), entityPlayer.getEyeY(), entityPlayer.getZ());
|
||||
|
||||
entityPlayer.level.addParticle(new ItemParticleOption(ParticleTypes.ITEM, CraftItemStack.asNMSCopy(item)), vec3d1.x, vec3d1.y, vec3d1.z, vec3d.x, vec3d.y + 0.05D, vec3d.z);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package com.songoda.core.nms.v1_19_R2.world;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.core.nms.world.SSpawner;
|
||||
import com.songoda.core.nms.world.SpawnedEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class SSpawnerImpl implements SSpawner {
|
||||
private final Location spawnerLocation;
|
||||
|
||||
public SSpawnerImpl(Location location) {
|
||||
this.spawnerLocation = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity spawnEntity(EntityType type, Location spawnerLocation) {
|
||||
return spawnEntity(type, "EXPLOSION_NORMAL", null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity spawnEntity(EntityType type, String particleType, SpawnedEntity spawned, Set<CompatibleMaterial> canSpawnOn) {
|
||||
SpawnData data = new SpawnData();
|
||||
CompoundTag compound = data.getEntityToSpawn();
|
||||
|
||||
String name = type.name().toLowerCase().replace("snowman", "snow_golem")
|
||||
.replace("mushroom_cow", "mooshroom");
|
||||
compound.putString("id", "minecraft:" + name);
|
||||
|
||||
short spawnRange = 4;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
assert spawnerLocation.getWorld() != null;
|
||||
ServerLevel world = ((CraftWorld) spawnerLocation.getWorld()).getHandle();
|
||||
|
||||
RandomSource random = world.getRandom();
|
||||
double x = spawnerLocation.getX() + (random.nextDouble() - random.nextDouble()) * (double) spawnRange + 0.5D;
|
||||
double y = spawnerLocation.getY() + random.nextInt(3) - 1;
|
||||
double z = spawnerLocation.getZ() + (random.nextDouble() - random.nextDouble()) * (double) spawnRange + 0.5D;
|
||||
|
||||
Optional<Entity> optionalEntity = net.minecraft.world.entity.EntityType.create(compound, world);
|
||||
if (optionalEntity.isEmpty()) continue;
|
||||
|
||||
Entity entity = optionalEntity.get();
|
||||
entity.setPos(x, y, z);
|
||||
|
||||
BlockPos position = entity.blockPosition();
|
||||
DifficultyInstance damageScaler = world.getCurrentDifficultyAt(position);
|
||||
|
||||
if (!(entity instanceof Mob entityInsentient)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Location spot = new Location(spawnerLocation.getWorld(), x, y, z);
|
||||
|
||||
if (!canSpawn(world, entityInsentient, spot, canSpawnOn)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entityInsentient.finalizeSpawn(world, damageScaler, MobSpawnType.SPAWNER, null, null);
|
||||
|
||||
LivingEntity craftEntity = (LivingEntity) entity.getBukkitEntity();
|
||||
|
||||
if (spawned != null && !spawned.onSpawn(craftEntity)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (particleType != null) {
|
||||
float xx = (float) (0 + (Math.random() * 1));
|
||||
float yy = (float) (0 + (Math.random() * 2));
|
||||
float zz = (float) (0 + (Math.random() * 1));
|
||||
|
||||
CompatibleParticleHandler.spawnParticles(CompatibleParticleHandler.ParticleType.getParticle(particleType), spot, 5, xx, yy, zz, 0);
|
||||
}
|
||||
|
||||
world.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER);
|
||||
|
||||
spot.setYaw(random.nextFloat() * 360.0F);
|
||||
craftEntity.teleport(spot);
|
||||
|
||||
return craftEntity;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean canSpawn(ServerLevel world, Mob entityInsentient, Location location, Set<CompatibleMaterial> canSpawnOn) {
|
||||
if (!world.noCollision(entityInsentient, entityInsentient.getBoundingBox())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CompatibleMaterial spawnedIn = CompatibleMaterial.getMaterial(location.getBlock());
|
||||
CompatibleMaterial spawnedOn = CompatibleMaterial.getMaterial(location.getBlock().getRelative(BlockFace.DOWN));
|
||||
|
||||
if (spawnedIn == null || spawnedOn == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!spawnedIn.isAir() &&
|
||||
spawnedIn != CompatibleMaterial.WATER &&
|
||||
!spawnedIn.name().contains("PRESSURE") &&
|
||||
!spawnedIn.name().contains("SLAB")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (CompatibleMaterial material : canSpawnOn) {
|
||||
if (material == null) continue;
|
||||
|
||||
if (spawnedOn.equals(material) || material.isAir()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.songoda.core.nms.v1_19_R2.world;
|
||||
|
||||
import com.songoda.core.nms.world.SWorld;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SWorldImpl implements SWorld {
|
||||
private final World world;
|
||||
|
||||
public SWorldImpl(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LivingEntity> getLivingEntities() {
|
||||
List<LivingEntity> result = new ArrayList<>();
|
||||
|
||||
ServerLevel worldServer = ((CraftWorld) world).getHandle();
|
||||
LevelEntityGetter<Entity> entities = worldServer.getEntities();
|
||||
|
||||
entities.getAll().forEach((mcEnt) -> {
|
||||
org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity && bukkitEntity.isValid()) {
|
||||
result.add((LivingEntity) bukkitEntity);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.songoda.core.nms.v1_19_R2.world;
|
||||
|
||||
import com.songoda.core.nms.ReflectionUtils;
|
||||
import com.songoda.core.nms.v1_19_R2.world.spawner.BBaseSpawnerImpl;
|
||||
import com.songoda.core.nms.world.BBaseSpawner;
|
||||
import com.songoda.core.nms.world.SItemStack;
|
||||
import com.songoda.core.nms.world.SSpawner;
|
||||
import com.songoda.core.nms.world.SWorld;
|
||||
import com.songoda.core.nms.world.WorldCore;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.BaseSpawner;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.CraftChunk;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class WorldCoreImpl implements WorldCore {
|
||||
@Override
|
||||
public SSpawner getSpawner(CreatureSpawner spawner) {
|
||||
return new SSpawnerImpl(spawner.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSpawner getSpawner(Location location) {
|
||||
return new SSpawnerImpl(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SItemStack getItemStack(ItemStack item) {
|
||||
return new SItemStackImpl(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWorld getWorld(World world) {
|
||||
return new SWorldImpl(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BBaseSpawner getBaseSpawner(CreatureSpawner spawner) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException {
|
||||
Object cTileEntity = ReflectionUtils.getFieldValue(spawner, "tileEntity");
|
||||
|
||||
return new BBaseSpawnerImpl(spawner, (BaseSpawner) ReflectionUtils.getFieldValue(cTileEntity, "a"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method is based on {@link ServerLevel#tickChunk(LevelChunk, int)}.
|
||||
*/
|
||||
@Override
|
||||
public void randomTickChunk(org.bukkit.Chunk bukkitChunk, int tickAmount) {
|
||||
LevelChunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
ServerLevel world = chunk.q;
|
||||
ProfilerFiller gameProfilerFiller = world.getProfiler();
|
||||
|
||||
ChunkPos chunkCoordIntPair = chunk.getPos();
|
||||
int j = chunkCoordIntPair.getMinBlockX();
|
||||
int k = chunkCoordIntPair.getMinBlockZ();
|
||||
|
||||
gameProfilerFiller.popPush("tickBlocks");
|
||||
if (tickAmount > 0) {
|
||||
LevelChunkSection[] aChunkSection = chunk.getSections();
|
||||
|
||||
for (LevelChunkSection chunkSection : aChunkSection) {
|
||||
if (chunkSection.isRandomlyTicking()) {
|
||||
int j1 = chunkSection.bottomBlockY();
|
||||
|
||||
for (int k1 = 0; k1 < tickAmount; ++k1) {
|
||||
BlockPos blockposition2 = world.getBlockRandomPos(j, j1, k, 15);
|
||||
gameProfilerFiller.push("randomTick");
|
||||
BlockState iBlockData1 = chunkSection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k);
|
||||
if (iBlockData1.isRandomlyTicking()) {
|
||||
iBlockData1.randomTick(world, blockposition2, world.random);
|
||||
}
|
||||
|
||||
FluidState fluid = iBlockData1.getFluidState();
|
||||
if (fluid.isRandomlyTicking()) {
|
||||
fluid.randomTick(world, blockposition2, world.random);
|
||||
}
|
||||
|
||||
gameProfilerFiller.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,214 @@
|
||||
package com.songoda.core.nms.v1_19_R2.world.spawner;
|
||||
|
||||
import com.songoda.core.nms.world.BBaseSpawner;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.WeightedEntry;
|
||||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.SpawnPlacements;
|
||||
import net.minecraft.world.level.BaseSpawner;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.block.CraftCreatureSpawner;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BBaseSpawnerImpl implements BBaseSpawner {
|
||||
private final CreatureSpawner bukkitSpawner;
|
||||
private final BaseSpawner spawner;
|
||||
|
||||
private final Method setNextSpawnDataMethod;
|
||||
private final Method getOrCreateNextSpawnDataMethod;
|
||||
|
||||
public BBaseSpawnerImpl(CreatureSpawner bukkitSpawner, BaseSpawner spawner) throws NoSuchMethodException {
|
||||
this.bukkitSpawner = bukkitSpawner;
|
||||
this.spawner = spawner;
|
||||
|
||||
this.setNextSpawnDataMethod = this.spawner.getClass().getDeclaredMethod("a", Level.class, BlockPos.class, SpawnData.class);
|
||||
if (!this.setNextSpawnDataMethod.canAccess(this.spawner)) {
|
||||
this.setNextSpawnDataMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
this.getOrCreateNextSpawnDataMethod = this.spawner.getClass().getSuperclass().getDeclaredMethod("b", Level.class, RandomSource.class, BlockPos.class);
|
||||
if (!this.getOrCreateNextSpawnDataMethod.canAccess(this.spawner)) {
|
||||
this.getOrCreateNextSpawnDataMethod.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is based on {@link BaseSpawner#isNearPlayer(Level, BlockPos)}.
|
||||
*/
|
||||
@SuppressWarnings("JavadocReference")
|
||||
@Override
|
||||
public boolean isNearPlayer() {
|
||||
BlockPos bPos = getBlockPosition();
|
||||
return getWorld().hasNearbyAlivePlayer(
|
||||
(double) bPos.getX() + 0.5,
|
||||
(double) bPos.getY() + 0.5,
|
||||
(double) bPos.getZ() + 0.5,
|
||||
this.spawner.requiredPlayerRange
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is based on {@link BaseSpawner#serverTick(ServerLevel, BlockPos)}.
|
||||
*/
|
||||
@Override
|
||||
public void tick() throws InvocationTargetException, IllegalAccessException {
|
||||
ServerLevel world = getWorld();
|
||||
BlockPos bPos = getBlockPosition();
|
||||
|
||||
if (this.spawner.spawnDelay == -1) {
|
||||
this.delay(world, bPos);
|
||||
}
|
||||
|
||||
if (this.spawner.spawnDelay > 0) {
|
||||
--this.spawner.spawnDelay;
|
||||
} else {
|
||||
boolean flag = false;
|
||||
RandomSource randomsource = world.getRandom();
|
||||
SpawnData mobspawnerdata = (SpawnData) this.getOrCreateNextSpawnDataMethod.invoke(this.spawner, world, randomsource, bPos);
|
||||
int i = 0;
|
||||
|
||||
while (true) {
|
||||
if (i >= this.spawner.spawnCount) {
|
||||
if (flag) {
|
||||
this.delay(world, bPos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
CompoundTag nbttagcompound = mobspawnerdata.getEntityToSpawn();
|
||||
Optional<EntityType<?>> optional = EntityType.by(nbttagcompound);
|
||||
if (optional.isEmpty()) {
|
||||
this.delay(world, bPos);
|
||||
return;
|
||||
}
|
||||
|
||||
ListTag nbttaglist = nbttagcompound.getList("Pos", 6);
|
||||
int j = nbttaglist.size();
|
||||
double d0 = j >= 1 ? nbttaglist.getDouble(0) : (double) bPos.getX() + (randomsource.nextDouble() - randomsource.nextDouble()) * (double) this.spawner.spawnRange + 0.5;
|
||||
double d1 = j >= 2 ? nbttaglist.getDouble(1) : (double) (bPos.getY() + randomsource.nextInt(3) - 1);
|
||||
double d2 = j >= 3 ? nbttaglist.getDouble(2) : (double) bPos.getZ() + (randomsource.nextDouble() - randomsource.nextDouble()) * (double) this.spawner.spawnRange + 0.5;
|
||||
if (world.noCollision(optional.get().getAABB(d0, d1, d2))) {
|
||||
label128:
|
||||
{
|
||||
BlockPos blockposition1 = new BlockPos(d0, d1, d2);
|
||||
if (mobspawnerdata.getCustomSpawnRules().isPresent()) {
|
||||
if (!optional.get().getCategory().isFriendly() && world.getDifficulty() == Difficulty.PEACEFUL) {
|
||||
break label128;
|
||||
}
|
||||
|
||||
SpawnData.CustomSpawnRules mobspawnerdata_a = mobspawnerdata.getCustomSpawnRules().get();
|
||||
if (!mobspawnerdata_a.blockLightLimit().isValueInRange(world.getBrightness(LightLayer.BLOCK, blockposition1)) || !mobspawnerdata_a.skyLightLimit().isValueInRange(world.getBrightness(LightLayer.SKY, blockposition1))) {
|
||||
break label128;
|
||||
}
|
||||
} else if (!SpawnPlacements.checkSpawnRules(optional.get(), world, MobSpawnType.SPAWNER, blockposition1, world.getRandom())) {
|
||||
break label128;
|
||||
}
|
||||
|
||||
Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> {
|
||||
entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot());
|
||||
return entity1;
|
||||
});
|
||||
if (entity == null) {
|
||||
this.delay(world, bPos);
|
||||
return;
|
||||
}
|
||||
|
||||
int k = world.getEntitiesOfClass(entity.getClass(), (new AABB(bPos.getX(), bPos.getY(), bPos.getZ(), bPos.getX() + 1, bPos.getY() + 1, bPos.getZ() + 1)).inflate(this.spawner.spawnRange)).size();
|
||||
if (k >= this.spawner.maxNearbyEntities) {
|
||||
this.delay(world, bPos);
|
||||
return;
|
||||
}
|
||||
|
||||
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), randomsource.nextFloat() * 360.0F, 0.0F);
|
||||
if (entity instanceof Mob entityinsentient) {
|
||||
if (mobspawnerdata.getCustomSpawnRules().isEmpty() && !entityinsentient.checkSpawnRules(world, MobSpawnType.SPAWNER) || !entityinsentient.checkSpawnObstruction(world)) {
|
||||
break label128;
|
||||
}
|
||||
|
||||
if (mobspawnerdata.getEntityToSpawn().size() == 1 && mobspawnerdata.getEntityToSpawn().contains("id", 8)) {
|
||||
((Mob) entity).finalizeSpawn(world, world.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null, null);
|
||||
}
|
||||
|
||||
if (entityinsentient.level.spigotConfig.nerfSpawnerMobs) {
|
||||
entityinsentient.aware = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (CraftEventFactory.callSpawnerSpawnEvent(entity, bPos).isCancelled()) {
|
||||
Entity vehicle = entity.getVehicle();
|
||||
if (vehicle != null) {
|
||||
vehicle.discard();
|
||||
}
|
||||
|
||||
for (Entity passenger : entity.getIndirectPassengers()) {
|
||||
passenger.discard();
|
||||
}
|
||||
} else {
|
||||
if (!world.tryAddFreshEntityWithPassengers(entity, CreatureSpawnEvent.SpawnReason.SPAWNER)) {
|
||||
this.delay(world, bPos);
|
||||
return;
|
||||
}
|
||||
|
||||
world.levelEvent(2004, bPos, 0);
|
||||
world.gameEvent(entity, GameEvent.ENTITY_PLACE, blockposition1);
|
||||
if (entity instanceof Mob) {
|
||||
((Mob) entity).spawnAnim();
|
||||
}
|
||||
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is based on {@link BaseSpawner#delay(Level, BlockPos)}.
|
||||
*/
|
||||
@SuppressWarnings("JavadocReference")
|
||||
private void delay(ServerLevel world, BlockPos bPos) throws InvocationTargetException, IllegalAccessException {
|
||||
RandomSource randomsource = world.random;
|
||||
if (this.spawner.maxSpawnDelay <= this.spawner.minSpawnDelay) {
|
||||
this.spawner.spawnDelay = this.spawner.minSpawnDelay;
|
||||
} else {
|
||||
this.spawner.spawnDelay = this.spawner.minSpawnDelay + randomsource.nextInt(this.spawner.maxSpawnDelay - this.spawner.minSpawnDelay);
|
||||
}
|
||||
|
||||
Optional<WeightedEntry.Wrapper<SpawnData>> weightedEntry = this.spawner.spawnPotentials.getRandom(randomsource);
|
||||
if (weightedEntry.isPresent()) {
|
||||
this.setNextSpawnDataMethod.invoke(this.spawner, world, bPos, weightedEntry.get().getData());
|
||||
}
|
||||
|
||||
this.spawner.broadcastEvent(world, bPos, 1);
|
||||
}
|
||||
|
||||
private ServerLevel getWorld() {
|
||||
return ((CraftWorld) this.bukkitSpawner.getWorld()).getHandle();
|
||||
}
|
||||
|
||||
private BlockPos getBlockPosition() {
|
||||
return ((CraftCreatureSpawner) this.bukkitSpawner).getPosition();
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -35,6 +35,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
try {
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -35,6 +35,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
try {
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -36,6 +36,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
try {
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -21,6 +21,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
((CraftWorld) location.getWorld()).getHandle(),
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -21,6 +21,7 @@ public class NBTEntityImpl extends NBTCompoundImpl implements NBTEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity spawn(Location location) {
|
||||
String entityType = getNBTObject("entity_type").asString();
|
||||
getKeys().remove("UUID");
|
||||
|
||||
Entity spawned = ItemMonsterEgg.spawnCreature( // Changed since 1.14
|
||||
((CraftWorld) location.getWorld()).getHandle(),
|
||||
|
13
pom.xml
13
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.6.16</version>
|
||||
<version>2.6.18</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<!-- Run 'mvn versions:set -DgenerateBackupPoms=false -DnewVersion=X.Y.Z' to update version recursively -->
|
||||
@ -48,6 +48,7 @@
|
||||
<module>NMS/NMS-v1_18_R2</module>
|
||||
<module>NMS/NMS-v1_19_R1</module>
|
||||
<module>NMS/NMS-v1_19_R1v2</module>
|
||||
<module>NMS/NMS-v1_19_R2</module>
|
||||
</modules>
|
||||
|
||||
<issueManagement>
|
||||
@ -142,6 +143,16 @@
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>enginehub-repo</id>
|
||||
<url>https://maven.enginehub.org/repo/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
|
Loading…
Reference in New Issue
Block a user