Change NPC UUID version to 2 for Minecraft
This commit is contained in:
parent
651fbac979
commit
7008ffd013
|
@ -23,238 +23,235 @@ import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
||||||
private final boolean aggro;
|
private final boolean aggro;
|
||||||
private int attackTicks;
|
private int attackTicks;
|
||||||
private CancelReason cancelReason;
|
private CancelReason cancelReason;
|
||||||
private final Entity handle;
|
private final Entity handle;
|
||||||
private final NPC npc;
|
private final NPC npc;
|
||||||
private final NavigatorParameters parameters;
|
private final NavigatorParameters parameters;
|
||||||
private final Entity target;
|
private final Entity target;
|
||||||
private final TargetNavigator targetNavigator;
|
private final TargetNavigator targetNavigator;
|
||||||
|
|
||||||
public MCTargetStrategy(NPC npc, org.bukkit.entity.Entity target, boolean aggro,
|
public MCTargetStrategy(NPC npc, org.bukkit.entity.Entity target, boolean aggro, NavigatorParameters params) {
|
||||||
NavigatorParameters params) {
|
this.npc = npc;
|
||||||
this.npc = npc;
|
this.parameters = params;
|
||||||
this.parameters = params;
|
this.handle = ((CraftEntity) npc.getEntity()).getHandle();
|
||||||
this.handle = ((CraftEntity) npc.getEntity()).getHandle();
|
this.target = ((CraftEntity) target).getHandle();
|
||||||
this.target = ((CraftEntity) target).getHandle();
|
Navigation nav = NMS.getNavigation(this.handle);
|
||||||
Navigation nav = NMS.getNavigation(this.handle);
|
this.targetNavigator = nav != null && !params.useNewPathfinder() ? new NavigationFieldWrapper(nav)
|
||||||
this.targetNavigator = nav != null && !params.useNewPathfinder() ? new NavigationFieldWrapper(
|
: new AStarTargeter();
|
||||||
nav) : new AStarTargeter();
|
this.aggro = aggro;
|
||||||
this.aggro = aggro;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canAttack() {
|
private boolean canAttack() {
|
||||||
return attackTicks == 0
|
return attackTicks == 0
|
||||||
&& (handle.boundingBox.e > target.boundingBox.b && handle.boundingBox.b < target.boundingBox.e)
|
&& (handle.boundingBox.e > target.boundingBox.b && handle.boundingBox.b < target.boundingBox.e)
|
||||||
&& closeEnough(distanceSquared()) && hasLineOfSight();
|
&& closeEnough(distanceSquared()) && hasLineOfSight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearCancelReason() {
|
public void clearCancelReason() {
|
||||||
cancelReason = null;
|
cancelReason = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean closeEnough(double distance) {
|
private boolean closeEnough(double distance) {
|
||||||
return distance <= parameters.attackRange();
|
return distance <= parameters.attackRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double distanceSquared() {
|
private double distanceSquared() {
|
||||||
return handle.getBukkitEntity().getLocation(HANDLE_LOCATION)
|
return handle.getBukkitEntity().getLocation(HANDLE_LOCATION)
|
||||||
.distanceSquared(target.getBukkitEntity().getLocation(TARGET_LOCATION));
|
.distanceSquared(target.getBukkitEntity().getLocation(TARGET_LOCATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CancelReason getCancelReason() {
|
public CancelReason getCancelReason() {
|
||||||
return cancelReason;
|
return cancelReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LivingEntity getTarget() {
|
public LivingEntity getTarget() {
|
||||||
return (LivingEntity) target.getBukkitEntity();
|
return (LivingEntity) target.getBukkitEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getTargetAsLocation() {
|
public Location getTargetAsLocation() {
|
||||||
return getTarget().getLocation();
|
return getTarget().getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetType getTargetType() {
|
public TargetType getTargetType() {
|
||||||
return TargetType.ENTITY;
|
return TargetType.ENTITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasLineOfSight() {
|
private boolean hasLineOfSight() {
|
||||||
return ((LivingEntity) handle.getBukkitEntity()).hasLineOfSight(target.getBukkitEntity());
|
return ((LivingEntity) handle.getBukkitEntity()).hasLineOfSight(target.getBukkitEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAggressive() {
|
public boolean isAggressive() {
|
||||||
return aggro;
|
return aggro;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPath() {
|
private void setPath() {
|
||||||
targetNavigator.setPath();
|
targetNavigator.setPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
targetNavigator.stop();
|
targetNavigator.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MCTargetStrategy [target=" + target + "]";
|
return "MCTargetStrategy [target=" + target + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update() {
|
public boolean update() {
|
||||||
if (target == null || !target.getBukkitEntity().isValid()) {
|
if (target == null || !target.getBukkitEntity().isValid()) {
|
||||||
cancelReason = CancelReason.TARGET_DIED;
|
cancelReason = CancelReason.TARGET_DIED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (target.world != handle.world) {
|
if (target.world != handle.world) {
|
||||||
cancelReason = CancelReason.TARGET_MOVED_WORLD;
|
cancelReason = CancelReason.TARGET_MOVED_WORLD;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (cancelReason != null) {
|
if (cancelReason != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (target.world.getWorld().getFullTime() % 10 == 0) {
|
if (target.world.getWorld().getFullTime() % 10 == 0) {
|
||||||
setPath();
|
setPath();
|
||||||
}
|
}
|
||||||
NMS.look(handle, target);
|
NMS.look(handle, target);
|
||||||
if (aggro && canAttack()) {
|
if (aggro && canAttack()) {
|
||||||
AttackStrategy strategy = parameters.attackStrategy();
|
AttackStrategy strategy = parameters.attackStrategy();
|
||||||
if (strategy != null && strategy.handle((LivingEntity) handle.getBukkitEntity(), getTarget())) {
|
if (strategy != null && strategy.handle((LivingEntity) handle.getBukkitEntity(), getTarget())) {
|
||||||
} else
|
} else if (strategy != parameters.defaultAttackStrategy()) {
|
||||||
if (strategy != parameters.defaultAttackStrategy()) {
|
parameters.defaultAttackStrategy().handle((LivingEntity) handle.getBukkitEntity(), getTarget());
|
||||||
parameters.defaultAttackStrategy().handle((LivingEntity) handle.getBukkitEntity(),
|
}
|
||||||
getTarget());
|
attackTicks = ATTACK_DELAY_TICKS;
|
||||||
}
|
}
|
||||||
attackTicks = ATTACK_DELAY_TICKS;
|
if (attackTicks > 0) {
|
||||||
}
|
attackTicks--;
|
||||||
if (attackTicks > 0) {
|
}
|
||||||
attackTicks--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AStarTargeter implements TargetNavigator {
|
private class AStarTargeter implements TargetNavigator {
|
||||||
private int failureTimes = 0;
|
private int failureTimes = 0;
|
||||||
private PathStrategy strategy;
|
private PathStrategy strategy;
|
||||||
|
|
||||||
public AStarTargeter() {
|
public AStarTargeter() {
|
||||||
setStrategy();
|
setStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPath() {
|
public void setPath() {
|
||||||
setStrategy();
|
setStrategy();
|
||||||
strategy.update();
|
strategy.update();
|
||||||
CancelReason subReason = strategy.getCancelReason();
|
CancelReason subReason = strategy.getCancelReason();
|
||||||
if (subReason == CancelReason.STUCK) {
|
if (subReason == CancelReason.STUCK) {
|
||||||
if (failureTimes++ > 10) {
|
if (failureTimes++ > 10) {
|
||||||
cancelReason = strategy.getCancelReason();
|
cancelReason = strategy.getCancelReason();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
failureTimes = 0;
|
failureTimes = 0;
|
||||||
cancelReason = strategy.getCancelReason();
|
cancelReason = strategy.getCancelReason();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setStrategy() {
|
private void setStrategy() {
|
||||||
Location location = target.getBukkitEntity().getLocation(TARGET_LOCATION);
|
Location location = target.getBukkitEntity().getLocation(TARGET_LOCATION);
|
||||||
strategy = npc.isFlyable() ? new FlyingAStarNavigationStrategy(npc, location, parameters)
|
strategy = npc.isFlyable() ? new FlyingAStarNavigationStrategy(npc, location, parameters)
|
||||||
: new AStarNavigationStrategy(npc, location, parameters);
|
: new AStarNavigationStrategy(npc, location, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
strategy.stop();
|
strategy.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NavigationFieldWrapper implements TargetNavigator {
|
private class NavigationFieldWrapper implements TargetNavigator {
|
||||||
boolean j = true, k, l, m;
|
boolean j = true, k, l, m;
|
||||||
private final Navigation navigation;
|
private final Navigation navigation;
|
||||||
float range;
|
float range;
|
||||||
|
|
||||||
private NavigationFieldWrapper(Navigation navigation) {
|
private NavigationFieldWrapper(Navigation navigation) {
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
this.k = navigation.c();
|
this.k = navigation.c();
|
||||||
this.l = navigation.a();
|
this.l = navigation.a();
|
||||||
try {
|
try {
|
||||||
if (navigation instanceof PlayerNavigation) {
|
if (navigation instanceof PlayerNavigation) {
|
||||||
if (P_NAV_E != null)
|
if (P_NAV_E != null)
|
||||||
range = (float) ((AttributeInstance) P_NAV_E.get(navigation)).getValue();
|
range = (float) ((AttributeInstance) P_NAV_E.get(navigation)).getValue();
|
||||||
if (P_NAV_J != null)
|
if (P_NAV_J != null)
|
||||||
j = P_NAV_J.getBoolean(navigation);
|
j = P_NAV_J.getBoolean(navigation);
|
||||||
if (P_NAV_M != null)
|
if (P_NAV_M != null)
|
||||||
m = P_NAV_M.getBoolean(navigation);
|
m = P_NAV_M.getBoolean(navigation);
|
||||||
} else {
|
} else {
|
||||||
if (E_NAV_E != null)
|
if (E_NAV_E != null)
|
||||||
range = (float) ((AttributeInstance) E_NAV_E.get(navigation)).getValue();
|
range = (float) ((AttributeInstance) E_NAV_E.get(navigation)).getValue();
|
||||||
if (E_NAV_J != null)
|
if (E_NAV_J != null)
|
||||||
j = E_NAV_J.getBoolean(navigation);
|
j = E_NAV_J.getBoolean(navigation);
|
||||||
if (E_NAV_M != null)
|
if (E_NAV_M != null)
|
||||||
m = E_NAV_M.getBoolean(navigation);
|
m = E_NAV_M.getBoolean(navigation);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
range = parameters.range();
|
range = parameters.range();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathEntity findPath(Entity from, Entity to) {
|
public PathEntity findPath(Entity from, Entity to) {
|
||||||
return handle.world.findPath(from, to, range, j, k, l, m);
|
return handle.world.findPath(from, to, range, j, k, l, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPath() {
|
public void setPath() {
|
||||||
navigation.a(parameters.avoidWater());
|
navigation.a(parameters.avoidWater());
|
||||||
navigation.a(findPath(handle, target), parameters.speed());
|
navigation.a(findPath(handle, target), parameters.speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
NMS.stopNavigation(navigation);
|
NMS.stopNavigation(navigation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static interface TargetNavigator {
|
private static interface TargetNavigator {
|
||||||
void setPath();
|
void setPath();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int ATTACK_DELAY_TICKS = 20;
|
private static final int ATTACK_DELAY_TICKS = 20;
|
||||||
static final AttackStrategy DEFAULT_ATTACK_STRATEGY = new AttackStrategy() {
|
static final AttackStrategy DEFAULT_ATTACK_STRATEGY = new AttackStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(LivingEntity attacker, LivingEntity bukkitTarget) {
|
public boolean handle(LivingEntity attacker, LivingEntity bukkitTarget) {
|
||||||
EntityLiving handle = NMS.getHandle(attacker);
|
EntityLiving handle = NMS.getHandle(attacker);
|
||||||
EntityLiving target = NMS.getHandle(bukkitTarget);
|
EntityLiving target = NMS.getHandle(bukkitTarget);
|
||||||
if (handle instanceof EntityPlayer) {
|
if (handle instanceof EntityPlayer) {
|
||||||
EntityPlayer humanHandle = (EntityPlayer) handle;
|
EntityPlayer humanHandle = (EntityPlayer) handle;
|
||||||
humanHandle.attack(target);
|
humanHandle.attack(target);
|
||||||
PlayerAnimation.ARM_SWING.play(humanHandle.getBukkitEntity());
|
PlayerAnimation.ARM_SWING.play(humanHandle.getBukkitEntity());
|
||||||
} else {
|
} else {
|
||||||
NMS.attack(handle, target);
|
NMS.attack(handle, target);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static Field E_NAV_E, E_NAV_J, E_NAV_M;
|
private static Field E_NAV_E, E_NAV_J, E_NAV_M;
|
||||||
private static final Location HANDLE_LOCATION = new Location(null, 0, 0, 0);
|
private static final Location HANDLE_LOCATION = new Location(null, 0, 0, 0);
|
||||||
private static Field P_NAV_E, P_NAV_J, P_NAV_M;
|
private static Field P_NAV_E, P_NAV_J, P_NAV_M;
|
||||||
private static final Location TARGET_LOCATION = new Location(null, 0, 0, 0);
|
private static final Location TARGET_LOCATION = new Location(null, 0, 0, 0);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
E_NAV_E = NMS.getField(Navigation.class, "e");
|
E_NAV_E = NMS.getField(Navigation.class, "e");
|
||||||
E_NAV_J = NMS.getField(Navigation.class, "j");
|
E_NAV_J = NMS.getField(Navigation.class, "j");
|
||||||
E_NAV_M = NMS.getField(Navigation.class, "m");
|
E_NAV_M = NMS.getField(Navigation.class, "m");
|
||||||
P_NAV_E = NMS.getField(PlayerNavigation.class, "e");
|
P_NAV_E = NMS.getField(PlayerNavigation.class, "e");
|
||||||
P_NAV_J = NMS.getField(PlayerNavigation.class, "j");
|
P_NAV_J = NMS.getField(PlayerNavigation.class, "j");
|
||||||
P_NAV_M = NMS.getField(PlayerNavigation.class, "m");
|
P_NAV_M = NMS.getField(PlayerNavigation.class, "m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,10 @@ public class HumanController extends AbstractEntityController {
|
||||||
|
|
||||||
UUID uuid = npc.getUniqueId();
|
UUID uuid = npc.getUniqueId();
|
||||||
if (uuid.version() == 4) { // clear version
|
if (uuid.version() == 4) { // clear version
|
||||||
uuid = new UUID(uuid.getMostSignificantBits() | 0x0000000000005000L, uuid.getLeastSignificantBits());
|
long msb = uuid.getMostSignificantBits();
|
||||||
|
msb &= ~0x0000000000004000L;
|
||||||
|
msb |= 0x0000000000002000L;
|
||||||
|
uuid = new UUID(msb, uuid.getLeastSignificantBits());
|
||||||
}
|
}
|
||||||
|
|
||||||
GameProfile profile = new GameProfile(uuid, coloredName);
|
GameProfile profile = new GameProfile(uuid, coloredName);
|
||||||
|
@ -124,8 +127,8 @@ public class HumanController extends AbstractEntityController {
|
||||||
private GameProfile fillProfileProperties(YggdrasilAuthenticationService auth, GameProfile profile,
|
private GameProfile fillProfileProperties(YggdrasilAuthenticationService auth, GameProfile profile,
|
||||||
boolean requireSecure) throws Exception {
|
boolean requireSecure) throws Exception {
|
||||||
URL url = HttpAuthenticationService.constantURL(new StringBuilder()
|
URL url = HttpAuthenticationService.constantURL(new StringBuilder()
|
||||||
.append("https://sessionserver.mojang.com/session/minecraft/profile/")
|
.append("https://sessionserver.mojang.com/session/minecraft/profile/")
|
||||||
.append(UUIDTypeAdapter.fromUUID(profile.getId())).toString());
|
.append(UUIDTypeAdapter.fromUUID(profile.getId())).toString());
|
||||||
url = HttpAuthenticationService.concatenateURL(url,
|
url = HttpAuthenticationService.concatenateURL(url,
|
||||||
new StringBuilder().append("unsigned=").append(!requireSecure).toString());
|
new StringBuilder().append("unsigned=").append(!requireSecure).toString());
|
||||||
MinecraftProfilePropertiesResponse response = (MinecraftProfilePropertiesResponse) MAKE_REQUEST.invoke(
|
MinecraftProfilePropertiesResponse response = (MinecraftProfilePropertiesResponse) MAKE_REQUEST.invoke(
|
||||||
|
@ -152,7 +155,7 @@ public class HumanController extends AbstractEntityController {
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
if (Messaging.isDebugging()) {
|
if (Messaging.isDebugging()) {
|
||||||
Messaging
|
Messaging
|
||||||
.debug("Using cached skin texture for NPC " + npc.getName() + " UUID " + npc.getUniqueId());
|
.debug("Using cached skin texture for NPC " + npc.getName() + " UUID " + npc.getUniqueId());
|
||||||
}
|
}
|
||||||
skinProfile = new GameProfile(UUID.fromString(realUUID), "");
|
skinProfile = new GameProfile(UUID.fromString(realUUID), "");
|
||||||
skinProfile.getProperties().put("textures", cached);
|
skinProfile.getProperties().put("textures", cached);
|
||||||
|
@ -164,7 +167,7 @@ public class HumanController extends AbstractEntityController {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if ((e.getMessage() != null && e.getMessage().contains("too many requests"))
|
if ((e.getMessage() != null && e.getMessage().contains("too many requests"))
|
||||||
|| (e.getCause() != null && e.getCause().getMessage() != null && e.getCause().getMessage()
|
|| (e.getCause() != null && e.getCause().getMessage() != null && e.getCause().getMessage()
|
||||||
.contains("too many requests"))) {
|
.contains("too many requests"))) {
|
||||||
SKIN_THREAD.delay();
|
SKIN_THREAD.delay();
|
||||||
SKIN_THREAD.addRunnable(this);
|
SKIN_THREAD.addRunnable(this);
|
||||||
}
|
}
|
||||||
|
@ -254,22 +257,22 @@ public class HumanController extends AbstractEntityController {
|
||||||
.getGameProfileRepository();
|
.getGameProfileRepository();
|
||||||
repo.findProfilesByNames(new String[] { ChatColor.stripColor(reportedUUID) }, Agent.MINECRAFT,
|
repo.findProfilesByNames(new String[] { ChatColor.stripColor(reportedUUID) }, Agent.MINECRAFT,
|
||||||
new ProfileLookupCallback() {
|
new ProfileLookupCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onProfileLookupFailed(GameProfile arg0, Exception arg1) {
|
public void onProfileLookupFailed(GameProfile arg0, Exception arg1) {
|
||||||
throw new RuntimeException(arg1);
|
throw new RuntimeException(arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProfileLookupSucceeded(final GameProfile profile) {
|
public void onProfileLookupSucceeded(final GameProfile profile) {
|
||||||
UUID_CACHE.put(reportedUUID, profile.getId().toString());
|
UUID_CACHE.put(reportedUUID, profile.getId().toString());
|
||||||
if (Messaging.isDebugging()) {
|
if (Messaging.isDebugging()) {
|
||||||
Messaging.debug("Fetched UUID " + profile.getId() + " for NPC " + npc.getName()
|
Messaging.debug("Fetched UUID " + profile.getId() + " for NPC " + npc.getName()
|
||||||
+ " UUID " + npc.getUniqueId());
|
+ " UUID " + npc.getUniqueId());
|
||||||
}
|
}
|
||||||
npc.data().setPersistent(CACHED_SKIN_UUID_METADATA, profile.getId().toString());
|
npc.data().setPersistent(CACHED_SKIN_UUID_METADATA, profile.getId().toString());
|
||||||
npc.data().setPersistent(CACHED_SKIN_UUID_NAME_METADATA, profile.getName());
|
npc.data().setPersistent(CACHED_SKIN_UUID_NAME_METADATA, profile.getName());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return npc.data().get(CACHED_SKIN_UUID_METADATA, reportedUUID);
|
return npc.data().get(CACHED_SKIN_UUID_METADATA, reportedUUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue