mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 20:44:08 +00:00
Merge branch 'dev' into dev
This commit is contained in:
799 files changed
+49724
-13791
No files matched your search
@@ -172,7 +172,7 @@ public class CmdClone extends ChMcLogger {
|
||||
entity.setPosition(posX + 0.5, posY + 1, posZ + 0.5);
|
||||
if(entity instanceof EntityNPCInterface){
|
||||
EntityNPCInterface npc = (EntityNPCInterface) entity;
|
||||
npc.ai.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
npc.ais.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
if(newname != null && !newname.isEmpty())
|
||||
npc.display.name = newname.replaceAll("%", " "); // like name, newname must use % in place of space to keep a logical way
|
||||
}
|
||||
@@ -274,7 +274,7 @@ public class CmdClone extends ChMcLogger {
|
||||
entity.setPosition(posX + 0.5 + x, yy + 1, posZ + 0.5 + z);
|
||||
if(entity instanceof EntityNPCInterface){
|
||||
EntityNPCInterface npc = (EntityNPCInterface) entity;
|
||||
npc.ai.startPos = new int[]{xx, yy, zz};
|
||||
npc.ais.startPos = new int[]{xx, yy, zz};
|
||||
if(newname != null && !newname.isEmpty())
|
||||
npc.display.name = newname.replaceAll("%", " "); // like name, newname must use % in place of space to keep a logical way
|
||||
}
|
||||
|
||||
@@ -5,15 +5,16 @@ import foxz.commandhelper.annotations.Command;
|
||||
import foxz.commandhelper.annotations.SubCommand;
|
||||
import foxz.commandhelper.permissions.OpOnly;
|
||||
import foxz.commandhelper.permissions.PlayerOnly;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumConfigOperation;
|
||||
import kamkeel.npcs.network.packets.data.ConfigCommandPacket;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockIce;
|
||||
import net.minecraft.block.BlockLeavesBase;
|
||||
import net.minecraft.block.BlockVine;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.Server;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.constants.EnumPacketClient;
|
||||
import noppes.npcs.controllers.ChunkController;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -207,6 +208,6 @@ public class CmdConfig extends ChMcLogger {
|
||||
for(int i = 0; i < args.length; i++){
|
||||
font += " " + args[i];
|
||||
}
|
||||
Server.sendData((EntityPlayerMP)this.pcParam, EnumPacketClient.CONFIG, 0, font.trim(), size);
|
||||
PacketHandler.Instance.sendToPlayer(new ConfigCommandPacket(EnumConfigOperation.FONT, font.trim(), size), (EntityPlayerMP)this.pcParam);
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import foxz.commandhelper.annotations.Command;
|
||||
import foxz.commandhelper.annotations.SubCommand;
|
||||
import foxz.commandhelper.permissions.OpOnly;
|
||||
import foxz.commandhelper.permissions.ParamCheck;
|
||||
import kamkeel.npcs.controllers.SyncController;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import noppes.npcs.NoppesUtilServer;
|
||||
import noppes.npcs.client.EntityUtil;
|
||||
import noppes.npcs.controllers.DialogController;
|
||||
import noppes.npcs.controllers.SyncController;
|
||||
import noppes.npcs.controllers.data.Dialog;
|
||||
import noppes.npcs.controllers.data.DialogOption;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class CmdNpc extends ChMcLogger {
|
||||
posZ = CommandBase.func_110666_a(pcParam, selectedNpc.posZ, args[2]);
|
||||
}
|
||||
|
||||
selectedNpc.ai.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
selectedNpc.ais.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
@@ -144,7 +144,7 @@ public class CmdNpc extends ChMcLogger {
|
||||
if(args.length > 0)
|
||||
npc.display.name = args[0];
|
||||
npc.setPositionAndRotation(player.posX, player.posY, player.posZ, player.cameraYaw, player.cameraPitch);
|
||||
npc.ai.startPos = new int[]{MathHelper.floor_double(player.posX),MathHelper.floor_double(player.posY),MathHelper.floor_double(player.posZ)};
|
||||
npc.ais.startPos = new int[]{MathHelper.floor_double(player.posX),MathHelper.floor_double(player.posY),MathHelper.floor_double(player.posZ)};
|
||||
pw.spawnEntityInWorld(npc);
|
||||
npc.setHealth(npc.getMaxHealth());
|
||||
NoppesUtilServer.sendOpenGui(player, EnumGuiType.MainMenuDisplay, npc);
|
||||
|
||||
@@ -5,11 +5,11 @@ import foxz.commandhelper.annotations.Command;
|
||||
import foxz.commandhelper.annotations.SubCommand;
|
||||
import foxz.commandhelper.permissions.OpOnly;
|
||||
import foxz.commandhelper.permissions.ParamCheck;
|
||||
import kamkeel.npcs.controllers.SyncController;
|
||||
import kamkeel.npcs.network.packets.data.AchievementPacket;
|
||||
import kamkeel.npcs.network.packets.data.ChatAlertPacket;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import noppes.npcs.Server;
|
||||
import noppes.npcs.constants.EnumPacketClient;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.SyncController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.controllers.data.Quest;
|
||||
import noppes.npcs.controllers.data.QuestData;
|
||||
@@ -58,8 +58,8 @@ public class CmdQuest extends ChMcLogger{
|
||||
playerdata.questData.activeQuests.put(questid, questdata);
|
||||
playerdata.save();
|
||||
if(playerdata.player != null){
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.MESSAGE, "quest.newquest", quest.title);
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.CHAT, "quest.newquest", ": ", quest.title);
|
||||
AchievementPacket.sendAchievement((EntityPlayerMP) playerdata.player, false, "quest.newquest", quest.title);
|
||||
ChatAlertPacket.sendChatAlert((EntityPlayerMP) playerdata.player, "quest.newquest", ": ", quest.title);
|
||||
}
|
||||
playerdata.updateClient = true;
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
package kamkeel.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.scripted.CustomNPCsException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandKamkeel extends CommandBase{
|
||||
|
||||
public Map<String, CommandKamkeelBase> map = new HashMap<String, CommandKamkeelBase>();
|
||||
public HelpCommand help = new HelpCommand(this);
|
||||
public String[] alias = {"kam"};
|
||||
|
||||
public CommandKamkeel(){
|
||||
registerCommand(help);
|
||||
registerCommand(new ScriptCommand());
|
||||
registerCommand(new SlayCommand());
|
||||
registerCommand(new QuestCommand());
|
||||
registerCommand(new QuestCategoryCommand());
|
||||
registerCommand(new DialogCommand());
|
||||
registerCommand(new DialogCategoryCommand());
|
||||
registerCommand(new FactionCommand());
|
||||
registerCommand(new NpcCommand());
|
||||
registerCommand(new CloneCommand());
|
||||
registerCommand(new ConfigCommand());
|
||||
registerCommand(new AnimationCommand());
|
||||
registerCommand(new OverlayCommand());
|
||||
registerCommand(new CommandCommand());
|
||||
}
|
||||
|
||||
public void registerCommand(CommandKamkeelBase command){
|
||||
String name = command.getCommandName().toLowerCase();
|
||||
if(map.containsKey(name))
|
||||
throw new CustomNPCsException("Already a subcommand with the name: " + name);
|
||||
map.put(name, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "kamkeel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getCommandAliases()
|
||||
{
|
||||
return Arrays.asList(alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "Use as /kamkeel subcommand";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length == 0){
|
||||
help.processCommand(sender, args);
|
||||
return;
|
||||
}
|
||||
|
||||
CommandKamkeelBase command = getCommand(args);
|
||||
if(command == null)
|
||||
throw new CommandException("Unknown command " + args[0]);
|
||||
|
||||
args = Arrays.copyOfRange(args, 1, args.length);
|
||||
if(command.subcommands.isEmpty() || !command.runSubCommands()){
|
||||
if(!canSendCommand(sender, command))
|
||||
throw new CommandException("You are not allowed to use this command: " + command);
|
||||
command.canRun(sender, command.getUsage(), args);
|
||||
command.processCommand(sender, args);
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 0){
|
||||
help.processCommand(sender, new String[]{command.getCommandName()});
|
||||
return;
|
||||
}
|
||||
|
||||
command.processSubCommand(sender, args[0], Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender sender, String[] args){
|
||||
if(args.length == 1)
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, map.keySet().toArray(new String[map.size()]));
|
||||
CommandKamkeelBase command = getCommand(args);
|
||||
if(command == null)
|
||||
return null;
|
||||
if(args.length == 2 && command.runSubCommands())
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, command.subcommands.keySet().toArray(new String[command.subcommands.keySet().size()]));
|
||||
String[] useArgs = command.getUsage().split(" ");
|
||||
if(command.runSubCommands()) {
|
||||
Method m = command.subcommands.get(args[1].toLowerCase());
|
||||
if(m != null) {
|
||||
useArgs = m.getAnnotation(CommandKamkeelBase.SubCommand.class).usage().split(" ");
|
||||
}
|
||||
}
|
||||
if(args.length <= useArgs.length + 2) {
|
||||
if(args.length - 3 >= 0){
|
||||
String usage = useArgs[args.length - 3];
|
||||
if(usage.equals("<player>") || usage.equals("[player]")) {
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, MinecraftServer.getServer().getAllUsernames());
|
||||
}
|
||||
}
|
||||
}
|
||||
return command.addTabCompletionOptions(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
public CommandKamkeelBase getCommand(String[] args){
|
||||
if(args.length == 0)
|
||||
return null;
|
||||
return map.get(args[0].toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel(){
|
||||
return 2;
|
||||
}
|
||||
|
||||
public static String getCommandPermission(String command){
|
||||
return "cnpc.kamkeel." + command.toLowerCase();
|
||||
}
|
||||
|
||||
public static String getUniversalPermission(){
|
||||
return "cnpc.kamkeel.*";
|
||||
}
|
||||
|
||||
public static boolean canSendCommand(ICommandSender sender, CommandKamkeelBase command){
|
||||
if(sender.canCommandSenderUseCommand(command.getRequiredPermissionLevel(), getUniversalPermission())){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sender.canCommandSenderUseCommand(command.getRequiredPermissionLevel(), getCommandPermission(command.getCommandName()))){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sender instanceof EntityPlayer){
|
||||
return CustomNpcsPermissions.hasCustomPermission((EntityPlayer) sender, getCommandPermission(command.getCommandName()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
package kamkeel.command.profile;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class CommandHelpProfile extends CommandProfileBase {
|
||||
private CommandProfile parent;
|
||||
|
||||
public CommandHelpProfile(CommandProfile parent){
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "help";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "help [command]";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length == 0){
|
||||
sendMessage(sender, "\u00A78------ \u00A7aProfile Commands \u00A78------");
|
||||
for(Entry<String, CommandProfileBase> entry : parent.map.entrySet()){
|
||||
sendMessage(sender, "\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + entry.getValue().getCommandUsage(sender));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CommandProfileBase command = parent.getCommand(args);
|
||||
if(command == null){
|
||||
sendError(sender, "Unknown command " + args[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(command.subcommands.isEmpty()){
|
||||
sender.addChatMessage(new ChatComponentTranslation(command.getCommandUsage(sender)));
|
||||
return;
|
||||
}
|
||||
|
||||
Method m = null;
|
||||
if(args.length > 1){
|
||||
m = command.subcommands.get(args[1].toLowerCase());
|
||||
}
|
||||
if(m == null){
|
||||
sendMessage(sender, "\u00A78------ \u00A7a" + command.getCommandName().toUpperCase() + " SubCommands \u00A78------");
|
||||
sendMessage(sender, "\u00A77Usage: \u00A76" + command.getUsage());
|
||||
for(Entry<String, Method> entry : command.subcommands.entrySet()){
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + entry.getValue().getAnnotation(SubCommand.class).desc()));
|
||||
}
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + CommandProfile.getCommandPermission(command.getCommandName())));
|
||||
}
|
||||
else{
|
||||
sendMessage(sender, "\u00A78------ \u00A7b" + command.getCommandName().toUpperCase() + "." + args[1].toUpperCase() + " Command \u00A78------");
|
||||
SubCommand sc = m.getAnnotation(SubCommand.class);
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A77" + sc.desc()));
|
||||
if(!sc.usage().isEmpty())
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A77Usage: \u00A76" + sc.usage()));
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + getSubCommandPermission(args[1])));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package kamkeel.command.profile;
|
||||
|
||||
import kamkeel.controllers.ProfileController;
|
||||
import kamkeel.controllers.data.Profile;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
public class CommandProfileChange extends CommandProfileBase {
|
||||
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "change";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "change profiles";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "<number>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runSubCommands(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)){
|
||||
sendError(sender, "This command can only be sent by a player");
|
||||
return;
|
||||
}
|
||||
|
||||
int slotID;
|
||||
try {
|
||||
slotID = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number: " + args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Check if the player has permission to switch to this slot
|
||||
EntityPlayerMP player = (EntityPlayerMP) sender;
|
||||
|
||||
Profile profile = ProfileController.activeProfiles.get(player.getUniqueID());
|
||||
if(profile == null){
|
||||
sendError(sender, "Could not find a valid profile file");
|
||||
return;
|
||||
}
|
||||
|
||||
ProfileController.changePlayerSlot(player, slotID);
|
||||
// TODO: Add Cooldown to successful operation
|
||||
sendResult(sender, String.format("Switched to Slot \u00A7b%d\u00A77", slotID));
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
package kamkeel.controllers;
|
||||
|
||||
import kamkeel.controllers.data.IProfileData;
|
||||
import kamkeel.controllers.data.Profile;
|
||||
import kamkeel.controllers.data.Slot;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.util.CustomNPCsThreader;
|
||||
import noppes.npcs.util.NBTJsonUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ProfileController {
|
||||
|
||||
public static HashMap<String, IProfileData> profileTypes;
|
||||
public static HashMap<UUID, Profile> activeProfiles;
|
||||
|
||||
public static String profile_directory = "profiles";
|
||||
|
||||
public ProfileController(){
|
||||
profileTypes = new HashMap<>();
|
||||
activeProfiles = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register during ServerStartEvent()
|
||||
*
|
||||
* @param type - IProfile Type to always Save/Load
|
||||
* @return true/false if profile was successfully added
|
||||
*/
|
||||
public static boolean registerProfileType(IProfileData type){
|
||||
if(profileTypes.containsKey(type.getTagName()))
|
||||
return false;
|
||||
|
||||
profileTypes.put(type.getTagName(), type);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static File getProfileDir(){
|
||||
try{
|
||||
File file = new File(CustomNpcs.getWorldSaveDirectory(), profile_directory);
|
||||
if(!file.exists())
|
||||
file.mkdir();
|
||||
return file;
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void login(EntityPlayer player){
|
||||
if(player == null)
|
||||
return;
|
||||
|
||||
Profile profile;
|
||||
if(activeProfiles.containsKey(player.getUniqueID())){
|
||||
profile = activeProfiles.get(player.getUniqueID());
|
||||
profile.player = player;
|
||||
} else {
|
||||
NBTTagCompound profileCompound = load(player);
|
||||
profile = new Profile(player, profileCompound);
|
||||
activeProfiles.put(player.getUniqueID(), profile);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized NBTTagCompound load(EntityPlayer player) {
|
||||
File saveDir = getProfileDir();
|
||||
String filename = player.getUniqueID().toString();
|
||||
filename += ".dat";
|
||||
try {
|
||||
File file = new File(saveDir, filename);
|
||||
if(file.exists()){
|
||||
return NBTJsonUtil.loadNBTData(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogWriter.error("Error loading profile file: " + filename, e);
|
||||
}
|
||||
return new NBTTagCompound();
|
||||
}
|
||||
|
||||
public static synchronized void save(EntityPlayer player, Profile profile) {
|
||||
CustomNPCsThreader.customNPCThread.execute(() -> {
|
||||
final NBTTagCompound compound = profile.writeToNBT();
|
||||
final String filename = player.getUniqueID() + ".dat";
|
||||
try {
|
||||
File saveDir = getProfileDir();
|
||||
File file = new File(saveDir, filename + "_new");
|
||||
File file1 = new File(saveDir, filename);
|
||||
CompressedStreamTools.writeCompressed(compound, new FileOutputStream(file));
|
||||
if(file1.exists()){
|
||||
file1.delete();
|
||||
}
|
||||
file.renameTo(file1);
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void changeSlot(EntityPlayer player, int slotNumber){
|
||||
if(!activeProfiles.containsKey(player.getUniqueID()))
|
||||
return;
|
||||
|
||||
Profile profile = activeProfiles.get(player.getUniqueID());
|
||||
if(profile.currentID == slotNumber)
|
||||
return;
|
||||
|
||||
// Saves Current Slot Data
|
||||
saveSlotData(player);
|
||||
|
||||
// Sets Player to New Slot
|
||||
changePlayerSlot(player, slotNumber);
|
||||
|
||||
// Save Slot File
|
||||
save(player, profile);
|
||||
}
|
||||
|
||||
public static void saveSlotData(EntityPlayer player){
|
||||
if(!activeProfiles.containsKey(player.getUniqueID()))
|
||||
return;
|
||||
|
||||
NBTTagCompound dataCompound;
|
||||
Slot slot;
|
||||
|
||||
Profile profile = activeProfiles.get(player.getUniqueID());
|
||||
if(!profile.slots.isEmpty() && profile.slots.containsKey(profile.currentID)){
|
||||
slot = profile.slots.get(profile.currentID);
|
||||
dataCompound = (NBTTagCompound) slot.getCompound().copy();
|
||||
} else {
|
||||
slot = new Slot(profile.currentID, "Slot " + profile.currentID);
|
||||
dataCompound = new NBTTagCompound();
|
||||
slot.setCompound(dataCompound);
|
||||
}
|
||||
|
||||
for(IProfileData profileData : profileTypes.values()){
|
||||
NBTTagCompound cloned = (NBTTagCompound) profileData.getCurrentNBT(player).copy();
|
||||
dataCompound.setTag(profileData.getTagName(), cloned);
|
||||
}
|
||||
|
||||
slot.setCompound(dataCompound);
|
||||
}
|
||||
|
||||
public static void changePlayerSlot(EntityPlayer player, int id){
|
||||
if(!activeProfiles.containsKey(player.getUniqueID()))
|
||||
return;
|
||||
|
||||
NBTTagCompound slotCompound;
|
||||
Slot slot;
|
||||
Profile profile = activeProfiles.get(player.getUniqueID());
|
||||
if(!profile.slots.isEmpty() && profile.slots.containsKey(id)){
|
||||
slot = profile.slots.get(id);
|
||||
slotCompound = (NBTTagCompound) slot.getCompound().copy();
|
||||
} else {
|
||||
slot = new Slot(id, "Slot " + id);
|
||||
slotCompound = new NBTTagCompound();
|
||||
slot.setCompound(slotCompound);
|
||||
}
|
||||
|
||||
slot.setLastLoaded(System.currentTimeMillis());
|
||||
profile.slots.put(id, slot);
|
||||
|
||||
for(IProfileData profileData : profileTypes.values()){
|
||||
profileData.setNBT(player, slotCompound.getCompoundTag(profileData.getTagName()));
|
||||
profileData.save(player);
|
||||
}
|
||||
|
||||
profile.currentID = id;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package kamkeel.controllers.data;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
|
||||
public class CNPCData implements IProfileData {
|
||||
|
||||
@Override
|
||||
public String getTagName() {
|
||||
return "CustomNPC+";
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getCurrentNBT(EntityPlayer player) {
|
||||
PlayerData customNPCData = PlayerData.get(player);
|
||||
return customNPCData.getNBT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(EntityPlayer player) {
|
||||
PlayerData customNPCData = PlayerData.get(player);
|
||||
customNPCData.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNBT(EntityPlayer player, NBTTagCompound replace) {
|
||||
PlayerData customNPCData = PlayerData.get(player);
|
||||
if(replace.hasNoTags()){
|
||||
PlayerData newData = new PlayerData();
|
||||
newData.player = player;
|
||||
customNPCData.setNBT((NBTTagCompound) newData.getNBT().copy());
|
||||
}
|
||||
else {
|
||||
customNPCData.setNBT(replace);
|
||||
}
|
||||
customNPCData.updateClient = true;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package kamkeel.controllers.data;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public interface IProfileData {
|
||||
|
||||
/**
|
||||
* Do not use the tag: - Name, lastLoaded, ID
|
||||
*
|
||||
* @return The Save Tag utilized in the Profile
|
||||
*/
|
||||
public String getTagName();
|
||||
|
||||
/**
|
||||
* @return NBTTagCompound of their Current Data for a given Entity Player
|
||||
*/
|
||||
public NBTTagCompound getCurrentNBT(EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Called immediately after setNBT() Replaces existing NBT
|
||||
*/
|
||||
public void save(EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Replaces their Current Data operation when changing Profiles
|
||||
*/
|
||||
public void setNBT(EntityPlayer player, NBTTagCompound replace);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package kamkeel.controllers.data;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
public class Profile {
|
||||
|
||||
public EntityPlayer player;
|
||||
public int currentID;
|
||||
public HashMap<Integer, Slot> slots = new HashMap<>();
|
||||
|
||||
public Profile(EntityPlayer player, NBTTagCompound compound){
|
||||
this.player = player;
|
||||
if(compound.hasKey("CurrentID")){
|
||||
this.currentID = compound.getInteger("CurrentID");
|
||||
} else {
|
||||
this.currentID = 1;
|
||||
}
|
||||
|
||||
if (compound.hasKey("Slots")) {
|
||||
// Load Slots
|
||||
NBTTagCompound slotsCompound = compound.getCompoundTag("Slots");
|
||||
for (String key : (Set<String>) slotsCompound.func_150296_c()) {
|
||||
int slotID = Integer.parseInt(key);
|
||||
NBTTagCompound slotNBT = slotsCompound.getCompoundTag(key);
|
||||
Slot slot = Slot.fromNBT(slotID, slotNBT);
|
||||
slots.put(slotID, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNBT() {
|
||||
NBTTagCompound fullCompound = new NBTTagCompound();
|
||||
|
||||
if(this.player != null)
|
||||
fullCompound.setString("Name", player.getCommandSenderName());
|
||||
fullCompound.setInteger("CurrentID", currentID);
|
||||
|
||||
if(!slots.isEmpty()){
|
||||
NBTTagCompound slotsCompound = new NBTTagCompound();
|
||||
for (HashMap.Entry<Integer, Slot> entry : slots.entrySet()) {
|
||||
int id = entry.getKey();
|
||||
Slot slot = entry.getValue();
|
||||
slot.setId(id);
|
||||
|
||||
NBTTagCompound slotTag = slot.toNBT();
|
||||
slotsCompound.setTag(String.valueOf(id), slotTag);
|
||||
}
|
||||
|
||||
fullCompound.setTag("Slots", slotsCompound);
|
||||
}
|
||||
return fullCompound;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package kamkeel.controllers.data;
|
||||
|
||||
import kamkeel.controllers.ProfileController;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class Slot {
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private long lastLoaded;
|
||||
private NBTTagCompound compound;
|
||||
|
||||
public Slot(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Slot(int id, String name, NBTTagCompound compound, long last) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.compound = compound;
|
||||
this.lastLoaded = last;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getLastLoaded() {
|
||||
return lastLoaded;
|
||||
}
|
||||
|
||||
public void setLastLoaded(long lastLoaded) {
|
||||
this.lastLoaded = lastLoaded;
|
||||
}
|
||||
|
||||
public NBTTagCompound getCompound() {
|
||||
return compound;
|
||||
}
|
||||
|
||||
public void setCompound(NBTTagCompound compound) {
|
||||
this.compound = compound;
|
||||
}
|
||||
|
||||
public NBTTagCompound toNBT() {
|
||||
NBTTagCompound slotNBT = new NBTTagCompound();
|
||||
slotNBT.setString("Name", name);
|
||||
slotNBT.setLong("LastLoaded", lastLoaded);
|
||||
slotNBT.setTag("Data", compound);
|
||||
return slotNBT;
|
||||
}
|
||||
|
||||
public static Slot fromNBT(int id, NBTTagCompound slotNBT) {
|
||||
String name = slotNBT.getString("Name");
|
||||
long lastLoaded = slotNBT.getLong("LastLoaded");
|
||||
NBTTagCompound compound = slotNBT.getCompoundTag("Data");
|
||||
return new Slot(id, name, compound, lastLoaded);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package kamkeel.network;
|
||||
|
||||
import kamkeel.network.enums.EnumPacketType;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketChannel {
|
||||
|
||||
private String channelName;
|
||||
private EnumPacketType channelType;
|
||||
|
||||
public Map<Integer, AbstractPacket> packets = new Hashtable<>();
|
||||
|
||||
public PacketChannel(String channelName, EnumPacketType channelType) {
|
||||
this.channelName = channelName;
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public String getChannelName() {
|
||||
return channelName;
|
||||
}
|
||||
|
||||
public void setChannelName(String channelName) {
|
||||
this.channelName = channelName;
|
||||
}
|
||||
|
||||
public EnumPacketType getChannelType() {
|
||||
return channelType;
|
||||
}
|
||||
|
||||
public void setChannelType(EnumPacketType channelType) {
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public void registerPacket(Enum ord, AbstractPacket packet) {
|
||||
this.packets.put(ord.ordinal(), packet);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package kamkeel.network;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.network.FMLEventChannel;
|
||||
import cpw.mods.fml.common.network.FMLNetworkEvent;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.network.enums.EnumPacketType;
|
||||
import kamkeel.util.ByteBufUtils;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public final class PacketHandler {
|
||||
public static PacketHandler Instance;
|
||||
|
||||
public Map<EnumPacketType, FMLEventChannel> channels = new Hashtable<>();
|
||||
|
||||
public final static PacketChannel INFO_PACKET = new PacketChannel("CNPC+|Info", EnumPacketType.INFO);
|
||||
public final static PacketChannel DATA_PACKET = new PacketChannel("CNPC+|Data", EnumPacketType.DATA);
|
||||
public final static PacketChannel CLIENT_PACKET = new PacketChannel("CNPC+|Client", EnumPacketType.CLIENT);
|
||||
public final static PacketChannel LARGE_PACKET = new PacketChannel("CNPC+|Large", EnumPacketType.LARGE);
|
||||
|
||||
public final static List<PacketChannel> packetChannels = new ArrayList<>();
|
||||
|
||||
public PacketHandler() {
|
||||
// Register Channels
|
||||
packetChannels.add(INFO_PACKET);
|
||||
packetChannels.add(DATA_PACKET);
|
||||
packetChannels.add(CLIENT_PACKET);
|
||||
this.registerChannels();
|
||||
|
||||
// Register Info Packets
|
||||
|
||||
// Register Data Packets
|
||||
|
||||
// Register Client Packets
|
||||
|
||||
// Register Packets
|
||||
// map.put(PingPacket.packetName, new PingPacket());
|
||||
}
|
||||
|
||||
public void registerChannels() {
|
||||
FMLEventChannel eventChannel;
|
||||
for (PacketChannel channel : packetChannels) {
|
||||
eventChannel = NetworkRegistry.INSTANCE.newEventDrivenChannel(channel.getChannelName());
|
||||
eventChannel.register(this);
|
||||
channels.put(channel.getChannelType(), eventChannel);
|
||||
}
|
||||
}
|
||||
|
||||
public PacketChannel getPacketChannel(EnumPacketType type){
|
||||
PacketChannel packetChannel;
|
||||
switch (type){
|
||||
case DATA:
|
||||
packetChannel = DATA_PACKET;
|
||||
break;
|
||||
case INFO:
|
||||
packetChannel = INFO_PACKET;
|
||||
break;
|
||||
case LARGE:
|
||||
packetChannel = LARGE_PACKET;
|
||||
break;
|
||||
default:
|
||||
packetChannel = CLIENT_PACKET;
|
||||
break;
|
||||
}
|
||||
return packetChannel;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package kamkeel.network.enums;
|
||||
|
||||
public enum EnumClientPacket {
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package kamkeel.network.enums;
|
||||
|
||||
public enum EnumDataPacket {
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package kamkeel.network.enums;
|
||||
|
||||
public enum EnumInfoPacket {
|
||||
LOGIN,
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package kamkeel.network.enums;
|
||||
|
||||
public enum EnumPacketType {
|
||||
INFO, DATA, CLIENT, LARGE
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package kamkeel.network.packets;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.network.AbstractPacket;
|
||||
import kamkeel.network.PacketChannel;
|
||||
import kamkeel.network.PacketHandler;
|
||||
import kamkeel.network.enums.EnumInfoPacket;
|
||||
import kamkeel.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class LoginPacket extends AbstractPacket {
|
||||
public static final String packetName = "CNPC+|LoginPacket";
|
||||
|
||||
public LoginPacket() {}
|
||||
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumInfoPacket.LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.INFO_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
// ByteBufUtils.writeUTF8String(out, this.data.player.getCommandSenderName());
|
||||
// ByteBufUtils.writeNBT(out,this.data.saveFromNBT(new NBTTagCompound()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
String playerName = ByteBufUtils.readUTF8String(in);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package kamkeel.npcs;
|
||||
|
||||
import kamkeel.npcs.controllers.AttributeController;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeValueType;
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.types.QuestActiveRequirement;
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.types.QuestCompletedRequirement;
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
|
||||
|
||||
/**
|
||||
* ModAttributes registers the core attributes (both non–magic and magic–based).
|
||||
*/
|
||||
public class CustomAttributes {
|
||||
public static final String HEALTH_KEY = "health";
|
||||
public static final String MAIN_ATTACK_KEY = "main_attack";
|
||||
public static final String MAIN_ATTACK_BOOST_KEY = "main_attack_boost";
|
||||
public static final String NEUTRAL_KEY = "neutral";
|
||||
public static final String NEUTRAL_BOOST_KEY = "neutral_boost";
|
||||
public static final String CRITICAL_DAMAGE_KEY = "critical_damage";
|
||||
public static final String CRITICAL_CHANCE_KEY = "critical_chance";
|
||||
public static final String MAGIC_DAMAGE_KEY = "magic_damage";
|
||||
public static final String MAGIC_BOOST_KEY = "magic_boost";
|
||||
public static final String MAGIC_DEFENSE_KEY = "magic_defense";
|
||||
public static final String MAGIC_RESISTANCE_KEY = "magic_resistance";
|
||||
|
||||
|
||||
public static AttributeDefinition MAIN_ATTACK;
|
||||
public static AttributeDefinition MAIN_BOOST;
|
||||
public static AttributeDefinition NEUTRAL_ATTACK;
|
||||
public static AttributeDefinition NEUTRAL_BOOST;
|
||||
|
||||
public static AttributeDefinition HEALTH;
|
||||
public static AttributeDefinition CRITICAL_CHANCE;
|
||||
public static AttributeDefinition CRITICAL_DAMAGE;
|
||||
|
||||
public static AttributeDefinition MAGIC_DAMAGE;
|
||||
public static AttributeDefinition MAGIC_BOOST;
|
||||
public static AttributeDefinition MAGIC_DEFENSE;
|
||||
public static AttributeDefinition MAGIC_RESISTANCE;
|
||||
|
||||
public CustomAttributes(){
|
||||
HEALTH = AttributeController.registerAttribute(HEALTH_KEY, "Health", 'c', AttributeValueType.FLAT, AttributeDefinition.AttributeSection.BASE);
|
||||
|
||||
MAIN_ATTACK = AttributeController.registerAttribute(MAIN_ATTACK_KEY, "Main Attack Damage", '4', AttributeValueType.FLAT, AttributeDefinition.AttributeSection.BASE);
|
||||
MAIN_BOOST = AttributeController.registerAttribute(MAIN_ATTACK_BOOST_KEY, "Main Attack Damage", '4', AttributeValueType.PERCENT, AttributeDefinition.AttributeSection.MODIFIER);
|
||||
|
||||
NEUTRAL_ATTACK = AttributeController.registerAttribute(NEUTRAL_KEY, "Neutral Damage", '6', AttributeValueType.FLAT, AttributeDefinition.AttributeSection.BASE);
|
||||
NEUTRAL_BOOST = AttributeController.registerAttribute(NEUTRAL_BOOST_KEY, "Neutral Damage", '6', AttributeValueType.PERCENT, AttributeDefinition.AttributeSection.MODIFIER);
|
||||
|
||||
CRITICAL_CHANCE = AttributeController.registerAttribute(CRITICAL_CHANCE_KEY, "Critical Chance", '6', AttributeValueType.PERCENT, AttributeDefinition.AttributeSection.INFO);
|
||||
CRITICAL_DAMAGE = AttributeController.registerAttribute(CRITICAL_DAMAGE_KEY, "Critical Damage", '6', AttributeValueType.FLAT, AttributeDefinition.AttributeSection.INFO);
|
||||
|
||||
MAGIC_DAMAGE = AttributeController.registerAttribute(MAGIC_DAMAGE_KEY, "Magic Damage", '3', AttributeValueType.MAGIC, AttributeDefinition.AttributeSection.BASE);
|
||||
MAGIC_BOOST = AttributeController.registerAttribute(MAGIC_BOOST_KEY, "Magic Damage", '3', AttributeValueType.MAGIC, AttributeDefinition.AttributeSection.MODIFIER);
|
||||
|
||||
MAGIC_DEFENSE = AttributeController.registerAttribute(MAGIC_DEFENSE_KEY, "Magic Defense", 'b', AttributeValueType.MAGIC, AttributeDefinition.AttributeSection.BASE);
|
||||
MAGIC_RESISTANCE = AttributeController.registerAttribute(MAGIC_RESISTANCE_KEY, "Magic Resistance", 'b', AttributeValueType.MAGIC, AttributeDefinition.AttributeSection.MODIFIER);
|
||||
|
||||
|
||||
// TODO: Attributes
|
||||
// Durability Attribute
|
||||
// Unique Name Attribute
|
||||
|
||||
// Requirement
|
||||
RequirementCheckerRegistry.registerChecker(new QuestCompletedRequirement());
|
||||
RequirementCheckerRegistry.registerChecker(new QuestActiveRequirement());
|
||||
|
||||
// TODO: Requirements
|
||||
// Player Requirement : Soulbound UUID
|
||||
// Profile Requirement : Slot Number
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package kamkeel.addon;
|
||||
package kamkeel.npcs.addon;
|
||||
|
||||
import kamkeel.addon.client.DBCClient;
|
||||
import kamkeel.addon.client.GeckoAddonClient;
|
||||
import kamkeel.npcs.addon.client.DBCClient;
|
||||
import kamkeel.npcs.addon.client.GeckoAddonClient;
|
||||
|
||||
public class AddonManager {
|
||||
public static AddonManager Instance;
|
||||
+6
-2
@@ -1,6 +1,6 @@
|
||||
package kamkeel.addon;
|
||||
package kamkeel.npcs.addon;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -22,6 +22,10 @@ public class DBCAddon {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static boolean IsAvailable() {
|
||||
return Loader.isModLoaded("npcdbc");
|
||||
}
|
||||
|
||||
public void dbcCopyData(EntityLivingBase copied, EntityLivingBase entity){}
|
||||
|
||||
// AI / STATS
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package kamkeel.addon;
|
||||
package kamkeel.npcs.addon;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
||||
@@ -17,4 +17,4 @@ public class GeckoAddon {
|
||||
|
||||
public void geckoCopyData(EntityLivingBase copied, EntityLivingBase entity){}
|
||||
|
||||
}
|
||||
}
|
||||
+1
-10
@@ -1,15 +1,9 @@
|
||||
package kamkeel.addon.client;
|
||||
package kamkeel.npcs.addon.client;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import noppes.npcs.client.gui.mainmenu.GuiNpcStats;
|
||||
import noppes.npcs.client.gui.model.GuiCreationScreen;
|
||||
import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory;
|
||||
import noppes.npcs.client.gui.util.GuiNPCInterface2;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.model.ModelMPM;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
public class DBCClient {
|
||||
@@ -39,7 +33,4 @@ public class DBCClient {
|
||||
public GuiNPCInterface2 manageCustomForms(EntityNPCInterface npcInterface){ return null; }
|
||||
// Manage Custom Forms
|
||||
public GuiNPCInterface2 manageCustomAuras(EntityNPCInterface npcInterface){ return null; }
|
||||
|
||||
// Inventory GUI
|
||||
public GuiCNPCInventory inventoryGUI(){ return null; }
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package kamkeel.addon.client;
|
||||
package kamkeel.npcs.addon.client;
|
||||
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -9,6 +9,9 @@ import noppes.npcs.controllers.data.PlayerData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class AnimationCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,245 @@
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import kamkeel.npcs.controllers.AttributeController;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeValueType;
|
||||
import kamkeel.npcs.util.AttributeItemUtil;
|
||||
import noppes.npcs.controllers.MagicController;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class AttributeCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "attribute";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Manage attributes on your held item";
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
name = "list",
|
||||
usage = "[page]",
|
||||
desc = "Lists all available attributes"
|
||||
)
|
||||
public void list(ICommandSender sender, String[] args) throws CommandException {
|
||||
// Get all registered attributes.
|
||||
List<AttributeDefinition> defs = new ArrayList<AttributeDefinition>(AttributeController.getAllAttributes());
|
||||
if(defs.isEmpty()){
|
||||
sendError(sender, "No attributes found.");
|
||||
return;
|
||||
}
|
||||
// Sort attributes by display name.
|
||||
Collections.sort(defs, new Comparator<AttributeDefinition>() {
|
||||
@Override
|
||||
public int compare(AttributeDefinition a, AttributeDefinition b) {
|
||||
return a.getKey().compareToIgnoreCase(b.getKey());
|
||||
}
|
||||
});
|
||||
|
||||
// Determine which page to show.
|
||||
int page = 1;
|
||||
if(args.length > 0) {
|
||||
try {
|
||||
page = Integer.parseInt(args[0]);
|
||||
} catch(NumberFormatException e) {
|
||||
// If parsing fails, default to page 1.
|
||||
}
|
||||
}
|
||||
int perPage = 10;
|
||||
int total = defs.size();
|
||||
int totalPages = (int)Math.ceil(total / (double) perPage);
|
||||
if(page < 1) page = 1;
|
||||
if(page > totalPages) page = totalPages;
|
||||
int startIndex = (page - 1) * perPage;
|
||||
int endIndex = Math.min(startIndex + perPage, total);
|
||||
|
||||
sendResult(sender, "--------------------");
|
||||
sendResult(sender, "Attributes (Page " + page + "/" + totalPages + "):");
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
AttributeDefinition def = defs.get(i);
|
||||
// First line: numbered display name.
|
||||
sendResult(sender, (i + 1) + ". " + def.getDisplayName());
|
||||
// Second line: key and value type.
|
||||
sendResult(sender, " - " + def.getKey() + ", " + def.getValueType());
|
||||
}
|
||||
sendResult(sender, "--------------------");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
name = "apply",
|
||||
usage = "<attribute> <value> [magicID]",
|
||||
desc = "Applies an attribute to your held item. For magic attributes, provide a magicID."
|
||||
)
|
||||
public void apply(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)){
|
||||
sendError(sender, "Only players can use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
ItemStack held = player.getHeldItem();
|
||||
if(held == null){
|
||||
sendError(sender, "You are not holding an item.");
|
||||
return;
|
||||
}
|
||||
|
||||
String attrKey = args[0];
|
||||
AttributeDefinition def = AttributeController.getAttribute(attrKey);
|
||||
if(def == null){
|
||||
sendError(sender, "Unknown attribute: " + attrKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is a magic attribute.
|
||||
if(def.getValueType() == AttributeValueType.MAGIC) {
|
||||
if(args.length < 3){
|
||||
sendError(sender, "Usage for magic attribute: apply <attribute> <value> <magicID>");
|
||||
return;
|
||||
}
|
||||
int magicId;
|
||||
float value;
|
||||
try {
|
||||
value = Float.parseFloat(args[1]);
|
||||
magicId = Integer.parseInt(args[2]);
|
||||
} catch(NumberFormatException e) {
|
||||
sendError(sender, "Invalid number format for magicID or value.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(MagicController.getInstance().getMagic(magicId) == null){
|
||||
sendError(sender, "No Magic Found for Magic ID %d", magicId);
|
||||
return;
|
||||
}
|
||||
|
||||
AttributeItemUtil.writeMagicAttribute(held, attrKey, magicId, value);
|
||||
sendResult(sender, "Applied magic attribute " + attrKey + " with magicID " + magicId + " and value " + value + " to held item.");
|
||||
} else {
|
||||
if(args.length < 2){
|
||||
sendError(sender, "Usage: <attribute> <value>");
|
||||
return;
|
||||
}
|
||||
float value;
|
||||
try {
|
||||
value = Float.parseFloat(args[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
sendError(sender, "Invalid number format for value.");
|
||||
return;
|
||||
}
|
||||
AttributeItemUtil.applyAttribute(held, attrKey, value);
|
||||
sendResult(sender, "Applied attribute " + attrKey + " with value " + value + " to held item.");
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
name = "remove",
|
||||
usage = "<attribute> [magicID)",
|
||||
desc = "Removes an attribute from your held item. For magic attributes, provide a magicID."
|
||||
)
|
||||
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)){
|
||||
sendError(sender, "Only players can use this command.");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
ItemStack held = player.getHeldItem();
|
||||
if(held == null){
|
||||
sendError(sender, "You are not holding an item.");
|
||||
return;
|
||||
}
|
||||
|
||||
String attrKey = args[0];
|
||||
AttributeDefinition def = AttributeController.getAttribute(attrKey);
|
||||
if(def == null){
|
||||
sendError(sender, "Unknown attribute: " + attrKey);
|
||||
return;
|
||||
}
|
||||
|
||||
if(def.getValueType() == AttributeValueType.MAGIC) {
|
||||
if(args.length < 2){
|
||||
sendError(sender, "Usage for magic attribute: remove <attribute> <magicID>");
|
||||
return;
|
||||
}
|
||||
int magicId;
|
||||
try {
|
||||
magicId = Integer.parseInt(args[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
sendError(sender, "Invalid magicID format.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(MagicController.getInstance().getMagic(magicId) == null){
|
||||
sendError(sender, "No Magic Found for Magic ID %d", magicId);
|
||||
return;
|
||||
}
|
||||
|
||||
AttributeItemUtil.removeMagicAttribute(held, attrKey, magicId);
|
||||
sendResult(sender, "Removed magic attribute " + attrKey + " (magicID " + magicId + ") from held item.");
|
||||
} else {
|
||||
AttributeItemUtil.removeAttribute(held, attrKey);
|
||||
sendResult(sender, "Removed attribute " + attrKey + " from held item.");
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
name = "requirement",
|
||||
usage = "<apply|remove> <requirement> [value]",
|
||||
desc = "Apply or remove a requirement from your held item."
|
||||
)
|
||||
public void requirement(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "Only players can use this command.");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer) sender;
|
||||
ItemStack held = player.getHeldItem();
|
||||
if (held == null) {
|
||||
sendError(sender, "You are not holding an item.");
|
||||
return;
|
||||
}
|
||||
if (args.length < 2) {
|
||||
sendError(sender, "Usage: requirement <apply|remove> <requirementKey> [value]");
|
||||
return;
|
||||
}
|
||||
String action = args[0];
|
||||
String reqKey = args[1];
|
||||
if (action.equalsIgnoreCase("apply")) {
|
||||
if (args.length < 3) {
|
||||
sendError(sender, "Usage: requirement apply <requirementKey> <value>");
|
||||
return;
|
||||
}
|
||||
String valueStr = args[2];
|
||||
Object value;
|
||||
try {
|
||||
value = Integer.parseInt(valueStr);
|
||||
} catch (NumberFormatException e1) {
|
||||
try {
|
||||
value = Float.parseFloat(valueStr);
|
||||
} catch (NumberFormatException e2) {
|
||||
value = valueStr;
|
||||
}
|
||||
}
|
||||
|
||||
AttributeItemUtil.applyRequirement(held, reqKey, value);
|
||||
sendResult(sender, "Applied requirement " + reqKey + " with value " + value + " to held item.");
|
||||
} else if (action.equalsIgnoreCase("remove")) {
|
||||
AttributeItemUtil.removeRequirement(held, reqKey);
|
||||
sendResult(sender, "Removed requirement " + reqKey + " from held item.");
|
||||
} else {
|
||||
sendError(sender, "Invalid action. Use apply or remove.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-10
@@ -1,8 +1,7 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import foxz.utils.Utils;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -18,6 +17,8 @@ import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.*;
|
||||
|
||||
public class CloneCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
@@ -180,9 +181,9 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
return;
|
||||
}
|
||||
try{
|
||||
posX = CommandBase.func_110666_a(sender, posX, par[0]);
|
||||
posY = CommandBase.func_110665_a(sender, posY, par[1].trim(), 0, 0);
|
||||
posZ = CommandBase.func_110666_a(sender, posZ, par[2]);
|
||||
posX = func_110666_a(sender, posX, par[0]);
|
||||
posY = func_110665_a(sender, posY, par[1].trim(), 0, 0);
|
||||
posZ = func_110666_a(sender, posZ, par[2]);
|
||||
} catch(NumberFormatException ex){
|
||||
sendError(sender, "Location should be in numbers");
|
||||
return;
|
||||
@@ -204,7 +205,7 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
entity.setPosition(posX + 0.5, posY + 1, posZ + 0.5);
|
||||
if(entity instanceof EntityNPCInterface){
|
||||
EntityNPCInterface npc = (EntityNPCInterface) entity;
|
||||
npc.ai.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
npc.ais.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
if(newname != null && !newname.isEmpty())
|
||||
npc.display.name = newname.replaceAll("%", " "); // like name, newname must use % in place of space to keep a logical way
|
||||
}
|
||||
@@ -272,9 +273,9 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
return;
|
||||
}
|
||||
try{
|
||||
posX = CommandBase.func_110666_a(sender, posX, par[0]);
|
||||
posY = CommandBase.func_110665_a(sender, posY, par[1].trim(), 0, 0);
|
||||
posZ = CommandBase.func_110666_a(sender, posZ, par[2]);
|
||||
posX = func_110666_a(sender, posX, par[0]);
|
||||
posY = func_110665_a(sender, posY, par[1].trim(), 0, 0);
|
||||
posZ = func_110666_a(sender, posZ, par[2]);
|
||||
} catch(NumberFormatException ex){
|
||||
sendError(sender, "Location should be in numbers");
|
||||
return;
|
||||
@@ -310,7 +311,7 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
entity.setPosition(posX + 0.5 + x, yy + 1, posZ + 0.5 + z);
|
||||
if(entity instanceof EntityNPCInterface){
|
||||
EntityNPCInterface npc = (EntityNPCInterface) entity;
|
||||
npc.ai.startPos = new int[]{xx, yy, zz};
|
||||
npc.ais.startPos = new int[]{xx, yy, zz};
|
||||
if(newname != null && !newname.isEmpty())
|
||||
npc.display.name = newname.replaceAll("%", " "); // like name, newname must use % in place of space to keep a logical way
|
||||
}
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -10,6 +10,9 @@ import noppes.npcs.api.IWorld;
|
||||
import noppes.npcs.scripted.NpcAPI;
|
||||
import noppes.npcs.scripted.event.CustomNPCsEvent;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendMessage;
|
||||
|
||||
public class CommandCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,173 @@
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import kamkeel.npcs.controllers.AttributeController;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.scripted.CustomNPCsException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
import static kamkeel.npcs.command.EffectCommand.getSortedEffectNames;
|
||||
|
||||
public class CommandKamkeel extends CommandBase{
|
||||
|
||||
public Map<String, CommandKamkeelBase> map = new HashMap<String, CommandKamkeelBase>();
|
||||
public HelpCommand help = new HelpCommand(this);
|
||||
public String[] alias = {"kam"};
|
||||
|
||||
public CommandKamkeel(){
|
||||
registerCommand(help);
|
||||
registerCommand(new ScriptCommand());
|
||||
registerCommand(new SlayCommand());
|
||||
registerCommand(new QuestCommand());
|
||||
registerCommand(new QuestCategoryCommand());
|
||||
registerCommand(new DialogCommand());
|
||||
registerCommand(new DialogCategoryCommand());
|
||||
registerCommand(new FactionCommand());
|
||||
registerCommand(new NpcCommand());
|
||||
registerCommand(new CloneCommand());
|
||||
registerCommand(new ConfigCommand());
|
||||
registerCommand(new AnimationCommand());
|
||||
registerCommand(new OverlayCommand());
|
||||
registerCommand(new CommandCommand());
|
||||
registerCommand(new EffectCommand());
|
||||
if(ConfigMain.AttributesEnabled)
|
||||
registerCommand(new AttributeCommand());
|
||||
}
|
||||
|
||||
public void registerCommand(CommandKamkeelBase command){
|
||||
String name = command.getCommandName().toLowerCase();
|
||||
if(map.containsKey(name))
|
||||
throw new CustomNPCsException("Already a subcommand with the name: " + name);
|
||||
map.put(name, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "kamkeel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getCommandAliases()
|
||||
{
|
||||
return Arrays.asList(alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "Use as /kamkeel subcommand";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length == 0){
|
||||
help.processCommand(sender, args);
|
||||
return;
|
||||
}
|
||||
|
||||
CommandKamkeelBase command = getCommand(args);
|
||||
if(command == null)
|
||||
throw new CommandException("Unknown command " + args[0]);
|
||||
|
||||
args = Arrays.copyOfRange(args, 1, args.length);
|
||||
if(command.subcommands.isEmpty() || !command.runSubCommands()){
|
||||
if(!canSendCommand(sender, command))
|
||||
throw new CommandException("You are not allowed to use this command: " + command);
|
||||
command.canRun(sender, command.getUsage(), args);
|
||||
command.processCommand(sender, args);
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 0){
|
||||
help.processCommand(sender, new String[]{command.getCommandName()});
|
||||
return;
|
||||
}
|
||||
|
||||
command.processSubCommand(sender, args[0], Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender sender, String[] args){
|
||||
if(args.length == 1)
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, map.keySet().toArray(new String[map.size()]));
|
||||
CommandKamkeelBase command = getCommand(args);
|
||||
if(command == null)
|
||||
return null;
|
||||
if(args.length == 2 && command.runSubCommands())
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, command.subcommands.keySet().toArray(new String[command.subcommands.keySet().size()]));
|
||||
String[] useArgs = command.getUsage().split(" ");
|
||||
if(command.runSubCommands()) {
|
||||
Method m = command.subcommands.get(args[1].toLowerCase());
|
||||
if(m != null) {
|
||||
useArgs = m.getAnnotation(CommandKamkeelBase.SubCommand.class).usage().split(" ");
|
||||
}
|
||||
}
|
||||
if(args.length <= useArgs.length + 2) {
|
||||
if(args.length - 3 >= 0){
|
||||
String usage = useArgs[args.length - 3];
|
||||
if(usage.equals("<player>") || usage.equals("[player]")) {
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, MinecraftServer.getServer().getAllUsernames());
|
||||
}
|
||||
else if(usage.equals("<attribute>")) {
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (AttributeDefinition def : AttributeController.getAllAttributes()) {
|
||||
keys.add(def.getKey());
|
||||
}
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, keys.toArray(new String[keys.size()]));
|
||||
} else if (usage.equals("<requirement>")) {
|
||||
List<String> keys = new ArrayList<>(RequirementCheckerRegistry.getAllKeys());
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, keys.toArray(new String[keys.size()]));
|
||||
} else if(usage.equals("<effectName>")){
|
||||
List<String> keys = getSortedEffectNames();
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, keys.toArray(new String[keys.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return command.addTabCompletionOptions(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
public CommandKamkeelBase getCommand(String[] args){
|
||||
if(args.length == 0)
|
||||
return null;
|
||||
return map.get(args[0].toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel(){
|
||||
return 2;
|
||||
}
|
||||
|
||||
public static String getCommandPermission(String command){
|
||||
return "cnpc.kamkeel." + command.toLowerCase();
|
||||
}
|
||||
|
||||
public static String getUniversalPermission(){
|
||||
return "cnpc.kamkeel.*";
|
||||
}
|
||||
|
||||
public static boolean canSendCommand(ICommandSender sender, CommandKamkeelBase command){
|
||||
if(sender.canCommandSenderUseCommand(command.getRequiredPermissionLevel(), getUniversalPermission())){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sender.canCommandSenderUseCommand(command.getRequiredPermissionLevel(), getCommandPermission(command.getCommandName()))){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sender instanceof EntityPlayer){
|
||||
return CustomNpcsPermissions.hasCustomPermission((EntityPlayer) sender, getCommandPermission(command.getCommandName()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-14
@@ -1,10 +1,9 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -55,18 +54,6 @@ public abstract class CommandKamkeelBase extends CommandBase{
|
||||
return !subcommands.isEmpty();
|
||||
}
|
||||
|
||||
protected static void sendMessage(ICommandSender sender, String message, Object... obs) {
|
||||
sender.addChatMessage(new ChatComponentTranslation(message, obs));
|
||||
}
|
||||
|
||||
protected static void sendResult(ICommandSender sender, String message, Object... obs) {
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A77 " + message, obs));
|
||||
}
|
||||
|
||||
protected static void sendError(ICommandSender sender, String message, Object... obs) {
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A74 Error:\u00A7c " + message, obs));
|
||||
}
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface SubCommand {
|
||||
+8
-5
@@ -1,6 +1,9 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import foxz.utils.Market;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumConfigOperation;
|
||||
import kamkeel.npcs.network.packets.data.ConfigCommandPacket;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockIce;
|
||||
import net.minecraft.block.BlockLeavesBase;
|
||||
@@ -10,15 +13,16 @@ import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.Server;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.constants.EnumPacketClient;
|
||||
import noppes.npcs.controllers.ChunkController;
|
||||
import noppes.npcs.controllers.PlayerDataController;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class ConfigCommand extends CommandKamkeelBase {
|
||||
|
||||
|
||||
@@ -291,8 +295,7 @@ public class ConfigCommand extends CommandKamkeelBase {
|
||||
for(int i = 0; i < args.length; i++){
|
||||
font += " " + args[i];
|
||||
}
|
||||
Server.sendData((EntityPlayerMP)sender, EnumPacketClient.CONFIG, 0, font.trim(), size);
|
||||
PacketHandler.Instance.sendToPlayer(new ConfigCommandPacket(EnumConfigOperation.FONT, font.trim(), size), (EntityPlayerMP)sender);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -11,6 +11,9 @@ import noppes.npcs.controllers.data.PlayerData;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class DialogCategoryCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
+5
-2
@@ -1,5 +1,6 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import kamkeel.npcs.controllers.SyncController;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -10,7 +11,6 @@ import noppes.npcs.constants.EnumAvailabilityDialog;
|
||||
import noppes.npcs.constants.EnumAvailabilityQuest;
|
||||
import noppes.npcs.controllers.DialogController;
|
||||
import noppes.npcs.controllers.PlayerDataController;
|
||||
import noppes.npcs.controllers.SyncController;
|
||||
import noppes.npcs.controllers.data.Availability;
|
||||
import noppes.npcs.controllers.data.Dialog;
|
||||
import noppes.npcs.controllers.data.DialogOption;
|
||||
@@ -20,6 +20,9 @@ import noppes.npcs.entity.EntityDialogNpc;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class DialogCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,345 @@
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import noppes.npcs.controllers.CustomEffectController;
|
||||
import noppes.npcs.controllers.PlayerDataController;
|
||||
import noppes.npcs.controllers.data.CustomEffect;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.scripted.event.PlayerEvent.EffectEvent.ExpirationType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class EffectCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Custom Effect operations";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "effect";
|
||||
}
|
||||
|
||||
// List command with pagination
|
||||
@SubCommand(desc = "Lists all Effects", usage = "[page]")
|
||||
public void list(ICommandSender sender, String[] args) throws CommandException {
|
||||
CustomEffectController controller = CustomEffectController.getInstance();
|
||||
if (controller.indexMapper.isEmpty()) {
|
||||
sendError(sender, "No effects found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Flatten effects into a list
|
||||
List<EffectEntry> effectsList = new ArrayList<>();
|
||||
for (Map.Entry<Integer, HashMap<Integer, CustomEffect>> entry : controller.indexMapper.entrySet()) {
|
||||
int idx = entry.getKey();
|
||||
Map<Integer, CustomEffect> effects = entry.getValue();
|
||||
if (effects == null || effects.isEmpty())
|
||||
continue;
|
||||
for (Map.Entry<Integer, CustomEffect> effectEntry : effects.entrySet()) {
|
||||
int id = effectEntry.getKey();
|
||||
CustomEffect effect = effectEntry.getValue();
|
||||
effectsList.add(new EffectEntry(idx, id, effect));
|
||||
}
|
||||
}
|
||||
// Sort by index then by effect ID
|
||||
Collections.sort(effectsList, Comparator.comparingInt((EffectEntry e) -> e.index)
|
||||
.thenComparingInt(e -> e.id));
|
||||
|
||||
// Determine page number
|
||||
int page = 1;
|
||||
if (args.length > 0) {
|
||||
try {
|
||||
page = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
// default to page 1
|
||||
}
|
||||
}
|
||||
int perPage = 10;
|
||||
int total = effectsList.size();
|
||||
int totalPages = (int) Math.ceil(total / (double) perPage);
|
||||
if (page < 1) page = 1;
|
||||
if (page > totalPages) page = totalPages;
|
||||
int startIndex = (page - 1) * perPage;
|
||||
int endIndex = Math.min(startIndex + perPage, total);
|
||||
|
||||
sendResult(sender, "--------------------");
|
||||
sendResult(sender, "Effects (Page " + page + "/" + totalPages + "):");
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
EffectEntry entry = effectsList.get(i);
|
||||
sendResult(sender, String.format("\u00a7b%s \u00a77(ID: %d, INDEX: %d)",
|
||||
entry.effect.getName(),
|
||||
entry.id,
|
||||
entry.index));
|
||||
}
|
||||
sendResult(sender, "--------------------");
|
||||
}
|
||||
|
||||
|
||||
// Give effect by name.
|
||||
// Usage: <player> <time> <effectName>
|
||||
@SubCommand(desc = "Gives an effect to a player", usage = "<player> <time> <effectName>")
|
||||
public void give(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 3) {
|
||||
sendError(sender, "Usage: <player> <time> <effectName>");
|
||||
return;
|
||||
}
|
||||
|
||||
String playername = args[0];
|
||||
int time;
|
||||
try {
|
||||
time = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
sendError(sender, "Invalid time: " + args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Join all remaining arguments as the effect name.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 2; i < args.length; i++) {
|
||||
sb.append(args[i]).append(i < args.length - 1 ? " " : "");
|
||||
}
|
||||
String effectName = sb.toString();
|
||||
|
||||
List<EffectEntry> matches = findEffectsByName(effectName);
|
||||
if (matches.isEmpty()) {
|
||||
sendError(sender, "Unknown effect: " + effectName);
|
||||
return;
|
||||
}
|
||||
if (matches.size() > 1) {
|
||||
StringBuilder ambig = new StringBuilder();
|
||||
ambig.append("Ambiguous effect name '").append(effectName).append("'. Multiple matches: ");
|
||||
for (EffectEntry match : matches) {
|
||||
ambig.append(match.effect.getName())
|
||||
.append(" (ID: ").append(match.id)
|
||||
.append(", INDEX: ").append(match.index)
|
||||
.append("), ");
|
||||
}
|
||||
sendError(sender, ambig.substring(0, ambig.length() - 2));
|
||||
return;
|
||||
}
|
||||
EffectEntry match = matches.get(0);
|
||||
|
||||
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
||||
if (players.isEmpty()) {
|
||||
sendError(sender, "Unknown player: " + playername);
|
||||
return;
|
||||
}
|
||||
|
||||
for (PlayerData pdata : players) {
|
||||
CustomEffectController.getInstance().applyEffect(pdata.player, match.id, time, (byte) 1, match.index);
|
||||
sendResult(sender, String.format("%s §agiven to §7'§b%s§7'", match.effect.getName(), pdata.playername));
|
||||
if (sender != pdata.player) {
|
||||
sendResult(pdata.player, String.format("Effect §7%s §aadded.", match.effect.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove effect by name.
|
||||
// Usage: <player> <effectName>
|
||||
@SubCommand(desc = "Removes an effect from a player", usage = "<player> <effectName>")
|
||||
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 2) {
|
||||
sendError(sender, "Usage: <player> <effectName>");
|
||||
return;
|
||||
}
|
||||
|
||||
String playername = args[0];
|
||||
// Join all remaining arguments as the effect name.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
sb.append(args[i]).append(i < args.length - 1 ? " " : "");
|
||||
}
|
||||
String effectName = sb.toString();
|
||||
|
||||
List<EffectEntry> matches = findEffectsByName(effectName);
|
||||
if (matches.isEmpty()) {
|
||||
sendError(sender, "Unknown effect: " + effectName);
|
||||
return;
|
||||
}
|
||||
if (matches.size() > 1) {
|
||||
StringBuilder ambig = new StringBuilder();
|
||||
ambig.append("Ambiguous effect name '").append(effectName).append("'. Multiple matches: ");
|
||||
for (EffectEntry match : matches) {
|
||||
ambig.append(match.effect.getName())
|
||||
.append(" (ID: ").append(match.id)
|
||||
.append(", INDEX: ").append(match.index)
|
||||
.append("), ");
|
||||
}
|
||||
sendError(sender, ambig.substring(0, ambig.length() - 2));
|
||||
return;
|
||||
}
|
||||
EffectEntry match = matches.get(0);
|
||||
|
||||
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
||||
if (players.isEmpty()) {
|
||||
sendError(sender, "Unknown player: " + playername);
|
||||
return;
|
||||
}
|
||||
|
||||
for (PlayerData pdata : players) {
|
||||
CustomEffectController.getInstance().removeEffect(pdata.player, match.id, match.index, ExpirationType.REMOVED);
|
||||
sendResult(sender, String.format("Effect %s removed from %s", match.effect.getName(), pdata.playername));
|
||||
}
|
||||
}
|
||||
|
||||
// Give effect by ID.
|
||||
// Usage: <player> <time> <effectId> [index]
|
||||
@SubCommand(desc = "Gives an effect to a player by ID", usage = "<player> <time> <effectId> [index]")
|
||||
public void giveId(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 3) {
|
||||
sendError(sender, "Usage: <player> <time> <effectId> [index]");
|
||||
return;
|
||||
}
|
||||
|
||||
String playername = args[0];
|
||||
int time;
|
||||
try {
|
||||
time = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
sendError(sender, "Invalid time: " + args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
int effectId;
|
||||
int index = 0;
|
||||
try {
|
||||
effectId = Integer.parseInt(args[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
sendError(sender, "Invalid effect ID: " + args[2]);
|
||||
return;
|
||||
}
|
||||
if (args.length > 3) {
|
||||
try {
|
||||
index = Integer.parseInt(args[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
||||
if (players.isEmpty()) {
|
||||
sendError(sender, "Unknown player: " + playername);
|
||||
return;
|
||||
}
|
||||
|
||||
CustomEffect effect = CustomEffectController.getInstance().get(effectId, index);
|
||||
if (effect == null) {
|
||||
sendError(sender, "Unknown effect with ID: " + effectId + " and index " + index);
|
||||
return;
|
||||
}
|
||||
|
||||
for (PlayerData pdata : players) {
|
||||
CustomEffectController.getInstance().applyEffect(pdata.player, effectId, time, (byte) 1, index);
|
||||
sendResult(sender, String.format("Effect %d given to %s", effectId, pdata.playername));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove effect by ID.
|
||||
// Usage: <player> <effectId> [index]
|
||||
@SubCommand(desc = "Removes an effect from a player by ID", usage = "<player> <effectId> [index]")
|
||||
public void removeId(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 2) {
|
||||
sendError(sender, "Usage: <player> <effectId> [index]");
|
||||
return;
|
||||
}
|
||||
|
||||
String playername = args[0];
|
||||
int effectId;
|
||||
int index = 0;
|
||||
try {
|
||||
effectId = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
sendError(sender, "Invalid effect ID: " + args[1]);
|
||||
return;
|
||||
}
|
||||
if (args.length > 2) {
|
||||
try {
|
||||
index = Integer.parseInt(args[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
||||
if (players.isEmpty()) {
|
||||
sendError(sender, "Unknown player: " + playername);
|
||||
return;
|
||||
}
|
||||
|
||||
CustomEffect effect = CustomEffectController.getInstance().get(effectId, index);
|
||||
if (effect == null) {
|
||||
sendError(sender, "Unknown effect with ID: " + effectId + " and index " + index);
|
||||
return;
|
||||
}
|
||||
|
||||
for (PlayerData pdata : players) {
|
||||
CustomEffectController.getInstance().removeEffect(pdata.player, effectId, index, ExpirationType.REMOVED);
|
||||
sendResult(sender, String.format("Effect %d removed from %s", effectId, pdata.playername));
|
||||
}
|
||||
}
|
||||
|
||||
private static class EffectEntry {
|
||||
int index;
|
||||
int id;
|
||||
CustomEffect effect;
|
||||
|
||||
public EffectEntry(int index, int id, CustomEffect effect) {
|
||||
this.index = index;
|
||||
this.id = id;
|
||||
this.effect = effect;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to find effects by name.
|
||||
private List<EffectEntry> findEffectsByName(String name) {
|
||||
List<EffectEntry> matches = new ArrayList<>();
|
||||
CustomEffectController controller = CustomEffectController.getInstance();
|
||||
for (Map.Entry<Integer, HashMap<Integer, CustomEffect>> entry : controller.indexMapper.entrySet()) {
|
||||
int idx = entry.getKey();
|
||||
Map<Integer, CustomEffect> effects = entry.getValue();
|
||||
if (effects == null) continue;
|
||||
for (Map.Entry<Integer, CustomEffect> effectEntry : effects.entrySet()) {
|
||||
int id = effectEntry.getKey();
|
||||
CustomEffect effect = effectEntry.getValue();
|
||||
if (effect.getName().equalsIgnoreCase(name)) {
|
||||
List<EffectEntry> exact = new ArrayList<>();
|
||||
exact.add(new EffectEntry(idx, id, effect));
|
||||
return exact;
|
||||
} else if (effect.getName().toLowerCase().contains(name.toLowerCase())) {
|
||||
matches.add(new EffectEntry(idx, id, effect));
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
public static List<String> getSortedEffectNames() {
|
||||
List<EffectEntry> entries = new ArrayList<>();
|
||||
CustomEffectController controller = CustomEffectController.getInstance();
|
||||
for (Map.Entry<Integer, HashMap<Integer, CustomEffect>> indexEntry : controller.indexMapper.entrySet()) {
|
||||
int index = indexEntry.getKey();
|
||||
Map<Integer, CustomEffect> effects = indexEntry.getValue();
|
||||
if (effects != null) {
|
||||
for (Map.Entry<Integer, CustomEffect> effectEntry : effects.entrySet()) {
|
||||
int id = effectEntry.getKey();
|
||||
CustomEffect effect = effectEntry.getValue();
|
||||
entries.add(new EffectEntry(index, id, effect));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort entries by index then by effect ID.
|
||||
entries.sort(Comparator.comparingInt((EffectEntry e) -> e.index)
|
||||
.thenComparingInt(e -> e.id));
|
||||
List<String> effectNames = new ArrayList<>();
|
||||
for (EffectEntry entry : entries) {
|
||||
effectNames.add(entry.effect.getName());
|
||||
}
|
||||
return effectNames;
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -1,6 +1,5 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import noppes.npcs.controllers.FactionController;
|
||||
@@ -12,6 +11,9 @@ import noppes.npcs.controllers.data.PlayerFactionData;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class FactionCommand extends CommandKamkeelBase {
|
||||
|
||||
public Faction selectedFaction;
|
||||
@@ -153,7 +155,7 @@ public class FactionCommand extends CommandKamkeelBase {
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender par1, String[] args) {
|
||||
if(args.length == 3){
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, new String[]{"add", "subtract", "set", "reset", "drop", "create"});
|
||||
return getListOfStringsMatchingLastWord(args, new String[]{"add", "subtract", "set", "reset", "drop", "create"});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
+10
-7
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -7,6 +7,9 @@ import net.minecraft.util.ChatComponentTranslation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendMessage;
|
||||
|
||||
public class HelpCommand extends CommandKamkeelBase{
|
||||
private CommandKamkeel parent;
|
||||
|
||||
@@ -42,7 +45,7 @@ public class HelpCommand extends CommandKamkeelBase{
|
||||
}
|
||||
|
||||
if(command.subcommands.isEmpty()){
|
||||
sender.addChatMessage(new ChatComponentTranslation(command.getCommandUsage(sender)));
|
||||
sendMessage(sender, (command.getCommandUsage(sender)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,17 +57,17 @@ public class HelpCommand extends CommandKamkeelBase{
|
||||
sendMessage(sender, "\u00A78------ \u00A7a" + command.getCommandName().toUpperCase() + " SubCommands \u00A78------");
|
||||
sendMessage(sender, "\u00A77Usage: \u00A76" + command.getUsage());
|
||||
for(Entry<String, Method> entry : command.subcommands.entrySet()){
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + entry.getValue().getAnnotation(SubCommand.class).desc()));
|
||||
sendMessage(sender, ("\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + entry.getValue().getAnnotation(SubCommand.class).desc()));
|
||||
}
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + CommandKamkeel.getCommandPermission(command.getCommandName())));
|
||||
sendMessage(sender, ("\u00A78Permission:\u00A77 " + CommandKamkeel.getCommandPermission(command.getCommandName())));
|
||||
}
|
||||
else{
|
||||
sendMessage(sender, "\u00A78------ \u00A7b" + command.getCommandName().toUpperCase() + "." + args[1].toUpperCase() + " Command \u00A78------");
|
||||
SubCommand sc = m.getAnnotation(SubCommand.class);
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A77" + sc.desc()));
|
||||
sendMessage(sender, ("\u00A77" + sc.desc()));
|
||||
if(!sc.usage().isEmpty())
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A77Usage: \u00A76" + sc.usage()));
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + getSubCommandPermission(args[1])));
|
||||
sendMessage(sender, ("\u00A77Usage: \u00A76" + sc.usage()));
|
||||
sendMessage(sender, ("\u00A78Permission:\u00A77 " + getSubCommandPermission(args[1])));
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
@@ -22,6 +22,9 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class NpcCommand extends CommandKamkeelBase {
|
||||
|
||||
public EntityNPCInterface selectedNpc;
|
||||
@@ -93,7 +96,7 @@ public class NpcCommand extends CommandKamkeelBase {
|
||||
posZ = CommandBase.func_110666_a(sender, selectedNpc.posZ, args[2]);
|
||||
}
|
||||
|
||||
selectedNpc.ai.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
selectedNpc.ais.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)};
|
||||
sendResult(sender, String.format("Set NPC \u00A7e%s\u00A77 Home to \u00A7b[%.1f] [%.1f] [%.1f]\u00A77", selectedNpc.display.name, posX, posY, posZ));
|
||||
}
|
||||
|
||||
@@ -199,7 +202,7 @@ public class NpcCommand extends CommandKamkeelBase {
|
||||
if(args.length > 0)
|
||||
npc.display.name = args[0];
|
||||
npc.setPositionAndRotation(player.posX, player.posY, player.posZ, player.cameraYaw, player.cameraPitch);
|
||||
npc.ai.startPos = new int[]{MathHelper.floor_double(player.posX),MathHelper.floor_double(player.posY),MathHelper.floor_double(player.posZ)};
|
||||
npc.ais.startPos = new int[]{MathHelper.floor_double(player.posX),MathHelper.floor_double(player.posY),MathHelper.floor_double(player.posZ)};
|
||||
pw.spawnEntityInWorld(npc);
|
||||
npc.setHealth(npc.getMaxHealth());
|
||||
NoppesUtilServer.sendOpenGui(player, EnumGuiType.MainMenuDisplay, npc);
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -9,6 +9,9 @@ import noppes.npcs.controllers.data.SkinOverlay;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class OverlayCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
+25
-13
@@ -1,12 +1,16 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.network.packets.data.AchievementPacket;
|
||||
import kamkeel.npcs.network.packets.data.ChatAlertPacket;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import noppes.npcs.Server;
|
||||
import noppes.npcs.constants.EnumPacketClient;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.constants.EnumProfileSync;
|
||||
import noppes.npcs.constants.EnumQuestRepeat;
|
||||
import noppes.npcs.controllers.PlayerDataController;
|
||||
import noppes.npcs.controllers.PlayerQuestController;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.controllers.data.Quest;
|
||||
@@ -16,6 +20,9 @@ import noppes.npcs.controllers.data.QuestData;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class QuestCategoryCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
@@ -82,19 +89,24 @@ public class QuestCategoryCommand extends CommandKamkeelBase {
|
||||
|
||||
int count = 0;
|
||||
for(PlayerData playerdata : data){
|
||||
count = 0;
|
||||
for(Quest quest : questCategory.quests.values()){
|
||||
if(playerdata.questData.activeQuests.containsKey(quest.id)){
|
||||
playerdata.questData.activeQuests.remove(quest.id);
|
||||
playerdata.questData.activeQuests.remove(quest.id);
|
||||
long completeTime;
|
||||
if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY || quest.repeat == EnumQuestRepeat.RLCUSTOM){
|
||||
completeTime = System.currentTimeMillis();
|
||||
playerdata.questData.finishedQuests.put(quest.id, completeTime);
|
||||
} else {
|
||||
completeTime = sender.getEntityWorld().getTotalWorldTime();
|
||||
playerdata.questData.finishedQuests.put(quest.id, completeTime);
|
||||
}
|
||||
|
||||
if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY)
|
||||
playerdata.questData.finishedQuests.put(quest.id, System.currentTimeMillis());
|
||||
else
|
||||
playerdata.questData.finishedQuests.put(quest.id, sender.getEntityWorld().getTotalWorldTime());
|
||||
if(ConfigMain.ProfilesEnabled && playerdata.player != null && quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared)
|
||||
ProfileController.Instance.shareQuestCompletion(playerdata.player, quest.id, completeTime);;
|
||||
|
||||
if(playerdata.player != null){
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.MESSAGE, "quest.completed", quest.title);
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.CHAT, "quest.completed", ": ", quest.title);
|
||||
AchievementPacket.sendAchievement((EntityPlayerMP) playerdata.player, false, "quest.completed", quest.title);
|
||||
ChatAlertPacket.sendChatAlert((EntityPlayerMP) playerdata.player, "quest.completed", ": ", quest.title);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
@@ -185,8 +197,8 @@ public class QuestCategoryCommand extends CommandKamkeelBase {
|
||||
count++;
|
||||
|
||||
if(playerdata.player != null && questData.sendAlerts){
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.MESSAGE, "quest.newquest", quest.title);
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.CHAT, "quest.newquest", ": ", quest.title);
|
||||
AchievementPacket.sendAchievement((EntityPlayerMP) playerdata.player, false, "quest.newquest", quest.title);
|
||||
ChatAlertPacket.sendChatAlert((EntityPlayerMP) playerdata.player, "quest.newquest", ": ", quest.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
-17
@@ -1,19 +1,20 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.SyncController;
|
||||
import kamkeel.npcs.network.packets.data.AchievementPacket;
|
||||
import kamkeel.npcs.network.packets.data.ChatAlertPacket;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import noppes.npcs.Server;
|
||||
import noppes.npcs.api.handler.data.IQuestObjective;
|
||||
import noppes.npcs.constants.EnumPacketClient;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.constants.EnumProfileSync;
|
||||
import noppes.npcs.constants.EnumQuestCompletion;
|
||||
import noppes.npcs.constants.EnumQuestRepeat;
|
||||
import noppes.npcs.controllers.PlayerDataController;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.SyncController;
|
||||
import noppes.npcs.controllers.data.Party;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.controllers.data.Quest;
|
||||
@@ -23,6 +24,9 @@ import noppes.npcs.util.ValueUtil;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class QuestCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
@@ -67,8 +71,8 @@ public class QuestCommand extends CommandKamkeelBase {
|
||||
playerdata.questData.activeQuests.put(questid, questdata);
|
||||
playerdata.save();
|
||||
if(playerdata.player != null && questdata.sendAlerts){
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.MESSAGE, "quest.newquest", quest.title);
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.CHAT, "quest.newquest", ": ", quest.title);
|
||||
AchievementPacket.sendAchievement((EntityPlayerMP) playerdata.player, false, "quest.newquest", quest.title);
|
||||
ChatAlertPacket.sendChatAlert((EntityPlayerMP) playerdata.player, "quest.newquest", ": ", quest.title);
|
||||
}
|
||||
playerdata.updateClient = true;
|
||||
sendResult(sender, String.format("Started Quest \u00A7e%d\u00A77 for Player '\u00A7b%s\u00A77'", questid, playerdata.playername));
|
||||
@@ -102,19 +106,23 @@ public class QuestCommand extends CommandKamkeelBase {
|
||||
return;
|
||||
}
|
||||
for(PlayerData playerdata : data){
|
||||
if(playerdata.questData.activeQuests.containsKey(questid)){
|
||||
playerdata.questData.activeQuests.remove(questid);
|
||||
playerdata.questData.activeQuests.remove(questid);
|
||||
long completeTime;
|
||||
if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY || quest.repeat == EnumQuestRepeat.RLCUSTOM){
|
||||
completeTime = System.currentTimeMillis();
|
||||
playerdata.questData.finishedQuests.put(quest.id, completeTime);
|
||||
} else {
|
||||
completeTime = sender.getEntityWorld().getTotalWorldTime();
|
||||
playerdata.questData.finishedQuests.put(quest.id, completeTime);
|
||||
}
|
||||
|
||||
if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY)
|
||||
playerdata.questData.finishedQuests.put(quest.id, System.currentTimeMillis());
|
||||
else
|
||||
playerdata.questData.finishedQuests.put(quest.id, sender.getEntityWorld().getTotalWorldTime());
|
||||
if(ConfigMain.ProfilesEnabled && playerdata.player != null && quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared)
|
||||
ProfileController.Instance.shareQuestCompletion(playerdata.player, quest.id, completeTime);
|
||||
|
||||
playerdata.save();
|
||||
if(playerdata.player != null){
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.MESSAGE, "quest.completed", quest.title);
|
||||
Server.sendData((EntityPlayerMP)playerdata.player, EnumPacketClient.CHAT, "quest.completed", ": ", quest.title);
|
||||
AchievementPacket.sendAchievement((EntityPlayerMP) playerdata.player, false, "quest.completed", quest.title);
|
||||
ChatAlertPacket.sendChatAlert((EntityPlayerMP) playerdata.player, "quest.completed", ": ", quest.title);
|
||||
}
|
||||
playerdata.updateClient = true;
|
||||
sendResult(sender, String.format("Finished Quest \u00A7e%d\u00A77 for Player '\u00A7b%s\u00A77'", questid, playerdata.playername));
|
||||
@@ -192,7 +200,7 @@ public class QuestCommand extends CommandKamkeelBase {
|
||||
usage = "<player> <quest> [objective] [value]"
|
||||
)
|
||||
public void objective(ICommandSender sender, String[] args) throws CommandException {
|
||||
EntityPlayer player = CommandBase.getPlayer(sender, args[0]);
|
||||
EntityPlayer player = getPlayer(sender, args[0]);
|
||||
int questid;
|
||||
try {
|
||||
questid = Integer.parseInt(args[1]);
|
||||
+4
-1
@@ -1,8 +1,11 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import noppes.npcs.controllers.ScriptController;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
|
||||
public class ScriptCommand extends CommandKamkeelBase {
|
||||
|
||||
+4
-3
@@ -1,6 +1,5 @@
|
||||
package kamkeel.command;
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -21,6 +20,8 @@ import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class SlayCommand extends CommandKamkeelBase {
|
||||
public Map<String, Class<?>> SlayMap = new LinkedHashMap<String, Class<?>>();
|
||||
|
||||
@@ -134,6 +135,6 @@ public class SlayCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender sender, String[] args){
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, SlayMap.keySet().toArray(new String[SlayMap.size()]));
|
||||
return getListOfStringsMatchingLastWord(args, SlayMap.keySet().toArray(new String[SlayMap.size()]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendMessage;
|
||||
|
||||
public class CommandHelpProfile extends CommandProfileBase {
|
||||
private CommandProfile parent;
|
||||
|
||||
public CommandHelpProfile(CommandProfile parent){
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "help";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "help [command]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length == 0){
|
||||
sendMessage(sender, "\u00A78------ \u00A7aProfile Commands \u00A78------");
|
||||
for(Entry<String, CommandProfileBase> entry : parent.map.entrySet()){
|
||||
sendMessage(sender, "\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77"
|
||||
+ entry.getValue().getCommandUsage(sender));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CommandProfileBase command = parent.getCommand(args);
|
||||
if(command == null){
|
||||
sendError(sender, "Unknown command " + args[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(command.subcommands.isEmpty()){
|
||||
sendMessage(sender, (command.getCommandUsage(sender)));
|
||||
return;
|
||||
}
|
||||
|
||||
Method m = null;
|
||||
if(args.length > 1){
|
||||
m = command.subcommands.get(args[1].toLowerCase());
|
||||
}
|
||||
if(m == null){
|
||||
sendMessage(sender, "\u00A78------ \u00A7a" + command.getCommandName().toUpperCase()
|
||||
+ " SubCommands \u00A78------");
|
||||
sendMessage(sender, "\u00A77Usage: \u00A76" + command.getUsage());
|
||||
for(Entry<String, Method> entry : command.subcommands.entrySet()){
|
||||
SubCommand sc = entry.getValue().getAnnotation(SubCommand.class);
|
||||
// For players, only list subcommands if they have permission; for console, show all.
|
||||
if(!(sender instanceof EntityPlayer) || command.canSendCommand(sender, sc, entry.getKey())){
|
||||
sendMessage(sender, ("\u00A77> "
|
||||
+ "\u00A7e" + entry.getKey()
|
||||
+ "\u00A78: \u00A77" + sc.desc()));
|
||||
}
|
||||
}
|
||||
// Show permission node only if sender is console or has permission.
|
||||
if(!(sender instanceof EntityPlayer) ||
|
||||
CustomNpcsPermissions.hasPermission((EntityPlayer)sender, CustomNpcsPermissions.PROFILE_ADMIN)){
|
||||
sendMessage(sender, ("\u00A78Permission:\u00A77 "
|
||||
+ CommandProfile.getCommandPermission(command.getCommandName())));
|
||||
}
|
||||
}
|
||||
else{
|
||||
sendMessage(sender, "\u00A78------ \u00A7b" + command.getCommandName().toUpperCase()
|
||||
+ "." + args[1].toUpperCase() + " Command \u00A78------");
|
||||
SubCommand sc = m.getAnnotation(SubCommand.class);
|
||||
sendMessage(sender, ("\u00A77" + sc.desc()));
|
||||
if(!sc.usage().isEmpty()){
|
||||
sendMessage(sender, ("\u00A77Usage: \u00A76" + sc.usage()));
|
||||
}
|
||||
if(!(sender instanceof EntityPlayer) ||
|
||||
CustomNpcsPermissions.hasPermission((EntityPlayer)sender, CustomNpcsPermissions.PROFILE_ADMIN)){
|
||||
sendMessage(sender, ("\u00A78Permission:\u00A77 "
|
||||
+ getSubCommandPermission(args[1])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -1,4 +1,4 @@
|
||||
package kamkeel.command.profile;
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
@@ -23,6 +23,12 @@ public class CommandProfile extends CommandBase {
|
||||
public CommandProfile(){
|
||||
registerCommand(help);
|
||||
registerCommand(new CommandProfileChange());
|
||||
registerCommand(new CommandProfileCreate());
|
||||
registerCommand(new CommandProfileRemove());
|
||||
registerCommand(new CommandProfileAdmin());
|
||||
registerCommand(new CommandProfileRegion());
|
||||
registerCommand(new CommandProfileList());
|
||||
registerCommand(new CommandProfileRename());
|
||||
}
|
||||
|
||||
public void registerCommand(CommandProfileBase command){
|
||||
@@ -84,7 +90,7 @@ public class CommandProfile extends CommandBase {
|
||||
if(command == null)
|
||||
return null;
|
||||
if(args.length == 2 && command.runSubCommands())
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, command.subcommands.keySet().toArray(new String[command.subcommands.keySet().size()]));
|
||||
return getListOfStringsMatchingLastWord(args, command.subcommands.keySet().toArray(new String[command.subcommands.keySet().size()]));
|
||||
String[] useArgs = command.getUsage().split(" ");
|
||||
if(command.runSubCommands()) {
|
||||
Method m = command.subcommands.get(args[1].toLowerCase());
|
||||
@@ -95,7 +101,8 @@ public class CommandProfile extends CommandBase {
|
||||
if(args.length <= useArgs.length + 2) {
|
||||
if(args.length - 3 >= 0){
|
||||
String usage = useArgs[args.length - 3];
|
||||
if(usage.equals("<player>") || usage.equals("[player]")) {
|
||||
if(usage.equals("<player>") || usage.equals("[player]") || usage.equals("<targetPlayer>")
|
||||
|| usage.equals("<sourcePlayer>") || usage.equals("<destinationPlayer>")) {
|
||||
return CommandBase.getListOfStringsMatchingLastWord(args, MinecraftServer.getServer().getAllUsernames());
|
||||
}
|
||||
}
|
||||
@@ -111,7 +118,7 @@ public class CommandProfile extends CommandBase {
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel(){
|
||||
return 0;
|
||||
return 4;
|
||||
}
|
||||
|
||||
public static String getCommandPermission(String command){
|
||||
@@ -0,0 +1,259 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.data.profile.EnumProfileOperation;
|
||||
import noppes.npcs.api.handler.data.ISlot;
|
||||
import kamkeel.npcs.controllers.data.profile.Profile;
|
||||
import kamkeel.npcs.controllers.data.profile.ProfileOperation;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.*;
|
||||
|
||||
public class CommandProfileAdmin extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "admin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Admin profile management: clone, remove, change, list, rename, and rollback profiles.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "<subcommand>";
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Clone a slot from one player's profile to another's.",
|
||||
usage = "<sourcePlayer> <destinationPlayer> <sourceSlot> <destinationSlot> [temp]"
|
||||
)
|
||||
public void clone(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 4) {
|
||||
sendError(sender, "Usage: /profile admin clone <sourcePlayer> <destinationPlayer> <sourceSlot> <destinationSlot> [temp]");
|
||||
return;
|
||||
}
|
||||
String sourcePlayer = args[0];
|
||||
String destinationPlayer = args[1];
|
||||
int sourceSlot, destinationSlot;
|
||||
try {
|
||||
sourceSlot = Integer.parseInt(args[2]);
|
||||
destinationSlot = Integer.parseInt(args[3]);
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, "Slot IDs must be numbers.");
|
||||
return;
|
||||
}
|
||||
boolean temporary = (args.length >= 5 && args[4].equalsIgnoreCase("temp"));
|
||||
ProfileOperation result = ProfileController.Instance.cloneSlot(sourcePlayer, sourceSlot, destinationSlot, temporary);
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "Successfully cloned slot %d from %s to slot %d for %s.", sourceSlot, sourcePlayer, destinationSlot, destinationPlayer);
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
// Detail message for admins – note: using result.getMessage() for further details.
|
||||
sendError(sender, "Clone failed for %s: Profile is locked. Details: %s", sourcePlayer, result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error cloning slot for %s: %s", sourcePlayer, result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error cloning slot: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Remove a specified slot from a player's profile.",
|
||||
usage = "<targetPlayer> <slotId>"
|
||||
)
|
||||
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: /profile admin remove <targetPlayer> <slotId>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[1]);
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
ProfileOperation result = ProfileController.Instance.removeSlot(targetPlayer, slotId);
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "Successfully removed slot %d from %s.", slotId, targetPlayer);
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
sendError(sender, "Remove failed for %s: Profile is locked. Details: %s", targetPlayer, result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error removing slot %d from %s: %s", slotId, targetPlayer, result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error during removal: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Change a specified player's active slot.",
|
||||
usage = "<targetPlayer> <newSlotId>"
|
||||
)
|
||||
public void change(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: /profile admin change <targetPlayer> <newSlotId>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
int newSlotId;
|
||||
try {
|
||||
newSlotId = Integer.parseInt(args[1]);
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
ProfileOperation result = ProfileController.Instance.changeSlot(targetPlayer, newSlotId);
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "Successfully changed %s's active slot to %d.", targetPlayer, newSlotId);
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
sendError(sender, "Change failed for %s: Profile is locked. Details: %s", targetPlayer, result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error changing active slot for %s: %s", targetPlayer, result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error during change: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Create a new slot for a specified player's profile.",
|
||||
usage = "<targetPlayer>"
|
||||
)
|
||||
public void create(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: /profile admin create <targetPlayer>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
Profile profile = ProfileController.Instance.getProfile(targetPlayer);
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found for player: %s", targetPlayer);
|
||||
return;
|
||||
}
|
||||
ProfileOperation result = ProfileController.Instance.createSlotInternal(profile);
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "New slot created successfully for %s.", targetPlayer);
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
sendError(sender, "Create failed for %s: Profile is locked. Details: %s", targetPlayer, result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error creating new slot for %s: %s", targetPlayer, result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error during slot creation: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "List all slots (IDs and names) for a specified player's profile.",
|
||||
usage = "<targetPlayer>"
|
||||
)
|
||||
public void list(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: /profile admin list <targetPlayer>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
Profile profile = ProfileController.Instance.getProfile(targetPlayer);
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found for player: %s", targetPlayer);
|
||||
return;
|
||||
}
|
||||
sendMessage(sender, "Profile Slots for %s:", targetPlayer);
|
||||
for(Map.Entry<Integer, ISlot> entry : profile.getSlots().entrySet()) {
|
||||
int id = entry.getKey();
|
||||
String name = entry.getValue().getName();
|
||||
String prefix = (id == profile.currentSlotId) ? "* " : "- ";
|
||||
sendMessage(sender, prefix + "Slot " + id + ": " + name);
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Rename a specified player's slot.",
|
||||
usage = "<targetPlayer> <slotId> <newName>"
|
||||
)
|
||||
public void rename(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 3) {
|
||||
sendError(sender, "Usage: /profile admin rename <targetPlayer> <slotId> <newName>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[1]);
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 2; i < args.length; i++){
|
||||
if(i > 2) sb.append(" ");
|
||||
sb.append(args[i]);
|
||||
}
|
||||
String newName = sb.toString().trim();
|
||||
if(newName.length() > 20) {
|
||||
newName = newName.substring(0, 20);
|
||||
}
|
||||
if(!newName.matches("[A-Za-z ]+")){
|
||||
sendError(sender, "Invalid name. Only alphabetic characters and spaces are allowed.");
|
||||
return;
|
||||
}
|
||||
Profile profile = ProfileController.Instance.getProfile(targetPlayer);
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found for player: %s", targetPlayer);
|
||||
return;
|
||||
}
|
||||
if(profile.isLocked()) {
|
||||
sendError(sender, "Profile for %s is locked. Please try again later.", targetPlayer);
|
||||
return;
|
||||
}
|
||||
if(!profile.getSlots().containsKey(slotId)) {
|
||||
sendError(sender, "Slot %d not found in %s's profile.", slotId, targetPlayer);
|
||||
return;
|
||||
}
|
||||
profile.getSlots().get(slotId).setName(newName);
|
||||
if(profile.getPlayer() != null) {
|
||||
ProfileController.Instance.save(profile.player, profile);
|
||||
} else {
|
||||
UUID uuid = ProfileController.Instance.getUUIDFromUsername(targetPlayer);
|
||||
if(uuid != null)
|
||||
ProfileController.Instance.saveOffline(profile, uuid);
|
||||
}
|
||||
sendResult(sender, "Successfully renamed slot %d for %s to '%s'.", slotId, targetPlayer, newName);
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Rollback a player's profile to one of their backups.",
|
||||
usage = "<targetPlayer> <backupFileName>"
|
||||
)
|
||||
public void rollback(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: /profile admin rollback <targetPlayer> <backupFileName>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
String backupFileName = args[1] + ".dat";
|
||||
|
||||
Profile profile = ProfileController.Instance.getProfile(targetPlayer);
|
||||
if(profile == null || profile.player == null)
|
||||
return;
|
||||
|
||||
File backupDir = new File(ProfileController.getBackupDir(), profile.getPlayer().getUniqueID().toString());
|
||||
File backupFile = new File(backupDir, backupFileName);
|
||||
if(!backupFile.exists()){
|
||||
sendError(sender, "Backup file %s not found for player %s.", backupFileName, targetPlayer);
|
||||
return;
|
||||
}
|
||||
boolean success = ProfileController.Instance.rollbackProfile(targetPlayer, backupFile);
|
||||
if(success) {
|
||||
sendResult(sender, "Successfully rolled back %s's profile to backup %s.", targetPlayer, backupFileName);
|
||||
} else {
|
||||
sendError(sender, "Failed to rollback %s's profile.", targetPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-15
@@ -1,10 +1,9 @@
|
||||
package kamkeel.command.profile;
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -55,19 +54,7 @@ public abstract class CommandProfileBase extends CommandBase{
|
||||
return !subcommands.isEmpty();
|
||||
}
|
||||
|
||||
protected static void sendMessage(ICommandSender sender, String message, Object... obs) {
|
||||
sender.addChatMessage(new ChatComponentTranslation(message, obs));
|
||||
}
|
||||
|
||||
protected static void sendResult(ICommandSender sender, String message, Object... obs) {
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A77 " + message, obs));
|
||||
}
|
||||
|
||||
protected static void sendError(ICommandSender sender, String message, Object... obs) {
|
||||
sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A74 Error:\u00A7c " + message, obs));
|
||||
}
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface SubCommand {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.data.profile.EnumProfileOperation;
|
||||
import kamkeel.npcs.controllers.data.profile.ProfileOperation;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class CommandProfileChange extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "change";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Change your active profile slot.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "<slotId>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runSubCommands() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: " + getUsage());
|
||||
return;
|
||||
}
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[0]);
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number: " + args[0]);
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
ProfileOperation result = ProfileController.Instance.changeSlot(player, slotId);
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "Successfully changed profile slot to %d.", slotId);
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
sendError(sender, "Profile is locked. Details: %s", result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error changing your profile slot: %s", result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.data.profile.EnumProfileOperation;
|
||||
import kamkeel.npcs.controllers.data.profile.ProfileOperation;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class CommandProfileCreate extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "create";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Create a new profile slot.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runSubCommands() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
if(ProfileController.Instance.getProfile(player) == null) {
|
||||
sendError(sender, "Profile not found.");
|
||||
return;
|
||||
}
|
||||
ProfileOperation result = ProfileController.Instance.createSlotInternal(ProfileController.Instance.getProfile(player));
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "New profile slot created successfully.");
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
sendError(sender, "Profile is locked. Details: %s", result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error creating new profile slot: %s", result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import noppes.npcs.api.handler.data.ISlot;
|
||||
import kamkeel.npcs.controllers.data.profile.Profile;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendMessage;
|
||||
|
||||
public class CommandProfileList extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "list";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "List all your current profile slots (IDs and names).";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return ""; // No extra parameters.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
Profile profile = ProfileController.Instance.getProfile(player);
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found.");
|
||||
return;
|
||||
}
|
||||
if(profile.getSlots().isEmpty()){
|
||||
sendMessage(sender, "No slots found. Using default slot 0.");
|
||||
}
|
||||
sendMessage(sender, "Your Profile Slots:");
|
||||
for(Map.Entry<Integer, ISlot> entry : profile.getSlots().entrySet()) {
|
||||
int id = entry.getKey();
|
||||
String name = entry.getValue().getName();
|
||||
String prefix = (id == profile.currentSlotId) ? "* " : "- ";
|
||||
sendMessage(sender, prefix + "Slot " + id + ": " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.*;
|
||||
|
||||
public class CommandProfileRegion extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "region";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Manage profile region switching and restricted regions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "<subcommand>";
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Enable region-based profile switching",
|
||||
usage = ""
|
||||
)
|
||||
public void enable(ICommandSender sender, String[] args) throws CommandException {
|
||||
ConfigMain.RegionProfileSwitching = true;
|
||||
ConfigMain.RegionProfileSwitchingProperty.set(true);
|
||||
if(ConfigMain.config.hasChanged()){
|
||||
ConfigMain.config.save();
|
||||
}
|
||||
sendResult(sender, "Profile region switching enabled.");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Disable region-based profile switching",
|
||||
usage = ""
|
||||
)
|
||||
public void disable(ICommandSender sender, String[] args) throws CommandException {
|
||||
ConfigMain.RegionProfileSwitching = false;
|
||||
ConfigMain.RegionProfileSwitchingProperty.set(false);
|
||||
if(ConfigMain.config.hasChanged()){
|
||||
ConfigMain.config.save();
|
||||
}
|
||||
sendResult(sender, "Profile region switching disabled.");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Add a new region. Format: DIM, X1, Y1, Z1, X2, Y2, Z2",
|
||||
usage = "<dim> <x1> <y1> <z1> <x2> <y2> <z2>"
|
||||
)
|
||||
public void add(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 1){
|
||||
sendError(sender, "Usage: /profile region add <DIM, X1, Y1, Z1, X2, Y2, Z2>");
|
||||
return;
|
||||
}
|
||||
// Combine args in case the region data was split by spaces
|
||||
String regionStr = String.join(" ", args).trim();
|
||||
String[] parts = regionStr.split(",");
|
||||
if(parts.length != 7){
|
||||
sendError(sender, "Invalid region format. Must contain 7 integers separated by commas.");
|
||||
return;
|
||||
}
|
||||
List<Integer> regionList = new ArrayList<>();
|
||||
try {
|
||||
for(String part : parts){
|
||||
regionList.add(Integer.parseInt(part.trim()));
|
||||
}
|
||||
} catch(NumberFormatException e){
|
||||
sendError(sender, "Invalid number format in region data.");
|
||||
return;
|
||||
}
|
||||
ConfigMain.RestrictedProfileRegions.add(regionList);
|
||||
// Update config property value
|
||||
List<String> regionStrings = new ArrayList<>();
|
||||
for(List<Integer> region : ConfigMain.RestrictedProfileRegions) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < region.size(); i++) {
|
||||
if(i > 0) sb.append(", ");
|
||||
sb.append(region.get(i));
|
||||
}
|
||||
regionStrings.add(sb.toString());
|
||||
}
|
||||
ConfigMain.RestrictedProfileRegionsProperty.set(regionStrings.toArray(new String[0]));
|
||||
if(ConfigMain.config.hasChanged()){
|
||||
ConfigMain.config.save();
|
||||
}
|
||||
sendResult(sender, "Region added successfully.");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Remove a region by its index (1-based).",
|
||||
usage = "<index>"
|
||||
)
|
||||
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(args.length < 1){
|
||||
sendError(sender, "Usage: /profile region remove <index>");
|
||||
return;
|
||||
}
|
||||
int index;
|
||||
try {
|
||||
index = Integer.parseInt(args[0]);
|
||||
} catch(NumberFormatException e){
|
||||
sendError(sender, "Index must be a number.");
|
||||
return;
|
||||
}
|
||||
index = index - 1; // Convert to 0-based index
|
||||
if(index < 0 || index >= ConfigMain.RestrictedProfileRegions.size()){
|
||||
sendError(sender, "Invalid index. Must be between 1 and " + ConfigMain.RestrictedProfileRegions.size());
|
||||
return;
|
||||
}
|
||||
ConfigMain.RestrictedProfileRegions.remove(index);
|
||||
// Update config property value
|
||||
List<String> regionStrings = new ArrayList<>();
|
||||
for(List<Integer> region : ConfigMain.RestrictedProfileRegions) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < region.size(); i++) {
|
||||
if(i > 0) sb.append(", ");
|
||||
sb.append(region.get(i));
|
||||
}
|
||||
regionStrings.add(sb.toString());
|
||||
}
|
||||
ConfigMain.RestrictedProfileRegionsProperty.set(regionStrings.toArray(new String[0]));
|
||||
if(ConfigMain.config.hasChanged()){
|
||||
ConfigMain.config.save();
|
||||
}
|
||||
sendResult(sender, "Region removed successfully.");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "List all restricted profile regions.",
|
||||
usage = ""
|
||||
)
|
||||
public void list(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(ConfigMain.RestrictedProfileRegions.isEmpty()){
|
||||
sendMessage(sender, "No restricted profile regions configured.");
|
||||
return;
|
||||
}
|
||||
sendMessage(sender, "Restricted Profile Regions:");
|
||||
int i = 1;
|
||||
for(List<Integer> region : ConfigMain.RestrictedProfileRegions) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(i).append(": ");
|
||||
for (int j = 0; j < region.size(); j++) {
|
||||
if(j > 0) sb.append(", ");
|
||||
sb.append(region.get(j));
|
||||
}
|
||||
sendMessage(sender, sb.toString());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.data.profile.EnumProfileOperation;
|
||||
import kamkeel.npcs.controllers.data.profile.ProfileOperation;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class CommandProfileRemove extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "remove";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Remove a slot from your profile. You cannot remove your active slot.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "<slotId>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runSubCommands() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: " + getUsage());
|
||||
return;
|
||||
}
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[0]);
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number: " + args[0]);
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
ProfileOperation result = ProfileController.Instance.removeSlot(player, slotId);
|
||||
if(result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
sendResult(sender, "Successfully removed slot %d from your profile.", slotId);
|
||||
} else if(result.getResult() == EnumProfileOperation.LOCKED) {
|
||||
sendError(sender, "Profile is locked. Details: %s", result.getMessage());
|
||||
} else if(result.getResult() == EnumProfileOperation.ERROR) {
|
||||
sendError(sender, "Error removing slot: %s", result.getMessage());
|
||||
} else {
|
||||
sendError(sender, "Unexpected error: %s", result.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class CommandProfileRename extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "rename";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Rename one of your profile slots. Only letters and spaces are allowed (max 20 characters).";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return "<slotId> <newName>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: " + getUsage());
|
||||
return;
|
||||
}
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[0]);
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 1; i < args.length; i++){
|
||||
if(i > 1) sb.append(" ");
|
||||
sb.append(args[i]);
|
||||
}
|
||||
String newName = sb.toString().trim();
|
||||
if(newName.length() > 20) {
|
||||
newName = newName.substring(0, 20);
|
||||
}
|
||||
if(!newName.matches("[A-Za-z ]+")){
|
||||
sendError(sender, "Invalid name. Only alphabetic characters and spaces are allowed.");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
if(ProfileController.Instance.getProfile(player) == null) {
|
||||
sendError(sender, "Profile not found.");
|
||||
return;
|
||||
}
|
||||
if(!ProfileController.Instance.getProfile(player).getSlots().containsKey(slotId)) {
|
||||
sendError(sender, "Slot %d not found in your profile.", slotId);
|
||||
return;
|
||||
}
|
||||
ProfileController.Instance.getProfile(player).getSlots().get(slotId).setName(newName);
|
||||
ProfileController.Instance.save(player, ProfileController.Instance.getProfile(player));
|
||||
sendResult(sender, "Successfully renamed slot %d to '%s'.", slotId, newName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package kamkeel.npcs.controllers;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeValueType;
|
||||
import kamkeel.npcs.CustomAttributes;
|
||||
import kamkeel.npcs.controllers.data.attribute.tracker.PlayerAttributeTracker;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* AttributeController is the central registry for attribute definitions.
|
||||
* It ensures that keys are unique.
|
||||
*/
|
||||
public class AttributeController {
|
||||
|
||||
public AttributeController Instance;
|
||||
public CustomAttributes attributes;
|
||||
|
||||
// Tracking Player Attributes
|
||||
private static final Map<UUID, PlayerAttributeTracker> trackers = new HashMap<>();
|
||||
private static final Map<String, AttributeDefinition> definitions = new HashMap<>();
|
||||
|
||||
public AttributeController(){
|
||||
this.Instance = this;
|
||||
definitions.clear();
|
||||
trackers.clear();
|
||||
attributes = new CustomAttributes();
|
||||
}
|
||||
|
||||
|
||||
public static AttributeDefinition registerAttribute(String key, String displayName, char colorCode, AttributeValueType valueType, AttributeDefinition.AttributeSection section) {
|
||||
if (definitions.containsKey(key)) {
|
||||
throw new IllegalArgumentException("Attribute already registered with key: " + key);
|
||||
}
|
||||
AttributeDefinition def = new AttributeDefinition(key, displayName, colorCode, valueType, section);
|
||||
definitions.put(key, def);
|
||||
return def;
|
||||
}
|
||||
|
||||
public static AttributeDefinition registerAttribute(AttributeDefinition definition) {
|
||||
if (definitions.containsKey(definition.getKey())) {
|
||||
throw new IllegalArgumentException("Attribute already registered with key: " + definition.getKey());
|
||||
} else {
|
||||
definitions.put(definition.getKey(), definition);
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
|
||||
public static AttributeDefinition getAttribute(String key) {
|
||||
return definitions.get(key);
|
||||
}
|
||||
|
||||
public static Collection<AttributeDefinition> getAllAttributes() {
|
||||
return definitions.values();
|
||||
}
|
||||
|
||||
public static PlayerAttributeTracker getTracker(EntityPlayer player) {
|
||||
return trackers.computeIfAbsent(player.getUniqueID(), id -> new PlayerAttributeTracker(id));
|
||||
}
|
||||
|
||||
public static void removeTracker(UUID playerId) {
|
||||
trackers.remove(playerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all trackers (e.g. called every 10 ticks for all online players).
|
||||
*/
|
||||
public static void updateAllTrackers(Iterable<EntityPlayer> players) {
|
||||
for (EntityPlayer player : players) {
|
||||
PlayerAttributeTracker tracker = getTracker(player);
|
||||
tracker.updateIfChanged(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,795 @@
|
||||
package kamkeel.npcs.controllers;
|
||||
|
||||
import kamkeel.npcs.controllers.data.profile.*;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.NoppesUtilServer;
|
||||
import noppes.npcs.api.entity.IPlayer;
|
||||
import noppes.npcs.api.handler.IPlayerData;
|
||||
import noppes.npcs.api.handler.data.IProfile;
|
||||
import noppes.npcs.api.handler.IProfileHandler;
|
||||
import noppes.npcs.api.handler.data.ISlot;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.controllers.data.PlayerQuestData;
|
||||
import noppes.npcs.util.CustomNPCsThreader;
|
||||
import noppes.npcs.util.NBTJsonUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import static noppes.npcs.CustomNpcsPermissions.PROFILE_REGION_BYPASS;
|
||||
import static noppes.npcs.CustomNpcsPermissions.hasPermission;
|
||||
|
||||
public class ProfileController implements IProfileHandler {
|
||||
|
||||
// Message constants
|
||||
private static final String MSG_PLAYER_NOT_FOUND = "Player not found.";
|
||||
private static final String MSG_PROFILE_LOCKED_CLONE = "Profile is locked; cannot clone slot.";
|
||||
private static final String MSG_SOURCE_SLOT_NOT_EXIST = "Source slot does not exist.";
|
||||
private static final String MSG_CANNOT_CLONE_CURRENT = "Cannot clone to the current active slot.";
|
||||
private static final String MSG_INVALID_DEST_SLOT = "Invalid destination slot id.";
|
||||
private static final String MSG_CLONE_SUCCESS = "Slot cloned successfully.";
|
||||
private static final String MSG_PROFILE_LOCKED_REMOVE = "Profile is locked; cannot remove slot.";
|
||||
private static final String MSG_CANNOT_REMOVE_ACTIVE = "Cannot remove the currently active slot.";
|
||||
private static final String MSG_SLOT_NOT_EXIST = "Slot does not exist.";
|
||||
private static final String MSG_REMOVE_SUCCESS = "Slot removed successfully.";
|
||||
private static final String MSG_PROFILE_LOCKED_CREATE = "Profile is locked; cannot create slot.";
|
||||
private static final String MSG_MAX_SLOTS_REACHED = "Maximum allowed slots reached.";
|
||||
private static final String MSG_NEW_SLOT_CREATED = "New slot created successfully.";
|
||||
private static final String MSG_PROFILE_LOCKED_CHANGE = "Profile is locked; cannot change slot.";
|
||||
private static final String MSG_SLOT_ALREADY_ACTIVE = "Slot is already active.";
|
||||
private static final String MSG_REGION_NOT_ALLOWED = "Profile switching not allowed from your current location.";
|
||||
private static final String MSG_CHANGE_SUCCESS = "Slot changed successfully.";
|
||||
|
||||
public static Map<String, IProfileData> profileTypes = new HashMap<>();
|
||||
public static Map<UUID, Profile> activeProfiles = new HashMap<>();
|
||||
public static String profile_directory = "profiles";
|
||||
|
||||
public static ProfileController Instance;
|
||||
|
||||
public ProfileController() {
|
||||
Instance = this;
|
||||
profileTypes = new HashMap<>();
|
||||
activeProfiles = new HashMap<>();
|
||||
}
|
||||
|
||||
public static boolean registerProfileType(IProfileData type) {
|
||||
if (profileTypes.containsKey(type.getTagName()))
|
||||
return false;
|
||||
profileTypes.put(type.getTagName(), type);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static File getProfileDir() {
|
||||
try {
|
||||
File file = new File(CustomNpcs.getWorldSaveDirectory(), profile_directory);
|
||||
if (!file.exists())
|
||||
file.mkdir();
|
||||
return file;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static File getBackupDir() {
|
||||
File base = getProfileDir();
|
||||
File backup = new File(base, "backup");
|
||||
if (!backup.exists()) {
|
||||
backup.mkdir();
|
||||
}
|
||||
return backup;
|
||||
}
|
||||
|
||||
public synchronized void login(EntityPlayer player) {
|
||||
if(!ConfigMain.ProfilesEnabled)
|
||||
return;
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
Profile profile;
|
||||
if (activeProfiles.containsKey(player.getUniqueID())) {
|
||||
profile = activeProfiles.get(player.getUniqueID());
|
||||
profile.player = player;
|
||||
} else {
|
||||
NBTTagCompound compound = load(player);
|
||||
profile = new Profile(player, compound);
|
||||
if (profile.getSlots().isEmpty()) {
|
||||
Slot defaultSlot = new Slot(0, "Default Slot");
|
||||
defaultSlot.setLastLoaded(System.currentTimeMillis());
|
||||
profile.getSlots().put(0, defaultSlot);
|
||||
profile.currentSlotId = 0;
|
||||
saveSlotData(player);
|
||||
}
|
||||
profile.player = player;
|
||||
activeProfiles.put(player.getUniqueID(), profile);
|
||||
verifySlotQuests(profile.player);
|
||||
save(player, profile);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized NBTTagCompound load(EntityPlayer player) {
|
||||
File saveDir = getProfileDir();
|
||||
String filename = player.getUniqueID().toString() + ".dat";
|
||||
try {
|
||||
File file = new File(saveDir, filename);
|
||||
if (file.exists()) {
|
||||
return NBTJsonUtil.loadNBTData(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogWriter.error("Error loading profile file: " + filename, e);
|
||||
}
|
||||
return new NBTTagCompound();
|
||||
}
|
||||
|
||||
public synchronized NBTTagCompound load(UUID uuid) {
|
||||
File saveDir = getProfileDir();
|
||||
String filename = uuid.toString() + ".dat";
|
||||
try {
|
||||
File file = new File(saveDir, filename);
|
||||
if (file.exists()) {
|
||||
return NBTJsonUtil.loadNBTData(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogWriter.error("Error loading profile file: " + filename, e);
|
||||
}
|
||||
return new NBTTagCompound();
|
||||
}
|
||||
|
||||
public synchronized void saveOffline(Profile profile, UUID uuid) {
|
||||
profile.setLocked(true);
|
||||
CustomNPCsThreader.customNPCThread.execute(() -> {
|
||||
final NBTTagCompound compound = profile.writeToNBT();
|
||||
final String filename = uuid.toString() + ".dat";
|
||||
try {
|
||||
File saveDir = getProfileDir();
|
||||
File fileNew = new File(saveDir, filename + "_new");
|
||||
File fileOld = new File(saveDir, filename);
|
||||
CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew));
|
||||
if (fileOld.exists()) {
|
||||
fileOld.delete();
|
||||
}
|
||||
fileNew.renameTo(fileOld);
|
||||
backupProfile(uuid, compound);
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
} finally {
|
||||
profile.setLocked(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void save(EntityPlayer player, Profile profile) {
|
||||
profile.setLocked(true);
|
||||
CustomNPCsThreader.customNPCThread.execute(() -> {
|
||||
final NBTTagCompound compound = profile.writeToNBT();
|
||||
final String filename = player.getUniqueID() + ".dat";
|
||||
try {
|
||||
File saveDir = getProfileDir();
|
||||
File fileNew = new File(saveDir, filename + "_new");
|
||||
File fileOld = new File(saveDir, filename);
|
||||
CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew));
|
||||
if (fileOld.exists()) {
|
||||
fileOld.delete();
|
||||
}
|
||||
fileNew.renameTo(fileOld);
|
||||
if (ConfigMain.AllowProfileBackups) {
|
||||
backupProfile(player.getUniqueID(), compound);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
} finally {
|
||||
profile.setLocked(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void backupProfile(UUID uuid, NBTTagCompound compound) {
|
||||
try {
|
||||
File backupDir = new File(getBackupDir(), uuid.toString());
|
||||
if (!backupDir.exists()) {
|
||||
backupDir.mkdirs();
|
||||
}
|
||||
String dateStr = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
|
||||
File backupFile = new File(backupDir, dateStr + ".dat");
|
||||
CompressedStreamTools.writeCompressed(compound, new FileOutputStream(backupFile));
|
||||
File[] backups = backupDir.listFiles((dir, name) -> name.endsWith(".dat"));
|
||||
if (backups != null && backups.length > ConfigMain.ProfileBackupAmount) {
|
||||
Arrays.sort(backups, Comparator.comparingLong(File::lastModified));
|
||||
for (int i = 0; i < backups.length - ConfigMain.ProfileBackupAmount; i++) {
|
||||
backups[i].delete();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean rollbackProfile(String username, File backupFile) {
|
||||
UUID uuid = getUUIDFromUsername(username);
|
||||
if (uuid == null)
|
||||
return false;
|
||||
try (FileInputStream fis = new FileInputStream(backupFile)) {
|
||||
NBTTagCompound compound = CompressedStreamTools.readCompressed(fis);
|
||||
File saveDir = getProfileDir();
|
||||
File mainFile = new File(saveDir, uuid.toString() + ".dat");
|
||||
File fileNew = new File(saveDir, uuid.toString() + "_new");
|
||||
CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew));
|
||||
if (mainFile.exists()) {
|
||||
mainFile.delete();
|
||||
}
|
||||
fileNew.renameTo(mainFile);
|
||||
EntityPlayer player = NoppesUtilServer.getPlayerByName(username);
|
||||
Profile newProfile;
|
||||
if (player != null) {
|
||||
newProfile = new Profile(player, compound);
|
||||
activeProfiles.put(uuid, newProfile);
|
||||
loadSlotData(player);
|
||||
} else {
|
||||
newProfile = new Profile(null, compound);
|
||||
activeProfiles.put(uuid, newProfile);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void logout(EntityPlayer player) {
|
||||
if (player != null) {
|
||||
activeProfiles.remove(player.getUniqueID());
|
||||
}
|
||||
}
|
||||
|
||||
public Profile getProfile(EntityPlayer player) {
|
||||
if (player == null)
|
||||
return null;
|
||||
if (!activeProfiles.containsKey(player.getUniqueID()))
|
||||
login(player);
|
||||
return activeProfiles.get(player.getUniqueID());
|
||||
}
|
||||
|
||||
public Profile getProfile(UUID uuid) {
|
||||
if (activeProfiles.containsKey(uuid))
|
||||
return activeProfiles.get(uuid);
|
||||
NBTTagCompound compound = load(uuid);
|
||||
return new Profile(null, compound);
|
||||
}
|
||||
|
||||
public Profile getProfile(String username) {
|
||||
EntityPlayer player = NoppesUtilServer.getPlayerByName(username);
|
||||
if (player != null) {
|
||||
return getProfile(player);
|
||||
} else {
|
||||
UUID uuid = getUUIDFromUsername(username);
|
||||
if (uuid == null)
|
||||
return null;
|
||||
return getProfile(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getUUIDFromUsername(String username) {
|
||||
try {
|
||||
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username);
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
con.setConnectTimeout(5000);
|
||||
con.setReadTimeout(5000);
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||
StringBuilder temp = new StringBuilder();
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
temp.append(line);
|
||||
}
|
||||
in.close();
|
||||
con.disconnect();
|
||||
String response = temp.toString();
|
||||
if (response.contains("\"id\"")) {
|
||||
int idIndex = response.indexOf("\"id\"");
|
||||
int colonIndex = response.indexOf(":", idIndex);
|
||||
int quoteStart = response.indexOf("\"", colonIndex);
|
||||
int quoteEnd = response.indexOf("\"", quoteStart + 1);
|
||||
String idString = response.substring(quoteStart + 1, quoteEnd);
|
||||
idString = idString.replaceFirst(
|
||||
"(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)",
|
||||
"$1-$2-$3-$4-$5"
|
||||
);
|
||||
return UUID.fromString(idString);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LogWriter.error("Error retrieving UUID for " + username, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getNextAvailableTempSlot(Profile profile) {
|
||||
int id = -1;
|
||||
while (profile.getSlots().containsKey(id)) {
|
||||
id--;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private ProfileOperation cloneSlotInternal(Profile profile, int sourceSlotId, int destinationSlotId, boolean temporary) {
|
||||
if (profile.isLocked()) {
|
||||
return ProfileOperation.locked(MSG_PROFILE_LOCKED_CLONE);
|
||||
}
|
||||
if (profile.player != null) {
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
for (IProfileData pd : dataList) {
|
||||
if (pd.verifySwitch(profile.player).getResult() != EnumProfileOperation.SUCCESS) {
|
||||
return pd.verifySwitch(profile.player);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!profile.getSlots().containsKey(sourceSlotId)) {
|
||||
return ProfileOperation.error(MSG_SOURCE_SLOT_NOT_EXIST);
|
||||
}
|
||||
if (destinationSlotId == profile.getCurrentSlotId()) {
|
||||
return ProfileOperation.error(MSG_CANNOT_CLONE_CURRENT);
|
||||
}
|
||||
if (temporary) {
|
||||
destinationSlotId = getNextAvailableTempSlot(profile);
|
||||
} else {
|
||||
if (destinationSlotId <= 0) {
|
||||
return ProfileOperation.error(MSG_INVALID_DEST_SLOT);
|
||||
}
|
||||
}
|
||||
ISlot sourceSlot = profile.getSlots().get(sourceSlotId);
|
||||
Map<String, NBTTagCompound> newComponents = new HashMap<>();
|
||||
for (String key : sourceSlot.getComponents().keySet()) {
|
||||
newComponents.put(key, (NBTTagCompound) sourceSlot.getComponentData(key).copy());
|
||||
}
|
||||
Slot clonedSlot = new Slot(destinationSlotId, "Cloned Slot " + destinationSlotId, System.currentTimeMillis(), temporary, newComponents);
|
||||
profile.getSlots().put(destinationSlotId, clonedSlot);
|
||||
return ProfileOperation.success(MSG_CLONE_SUCCESS);
|
||||
}
|
||||
|
||||
private ProfileOperation removeSlotInternal(Profile profile, int slotId) {
|
||||
if (profile.isLocked()) {
|
||||
return ProfileOperation.locked(MSG_PROFILE_LOCKED_REMOVE);
|
||||
}
|
||||
if (slotId == profile.getCurrentSlotId()) {
|
||||
return ProfileOperation.error(MSG_CANNOT_REMOVE_ACTIVE);
|
||||
}
|
||||
if (!profile.getSlots().containsKey(slotId)) {
|
||||
return ProfileOperation.error(MSG_SLOT_NOT_EXIST);
|
||||
}
|
||||
profile.getSlots().remove(slotId);
|
||||
return ProfileOperation.success(MSG_REMOVE_SUCCESS);
|
||||
}
|
||||
|
||||
public ProfileOperation createSlotInternal(Profile profile) {
|
||||
if (profile.isLocked()) {
|
||||
return ProfileOperation.locked(MSG_PROFILE_LOCKED_CREATE);
|
||||
}
|
||||
int newSlotId = 0;
|
||||
while (profile.getSlots().containsKey(newSlotId)) {
|
||||
newSlotId++;
|
||||
}
|
||||
if (!allowSlotPermission(profile.player)) {
|
||||
return ProfileOperation.error(MSG_MAX_SLOTS_REACHED);
|
||||
}
|
||||
if (profile.player != null) {
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
for (IProfileData pd : dataList) {
|
||||
if (pd.verifySwitch(profile.player).getResult() != EnumProfileOperation.SUCCESS) {
|
||||
return pd.verifySwitch(profile.player);
|
||||
}
|
||||
}
|
||||
}
|
||||
Slot newSlot = new Slot(newSlotId, "Slot " + newSlotId);
|
||||
newSlot.setLastLoaded(System.currentTimeMillis());
|
||||
profile.getSlots().put(newSlotId, newSlot);
|
||||
if(profile.player != null){
|
||||
verifySlotQuests(profile.player);
|
||||
save(profile.player, profile);
|
||||
}
|
||||
return ProfileOperation.success(MSG_NEW_SLOT_CREATED);
|
||||
}
|
||||
|
||||
private ProfileOperation changeSlotInternal(Profile profile, int newSlotId) {
|
||||
if (profile.isLocked()) {
|
||||
return ProfileOperation.locked(MSG_PROFILE_LOCKED_CHANGE);
|
||||
}
|
||||
if (profile.getCurrentSlotId() == newSlotId) {
|
||||
return ProfileOperation.error(MSG_SLOT_ALREADY_ACTIVE);
|
||||
}
|
||||
if (!profile.getSlots().containsKey(newSlotId)) {
|
||||
return ProfileOperation.error(MSG_SLOT_NOT_EXIST);
|
||||
}
|
||||
if (profile.player != null) {
|
||||
if (ConfigMain.RegionProfileSwitching) {
|
||||
boolean allowed = hasPermission(profile.player, PROFILE_REGION_BYPASS);
|
||||
if (!allowed) {
|
||||
int playerDim = profile.player.dimension;
|
||||
int playerX = (int) profile.player.posX;
|
||||
int playerY = (int) profile.player.posY;
|
||||
int playerZ = (int) profile.player.posZ;
|
||||
for (List<Integer> region : ConfigMain.RestrictedProfileRegions) {
|
||||
if (region.size() == 7) {
|
||||
int dim = region.get(0);
|
||||
int x1 = Math.min(region.get(1), region.get(4));
|
||||
int y1 = Math.min(region.get(2), region.get(5));
|
||||
int z1 = Math.min(region.get(3), region.get(6));
|
||||
int x2 = Math.max(region.get(1), region.get(4));
|
||||
int y2 = Math.max(region.get(2), region.get(5));
|
||||
int z2 = Math.max(region.get(3), region.get(6));
|
||||
if (playerDim == dim &&
|
||||
playerX >= x1 && playerX <= x2 &&
|
||||
playerY >= y1 && playerY <= y2 &&
|
||||
playerZ >= z1 && playerZ <= z2) {
|
||||
allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allowed) {
|
||||
return ProfileOperation.error(MSG_REGION_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
for (IProfileData pd : dataList) {
|
||||
if (pd.verifySwitch(profile.player).getResult() != EnumProfileOperation.SUCCESS) {
|
||||
return pd.verifySwitch(profile.player);
|
||||
}
|
||||
}
|
||||
saveSlotData(profile.player);
|
||||
profile.currentSlotId = newSlotId;
|
||||
loadSlotData(profile.player);
|
||||
PlayerData pdata = PlayerData.get(profile.player);
|
||||
pdata.profileSlot = newSlotId;
|
||||
pdata.save();
|
||||
|
||||
if(ConfigMain.AttributesEnabled)
|
||||
AttributeController.getTracker(profile.player).recalcAttributes(profile.player);
|
||||
} else {
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
}
|
||||
return ProfileOperation.success(MSG_CHANGE_SUCCESS);
|
||||
}
|
||||
|
||||
public ProfileOperation cloneSlot(EntityPlayer player, int sourceSlotId, int destinationSlotId, boolean temporary) {
|
||||
Profile profile = getProfile(player);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS && player != null) {
|
||||
save(player, profile);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ProfileOperation cloneSlot(UUID uuid, int sourceSlotId, int destinationSlotId, boolean temporary) {
|
||||
Profile profile = getProfile(uuid);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
if (profile.player != null)
|
||||
save(profile.player, profile);
|
||||
else
|
||||
saveOffline(profile, uuid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ProfileOperation cloneSlot(String username, int sourceSlotId, int destinationSlotId, boolean temporary) {
|
||||
Profile profile = getProfile(username);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
if (profile.player != null)
|
||||
save(profile.player, profile);
|
||||
else {
|
||||
UUID uuid = getUUIDFromUsername(username);
|
||||
if (uuid != null)
|
||||
saveOffline(profile, uuid);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ProfileOperation removeSlot(EntityPlayer player, int slotId) {
|
||||
Profile profile = getProfile(player);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = removeSlotInternal(profile, slotId);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS && player != null) {
|
||||
save(player, profile);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ProfileOperation removeSlot(String username, int slotId) {
|
||||
Profile profile = getProfile(username);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = removeSlotInternal(profile, slotId);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
if (profile.player != null)
|
||||
save(profile.player, profile);
|
||||
else {
|
||||
UUID uuid = getUUIDFromUsername(username);
|
||||
if (uuid != null)
|
||||
saveOffline(profile, uuid);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ProfileOperation changeSlot(EntityPlayer player, int newSlotId) {
|
||||
Profile profile = getProfile(player);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = changeSlotInternal(profile, newSlotId);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS && player != null)
|
||||
save(player, profile);
|
||||
return result;
|
||||
}
|
||||
|
||||
public ProfileOperation changeSlot(String username, int newSlotId) {
|
||||
Profile profile = getProfile(username);
|
||||
if (profile == null)
|
||||
return ProfileOperation.error(MSG_PLAYER_NOT_FOUND);
|
||||
ProfileOperation result = changeSlotInternal(profile, newSlotId);
|
||||
if (result.getResult() == EnumProfileOperation.SUCCESS) {
|
||||
if (profile.player != null)
|
||||
save(profile.player, profile);
|
||||
else {
|
||||
UUID uuid = getUUIDFromUsername(username);
|
||||
if (uuid != null)
|
||||
saveOffline(profile, uuid);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void saveSlotData(EntityPlayer player) {
|
||||
if (player == null || !activeProfiles.containsKey(player.getUniqueID()))
|
||||
return;
|
||||
Profile profile = activeProfiles.get(player.getUniqueID());
|
||||
if (profile.isLocked()) {
|
||||
return;
|
||||
}
|
||||
ISlot slot = profile.getSlots().get(profile.getCurrentSlotId());
|
||||
if (slot == null) {
|
||||
slot = new Slot(profile.getCurrentSlotId(), "Slot " + profile.getCurrentSlotId());
|
||||
profile.getSlots().put(profile.getCurrentSlotId(), slot);
|
||||
}
|
||||
for (IProfileData profileData : profileTypes.values()) {
|
||||
NBTTagCompound cloned = (NBTTagCompound) profileData.getCurrentNBT(player).copy();
|
||||
slot.setComponentData(profileData.getTagName(), cloned);
|
||||
}
|
||||
slot.setLastLoaded(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void loadSlotData(EntityPlayer player) {
|
||||
if (player == null || !activeProfiles.containsKey(player.getUniqueID()))
|
||||
return;
|
||||
Profile profile = activeProfiles.get(player.getUniqueID());
|
||||
ISlot slot = profile.getSlots().get(profile.getCurrentSlotId());
|
||||
if (slot == null)
|
||||
return;
|
||||
for (IProfileData profileData : profileTypes.values()) {
|
||||
NBTTagCompound data;
|
||||
if (slot.getComponents().containsKey(profileData.getTagName()))
|
||||
data = slot.getComponentData(profileData.getTagName());
|
||||
else
|
||||
data = new NBTTagCompound();
|
||||
profileData.setNBT(player, data);
|
||||
}
|
||||
for (IProfileData profileData : profileTypes.values()) {
|
||||
profileData.save(player);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ProfileInfoEntry> getProfileInfo(EntityPlayer player, int slotId) {
|
||||
List<ProfileInfoEntry> infoList = new ArrayList<>();
|
||||
Profile profile = getProfile(player);
|
||||
if (profile == null)
|
||||
return infoList;
|
||||
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
if (slotId == profile.getCurrentSlotId()) {
|
||||
for (IProfileData pd : dataList) {
|
||||
NBTTagCompound currentNBT = pd.getCurrentNBT(player);
|
||||
List<ProfileInfoEntry> subInfo = pd.getInfo(player, currentNBT);
|
||||
infoList.addAll(subInfo);
|
||||
}
|
||||
} else {
|
||||
if (!profile.getSlots().containsKey(slotId))
|
||||
return infoList;
|
||||
ISlot slot = profile.getSlots().get(slotId);
|
||||
for (IProfileData pd : dataList) {
|
||||
if (slot.getComponents().containsKey(pd.getTagName())) {
|
||||
NBTTagCompound sub = slot.getComponentData(pd.getTagName());
|
||||
List<ProfileInfoEntry> subInfo = pd.getInfo(player, sub);
|
||||
infoList.addAll(subInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
public boolean allowSlotPermission(EntityPlayer player) {
|
||||
Profile profile = getProfile(player);
|
||||
int currentSlots = profile.getSlots().size();
|
||||
if (CustomNpcsPermissions.hasCustomPermission(player, "customnpcs.profile.max.*")) {
|
||||
return true;
|
||||
}
|
||||
int highestAllowed = 0;
|
||||
for (int i = 1; i <= 50; i++) {
|
||||
String perm = "customnpcs.profile.max." + i;
|
||||
if (CustomNpcsPermissions.hasCustomPermission(player, perm)) {
|
||||
highestAllowed = i;
|
||||
}
|
||||
}
|
||||
if (highestAllowed == 0) {
|
||||
highestAllowed = 1;
|
||||
}
|
||||
return currentSlots < highestAllowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfile getProfile(IPlayer player) {
|
||||
if(player == null || player.getMCEntity() == null)
|
||||
return null;
|
||||
return getProfile((EntityPlayer) player.getMCEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeSlot(IPlayer player, int slotID) {
|
||||
if(player == null || player.getMCEntity() == null)
|
||||
return false;
|
||||
|
||||
EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity();
|
||||
ProfileOperation profileOperation = changeSlot(entityPlayer, slotID);
|
||||
return profileOperation.getResult() == EnumProfileOperation.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSlot(IPlayer player, int slotID) {
|
||||
if(player == null || player.getMCEntity() == null)
|
||||
return false;
|
||||
|
||||
EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity();
|
||||
Profile profile = getProfile(entityPlayer);
|
||||
if(profile == null)
|
||||
return false;
|
||||
return profile.getSlots().containsKey(slotID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSlot(IPlayer player, int slotID) {
|
||||
if(player == null || player.getMCEntity() == null)
|
||||
return false;
|
||||
|
||||
EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity();
|
||||
ProfileOperation profileOperation = removeSlot(entityPlayer, slotID);
|
||||
return profileOperation.getResult() == EnumProfileOperation.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPlayerData getSlotPlayerData(IPlayer player, int slotID) {
|
||||
PlayerData playerData;
|
||||
if(player == null || player.getMCEntity() == null)
|
||||
return null;
|
||||
|
||||
EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity();
|
||||
Profile profile = getProfile(entityPlayer);
|
||||
if(profile == null)
|
||||
return null;
|
||||
return getSlotPlayerData(entityPlayer, slotID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveSlotData(IPlayer player) {
|
||||
if(player == null || player.getMCEntity() == null)
|
||||
return;
|
||||
|
||||
EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity();
|
||||
saveSlotData(entityPlayer);
|
||||
}
|
||||
|
||||
public IPlayerData getSlotPlayerData(EntityPlayer player, int slotID) {
|
||||
PlayerData playerData;
|
||||
Profile profile = getProfile(player);
|
||||
if(profile == null)
|
||||
return null;
|
||||
|
||||
if(profile.currentSlotId == slotID){
|
||||
playerData = PlayerData.get(player);
|
||||
} else {
|
||||
Slot slot = (Slot) profile.getSlots().get(slotID);
|
||||
playerData = getSlotPlayerData(player, slot);
|
||||
}
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public PlayerData getSlotPlayerData(EntityPlayer player, Slot slot) {
|
||||
if(slot == null)
|
||||
return null;
|
||||
|
||||
PlayerData playerData = new PlayerData();
|
||||
playerData.player = player;
|
||||
|
||||
NBTTagCompound compound = slot.getComponentData(new CNPCData().getTagName());
|
||||
if(compound == null)
|
||||
compound = new NBTTagCompound();
|
||||
playerData.setNBT(compound);
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public void verifySlotQuests(EntityPlayer player) {
|
||||
Profile profile = getProfile(player);
|
||||
if (profile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<Integer, Long> universalFinished = new HashMap<>();
|
||||
for (Integer questId : QuestController.Instance.sharedQuests.keySet()) {
|
||||
long maxTime = 0;
|
||||
for (ISlot slot : profile.getSlots().values()) {
|
||||
IPlayerData data = getSlotPlayerData(player, slot.getId());
|
||||
if (data == null) {
|
||||
continue;
|
||||
}
|
||||
PlayerQuestData questData = (PlayerQuestData) data.getQuestData();
|
||||
Long t = questData.finishedQuests.get(questId);
|
||||
if (t != null && t > maxTime) {
|
||||
maxTime = t;
|
||||
}
|
||||
}
|
||||
if (maxTime > 0) {
|
||||
universalFinished.put(questId, maxTime);
|
||||
}
|
||||
}
|
||||
|
||||
// Push the universal shared completion times into every slot.
|
||||
for (ISlot slot : profile.getSlots().values()) {
|
||||
IPlayerData data = getSlotPlayerData(player, slot.getId());
|
||||
if (data != null) {
|
||||
PlayerData playerData = (PlayerData) data;
|
||||
PlayerQuestData questData = (PlayerQuestData) data.getQuestData();
|
||||
questData.finishedQuests.putAll(universalFinished);
|
||||
slot.setComponentData(new CNPCData().getTagName(), playerData.getNBT());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shareQuestCompletion(EntityPlayer player, int questId, long completeTime) {
|
||||
Profile profile = getProfile(player);
|
||||
if (profile == null) {
|
||||
return;
|
||||
}
|
||||
for (ISlot slot : profile.getSlots().values()) {
|
||||
IPlayerData playerData = getSlotPlayerData(player, slot.getId());
|
||||
if (playerData != null) {
|
||||
PlayerQuestData questData = (PlayerQuestData) playerData.getQuestData();
|
||||
Long existing = questData.finishedQuests.get(questId);
|
||||
if (existing == null || completeTime > existing) {
|
||||
questData.finishedQuests.put(questId, completeTime);
|
||||
}
|
||||
playerData.save();
|
||||
}
|
||||
}
|
||||
save(player, profile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,676 @@
|
||||
package kamkeel.npcs.controllers;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.addon.DBCAddon;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumSyncAction;
|
||||
import kamkeel.npcs.network.enums.EnumSyncType;
|
||||
import kamkeel.npcs.network.packets.data.LoginPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.SyncEffectPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.SyncPacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import noppes.npcs.client.ClientCacheHandler;
|
||||
import noppes.npcs.controllers.*;
|
||||
import noppes.npcs.controllers.data.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SyncController {
|
||||
|
||||
public static void syncPlayer(EntityPlayerMP player){
|
||||
|
||||
// Login Packet
|
||||
PacketHandler.Instance.sendToPlayer(new LoginPacket(), player);
|
||||
|
||||
// 1) Factions
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.FACTION,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
factionsNBT()
|
||||
), player);
|
||||
|
||||
// 2) Dialog Categories
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.DIALOG_CATEGORY,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
dialogCategoriesNBT()
|
||||
), player);
|
||||
|
||||
// 3) Quest Categories
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.QUEST_CATEGORY,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
questCategoriesNBT()
|
||||
), player);
|
||||
|
||||
// 4) Workbench Recipes
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.WORKBENCH_RECIPES,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
workbenchNBT()
|
||||
), player);
|
||||
|
||||
// 5) Carpentry Recipes
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.CARPENTRY_RECIPES,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
carpentryNBT()
|
||||
), player);
|
||||
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.ANVIL_RECIPES,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
anvilNBT()
|
||||
), player);
|
||||
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.CUSTOM_EFFECTS,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
customEffectsNBT()
|
||||
), player);
|
||||
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.MAGIC,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
magicsNBT()
|
||||
), player);
|
||||
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.MAGIC_CYCLE,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
magicCyclesNBT()
|
||||
), player);
|
||||
|
||||
DBCAddon.instance.syncPlayer(player);
|
||||
syncPlayerData(player, false);
|
||||
}
|
||||
|
||||
public static NBTTagCompound workbenchNBT(){
|
||||
RecipeController controller = RecipeController.Instance;
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for(RecipeCarpentry recipe : controller.globalRecipes.values()){
|
||||
list.appendTag(recipe.writeNBT());
|
||||
}
|
||||
compound.setTag("recipes", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound carpentryNBT(){
|
||||
RecipeController controller = RecipeController.Instance;
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for(RecipeCarpentry recipe : controller.carpentryRecipes.values()){
|
||||
list.appendTag(recipe.writeNBT());
|
||||
}
|
||||
compound.setTag("recipes", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound anvilNBT(){
|
||||
RecipeController controller = RecipeController.Instance;
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for(RecipeAnvil recipe : controller.anvilRecipes.values()){
|
||||
list.appendTag(recipe.writeNBT());
|
||||
}
|
||||
compound.setTag("recipes", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound factionsNBT(){
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for(Faction faction : FactionController.getInstance().factions.values()){
|
||||
NBTTagCompound factioNBT = new NBTTagCompound();
|
||||
faction.writeNBT(factioNBT);
|
||||
list.appendTag(factioNBT);
|
||||
}
|
||||
compound.setTag("Factions", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound dialogCategoriesNBT(){
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
NBTTagList categoryList = new NBTTagList();
|
||||
for(DialogCategory category : DialogController.Instance.categories.values()){
|
||||
NBTTagCompound questCompound = new NBTTagCompound();
|
||||
NBTTagList dialogList = new NBTTagList();
|
||||
for(int dialogID : category.dialogs.keySet()){
|
||||
Dialog quest = category.dialogs.get(dialogID);
|
||||
dialogList.appendTag(quest.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
questCompound.setTag("Data", dialogList);
|
||||
questCompound.setTag("CatNBT", category.writeSmallNBT(new NBTTagCompound()));
|
||||
categoryList.appendTag(questCompound);
|
||||
}
|
||||
compound.setTag("DialogCategories", categoryList);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound questCategoriesNBT(){
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
NBTTagList categoryList = new NBTTagList();
|
||||
for(QuestCategory category : QuestController.Instance.categories.values()){
|
||||
NBTTagCompound questCompound = new NBTTagCompound();;
|
||||
NBTTagList questList = new NBTTagList();
|
||||
for(int questID : category.quests.keySet()){
|
||||
Quest quest = category.quests.get(questID);
|
||||
questList.appendTag(quest.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
questCompound.setTag("Data", questList);
|
||||
questCompound.setTag("CatNBT", category.writeSmallNBT(new NBTTagCompound()));
|
||||
categoryList.appendTag(questCompound);
|
||||
}
|
||||
compound.setTag("QuestCategories", categoryList);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound customEffectsNBT(){
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for (CustomEffect effect : CustomEffectController.getInstance().getCustomEffects().values()) {
|
||||
list.appendTag(effect.writeToNBT(false));
|
||||
}
|
||||
compound.setTag("Data", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound magicsNBT(){
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for (Magic magic : MagicController.getInstance().magics.values()) {
|
||||
NBTTagCompound magicCompound = new NBTTagCompound();
|
||||
magic.writeNBT(magicCompound);
|
||||
list.appendTag(magicCompound);
|
||||
}
|
||||
compound.setTag("Data", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound magicCyclesNBT(){
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for (MagicCycle cycle : MagicController.getInstance().cycles.values()) {
|
||||
NBTTagCompound cycleCompound = new NBTTagCompound();
|
||||
cycle.writeNBT(cycleCompound);
|
||||
list.appendTag(cycleCompound);
|
||||
}
|
||||
compound.setTag("Data", list);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static void syncPlayerData(EntityPlayerMP player, boolean update){
|
||||
PlayerData data = PlayerData.get(player);
|
||||
if(data != null){
|
||||
if(update){
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.PLAYERDATA,
|
||||
EnumSyncAction.UPDATE,
|
||||
-1,
|
||||
data.getSyncNBT())
|
||||
, player);
|
||||
} else {
|
||||
PacketHandler.Instance.sendToPlayer(new SyncPacket(
|
||||
EnumSyncType.PLAYERDATA,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
data.getSyncNBTFull()), player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void syncRemove(EnumSyncType enumSyncType, int id){
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
enumSyncType,
|
||||
EnumSyncAction.REMOVE,
|
||||
id,
|
||||
new NBTTagCompound()
|
||||
));
|
||||
}
|
||||
|
||||
public static void syncAllDialogs() {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
EnumSyncType.DIALOG_CATEGORY,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
dialogCategoriesNBT()
|
||||
));
|
||||
}
|
||||
|
||||
public static void syncAllQuests() {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
EnumSyncType.QUEST_CATEGORY,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
questCategoriesNBT()
|
||||
));
|
||||
}
|
||||
|
||||
public static void syncAllWorkbenchRecipes() {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
EnumSyncType.WORKBENCH_RECIPES,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
workbenchNBT()
|
||||
));
|
||||
}
|
||||
|
||||
public static void syncAllCarpentryRecipes() {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
EnumSyncType.CARPENTRY_RECIPES,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
carpentryNBT()
|
||||
));
|
||||
}
|
||||
|
||||
public static void syncAllAnvilRecipes() {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
EnumSyncType.ANVIL_RECIPES,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
anvilNBT()
|
||||
));
|
||||
}
|
||||
|
||||
public static void syncAllCustomEffects() {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
EnumSyncType.CUSTOM_EFFECTS,
|
||||
EnumSyncAction.RELOAD,
|
||||
-1,
|
||||
customEffectsNBT()
|
||||
));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void clientSync(EnumSyncType enumSyncType, NBTTagCompound fullCompound) {
|
||||
switch (enumSyncType){
|
||||
case FACTION: {
|
||||
NBTTagList list = fullCompound.getTagList("Factions", 10);
|
||||
for (int i = 0; i < list.tagCount(); i++) {
|
||||
Faction faction = new Faction();
|
||||
faction.readNBT(list.getCompoundTagAt(i));
|
||||
FactionController.getInstance().factionsSync.put(faction.id, faction);
|
||||
}
|
||||
FactionController.getInstance().factions = FactionController.getInstance().factionsSync;
|
||||
FactionController.getInstance().factionsSync = new HashMap<Integer, Faction>();
|
||||
break;
|
||||
}
|
||||
case DIALOG_CATEGORY: {
|
||||
if(!fullCompound.hasNoTags()){
|
||||
NBTTagList categories = fullCompound.getTagList("DialogCategories", 10);
|
||||
for(int j = 0; j < fullCompound.getTagList("DialogCategories", 10).tagCount(); j++) {
|
||||
NBTTagCompound categoryCompound = categories.getCompoundTagAt(j);
|
||||
if(categoryCompound.hasNoTags())
|
||||
continue;
|
||||
|
||||
DialogCategory category = new DialogCategory();
|
||||
category.readSmallNBT(categoryCompound.getCompoundTag("CatNBT"));
|
||||
NBTTagList dialogList = categoryCompound.getTagList("Data", 10);
|
||||
if(DialogController.Instance.categoriesSync.containsKey(category.id)){
|
||||
category = DialogController.Instance.categoriesSync.get(category.id);
|
||||
category.readSmallNBT(categoryCompound.getCompoundTag("CatNBT"));
|
||||
}
|
||||
for(int i = 0; i < dialogList.tagCount(); i++)
|
||||
{
|
||||
Dialog dialog = new Dialog();
|
||||
dialog.readNBT(dialogList.getCompoundTagAt(i));
|
||||
dialog.category = category;
|
||||
category.dialogs.put(dialog.id, dialog);
|
||||
}
|
||||
DialogController.Instance.categoriesSync.put(category.id, category);
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<Integer, Dialog> dialogs = new HashMap<Integer, Dialog>();
|
||||
for(DialogCategory category : DialogController.Instance.categoriesSync.values()){
|
||||
for(Dialog dialog : category.dialogs.values()){
|
||||
dialogs.put(dialog.id, dialog);
|
||||
}
|
||||
}
|
||||
|
||||
DialogController.Instance.categories = DialogController.Instance.categoriesSync;
|
||||
DialogController.Instance.dialogs = dialogs;
|
||||
DialogController.Instance.categoriesSync = new HashMap<Integer, DialogCategory>();
|
||||
break;
|
||||
}
|
||||
case QUEST_CATEGORY: {
|
||||
if(!fullCompound.hasNoTags()){
|
||||
NBTTagList categories = fullCompound.getTagList("QuestCategories", 10);
|
||||
for(int j = 0; j < fullCompound.getTagList("QuestCategories", 10).tagCount(); j++) {
|
||||
NBTTagCompound categoryCompound = categories.getCompoundTagAt(j);
|
||||
if(categoryCompound.hasNoTags())
|
||||
continue;
|
||||
|
||||
QuestCategory category = new QuestCategory();
|
||||
category.readSmallNBT(categoryCompound.getCompoundTag("CatNBT"));
|
||||
NBTTagList questList = categoryCompound.getTagList("Data", 10);
|
||||
if(QuestController.Instance.categoriesSync.containsKey(category.id)){
|
||||
category = QuestController.Instance.categoriesSync.get(category.id);
|
||||
category.readSmallNBT(categoryCompound.getCompoundTag("CatNBT"));
|
||||
}
|
||||
for(int i = 0; i < questList.tagCount(); i++)
|
||||
{
|
||||
Quest quest = new Quest();
|
||||
quest.readNBT(questList.getCompoundTagAt(i));
|
||||
quest.category = category;
|
||||
category.quests.put(quest.id, quest);
|
||||
}
|
||||
QuestController.Instance.categoriesSync.put(category.id, category);
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<Integer,Quest> quests = new HashMap<Integer, Quest>();
|
||||
for(QuestCategory category : QuestController.Instance.categoriesSync.values()){
|
||||
for(Quest quest : category.quests.values()){
|
||||
quests.put(quest.id, quest);
|
||||
}
|
||||
}
|
||||
|
||||
QuestController.Instance.categories = QuestController.Instance.categoriesSync;
|
||||
QuestController.Instance.quests = quests;
|
||||
QuestController.Instance.categoriesSync = new HashMap<Integer, QuestCategory>();
|
||||
break;
|
||||
}
|
||||
case PLAYERDATA: {
|
||||
ClientCacheHandler.playerData.setSyncNBTFull(fullCompound);
|
||||
break;
|
||||
}
|
||||
case MAGIC: {
|
||||
NBTTagList list = fullCompound.getTagList("Data", 10);
|
||||
MagicController mc = MagicController.getInstance();
|
||||
mc.magicSync.clear();
|
||||
for (int i = 0; i < list.tagCount(); i++) {
|
||||
Magic magic = new Magic();
|
||||
magic.readNBT(list.getCompoundTagAt(i));
|
||||
mc.magicSync.put(magic.id, magic);
|
||||
}
|
||||
|
||||
mc.magics.clear();
|
||||
mc.magics.putAll(mc.magicSync);
|
||||
mc.magicSync.clear();
|
||||
break;
|
||||
}
|
||||
case MAGIC_CYCLE: {
|
||||
NBTTagList list = fullCompound.getTagList("Data", 10);
|
||||
MagicController mc = MagicController.getInstance();
|
||||
mc.cyclesSync.clear();
|
||||
for (int i = 0; i < list.tagCount(); i++) {
|
||||
MagicCycle cycle = new MagicCycle();
|
||||
cycle.readNBT(list.getCompoundTagAt(i));
|
||||
mc.cyclesSync.put(cycle.id, cycle);
|
||||
}
|
||||
|
||||
mc.cycles.clear();
|
||||
mc.cycles.putAll(mc.cyclesSync);
|
||||
mc.cyclesSync.clear();
|
||||
break;
|
||||
}
|
||||
case WORKBENCH_RECIPES: {
|
||||
NBTTagList list = fullCompound.getTagList("recipes", 10);
|
||||
if(list == null)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
RecipeCarpentry recipe = RecipeCarpentry.read(list.getCompoundTagAt(i));
|
||||
RecipeController.syncRecipes.put(recipe.id,recipe);
|
||||
}
|
||||
|
||||
RecipeController.reloadGlobalRecipes(RecipeController.syncRecipes);
|
||||
RecipeController.syncRecipes = new HashMap<Integer, RecipeCarpentry>();
|
||||
break;
|
||||
}
|
||||
case CARPENTRY_RECIPES: {
|
||||
NBTTagList list = fullCompound.getTagList("recipes", 10);
|
||||
if(list == null)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
RecipeCarpentry recipe = RecipeCarpentry.read(list.getCompoundTagAt(i));
|
||||
RecipeController.syncRecipes.put(recipe.id,recipe);
|
||||
}
|
||||
|
||||
RecipeController.Instance.carpentryRecipes = RecipeController.syncRecipes;
|
||||
RecipeController.syncRecipes = new HashMap<Integer, RecipeCarpentry>();
|
||||
break;
|
||||
}
|
||||
case ANVIL_RECIPES: {
|
||||
NBTTagList list = fullCompound.getTagList("recipes", 10);
|
||||
if(list == null)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
RecipeAnvil recipe = RecipeAnvil.read(list.getCompoundTagAt(i));
|
||||
RecipeController.syncAnvilRecipes.put(recipe.id, recipe);
|
||||
}
|
||||
|
||||
RecipeController.Instance.anvilRecipes = RecipeController.syncAnvilRecipes;
|
||||
RecipeController.syncAnvilRecipes = new HashMap<Integer, RecipeAnvil>();
|
||||
break;
|
||||
}
|
||||
case CUSTOM_EFFECTS: {
|
||||
NBTTagList list = fullCompound.getTagList("Data", 10);
|
||||
CustomEffectController ce = CustomEffectController.getInstance();
|
||||
ce.customEffectsSync.clear();
|
||||
for (int i = 0; i < list.tagCount(); i++) {
|
||||
CustomEffect effect = new CustomEffect();
|
||||
effect.readFromNBT(list.getCompoundTagAt(i));
|
||||
ClientCacheHandler.getImageData(effect.icon);
|
||||
ce.customEffectsSync.put(effect.id, effect);
|
||||
}
|
||||
|
||||
ce.getCustomEffects().clear();
|
||||
ce.getCustomEffects().putAll(ce.customEffectsSync);
|
||||
ce.customEffectsSync.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Related Tasks
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void clientUpdate(EnumSyncType enumSyncType, int category_id, NBTTagCompound compound) {
|
||||
switch (enumSyncType){
|
||||
case FACTION: {
|
||||
Faction faction = new Faction();
|
||||
faction.readNBT(compound);
|
||||
FactionController.getInstance().factions.put(faction.id, faction);
|
||||
break;
|
||||
}
|
||||
case DIALOG: {
|
||||
DialogCategory category = DialogController.Instance.categories.get(category_id);
|
||||
Dialog dialog = new Dialog();
|
||||
dialog.category = category;
|
||||
dialog.readNBT(compound);
|
||||
DialogController.Instance.dialogs.put(dialog.id, dialog);
|
||||
category.dialogs.put(dialog.id, dialog);
|
||||
break;
|
||||
}
|
||||
case QUEST: {
|
||||
QuestCategory category = QuestController.Instance.categories.get(category_id);
|
||||
Quest quest = new Quest();
|
||||
quest.category = category;
|
||||
quest.readNBT(compound);
|
||||
QuestController.Instance.quests.put(quest.id, quest);
|
||||
category.quests.put(quest.id, quest);
|
||||
break;
|
||||
}
|
||||
case QUEST_CATEGORY: {
|
||||
QuestCategory category = new QuestCategory();
|
||||
category.readSmallNBT(compound.getCompoundTag("CatNBT"));
|
||||
NBTTagList list = compound.getTagList("Data", 10);
|
||||
if(QuestController.Instance.categoriesSync.containsKey(category.id)){
|
||||
category = QuestController.Instance.categoriesSync.get(category.id);
|
||||
category.readSmallNBT(compound.getCompoundTag("CatNBT"));
|
||||
}
|
||||
for(int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
Quest quest = new Quest();
|
||||
quest.readNBT(list.getCompoundTagAt(i));
|
||||
quest.category = category;
|
||||
category.quests.put(quest.id, quest);
|
||||
}
|
||||
QuestController.Instance.categories.put(category.id, category);
|
||||
break;
|
||||
}
|
||||
case DIALOG_CATEGORY: {
|
||||
DialogCategory category = new DialogCategory();
|
||||
category.readSmallNBT(compound.getCompoundTag("CatNBT"));
|
||||
NBTTagList list = compound.getTagList("Data", 10);
|
||||
if(DialogController.Instance.categoriesSync.containsKey(category.id)){
|
||||
category = DialogController.Instance.categoriesSync.get(category.id);
|
||||
category.readSmallNBT(compound.getCompoundTag("CatNBT"));
|
||||
}
|
||||
for(int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
Dialog dialog = new Dialog();
|
||||
dialog.readNBT(list.getCompoundTagAt(i));
|
||||
dialog.category = category;
|
||||
category.dialogs.put(dialog.id, dialog);
|
||||
}
|
||||
DialogController.Instance.categories.put(category.id, category);
|
||||
break;
|
||||
}
|
||||
case MAGIC_CYCLE: {
|
||||
MagicCycle cycle = new MagicCycle();
|
||||
cycle.readNBT(compound);
|
||||
MagicController.getInstance().cycles.put(cycle.id, cycle);
|
||||
break;
|
||||
}
|
||||
case MAGIC: {
|
||||
Magic magic = new Magic();
|
||||
magic.readNBT(compound);
|
||||
MagicController.getInstance().magics.put(magic.id, magic);
|
||||
break;
|
||||
}
|
||||
case PLAYERDATA: {
|
||||
ClientCacheHandler.playerData.setSyncNBT(compound);
|
||||
break;
|
||||
}
|
||||
case CUSTOM_EFFECTS: {
|
||||
CustomEffect effect = new CustomEffect();
|
||||
effect.readFromNBT(compound);
|
||||
ClientCacheHandler.getImageData(effect.icon);
|
||||
|
||||
CustomEffectController.Instance.getCustomEffects().put(effect.id, effect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void syncUpdate(EnumSyncType type, int cat, NBTTagCompound compound) {
|
||||
PacketHandler.Instance.sendToAll(new SyncPacket(
|
||||
type,
|
||||
EnumSyncAction.UPDATE,
|
||||
cat,
|
||||
compound
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
public static NBTTagCompound updateQuestCat(QuestCategory questCategory) {
|
||||
NBTTagCompound questCompound = new NBTTagCompound();
|
||||
NBTTagList questList = new NBTTagList();
|
||||
for(int questID : questCategory.quests.keySet()){
|
||||
Quest quest = questCategory.quests.get(questID);
|
||||
questList.appendTag(quest.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
questCompound.setTag("Data", questList);
|
||||
questCompound.setTag("CatNBT", questCategory.writeSmallNBT(new NBTTagCompound()));
|
||||
return questCompound;
|
||||
}
|
||||
|
||||
public static NBTTagCompound updateDialogCat(DialogCategory dialogCategory) {
|
||||
NBTTagCompound dialogCompound = new NBTTagCompound();
|
||||
NBTTagList dialogList = new NBTTagList();
|
||||
for(int questID : dialogCategory.dialogs.keySet()){
|
||||
Dialog dialog = dialogCategory.dialogs.get(questID);
|
||||
dialogList.appendTag(dialog.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
dialogCompound.setTag("Data", dialogList);
|
||||
dialogCompound.setTag("CatNBT", dialogCategory.writeSmallNBT(new NBTTagCompound()));
|
||||
return dialogCompound;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void clientSyncRemove(EnumSyncType enumSyncType, int id) {
|
||||
switch (enumSyncType){
|
||||
case FACTION:
|
||||
FactionController.getInstance().factions.remove(id);
|
||||
break;
|
||||
case DIALOG:
|
||||
Dialog dialog = DialogController.Instance.dialogs.remove(id);
|
||||
if(dialog != null) {
|
||||
dialog.category.dialogs.remove(id);
|
||||
}
|
||||
break;
|
||||
case DIALOG_CATEGORY:
|
||||
DialogCategory dialogCategory = DialogController.Instance.categories.remove(id);
|
||||
if(dialogCategory != null) {
|
||||
DialogController.Instance.dialogs.keySet().removeAll(dialogCategory.dialogs.keySet());
|
||||
}
|
||||
break;
|
||||
case QUEST:
|
||||
Quest quest = QuestController.Instance.quests.remove(id);
|
||||
if(quest != null) {
|
||||
quest.category.quests.remove(id);
|
||||
}
|
||||
break;
|
||||
case QUEST_CATEGORY:
|
||||
QuestCategory questCategory = QuestController.Instance.categories.remove(id);
|
||||
if(questCategory != null) {
|
||||
QuestController.Instance.quests.keySet().removeAll(questCategory.quests.keySet());
|
||||
}
|
||||
break;
|
||||
case MAGIC:
|
||||
for(MagicCycle cycle : MagicController.getInstance().cycles.values()){
|
||||
cycle.associations.remove(id);
|
||||
}
|
||||
MagicController.getInstance().cycles.remove(id);
|
||||
break;
|
||||
case MAGIC_CYCLE:
|
||||
MagicController.getInstance().cycles.remove(id);
|
||||
break;
|
||||
case CUSTOM_EFFECTS:
|
||||
CustomEffectController.Instance.getCustomEffects().remove(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void syncEffects(EntityPlayerMP playerMP){
|
||||
ConcurrentHashMap<EffectKey, PlayerEffect> playerEffects = CustomEffectController.getInstance().getPlayerEffects(playerMP);
|
||||
PlayerData playerData = PlayerData.get(playerMP);
|
||||
playerData.effectData.setEffects(playerEffects);
|
||||
|
||||
NBTTagCompound compound = playerData.getPlayerEffects();
|
||||
PacketHandler.Instance.sendToPlayer(new SyncEffectPacket(compound), playerMP);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void clientSyncEffects(NBTTagCompound compound) {
|
||||
PlayerData playerData = PlayerData.get(Minecraft.getMinecraft().thePlayer);
|
||||
if(playerData != null){
|
||||
playerData.setPlayerEffects(compound);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package kamkeel.npcs.controllers.data.attribute;
|
||||
|
||||
public class AttributeDefinition {
|
||||
private final String key;
|
||||
private String translationKey;// e.g., "main_attack_flat"
|
||||
private final String displayName; // Human‑readable name
|
||||
private final char colorCode;
|
||||
private final AttributeValueType attributeValueType;
|
||||
private final AttributeSection section;
|
||||
|
||||
public AttributeDefinition(String key, String displayName, char colorCode, AttributeValueType attributeValueType, AttributeSection section) {
|
||||
this.key = key;
|
||||
this.translationKey = "rpgcore:attribute." + key;
|
||||
this.displayName = displayName;
|
||||
this.attributeValueType = attributeValueType;
|
||||
this.section = section;
|
||||
this.colorCode = colorCode;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getTranslationKey() {
|
||||
return translationKey;
|
||||
}
|
||||
|
||||
public void setTranslationKey(String translationKey) {
|
||||
this.translationKey = translationKey;
|
||||
}
|
||||
|
||||
public AttributeValueType getValueType() {
|
||||
return attributeValueType;
|
||||
}
|
||||
|
||||
public AttributeSection getSection() {
|
||||
return section;
|
||||
}
|
||||
|
||||
public char getColorCode() {
|
||||
return colorCode;
|
||||
}
|
||||
|
||||
public enum AttributeSection {
|
||||
BASE,
|
||||
MODIFIER,
|
||||
STATS,
|
||||
INFO,
|
||||
EXTRA;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package kamkeel.npcs.controllers.data.attribute;
|
||||
|
||||
public enum AttributeValueType {
|
||||
FLAT, // e.g., +10 Health or +3 Damage
|
||||
PERCENT, // e.g., +0.25 means +25% bonus
|
||||
MAGIC // Represents a container of magic–based values (summed up as a float)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package kamkeel.npcs.controllers.data.attribute;
|
||||
|
||||
/**
|
||||
* IAttributeInstance represents an instance of an attribute (with a base value and applied modifiers).
|
||||
*/
|
||||
public interface ICustomAttribute {
|
||||
AttributeDefinition getAttribute();
|
||||
float getValue();
|
||||
void setValue(float value);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package kamkeel.npcs.controllers.data.attribute;
|
||||
|
||||
|
||||
public class PlayerAttribute implements ICustomAttribute {
|
||||
private final AttributeDefinition attribute;
|
||||
private float baseValue;
|
||||
|
||||
public PlayerAttribute(AttributeDefinition attribute, float baseValue) {
|
||||
this.attribute = attribute;
|
||||
this.baseValue = baseValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeDefinition getAttribute() {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getValue() {
|
||||
return baseValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(float value) {
|
||||
this.baseValue = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package kamkeel.npcs.controllers.data.attribute;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* CustomAttributeMap holds a set of attribute instances for an entity (or item).
|
||||
*/
|
||||
public class PlayerAttributeMap {
|
||||
private final Map<AttributeDefinition, ICustomAttribute> map = new HashMap<>();
|
||||
|
||||
public ICustomAttribute registerAttribute(AttributeDefinition attribute, float baseValue) {
|
||||
if (map.containsKey(attribute)) {
|
||||
throw new IllegalArgumentException("Attribute already registered: " + attribute.getKey());
|
||||
}
|
||||
ICustomAttribute instance = new PlayerAttribute(attribute, baseValue);
|
||||
map.put(attribute, instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ICustomAttribute getAttributeInstance(AttributeDefinition attribute) {
|
||||
return map.get(attribute);
|
||||
}
|
||||
|
||||
public Collection<ICustomAttribute> getAllAttributes() {
|
||||
return map.values();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.requirement;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public interface IRequirementChecker {
|
||||
|
||||
public String getKey();
|
||||
|
||||
public String getTranslation();
|
||||
|
||||
String getTooltipValue(NBTTagCompound nbt);
|
||||
|
||||
void apply(NBTTagCompound nbt, Object value);
|
||||
|
||||
/**
|
||||
* Checks the requirement in the provided NBT.
|
||||
* Return false if the requirement isn’t met.
|
||||
*/
|
||||
boolean check(EntityPlayer player, NBTTagCompound nbt);
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.requirement;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RequirementCheckerRegistry {
|
||||
private static final Map<String, IRequirementChecker> checkers = new HashMap<>();
|
||||
|
||||
public static void registerChecker(IRequirementChecker checker) {
|
||||
if (!checkers.containsKey(checker.getKey())) {
|
||||
checkers.put(checker.getKey(), checker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops over all registered requirement keys.
|
||||
* For each key present in the NBT, its checker must return true.
|
||||
*/
|
||||
public static boolean checkRequirements(EntityPlayer player, NBTTagCompound nbt) {
|
||||
for (Map.Entry<String, IRequirementChecker> entry : checkers.entrySet()) {
|
||||
String reqKey = entry.getKey();
|
||||
if (nbt.hasKey(reqKey)) {
|
||||
if (!entry.getValue().check(player, nbt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Set<String> getAllKeys() {
|
||||
return checkers.keySet();
|
||||
}
|
||||
|
||||
public static IRequirementChecker getChecker(String key) {
|
||||
return checkers.get(key);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.requirement.types;
|
||||
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.IRequirementChecker;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
|
||||
public class QuestActiveRequirement implements IRequirementChecker {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "cnpc_quest_active";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslation() {
|
||||
return "quest.active";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltipValue(NBTTagCompound nbt) {
|
||||
if(nbt.hasKey(getKey())) {
|
||||
int questID = nbt.getInteger(getKey());
|
||||
if(QuestController.Instance.get(questID) != null) {
|
||||
return QuestController.Instance.get(questID).getName();
|
||||
}
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(NBTTagCompound nbt, Object value) {
|
||||
if(value instanceof Integer) {
|
||||
nbt.setInteger(getKey(), (Integer) value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(EntityPlayer player, NBTTagCompound nbt) {
|
||||
if(nbt.hasKey(getKey())) {
|
||||
int questID = nbt.getInteger(getKey());
|
||||
return PlayerData.get(player).questData.hasActiveQuest(questID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.requirement.types;
|
||||
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.IRequirementChecker;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
|
||||
public class QuestCompletedRequirement implements IRequirementChecker {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "cnpc_quest_completed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslation() {
|
||||
return "quest.quest";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltipValue(NBTTagCompound nbt) {
|
||||
if(nbt.hasKey(getKey())) {
|
||||
int questID = nbt.getInteger(getKey());
|
||||
if(QuestController.Instance.get(questID) != null) {
|
||||
return QuestController.Instance.get(questID).getName();
|
||||
}
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(NBTTagCompound nbt, Object value) {
|
||||
if(value instanceof Integer) {
|
||||
nbt.setInteger(getKey(), (Integer) value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(EntityPlayer player, NBTTagCompound nbt) {
|
||||
if(nbt.hasKey(getKey())) {
|
||||
int questID = nbt.getInteger(getKey());
|
||||
return PlayerData.get(player).questData.hasFinishedQuest(questID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.tracker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public class AttributeRecalcEvent {
|
||||
private static final List<IAttributeRecalcListener> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Allows other mods to register a listener that is called after attribute recalculation.
|
||||
*/
|
||||
public static void registerListener(IAttributeRecalcListener listener) {
|
||||
if (listener != null && !listeners.contains(listener)) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts an event to all registered listeners.
|
||||
*/
|
||||
public static void post(EntityPlayer player, PlayerAttributeTracker tracker) {
|
||||
for (IAttributeRecalcListener listener : listeners) {
|
||||
listener.onAttributesRecalculated(player, tracker);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.tracker;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
/**
|
||||
* Implement this interface to receive a callback after a player's attributes have been recalculated.
|
||||
*/
|
||||
public interface IAttributeRecalcListener {
|
||||
void onAttributesRecalculated(EntityPlayer player, PlayerAttributeTracker tracker);
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.tracker;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import kamkeel.npcs.CustomAttributes;
|
||||
import kamkeel.npcs.controllers.AttributeController;
|
||||
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
|
||||
import kamkeel.npcs.controllers.data.attribute.ICustomAttribute;
|
||||
import kamkeel.npcs.controllers.data.attribute.PlayerAttributeMap;
|
||||
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
|
||||
import kamkeel.npcs.util.AttributeAttackUtil;
|
||||
import kamkeel.npcs.util.AttributeItemUtil;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.entity.ai.attributes.IAttributeInstance;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class PlayerAttributeTracker {
|
||||
|
||||
public static UUID healthUUID = UUID.fromString("48a0ad75-2cf8-4838-ad2f-9a0aadc57dfe");
|
||||
|
||||
|
||||
private final UUID playerId;
|
||||
private PlayerAttributeMap playerAttributes = new PlayerAttributeMap();
|
||||
|
||||
public float extraHealth = 0;
|
||||
public float maximumOutput = 0.0f;
|
||||
|
||||
public final Map<Integer, Float> magicDamage = new HashMap<>();
|
||||
public final Map<Integer, Float> magicBoost = new HashMap<>();
|
||||
public final Map<Integer, Float> magicDefense = new HashMap<>();
|
||||
public final Map<Integer, Float> magicResistance = new HashMap<>();
|
||||
|
||||
private PlayerEquipmentTracker equipmentTracker = new PlayerEquipmentTracker();
|
||||
|
||||
public PlayerAttributeTracker(UUID playerId) {
|
||||
this.playerId = playerId;
|
||||
// Initial recalc with base damage 0.
|
||||
recalcAttributes(null);
|
||||
}
|
||||
|
||||
public PlayerAttributeMap getPlayerAttributes() {
|
||||
return playerAttributes;
|
||||
}
|
||||
|
||||
public void recalcAttributes(EntityPlayer player) {
|
||||
// Reset aggregated attributes and magic maps.
|
||||
playerAttributes = new PlayerAttributeMap();
|
||||
magicDamage.clear();
|
||||
magicBoost.clear();
|
||||
magicDefense.clear();
|
||||
magicResistance.clear();
|
||||
if (player != null) {
|
||||
// Update equipment tracker.
|
||||
PlayerEquipmentTracker currentEquip = new PlayerEquipmentTracker();
|
||||
currentEquip.updateFrom(player);
|
||||
ItemStack[] equipment = new ItemStack[] { currentEquip.heldItem, currentEquip.boots, currentEquip.leggings, currentEquip.chestplate, currentEquip.helmet };
|
||||
for (ItemStack piece : equipment) {
|
||||
if (piece != null) {
|
||||
if (piece.stackTagCompound != null && piece.stackTagCompound.hasKey(AttributeItemUtil.TAG_RPGCORE)) {
|
||||
NBTTagCompound rpgCore = piece.stackTagCompound.getCompoundTag(AttributeItemUtil.TAG_RPGCORE);
|
||||
if (rpgCore.hasKey(AttributeItemUtil.TAG_REQUIREMENTS)) {
|
||||
NBTTagCompound reqTag = rpgCore.getCompoundTag(AttributeItemUtil.TAG_REQUIREMENTS);
|
||||
if (!RequirementCheckerRegistry.checkRequirements(player, reqTag)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, Float> entry : AttributeItemUtil.readAttributes(piece).entrySet()) {
|
||||
String key = entry.getKey();
|
||||
float value = entry.getValue();
|
||||
AttributeDefinition def = AttributeController.getAttribute(key);
|
||||
if (def != null) {
|
||||
ICustomAttribute inst = playerAttributes.getAttributeInstance(def);
|
||||
if (inst == null) {
|
||||
inst = playerAttributes.registerAttribute(def, 0.0f);
|
||||
}
|
||||
inst.setValue(inst.getValue() + value);
|
||||
}
|
||||
}
|
||||
// Process Magic
|
||||
|
||||
// OFFENSIVE MAGIC
|
||||
Map<Integer, Float> magicFlat = AttributeItemUtil.readMagicAttributeMap(piece, CustomAttributes.MAGIC_DAMAGE_KEY);
|
||||
for (Entry<Integer, Float> entry : magicFlat.entrySet()) {
|
||||
int magicId = entry.getKey();
|
||||
float value = entry.getValue();
|
||||
magicDamage.put(magicId, magicDamage.getOrDefault(magicId, 0.0f) + value);
|
||||
}
|
||||
Map<Integer, Float> magicPercent = AttributeItemUtil.readMagicAttributeMap(piece, CustomAttributes.MAGIC_BOOST_KEY);
|
||||
for (Entry<Integer, Float> entry : magicPercent.entrySet()) {
|
||||
int magicId = entry.getKey();
|
||||
float value = entry.getValue();
|
||||
magicBoost.put(magicId, magicBoost.getOrDefault(magicId, 0.0f) + value);
|
||||
}
|
||||
|
||||
// DEFENSIVE MAGIC
|
||||
Map<Integer, Float> magicDefFlat = AttributeItemUtil.readMagicAttributeMap(piece, CustomAttributes.MAGIC_DEFENSE_KEY);
|
||||
for (Entry<Integer, Float> entry : magicDefFlat.entrySet()) {
|
||||
int magicId = entry.getKey();
|
||||
float value = entry.getValue();
|
||||
magicDefense.put(magicId, magicDefense.getOrDefault(magicId, 0.0f) + value);
|
||||
}
|
||||
Map<Integer, Float> magicResist = AttributeItemUtil.readMagicAttributeMap(piece, CustomAttributes.MAGIC_RESISTANCE_KEY);
|
||||
for (Entry<Integer, Float> entry : magicResist.entrySet()) {
|
||||
int magicId = entry.getKey();
|
||||
float value = entry.getValue();
|
||||
magicResistance.put(magicId, magicResistance.getOrDefault(magicId, 0.0f) + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
equipmentTracker = currentEquip;
|
||||
maximumOutput = AttributeAttackUtil.calculateMaximumOutput(this);
|
||||
extraHealth = getAttributeValue(CustomAttributes.HEALTH);
|
||||
|
||||
updatePlayerMaxHealth(player);
|
||||
|
||||
// Post Recalculation Event to Listeners
|
||||
AttributeRecalcEvent.post(player, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the player's maximum health attribute by applying a custom attribute modifier.
|
||||
* In this system, the aggregated HEALTH attribute is treated as bonus health on top of a base of 20.
|
||||
*
|
||||
* @param player The EntityPlayer whose max health should be updated.
|
||||
*/
|
||||
public void updatePlayerMaxHealth(EntityPlayer player) {
|
||||
float bonusHealth = extraHealth;
|
||||
IAttributeInstance maxHealthAttr = player.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth);
|
||||
try {
|
||||
AttributeModifier old = maxHealthAttr.getModifier(healthUUID);
|
||||
if (old != null) {
|
||||
maxHealthAttr.removeModifier(old);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
if (bonusHealth != 0) {
|
||||
maxHealthAttr.applyModifier(new AttributeModifier(healthUUID, "RPGCoreHealthBonus", bonusHealth, 0));
|
||||
}
|
||||
// Ensure the player's current health does not exceed the new maximum.
|
||||
float currentHealth = player.getHealth();
|
||||
if (currentHealth > maxHealthAttr.getAttributeValue()) {
|
||||
player.setHealth((float) maxHealthAttr.getAttributeValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player's equipment has changed and recalculates attributes if needed.
|
||||
*/
|
||||
public void updateIfChanged(EntityPlayer player) {
|
||||
PlayerEquipmentTracker currentEquip = new PlayerEquipmentTracker();
|
||||
currentEquip.updateFrom(player);
|
||||
if (!equipmentTracker.equals(player)) {
|
||||
recalcAttributes(player);
|
||||
}
|
||||
}
|
||||
|
||||
public float getAttributeValue(AttributeDefinition def) {
|
||||
ICustomAttribute inst = playerAttributes.getAttributeInstance(def);
|
||||
return inst != null ? inst.getValue() : 0.0f;
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package kamkeel.npcs.controllers.data.attribute.tracker;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import kamkeel.npcs.util.AttributeItemUtil;
|
||||
|
||||
public class PlayerEquipmentTracker {
|
||||
public ItemStack heldItem;
|
||||
public ItemStack helmet;
|
||||
public ItemStack chestplate;
|
||||
public ItemStack leggings;
|
||||
public ItemStack boots;
|
||||
|
||||
/**
|
||||
* Updates the stored equipment based on the player's current held item and armor.
|
||||
*/
|
||||
public void updateFrom(EntityPlayer player) {
|
||||
heldItem = copyIfNotNull(player.getHeldItem());
|
||||
ItemStack[] armor = player.inventory.armorInventory;
|
||||
// Armor inventory order: 0=boots, 1=leggings, 2=chestplate, 3=helmet.
|
||||
boots = copyIfNotNull(armor[0]);
|
||||
leggings = copyIfNotNull(armor[1]);
|
||||
chestplate = copyIfNotNull(armor[2]);
|
||||
helmet = copyIfNotNull(armor[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the stored equipment with the player's current equipment.
|
||||
* Ignores changes like durability by comparing the item and the CNPCAttributes NBT only.
|
||||
*/
|
||||
public boolean equals(EntityPlayer player) {
|
||||
if (player == null) return false;
|
||||
if (!areItemStacksEquivalent(heldItem, player.getHeldItem())) return false;
|
||||
ItemStack[] armor = player.inventory.armorInventory;
|
||||
if (!areItemStacksEquivalent(boots, armor[0])) return false;
|
||||
if (!areItemStacksEquivalent(leggings, armor[1])) return false;
|
||||
if (!areItemStacksEquivalent(chestplate, armor[2])) return false;
|
||||
if (!areItemStacksEquivalent(helmet, armor[3])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the given ItemStack, or null if it is null.
|
||||
*/
|
||||
private ItemStack copyIfNotNull(ItemStack stack) {
|
||||
return (stack == null) ? null : stack.copy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two ItemStacks for equivalence, ignoring durability differences.
|
||||
* It checks if the items are the same and if the "CNPCAttributes" NBT compound is equal.
|
||||
*/
|
||||
private boolean areItemStacksEquivalent(ItemStack a, ItemStack b) {
|
||||
if (a == b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
if (a.getItem() != b.getItem()) return false;
|
||||
NBTTagCompound tagA = a.stackTagCompound;
|
||||
NBTTagCompound tagB = b.stackTagCompound;
|
||||
String attrA = (tagA != null && tagA.hasKey(AttributeItemUtil.TAG_RPGCORE))
|
||||
? tagA.getCompoundTag(AttributeItemUtil.TAG_RPGCORE).toString() : "";
|
||||
String attrB = (tagB != null && tagB.hasKey(AttributeItemUtil.TAG_RPGCORE))
|
||||
? tagB.getCompoundTag(AttributeItemUtil.TAG_RPGCORE).toString() : "";
|
||||
return attrA.equals(attrB);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.SyncController;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CNPCData implements IProfileData {
|
||||
|
||||
@Override
|
||||
public String getTagName() {
|
||||
return "CNPC+";
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getCurrentNBT(EntityPlayer player) {
|
||||
PlayerData customNPCData = PlayerData.get(player);
|
||||
return customNPCData.getNBT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(EntityPlayer player) {
|
||||
PlayerData customNPCData = PlayerData.get(player);
|
||||
customNPCData.save();
|
||||
SyncController.syncPlayerData((EntityPlayerMP) player, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNBT(EntityPlayer player, NBTTagCompound replace) {
|
||||
PlayerData customNPCData = PlayerData.get(player);
|
||||
if(replace.hasNoTags()){
|
||||
PlayerData newData = new PlayerData();
|
||||
newData.player = player;
|
||||
customNPCData.setNBT((NBTTagCompound) newData.getNBT().copy());
|
||||
}
|
||||
else {
|
||||
customNPCData.setNBT(replace);
|
||||
}
|
||||
customNPCData.updateClient = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSwitchPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileOperation verifySwitch(EntityPlayer player) {
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
if(playerData.partyUUID != null)
|
||||
return ProfileOperation.error("Cannot switch while in Party");
|
||||
|
||||
return ProfileOperation.success("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProfileInfoEntry> getInfo(EntityPlayer player, NBTTagCompound compound) {
|
||||
PlayerData playerData = new PlayerData();
|
||||
playerData.player = player;
|
||||
playerData.setNBT(compound);
|
||||
|
||||
List<ProfileInfoEntry> info = new ArrayList<>();
|
||||
info.add(new ProfileInfoEntry("profile.info.quest.finished", 0x60fa57, playerData.questData.finishedQuests.size(), 0xFFFFFF));
|
||||
info.add(new ProfileInfoEntry("profile.info.quest.active", 0xf75336, playerData.questData.activeQuests.size(), 0xFFFFFF));
|
||||
info.add(new ProfileInfoEntry("profile.info.dialog.read", 0x47acf5, playerData.dialogData.dialogsRead.size(), 0xFFFFFF));
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
public enum EnumProfileOperation {
|
||||
SUCCESS,
|
||||
ERROR,
|
||||
LOCKED
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IProfileData {
|
||||
|
||||
/**
|
||||
* Do not use the tags: Name, lastLoaded, ID.
|
||||
* @return The save tag utilized in the Profile.
|
||||
*/
|
||||
public String getTagName();
|
||||
|
||||
/**
|
||||
* @return NBTTagCompound of the current data for a given EntityPlayer.
|
||||
*/
|
||||
public NBTTagCompound getCurrentNBT(EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Called immediately after setNBT() to replace existing NBT.
|
||||
*/
|
||||
public void save(EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Replaces the current data operation when changing profiles.
|
||||
*/
|
||||
public void setNBT(EntityPlayer player, NBTTagCompound replace);
|
||||
|
||||
/**
|
||||
* Returns the priority for this ProfileData's verification check.
|
||||
* Lower numbers run first.
|
||||
*/
|
||||
public int getSwitchPriority();
|
||||
|
||||
/**
|
||||
* Called before a profile switch occurs.
|
||||
* @param player The player switching profiles.
|
||||
* @return true if allowed, false if not.
|
||||
*/
|
||||
public ProfileOperation verifySwitch(EntityPlayer player);
|
||||
|
||||
/**
|
||||
* NEW: Builds and returns a list of informational strings about this profile data,
|
||||
* based on the provided NBTTagCompound from the slot.
|
||||
* @param player The player in question.
|
||||
* @param compound The NBT data from the slot under this profile data's tag.
|
||||
* @return A list of InfoEntry with information
|
||||
*/
|
||||
public List<ProfileInfoEntry> getInfo(EntityPlayer player, NBTTagCompound compound);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.NoppesUtilServer;
|
||||
import noppes.npcs.api.entity.IPlayer;
|
||||
import noppes.npcs.api.handler.data.IProfile;
|
||||
import noppes.npcs.api.handler.data.ISlot;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Profile implements IProfile {
|
||||
public EntityPlayer player;
|
||||
public int currentSlotId;
|
||||
private Map<Integer, ISlot> slots = new HashMap<>();
|
||||
private boolean locked = false;
|
||||
|
||||
public Profile(EntityPlayer player, NBTTagCompound compound) {
|
||||
this.player = player;
|
||||
if(compound.hasKey("CurrentSlotId")){
|
||||
this.currentSlotId = compound.getInteger("CurrentSlotId");
|
||||
} else {
|
||||
this.currentSlotId = 0;
|
||||
}
|
||||
|
||||
if(compound.hasKey("Slots")){
|
||||
NBTTagCompound slotsCompound = compound.getCompoundTag("Slots");
|
||||
Set<String> keys = slotsCompound.func_150296_c();
|
||||
for(String key : keys) {
|
||||
try {
|
||||
int slotId = Integer.parseInt(key);
|
||||
NBTTagCompound slotNBT = slotsCompound.getCompoundTag(key);
|
||||
ISlot slot = Slot.fromNBT(slotId, slotNBT);
|
||||
slots.put(slotId, slot);
|
||||
} catch (NumberFormatException e) {
|
||||
// Skip keys that are not valid slot IDs.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Profile(EntityPlayer player) {
|
||||
this.player = player;
|
||||
this.currentSlotId = 0;
|
||||
// Create a default slot.
|
||||
Slot defaultSlot = new Slot(0, "Default Slot");
|
||||
defaultSlot.setLastLoaded(System.currentTimeMillis());
|
||||
slots.put(0, defaultSlot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPlayer getPlayer() {
|
||||
return NoppesUtilServer.getIPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentSlotId() {
|
||||
return currentSlotId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, ISlot> getSlots() {
|
||||
return slots;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT() {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
if(player != null)
|
||||
compound.setString("Name", player.getCommandSenderName());
|
||||
compound.setInteger("CurrentSlotId", currentSlotId);
|
||||
NBTTagCompound slotsCompound = new NBTTagCompound();
|
||||
for(Map.Entry<Integer, ISlot> entry : slots.entrySet()) {
|
||||
// Save only non-temporary slots.
|
||||
if(entry.getValue().isTemporary())
|
||||
continue;
|
||||
slotsCompound.setTag(String.valueOf(entry.getKey()), entry.getValue().toNBT());
|
||||
}
|
||||
compound.setTag("Slots", slotsCompound);
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ProfileInfoEntry {
|
||||
private String label;
|
||||
private String result;
|
||||
private int labelColor;
|
||||
private int resultColor;
|
||||
|
||||
public ProfileInfoEntry() {}
|
||||
|
||||
public ProfileInfoEntry(String label, int labelColor, String result, int resultColor) {
|
||||
this.label = label;
|
||||
this.result = result;
|
||||
this.labelColor = labelColor;
|
||||
this.resultColor = resultColor;
|
||||
}
|
||||
|
||||
public ProfileInfoEntry(String label, int labelColor, int result, int resultColor) {
|
||||
this(label, labelColor, String.valueOf(result), resultColor);
|
||||
}
|
||||
|
||||
public ProfileInfoEntry(String label, String result) {
|
||||
this(label, 0xFFFFFF, result, 0xFFFFFF);
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNBT() {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("Label", label);
|
||||
tag.setInteger("LabelColor", labelColor);
|
||||
tag.setString("Result", result);
|
||||
tag.setInteger("ResultColor", resultColor);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static ProfileInfoEntry readFromNBT(NBTTagCompound tag) {
|
||||
return new ProfileInfoEntry(
|
||||
tag.getString("Label"),
|
||||
tag.getInteger("LabelColor"),
|
||||
tag.getString("Result"),
|
||||
tag.getInteger("ResultColor")
|
||||
);
|
||||
}
|
||||
|
||||
public String getLabel() { return label; }
|
||||
public String getResult() { return result; }
|
||||
public int getLabelColor() { return labelColor; }
|
||||
public int getResultColor() { return resultColor; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
public class ProfileOperation {
|
||||
private final EnumProfileOperation result;
|
||||
private final String message;
|
||||
|
||||
public ProfileOperation(EnumProfileOperation result, String message) {
|
||||
this.result = result;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public EnumProfileOperation getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static ProfileOperation success(String message) {
|
||||
return new ProfileOperation(EnumProfileOperation.SUCCESS, message);
|
||||
}
|
||||
|
||||
public static ProfileOperation error(String message) {
|
||||
return new ProfileOperation(EnumProfileOperation.ERROR, message);
|
||||
}
|
||||
|
||||
public static ProfileOperation locked(String message) {
|
||||
return new ProfileOperation(EnumProfileOperation.LOCKED, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package kamkeel.npcs.controllers.data.profile;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.api.handler.data.ISlot;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Slot implements ISlot {
|
||||
private int id;
|
||||
private String name;
|
||||
private long lastLoaded;
|
||||
private boolean temporary;
|
||||
private Map<String, NBTTagCompound> components = new HashMap<>();
|
||||
|
||||
public Slot(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Slot(int id, String name, long lastLoaded, boolean temporary, Map<String, NBTTagCompound> components) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.lastLoaded = lastLoaded;
|
||||
this.temporary = temporary;
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastLoaded() {
|
||||
return lastLoaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastLoaded(long time) {
|
||||
this.lastLoaded = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTemporary() {
|
||||
return temporary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemporary(boolean temporary) {
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, NBTTagCompound> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentData(String key, NBTTagCompound data) {
|
||||
components.put(key, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getComponentData(String key) {
|
||||
return components.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound toNBT() {
|
||||
NBTTagCompound slotNBT = new NBTTagCompound();
|
||||
slotNBT.setString("Name", name);
|
||||
slotNBT.setLong("LastLoaded", lastLoaded);
|
||||
slotNBT.setBoolean("Temporary", temporary);
|
||||
NBTTagCompound compCompound = new NBTTagCompound();
|
||||
for (Map.Entry<String, NBTTagCompound> entry : components.entrySet()) {
|
||||
compCompound.setTag(entry.getKey(), entry.getValue());
|
||||
}
|
||||
slotNBT.setTag("Components", compCompound);
|
||||
return slotNBT;
|
||||
}
|
||||
|
||||
public static Slot fromNBT(int id, NBTTagCompound slotNBT) {
|
||||
String name = slotNBT.getString("Name");
|
||||
long lastLoaded = slotNBT.getLong("LastLoaded");
|
||||
boolean temporary = slotNBT.getBoolean("Temporary");
|
||||
Slot slot = new Slot(id, name);
|
||||
slot.setLastLoaded(lastLoaded);
|
||||
slot.setTemporary(temporary);
|
||||
if (slotNBT.hasKey("Components")) {
|
||||
NBTTagCompound compCompound = slotNBT.getCompoundTag("Components");
|
||||
Set<String> keys = compCompound.func_150296_c();
|
||||
for (String key : keys) {
|
||||
slot.setComponentData(key, compCompound.getCompoundTag(key));
|
||||
}
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package kamkeel.developer;
|
||||
package kamkeel.npcs.developer;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
+33
-6
@@ -1,17 +1,20 @@
|
||||
package kamkeel.network;
|
||||
package kamkeel.npcs.network;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractPacket {
|
||||
|
||||
public EntityNPCInterface npc;
|
||||
|
||||
public FMLProxyPacket generatePacket() {
|
||||
PacketChannel packetChannel = getChannel();
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
@@ -19,13 +22,37 @@ public abstract class AbstractPacket {
|
||||
buf.writeInt(packetChannel.getChannelType().ordinal());
|
||||
buf.writeInt(getType().ordinal());
|
||||
sendData(buf);
|
||||
return new FMLProxyPacket(buf, getChannel().getChannelName());
|
||||
} catch (Exception ignored) {}
|
||||
return new FMLProxyPacket(buf, packetChannel.getChannelName());
|
||||
} catch (Exception e) {
|
||||
// For debugging, you might want to log it
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<FMLProxyPacket> generatePackets() {
|
||||
FMLProxyPacket single = generatePacket();
|
||||
if (single == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList(single);
|
||||
}
|
||||
|
||||
public abstract Enum getType();
|
||||
public abstract PacketChannel getChannel();
|
||||
|
||||
public CustomNpcsPermissions.Permission getPermission(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean needsNPC(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setNPC(EntityNPCInterface npc){
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
public abstract void sendData(ByteBuf out) throws IOException;
|
||||
|
||||
//"player" on the server side is the client who sent this packet
|
||||
@@ -0,0 +1,161 @@
|
||||
package kamkeel.npcs.network;
|
||||
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import noppes.npcs.LogWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class LargeAbstractPacket extends AbstractPacket {
|
||||
|
||||
private static final Map<UUID, PacketStorage> packetChunks = new ConcurrentHashMap<>();
|
||||
private static final int CHUNK_SIZE = 10000;
|
||||
|
||||
/**
|
||||
* Create multiple FMLProxyPacket objects, each containing up to CHUNK_SIZE bytes.
|
||||
*/
|
||||
@Override
|
||||
public List<FMLProxyPacket> generatePackets() {
|
||||
List<FMLProxyPacket> packets = new ArrayList<>();
|
||||
PacketChannel packetChannel = getChannel();
|
||||
|
||||
byte[] fullData;
|
||||
try {
|
||||
fullData = getData();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return packets;
|
||||
}
|
||||
|
||||
int totalSize = fullData.length;
|
||||
UUID packetId = UUID.randomUUID();
|
||||
|
||||
// Break data into CHUNK_SIZE chunks
|
||||
for (int offset = 0; offset < totalSize; offset += CHUNK_SIZE) {
|
||||
int chunkSize = Math.min(CHUNK_SIZE, totalSize - offset);
|
||||
ByteBuf chunkBuf = Unpooled.buffer();
|
||||
|
||||
chunkBuf.writeInt(packetChannel.getChannelType().ordinal());
|
||||
chunkBuf.writeInt(getType().ordinal());
|
||||
|
||||
chunkBuf.writeLong(packetId.getMostSignificantBits());
|
||||
chunkBuf.writeLong(packetId.getLeastSignificantBits());
|
||||
chunkBuf.writeInt(totalSize);
|
||||
chunkBuf.writeInt(offset);
|
||||
chunkBuf.writeInt((totalSize + CHUNK_SIZE - 1) / CHUNK_SIZE);
|
||||
|
||||
chunkBuf.writeBytes(fullData, offset, chunkSize);
|
||||
|
||||
FMLProxyPacket proxyPacket = new FMLProxyPacket(chunkBuf, packetChannel.getChannelName());
|
||||
packets.add(proxyPacket);
|
||||
}
|
||||
return packets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
UUID packetId = null;
|
||||
PacketStorage storage = null;
|
||||
ByteBuf chunk = null;
|
||||
ByteBuf completeData = null;
|
||||
|
||||
try {
|
||||
// Read UUID from the buffer
|
||||
long mostSigBits = in.readLong();
|
||||
long leastSigBits = in.readLong();
|
||||
packetId = new UUID(mostSigBits, leastSigBits);
|
||||
|
||||
// Read packet metadata
|
||||
int totalSize = in.readInt();
|
||||
int offset = in.readInt();
|
||||
int totalChunks = in.readInt(); // Debugging info
|
||||
int chunkSize = Math.min(CHUNK_SIZE, totalSize - offset);
|
||||
|
||||
// Basic validation to ensure the chunk won't overwrite out of bounds
|
||||
if (chunkSize <= 0 || offset < 0 || (offset + chunkSize) > totalSize) {
|
||||
throw new IndexOutOfBoundsException("Invalid chunk size/offset: chunkSize="
|
||||
+ chunkSize + ", offset=" + offset + ", totalSize=" + totalSize);
|
||||
}
|
||||
|
||||
// Read the exact chunk data
|
||||
chunk = in.readBytes(chunkSize);
|
||||
|
||||
// Store the received chunk in a PacketStorage
|
||||
storage = packetChunks.computeIfAbsent(packetId, k -> new PacketStorage(Unpooled.buffer(totalSize), 0, totalSize));
|
||||
|
||||
// Write this chunk into the buffer at the correct offset
|
||||
storage.data.setBytes(offset, chunk);
|
||||
storage.receivedSoFar += chunkSize;
|
||||
|
||||
// If we've received all bytes, finalize
|
||||
if (storage.receivedSoFar >= totalSize) {
|
||||
packetChunks.remove(packetId);
|
||||
completeData = storage.data.copy(0, totalSize);
|
||||
|
||||
try {
|
||||
handleCompleteData(completeData, player);
|
||||
} finally {
|
||||
completeData.release();
|
||||
}
|
||||
|
||||
storage.data.release();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Log the exception with contextual information
|
||||
LogWriter.error("Error in receiveData for packetId " + (packetId != null ? packetId.toString() : "null") + ": " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
|
||||
// If storage was created but the packet is incomplete, release storage.data
|
||||
if (storage != null && storage.receivedSoFar < storage.totalSize) {
|
||||
storage.data.release();
|
||||
if (packetId != null) {
|
||||
packetChunks.remove(packetId);
|
||||
}
|
||||
}
|
||||
|
||||
throw e; // Rethrow the exception after logging
|
||||
} finally {
|
||||
// Ensure that 'chunk' is released if it was allocated
|
||||
if (chunk != null && chunk.refCnt() > 0) {
|
||||
chunk.release();
|
||||
}
|
||||
|
||||
// Ensure that 'completeData' is released if it was created and not yet released
|
||||
if (completeData != null && completeData.refCnt() > 0) {
|
||||
completeData.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract byte[] getData() throws IOException;
|
||||
|
||||
protected abstract void handleCompleteData(ByteBuf data, EntityPlayer player) throws IOException;
|
||||
|
||||
@Override
|
||||
public final FMLProxyPacket generatePacket() {return null;}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {}
|
||||
|
||||
/**
|
||||
* Simple storage class to keep track of partial data and how many bytes we've received so far.
|
||||
*/
|
||||
private static class PacketStorage {
|
||||
final ByteBuf data;
|
||||
int receivedSoFar;
|
||||
final int totalSize;
|
||||
|
||||
PacketStorage(ByteBuf data, int receivedSoFar, int totalSize) {
|
||||
this.data = data;
|
||||
this.receivedSoFar = receivedSoFar;
|
||||
this.totalSize = totalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package kamkeel.npcs.network;
|
||||
|
||||
import kamkeel.npcs.network.enums.EnumChannelType;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketChannel {
|
||||
|
||||
private String channelName;
|
||||
private EnumChannelType channelType;
|
||||
|
||||
public Map<Integer, AbstractPacket> packets = new Hashtable<>();
|
||||
|
||||
public PacketChannel(String channelName, EnumChannelType channelType) {
|
||||
this.channelName = channelName;
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public String getChannelName() {
|
||||
return channelName;
|
||||
}
|
||||
|
||||
public void setChannelName(String channelName) {
|
||||
this.channelName = channelName;
|
||||
}
|
||||
|
||||
public EnumChannelType getChannelType() {
|
||||
return channelType;
|
||||
}
|
||||
|
||||
public void setChannelType(EnumChannelType channelType) {
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public void registerPacket(AbstractPacket packet) {
|
||||
if(packets.containsKey(packet.getType().ordinal())){
|
||||
System.out.println("Packet ID: " + packet.getType().ordinal() + " is already registered in " + this.channelName);
|
||||
return;
|
||||
}
|
||||
this.packets.put(packet.getType().ordinal(), packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package kamkeel.npcs.network;
|
||||
|
||||
public class PacketClient extends PacketHandler {
|
||||
|
||||
public static void sendClient(AbstractPacket packet){
|
||||
PacketHandler.Instance.sendToServer(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
package kamkeel.npcs.network;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.network.FMLEventChannel;
|
||||
import cpw.mods.fml.common.network.FMLNetworkEvent;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.enums.EnumChannelType;
|
||||
import kamkeel.npcs.network.packets.data.*;
|
||||
import kamkeel.npcs.network.packets.data.gui.*;
|
||||
import kamkeel.npcs.network.packets.data.large.*;
|
||||
import kamkeel.npcs.network.packets.data.npc.*;
|
||||
import kamkeel.npcs.network.packets.data.script.ScriptOverlayClosePacket;
|
||||
import kamkeel.npcs.network.packets.data.script.ScriptOverlayDataPacket;
|
||||
import kamkeel.npcs.network.packets.data.script.ScriptedParticlePacket;
|
||||
import kamkeel.npcs.network.packets.player.*;
|
||||
import kamkeel.npcs.network.packets.request.*;
|
||||
import kamkeel.npcs.network.packets.request.animation.AnimationGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.animation.AnimationRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.animation.AnimationSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.animation.AnimationsGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.bank.BankGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.bank.BankRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.bank.BankSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.bank.BanksGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.*;
|
||||
import kamkeel.npcs.network.packets.player.customgui.CustomGuiButtonPacket;
|
||||
import kamkeel.npcs.network.packets.player.customgui.CustomGuiClosePacket;
|
||||
import kamkeel.npcs.network.packets.player.customgui.CustomGuiUnfocusedPacket;
|
||||
import kamkeel.npcs.network.packets.player.customgui.CustomScrollClickPacket;
|
||||
import kamkeel.npcs.network.packets.request.dialog.*;
|
||||
import kamkeel.npcs.network.packets.request.effects.EffectGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.effects.EffectRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.effects.EffectSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.effects.EffectsGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.faction.*;
|
||||
import kamkeel.npcs.network.packets.request.feather.DimensionTeleportPacket;
|
||||
import kamkeel.npcs.network.packets.request.item.ColorBrushPacket;
|
||||
import kamkeel.npcs.network.packets.request.item.ColorSetPacket;
|
||||
import kamkeel.npcs.network.packets.request.jobs.JobGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.jobs.JobSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.jobs.JobSpawnerAddPacket;
|
||||
import kamkeel.npcs.network.packets.request.jobs.JobSpawnerRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.linked.*;
|
||||
import kamkeel.npcs.network.packets.request.magic.*;
|
||||
import kamkeel.npcs.network.packets.request.mainmenu.*;
|
||||
import kamkeel.npcs.network.packets.request.naturalspawns.NaturalSpawnGetAllPacket;
|
||||
import kamkeel.npcs.network.packets.request.naturalspawns.NaturalSpawnGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.naturalspawns.NaturalSpawnRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.naturalspawns.NaturalSpawnSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.npc.*;
|
||||
import kamkeel.npcs.network.packets.request.party.*;
|
||||
import kamkeel.npcs.network.packets.request.pather.MovingPathGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.pather.MovingPathSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.playerdata.*;
|
||||
import kamkeel.npcs.network.packets.request.profile.*;
|
||||
import kamkeel.npcs.network.packets.request.quest.*;
|
||||
import kamkeel.npcs.network.packets.request.recipe.RecipeGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.recipe.RecipeRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.recipe.RecipeSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.recipe.RecipesGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.role.RoleCompanionUpdatePacket;
|
||||
import kamkeel.npcs.network.packets.request.role.RoleGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.role.RoleSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.script.*;
|
||||
import kamkeel.npcs.network.packets.request.script.item.ItemScriptErrorPacket;
|
||||
import kamkeel.npcs.network.packets.request.script.item.ItemScriptPacket;
|
||||
import kamkeel.npcs.network.packets.request.script.item.LinkedItemScriptPacket;
|
||||
import kamkeel.npcs.network.packets.request.tags.*;
|
||||
import kamkeel.npcs.network.packets.request.transform.TransformGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.transform.TransformLoadPacket;
|
||||
import kamkeel.npcs.network.packets.request.transform.TransformSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.transport.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.NoppesUtilServer;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketHandler {
|
||||
public static PacketHandler Instance;
|
||||
|
||||
// Channels
|
||||
public Map<EnumChannelType, FMLEventChannel> channels = new Hashtable<>();
|
||||
|
||||
// Client to Server
|
||||
public static final PacketChannel REQUEST_PACKET = new PacketChannel("CNPC+|Req", EnumChannelType.REQUEST);
|
||||
|
||||
// Client to Server - Typically information
|
||||
public static final PacketChannel PLAYER_PACKET = new PacketChannel("CNPC+|Player", EnumChannelType.PLAYER);
|
||||
|
||||
// Server to Client
|
||||
public static final PacketChannel DATA_PACKET = new PacketChannel("CNPC+|Data", EnumChannelType.DATA);
|
||||
|
||||
public static final List<PacketChannel> packetChannels = new ArrayList<>();
|
||||
|
||||
public PacketHandler() {
|
||||
// Register Channels
|
||||
packetChannels.add(REQUEST_PACKET);
|
||||
packetChannels.add(PLAYER_PACKET);
|
||||
packetChannels.add(DATA_PACKET);
|
||||
|
||||
this.registerDataPackets();
|
||||
this.registerRequestPackets();
|
||||
this.registerPlayerPackets();
|
||||
}
|
||||
|
||||
public void registerRequestPackets(){
|
||||
// NPC Packets
|
||||
REQUEST_PACKET.registerPacket(new NpcClosePacket());
|
||||
REQUEST_PACKET.registerPacket(new NpcDeletePacket());
|
||||
|
||||
// Script Packets
|
||||
REQUEST_PACKET.registerPacket(new BlockScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new EventScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new ForgeScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new GlobalNPCScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new ItemScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new ItemScriptErrorPacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedItemScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new NPCScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new PlayerScriptPacket());
|
||||
REQUEST_PACKET.registerPacket(new ScriptInfoPacket());
|
||||
REQUEST_PACKET.registerPacket(new EffectScriptPacket());
|
||||
|
||||
// Cloner Packets
|
||||
REQUEST_PACKET.registerPacket(new CloneListPacket());
|
||||
REQUEST_PACKET.registerPacket(new SpawnMobPacket());
|
||||
REQUEST_PACKET.registerPacket(new MobSpawnerPacket());
|
||||
REQUEST_PACKET.registerPacket(new ClonePreSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneTagListPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneAllTagsPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneAllTagsShortPacket());
|
||||
|
||||
|
||||
// Linked Packets
|
||||
REQUEST_PACKET.registerPacket(new LinkedGetAllPacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedNPCRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedSetPacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedNPCAddPacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedItemSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedItemRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new LinkedItemBuildPacket());
|
||||
|
||||
|
||||
// Bank Packets
|
||||
REQUEST_PACKET.registerPacket(new BanksGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new BankGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new BankRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new BankSavePacket());
|
||||
|
||||
// Recipe Packets
|
||||
REQUEST_PACKET.registerPacket(new RecipesGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new RecipeGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new RecipeRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new RecipeSavePacket());
|
||||
|
||||
// Natural Spawn Packets
|
||||
REQUEST_PACKET.registerPacket(new NaturalSpawnGetAllPacket());
|
||||
REQUEST_PACKET.registerPacket(new NaturalSpawnGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new NaturalSpawnSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new NaturalSpawnRemovePacket());
|
||||
|
||||
// Dialog Category Packets
|
||||
REQUEST_PACKET.registerPacket(new DialogCategorySavePacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogCategoryRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogCategoryGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogCategoriesGetPacket());
|
||||
|
||||
// Dialog Packets
|
||||
REQUEST_PACKET.registerPacket(new DialogSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogGetPacket());
|
||||
|
||||
REQUEST_PACKET.registerPacket(new DialogNpcGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogNpcSetPacket());
|
||||
REQUEST_PACKET.registerPacket(new DialogNpcRemovePacket());
|
||||
|
||||
// Quest Category Packets
|
||||
REQUEST_PACKET.registerPacket(new QuestCategorySavePacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestCategoryRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestCategoryGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestCategoriesGetPacket());
|
||||
|
||||
// Quest Packets
|
||||
REQUEST_PACKET.registerPacket(new QuestOpenGuiPacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestDialogGetTitlePacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestLogToServerPacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestUntrackPacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new QuestsGetPacket());
|
||||
|
||||
// Faction Packets
|
||||
REQUEST_PACKET.registerPacket(new FactionSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new FactionRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new FactionSetPacket());
|
||||
REQUEST_PACKET.registerPacket(new FactionGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new FactionsGetPacket());
|
||||
|
||||
// Tag Packets
|
||||
REQUEST_PACKET.registerPacket(new TagsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TagGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TagsNpcGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TagSetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TagSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new TagRemovePacket());
|
||||
|
||||
// PlayerData Packets
|
||||
REQUEST_PACKET.registerPacket(new PlayerDataGetNamesPacket());
|
||||
REQUEST_PACKET.registerPacket(new PlayerDataRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new PlayerDataGetInfoPacket());
|
||||
REQUEST_PACKET.registerPacket(new PlayerDataRemoveInfoPacket());
|
||||
REQUEST_PACKET.registerPacket(new PlayerDataMapRegenPacket());
|
||||
|
||||
// Main Menu Packets
|
||||
REQUEST_PACKET.registerPacket(new MainmenuDisplayGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new MainmenuDisplaySavePacket());
|
||||
|
||||
REQUEST_PACKET.registerPacket(new MainmenuStatsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new MainmenuStatsSavePacket());
|
||||
|
||||
REQUEST_PACKET.registerPacket(new MainmenuAIGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new MainmenuAISavePacket());
|
||||
|
||||
REQUEST_PACKET.registerPacket(new MainmenuAdvancedGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new MainmenuAdvancedSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new MainmenuAdvancedMarkDataPacket());
|
||||
|
||||
REQUEST_PACKET.registerPacket(new MainmenuInvGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new MainmenuInvSavePacket());
|
||||
|
||||
// Transport Packets
|
||||
REQUEST_PACKET.registerPacket(new TransportCategoriesGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TransportCategorySavePacket());
|
||||
REQUEST_PACKET.registerPacket(new TransportCategoryRemovePacket());
|
||||
|
||||
REQUEST_PACKET.registerPacket(new TransportRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new TransportsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TransportSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new TransportGetLocationPacket());
|
||||
|
||||
// Remote Packets Packets
|
||||
REQUEST_PACKET.registerPacket(new RemoteMainMenuPacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteGlobalMenuPacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteDeletePacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteNpcsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteFreezeGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteFreezePacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteResetPacket());
|
||||
REQUEST_PACKET.registerPacket(new RemoteTpToNpcPacket());
|
||||
|
||||
// Job Packets
|
||||
REQUEST_PACKET.registerPacket(new JobGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new JobSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new JobSpawnerAddPacket());
|
||||
REQUEST_PACKET.registerPacket(new JobSpawnerRemovePacket());
|
||||
|
||||
// Role Packets
|
||||
REQUEST_PACKET.registerPacket(new RoleCompanionUpdatePacket());
|
||||
REQUEST_PACKET.registerPacket(new RoleSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new RoleGetPacket());
|
||||
|
||||
// Transform Packets
|
||||
REQUEST_PACKET.registerPacket(new TransformSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new TransformGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TransformLoadPacket());
|
||||
|
||||
// Trader Packets
|
||||
REQUEST_PACKET.registerPacket(new TraderMarketSavePacket());
|
||||
|
||||
// Party Packets
|
||||
REQUEST_PACKET.registerPacket(new PartySavePacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyInfoPacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyDisbandPacket());
|
||||
REQUEST_PACKET.registerPacket(new PartySetLeaderPacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyKickPacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyLeavePacket());
|
||||
REQUEST_PACKET.registerPacket(new PartySetQuestPacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyInvitePacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyAcceptInvitePacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyIgnoreInvitePacket());
|
||||
REQUEST_PACKET.registerPacket(new PartyLogToServerPacket());
|
||||
|
||||
// Animation Packets
|
||||
REQUEST_PACKET.registerPacket(new AnimationsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new AnimationGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new AnimationRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new AnimationSavePacket());
|
||||
|
||||
// Moving Path
|
||||
REQUEST_PACKET.registerPacket(new MovingPathSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new MovingPathGetPacket());
|
||||
|
||||
// Tool Packets
|
||||
REQUEST_PACKET.registerPacket(new ColorBrushPacket());
|
||||
REQUEST_PACKET.registerPacket(new ColorSetPacket());
|
||||
|
||||
// Custom Effect Packets
|
||||
REQUEST_PACKET.registerPacket(new EffectGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new EffectsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new EffectSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new EffectRemovePacket());
|
||||
|
||||
// Profile Packets
|
||||
REQUEST_PACKET.registerPacket(new ProfileGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new ProfileGetInfoPacket());
|
||||
REQUEST_PACKET.registerPacket(new ProfileCreatePacket());
|
||||
REQUEST_PACKET.registerPacket(new ProfileRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new ProfileRenamePacket());
|
||||
REQUEST_PACKET.registerPacket(new ProfileChangePacket());
|
||||
|
||||
// Job Packets
|
||||
REQUEST_PACKET.registerPacket(new MagicCycleRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new MagicCycleSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new MagicGetAllPacket());
|
||||
REQUEST_PACKET.registerPacket(new MagicSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new MagicRemovePacket());
|
||||
REQUEST_PACKET.registerPacket(new MagicGetPacket());
|
||||
|
||||
// Other Packets
|
||||
REQUEST_PACKET.registerPacket(new IsGuiOpenInform());
|
||||
REQUEST_PACKET.registerPacket(new GuiRequestPacket());
|
||||
REQUEST_PACKET.registerPacket(new DimensionsGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new MerchantUpdatePacket());
|
||||
REQUEST_PACKET.registerPacket(new ModelDataSavePacket());
|
||||
REQUEST_PACKET.registerPacket(new MailOpenSetupPacket());
|
||||
REQUEST_PACKET.registerPacket(new TileEntityGetPacket());
|
||||
REQUEST_PACKET.registerPacket(new TileEntitySavePacket());
|
||||
REQUEST_PACKET.registerPacket(new MountPacket());
|
||||
REQUEST_PACKET.registerPacket(new DimensionTeleportPacket());
|
||||
}
|
||||
|
||||
public void registerDataPackets(){
|
||||
// Data Packets
|
||||
DATA_PACKET.registerPacket(new LoginPacket());
|
||||
DATA_PACKET.registerPacket(new AchievementPacket());
|
||||
DATA_PACKET.registerPacket(new ChatAlertPacket());
|
||||
DATA_PACKET.registerPacket(new ChatBubblePacket());
|
||||
DATA_PACKET.registerPacket(new ConfigCommandPacket());
|
||||
DATA_PACKET.registerPacket(new DisableMouseInputPacket());
|
||||
DATA_PACKET.registerPacket(new MarkDataPacket());
|
||||
DATA_PACKET.registerPacket(new OverlayQuestTrackingPacket());
|
||||
DATA_PACKET.registerPacket(new ParticlePacket());
|
||||
DATA_PACKET.registerPacket(new PlayerUpdateSkinOverlaysPacket());
|
||||
DATA_PACKET.registerPacket(new QuestCompletionPacket());
|
||||
DATA_PACKET.registerPacket(new ScrollSelectedPacket());
|
||||
DATA_PACKET.registerPacket(new SoundManagementPacket());
|
||||
DATA_PACKET.registerPacket(new SwingPlayerArmPacket());
|
||||
DATA_PACKET.registerPacket(new UpdateAnimationsPacket());
|
||||
DATA_PACKET.registerPacket(new VillagerListPacket());
|
||||
DATA_PACKET.registerPacket(new PlayerDataInfoPacket());
|
||||
|
||||
// Data | GUI Packets
|
||||
DATA_PACKET.registerPacket(new GuiClosePacket());
|
||||
DATA_PACKET.registerPacket(new GuiOpenPacket());
|
||||
DATA_PACKET.registerPacket(new GuiErrorPacket());
|
||||
DATA_PACKET.registerPacket(new GuiRedstonePacket());
|
||||
DATA_PACKET.registerPacket(new GuiTeleporterPacket());
|
||||
DATA_PACKET.registerPacket(new GuiWaypointPacket());
|
||||
DATA_PACKET.registerPacket(new IsGuiOpenPacket());
|
||||
DATA_PACKET.registerPacket(new GuiOpenBookPacket());
|
||||
|
||||
// Data | NPC Packets
|
||||
DATA_PACKET.registerPacket(new DeleteNpcPacket());
|
||||
DATA_PACKET.registerPacket(new EditNpcPacket());
|
||||
DATA_PACKET.registerPacket(new UpdateNpcPacket());
|
||||
DATA_PACKET.registerPacket(new DialogPacket());
|
||||
DATA_PACKET.registerPacket(new RolePacket());
|
||||
DATA_PACKET.registerPacket(new WeaponNpcPacket());
|
||||
|
||||
// Data | Script Packets
|
||||
DATA_PACKET.registerPacket(new ScriptedParticlePacket());
|
||||
DATA_PACKET.registerPacket(new ScriptOverlayClosePacket());
|
||||
DATA_PACKET.registerPacket(new ScriptOverlayDataPacket());
|
||||
|
||||
// Data | Large Packets
|
||||
DATA_PACKET.registerPacket(new ClonerPacket());
|
||||
DATA_PACKET.registerPacket(new ScrollDataPacket());
|
||||
DATA_PACKET.registerPacket(new ScrollListPacket());
|
||||
DATA_PACKET.registerPacket(new SyncPacket());
|
||||
DATA_PACKET.registerPacket(new SyncEffectPacket());
|
||||
DATA_PACKET.registerPacket(new GuiDataPacket());
|
||||
DATA_PACKET.registerPacket(new PartyDataPacket());
|
||||
}
|
||||
|
||||
public void registerPlayerPackets() {
|
||||
PLAYER_PACKET.registerPacket(new FollowerPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new TransportPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new BankActionPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new DialogSelectPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new CheckPlayerValue());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new MailActionPacket());
|
||||
PLAYER_PACKET.registerPacket(new MailActionPacket.MailSendPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new SaveSignPacket());
|
||||
PLAYER_PACKET.registerPacket(new SaveBookPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new CompanionActionPacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new GetNPCRole());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new InputDevicePacket());
|
||||
|
||||
PLAYER_PACKET.registerPacket(new ScreenSizePacket());
|
||||
|
||||
// CustomGUI Packets
|
||||
PLAYER_PACKET.registerPacket(new CustomGuiButtonPacket());
|
||||
PLAYER_PACKET.registerPacket(new CustomGuiClosePacket());
|
||||
PLAYER_PACKET.registerPacket(new CustomGuiUnfocusedPacket());
|
||||
PLAYER_PACKET.registerPacket(new CustomScrollClickPacket());
|
||||
}
|
||||
|
||||
public void registerChannels() {
|
||||
for (PacketChannel channel : packetChannels) {
|
||||
FMLEventChannel eventChannel =
|
||||
NetworkRegistry.INSTANCE.newEventDrivenChannel(channel.getChannelName());
|
||||
eventChannel.register(this);
|
||||
channels.put(channel.getChannelType(), eventChannel);
|
||||
}
|
||||
}
|
||||
|
||||
public PacketChannel getPacketChannel(EnumChannelType type) {
|
||||
return packetChannels.stream()
|
||||
.filter(channel -> channel.getChannelType() == type)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public FMLEventChannel getEventChannel(AbstractPacket abstractPacket){
|
||||
PacketChannel packetChannel = getPacketChannel(abstractPacket.getChannel().getChannelType());
|
||||
if (packetChannel == null) {
|
||||
return null;
|
||||
}
|
||||
return channels.get(packetChannel.getChannelType());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) {
|
||||
handlePacket(event.packet, ((NetHandlerPlayServer) event.handler).playerEntity, Side.SERVER);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) {
|
||||
handlePacket(event.packet, CustomNpcs.proxy.getPlayer(), Side.CLIENT);
|
||||
}
|
||||
|
||||
private void handlePacket(FMLProxyPacket packet, EntityPlayer player, Side side) {
|
||||
ByteBuf buf = packet.payload();
|
||||
try {
|
||||
int packetTypeOrdinal = buf.readInt();
|
||||
EnumChannelType packetType = EnumChannelType.values()[packetTypeOrdinal];
|
||||
|
||||
PacketChannel packetChannel = getPacketChannel(packetType);
|
||||
if (packetChannel == null) {
|
||||
LogWriter.error("Error: Packet channel is null for packet type: " + packetType);
|
||||
return;
|
||||
}
|
||||
|
||||
int packetId = buf.readInt();
|
||||
AbstractPacket abstractPacket = packetChannel.packets.get(packetId);
|
||||
if (abstractPacket == null) {
|
||||
LogWriter.error("Error: Abstract packet is null for packet ID: " + packetId);
|
||||
return;
|
||||
}
|
||||
|
||||
if(side == Side.SERVER){
|
||||
if(abstractPacket.getChannel() == REQUEST_PACKET && ConfigMain.OpsOnly && !NoppesUtilServer.isOp(player)){
|
||||
LogWriter.error(String.format("%s tried to use CNPC+ without being an op", player.getCommandSenderName()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if permission is allowed
|
||||
if(abstractPacket.getPermission() != null && !CustomNpcsPermissions.hasPermission(player, abstractPacket.getPermission())){
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for required NPC
|
||||
EntityNPCInterface npc = NoppesUtilServer.getEditingNpc(player);
|
||||
if(abstractPacket.needsNPC() && npc == null){
|
||||
return;
|
||||
}
|
||||
|
||||
abstractPacket.setNPC(npc);
|
||||
}
|
||||
|
||||
// Let the packet parse the rest
|
||||
abstractPacket.receiveData(buf, player);
|
||||
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
LogWriter.error("Error: IndexOutOfBoundsException in handlePacket: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
LogWriter.error("Error: Exception in handlePacket: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends every FMLProxyPacket produced by packet.generatePackets()
|
||||
*/
|
||||
private void sendAllPackets(AbstractPacket packet, SendAction action) {
|
||||
// get all generated FMLProxyPacket objects (could be 1 for normal, or many for large)
|
||||
List<FMLProxyPacket> proxyPackets = packet.generatePackets();
|
||||
if (proxyPackets.isEmpty()) {
|
||||
LogWriter.error("Warning: No packets generated for " + packet.getClass().getName());
|
||||
}
|
||||
|
||||
for (FMLProxyPacket proxy : proxyPackets) {
|
||||
action.send(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Public API methods for sending
|
||||
|
||||
public void sendToPlayer(AbstractPacket packet, EntityPlayerMP player) {
|
||||
FMLEventChannel eventChannel = getEventChannel(packet);
|
||||
if (eventChannel == null) {
|
||||
LogWriter.error("Error: Event channel is null for packet: " + packet.getClass().getName());
|
||||
return;
|
||||
}
|
||||
sendAllPackets(packet, p -> eventChannel.sendTo(p, player));
|
||||
}
|
||||
|
||||
public void sendToServer(AbstractPacket packet) {
|
||||
FMLEventChannel eventChannel = getEventChannel(packet);
|
||||
if (eventChannel == null) {
|
||||
LogWriter.error("Error: Event channel is null for packet: " + packet.getClass().getName());
|
||||
return;
|
||||
}
|
||||
sendAllPackets(packet, eventChannel::sendToServer);
|
||||
}
|
||||
|
||||
public void sendToAll(AbstractPacket packet) {
|
||||
FMLEventChannel eventChannel = getEventChannel(packet);
|
||||
if (eventChannel == null) {
|
||||
LogWriter.error("Error: Event channel is null for packet: " + packet.getClass().getName());
|
||||
return;
|
||||
}
|
||||
sendAllPackets(packet, eventChannel::sendToAll);
|
||||
}
|
||||
|
||||
public void sendToDimension(AbstractPacket packet, final int dimensionId) {
|
||||
FMLEventChannel eventChannel = getEventChannel(packet);
|
||||
if (eventChannel == null) {
|
||||
LogWriter.error("Error: Event channel is null for packet: " + packet.getClass().getName());
|
||||
return;
|
||||
}
|
||||
sendAllPackets(packet, p -> eventChannel.sendToDimension(p, dimensionId));
|
||||
}
|
||||
|
||||
public void sendTracking(AbstractPacket packet, final Entity entity) {
|
||||
FMLEventChannel eventChannel = getEventChannel(packet);
|
||||
if (eventChannel == null) {
|
||||
LogWriter.error("Error: Event channel is null for packet: " + packet.getClass().getName());
|
||||
return;
|
||||
}
|
||||
final NetworkRegistry.TargetPoint point = new NetworkRegistry.TargetPoint(entity.dimension, entity.posX, entity.posY, entity.posZ, 60);
|
||||
sendAllPackets(packet, p -> eventChannel.sendToAllAround(p, point));
|
||||
}
|
||||
|
||||
// Simple functional interface to unify the "send" action
|
||||
private interface SendAction {
|
||||
void send(FMLProxyPacket proxy);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
package kamkeel.npcs.network;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.enums.EnumItemPacketType;
|
||||
import kamkeel.npcs.network.packets.data.large.GuiDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.CustomItems;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.NBTTags;
|
||||
import noppes.npcs.controllers.ScriptContainer;
|
||||
import noppes.npcs.controllers.ScriptController;
|
||||
import noppes.npcs.controllers.data.IScriptHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PacketUtil {
|
||||
|
||||
public static boolean verifyItemPacket(EnumItemPacketType type, EntityPlayer player) {
|
||||
if (player == null)
|
||||
return false;
|
||||
|
||||
ItemStack item = player.inventory.getCurrentItem();
|
||||
if (item == null) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without an item, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case WAND:
|
||||
if (item.getItem() != CustomItems.wand) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Wand, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case MOUNTER:
|
||||
if (item.getItem() != CustomItems.mount) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Mounter, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case CLONER:
|
||||
if (item.getItem() != CustomItems.cloner) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Cloner, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case TELEPORTER:
|
||||
if (item.getItem() != CustomItems.teleporter) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Teleporter, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SCRIPTER:
|
||||
if (item.getItem() != CustomItems.scripter) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Scripter, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PATHER:
|
||||
if (item.getItem() != CustomItems.moving) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Pather, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case BLOCK:
|
||||
if (item.getItem() == Item.getItemFromBlock(CustomItems.waypoint)
|
||||
|| item.getItem() == Item.getItemFromBlock(CustomItems.border)
|
||||
|| item.getItem() == Item.getItemFromBlock(CustomItems.redstoneBlock)) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a valid Block, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case BRUSH:
|
||||
if (item.getItem() != CustomItems.tool || item.getItemDamage() != 1) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a %s Packet without a Pather, they could be a hacker",
|
||||
player.getCommandSenderName(), type));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* New method that accepts multiple EnumItemPacketTypes.
|
||||
* It returns true if any one of the provided types is valid.
|
||||
* If none are valid, a merged error message is logged.
|
||||
*/
|
||||
public static boolean verifyItemPacket(EntityPlayer player, EnumItemPacketType... types) {
|
||||
if (player == null)
|
||||
return false;
|
||||
|
||||
ItemStack item = player.inventory.getCurrentItem();
|
||||
if (item == null) {
|
||||
LogWriter.error(String.format("%s attempted to utilize a Packet without an item. Expected one of: %s, they could be a hacker",
|
||||
player.getCommandSenderName(), getExpectedItemNames(types)));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (EnumItemPacketType type : types) {
|
||||
if (isValidItemForType(item, type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// None passed; log one merged error message listing all expected items.
|
||||
LogWriter.error(String.format("%s attempted to utilize a Packet without a valid item. Expected one of: %s, they could be a hacker",
|
||||
player.getCommandSenderName(), getExpectedItemNames(types)));
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isValidItemForType(ItemStack item, EnumItemPacketType type) {
|
||||
if(item == null || item.getItem() == null)
|
||||
return false;
|
||||
|
||||
switch (type) {
|
||||
case WAND:
|
||||
return item.getItem() == CustomItems.wand;
|
||||
case MOUNTER:
|
||||
return item.getItem() == CustomItems.mount;
|
||||
case CLONER:
|
||||
return item.getItem() == CustomItems.cloner;
|
||||
case TELEPORTER:
|
||||
return item.getItem() == CustomItems.teleporter;
|
||||
case SCRIPTER:
|
||||
return item.getItem() == CustomItems.scripter;
|
||||
case PATHER:
|
||||
return item.getItem() == CustomItems.moving;
|
||||
case BLOCK:
|
||||
// For BLOCK, the item is valid as long as it is NOT one of these blocks.
|
||||
return !(item.getItem() == Item.getItemFromBlock(CustomItems.waypoint)
|
||||
|| item.getItem() == Item.getItemFromBlock(CustomItems.border)
|
||||
|| item.getItem() == Item.getItemFromBlock(CustomItems.redstoneBlock));
|
||||
case BRUSH:
|
||||
return item.getItem() == CustomItems.tool && item.getItemDamage() == 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a comma‐separated list of expected item names for the given types.
|
||||
*/
|
||||
private static String getExpectedItemNames(EnumItemPacketType... types) {
|
||||
Set<String> expectedNames = new LinkedHashSet<>();
|
||||
for (EnumItemPacketType type : types) {
|
||||
expectedNames.add(getExpectedItemName(type));
|
||||
}
|
||||
return String.join(", ", expectedNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expected item name for the given EnumItemPacketType.
|
||||
*/
|
||||
private static String getExpectedItemName(EnumItemPacketType type) {
|
||||
switch (type) {
|
||||
case WAND:
|
||||
return "Wand";
|
||||
case MOUNTER:
|
||||
return "Mounter";
|
||||
case CLONER:
|
||||
return "Cloner";
|
||||
case TELEPORTER:
|
||||
return "Teleporter";
|
||||
case SCRIPTER:
|
||||
return "Scripter";
|
||||
case PATHER:
|
||||
return "Pather";
|
||||
case BLOCK:
|
||||
return "valid Block";
|
||||
case BRUSH:
|
||||
return "Paintbrush";
|
||||
default:
|
||||
return type.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static void getScripts(IScriptHandler data, EntityPlayerMP player) {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setBoolean("ScriptEnabled", data.getEnabled());
|
||||
compound.setString("ScriptLanguage", data.getLanguage());
|
||||
compound.setTag("Languages", ScriptController.Instance.nbtLanguages());
|
||||
compound.setTag("ScriptConsole", NBTTags.NBTLongStringMap(data.getConsoleText()));
|
||||
GuiDataPacket.sendGuiData(player, compound);
|
||||
List<ScriptContainer> containers = data.getScripts();
|
||||
for (int i = 0; i < containers.size(); i++) {
|
||||
ScriptContainer container = containers.get(i);
|
||||
NBTTagCompound tabCompound = new NBTTagCompound();
|
||||
tabCompound.setInteger("Tab",i);
|
||||
tabCompound.setTag("Script",container.writeToNBT(new NBTTagCompound()));
|
||||
tabCompound.setInteger("TotalScripts",containers.size());
|
||||
GuiDataPacket.sendGuiData(player, tabCompound);
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveScripts(IScriptHandler data, ByteBuf buffer) throws IOException {
|
||||
int tab = buffer.readInt();
|
||||
int totalScripts = buffer.readInt();
|
||||
if (totalScripts == 0) {
|
||||
data.getScripts().clear();
|
||||
}
|
||||
|
||||
if (tab >= 0) {
|
||||
if (data.getScripts().size() > totalScripts) {
|
||||
data.setScripts(data.getScripts().subList(0,totalScripts));
|
||||
} else while (data.getScripts().size() < totalScripts) {
|
||||
data.getScripts().add(new ScriptContainer(data));
|
||||
}
|
||||
NBTTagCompound tabCompound = ByteBufUtils.readNBT(buffer);
|
||||
ScriptContainer script = new ScriptContainer(data);
|
||||
script.readFromNBT(tabCompound);
|
||||
data.getScripts().set(tab,script);
|
||||
} else {
|
||||
NBTTagCompound compound = ByteBufUtils.readNBT(buffer);
|
||||
data.setLanguage(compound.getString("ScriptLanguage"));
|
||||
if (!ScriptController.Instance.languages.containsKey(data.getLanguage())) {
|
||||
if (!ScriptController.Instance.languages.isEmpty()) {
|
||||
data.setLanguage((String) ScriptController.Instance.languages.keySet().toArray()[0]);
|
||||
} else {
|
||||
data.setLanguage("ECMAScript");
|
||||
}
|
||||
}
|
||||
data.setEnabled(compound.getBoolean("ScriptEnabled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumChannelType {
|
||||
REQUEST,
|
||||
PLAYER,
|
||||
DATA,
|
||||
INFO
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumConfigOperation {
|
||||
FONT,
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
// Packets to the Client
|
||||
public enum EnumDataPacket {
|
||||
// Synchronization
|
||||
SYNC,
|
||||
SYNC_EFFECTS,
|
||||
CONFIG_COMMAND,
|
||||
|
||||
// Messages
|
||||
CHAT_ALERT,
|
||||
ACHIEVEMENT,
|
||||
CHATBUBBLE,
|
||||
SOUND,
|
||||
DIALOG,
|
||||
QUEST_COMPLETION,
|
||||
|
||||
|
||||
// NPC
|
||||
EDIT_NPC,
|
||||
UPDATE_NPC,
|
||||
ROLE_NPC,
|
||||
DELETE_NPC,
|
||||
CLONE_NPC,
|
||||
WEAPON_NPC,
|
||||
|
||||
// Data
|
||||
SCROLL_LIST,
|
||||
SCROLL_DATA,
|
||||
SCROLL_GROUP,
|
||||
SCROLL_SELECTED,
|
||||
PARTY_DATA,
|
||||
|
||||
// GUI
|
||||
GUI_OPEN,
|
||||
GUI_REDSTONE,
|
||||
GUI_WAYPOINT,
|
||||
GUI_TELEPORTER,
|
||||
GUI_BOOK,
|
||||
GUI_DATA,
|
||||
PLAYER_DATA,
|
||||
GUI_ERROR,
|
||||
GUI_CLOSE,
|
||||
ISGUIOPEN,
|
||||
|
||||
// Visual
|
||||
SCRIPTED_PARTICLE,
|
||||
PARTICLE,
|
||||
PLAYER_UPDATE_SKIN_OVERLAYS,
|
||||
UPDATE_ANIMATIONS,
|
||||
SCRIPT_OVERLAY_DATA,
|
||||
SCRIPT_OVERLAY_CLOSE,
|
||||
OVERLAY_QUEST_TRACKING,
|
||||
MARK_DATA,
|
||||
|
||||
// Other
|
||||
VILLAGER_LIST,
|
||||
SWING_PLAYER_ARM,
|
||||
DISABLE_MOUSE_INPUT,
|
||||
LOGIN,
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumItemPacketType {
|
||||
WAND,
|
||||
MOUNTER,
|
||||
CLONER,
|
||||
TELEPORTER,
|
||||
SCRIPTER,
|
||||
PATHER,
|
||||
BLOCK,
|
||||
BRUSH
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumPlayerPacket {
|
||||
FollowerAction,
|
||||
Transport,
|
||||
BankAction,
|
||||
DialogSelect,
|
||||
GetPlayerValue,
|
||||
MailBoxAction,
|
||||
MailSend,
|
||||
SaveSign,
|
||||
SaveBook,
|
||||
CompanionAction,
|
||||
GetRole,
|
||||
InputDevice,
|
||||
ScreenSize,
|
||||
|
||||
CustomGuiButton,
|
||||
CustomGuiScrollClick,
|
||||
CustomGuiClose,
|
||||
CustomGuiUnfocused,
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumRequestPacket {
|
||||
NPCDelete,
|
||||
RemoteMainMenu,
|
||||
RemoteGlobalMenu,
|
||||
NpcClose,
|
||||
RemoteDelete,
|
||||
RemoteFreeze,
|
||||
RemoteFreezeGet,
|
||||
RemoteReset,
|
||||
SpawnMob,
|
||||
MobSpawner,
|
||||
|
||||
DimensionsGet,
|
||||
|
||||
MainmenuAISave,
|
||||
MainmenuAIGet,
|
||||
MainmenuInvSave,
|
||||
MainmenuInvGet,
|
||||
MainmenuStatsSave,
|
||||
MainmenuStatsGet,
|
||||
MainmenuDisplaySave,
|
||||
MainmenuDisplayGet,
|
||||
ModelDataSave,
|
||||
MainmenuAdvancedSave,
|
||||
MainmenuAdvancedGet,
|
||||
MainmenuAdvancedMarkData,
|
||||
|
||||
DialogNpcSet,
|
||||
DialogNpcRemove,
|
||||
DialogNpcGet,
|
||||
DialogCategorySave,
|
||||
DialogCategoriesGet,
|
||||
DialogCategoryRemove,
|
||||
DialogCategoryGet,
|
||||
DialogSave,
|
||||
DialogsGet,
|
||||
DialogGet,
|
||||
DialogRemove,
|
||||
|
||||
TransportSave,
|
||||
TransportCategoriesGet,
|
||||
TransportCategorySave,
|
||||
TransportCategoryRemove,
|
||||
TransportRemove,
|
||||
TransportGetLocation,
|
||||
TransportsGet,
|
||||
|
||||
FactionSet,
|
||||
FactionSave,
|
||||
FactionsGet,
|
||||
FactionGet,
|
||||
FactionRemove,
|
||||
|
||||
TagSet,
|
||||
TagSave,
|
||||
TagsGet,
|
||||
TagGet,
|
||||
NpcTagsGet,
|
||||
TagRemove,
|
||||
|
||||
QuestUntrack,
|
||||
QuestLogToServer,
|
||||
QuestCategorySave,
|
||||
QuestCategoriesGet,
|
||||
QuestRemove,
|
||||
QuestCategoryRemove,
|
||||
QuestRewardSave,
|
||||
QuestSave,
|
||||
QuestsGetFromQuest,
|
||||
QuestsGet,
|
||||
QuestDialogGetTitle,
|
||||
QuestOpenGui,
|
||||
QuestGet,
|
||||
|
||||
RecipeSave,
|
||||
RecipeRemove,
|
||||
RecipesGet,
|
||||
RecipeGet,
|
||||
|
||||
NaturalSpawnSave,
|
||||
NaturalSpawnGet,
|
||||
NaturalSpawnRemove,
|
||||
NaturalSpawnGetAll,
|
||||
|
||||
MerchantUpdate,
|
||||
MountPacket,
|
||||
MovingPathSave,
|
||||
MovingPathGet,
|
||||
|
||||
AnimationsGet,
|
||||
AnimationGet,
|
||||
AnimationRemove,
|
||||
AnimationSave,
|
||||
|
||||
RemoteNpcsGet,
|
||||
RemoteTpToNpc,
|
||||
TileEntitySave,
|
||||
TileEntityGet,
|
||||
Gui,
|
||||
IsGuiOpen,
|
||||
CacheAnimation,
|
||||
|
||||
PartyLogToServer,
|
||||
PartySave,
|
||||
PartyInfo,
|
||||
PartyDisband,
|
||||
PartyKick,
|
||||
PartyLeave,
|
||||
PartyInvite,
|
||||
PartyAcceptInvite,
|
||||
PartyIgnoreInvite,
|
||||
PartySetLeader,
|
||||
PartySetQuest,
|
||||
|
||||
LinkedNPCRemove,
|
||||
LinkedNPCAdd,
|
||||
LinkedGetAll,
|
||||
LinkedSet,
|
||||
LinkedGet,
|
||||
LinkedItemSave,
|
||||
LinkedItemRemove,
|
||||
LinkedItemBuild,
|
||||
LinkedItemScript,
|
||||
|
||||
BankGet,
|
||||
BanksGet,
|
||||
BankSave,
|
||||
BankRemove,
|
||||
|
||||
QuestCategoryGet,
|
||||
|
||||
PlayerDataInfo,
|
||||
PlayerDataGetNames,
|
||||
PlayerDataDelete,
|
||||
PlayerDataRemove,
|
||||
PlayerDataMapRegen,
|
||||
|
||||
JobSave,
|
||||
JobGet,
|
||||
JobSpawnerAdd,
|
||||
JobSpawnerRemove,
|
||||
|
||||
RoleCompanionUpdate,
|
||||
RoleSave,
|
||||
RoleGet,
|
||||
|
||||
MailOpenSetup,
|
||||
|
||||
TransformSave,
|
||||
TransformGet,
|
||||
TransformLoad,
|
||||
|
||||
TraderMarketSave,
|
||||
|
||||
CloneList,
|
||||
CloneSave,
|
||||
CloneRemove,
|
||||
CloneTagList,
|
||||
CloneAllTags,
|
||||
CloneAllTagsShort,
|
||||
ClonePreSave,
|
||||
|
||||
EventScript,
|
||||
PlayerScript,
|
||||
ForgeScript,
|
||||
GlobalNPCScript,
|
||||
ItemScript,
|
||||
ItemScriptError,
|
||||
BlockScript,
|
||||
NPCScript,
|
||||
ScriptInfo,
|
||||
EffectScript,
|
||||
|
||||
DimensionTeleport,
|
||||
|
||||
EffectList,
|
||||
EffectGet,
|
||||
EffectScriptGet,
|
||||
EffectRemove,
|
||||
EffectSave,
|
||||
|
||||
ColorSet,
|
||||
ColorBrush,
|
||||
|
||||
ProfileGet,
|
||||
ProfileGetAll,
|
||||
ProfileGetInfo,
|
||||
ProfileCreate,
|
||||
ProfileRemove,
|
||||
ProfileRename,
|
||||
ProfileChange,
|
||||
|
||||
MagicCycleRemove,
|
||||
MagicCycleSave,
|
||||
MagicGetAll,
|
||||
MagicRemove,
|
||||
MagicGet, MagicSave
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumSoundOperation {
|
||||
CONTINUE_SOUNDS,
|
||||
PAUSE_SOUNDS,
|
||||
PLAY_MUSIC,
|
||||
PLAY_SOUND,
|
||||
PLAY_SOUND_TO,
|
||||
PLAY_SOUND_TO_NO_ID,
|
||||
STOP_SOUND_FOR,
|
||||
STOP_SOUNDS
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumSyncAction {
|
||||
RELOAD,
|
||||
UPDATE,
|
||||
REMOVE
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package kamkeel.npcs.network.enums;
|
||||
|
||||
public enum EnumSyncType {
|
||||
FACTION,
|
||||
DIALOG,
|
||||
DIALOG_CATEGORY,
|
||||
QUEST,
|
||||
QUEST_CATEGORY,
|
||||
PLAYERDATA,
|
||||
MAGIC,
|
||||
MAGIC_CYCLE,
|
||||
WORKBENCH_RECIPES,
|
||||
CARPENTRY_RECIPES,
|
||||
ANVIL_RECIPES,
|
||||
CUSTOM_EFFECTS
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.achievement.GuiAchievement;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.stats.Achievement;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.CustomItems;
|
||||
import noppes.npcs.client.MessageAchievement;
|
||||
import noppes.npcs.config.ConfigClient;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class AchievementPacket extends AbstractPacket {
|
||||
public static final String packetName = "Data|Achievement";
|
||||
|
||||
private boolean isParty;
|
||||
private String description;
|
||||
private String message;
|
||||
|
||||
public AchievementPacket() {
|
||||
}
|
||||
|
||||
public AchievementPacket(boolean isParty, String description, String message) {
|
||||
this.isParty = isParty;
|
||||
this.description = description;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static void sendAchievement(EntityPlayerMP playerMP, boolean isParty, String description, String message) {
|
||||
AchievementPacket packet = new AchievementPacket(isParty, description, message);
|
||||
PacketHandler.Instance.sendToPlayer(packet, playerMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.ACHIEVEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeBoolean(this.isParty);
|
||||
ByteBufUtils.writeString(out, this.description);
|
||||
ByteBufUtils.writeString(out, this.message);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
if (!ConfigClient.BannerAlerts)
|
||||
return;
|
||||
|
||||
boolean isNotParty = !in.readBoolean();
|
||||
String description = StatCollector.translateToLocal(ByteBufUtils.readString(in));
|
||||
String message = ByteBufUtils.readString(in);
|
||||
Achievement ach = isNotParty ? new MessageAchievement(message, description) : new MessageAchievement(CustomItems.bag == null ? Items.paper : CustomItems.bag, message, description);
|
||||
Minecraft.getMinecraft().guiAchievement.func_146256_a(ach);
|
||||
ObfuscationReflectionHelper.setPrivateValue(GuiAchievement.class, Minecraft.getMinecraft().guiAchievement, ach.getDescription(), 4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import kamkeel.npcs.util.ColorUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.IChatComponent;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.config.ConfigClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ChatAlertPacket extends AbstractPacket {
|
||||
public static final String packetName = "Data|ChatAlert";
|
||||
|
||||
private Object[] objects;
|
||||
|
||||
public ChatAlertPacket() {
|
||||
}
|
||||
|
||||
public ChatAlertPacket(final Object... obs) {
|
||||
this.objects = obs;
|
||||
}
|
||||
|
||||
public static void sendChatAlert(EntityPlayerMP playerMP, final Object... obs) {
|
||||
ChatAlertPacket packet = new ChatAlertPacket(obs);
|
||||
PacketHandler.Instance.sendToPlayer(packet, playerMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.CHAT_ALERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
ByteBufUtils.fillBuffer(out, this.objects);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
if (!ConfigClient.ChatAlerts)
|
||||
return;
|
||||
|
||||
// Read all objects (sent as strings) from the buffer.
|
||||
List<String> parts = new ArrayList<>();
|
||||
String part;
|
||||
while ((part = ByteBufUtils.readString(in)) != null && !part.isEmpty()) {
|
||||
parts.add(part);
|
||||
}
|
||||
|
||||
StringBuilder finalMessage = new StringBuilder();
|
||||
for (String s : parts) {
|
||||
finalMessage.append(StatCollector.translateToLocal(s));
|
||||
}
|
||||
|
||||
String text = finalMessage.toString();
|
||||
IChatComponent comp = ColorUtil.assembleComponent(text);
|
||||
player.addChatMessage(comp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import noppes.npcs.NoppesStringUtils;
|
||||
import noppes.npcs.client.RenderChatMessages;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class ChatBubblePacket extends AbstractPacket {
|
||||
public static final String packetName = "Data|ChatBubble";
|
||||
|
||||
private int entityId;
|
||||
private String text;
|
||||
private boolean hideText;
|
||||
|
||||
public ChatBubblePacket() {
|
||||
}
|
||||
|
||||
public ChatBubblePacket(int entityId, String text, boolean hideText) {
|
||||
this.entityId = entityId;
|
||||
this.text = text;
|
||||
this.hideText = hideText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.CHATBUBBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeInt(this.entityId);
|
||||
ByteBufUtils.writeString(out, this.text);
|
||||
out.writeBoolean(this.hideText);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(in.readInt());
|
||||
if (!(entity instanceof EntityNPCInterface))
|
||||
return;
|
||||
|
||||
EntityNPCInterface npc = (EntityNPCInterface) entity;
|
||||
if (npc.messages == null)
|
||||
npc.messages = new RenderChatMessages();
|
||||
String text = NoppesStringUtils.formatText(ByteBufUtils.readString(in), player, npc);
|
||||
npc.messages.addMessage(text, npc);
|
||||
|
||||
if (in.readBoolean())
|
||||
player.addChatMessage(new ChatComponentTranslation(npc.getCommandSenderName() + ": " + text));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import kamkeel.npcs.network.LargeAbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.client.NoppesUtil;
|
||||
import noppes.npcs.client.gui.GuiNpcMobSpawnerAdd;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class ClonerPacket extends LargeAbstractPacket {
|
||||
public static final String packetName = "Data|Clone";
|
||||
|
||||
private NBTTagCompound compound;
|
||||
|
||||
public ClonerPacket() {
|
||||
}
|
||||
|
||||
public ClonerPacket(NBTTagCompound comp) {
|
||||
this.compound = comp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.CLONE_NPC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected byte[] getData() throws IOException {
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
ByteBufUtils.writeBigNBT(buffer, compound);
|
||||
byte[] bytes = new byte[buffer.readableBytes()];
|
||||
buffer.readBytes(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
protected void handleCompleteData(ByteBuf data, EntityPlayer player) throws IOException {
|
||||
NBTTagCompound nbt = ByteBufUtils.readBigNBT(data);
|
||||
NoppesUtil.openGUI(player, new GuiNpcMobSpawnerAdd(nbt));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumConfigOperation;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import noppes.npcs.client.ClientProxy;
|
||||
import noppes.npcs.client.ClientProxy.FontContainer;
|
||||
import noppes.npcs.config.ConfigClient;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class ConfigCommandPacket extends AbstractPacket {
|
||||
public static final String packetName = "Data|ConfigCommand";
|
||||
|
||||
private EnumConfigOperation configOperation;
|
||||
private Object[] objects;
|
||||
|
||||
public ConfigCommandPacket() {
|
||||
}
|
||||
|
||||
public ConfigCommandPacket(EnumConfigOperation operation, Object... obs) {
|
||||
this.configOperation = operation;
|
||||
this.objects = obs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.CONFIG_COMMAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeInt(this.configOperation.ordinal());
|
||||
ByteBufUtils.fillBuffer(out, objects);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
EnumConfigOperation configType = EnumConfigOperation.values()[in.readInt()];
|
||||
if (configType == EnumConfigOperation.FONT) { // Font Configuration
|
||||
String font = ByteBufUtils.readString(in);
|
||||
if(font == null)
|
||||
return;
|
||||
|
||||
int size = in.readInt();
|
||||
if (!font.isEmpty()) {
|
||||
ConfigClient.FontType = font;
|
||||
ConfigClient.FontSize = size;
|
||||
ClientProxy.Font = new FontContainer(ConfigClient.FontType, ConfigClient.FontSize);
|
||||
|
||||
ConfigClient.FontTypeProperty.set(ConfigClient.FontType);
|
||||
ConfigClient.FontSizeProperty.set(ConfigClient.FontSize);
|
||||
|
||||
if (ConfigClient.config.hasChanged()) {
|
||||
ConfigClient.config.save();
|
||||
}
|
||||
|
||||
player.addChatMessage(new ChatComponentTranslation("Font set to %s", ClientProxy.Font.getName()));
|
||||
} else {
|
||||
player.addChatMessage(new ChatComponentTranslation("Current font is %s", ClientProxy.Font.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import noppes.npcs.client.ClientEventHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class DisableMouseInputPacket extends AbstractPacket {
|
||||
public static final String packetName = "Data|DisableMouseInput";
|
||||
|
||||
private long duration;
|
||||
private String keys;
|
||||
|
||||
public DisableMouseInputPacket() {
|
||||
}
|
||||
|
||||
public DisableMouseInputPacket(long duration, String keys) {
|
||||
this.duration = duration;
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.DISABLE_MOUSE_INPUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeLong(this.duration);
|
||||
ByteBufUtils.writeString(out, this.keys);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
long duration = in.readLong();
|
||||
String parsedButtons = ByteBufUtils.readString(in);
|
||||
|
||||
if (parsedButtons == null || parsedButtons.isEmpty()) {
|
||||
ClientEventHandler.disabledButtonTimes.put(-1, duration);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] buttonIds = parsedButtons.split(";");
|
||||
for (String button : buttonIds) {
|
||||
ClientEventHandler.disabledButtonTimes.put(Integer.parseInt(button), duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package kamkeel.npcs.network.packets.data;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.enums.EnumDataPacket;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import noppes.npcs.client.ClientCacheHandler;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class LoginPacket extends AbstractPacket {
|
||||
public static final String packetName = "CNPC+|Login";
|
||||
public LoginPacket() {}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumDataPacket.LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.DATA_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeBoolean(ConfigMain.PartiesEnabled);
|
||||
out.writeBoolean(ConfigMain.ProfilesEnabled);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
ClientCacheHandler.allowParties = in.readBoolean();
|
||||
ClientCacheHandler.allowProfiles = in.readBoolean();
|
||||
}
|
||||
}
|
||||
Loaded 100 of 799 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user