Replacing every block in a chunk crashes server - java

I am replacing blocks in chunks. Every time a chunk is loaded, I replace generating blocks with a random other one. So here is my code
package de.belinked.chunkrandomizer;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class ChunkRandomizer extends JavaPlugin implements Listener {
public List<Material> blocks = Arrays.asList(
Material.ACACIA_LEAVES,
Material.ACACIA_LOG,
// I'll leave this out, just every full, solid block
Material.YELLOW_STAINED_GLASS,
Material.YELLOW_TERRACOTTA,
Material.YELLOW_WOOL
);
#Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
Bukkit.broadcastMessage(this.prefix + "Der Chunk-Randomizer wurde erfolgreich geladen");
}
#Override
public void onDisable() {
}
public Material getRandomMaterial(List l) {
int rnd = ThreadLocalRandom.current().nextInt(l.size());
Material m = (Material) l.get(rnd);
return m;
}
#EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
if(e.isNewChunk()) {
Chunk chunk = e.getChunk();
Block b;
Material m = getRandomMaterial(this.blocks);
for(int y = -64; y <= 320; y++) {
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
b = chunk.getBlock(x, y, z);
if(!b.getType().isAir()
&& b.getType() != Material.BEDROCK
&& b.getType() != Material.WATER
&& b.getType() != Material.LAVA
&& b.getType() != Material.END_PORTAL_FRAME
&& b.getType() != Material.END_PORTAL) {
b.setType(m);
}
}
}
}
}
}
}
but when I join the server and load a few chunks then I get this log:
https://pastebin.com/vA8qHSUr
Can anyone help me fix this?
Edit: now I get kicked and for a while nothing happens, then I get this log which is even to long for the console: https://pastebin.com/8eZ4Ja4m

In the error, line 77, it says :
Cannot get data for not block BRICK
I think the problem comes from your list blocks.
Somewhere in it, there must be a Material.BRICK, but in fact, I think the material should be Material.BRICKS, Bricks being the whole block, and Brick being the cooked clay item to make the Bricks block.

You should check that you well have api-version: 1.13 in your plugin.yml.
It's because some mapping names changes, and they are not well detected by spigot without this option.

Related

Java Spigot, Popultate and block.setType cause StackOverflow

i'm actually developing a little ore remover plugin using Spigot 1.15 API.
Here is my problem. when i use block.setType() in my populate method (which is called by minecraft generator), it seems to call back the minecraft generator.
This cause a StackOverflowError. See this log
My question is, how could i do to stop this callback.
Here are my sources :
Plugin.yml :
#####################################
# General Plugin Informations #
#####################################
name: Remover
author: me
version: 1.0
api-version: 1.15
prefix: Remover
main: OresRemover.Remover
load: startup
Remover Class:
package OresRemover;
import org.bukkit.plugin.java.JavaPlugin;
public class Remover extends JavaPlugin {
#Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new RemoverListener(), this);
}
#Override
public void onDisable() {
}
}
RemoverListener Class
package OresRemover;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import java.util.logging.Logger;
public class RemoverListener implements Listener {
Logger logger;
public RemoverListener () {
logger = Logger.getLogger("Minecraft");
}
#EventHandler
public void onWorldInit(WorldInitEvent e) {
if (e.getWorld().getName().equals("world"))
e.getWorld().getPopulators().add(new CustomPopulator());
}
}
CustomPopulator Class:
package OresRemover;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.generator.BlockPopulator;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.logging.Logger;
public class CustomPopulator extends BlockPopulator {
Logger logger;
public CustomPopulator() {
logger = Logger.getLogger("Minecraft");
}
#Override
public void populate(World world, Random random, Chunk chunk) {
int X, Y , Z;
for (X = 0; X < 16; X++)
for (Z = 0; Z < 16; Z++) {
for (Y = world.getMaxHeight() - 1; chunk.getBlock(X, Y, Z).getType() == Material.AIR; Y--);
logger.info("Surface at x:" + X + " y:" + Y + " z:" + Z);
for (; Y > 0; Y--)
if (isOreType(chunk.getBlock(X, Y, Z).getType())) {
logger.info("Cave block found at x:" + X + " y:" + Y + " z:" + Z + " and Type is " + chunk.getBlock(X, Y, Z).getType().toString());
chunk.getBlock(X, Y, Z).setType(Material.STONE);
}
}
}
private List<Material> oreMaterial = Arrays.asList(
// Ores
Material.COAL_ORE,
Material.IRON_ORE,
Material.LAPIS_ORE,
Material.REDSTONE_ORE,
Material.GOLD_ORE,
Material.DIAMOND_ORE,
Material.EMERALD_ORE
);
private boolean isOreType(Material block) {
for (Material material : oreMaterial)
if (block == material)
return (true);
return (false);
}
}
Any help would be appreciate. Thanks
Block.setType by default updates neighboring blocks, which, if happening near a yet unpopulated chunk, causes it to populate as well, and so on. This needs to be turned off with the second boolean parameter: setType(Material.STONE, false).

