diff --git a/src/main/java/org/ultramine/commands/CommandContext.java b/src/main/java/org/ultramine/commands/CommandContext.java index 3a2caca..47960d6 100644 --- a/src/main/java/org/ultramine/commands/CommandContext.java +++ b/src/main/java/org/ultramine/commands/CommandContext.java @@ -11,9 +11,6 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.ChatStyle; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; import net.minecraft.world.WorldServer; @@ -21,6 +18,7 @@ import org.ultramine.server.PermissionHandler; import org.ultramine.server.data.ServerDataLoader; import org.ultramine.server.data.player.PlayerData; +import org.ultramine.server.util.BasicTypeFormatter; import org.ultramine.server.util.BasicTypeParser; import java.util.ArrayList; @@ -144,23 +142,9 @@ } - private IChatComponent formatMessage(EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) - { - for(int i = 0; i < args.length; i++) - { - Object o = args[i]; - if(!(o instanceof IChatComponent)) - args[i] = new ChatComponentText(o.toString()).setChatStyle(new ChatStyle().setColor(argsColor)); - } - - ChatComponentTranslation comp = new ChatComponentTranslation(msg, args); - comp.getChatStyle().setColor(tplColor); - return comp; - } - public void sendMessage(EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) { - sender.addChatMessage(formatMessage(tplColor, argsColor, msg, args)); + sender.addChatMessage(BasicTypeFormatter.formatMessage(tplColor, argsColor, msg, args)); } public void sendMessage(EnumChatFormatting argsColor, String msg, Object... args) @@ -175,7 +159,7 @@ public void broadcast(EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) { - getServer().getConfigurationManager().sendChatMsg(formatMessage(tplColor, argsColor, msg, args)); + getServer().getConfigurationManager().sendChatMsg(BasicTypeFormatter.formatMessage(tplColor, argsColor, msg, args)); } public void broadcast(EnumChatFormatting argsColor, String msg, Object... args) @@ -190,7 +174,7 @@ public void sendMessage(ICommandSender to, EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) { - to.addChatMessage(formatMessage(tplColor, argsColor, msg, args)); + to.addChatMessage(BasicTypeFormatter.formatMessage(tplColor, argsColor, msg, args)); } public void sendMessage(ICommandSender to, EnumChatFormatting argsColor, String msg, Object... args) @@ -390,6 +374,11 @@ return data; } + public OfflinePlayer asOfflinePlayer() + { + return new OfflinePlayer(getServer(), asPlayerData()); + } + public WorldServer asWorld() { WorldServer world = MinecraftServer.getServer().getMultiWorld().getWorldByNameOrID(value); diff --git a/src/main/java/org/ultramine/commands/OfflinePlayer.java b/src/main/java/org/ultramine/commands/OfflinePlayer.java new file mode 100644 index 0000000..ed1a0fc --- /dev/null +++ b/src/main/java/org/ultramine/commands/OfflinePlayer.java @@ -0,0 +1,74 @@ +package org.ultramine.commands; + +import org.ultramine.server.data.player.PlayerData; +import org.ultramine.server.util.BasicTypeFormatter; + +import com.google.common.base.Function; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.management.ServerConfigurationManager; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.util.FakePlayer; + +public class OfflinePlayer +{ + private final ServerConfigurationManager mgr; + private final PlayerData data; + + public OfflinePlayer(MinecraftServer server, PlayerData profile) + { + this.mgr = server.getConfigurationManager(); + this.data = profile; + } + + public PlayerData getPlayerData() + { + return data; + } + + public EntityPlayerMP getIfOnline() + { + return mgr.getPlayerByUsername(data.getProfile().getName()); + } + + public void loadPlayer(Function callback) + { + EntityPlayerMP exists = getIfOnline(); + if(exists != null) + callback.apply(exists); + else + mgr.getDataLoader().loadOffline(data.getProfile(), callback); + + } + + //Totally unsafe... + public void saveFakePlayer(EntityPlayerMP player) + { + if(!(player instanceof FakePlayer)) + return; + if(!player.getGameProfile().equals(data.getProfile())) + throw new RuntimeException("Player not this! this:"+data.getProfile().getName()+" other:"+player.getGameProfile().getName()); + if(getIfOnline() != null) + throw new RuntimeException("Can't save FakePlayer: real player is online! username:"+data.getProfile().getName()); + + mgr.getDataLoader().saveOfflinePlayer((FakePlayer)player); + } + + public void sendMessage(EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) + { + EntityPlayerMP player = getIfOnline(); + if(player != null) + player.addChatMessage(BasicTypeFormatter.formatMessage(tplColor, argsColor, msg, args)); + } + + public void sendMessage(EnumChatFormatting argsColor, String msg, Object... args) + { + sendMessage(EnumChatFormatting.GOLD, argsColor, msg, args); + } + + public void sendMessage(String msg, Object... args) + { + sendMessage(EnumChatFormatting.YELLOW, msg, args); + } +} diff --git a/src/main/java/org/ultramine/economy/EconomyCommands.java b/src/main/java/org/ultramine/economy/EconomyCommands.java index f908550..9371931 100644 --- a/src/main/java/org/ultramine/economy/EconomyCommands.java +++ b/src/main/java/org/ultramine/economy/EconomyCommands.java @@ -1,7 +1,6 @@ package org.ultramine.economy; import static net.minecraft.util.EnumChatFormatting.*; -import net.minecraft.entity.player.EntityPlayerMP; import org.ultramine.commands.Command; import org.ultramine.commands.CommandContext; @@ -27,9 +26,7 @@ double amount = ctx.get("amount").asDouble(); from.transactChecked(to, amount); ctx.sendMessage(DARK_GREEN, GREEN, "command.pay.sended", ctx.get("player").asString(), cur.format(amount)); - EntityPlayerMP maybeOnline = ctx.getServer().getConfigurationManager().getPlayerByUsername(ctx.get("player").asString()); - if(maybeOnline != null) - ctx.sendMessage(maybeOnline, DARK_GREEN, GREEN, "command.pay.received", cur.format(amount), ctx.getSenderAsPlayer().func_145748_c_()); + ctx.get("player").asOfflinePlayer().sendMessage(DARK_GREEN, GREEN, "command.pay.received", cur.format(amount), ctx.getSenderAsPlayer().func_145748_c_()); } @Command( @@ -72,9 +69,7 @@ to.subtract(amount); //result may be negative from.add(amount); ctx.sendMessage(DARK_GREEN, GREEN, "command.msub.sended", cur.format(amount), ctx.get("player").asString()); - EntityPlayerMP maybeOnline = ctx.getServer().getConfigurationManager().getPlayerByUsername(ctx.get("player").asString()); - if(maybeOnline != null) - ctx.sendMessage(maybeOnline, DARK_GREEN, GREEN, "command.msub.received", cur.format(amount)); + ctx.get("player").asOfflinePlayer().sendMessage(DARK_GREEN, GREEN, "command.msub.received", cur.format(amount)); } @Command( @@ -94,9 +89,7 @@ double amount = ctx.get("amount").asDouble(); holdings.add(amount); ctx.sendMessage(DARK_GREEN, GREEN, "command.mgive.sended", ctx.get("player").asString(), cur.format(amount)); - EntityPlayerMP maybeOnline = ctx.getServer().getConfigurationManager().getPlayerByUsername(ctx.get("player").asString()); - if(maybeOnline != null) - ctx.sendMessage(maybeOnline, DARK_GREEN, GREEN, "command.mgive.received", cur.format(amount)); + ctx.get("player").asOfflinePlayer().sendMessage(DARK_GREEN, GREEN, "command.mgive.received", cur.format(amount)); } @Command( @@ -117,8 +110,6 @@ double last = holdings.getBalance(); holdings.setBalance(amount); ctx.sendMessage(DARK_GREEN, GREEN, "command.mset.sended", ctx.get("player").asString(), cur.format(last), cur.format(amount)); - EntityPlayerMP maybeOnline = ctx.getServer().getConfigurationManager().getPlayerByUsername(ctx.get("player").asString()); - if(maybeOnline != null) - ctx.sendMessage(maybeOnline, DARK_GREEN, GREEN, "command.mset.received", cur.format(last), cur.format(amount)); + ctx.get("player").asOfflinePlayer().sendMessage(DARK_GREEN, GREEN, "command.mset.received", cur.format(last), cur.format(amount)); } } diff --git a/src/main/java/org/ultramine/server/data/ServerDataLoader.java b/src/main/java/org/ultramine/server/data/ServerDataLoader.java index 154d07d..4a1eecf 100644 --- a/src/main/java/org/ultramine/server/data/ServerDataLoader.java +++ b/src/main/java/org/ultramine/server/data/ServerDataLoader.java @@ -33,6 +33,7 @@ import net.minecraft.world.WorldServer; import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; +import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.event.ForgeEventFactory; public class ServerDataLoader @@ -414,6 +415,39 @@ return dataExtinfos; } + public void loadOffline(final GameProfile profile, final Function callback) + { + executor.execute(new Function() + { + @Override + public NBTTagCompound apply(Void input) //async + { + return getDataProvider().loadPlayer(profile); + } + }, new Function() + { + @Override + public Void apply(NBTTagCompound nbt) //sync + { + EntityPlayerMP player = mgr.getPlayerByUsername(profile.getName()); + if(player == null) + { + player = new FakePlayer(mgr.getServerInstance().getMultiWorld().getWorldByID(0), profile); + player.readFromNBT(nbt); + } + callback.apply(player); + return null; + } + }); + } + + public void saveOfflinePlayer(FakePlayer player) + { + NBTTagCompound nbt = new NBTTagCompound(); + player.writeToNBT(nbt); + getDataProvider().savePlayer(player.getGameProfile(), nbt); + } + private static class LoadedDataStruct { private final NBTTagCompound nbt; diff --git a/src/main/java/org/ultramine/server/util/BasicTypeFormatter.java b/src/main/java/org/ultramine/server/util/BasicTypeFormatter.java index c64e3d3..924680d 100644 --- a/src/main/java/org/ultramine/server/util/BasicTypeFormatter.java +++ b/src/main/java/org/ultramine/server/util/BasicTypeFormatter.java @@ -1,5 +1,11 @@ package org.ultramine.server.util; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; + public class BasicTypeFormatter { public static String formatTime(long timeMills) @@ -61,4 +67,18 @@ (minutes > 0 ? minutes + " " + minN + " " : "") + (printSec && (seconds != 0 || minutes == 0 && hours == 0 && days == 0) ? seconds + " " + secN : ""); } + + public static IChatComponent formatMessage(EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) + { + for(int i = 0; i < args.length; i++) + { + Object o = args[i]; + if(!(o instanceof IChatComponent)) + args[i] = new ChatComponentText(o.toString()).setChatStyle(new ChatStyle().setColor(argsColor)); + } + + ChatComponentTranslation comp = new ChatComponentTranslation(msg, args); + comp.getChatStyle().setColor(tplColor); + return comp; + } }