mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-12-26 10:28:05 +01:00
[SAFETY COMMIT, INCOMPLETE] RAW: Add support for bukkit-api-only.
This commit is contained in:
parent
c8c4d4c9cc
commit
8e313f4a47
@ -0,0 +1,64 @@
|
||||
package fr.neatmonster.nocheatplus.compat.bukkit;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockCache;
|
||||
|
||||
public class BlockCacheBukkit extends BlockCache{
|
||||
|
||||
protected World world;
|
||||
|
||||
public BlockCacheBukkit(World world) {
|
||||
setAccess(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccess(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fetchTypeId(final int x, final int y, final int z) {
|
||||
// TODO: consider setting type id and data at once.
|
||||
return world.getBlockTypeIdAt(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fetchData(final int x, final int y, final int z) {
|
||||
// TODO: consider setting type id and data at once.
|
||||
return world.getBlockAt(x, y, z).getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] fetchBounds(final int x, final int y, final int z){
|
||||
// minX, minY, minZ, maxX, maxY, maxZ
|
||||
// TODO: Want to maintain a list with manual entries or at least half / full blocks ?
|
||||
// Always return full bounds, needs extra adaption to BlockProperties (!).
|
||||
return new double[]{0f, 0f, 0f, 1f, 1f, 1f};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean standsOnEntity(final Entity entity, final double minX, final double minY, final double minZ, final double maxX, final double maxY, final double maxZ){
|
||||
try{
|
||||
// TODO: Probably check other ids too before doing this ?
|
||||
for (final Entity other : entity.getNearbyEntities(2.0, 2.0, 2.0)){
|
||||
final EntityType type = other.getType();
|
||||
if (type != EntityType.BOAT && type != EntityType.MINECART) continue;
|
||||
final Location loc = entity.getLocation();
|
||||
if (Math.abs(loc.getY() - minY) < 0.6){
|
||||
// TODO: A "better" estimate is possible, though some more tolerance would be good.
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
catch (Throwable t){
|
||||
// Ignore exceptions (Context: DisguiseCraft).
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
package fr.neatmonster.nocheatplus.compat.bukkit;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.entity.ComplexEntityPart;
|
||||
import org.bukkit.entity.ComplexLivingEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockCache;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
|
||||
|
||||
public class MCAccessBukkit implements MCAccess{
|
||||
|
||||
/**
|
||||
* Get amplifier for a potion effect.
|
||||
* @param player
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public static double getPotionEffectAmplifier(final Player player, final PotionEffectType type) {
|
||||
if (!player.hasPotionEffect(type)) return Double.MIN_VALUE;
|
||||
final Collection<PotionEffect> effects = player.getActivePotionEffects();
|
||||
double max = Double.MIN_VALUE;
|
||||
for (final PotionEffect effect : effects){
|
||||
if (effect.getType() == type){
|
||||
max = Math.max(max, effect.getAmplifier());
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to let it fail.
|
||||
*/
|
||||
public MCAccessBukkit(){
|
||||
// TODO: ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMCVersion() {
|
||||
// Bukkit API.
|
||||
// TODO: maybe output something else.
|
||||
return "?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersionTag() {
|
||||
return "Bukkit-API";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandMap getCommandMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockCache getBlockCache(final World world) {
|
||||
return new BlockCacheBukkit(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHeight(final Entity entity) {
|
||||
final double entityHeight = 1.0;
|
||||
if (entity instanceof LivingEntity) {
|
||||
return Math.max(((LivingEntity) entity).getEyeHeight(), entityHeight);
|
||||
} else return entityHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlmostBoolean isBlockSolid(final int id) {
|
||||
final Material mat = Material.getMaterial(id);
|
||||
if (mat == null) return AlmostBoolean.MAYBE;
|
||||
else return AlmostBoolean.match(mat.isSolid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlmostBoolean isBlockLiquid(final int id) {
|
||||
final Material mat = Material.getMaterial(id);
|
||||
if (mat == null) return AlmostBoolean.MAYBE;
|
||||
switch (mat) {
|
||||
case STATIONARY_LAVA:
|
||||
case STATIONARY_WATER:
|
||||
case WATER:
|
||||
case LAVA:
|
||||
return AlmostBoolean.YES;
|
||||
}
|
||||
return AlmostBoolean.NO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Block_i(final int id) {
|
||||
// TODO: This is inaccurate (would be something like "can suffocate"), however it is used for piling upwards and might about do.
|
||||
return BlockProperties.isGround(id) || BlockProperties.isSolid(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWidth(final Entity entity) {
|
||||
// TODO
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlmostBoolean isIllegalBounds(final Player player) {
|
||||
if (player.isDead()) return AlmostBoolean.NO;
|
||||
if (!player.isSleeping()){ // TODO: ignored sleeping ?
|
||||
// TODO: This can test like ... nothing !
|
||||
// (Might not be necessary.)
|
||||
}
|
||||
return AlmostBoolean.MAYBE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getJumpAmplifier(final Player player) {
|
||||
return getPotionEffectAmplifier(player, PotionEffectType.JUMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFasterMovementAmplifier(final Player player) {
|
||||
return getPotionEffectAmplifier(player, PotionEffectType.SPEED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInvulnerableTicks(final Player player) {
|
||||
// TODO: Ahhh...
|
||||
return player.getNoDamageTicks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInvulnerableTicks(final Player player, final int ticks) {
|
||||
// TODO: Ahhh...
|
||||
player.setLastDamageCause(new EntityDamageEvent(player, DamageCause.CUSTOM, 500));
|
||||
player.setNoDamageTicks(ticks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dealFallDamage(final Player player, final int damage) {
|
||||
// TODO: account for armor, other.
|
||||
player.damage(damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplexPart(final Entity entity) {
|
||||
return entity instanceof ComplexEntityPart || entity instanceof ComplexLivingEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldBeZombie(final Player player) {
|
||||
return player.getHealth() <= 0 || player.isDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead(final Player player, final int deathTicks) {
|
||||
// TODO: Test / kick ? ...
|
||||
player.setHealth(0);
|
||||
player.damage(1);
|
||||
}
|
||||
|
||||
}
|
@ -3,11 +3,16 @@ package fr.neatmonster.nocheatplus.command;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NoCheatPlus;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
@ -40,8 +45,21 @@ public class CommandUtil {
|
||||
return ((SimpleCommandMap) commandMap).getCommands();
|
||||
}
|
||||
else{
|
||||
// TODO: Find a way to also secure server commands.
|
||||
throw new RuntimeException("Can not handle other than SimpleCommandMap.");
|
||||
final Collection<Command> commands = new LinkedHashSet<Command>(100);
|
||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()){
|
||||
if (plugin instanceof JavaPlugin){
|
||||
final JavaPlugin javaPlugin = (JavaPlugin) plugin;
|
||||
final Map<String, Map<String, Object>> map = javaPlugin.getDescription().getCommands();
|
||||
if (map != null){
|
||||
for (String label : map.keySet()){
|
||||
Command command = javaPlugin.getCommand(label);
|
||||
if (command != null) commands.add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Vanilla / CB commands !?
|
||||
return commands;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,9 +83,14 @@ public class CommandUtil {
|
||||
* @return
|
||||
*/
|
||||
public static Command getCommand(final String alias) {
|
||||
final CommandMap map = getCommandMap();
|
||||
final String lcAlias = alias.trim().toLowerCase();
|
||||
return map.getCommand(lcAlias);
|
||||
final CommandMap map = getCommandMap();
|
||||
if (map != null){
|
||||
return map.getCommand(lcAlias);
|
||||
} else {
|
||||
// TODO: maybe match versus plugin commands.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,10 +3,13 @@ package fr.neatmonster.nocheatplus.compat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.bukkit.MCAccessBukkit;
|
||||
import fr.neatmonster.nocheatplus.compat.cb2511.MCAccessCB2511;
|
||||
import fr.neatmonster.nocheatplus.compat.cb2512.MCAccessCB2512;
|
||||
import fr.neatmonster.nocheatplus.compat.cb2545.MCAccessCB2545;
|
||||
import fr.neatmonster.nocheatplus.compat.cbdev.MCAccessCBDev;
|
||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
import fr.neatmonster.nocheatplus.utilities.LogUtil;
|
||||
|
||||
/**
|
||||
@ -16,45 +19,79 @@ import fr.neatmonster.nocheatplus.utilities.LogUtil;
|
||||
*/
|
||||
public class MCAccessFactory {
|
||||
|
||||
private final String[] updateLocs = new String[]{
|
||||
"[NoCheatPlus] Check for updates at BukkitDev: http://dev.bukkit.org/server-mods/nocheatplus/",
|
||||
"[NoCheatPlus] Development builds: http://nocheatplus.org:8080/job/NoCheatPlus/",
|
||||
};
|
||||
|
||||
/**
|
||||
* @throws RuntimeException if no access can be set.
|
||||
* @return
|
||||
*/
|
||||
public MCAccess getMCAccess(){
|
||||
final List<Throwable> throwables = new ArrayList<Throwable>();
|
||||
final boolean bukkitOnly = ConfigManager.getConfigFile().getBoolean(ConfPaths.COMPATIBILITY_BUKKITONLY);
|
||||
|
||||
// TEST //
|
||||
try{
|
||||
return new MCAccessCBDev();
|
||||
// Try to set up native access.
|
||||
if (!bukkitOnly){
|
||||
// TEST //
|
||||
try{
|
||||
return new MCAccessCBDev();
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
// TEST END //
|
||||
|
||||
// TODO: add 1.4.7 classes explicitly.
|
||||
|
||||
try{
|
||||
return new MCAccessCB2545();
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
|
||||
try{
|
||||
return new MCAccessCB2512();
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
|
||||
try{
|
||||
return new MCAccessCB2511();
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
// TEST END //
|
||||
|
||||
// Try to set up api-only access.
|
||||
try{
|
||||
return new MCAccessCB2545();
|
||||
final String msg;
|
||||
if (bukkitOnly){
|
||||
msg = "[NoCheatPlus] The plugin is configured for Bukkit-API-only access is configured.";
|
||||
}
|
||||
else{
|
||||
msg = "[NoCheatPlus] Could not set up non-api access for your specific Minecraft or server-mod version.";
|
||||
}
|
||||
LogUtil.logSevere("[NoCheatPlus] Some features will likely not function properly, performance might suffer.");
|
||||
LogUtil.logWarning(msg);
|
||||
for (String uMsg : updateLocs){
|
||||
LogUtil.logWarning(uMsg);
|
||||
}
|
||||
return new MCAccessBukkit();
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
|
||||
try{
|
||||
return new MCAccessCB2512();
|
||||
// All went wrong.
|
||||
LogUtil.logSevere("[NoCheatPlus] Your version of NoCheatPlus does not seem to provide support for either your Minecraft version or your specific server-mod.");
|
||||
for (String msg : updateLocs){
|
||||
LogUtil.logSevere(msg);
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
|
||||
try{
|
||||
return new MCAccessCB2511();
|
||||
}
|
||||
catch(Throwable t){
|
||||
throwables.add(t);
|
||||
};
|
||||
LogUtil.logSevere("[NoCheatPlus] Your version of NoCheatPlus does not seem to be compatible with either your Minecraft version or your specific serve-mod.");
|
||||
LogUtil.logSevere("[NoCheatPlus] Check for updates at BukkitDev: http://dev.bukkit.org/server-mods/nocheatplus/");
|
||||
LogUtil.logSevere("[NoCheatPlus] Development builds: http://nocheatplus.org:8080/job/NoCheatPlus/");
|
||||
LogUtil.logSevere("[NoCheatPlus] Could not set up MC version specific access.");
|
||||
for (Throwable t : throwables ){
|
||||
LogUtil.logSevere(t);
|
||||
|
@ -522,7 +522,8 @@ public abstract class ConfPaths {
|
||||
// Compatibility section (possibly temporary).
|
||||
@GlobalConfig
|
||||
public static final String COMPATIBILITY = "compatibility.";
|
||||
public static final String COMPATIBILITY_BLOCKS = COMPATIBILITY + "blocks.";
|
||||
public static final String COMPATIBILITY_BUKKITONLY = COMPATIBILITY + "bukkitapionly";
|
||||
public static final String COMPATIBILITY_BLOCKS = COMPATIBILITY + "blocks.";
|
||||
|
||||
// Sub paths that are used with different path prefixes potentially.
|
||||
public static final String SUB_DEBUG = "debug";
|
||||
|
@ -25,7 +25,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
* NCP build needed for this config.
|
||||
* (Should only increment with changing or removing paths.)
|
||||
*/
|
||||
public static final int buildNumber = 315; // TODO: Check jenkins...
|
||||
public static final int buildNumber = 322;
|
||||
|
||||
// TODO: auto input full version or null to an extra variable or several [fail safe for other syntax checking]?
|
||||
|
||||
@ -465,6 +465,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.STRINGS + ".tempkick1", "ncp tempkick [player] 1 Wait a minute!");
|
||||
set(ConfPaths.STRINGS + ".tempkick5", "ncp tempkick [player] 5 You have five minutes to think about it!");
|
||||
|
||||
set(ConfPaths.COMPATIBILITY_BUKKITONLY, false);
|
||||
set(ConfPaths.COMPATIBILITY_BLOCKS + ConfPaths.SUB_IGNOREPASSABLE, Arrays.asList(
|
||||
Material.WOODEN_DOOR.name(), Material.IRON_DOOR_BLOCK.name(),
|
||||
Material.TRAP_DOOR.name(),
|
||||
|
Loading…
Reference in New Issue
Block a user