Changing Horse Attributes

I have been making a plugin for a "portable horse" recently and I am very close to being done, my horses spawn in and despawn as I want them. However, the only thing that I am having a considerable amount of trouble with is changing Horse attributes like speed, color, jump height and Variant.
Here is my Code:
package io.github.bxnie.events;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Donkey;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.inventory.ItemStack;
public class HorseSpawn implements Listener {
#SuppressWarnings({ "deprecation" })
#EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
if(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK){
Player p = e.getPlayer();
ItemStack item = e.getItem();
if(item.getItemMeta().getDisplayName().equals(ChatColor.GRAY + "Donkey")) {
Donkey donkey = (Donkey) p.getWorld().spawn(p.getLocation(), Donkey.class);
donkey.setAdult();
donkey.setTamed(true);
donkey.setOwner(p);
donkey.getInventory().setSaddle(new ItemStack(Material.SADDLE));
donkey.setCustomName(ChatColor.GRAY + "Donkey");
donkey.setPassenger(p);
}
if(item.getItemMeta().getDisplayName().equals(ChatColor.RED + "Brown Horse")) {
Horse horsebrown = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horsebrown.setAdult();
horsebrown.setTamed(true);
horsebrown.setOwner(p);
horsebrown.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horsebrown.setCustomName(ChatColor.RED + "Horse");
horsebrown.setPassenger(p);
}
if(item.getItemMeta().getDisplayName().equals(ChatColor.DARK_GRAY + "Black Horse")) {
Horse horseblack = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horseblack.setAdult();
horseblack.setTamed(true);
horseblack.setOwner(p);
horseblack.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horseblack.setCustomName(ChatColor.DARK_GRAY + "Horse");
horseblack.setPassenger(p);
}
if(item.getItemMeta().getDisplayName().equals(ChatColor.WHITE + "White Horse")) {
Horse horsewhite = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horsewhite.setAdult();
horsewhite.setTamed(true);
horsewhite.setOwner(p);
horsewhite.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horsewhite.setCustomName(ChatColor.WHITE + "Horse");
horsewhite.setPassenger(p);
}
}
}
#EventHandler
public void onPLayerDismount(VehicleExitEvent e) {
if(e.getExited() instanceof Player) {
if(e.getVehicle() instanceof Donkey) {
Donkey donkey = (Donkey) e.getVehicle();
if(donkey.getCustomName() != null) {
if(donkey.getCustomName().equals(ChatColor.GRAY + "Donkey")) {
donkey.remove();
}
}
}
if(e.getVehicle() instanceof Horse) {
Horse horse = (Horse) e.getVehicle();
if(horse.getCustomName() != null) {
if(horse.getCustomName().equals(ChatColor.RED + "Horse")) {
horse.remove();
}
if(horse.getCustomName().equals(ChatColor.DARK_GRAY + "Horse")) {
horse.remove();
}
if(horse.getCustomName().equals(ChatColor.WHITE + "Horse")) {
horse.remove();
}
}
}
}
}
}
I've done a ton of research but nothing really seems to help my case, is there any way that any of you know of to spawn in a horse with the custom attributes I mentioned above?
When you believe you've researched enough, research a little more, I searched for "bukkit change horse speed" and one of the top answers works perfectly. With that being said, let's try to solve your issue.
Everything you need is right in the horse API, more specifically #setColor(), #setStyle(), #setJumpStrength and #setVariant(). Changing variant may not work using that method due to deprecation, instead you need to create a different entity, such as a skeletonHorse
These methods are really straightforward:
Horse horseblack = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horseblack.setJumpStrength(2.0);
horseblack.setColor(Color.BLACK);
SkeletonHorse skeletonHorse = (SkeletonHorse) p.getWorld().spawn(p.getLocation(), SkeletonHorse.class);
Changing speed is a little different, but the method works for any mobs.
entity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(yourValue);

Command in my bukkitplugin not working

