Better bot creation, faceLocation() improved, Mojang API fetching cache added.
This commit is contained in:
@@ -30,8 +30,8 @@ public class PlayerAI extends JavaPlugin {
|
|||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
// Create Instances
|
// Create Instances
|
||||||
this.handler = new CommandHandler(this);
|
|
||||||
this.manager = new BotManager(this);
|
this.manager = new BotManager(this);
|
||||||
|
this.handler = new CommandHandler(this);
|
||||||
|
|
||||||
// Register all the things
|
// Register all the things
|
||||||
this.registerEvents();
|
this.registerEvents();
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import com.mojang.authlib.GameProfile;
|
|||||||
import com.mojang.authlib.properties.Property;
|
import com.mojang.authlib.properties.Property;
|
||||||
import net.minecraft.server.v1_16_R3.*;
|
import net.minecraft.server.v1_16_R3.*;
|
||||||
import net.nuggetmc.ai.PlayerAI;
|
import net.nuggetmc.ai.PlayerAI;
|
||||||
|
import net.nuggetmc.ai.utils.MathUtils;
|
||||||
import net.nuggetmc.ai.utils.MojangAPI;
|
import net.nuggetmc.ai.utils.MojangAPI;
|
||||||
import net.nuggetmc.ai.utils.SteveUUID;
|
import net.nuggetmc.ai.utils.SteveUUID;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.attribute.Attribute;
|
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
|
import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
|
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity;
|
||||||
@@ -35,7 +35,7 @@ public class Bot extends EntityPlayer {
|
|||||||
kbTicks = 0;
|
kbTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bot createBot(String name, Location loc, String skin) {
|
public static Bot createBot(Location loc, String name, String skin) {
|
||||||
MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer();
|
MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer();
|
||||||
WorldServer nmsWorld = ((CraftWorld) loc.getWorld()).getHandle();
|
WorldServer nmsWorld = ((CraftWorld) loc.getWorld()).getHandle();
|
||||||
|
|
||||||
@@ -107,11 +107,11 @@ public class Bot extends EntityPlayer {
|
|||||||
if (noDamageTicks > 0) --noDamageTicks;
|
if (noDamageTicks > 0) --noDamageTicks;
|
||||||
if (kbTicks > 0) --kbTicks;
|
if (kbTicks > 0) --kbTicks;
|
||||||
|
|
||||||
Player playerNPC = this.getBukkitEntity();
|
Player botPlayer = this.getBukkitEntity();
|
||||||
if (playerNPC.isDead()) return;
|
if (botPlayer.isDead()) return;
|
||||||
|
|
||||||
double health = playerNPC.getHealth();
|
double health = botPlayer.getHealth();
|
||||||
double maxHealth = playerNPC.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue();
|
double maxHealth = botPlayer.getHealthScale();
|
||||||
double amount;
|
double amount;
|
||||||
|
|
||||||
if (health < maxHealth - regenAmount) {
|
if (health < maxHealth - regenAmount) {
|
||||||
@@ -120,7 +120,7 @@ public class Bot extends EntityPlayer {
|
|||||||
amount = maxHealth;
|
amount = maxHealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
playerNPC.setHealth(amount);
|
botPlayer.setHealth(amount);
|
||||||
|
|
||||||
updateLocation();
|
updateLocation();
|
||||||
}
|
}
|
||||||
@@ -184,6 +184,11 @@ public class Bot extends EntityPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void despawn() {
|
public void despawn() {
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||||
|
connection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, this));
|
||||||
|
}
|
||||||
|
|
||||||
getBukkitEntity().remove();
|
getBukkitEntity().remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,13 +237,13 @@ public class Bot extends EntityPlayer {
|
|||||||
Location loc1 = player.getLocation();
|
Location loc1 = player.getLocation();
|
||||||
Location loc2 = entity.getLocation();
|
Location loc2 = entity.getLocation();
|
||||||
|
|
||||||
kb(player, loc1, loc2);
|
kb(loc1, loc2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return damaged;
|
return damaged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void kb(Player playerBot, Location loc1, Location loc2) {
|
private void kb(Location loc1, Location loc2) {
|
||||||
Vector diff = loc1.toVector().subtract(loc2.toVector()).normalize();
|
Vector diff = loc1.toVector().subtract(loc2.toVector()).normalize();
|
||||||
diff.multiply(0.25);
|
diff.multiply(0.25);
|
||||||
diff.setY(0.5);
|
diff.setY(0.5);
|
||||||
@@ -252,17 +257,17 @@ public class Bot extends EntityPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void faceLocation(Location loc) {
|
public void faceLocation(Location loc) {
|
||||||
try {
|
CraftPlayer botPlayer = getBukkitEntity();
|
||||||
CraftPlayer playerBot = this.getBukkitEntity();
|
Vector dir = loc.toVector().subtract(botPlayer.getLocation().toVector());
|
||||||
Vector dir = loc.toVector().subtract(playerBot.getLocation().toVector()).normalize();
|
|
||||||
Location facing = playerBot.getLocation().setDirection(dir);
|
|
||||||
playerBot.teleport(facing);
|
|
||||||
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
float[] vals = MathUtils.fetchYawPitch(dir);
|
||||||
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
|
|
||||||
connection.sendPacket(new PacketPlayOutEntityHeadRotation(playerBot.getHandle(), (byte) (facing.getYaw() * 256 / 360)));
|
setYawPitch(vals[0], vals[1]);
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException ignored) { }
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||||
|
connection.sendPacket(new PacketPlayOutEntityHeadRotation(botPlayer.getHandle(), (byte) (vals[0] * 256 / 360f)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,10 +2,16 @@ package net.nuggetmc.ai.bot;
|
|||||||
|
|
||||||
import net.minecraft.server.v1_16_R3.PlayerConnection;
|
import net.minecraft.server.v1_16_R3.PlayerConnection;
|
||||||
import net.nuggetmc.ai.PlayerAI;
|
import net.nuggetmc.ai.PlayerAI;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -28,6 +34,35 @@ public class BotManager implements Listener {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createBots(Player sender, String name, String skin, int n) {
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (n < 1) n = 1;
|
||||||
|
|
||||||
|
World world = sender.getWorld();
|
||||||
|
Location loc = sender.getLocation();
|
||||||
|
|
||||||
|
if (name.length() > 16) name = name.substring(0, 16);
|
||||||
|
if (skin != null && skin.length() > 16) skin = skin.substring(0, 16);
|
||||||
|
|
||||||
|
sender.sendMessage("Creating " + (n == 1 ? "new bot" : ChatColor.RED + String.valueOf(n) + ChatColor.RESET + " new bots")
|
||||||
|
+ " with name " + ChatColor.GREEN + name
|
||||||
|
+ (skin == null ? "" : ChatColor.RESET + " and skin " + ChatColor.GREEN + skin) + ChatColor.RESET + "...");
|
||||||
|
|
||||||
|
skin = skin == null ? name : skin;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
Bot bot = Bot.createBot(loc, name, skin);
|
||||||
|
if (i > 0) bot.setVelocity(new Vector(Math.random() - 0.5, 0.5, Math.random() - 0.5).normalize().multiply(0.4));
|
||||||
|
}
|
||||||
|
|
||||||
|
world.spawnParticle(Particle.CLOUD, loc, 100, 1, 1, 1, 0.5);
|
||||||
|
|
||||||
|
double time = (System.currentTimeMillis() - timestamp) / 1000D;
|
||||||
|
|
||||||
|
sender.sendMessage("Process completed (" + ChatColor.RED + time + "s" + ChatColor.RESET + ").");
|
||||||
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
for (Bot bot : bots) {
|
for (Bot bot : bots) {
|
||||||
bot.despawn();
|
bot.despawn();
|
||||||
|
|||||||
@@ -11,15 +11,24 @@ import net.nuggetmc.ai.commands.CommandHandler;
|
|||||||
import net.nuggetmc.ai.commands.CommandInstance;
|
import net.nuggetmc.ai.commands.CommandInstance;
|
||||||
import net.nuggetmc.ai.utils.ChatUtils;
|
import net.nuggetmc.ai.utils.ChatUtils;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class PlayerAICommand extends CommandInstance {
|
public class PlayerAICommand extends CommandInstance {
|
||||||
|
|
||||||
|
private BotManager manager;
|
||||||
|
|
||||||
public PlayerAICommand(CommandHandler commandHandler) {
|
public PlayerAICommand(CommandHandler commandHandler) {
|
||||||
super(commandHandler);
|
super(commandHandler);
|
||||||
|
|
||||||
|
this.manager = PlayerAI.getInstance().getManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "", desc = "The PlayerAI main command.")
|
@Command(name = "", desc = "The PlayerAI main command.")
|
||||||
@@ -38,25 +47,36 @@ public class PlayerAICommand extends CommandInstance {
|
|||||||
@Command(name = "create", desc = "Create bots.", usage = "<name> [skin]")
|
@Command(name = "create", desc = "Create bots.", usage = "<name> [skin]")
|
||||||
@Require("playerai.manage")
|
@Require("playerai.manage")
|
||||||
public void createBotCommand(@Sender Player sender, String name, @OptArg String skin) {
|
public void createBotCommand(@Sender Player sender, String name, @OptArg String skin) {
|
||||||
// make 16 character limit on name
|
manager.createBots(sender, name, skin, 1);
|
||||||
Bot.createBot(name, sender.getLocation(), skin == null ? name : skin);
|
}
|
||||||
|
|
||||||
|
@Command(name = "multi", desc = "Create multiple bots at once.", usage = "<amount> <name> [skin]")
|
||||||
|
@Require("playerai.manage")
|
||||||
|
public void multiBotCommand(@Sender Player sender, int n, String name, @OptArg String skin) {
|
||||||
|
manager.createBots(sender, name, skin, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "debug", desc = "Debug bot stats.")
|
@Command(name = "debug", desc = "Debug bot stats.")
|
||||||
@Require("playerai.manage")
|
@Require("playerai.manage")
|
||||||
public void debugCommand(@Sender Player sender) {
|
public void debugCommand(@Sender Player sender) {
|
||||||
// This will be used for miscellaneous code for testing as the plugin is worked on
|
// This will be used for miscellaneous code for testing as the plugin is worked on
|
||||||
|
|
||||||
|
Location loc = sender.getLocation();
|
||||||
|
|
||||||
|
for (Bot bot : PlayerAI.getInstance().getManager().fetch()) {
|
||||||
|
bot.faceLocation(loc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "info", desc = "Information about loaded bots.")
|
@Command(name = "info", desc = "Information about loaded bots.")
|
||||||
@Require("playerai.manage")
|
@Require("playerai.manage")
|
||||||
public void infoCommand(@Sender Player sender) {
|
public void infoCommand(@Sender Player player) {
|
||||||
// This will be the future GUI where players can view information about every loaded bot
|
// This will be the future GUI where players can view information about every loaded bot
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "reset", desc = "Remove all loaded bots.")
|
@Command(name = "reset", desc = "Remove all loaded bots.")
|
||||||
@Require("playerai.manage")
|
@Require("playerai.manage")
|
||||||
public void resetCommand(@Sender Player sender) {
|
public void resetCommand(@Sender CommandSender sender) {
|
||||||
sender.sendMessage("Removing every bot...");
|
sender.sendMessage("Removing every bot...");
|
||||||
|
|
||||||
BotManager manager = PlayerAI.getInstance().getManager();
|
BotManager manager = PlayerAI.getInstance().getManager();
|
||||||
|
|||||||
30
src/main/java/net/nuggetmc/ai/utils/MathUtils.java
Normal file
30
src/main/java/net/nuggetmc/ai/utils/MathUtils.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package net.nuggetmc.ai.utils;
|
||||||
|
|
||||||
|
import org.bukkit.util.NumberConversions;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class MathUtils {
|
||||||
|
|
||||||
|
public static float[] fetchYawPitch(Vector dir) {
|
||||||
|
double x = dir.getX();
|
||||||
|
double z = dir.getZ();
|
||||||
|
|
||||||
|
float[] out = new float[2];
|
||||||
|
|
||||||
|
if (x == 0.0D && z == 0.0D) {
|
||||||
|
out[1] = (float) (dir.getY() > 0.0D ? -90 : 90);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
double theta = Math.atan2(-x, z);
|
||||||
|
out[0] = (float) Math.toDegrees((theta + 6.283185307179586D) % 6.283185307179586D);
|
||||||
|
|
||||||
|
double x2 = NumberConversions.square(x);
|
||||||
|
double z2 = NumberConversions.square(z);
|
||||||
|
double xz = Math.sqrt(x2 + z2);
|
||||||
|
out[1] = (float) Math.toDegrees(Math.atan(-dir.getY() / xz));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,12 +6,25 @@ import com.google.gson.JsonParser;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class MojangAPI {
|
public class MojangAPI {
|
||||||
|
|
||||||
// Eventually create some sort of cache that stores the skin data so it doesn't have to keep pulling from the API
|
private static final Map<String, String[]> CACHE = new HashMap<>();
|
||||||
// CATCHING NULLPOINTEREXCEPTION BAD!!!! eventually fix from the getAsJsonObject thingy
|
|
||||||
public static String[] getSkin(String name) {
|
public static String[] getSkin(String name) {
|
||||||
|
if (CACHE.containsKey(name)) {
|
||||||
|
return CACHE.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] values = pullFromAPI(name);
|
||||||
|
CACHE.put(name, values);
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CATCHING NULLPOINTEREXCEPTION BAD!!!! eventually fix from the getAsJsonObject thingy
|
||||||
|
public static String[] pullFromAPI(String name) {
|
||||||
try {
|
try {
|
||||||
String uuid = new JsonParser().parse(new InputStreamReader(new URL("https://api.mojang.com/users/profiles/minecraft/" + name)
|
String uuid = new JsonParser().parse(new InputStreamReader(new URL("https://api.mojang.com/users/profiles/minecraft/" + name)
|
||||||
.openStream())).getAsJsonObject().get("id").getAsString();
|
.openStream())).getAsJsonObject().get("id").getAsString();
|
||||||
@@ -19,7 +32,7 @@ public class MojangAPI {
|
|||||||
.parse(new InputStreamReader(new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false")
|
.parse(new InputStreamReader(new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false")
|
||||||
.openStream())).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
|
.openStream())).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
|
||||||
return new String[] {property.get("value").getAsString(), property.get("signature").getAsString()};
|
return new String[] {property.get("value").getAsString(), property.get("signature").getAsString()};
|
||||||
} catch (IOException | NullPointerException e) {
|
} catch (IOException | IllegalStateException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user