diff --git a/.github/workflows/java21-buld-test.yaml b/.github/workflows/java21-buld-test.yaml new file mode 100644 index 00000000..0b4cf6f3 --- /dev/null +++ b/.github/workflows/java21-buld-test.yaml @@ -0,0 +1,39 @@ +name: Java-Compatibility +on: + pull_request: + types: + - opened + - synchronize + - reopened + push: + branches: + - master + - main + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + # Java 8 is tested as a part of the build-and-test workflow + java-version: ['17', '21' ] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Java ${{ matrix.java-version }} + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java-version }} + distribution: temurin + java-package: jdk + + - name: Set up Maven + uses: stCarolas/setup-maven@v4.5 + with: + maven-version: 3.9.1 + + - name: Build application + shell: bash + run: | + mvn clean install diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..e6deea27 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,97 @@ +name: Release Workflow + +on: + push: + branches: + - main + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + # Step 1: Checkout the repository + - name: Checkout + uses: actions/checkout@v4 + + # Step 2: Set up JDK 1.8 + - name: Set up JDK 1.8 + uses: actions/setup-java@v2 + with: + distribution: 'temurin' + java-version: 8 + + # Step 3: Get the version from pom.xml + - name: Get the version from pom.xml + id: get_version + run: echo "PROJECT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV + + # Step 4: Fail if snapshot version + - name: Fail if snapshot version + run: | + if [[ $PROJECT_VERSION == *"-SNAPSHOT"* ]]; then + echo "Snapshot versions are not releasable" + exit 0 + fi + + # Step 5: Generate custom release version + - name: Generate Release Version + id: release_version + run: | + DATE=$(date +'%y%m%d-%H%M') + SHA=$(echo $GITHUB_SHA | cut -c1-7) + RELEASE_VERSION="${PROJECT_VERSION}-${DATE}-${SHA}" + echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV + + # Step 6: Create version.properties file + - name: Create version.properties file + run: | + mkdir -p src/main/resources + + # Application Information + APP_NAME=$(mvn help:evaluate -Dexpression=project.name -q -DforceStdout) + + # Core Metadata + echo "version=${{ env.RELEASE_VERSION }}" >> src/main/resources/version.properties + echo "build_timestamp=$(date --utc +'%Y-%m-%dT%H:%M:%SZ')" >> src/main/resources/version.properties + echo "git_branch=${{ github.ref_name }}" >> src/main/resources/version.properties + echo "git_commit=${GITHUB_SHA}" >> src/main/resources/version.properties + + echo "app_name=${APP_NAME}" >> src/main/resources/version.properties + echo "release_version=${{ env.RELEASE_VERSION }}" >> src/main/resources/version.properties + echo "maven_version=${{ env.PROJECT_VERSION }}" >> src/main/resources/version.properties + + # Build Type + if [[ "${{ github.ref }}" == "refs/heads/master" || "${{ github.ref }}" == "refs/heads/main" ]]; then + BUILD_TYPE="production" + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + BUILD_TYPE="pull_request" + else + BUILD_TYPE="development" + fi + echo "build_type=${BUILD_TYPE}" >> src/main/resources/version.properties + + # CI/CD Metadata + echo "workflow_name=${{ github.workflow }}" >> src/main/resources/version.properties + echo "workflow_run_id=${{ github.run_id }}" >> src/main/resources/version.properties + echo "workflow_run_number=${{ github.run_number }}" >> src/main/resources/version.properties + + # Team or Author Information + echo "build_author=${{ github.actor }}" >> src/main/resources/version.properties + + # Step 7: Build with Maven + - name: Build with Maven + run: mvn clean package + + # Step 8: Create GitHub Release + - name: Create GitHub Release + if: ${{ !endsWith(env.PROJECT_VERSION, '-SNAPSHOT') }} + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ env.RELEASE_VERSION }} + name: ${{ env.RELEASE_VERSION }} + files: | + target/*.jar + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index ae04f905..2fa467c1 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ You can download the latest GitHub release [here](https://github.com/Moresteck/P You can download the latest build through [GitHub actions](https://github.com/Moresteck/Project-Poseidon-Uberbukkit/actions/workflows/build-and-test.yaml) (You need to be logged in on GitHub)
or get it from [betacraft.uk](https://betacraft.uk/utilities) along with **pre-made configuration files**. +Please note, download the artifact (JAR) without `original` in the name, eg. `uberbukkit-2.0.2.jar`. + ## Licensing CraftBukkit and Bukkit are licensed under GNU General Public License v3.0
Any future commits to this repository will remain under the same GNU General Public License v3.0
diff --git a/pom.xml b/pom.xml index 7a42f0d3..4f6ad043 100644 --- a/pom.xml +++ b/pom.xml @@ -112,7 +112,7 @@ org.yaml snakeyaml - 1.7 + 2.0 jar provided @@ -133,7 +133,7 @@ com.google.guava guava - 30.1.1-jre + 32.0.0-jre jar compile @@ -153,15 +153,15 @@ clean install - - - - - - - - - + + + + + + + + + org.apache.maven.plugins diff --git a/src/main/java/com/legacyminecraft/poseidon/Poseidon.java b/src/main/java/com/legacyminecraft/poseidon/Poseidon.java index 2b116dd6..5887a8cb 100644 --- a/src/main/java/com/legacyminecraft/poseidon/Poseidon.java +++ b/src/main/java/com/legacyminecraft/poseidon/Poseidon.java @@ -1,11 +1,13 @@ package com.legacyminecraft.poseidon; import org.bukkit.Bukkit; +import org.bukkit.Server; import org.bukkit.craftbukkit.CraftServer; import java.util.LinkedList; -public class Poseidon { +public final class Poseidon { + private static PoseidonServer server; /** * Returns a list of the server's TPS (Ticks Per Second) records for performance monitoring. @@ -17,5 +19,17 @@ public static LinkedList getTpsRecords() { return ((CraftServer) Bukkit.getServer()).getServer().getTpsRecords(); } + public static PoseidonServer getServer() { + return server; + } + + public static void setServer(PoseidonServer server) { + if (Poseidon.server != null) { + throw new UnsupportedOperationException("Cannot redefine singleton Server"); + } + + Poseidon.server = server; + } + } diff --git a/src/main/java/com/legacyminecraft/poseidon/PoseidonConfig.java b/src/main/java/com/legacyminecraft/poseidon/PoseidonConfig.java index 48ace929..c37abc72 100644 --- a/src/main/java/com/legacyminecraft/poseidon/PoseidonConfig.java +++ b/src/main/java/com/legacyminecraft/poseidon/PoseidonConfig.java @@ -134,6 +134,12 @@ private void write() { generateConfigOption("world.settings.block-tree-growth.info", "This setting allows for server owners to easily block trees growing from automatically destroying certain blocks. The list must be a string with numerical item ids separated by commas."); generateConfigOption("world.settings.block-pistons-pushing-furnaces.info", "This workaround prevents pistons from pushing furnaces which prevents a malicious server crash."); generateConfigOption("world.settings.block-pistons-pushing-furnaces.enabled", true); + generateConfigOption("world.settings.pistons.transmutation-fix.enabled", true); + generateConfigOption("world.settings.pistons.transmutation-fix.info", "This setting fixes block transmutation exploits."); + generateConfigOption("world.settings.pistons.sand-gravel-duping-fix.enabled", true); + generateConfigOption("world.settings.pistons.sand-gravel-duping-fix.info", "This setting fixes sand/gravel duplication exploits."); + generateConfigOption("world.settings.pistons.other-fixes.enabled", true); + generateConfigOption("world.settings.pistons.other-fixes.info", "This setting fixes various other piston exploits like creating illegal pistons, breaking bedrock and duplicating redstone torches."); generateConfigOption("world.settings.skeleton-shooting-sound-fix.info", "This setting fixes the sound of skeletons and players shooting not playing on clients."); generateConfigOption("world.settings.skeleton-shooting-sound-fix.enabled", true); generateConfigOption("world.settings.speed-hack-check.enable", true); @@ -172,6 +178,11 @@ private void write() { generateConfigOption("emergency.debug.regenerate-corrupt-chunks.enable", false); generateConfigOption("emergency.debug.regenerate-corrupt-chunks.info", "This setting allows you to automatically regenerate corrupt chunks. This is useful after a ungraceful shutdown while a file is being written to or out of memory exception."); + generateConfigOption("settings.update-checker.enabled", true); + generateConfigOption("settings.update-checker.info", "This setting allows you to disable the update checker. This is useful if you have a custom build of Poseidon or don't want to be notified of updates."); + generateConfigOption("settings.update-checker.notify-staff.enabled", true); + generateConfigOption("settings.update-checker.notify-staff.info", "This setting notifies operators and players with the permission poseidon.update when a new version of Poseidon is available on join."); + //Messages generateConfigOption("message.kick.banned", "You are banned from this server!"); generateConfigOption("message.kick.ip-banned", "Your IP address is banned from this server!"); @@ -181,6 +192,7 @@ private void write() { generateConfigOption("message.kick.already-online", "\u00A7cA player with your username or uuid is already online, try reconnecting in a minute."); generateConfigOption("message.player.join", "\u00A7e%player% joined the game."); generateConfigOption("message.player.leave", "\u00A7e%player% left the game."); + generateConfigOption("message.update.available", "\u00A7dA newer version of Poseidon is available: %newversion%"); //Optional Poseidon Commands generateConfigOption("command.info", "This section allows you to enable or disable optional Poseidon commands. This is useful if you have a plugin that conflicts with a Poseidon command."); diff --git a/src/main/java/com/legacyminecraft/poseidon/PoseidonServer.java b/src/main/java/com/legacyminecraft/poseidon/PoseidonServer.java new file mode 100644 index 00000000..c3a85285 --- /dev/null +++ b/src/main/java/com/legacyminecraft/poseidon/PoseidonServer.java @@ -0,0 +1,200 @@ +package com.legacyminecraft.poseidon; + +import com.legacyminecraft.poseidon.utility.PoseidonVersionChecker; +import com.legacyminecraft.poseidon.watchdog.WatchDogThread; +import com.projectposeidon.johnymuffin.UUIDManager; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.NetServerHandler; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.CraftServer; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.logging.Logger; + +public final class PoseidonServer { + private final MinecraftServer server; + private final CraftServer craftServer; + + private final List hiddenCommands = new ArrayList<>(); + private final Properties versionProperties = new Properties(); + + private boolean serverInitialized = false; + + private PoseidonVersionChecker poseidonVersionChecker; + private WatchDogThread watchDogThread; + + public PoseidonServer(MinecraftServer server, CraftServer craftServer) { + this.server = server; + this.craftServer = craftServer; + + loadVersionProperties(); + + addHiddenCommands(Arrays.asList("login", "l", "register", "reg", "unregister", "changepassword", "changepw")); + } + + private void loadVersionProperties() { + try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("version.properties")) { + if (inputStream != null) { + versionProperties.load(inputStream); + } + } catch (IOException e) { + getLogger().warning("Failed to load version.properties: " + e.getMessage()); + } + } + + public void initializeServer() { + if (serverInitialized) { + throw new UnsupportedOperationException("Server already initialized"); + } + + getLogger().info("[Poseidon] Starting Project Poseidon Modules!"); + + PoseidonConfig.getInstance(); + UUIDManager.getInstance(); + + initializeUpdateChecker(); + + //Start Watchdog + watchDogThread = new WatchDogThread(Thread.currentThread()); + if (PoseidonConfig.getInstance().getBoolean("settings.enable-watchdog", true)) { + getLogger().info("[Poseidon] Starting Watchdog to detect any server hangs!"); + watchDogThread.start(); + watchDogThread.tickUpdate(); + } + + serverInitialized = true; + getLogger().info("[Poseidon] Finished loading Project Poseidon Modules!"); + } + + private void initializeUpdateChecker() { + if (!PoseidonConfig.getInstance().getConfigBoolean("settings.update-checker.enabled", true)) { + getLogger().info("[Poseidon] Version checker disabled. The server will not check for updates."); + return; + } + + String releaseVersion = getReleaseVersion(); + + if (releaseVersion == null) { + getLogger().warning("[Poseidon] Version checker is disabled as no version.properties file was found."); + return; + } + + if(!getBuildType().equalsIgnoreCase("production")) { + getLogger().warning("[Poseidon] Version checker is disabled as this is a " + getBuildType() + " build. The updater will only check for updates on production builds."); + return; + } + + poseidonVersionChecker = new PoseidonVersionChecker(craftServer, releaseVersion); + + getLogger().info("[Poseidon] Version checker enabled. The server will check for updates every hour."); + // Run the version checker in a separate thread every hour + Bukkit.getScheduler().scheduleSyncRepeatingTask(new PoseidonPlugin(), new Runnable() { + @Override + public void run() { + poseidonVersionChecker.fetchLatestVersion(); + } + }, 0, 20 * 60 * 60); + } + + public void shutdownServer() { + if (!serverInitialized) { + throw new UnsupportedOperationException("Server not initialized"); + } + + getLogger().info("[Poseidon] Stopping Project Poseidon Modules!"); + + UUIDManager.getInstance().saveJsonArray(); + + if (watchDogThread != null) { + getLogger().info("[Poseidon] Stopping Watchdog!"); + watchDogThread.interrupt(); + } + + serverInitialized = false; + getLogger().info("[Poseidon] Finished unloading Project Poseidon Modules!"); + } + + public Logger getLogger() { + return MinecraftServer.log; + } + + public String getAppName() { + return versionProperties.getProperty("app_name", "Unknown"); + } + + public String getReleaseVersion() { + return versionProperties.getProperty("release_version", "Unknown"); + } + + public String getMavenVersion() { + return versionProperties.getProperty("maven_version", "Unknown"); + } + + public String getBuildTimestamp() { + return versionProperties.getProperty("build_timestamp", "Unknown"); + } + + public String getGitCommit() { + return versionProperties.getProperty("git_commit", "Unknown"); + } + + public String getBuildType() { + return versionProperties.getProperty("build_type", "Unknown"); + } + + public boolean isUpdateAvailable() { + return poseidonVersionChecker != null && poseidonVersionChecker.isUpdateAvailable(); + } + + public String getNewestVersion() { + return poseidonVersionChecker == null ? "Unknown" : poseidonVersionChecker.getLatestVersion(); + } + + public WatchDogThread getWatchDogThread() { + return watchDogThread; + } + + /** + * Returns the current hide state of the command from param (Hide from console) + * + * @param cmdName Command name + * @return True if the command from param is hidden and false otherwise + */ + public boolean isCommandHidden(String cmdName) { + return hiddenCommands.contains(cmdName.toLowerCase()); + } + + + /** + * Hides the command from param from being logged to server console + * + * @param cmd Command name + */ + public void addHiddenCommand(String cmd) { + cmd = cmd.toLowerCase(); + + if (hiddenCommands.contains(cmd)) { + Logger.getLogger(NetServerHandler.class.getName()).warning("List of Hidden commands already contains " + cmd); + return; + } + + hiddenCommands.add(cmd); + } + + /** + * Hides the commands from param from being logged to server console + * + * @param commands List of command names + */ + public void addHiddenCommands(List commands) { + for (String cmd : commands) { + addHiddenCommand(cmd); + } + } + +} diff --git a/src/main/java/org/bukkit/command/defaults/PoseidonCommand.java b/src/main/java/com/legacyminecraft/poseidon/commands/PoseidonCommand.java similarity index 53% rename from src/main/java/org/bukkit/command/defaults/PoseidonCommand.java rename to src/main/java/com/legacyminecraft/poseidon/commands/PoseidonCommand.java index 1ebdc383..056d2ff9 100644 --- a/src/main/java/org/bukkit/command/defaults/PoseidonCommand.java +++ b/src/main/java/com/legacyminecraft/poseidon/commands/PoseidonCommand.java @@ -1,5 +1,6 @@ -package org.bukkit.command.defaults; +package com.legacyminecraft.poseidon.commands; +import com.legacyminecraft.poseidon.Poseidon; import com.projectposeidon.api.PoseidonUUID; import com.projectposeidon.api.UUIDType; import org.bukkit.Bukkit; @@ -7,14 +8,19 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; +import java.util.Properties; import java.util.UUID; public class PoseidonCommand extends Command { + private final Properties versionProperties = new Properties(); + public PoseidonCommand(String name) { super(name); - this.description = "Show data regarding the servers version of Project Poseidon"; + this.description = "Show data regarding the server's version of Project Poseidon"; this.usageMessage = "/poseidon"; this.setAliases(Arrays.asList("projectposeidon")); } @@ -22,7 +28,34 @@ public PoseidonCommand(String name) { @Override public boolean execute(CommandSender sender, String currentAlias, String[] args) { if (args.length == 0) { - sender.sendMessage(ChatColor.GRAY + "This server is running " + ChatColor.AQUA + "Project Poseidon" + ChatColor.GRAY + " Version: " + ChatColor.RED + Bukkit.getServer().getPoseidonVersion()); + String appName = Poseidon.getServer().getAppName(); + String releaseVersion = Poseidon.getServer().getReleaseVersion(); + String mavenVersion = Poseidon.getServer().getMavenVersion(); + String buildTimestamp = Poseidon.getServer().getBuildTimestamp(); + String gitCommit = Poseidon.getServer().getGitCommit(); + String buildType = Poseidon.getServer().getBuildType(); + + // Shorten the git commit hash to 7 characters + if (gitCommit.length() > 7) { + gitCommit = gitCommit.substring(0, 7); + } + + if ("Unknown".equals(releaseVersion)) { + sender.sendMessage(ChatColor.RED + "Warning: version.properties not found. This is a local or unconfigured build."); + } else { + sender.sendMessage(ChatColor.GRAY + "This server is running " + ChatColor.AQUA + appName + ChatColor.GRAY + ":"); + sender.sendMessage(ChatColor.GRAY + " - Version: " + ChatColor.YELLOW + releaseVersion); + sender.sendMessage(ChatColor.GRAY + " - Built at: " + ChatColor.YELLOW + buildTimestamp); + sender.sendMessage(ChatColor.GRAY + " - Git SHA: " + ChatColor.YELLOW + gitCommit); + + if ("production".equalsIgnoreCase(buildType)) { + sender.sendMessage(ChatColor.GREEN + "This is a release build."); + } else if ("pull_request".equalsIgnoreCase(buildType)) { + sender.sendMessage(ChatColor.BLUE + "This is a pull request build."); + } else { + sender.sendMessage(ChatColor.GRAY + "This is a development build."); + } + } } else if (args.length == 1) { if (args[0].equalsIgnoreCase("uuid")) { sender.sendMessage(ChatColor.GRAY + "Please specify a user /poseidon uuid (username)"); diff --git a/src/main/java/com/legacyminecraft/poseidon/utility/PoseidonVersionChecker.java b/src/main/java/com/legacyminecraft/poseidon/utility/PoseidonVersionChecker.java new file mode 100644 index 00000000..da39fbeb --- /dev/null +++ b/src/main/java/com/legacyminecraft/poseidon/utility/PoseidonVersionChecker.java @@ -0,0 +1,94 @@ +package com.legacyminecraft.poseidon.utility; + +import org.bukkit.craftbukkit.CraftServer; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; + +public class PoseidonVersionChecker { + + private static final String GITHUB_API_URL = "https://api.github.com/repos/retromcorg/Project-Poseidon/releases/latest"; + private static final String releaseUrl = "https://github.com/retromcorg/Project-Poseidon/releases"; + private final String currentVersion; + private volatile String latestVersion; + private CraftServer server; + + public PoseidonVersionChecker(CraftServer server, String currentVersion) { + this.currentVersion = currentVersion; + this.latestVersion = currentVersion; // Assume the latest version is the current version until checked + this.server = server; + } + + /** + * Checks if a new version is available. + * + * @return true if a newer version is available, false otherwise. + */ + public synchronized boolean isUpdateAvailable() { + return latestVersion != null && !currentVersion.equalsIgnoreCase(latestVersion); + } + + /** + * Fetches the latest release version from GitHub API. + * + * @return the latest version as a String or null if fetching fails. + */ + public void fetchLatestVersion() { + HttpURLConnection connection = null; + try { + URL url = new URL(GITHUB_API_URL); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Accept", "application/json"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + int responseCode = connection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + server.getLogger().log(Level.WARNING, "[Poseidon] Failed to check GitHub for latest version. HTTP Response Code: " + responseCode); + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder response = new StringBuilder(); + String line; + + while ((line = reader.readLine()) != null) { + response.append(line); + } + reader.close(); + + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(response.toString()); + + this.latestVersion = (String) json.get("tag_name"); + + if (isUpdateAvailable()) { + server.getLogger().log(Level.INFO, "[Poseidon] A new version is available: " + latestVersion); + server.getLogger().log(Level.INFO, "[Poseidon] You are currently running version: " + currentVersion); + server.getLogger().log(Level.INFO, "[Poseidon] Download the latest version here: " + releaseUrl); + } else { + server.getLogger().log(Level.INFO, "[Poseidon] You are running the latest version (" + currentVersion + ") of Project Poseidon."); + } + } catch (Exception e) { + server.getLogger().log(Level.WARNING, "[Poseidon] Failed to check GitHub for latest version.", e); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } + + public String getCurrentVersion() { + return currentVersion; + } + + public String getLatestVersion() { + return latestVersion; + } +} diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java index 37a55ecb..c5aa8185 100644 --- a/src/main/java/net/minecraft/server/BlockPiston.java +++ b/src/main/java/net/minecraft/server/BlockPiston.java @@ -340,7 +340,11 @@ private boolean i(World world, int i, int j, int k, int l) { } Block.byId[i2].g(world, i1, j1, k1, world.getData(i1, j1, k1)); - world.setTypeId(i1, j1, k1, 0); + if (PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.other-fixes.enabled", true)) { + world.setRawTypeId(i1, j1, k1, 0); + } else { + world.setTypeId(i1, j1, k1, 0); + } } } diff --git a/src/main/java/net/minecraft/server/BlockPistonExtension.java b/src/main/java/net/minecraft/server/BlockPistonExtension.java index ba89906f..fa50f2cc 100644 --- a/src/main/java/net/minecraft/server/BlockPistonExtension.java +++ b/src/main/java/net/minecraft/server/BlockPistonExtension.java @@ -16,7 +16,7 @@ public BlockPistonExtension(int i, int j) { public void remove(World world, int i, int j, int k) { super.remove(world, i, j, k); int l = world.getData(i, j, k); - if (l > 5 || l < 0) return; // CraftBukkit - fixed a piston AIOOBE issue. + if (l < 0 || l == 6 || l == 7 || l > 13) return; // CraftBukkit - fixed a piston AIOOBE issue. int i1 = PistonBlockTextures.a[b(l)]; i += PistonBlockTextures.b[i1]; diff --git a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java index ce9cff2f..fa06134a 100644 --- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java +++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.PoseidonConfig; import org.bukkit.event.block.BlockRedstoneEvent; import java.util.ArrayList; @@ -62,7 +63,7 @@ public void c(World world, int i, int j, int k) { } public void remove(World world, int i, int j, int k) { - if (this.isOn) { + if (this.isOn && (!PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.transmutation-fix.enabled", true) || world.getTypeId(i, j, k) == this.id || world.getTypeId(i, j, k) == 75)) { world.applyPhysics(i, j - 1, k, this.id); world.applyPhysics(i, j + 1, k, this.id); world.applyPhysics(i - 1, j, k, this.id); diff --git a/src/main/java/net/minecraft/server/BlockSand.java b/src/main/java/net/minecraft/server/BlockSand.java index 90abdf2b..d6532289 100644 --- a/src/main/java/net/minecraft/server/BlockSand.java +++ b/src/main/java/net/minecraft/server/BlockSand.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.PoseidonConfig; + import java.util.Random; public class BlockSand extends Block { @@ -27,6 +29,9 @@ private void g(World world, int i, int j, int k) { byte b0 = 32; if (!instaFall && world.a(i - b0, j - b0, k - b0, i + b0, j + b0, k + b0)) { + if (PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.sand-gravel-duping-fix.enabled", true)) { + world.setTypeId(i, j, k, 0); + } EntityFallingSand entityfallingsand = new EntityFallingSand(world, i + 0.5D, j + 0.5D, k + 0.5D, this.id); world.addEntity(entityfallingsand); diff --git a/src/main/java/net/minecraft/server/BlockTorch.java b/src/main/java/net/minecraft/server/BlockTorch.java index 23155b03..0ce7e64c 100644 --- a/src/main/java/net/minecraft/server/BlockTorch.java +++ b/src/main/java/net/minecraft/server/BlockTorch.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.PoseidonConfig; + import java.util.Random; import uk.betacraft.uberbukkit.UberbukkitConfig; @@ -34,6 +36,7 @@ public boolean canPlace(World world, int i, int j, int k) { } public void postPlace(World world, int i, int j, int k, int l) { + if (PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.transmutation-fix.enabled", true) && world.getTypeId(i, j, k) != this.id) return; int i1 = world.getData(i, j, k); if (l == 1 && this.g(world, i, j - 1, k)) { @@ -115,7 +118,7 @@ public void doPhysics(World world, int i, int j, int k, int l) { } private boolean h(World world, int i, int j, int k) { - if (!this.canPlace(world, i, j, k)) { + if (!this.canPlace(world, i, j, k) && (!PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.other-fixes.enabled") || world.getTypeId(i, j, k) == this.id)) { this.g(world, i, j, k, world.getData(i, j, k)); world.setTypeId(i, j, k, 0); return false; diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java index ebf35468..4fbe77fd 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.PoseidonConfig; + import java.util.*; public class Chunk { @@ -235,11 +237,18 @@ public boolean a(int i, int j, int k, int l, int i1) { int i2 = this.z * 16 + k; this.b[i << 11 | k << 7 | j] = (byte) (b0 & 255); - if (k1 != 0 && !this.world.isStatic) { - Block.byId[k1].remove(this.world, l1, j, i2); + if (PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.transmutation-fix.enabled", true)) { + this.e.a(i, j, k, i1); + if (k1 != 0 && !this.world.isStatic) { + Block.byId[k1].remove(this.world, l1, j, i2); + } + } else { + if (k1 != 0 && !this.world.isStatic) { + Block.byId[k1].remove(this.world, l1, j, i2); + } + this.e.a(i, j, k, i1); } - this.e.a(i, j, k, i1); if (!this.world.worldProvider.e) { if (Block.q[b0 & 255] != 0) { if (j >= j1) { @@ -254,7 +263,6 @@ public boolean a(int i, int j, int k, int l, int i1) { this.world.a(EnumSkyBlock.BLOCK, l1, j, i2, l1, j, i2); this.c(i, k); - this.e.a(i, j, k, i1); if (l != 0) { Block.byId[l].c(this.world, l1, j, i2); } diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index c52c0900..3d6749d8 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -15,6 +15,7 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; +import org.bukkit.event.inventory.ChestOpenedEvent; import com.legacyminecraft.poseidon.PoseidonConfig; import com.legacyminecraft.poseidon.event.PlayerDeathEvent; @@ -499,6 +500,12 @@ public void b(int i, int j, int k) { public void a(IInventory iinventory) { this.ai(); + // Poseidon start + ChestOpenedEvent event = new ChestOpenedEvent((org.bukkit.entity.Player) this.getBukkitEntity(), iinventory.getContents()); + this.world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + // Poseidon end + this.netServerHandler.sendPacket(new Packet100OpenWindow(this.bO, 0, iinventory.getName(), iinventory.getSize())); this.activeContainer = new ContainerChest(this.inventory, iinventory); this.activeContainer.windowId = this.bO; diff --git a/src/main/java/net/minecraft/server/IInventory.java b/src/main/java/net/minecraft/server/IInventory.java index bb6ce82f..67fc6924 100644 --- a/src/main/java/net/minecraft/server/IInventory.java +++ b/src/main/java/net/minecraft/server/IInventory.java @@ -18,5 +18,5 @@ public interface IInventory { boolean a_(EntityHuman entityhuman); - public abstract ItemStack[] getContents(); // CraftBukkit + ItemStack[] getContents(); // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/ItemBlock.java b/src/main/java/net/minecraft/server/ItemBlock.java index 4d7fa77c..420b08fb 100644 --- a/src/main/java/net/minecraft/server/ItemBlock.java +++ b/src/main/java/net/minecraft/server/ItemBlock.java @@ -1,7 +1,7 @@ package net.minecraft.server; // CraftBukkit start - +import com.legacyminecraft.poseidon.PoseidonConfig; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.block.BlockPlaceEvent; @@ -103,12 +103,18 @@ public boolean a(ItemStack itemstack, EntityHuman entityhuman, World world, int return true; } - world.update(i, j, k, this.id); // <-- world.setTypeIdAndData does this on success (tell the world) - // CraftBukkit end - Block.byId[this.id].postPlace(world, i, j, k, l); - Block.byId[this.id].postPlace(world, i, j, k, entityhuman); + if (PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.other-fixes.enabled", true) && (this.id == 29 || this.id == 33)) { + Block.byId[this.id].postPlace(world, i, j, k, l); + Block.byId[this.id].postPlace(world, i, j, k, entityhuman); + world.update(i, j, k, this.id); // <-- world.setTypeIdAndData does this on success (tell the world) + } else { + world.update(i, j, k, this.id); + Block.byId[this.id].postPlace(world, i, j, k, l); + Block.byId[this.id].postPlace(world, i, j, k, entityhuman); + } + world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), block.stepSound.getName(), (block.stepSound.getVolume1() + 1.0F) / 2.0F, block.stepSound.getVolume2() * 0.8F); --itemstack.count; } diff --git a/src/main/java/net/minecraft/server/ItemInWorldManager.java b/src/main/java/net/minecraft/server/ItemInWorldManager.java index 872c6e6a..2527efde 100644 --- a/src/main/java/net/minecraft/server/ItemInWorldManager.java +++ b/src/main/java/net/minecraft/server/ItemInWorldManager.java @@ -283,20 +283,13 @@ public boolean c(int i, int j, int k) { boolean flag = this.b(i, j, k); ItemStack itemstack = this.player.G(); - if (itemstack != null) { - itemstack.a(l, i, j, k, this.player); - // Uberbukkit - ref1 - } - if (flag && this.player.b(Block.byId[l])) { Block.byId[l].a(this.world, this.player, i, j, k, i1); ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); } - // Uberbukkit - moved from ref1 - // Fix tools not dropping the block on their last use - // TODO maybe make it optional? if (itemstack != null) { + itemstack.a(l, i, j, k, this.player); if (itemstack.count == 0) { itemstack.a(this.player); this.player.H(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 471bc3bb..a3a08a4e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1,9 +1,9 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.Poseidon; import com.legacyminecraft.poseidon.PoseidonConfig; import com.legacyminecraft.poseidon.util.CrackedAllowlist; import com.legacyminecraft.poseidon.util.ServerLogRotator; -import com.projectposeidon.johnymuffin.UUIDManager; import com.legacyminecraft.poseidon.watchdog.WatchDogThread; import jline.ConsoleReader; import joptsimple.OptionSet; @@ -66,8 +66,9 @@ public class MinecraftServer implements Runnable, ICommandListener { // CraftBukkit end //Poseidon Start - private WatchDogThread watchDogThread; +// private WatchDogThread watchDogThread; private boolean modLoaderSupport = false; +// private PoseidonVersionChecker poseidonVersionChecker; //Poseidon End public MinecraftServer(OptionSet options) { // CraftBukkit - adds argument OptionSet @@ -173,26 +174,7 @@ private boolean init() throws UnknownHostException { // CraftBukkit - added thro this.a(new WorldLoaderServer(new File(".")), s1, k); //Project Poseidon Start - log.info("[Poseidon] Starting Project Poseidon Modules!"); - - PoseidonConfig.getInstance(); - UUIDManager.getInstance(); - - //Start Watchdog - watchDogThread = new WatchDogThread(Thread.currentThread()); - if (PoseidonConfig.getInstance().getBoolean("settings.enable-watchdog", true)) { - log.info("[Poseidon] Starting Watchdog to detect any server hangs!"); - watchDogThread.start(); - watchDogThread.tickUpdate(); - } - //Start Poseidon Statistics - if (PoseidonConfig.getInstance().getBoolean("settings.settings.statistics.enabled", true)) { -// new PoseidonStatisticsAgent(this, this.server); - } else { - log.info("[Poseidon] Please consider enabling statistics in Poseidon.yml. It helps us see how many servers are running Poseidon, and what versions."); - } - - log.info("[Poseidon] Finished loading Project Poseidon Modules!"); + Poseidon.getServer().initializeServer(); //Project Poseidon End // CraftBukkit start @@ -374,12 +356,11 @@ public void stop() { // CraftBukkit - private -> public log.info("Stopping server"); //Project Poseidon Start - UUIDManager.getInstance().saveJsonArray(); + + // This is done before disablePlugins() to ensure the watchdog doesn't detect plugins disabling as a server hang + Poseidon.getServer().shutdownServer(); + CrackedAllowlist.get().saveAllowlist(); - if (watchDogThread != null) { - log.info("Stopping Poseidon Watchdog"); - watchDogThread.interrupt(); - } //Project Poseidon End // CraftBukkit start @@ -436,7 +417,7 @@ public void run() { } else { while (j > 50L) { MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit - watchDogThread.tickUpdate(); // Project Poseidon + getWatchdog().tickUpdate(); // Project Poseidon j -= 50L; this.h(); } @@ -654,6 +635,6 @@ public static boolean isRunning(MinecraftServer minecraftserver) { } public WatchDogThread getWatchdog() { - return this.watchDogThread; + return Poseidon.getServer().getWatchDogThread(); } } diff --git a/src/main/java/net/minecraft/server/NetServerHandler.java b/src/main/java/net/minecraft/server/NetServerHandler.java index 3cd848e9..ce6dd3f9 100644 --- a/src/main/java/net/minecraft/server/NetServerHandler.java +++ b/src/main/java/net/minecraft/server/NetServerHandler.java @@ -1,5 +1,9 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.Poseidon; +import com.legacyminecraft.poseidon.event.PlayerSendPacketEvent; +import com.projectposeidon.ConnectionType; +import com.legacyminecraft.poseidon.PoseidonConfig; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -23,22 +27,8 @@ import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.packet.PacketReceivedEvent; -import org.bukkit.event.packet.PacketSentEvent; -import org.bukkit.event.player.PlayerAnimationEvent; -import org.bukkit.event.player.PlayerChatEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerTeleportEvent; -import org.bukkit.event.player.PlayerToggleSneakEvent; - -import com.legacyminecraft.poseidon.PoseidonConfig; -import com.legacyminecraft.poseidon.event.PlayerSendPacketEvent; -import com.projectposeidon.ConnectionType; +import org.bukkit.event.packet.*; +import org.bukkit.event.player.*; import me.devcody.uberbukkit.nms.patch.IllegalContainerInteractionFix; import uk.betacraft.uberbukkit.UberbukkitConfig; @@ -349,6 +339,19 @@ public void a(Packet10Flying packet10flying) { if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) { d5 = packet10flying.x; d4 = packet10flying.z; + + // Project Poseidon - Start + // Boat crash fix ported from UberBukkit + + double d8 = d5 * d5 + d4 * d4; + if (d8 > 100.0D) { + a.warning("[Poseidon]" + this.player.name + " tried crashing server on entity " + this.player.vehicle.toString() + ". They have been kicked."); + player.kickPlayer("Boat crash attempt detected!"); + return; + } + + // Project Poseidon - End + } this.player.onGround = packet10flying.g; @@ -1168,7 +1171,7 @@ private void handleCommand(String s) { //Hide commands from being logged in console String cmdName = s.split(" ")[0].replaceAll("/", ""); - if (server.isCommandHidden(cmdName)) { + if (Poseidon.getServer().isCommandHidden(cmdName)) { a.info(player.getName() + " issued server command: COMMAND REDACTED"); } else { a.info(player.getName() + " issued server command: " + s); diff --git a/src/main/java/net/minecraft/server/ServerConfigurationManager.java b/src/main/java/net/minecraft/server/ServerConfigurationManager.java index eac65546..6794e84c 100644 --- a/src/main/java/net/minecraft/server/ServerConfigurationManager.java +++ b/src/main/java/net/minecraft/server/ServerConfigurationManager.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.legacyminecraft.poseidon.Poseidon; import com.legacyminecraft.poseidon.PoseidonConfig; import uk.betacraft.uberbukkit.packet.Packet62Sound; @@ -120,7 +121,8 @@ public void c(EntityPlayer entityplayer) { } // CraftBukkit start - PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(this.cserver.getPlayer(entityplayer), msgPlayerJoin.replace("%player%", entityplayer.name)); + Player player = this.cserver.getPlayer(entityplayer); + PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(player, msgPlayerJoin.replace("%player%", entityplayer.name)); this.cserver.getPluginManager().callEvent(playerJoinEvent); String joinMessage = playerJoinEvent.getJoinMessage(); @@ -130,6 +132,18 @@ public void c(EntityPlayer entityplayer) { } // CraftBukkit end + // Poseidon Start + // Notify staff of Poseidon update if they are op or have poseidon.update permission + if(PoseidonConfig.getInstance().getConfigBoolean("settings.update-checker.notify-staff.enabled", true) && Poseidon.getServer().isUpdateAvailable()) { + if (player.isOp() || player.hasPermission("poseidon.update")) { + String updateMessage = PoseidonConfig.getInstance().getConfigString("message.update.available"); + updateMessage = updateMessage.replace("%newversion%", Poseidon.getServer().getNewestVersion()); + updateMessage = updateMessage.replace("%currentversion%", Poseidon.getServer().getReleaseVersion()); + player.sendMessage(updateMessage); + } + } + // Poseidon End + worldserver.addEntity(entityplayer); this.getPlayerManager(entityplayer.dimension).addPlayer(entityplayer); } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index 68656ae1..82a923d5 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -471,25 +471,4 @@ public interface Server { */ public Set getBannedPlayers(); - /** - * Returns the current hide state of the command from param (Hide from console) - * - * @param cmdName Command name - * @return True if the command from param is hidden and false otherwise - */ - public boolean isCommandHidden(String cmdName); - - /** - * Hides the command from param from being logged to server console - * - * @param cmd Command name - */ - public void addHiddenCommand(String cmd); - - /** - * Hides the commands from param from being logged to server console - * - * @param commands List of command names - */ - public void addHiddenCommands(List commands); } diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java index cb108520..b43cc686 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -1,6 +1,7 @@ package org.bukkit.command; import com.legacyminecraft.poseidon.PoseidonConfig; +import com.legacyminecraft.poseidon.commands.PoseidonCommand; import com.legacyminecraft.poseidon.commands.TPSCommand; import org.bukkit.Server; import org.bukkit.command.defaults.*; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 7bcf9785..23492115 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -4,6 +4,11 @@ import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.config.dbplatform.SQLitePlatform; import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation; +import com.legacyminecraft.poseidon.Poseidon; +import com.legacyminecraft.poseidon.PoseidonConfig; +import com.legacyminecraft.poseidon.PoseidonPlugin; +import com.legacyminecraft.poseidon.PoseidonServer; +import com.legacyminecraft.poseidon.utility.PoseidonVersionChecker; import jline.ConsoleReader; import net.minecraft.server.*; import org.bukkit.Bukkit; @@ -55,7 +60,7 @@ public final class CraftServer implements Server { private final String serverName = "Project Poseidon Craftbukkit"; //Poseidon Versions private final String serverEnvironment = "POSEIDON"; - private final String serverVersion = "1.1.8"; + private final String serverVersion = "1.1.10"; private final String releaseType = "DEVELOPMENT"; private final String protocolVersion = "1.7.3"; private final String GameVersion = "b1.7.3"; @@ -78,16 +83,17 @@ public CraftServer(MinecraftServer console, ServerConfigurationManager server) { Bukkit.setServer(this); + //Project Poseidon Start + PoseidonServer poseidonServer = new PoseidonServer(console, this); + Poseidon.setServer(poseidonServer); + //Project Poseidon End + configuration = new Configuration((File) console.options.valueOf("bukkit-settings")); loadConfig(); loadPlugins(); enablePlugins(PluginLoadOrder.STARTUP); ChunkCompressionThread.startThread(); - - // Project Poseidon start - addHiddenCommands(Arrays.asList("login", "l", "register", "reg", "unregister", "changepassword", "changepw")); - // Project Poseidon end } private void loadConfig() { @@ -849,27 +855,6 @@ public void setShuttingdown(boolean shuttingdown) { this.shuttingdown = shuttingdown; } - public boolean isCommandHidden(String cmdName) { - return hiddenCommands.contains(cmdName.toLowerCase()); - } - - public void addHiddenCommand(String cmd) { - cmd = cmd.toLowerCase(); - - if (hiddenCommands.contains(cmd)) { - Logger.getLogger(NetServerHandler.class.getName()).warning("List of Hidden commands already contains " + cmd); - return; - } - - hiddenCommands.add(cmd); - } - - public void addHiddenCommands(List commands) { - for (String cmd : commands) { - addHiddenCommand(cmd); - } - } - // public GameMode getDefaultGameMode() { // return GameMode.SURVIVAL; // } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java index 471a4251..5a0b6445 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -1,12 +1,9 @@ package org.bukkit.craftbukkit.inventory; import net.minecraft.server.InventoryPlayer; -import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import java.util.ArrayList; - public class CraftInventoryPlayer extends CraftInventory implements PlayerInventory { public CraftInventoryPlayer(net.minecraft.server.InventoryPlayer inventory) { super(inventory); @@ -45,7 +42,7 @@ public ItemStack getLeggings() { } public ItemStack getBoots() { - return getItem(getSize()); + return getItem(getSize() + 0); } public void setHelmet(ItemStack helmet) { @@ -61,33 +58,17 @@ public void setLeggings(ItemStack leggings) { } public void setBoots(ItemStack boots) { - setItem(getSize(), boots); + setItem(getSize() + 0, boots); } - public ItemStack[] getArmorContents() { - ArrayList contents = new ArrayList<>(); - - ItemStack boots = getItem(getSize()); - if (boots != null && boots.getType() != Material.AIR) { - contents.add(boots); - } - - ItemStack leggings = getItem(getSize() + 1); - if (leggings != null && leggings.getType() != Material.AIR) { - contents.add(leggings); - } - - ItemStack chestplate = getItem(getSize() + 2); - if (chestplate != null && chestplate.getType() != Material.AIR) { - contents.add(chestplate); - } + public CraftItemStack[] getArmorContents() { + net.minecraft.server.ItemStack[] mcItems = getInventory().getArmorContents(); + CraftItemStack[] ret = new CraftItemStack[mcItems.length]; - ItemStack helmet = getItem(getSize() + 3); - if (helmet != null && helmet.getType() != Material.AIR) { - contents.add(helmet); + for (int i = 0; i < mcItems.length; i++) { + ret[i] = new CraftItemStack(mcItems[i]); } - - return contents.toArray(new ItemStack[0]); + return ret; } public void setArmorContents(ItemStack[] items) { diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java index 54916777..85ab9634 100644 --- a/src/main/java/org/bukkit/event/Event.java +++ b/src/main/java/org/bukkit/event/Event.java @@ -140,7 +140,7 @@ public enum Category { /** * Provides a lookup for all core events * - * @see org.bukkit.event. + * @see org.bukkit.event */ public enum Type { @@ -156,6 +156,7 @@ public enum Type { PACKET_SENT(Category.PACKET), + CHEST_OPENED(Category.BLOCK), /** * Called when a player first starts their connection. Called before UUID is known. diff --git a/src/main/java/org/bukkit/event/inventory/ChestOpenedEvent.java b/src/main/java/org/bukkit/event/inventory/ChestOpenedEvent.java new file mode 100644 index 00000000..1ac14967 --- /dev/null +++ b/src/main/java/org/bukkit/event/inventory/ChestOpenedEvent.java @@ -0,0 +1,34 @@ +package org.bukkit.event.inventory; + +import net.minecraft.server.ItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; + +public class ChestOpenedEvent extends Event implements Cancellable { + private boolean cancelled; + private Player player; + private ItemStack[] contents; + + public ChestOpenedEvent(Player player, ItemStack[] contents) { + super(Type.CHEST_OPENED); + this.player = player; + this.contents = contents; + } + + public Player getPlayer() { + return player; + } + + public ItemStack[] getContents() { + return contents; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } +} diff --git a/src/main/java/org/bukkit/plugin/RegisteredListener.java b/src/main/java/org/bukkit/plugin/RegisteredListener.java index 475bff15..6af5c238 100644 --- a/src/main/java/org/bukkit/plugin/RegisteredListener.java +++ b/src/main/java/org/bukkit/plugin/RegisteredListener.java @@ -1,5 +1,6 @@ package org.bukkit.plugin; +import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.Listener; @@ -11,19 +12,22 @@ public class RegisteredListener { private final Event.Priority priority; private final Plugin plugin; private final EventExecutor executor; + private final boolean ignoreCancelled; public RegisteredListener(final Listener pluginListener, final EventExecutor eventExecutor, final Event.Priority eventPriority, final Plugin registeredPlugin) { - listener = pluginListener; - priority = eventPriority; - plugin = registeredPlugin; - executor = eventExecutor; + this(pluginListener, eventExecutor, eventPriority, registeredPlugin, false); + } + + public RegisteredListener(final Listener pluginListener, final EventExecutor eventExecutor, final Event.Priority eventPriority, final Plugin registeredPlugin, final boolean ignoreCancelled) { + this.listener = pluginListener; + this.priority = eventPriority; + this.plugin = registeredPlugin; + this.executor = eventExecutor; + this.ignoreCancelled = ignoreCancelled; } public RegisteredListener(final Listener pluginListener, final Event.Priority eventPriority, final Plugin registeredPlugin, Event.Type type) { - listener = pluginListener; - priority = eventPriority; - plugin = registeredPlugin; - executor = registeredPlugin.getPluginLoader().createExecutor(type, pluginListener); + this(pluginListener, registeredPlugin.getPluginLoader().createExecutor(type, pluginListener), eventPriority, registeredPlugin, false); } public void registerAll() { @@ -63,6 +67,11 @@ public Event.Priority getPriority() { * @return Registered Priority */ public void callEvent(Event event) { + if(event instanceof Cancellable) { + if(((Cancellable) event).isCancelled() && ignoreCancelled) { + return; + } + } executor.execute(listener, event); } } diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 9ac83ce8..7a3a5195 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -2,6 +2,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.MapMaker; +import com.legacyminecraft.poseidon.Poseidon; import com.legacyminecraft.poseidon.event.PoseidonCustomListener; import org.bukkit.Server; import org.bukkit.command.Command; @@ -290,12 +291,14 @@ public void enablePlugin(final Plugin plugin) { if (!pluginCommands.isEmpty()) { commandMap.registerAll(plugin.getDescription().getName(), pluginCommands); + // Project Poseidon - Start - Hide commands for (Command c : pluginCommands) { if (c.isHidden()) { - server.addHiddenCommand(c.getLabel()); - server.addHiddenCommands(c.getAliases()); + Poseidon.getServer().addHiddenCommand(c.getLabel()); + Poseidon.getServer().addHiddenCommands(c.getAliases()); } } + // Project Poseidon - End - Hide commands } try { diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index da6f5c70..334820ad 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -232,7 +232,7 @@ public Map, Set> createRegisteredList e.printStackTrace(); } }; - eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin)); + eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); } return ret; }