Now that I have changed the 'Commands' to 'commands' in the plugin.yml I get another error in my cmd when I run my server. The error says '.Jar file does not contain plugin.yml'.
This is my plugin.yml as of now:
name: Wand
version: 1.0
main: me.Pixel.Main
commands:
wand:
And this is my Main file currently:
package me.Pixel;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin implements Listener {
public Main plugin;
public List<String> spells = new ArrayList<String>();
public getTargets getTargets = new getTargets();
public Spark spark = new Spark(this);
public PoisonWave poisonwave = new PoisonWave(this);
public DarkSpark darkSpark = new DarkSpark(this);
#Override
public void onEnable() {
plugin = this;
getServer().getPluginManager().registerEvents(this, this);
spells.add("Spark");
spells.add("PoisonWave");
spells.add("DarkSpark");
}
#Override
public boolean onCommand(CommandSender sender, Command command,
String label, String[] args) {
if(label.equalsIgnoreCase("wand")) {
if(!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "You need to be an in-game player to perform this action!");
} else {
Player p = (Player) sender;
if(sender.hasPermission("wand.wand")) {
ItemStack stack = new ItemStack(Material.BLAZE_ROD);
ItemMeta stackMeta = stack.getItemMeta();
stackMeta.setDisplayName(ChatColor.RED + "Empire Wand");
stack.setItemMeta(stackMeta);
p.getInventory().addItem(stack);
ChatUtilities.sendMessage(p, "You have got yourself a powerful Empire Wand!");
} else {
ChatUtilities.sendMessage(p, ChatColor.RED + "ERROR: No Permission!");
}
}
}
return false;
}
#EventHandler
public void onClick(PlayerInteractEvent e) {
if((e.getAction() == Action.RIGHT_CLICK_AIR) || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Player p = e.getPlayer();
ItemStack stack = p.getItemInHand();
if(stack != null && stack.getType() == Material.BLAZE_ROD && stack.hasItemMeta() && stack.getItemMeta().getDisplayName().equals(ChatColor.RED + "Empire Wand")) {
int SpellSelected = stack.getDurability();
if(SpellSelected < 2) {
stack.setDurability((short) (SpellSelected + 1));
p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, 119, 30);
} else {
stack.setDurability((short) 0);
}
ChatUtilities.sendMessage(p, "Selected: " + spells.get(SpellSelected));
}
}
if(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK) {
Player p = e.getPlayer();
ItemStack stack = p.getItemInHand();
if(stack != null && stack.getType() == Material.BLAZE_ROD && stack.hasItemMeta() && stack.getItemMeta().getDisplayName().equals(ChatColor.RED + "Empire Wand")) {
int SpellSelected = stack.getDurability();
if(SpellSelected == 1) {
this.spark.onCast(p);
} else if (SpellSelected == 0) {
this.poisonwave.onCast(p);
}
}
}
}
}
name: Wand
version: 1.0
main: me.Pixel.Main
commands:
wand:
Your plugin.yml file isn't valid. 'commands' must be all lower case, and there must be 2 spaces before wand.
Also, you should not make commands that way. You should make external classes implementing the CommandExecutor Interface.
I think, if you do it this way, I think you must register the command.
Like this:
getCommand("wand").setExecutor(this);
The plugin.yml file is case senstitive, the name of the list of commands needs to be all lowercase (commands instead of Commands). Since you currently have it capitalized, Bukkit/Spigot doesn't register any commands thus resulting in an "Unknown command. Type "/help" for help." message if you test the /wand command (I'm assuming this is the error you're getting, as you didn't describe the problem nor the expected behavior, but this is what happened when I tested the code, and correcting the name of the commands list made the command execute).
You might need to update the player's inventory after adding the item with p.updateInventory(). In your case, it would be something like this:
p.getInventory().addItem(stack);
p.updateInventory();

I need to know how to test if a value is not equal to multiple strings java

