mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 03:47:27 +00:00
More Profile Handling + Login Packet
This commit is contained in:
1 parent
36181d5165
commit
e8f657f7e6
17 files changed
+294
-223
No files matched your search
+1
-1
@@ -5,7 +5,7 @@ plugins {
|
||||
id 'idea'
|
||||
}
|
||||
|
||||
version = "1.9.4-beta3.2"
|
||||
version = "1.9.4-beta3.3"
|
||||
group= "kamkeel.customnpc-plus"
|
||||
archivesBaseName = "CustomNPC-Plus"
|
||||
|
||||
|
||||
@@ -99,7 +99,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,13 @@ import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.data.Profile;
|
||||
import kamkeel.npcs.controllers.data.ProfileOperation;
|
||||
import kamkeel.npcs.controllers.data.Slot;
|
||||
import noppes.npcs.LogWriter;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import noppes.npcs.LogWriter;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.*;
|
||||
|
||||
public class CommandProfileAdmin extends CommandProfileBase {
|
||||
@@ -23,7 +22,7 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Admin profile management: clone, remove, change, and list a player's slots.";
|
||||
return "Admin profile management: clone, remove, change, list, rename, and rollback profiles.";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,7 +35,7 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
usage = "<sourcePlayer> <destinationPlayer> <sourceSlot> <destinationSlot> [temp]"
|
||||
)
|
||||
public void clone(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 4) {
|
||||
if(args.length < 4) {
|
||||
sendError(sender, "Usage: /profile admin clone <sourcePlayer> <destinationPlayer> <sourceSlot> <destinationSlot> [temp]");
|
||||
return;
|
||||
}
|
||||
@@ -47,55 +46,31 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
sourceSlot = Integer.parseInt(args[2]);
|
||||
destinationSlot = Integer.parseInt(args[3]);
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, "Source and destination slot IDs must be numbers.");
|
||||
sendError(sender, "Slot IDs must be numbers.");
|
||||
return;
|
||||
}
|
||||
boolean temporary = (args.length >= 5 && args[4].equalsIgnoreCase("temp"));
|
||||
|
||||
Profile sourceProfile = ProfileController.getProfile(sourcePlayer);
|
||||
if (sourceProfile == null) {
|
||||
sendError(sender, "Source profile not found for player: " + sourcePlayer);
|
||||
return;
|
||||
}
|
||||
Profile destProfile = ProfileController.getProfile(destinationPlayer);
|
||||
if (destProfile == null) {
|
||||
sendError(sender, "Destination profile not found for player: " + destinationPlayer);
|
||||
return;
|
||||
}
|
||||
if (destProfile.locked) {
|
||||
sendError(sender, "Destination profile is locked. Please try again later.");
|
||||
return;
|
||||
}
|
||||
if (!sourceProfile.slots.containsKey(sourceSlot)) {
|
||||
sendError(sender, "Source slot " + sourceSlot + " does not exist for player: " + sourcePlayer);
|
||||
return;
|
||||
}
|
||||
if (destinationSlot == destProfile.currentID) {
|
||||
sendError(sender, "Cannot clone into the destination's active slot.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Slot sourceSlotObj = sourceProfile.slots.get(sourceSlot);
|
||||
if (sourceSlotObj == null) {
|
||||
sendError(sender, "Source slot is invalid.");
|
||||
return;
|
||||
}
|
||||
NBTTagCompound clonedData = (NBTTagCompound) sourceSlotObj.getCompound().copy();
|
||||
Slot clonedSlot = new Slot(destinationSlot, "Admin Cloned Slot " + destinationSlot, clonedData, System.currentTimeMillis(), temporary);
|
||||
destProfile.slots.put(destinationSlot, clonedSlot);
|
||||
|
||||
if (destProfile.player != null) {
|
||||
ProfileController.save(destProfile.player, destProfile);
|
||||
} else {
|
||||
UUID destUUID = ProfileController.getUUIDFromUsername(destinationPlayer);
|
||||
if (destUUID != null)
|
||||
ProfileController.saveOffline(destProfile, destUUID);
|
||||
}
|
||||
sendResult(sender, "Successfully cloned slot %d from %s to slot %d for %s%s.",
|
||||
sourceSlot, sourcePlayer, destinationSlot, destinationPlayer, (temporary ? " (temporary)" : ""));
|
||||
} catch (Exception e) {
|
||||
LogWriter.error("Error cloning slot", e);
|
||||
sendError(sender, "An error occurred while cloning slot.");
|
||||
ProfileOperation result = ProfileController.cloneSlot(sourcePlayer, sourceSlot, destinationSlot, temporary);
|
||||
switch(result) {
|
||||
case SUCCESS:
|
||||
sendResult(sender, "Successfully cloned slot %d from %s to slot %d for %s.", sourceSlot, sourcePlayer, destinationSlot, destinationPlayer);
|
||||
break;
|
||||
case NEW_SLOT_CREATED:
|
||||
sendResult(sender, "Successfully cloned slot %d from %s to NEW slot %d for %s.", sourceSlot, sourcePlayer, destinationSlot, destinationPlayer);
|
||||
break;
|
||||
case LOCKED:
|
||||
sendError(sender, "Profile is locked. Please try again later.");
|
||||
break;
|
||||
case VERIFICATION_FAILED:
|
||||
sendError(sender, "Profile verification failed. Change not permitted.");
|
||||
break;
|
||||
case PLAYER_NOT_FOUND:
|
||||
sendError(sender, "Player profile not found.");
|
||||
break;
|
||||
case ERROR:
|
||||
default:
|
||||
sendError(sender, "Error cloning slot.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +79,7 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
usage = "<targetPlayer> <slotId>"
|
||||
)
|
||||
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 2) {
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: /profile admin remove <targetPlayer> <slotId>");
|
||||
return;
|
||||
}
|
||||
@@ -112,29 +87,21 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
Profile targetProfile = ProfileController.getProfile(targetPlayer);
|
||||
if (targetProfile == null) {
|
||||
sendError(sender, "Profile not found for player: " + targetPlayer);
|
||||
return;
|
||||
}
|
||||
if (targetProfile.locked) {
|
||||
sendError(sender, "Profile for " + targetPlayer + " is locked. Please try again later.");
|
||||
return;
|
||||
}
|
||||
ProfileOperation result = ProfileController.removeSlot(targetPlayer, slotId);
|
||||
switch (result) {
|
||||
switch(result) {
|
||||
case SUCCESS:
|
||||
sendResult(sender, "Successfully removed slot %d from %s.", slotId, targetPlayer);
|
||||
break;
|
||||
case LOCKED:
|
||||
sendError(sender, "Profile for " + targetPlayer + " is locked.");
|
||||
sendError(sender, "Profile for %s is locked. Please try again later.", targetPlayer);
|
||||
break;
|
||||
default:
|
||||
sendError(sender, "Error removing slot %d from %s.", slotId, targetPlayer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +110,7 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
usage = "<targetPlayer> <newSlotId>"
|
||||
)
|
||||
public void change(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 2) {
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: /profile admin change <targetPlayer> <newSlotId>");
|
||||
return;
|
||||
}
|
||||
@@ -151,29 +118,29 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
int newSlotId;
|
||||
try {
|
||||
newSlotId = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
Profile targetProfile = ProfileController.getProfile(targetPlayer);
|
||||
if (targetProfile == null) {
|
||||
sendError(sender, "Profile not found for player: " + targetPlayer);
|
||||
return;
|
||||
}
|
||||
if (targetProfile.locked) {
|
||||
sendError(sender, "Profile for " + targetPlayer + " is locked. Please try again later.");
|
||||
return;
|
||||
}
|
||||
ProfileOperation result = ProfileController.changeSlot(targetPlayer, newSlotId);
|
||||
switch (result) {
|
||||
switch(result) {
|
||||
case SUCCESS:
|
||||
sendResult(sender, "Successfully changed %s's active slot to %d.", targetPlayer, newSlotId);
|
||||
break;
|
||||
case NEW_SLOT_CREATED:
|
||||
sendResult(sender, "Switched %s to NEW slot %d (new profile created).", targetPlayer, newSlotId);
|
||||
break;
|
||||
case ALREADY_ACTIVE:
|
||||
sendError(sender, "Slot %d is already active for %s.", newSlotId, targetPlayer);
|
||||
break;
|
||||
case LOCKED:
|
||||
sendError(sender, "Profile for " + targetPlayer + " is locked.");
|
||||
sendError(sender, "Profile for %s is locked. Please try again later.", targetPlayer);
|
||||
break;
|
||||
case VERIFICATION_FAILED:
|
||||
sendError(sender, "Profile verification failed for %s.", targetPlayer);
|
||||
break;
|
||||
default:
|
||||
sendError(sender, "Error changing active slot for " + targetPlayer);
|
||||
sendError(sender, "Error changing active slot for %s.", targetPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,21 +149,21 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
usage = "<targetPlayer>"
|
||||
)
|
||||
public void list(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 1) {
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: /profile admin list <targetPlayer>");
|
||||
return;
|
||||
}
|
||||
String targetPlayer = args[0];
|
||||
Profile targetProfile = ProfileController.getProfile(targetPlayer);
|
||||
if (targetProfile == null) {
|
||||
Profile profile = ProfileController.getProfile(targetPlayer);
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found for player: " + targetPlayer);
|
||||
return;
|
||||
}
|
||||
sendMessage(sender, "Profile Slots for " + targetPlayer + ":");
|
||||
for (Map.Entry<Integer, Slot> entry : targetProfile.slots.entrySet()) {
|
||||
sendMessage(sender, "Profile Slots for %s:", targetPlayer);
|
||||
for(Map.Entry<Integer, Slot> entry : profile.slots.entrySet()) {
|
||||
int id = entry.getKey();
|
||||
String name = entry.getValue().getName();
|
||||
String prefix = (id == targetProfile.currentID) ? "* " : "- ";
|
||||
String prefix = (id == profile.currentID) ? "* " : "- ";
|
||||
sendMessage(sender, prefix + "Slot " + id + ": " + name);
|
||||
}
|
||||
}
|
||||
@@ -206,7 +173,7 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
usage = "<targetPlayer> <slotId> <newName>"
|
||||
)
|
||||
public void rename(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 3) {
|
||||
if(args.length < 3) {
|
||||
sendError(sender, "Usage: /profile admin rename <targetPlayer> <slotId> <newName>");
|
||||
return;
|
||||
}
|
||||
@@ -214,50 +181,69 @@ public class CommandProfileAdmin extends CommandProfileBase {
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
// Combine remaining arguments for the new name.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 2; i < args.length; i++) {
|
||||
if (i > 2) sb.append(" ");
|
||||
for(int i = 2; i < args.length; i++){
|
||||
if(i > 2) sb.append(" ");
|
||||
sb.append(args[i]);
|
||||
}
|
||||
String newName = sb.toString().trim();
|
||||
// Cap name at 20 characters.
|
||||
if (newName.length() > 20) {
|
||||
if(newName.length() > 20) {
|
||||
newName = newName.substring(0, 20);
|
||||
}
|
||||
// Validate that name contains only letters and spaces.
|
||||
if (!newName.matches("[A-Za-z ]+")) {
|
||||
if(!newName.matches("[A-Za-z ]+")){
|
||||
sendError(sender, "Invalid name. Only alphabetic characters and spaces are allowed.");
|
||||
return;
|
||||
}
|
||||
Profile targetProfile = ProfileController.getProfile(targetPlayer);
|
||||
if (targetProfile == null) {
|
||||
Profile profile = ProfileController.getProfile(targetPlayer);
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found for player: " + targetPlayer);
|
||||
return;
|
||||
}
|
||||
if (targetProfile.locked) {
|
||||
sendError(sender, "Profile for " + targetPlayer + " is locked. Please try again later.");
|
||||
if(profile.locked) {
|
||||
sendError(sender, "Profile for %s is locked. Please try again later.", targetPlayer);
|
||||
return;
|
||||
}
|
||||
if (!targetProfile.slots.containsKey(slotId)) {
|
||||
sendError(sender, "Slot " + slotId + " not found in " + targetPlayer + "'s profile.");
|
||||
if(!profile.slots.containsKey(slotId)) {
|
||||
sendError(sender, "Slot %d not found in %s's profile.", slotId, targetPlayer);
|
||||
return;
|
||||
}
|
||||
// Rename the slot.
|
||||
Slot targetSlot = targetProfile.slots.get(slotId);
|
||||
targetSlot.setName(newName);
|
||||
// Save the updated profile.
|
||||
if (targetProfile.player != null) {
|
||||
ProfileController.save(targetProfile.player, targetProfile);
|
||||
profile.slots.get(slotId).setName(newName);
|
||||
if(profile.player != null) {
|
||||
ProfileController.save(profile.player, profile);
|
||||
} else {
|
||||
UUID uuid = ProfileController.getUUIDFromUsername(targetPlayer);
|
||||
if (uuid != null)
|
||||
ProfileController.saveOffline(targetProfile, uuid);
|
||||
if(uuid != null)
|
||||
ProfileController.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];
|
||||
File backupDir = new File(ProfileController.getBackupDir(), ProfileController.getProfile(targetPlayer).player.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.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);
|
||||
}
|
||||
sendResult(sender, "Successfully renamed slot %s for %s to '%s'.", slotId, targetPlayer, newName);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import kamkeel.npcs.controllers.data.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;
|
||||
|
||||
@@ -33,35 +32,41 @@ public class CommandProfileChange extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
if (args.length < 1) {
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: " + getUsage());
|
||||
return;
|
||||
}
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number: " + args[0]);
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer) sender;
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
ProfileOperation result = ProfileController.changeSlot(player, slotId);
|
||||
switch(result) {
|
||||
case SUCCESS:
|
||||
sendResult(sender, "Successfully changed profile slot to %s.", slotId);
|
||||
sendResult(sender, "Successfully changed profile slot to %d.", slotId);
|
||||
break;
|
||||
case NEW_SLOT_CREATED:
|
||||
sendResult(sender, "Switched to new slot %d (new profile created).", slotId);
|
||||
break;
|
||||
case ALREADY_ACTIVE:
|
||||
sendError(sender, "Slot %d is already active.", slotId);
|
||||
break;
|
||||
case LOCKED:
|
||||
sendError(sender, "Profile is locked. Please try again later.");
|
||||
break;
|
||||
case ERROR:
|
||||
sendError(sender, "Error occurred while changing your profile slot.");
|
||||
case VERIFICATION_FAILED:
|
||||
sendError(sender, "Profile verification failed. Change not permitted.");
|
||||
break;
|
||||
default:
|
||||
sendError(sender, "Operation could not be completed.");
|
||||
sendError(sender, "Error occurred while changing your profile slot.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,7 @@ import kamkeel.npcs.controllers.data.Slot;
|
||||
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;
|
||||
|
||||
@@ -31,18 +29,21 @@ public class CommandProfileList extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer) sender;
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
Profile profile = ProfileController.getProfile(player);
|
||||
if (profile == null) {
|
||||
if(profile == null) {
|
||||
sendError(sender, "Profile not found.");
|
||||
return;
|
||||
}
|
||||
if(profile.slots.isEmpty()){
|
||||
sendMessage(sender, "No slots found. Using default slot 0.");
|
||||
}
|
||||
sendMessage(sender, "Your Profile Slots:");
|
||||
for (Map.Entry<Integer, Slot> entry : profile.slots.entrySet()) {
|
||||
for(Map.Entry<Integer, Slot> entry : profile.slots.entrySet()) {
|
||||
int id = entry.getKey();
|
||||
String name = entry.getValue().getName();
|
||||
String prefix = (id == profile.currentID) ? "* " : "- ";
|
||||
|
||||
@@ -5,7 +5,6 @@ import kamkeel.npcs.controllers.data.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;
|
||||
|
||||
@@ -33,22 +32,22 @@ public class CommandProfileRemove extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
if (args.length < 1) {
|
||||
if(args.length < 1) {
|
||||
sendError(sender, "Usage: " + getUsage());
|
||||
return;
|
||||
}
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number: " + args[0]);
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer) sender;
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
ProfileOperation result = ProfileController.removeSlot(player, slotId);
|
||||
switch(result) {
|
||||
case SUCCESS:
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package kamkeel.npcs.command.profile;
|
||||
|
||||
import kamkeel.npcs.controllers.ProfileController;
|
||||
import kamkeel.npcs.controllers.data.Profile;
|
||||
import kamkeel.npcs.controllers.data.Slot;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
@@ -29,52 +27,45 @@ public class CommandProfileRename extends CommandProfileBase {
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
if(!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by a player.");
|
||||
return;
|
||||
}
|
||||
if (args.length < 2) {
|
||||
if(args.length < 2) {
|
||||
sendError(sender, "Usage: " + getUsage());
|
||||
return;
|
||||
}
|
||||
int slotId;
|
||||
try {
|
||||
slotId = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch(NumberFormatException ex) {
|
||||
sendError(sender, "Slot ID must be a number.");
|
||||
return;
|
||||
}
|
||||
// Combine remaining arguments into one name string.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
if (i > 1) sb.append(" ");
|
||||
for(int i = 1; i < args.length; i++){
|
||||
if(i > 1) sb.append(" ");
|
||||
sb.append(args[i]);
|
||||
}
|
||||
String newName = sb.toString().trim();
|
||||
// Cap at 20 characters.
|
||||
if (newName.length() > 20) {
|
||||
if(newName.length() > 20) {
|
||||
newName = newName.substring(0, 20);
|
||||
}
|
||||
// Validate that the new name contains only letters and spaces.
|
||||
if (!newName.matches("[A-Za-z ]+")) {
|
||||
if(!newName.matches("[A-Za-z ]+")){
|
||||
sendError(sender, "Invalid name. Only alphabetic characters and spaces are allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPlayer player = (EntityPlayer) sender;
|
||||
Profile profile = ProfileController.getProfile(player);
|
||||
if (profile == null) {
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
if(ProfileController.getProfile(player) == null) {
|
||||
sendError(sender, "Profile not found.");
|
||||
return;
|
||||
}
|
||||
if (!profile.slots.containsKey(slotId)) {
|
||||
sendError(sender, "Slot " + slotId + " not found in your profile.");
|
||||
if(!ProfileController.getProfile(player).slots.containsKey(slotId)) {
|
||||
sendError(sender, "Slot %d not found in your profile.", slotId);
|
||||
return;
|
||||
}
|
||||
Slot slot = profile.slots.get(slotId);
|
||||
slot.setName(newName);
|
||||
// Save the profile after renaming.
|
||||
ProfileController.save(player, profile);
|
||||
sendResult(sender, "Successfully renamed slot %s to '%s'.", slotId, newName);
|
||||
ProfileController.getProfile(player).slots.get(slotId).setName(newName);
|
||||
ProfileController.save(player, ProfileController.getProfile(player));
|
||||
sendResult(sender, "Successfully renamed slot %d to '%s'.", slotId, newName);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package kamkeel.npcs.controllers;
|
||||
|
||||
import kamkeel.npcs.controllers.data.IProfileData;
|
||||
import kamkeel.npcs.controllers.data.ProfileOperation;
|
||||
import kamkeel.npcs.controllers.data.Profile;
|
||||
import kamkeel.npcs.controllers.data.ProfileOperation;
|
||||
import kamkeel.npcs.controllers.data.Slot;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -11,17 +11,15 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.util.CustomNPCsThreader;
|
||||
import noppes.npcs.util.NBTJsonUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class ProfileController {
|
||||
@@ -36,7 +34,6 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
// ---------- Registration & I/O ----------
|
||||
|
||||
public static boolean registerProfileType(IProfileData type){
|
||||
if(profileTypes.containsKey(type.getTagName()))
|
||||
return false;
|
||||
@@ -56,7 +53,18 @@ public class ProfileController {
|
||||
}
|
||||
}
|
||||
|
||||
// Login for online players
|
||||
// Returns the backup folder for profiles.
|
||||
public static File getBackupDir() {
|
||||
File base = getProfileDir();
|
||||
File backup = new File(base, "backup");
|
||||
if(!backup.exists()){
|
||||
backup.mkdir();
|
||||
}
|
||||
return backup;
|
||||
}
|
||||
|
||||
// Login for online players.
|
||||
// If no slots exist, create default slot 0 and save the player's current IProfileData into it.
|
||||
public static synchronized void login(EntityPlayer player){
|
||||
if(player == null)
|
||||
return;
|
||||
@@ -67,6 +75,15 @@ public class ProfileController {
|
||||
} else {
|
||||
NBTTagCompound compound = load(player);
|
||||
profile = new Profile(player, compound);
|
||||
// If no slots exist, create default slot 0.
|
||||
if(profile.slots.isEmpty()){
|
||||
Slot defaultSlot = new Slot(0, "Default Slot");
|
||||
defaultSlot.setCompound(new NBTTagCompound());
|
||||
profile.slots.put(0, defaultSlot);
|
||||
profile.currentID = 0;
|
||||
saveSlotData(player);
|
||||
save(player, profile);
|
||||
}
|
||||
activeProfiles.put(player.getUniqueID(), profile);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +116,7 @@ public class ProfileController {
|
||||
return new NBTTagCompound();
|
||||
}
|
||||
|
||||
// Offline save (synchronous) when no EntityPlayer is available
|
||||
// Offline save (synchronous) when no EntityPlayer is available.
|
||||
public static synchronized void saveOffline(Profile profile, UUID uuid) {
|
||||
final NBTTagCompound compound = profile.writeToNBT();
|
||||
final String filename = uuid.toString() + ".dat";
|
||||
@@ -112,12 +129,14 @@ public class ProfileController {
|
||||
fileOld.delete();
|
||||
}
|
||||
fileNew.renameTo(fileOld);
|
||||
// Also backup if allowed.
|
||||
backupProfile(uuid, compound);
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Save for online players (asynchronous)
|
||||
// Save for online players (asynchronous).
|
||||
public static synchronized void save(EntityPlayer player, Profile profile) {
|
||||
profile.locked = true;
|
||||
CustomNPCsThreader.customNPCThread.execute(() -> {
|
||||
@@ -132,6 +151,10 @@ public class ProfileController {
|
||||
fileOld.delete();
|
||||
}
|
||||
fileNew.renameTo(fileOld);
|
||||
// Backup if enabled.
|
||||
if(ConfigMain.AllowProfileBackups) {
|
||||
backupProfile(player.getUniqueID(), compound);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
} finally {
|
||||
@@ -140,7 +163,67 @@ public class ProfileController {
|
||||
});
|
||||
}
|
||||
|
||||
// Logout removes an active profile
|
||||
// Backup the profile by saving a copy to profiles/backup/<uuid>/<date>.dat.
|
||||
private static 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));
|
||||
// Now enforce backup amount limit.
|
||||
File[] backups = backupDir.listFiles((dir, name) -> name.endsWith(".dat"));
|
||||
if(backups != null && backups.length > ConfigMain.ProfileBackupAmount) {
|
||||
// Sort backups by last modified ascending (oldest first)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Rollback a player's profile from a backup file.
|
||||
// Returns true if successful.
|
||||
public static 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);
|
||||
// Overwrite the main profile file.
|
||||
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);
|
||||
|
||||
// Update the in-memory profile.
|
||||
EntityPlayerMP player = getPlayer(username);
|
||||
Profile newProfile;
|
||||
if(player != null) {
|
||||
newProfile = new Profile(player, compound);
|
||||
activeProfiles.put(uuid, newProfile);
|
||||
// Load the rolled-back data into the player's IProfileData.
|
||||
loadSlotData(player);
|
||||
} else {
|
||||
newProfile = new Profile(null, compound);
|
||||
activeProfiles.put(uuid, newProfile);
|
||||
}
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
LogWriter.except(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Logout removes an active profile.
|
||||
public static synchronized void logout(EntityPlayer player) {
|
||||
if(player != null) {
|
||||
activeProfiles.remove(player.getUniqueID());
|
||||
@@ -148,8 +231,6 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
// ---------- Profile Retrieval Helpers ----------
|
||||
|
||||
// Get profile via EntityPlayer (online)
|
||||
public static Profile getProfile(EntityPlayer player) {
|
||||
if(player == null) return null;
|
||||
if(!activeProfiles.containsKey(player.getUniqueID()))
|
||||
@@ -157,7 +238,6 @@ public class ProfileController {
|
||||
return activeProfiles.get(player.getUniqueID());
|
||||
}
|
||||
|
||||
// Get profile via UUID (may be offline)
|
||||
public static Profile getProfile(UUID uuid) {
|
||||
if(activeProfiles.containsKey(uuid))
|
||||
return activeProfiles.get(uuid);
|
||||
@@ -165,7 +245,6 @@ public class ProfileController {
|
||||
return new Profile(null, compound);
|
||||
}
|
||||
|
||||
// Get profile via username (tries online first, then offline via Mojang API)
|
||||
public static Profile getProfile(String username) {
|
||||
EntityPlayer player = getPlayer(username);
|
||||
if(player != null) {
|
||||
@@ -178,7 +257,6 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
// ---------- Mojang API UUID Lookup ----------
|
||||
|
||||
public static UUID getUUIDFromUsername(String username) {
|
||||
try {
|
||||
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username);
|
||||
@@ -214,7 +292,6 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
// ---------- Internal Slot Operation Helpers ----------
|
||||
|
||||
// Returns the next available temporary (negative) slot id (starting at -1)
|
||||
private static int getNextAvailableTempSlot(Profile profile) {
|
||||
int id = -1;
|
||||
@@ -225,15 +302,12 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
// Clone a slot within a Profile.
|
||||
// sourceSlotId is the slot to copy.
|
||||
// destinationSlotId is the target id for non-temporary clones.
|
||||
// If temporary==true, destinationSlotId is computed automatically.
|
||||
private static ProfileOperation cloneSlotInternal(Profile profile, int sourceSlotId, int destinationSlotId, boolean temporary) {
|
||||
if(profile.locked) {
|
||||
LogWriter.error("Profile is locked; cannot clone slot.");
|
||||
return ProfileOperation.LOCKED;
|
||||
}
|
||||
|
||||
// Run verification checks on all IProfileData in priority order.
|
||||
if(profile.player != null) {
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
@@ -245,7 +319,6 @@ public class ProfileController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!profile.slots.containsKey(sourceSlotId)) {
|
||||
LogWriter.error("Source slot " + sourceSlotId + " does not exist.");
|
||||
return ProfileOperation.ERROR;
|
||||
@@ -288,17 +361,22 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
// Change the active slot in a Profile.
|
||||
// If the new slot doesn't exist, it is created and NEW_SLOT_CREATED is returned.
|
||||
// Saves current slot data before switching.
|
||||
private static ProfileOperation changeSlotInternal(Profile profile, int newSlotId) {
|
||||
if(profile.locked) {
|
||||
LogWriter.error("Profile is locked; cannot change slot.");
|
||||
return ProfileOperation.LOCKED;
|
||||
}
|
||||
|
||||
// Run verification checks from all registered IProfileData in order of priority.
|
||||
// Disallow switching to the same active slot.
|
||||
if(profile.currentID == newSlotId) {
|
||||
LogWriter.error("Slot " + newSlotId + " is already active.");
|
||||
return ProfileOperation.ALREADY_ACTIVE;
|
||||
}
|
||||
// Run verification checks from all IProfileData in order of priority.
|
||||
if(profile.player != null) {
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));;
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
for(IProfileData pd : dataList) {
|
||||
if(!pd.verifySwitch(profile.player)) {
|
||||
LogWriter.error("Verification check failed for profile type: " + pd.getTagName());
|
||||
@@ -306,34 +384,31 @@ public class ProfileController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(profile.player != null) {
|
||||
saveSlotData(profile.player);
|
||||
}
|
||||
|
||||
boolean createdNewSlot = false;
|
||||
// If the new slot doesn't exist, create it.
|
||||
if(!profile.slots.containsKey(newSlotId)) {
|
||||
Slot newSlot = new Slot(newSlotId, "Slot " + newSlotId);
|
||||
newSlot.setCompound(new NBTTagCompound());
|
||||
profile.slots.put(newSlotId, newSlot);
|
||||
createdNewSlot = true;
|
||||
}
|
||||
|
||||
profile.currentID = newSlotId;
|
||||
if(profile.player != null) {
|
||||
loadSlotData(profile.player);
|
||||
}
|
||||
|
||||
// Update PlayerData so that PlayerData.get(player).profileSlot matches Profile.currentID.
|
||||
if(profile.player != null) {
|
||||
PlayerData pdata = PlayerData.get(profile.player);
|
||||
pdata.profileSlot = newSlotId;
|
||||
pdata.save();
|
||||
}
|
||||
return ProfileOperation.SUCCESS;
|
||||
return createdNewSlot ? ProfileOperation.NEW_SLOT_CREATED : ProfileOperation.SUCCESS;
|
||||
}
|
||||
|
||||
// ---------- Public Operations (Overloaded for EntityPlayer, UUID, or username) ----------
|
||||
|
||||
// ----- Clone Slot -----
|
||||
public static ProfileOperation cloneSlot(EntityPlayer player, int sourceSlotId, int destinationSlotId, boolean temporary) {
|
||||
Profile profile = getProfile(player);
|
||||
@@ -417,7 +492,7 @@ public class ProfileController {
|
||||
Profile profile = getProfile(player);
|
||||
if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND;
|
||||
ProfileOperation result = changeSlotInternal(profile, newSlotId);
|
||||
if(result == ProfileOperation.SUCCESS && player != null)
|
||||
if((result == ProfileOperation.SUCCESS || result == ProfileOperation.NEW_SLOT_CREATED) && player != null)
|
||||
save(player, profile);
|
||||
return result;
|
||||
}
|
||||
@@ -426,7 +501,7 @@ public class ProfileController {
|
||||
Profile profile = getProfile(uuid);
|
||||
if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND;
|
||||
ProfileOperation result = changeSlotInternal(profile, newSlotId);
|
||||
if(result == ProfileOperation.SUCCESS) {
|
||||
if(result == ProfileOperation.SUCCESS || result == ProfileOperation.NEW_SLOT_CREATED) {
|
||||
if(profile.player != null)
|
||||
save(profile.player, profile);
|
||||
else
|
||||
@@ -439,7 +514,7 @@ public class ProfileController {
|
||||
Profile profile = getProfile(username);
|
||||
if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND;
|
||||
ProfileOperation result = changeSlotInternal(profile, newSlotId);
|
||||
if(result == ProfileOperation.SUCCESS) {
|
||||
if(result == ProfileOperation.SUCCESS || result == ProfileOperation.NEW_SLOT_CREATED) {
|
||||
if(profile.player != null)
|
||||
save(profile.player, profile);
|
||||
else {
|
||||
@@ -470,7 +545,6 @@ public class ProfileController {
|
||||
dataCompound = new NBTTagCompound();
|
||||
slot.setCompound(dataCompound);
|
||||
}
|
||||
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
for(IProfileData profileData : dataList){
|
||||
@@ -483,15 +557,10 @@ public class ProfileController {
|
||||
public static void loadSlotData(EntityPlayer player) {
|
||||
if(player == null || !activeProfiles.containsKey(player.getUniqueID()))
|
||||
return;
|
||||
|
||||
Profile profile = activeProfiles.get(player.getUniqueID());
|
||||
if(profile.slots.isEmpty() || !profile.slots.containsKey(profile.currentID))
|
||||
return;
|
||||
|
||||
// Get a copy of the active slot's NBT compound.
|
||||
NBTTagCompound slotCompound = (NBTTagCompound) profile.slots.get(profile.currentID).getCompound().copy();
|
||||
|
||||
// For each registered profile data type, load its saved compound onto the player.
|
||||
List<IProfileData> dataList = new ArrayList<>(profileTypes.values());
|
||||
dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority));
|
||||
for(IProfileData profileData : dataList){
|
||||
@@ -500,10 +569,8 @@ public class ProfileController {
|
||||
data = slotCompound.getCompoundTag(profileData.getTagName());
|
||||
else
|
||||
data = new NBTTagCompound();
|
||||
|
||||
profileData.setNBT(player, data);
|
||||
}
|
||||
|
||||
for(IProfileData profileData : dataList){
|
||||
profileData.save(player);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ 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.packets.data.LoginPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.SyncEffectPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.SyncPacket;
|
||||
import kamkeel.npcs.network.enums.EnumSyncAction;
|
||||
@@ -23,6 +24,10 @@ 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,
|
||||
|
||||
@@ -11,9 +11,9 @@ public class Profile {
|
||||
public EntityPlayer player;
|
||||
public int currentID;
|
||||
public HashMap<Integer, Slot> slots = new HashMap<>();
|
||||
public boolean locked = false; // Prevent modifications while saving
|
||||
public boolean locked = false;
|
||||
|
||||
public Profile(EntityPlayer player, NBTTagCompound compound){
|
||||
public Profile(EntityPlayer player, NBTTagCompound compound) {
|
||||
this.player = player;
|
||||
if(compound.hasKey("CurrentID")){
|
||||
this.currentID = compound.getInteger("CurrentID");
|
||||
@@ -21,9 +21,9 @@ public class Profile {
|
||||
this.currentID = 0;
|
||||
}
|
||||
|
||||
if (compound.hasKey("Slots")) {
|
||||
if(compound.hasKey("Slots")) {
|
||||
NBTTagCompound slotsCompound = compound.getCompoundTag("Slots");
|
||||
for (String key : (Set<String>) slotsCompound.func_150296_c()) {
|
||||
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);
|
||||
@@ -34,7 +34,6 @@ public class Profile {
|
||||
|
||||
public NBTTagCompound writeToNBT() {
|
||||
NBTTagCompound fullCompound = new NBTTagCompound();
|
||||
|
||||
if(this.player != null)
|
||||
fullCompound.setString("Name", player.getCommandSenderName());
|
||||
fullCompound.setInteger("CurrentID", currentID);
|
||||
@@ -44,7 +43,7 @@ public class Profile {
|
||||
for (HashMap.Entry<Integer, Slot> entry : slots.entrySet()) {
|
||||
Slot slot = entry.getValue();
|
||||
if(slot.isTemporary())
|
||||
continue; // Do not save temporary slots
|
||||
continue;
|
||||
int id = entry.getKey();
|
||||
slot.setId(id);
|
||||
NBTTagCompound slotTag = slot.toNBT();
|
||||
|
||||
@@ -5,6 +5,8 @@ public enum ProfileOperation {
|
||||
ERROR,
|
||||
LOCKED,
|
||||
PLAYER_NOT_FOUND,
|
||||
NEW_SLOT_CREATED,
|
||||
ALREADY_ACTIVE,
|
||||
VERIFICATION_FAILED
|
||||
}
|
||||
|
||||
@@ -338,6 +338,7 @@ public class PacketHandler {
|
||||
|
||||
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());
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
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.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() {
|
||||
}
|
||||
|
||||
public LoginPacket() {}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
@@ -29,13 +29,14 @@ public final class LoginPacket extends AbstractPacket {
|
||||
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
// ByteBufUtils.writeUTF8String(out, this.data.player.getCommandSenderName());
|
||||
// ByteBufUtils.writeNBT(out,this.data.saveFromNBT(new NBTTagCompound()));
|
||||
out.writeBoolean(ConfigMain.PartiesEnabled);
|
||||
out.writeBoolean(ConfigMain.ProfilesEnabled);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
String playerName = ByteBufUtils.readUTF8String(in);
|
||||
|
||||
ClientCacheHandler.allowParties = in.readBoolean();
|
||||
ClientCacheHandler.allowProfiles = in.readBoolean();
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,8 @@ public class CustomNpcs {
|
||||
public void serverstart(FMLServerStartingEvent event) {
|
||||
event.registerServerCommand(new CommandNoppes());
|
||||
event.registerServerCommand(new CommandKamkeel());
|
||||
event.registerServerCommand(new CommandProfile());
|
||||
if(ConfigMain.ProfilesEnabled)
|
||||
event.registerServerCommand(new CommandProfile());
|
||||
}
|
||||
|
||||
private void registerNpc(Class<? extends Entity> cl, String name) {
|
||||
|
||||
@@ -23,6 +23,10 @@ public class ClientCacheHandler {
|
||||
|
||||
public static Party party;
|
||||
|
||||
public static boolean allowProfiles = true;
|
||||
public static boolean allowParties = true;
|
||||
|
||||
|
||||
public static ImageData getImageData(String directory) {
|
||||
synchronized (imageDataCache) {
|
||||
if (!imageDataCache.containsKey(directory)) {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package noppes.npcs.client.gui.player.inventory;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import kamkeel.npcs.addon.client.DBCClient;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import noppes.npcs.client.ClientCacheHandler;
|
||||
import noppes.npcs.client.gui.util.GuiMenuSideButton;
|
||||
import noppes.npcs.client.gui.util.GuiNPCInterface;
|
||||
import noppes.npcs.config.ConfigClient;
|
||||
@@ -41,13 +40,14 @@ public class GuiCNPCInventory extends GuiNPCInterface {
|
||||
questsButton.renderResource = specialIcons;
|
||||
addButton(questsButton);
|
||||
|
||||
y += 21;
|
||||
GuiMenuSideButton partyButton = new GuiMenuSideButton(-101, guiLeft + xSize + 37, this.guiTop + y, 22, 22, "");
|
||||
partyButton.rightSided = true;
|
||||
partyButton.active = activeTab == -101;
|
||||
partyButton.renderResource = specialIcons;
|
||||
addButton(partyButton);
|
||||
|
||||
if(ClientCacheHandler.allowParties){
|
||||
y += 21;
|
||||
GuiMenuSideButton partyButton = new GuiMenuSideButton(-101, guiLeft + xSize + 37, this.guiTop + y, 22, 22, "");
|
||||
partyButton.rightSided = true;
|
||||
partyButton.active = activeTab == -101;
|
||||
partyButton.renderResource = specialIcons;
|
||||
addButton(partyButton);
|
||||
}
|
||||
if(ConfigClient.enableFactionTab){
|
||||
y += 21;
|
||||
GuiMenuSideButton factionButton = new GuiMenuSideButton(-102, guiLeft + xSize + 37, this.guiTop + y, 22, 22, "");
|
||||
@@ -57,7 +57,7 @@ public class GuiCNPCInventory extends GuiNPCInterface {
|
||||
factionButton.renderResource = specialIcons;
|
||||
addButton(factionButton);
|
||||
}
|
||||
if(ConfigMain.EnableProfiles){
|
||||
if(ClientCacheHandler.allowProfiles){
|
||||
y += 21;
|
||||
GuiMenuSideButton profileButton = new GuiMenuSideButton(-104, guiLeft + xSize + 37, this.guiTop + y, 22, 22, "");
|
||||
profileButton.rightSided = true;
|
||||
|
||||
@@ -80,7 +80,13 @@ public class ConfigMain
|
||||
public static Property DefaultMaxPartySizeProperty;
|
||||
public static int DefaultMaxPartySize = 4;
|
||||
|
||||
public static boolean EnableProfiles = true;
|
||||
/**
|
||||
* Profile Properties
|
||||
**/
|
||||
public static boolean ProfilesEnabled = true;
|
||||
public static boolean AllowProfileBackups = true;
|
||||
public static int ProfileBackupAmount = 5;
|
||||
|
||||
|
||||
/**
|
||||
* General NPC Properties
|
||||
@@ -220,7 +226,9 @@ public class ConfigMain
|
||||
TrackedQuestUpdateFrequency = TrackedQuestUpdateFrequencyProperty.getInt(5);
|
||||
|
||||
// PROFILES
|
||||
EnableProfiles = config.get(PROFILES, "Enable Profiles", true, "Allow the use of character Profiles").getBoolean(true);
|
||||
ProfilesEnabled = config.get(PROFILES, "Enable Profiles", true, "Allow the use of character Profiles").getBoolean(true);
|
||||
AllowProfileBackups = config.get(PROFILES, "Enable Profile Backups", true, "Will create backups of profile changes").getBoolean(true);
|
||||
ProfileBackupAmount = config.get(PROFILES, "Number of Backups", 5, "How many backups per player to save").getInt(5);
|
||||
|
||||
// Convert to Legacy
|
||||
if(CustomNpcs.legacyExist){
|
||||
|
||||
Reference in new issue
Block a user