How do i do this?
i want to test if the sign line 2 (1) is equal to "Closed" or "Open" and if not i want to say to please specify if its open or closed it says that if i type open or closed
where the || is does not work...
package me.mcmatt.shops;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class Signs implements Listener {
#EventHandler
public void onSignChange(SignChangeEvent e) {
if (e.getLine(0).equalsIgnoreCase("[shop]")) {
Block attached = e.getBlock().getRelative(0, -1, 0);
String name = e.getPlayer().getDisplayName();
if (!(attached.getType() == Material.CHEST))
e.getPlayer().sendMessage(ChatColor.RED + "Please place the shop on a chest!");
else {
if (!e.getPlayer().hasPermission("shops.create"))
e.getPlayer().sendMessage(ChatColor.RED + "You don't have permission to create a shop! (shops.create)");
else {
if (!e.getLine(1).equalsIgnoreCase("open") || (!e.getLine(1).equalsIgnoreCase("closed"))) {
e.getPlayer().sendMessage(ChatColor.RED + "You must specify if the shop is open or closed on the second line!");
} else {
Sign o = (Sign) e.getBlock().getState();
String p = o.getLine(1);
e.setLine(0, "§9[Shop]");
e.setLine(1, "§4" + name + "'s");
e.setLine(2, "§4Shop");
e.setLine(3, p);
e.getPlayer().sendMessage(ChatColor.GREEN + "Shop Created!");
e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.LEVEL_UP, 10, 10);
}
}
}
}
}
#EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
Player p = e.getPlayer();
Block b = e.getClickedBlock();
Material m = b.getType();
if (!(m == Material.SIGN_POST)) {
return;
} else {
Sign sign = (Sign) e.getClickedBlock().getState();
if ((sign.getLine(0).equalsIgnoreCase("§9[Shop]"))) {
p.sendMessage("I right clicked the sign!");
}
}
}
}
}
You can create a list of strings you want to compare with, and then use the List.contains method:
if (!Arrays.asList("open", "closed").contains(e.getLine(1).toLowerCase()) {...
The reason that your code is not working is because of De Morgan's law
Given two statements, A and B. If you do not want A or B to true
(!A) or (!B) is not correct
(!A) and (!B) is correct or !(A or B) is logically equivalent.

JavaScriptException when using DataTable.create() in JUnit with GWTTestCase

For a school project, I have to test one of my classes. After writing and executing the test, I got the following error message and stacktrace:
com.google.gwt.core.client.JavaScriptException: (null)
#com.google.gwt.visualization.client.DataTable::create()([]): null
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:249)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:576)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:284)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.visualization.client.DataTable$.create(DataTable.java)
at com.gwt.client.VizualizationManagerTest.gwtSetUp(VizualizationManagerTest.java:150)
...
From what I read, the problem is with the method: DataTable.create(), which creates a default DataTable that may later be filled with columns and rows.
I want to test if the data is being set up correctly. In my class, I am testing to verify that the initial data is being reformatted so that it can be used for GWT Graphs. So basically I take a very large DataTable and convert it into an ArrayList of smaller DataTables. But as far as I know, my test didn't even make it as far as testing that specific method, but got stuck in the: #Before method: gwtSetUp() on DataTable.create().
Here is the code of my test:
package com.gwt.client;
import static org.junit.Assert.*;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
public class VizualizationManagerTest extends GWTTestCase {
#Test
public void testPrepareData() {
VisualizationManager.TableDATA = (DataTable) data;
VisualizationManager.prepareData();
assertEquals(data.getNumberOfColumns(), VisualizationManager.DATA.length);
assertEquals(data.getNumberOfRows(), VisualizationManager.DATA[VisualizationManager.DATA.length-1].getNumberOfRows());
//check all Cells for equality
for (int i = 0; i < data.getNumberOfColumns()-1; i++) {
for (int j = 0; j < data.getNumberOfRows(); j++) {
String test1 = VisualizationManager.DATA[i].getFormattedValue(j, 0);
String tested1 = data.getFormattedValue(j, i+1);
assertEquals(tested1, test1);
}
}
}
public AbstractDataTable data;
#Before
public void gwtSetUp() {
DataTable mydata = DataTable.create();
mydata.addColumn(ColumnType.STRING, "Country");
mydata.addColumn(ColumnType.NUMBER, "2011");
mydata.addColumn(ColumnType.NUMBER, "2010");
mydata.addColumn(ColumnType.NUMBER, "2009");
mydata.addRows(5);
mydata.setCell(0, 0, "Switzerland", "Switzerland", null);
mydata.setCell(1, 0, "Germany", "Germany", null);
mydata.setCell(2, 0, "Austria", "Austria", null);
mydata.setCell(3, 0, "Slovakia", "Slovakia", null);
mydata.setCell(4, 0, "Czech Republic", "Czech Republic", null);
Random random = new Random();
for (int i=1; i<4; i++) {
for (int j=0; j<5; j++) {
double number = random.nextDouble() % 1000.0;
mydata.setCell(j, i, number, Double.toString(number), null);
}
}
data = mydata;
}
#Override
public String getModuleName() {
return "com.gwt.AgrarAlpha_v1";
}
}
Unfortunately, I wasn't able to find out how to fix the problem. I can't tell if it has to do with the set up of the whole test or just that I can't test with the class DataTable, or maybe something different...
I am using Eclipse Luna with Java 7 update 71 on OS X Yosemite (10.10).
Thank you for your help!!
Cheers, Romi
The problem with all GWT Visualization stuff (in the actual code and in JUnit and GWTtestCase) is that it needs to be reloaded on the web.
This means, that everything that has anything to do with GWT Visualization needs to be written the following way:
class Test extends GWTTestCase{
#Test
public void testSomething{
Runnable onLoadCallback = new Runnable() {
public void run() {
...
}
};
VisualizationUtils.loadVisualizationApi(onLoadCallback, Table.PACKAGE);
}
}

Categories

Resources