/*
* This file is part of NeptuneVanilla, licensed under the MIT License (MIT).
*
* Copyright (c) 2015-2017, Jamie Mansfield <https://github.com/jamierocks>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.neptunepowered.vanilla;
import com.google.common.collect.Lists;
import net.canarymod.Canary;
import net.canarymod.api.GameMode;
import net.canarymod.api.OfflinePlayer;
import net.canarymod.api.inventory.Inventory;
import net.canarymod.api.inventory.PlayerInventory;
import net.canarymod.api.nbt.CompoundTag;
import net.canarymod.api.statistics.Achievement;
import net.canarymod.api.statistics.Achievements;
import net.canarymod.api.statistics.Stat;
import net.canarymod.api.statistics.Statistics;
import net.canarymod.api.world.World;
import net.canarymod.api.world.position.Location;
import net.canarymod.api.world.position.Position;
import net.canarymod.permissionsystem.PermissionProvider;
import net.canarymod.user.Group;
import net.canarymod.user.UserAndGroupsProvider;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.stats.StatBase;
import net.minecraft.stats.StatisticsFile;
import net.minecraft.world.WorldSettings;
import org.neptunepowered.vanilla.util.NbtConstants;
import org.neptunepowered.vanilla.util.PermissionConstants;
import org.neptunepowered.vanilla.util.helper.StatisticsHelper;
import org.neptunepowered.vanilla.util.converter.GameModeConverter;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class NeptuneOfflinePlayer implements OfflinePlayer {
private final String name;
private final UUID id;
private final NBTTagCompound tag;
private final PermissionProvider permissions;
private final StatisticsFile statisticsFile;
private final InventoryPlayer inventory;
private List<Group> groups;
private String prefix;
private boolean isMuted;
public NeptuneOfflinePlayer(String name, UUID id, NBTTagCompound tag) {
this.name = name;
this.id = id;
this.tag = tag;
final UserAndGroupsProvider provider = Canary.usersAndGroups();
final String uuid = this.getUUIDString();
this.permissions = Canary.permissionManager().getPlayerProvider(this.name, this.getWorld().getFqName());
final String[] data = provider.getPlayerData(uuid);
final Group[] subs = provider.getModuleGroupsForPlayer(uuid);
this.groups = Lists.newLinkedList();
this.groups.add(Canary.usersAndGroups().getGroup(data[1]));
for (Group group : subs) {
if (group != null) {
this.groups.add(group);
}
}
this.prefix = data[0];
this.isMuted = Boolean.parseBoolean(data[2]);
this.statisticsFile = StatisticsHelper.getStatisticsFile(id, name);
this.inventory = new InventoryPlayer(null);
this.inventory.readFromNBT(this.tag.getTagList(NbtConstants.INVENTORY, NbtConstants.TAG_COMPOUND));
}
@Override
public CompoundTag getNBT() {
return (CompoundTag) this.tag;
}
public NBTTagCompound getMetadata() {
return this.tag.hasKey(NbtConstants.CANARY_TAG) ? this.tag.getCompoundTag(NbtConstants.CANARY_TAG) : null;
}
@Override
public void save() {
if (this.isOnline()) {
Canary.log.warn("Attempted to save an online player! (" + this.name + ")");
return;
}
this.tag.setTag(NbtConstants.INVENTORY, this.inventory.writeToNBT(new NBTTagList()));
// TODO: Save NBT
}
@Override
public PermissionProvider getPermissionProvider() {
return this.permissions;
}
@Override
public Group getGroup() {
return this.groups.get(0);
}
@Override
public String getPrefix() {
return this.prefix;
}
@Override
public boolean isOnline() {
return Canary.getServer().getPlayer(this.name) != null;
}
@Override
public boolean hasPermission(String path) {
return this.permissions.queryPermission(path);
}
@Override
public void setGroup(Group group) {
this.groups.set(0, group);
Canary.usersAndGroups().addOrUpdateOfflinePlayer(this);
}
@Override
public void addGroup(Group group) {
if (!this.groups.contains(group)) {
this.groups.add(group);
Canary.usersAndGroups().addOrUpdateOfflinePlayer(this);
}
}
@Override
public boolean removeGroup(Group group) {
return false;
}
@Override
public boolean removeGroup(String s) {
return false;
}
@Override
public boolean isInGroup(Group group, boolean b) {
return false;
}
@Override
public boolean isInGroup(String s, boolean b) {
return false;
}
@Override
public void setPrefix(String prefix) {
this.prefix = prefix;
Canary.usersAndGroups().addOrUpdateOfflinePlayer(this);
}
@Override
public World getWorld() {
return null;
}
@Override
public Position getPosition() {
return null;
}
@Override
public String getName() {
return this.name;
}
@Override
public UUID getUUID() {
return this.id;
}
@Override
public String getUUIDString() {
return this.id.toString();
}
@Override
public boolean isMuted() {
return this.isMuted;
}
@Override
public void setMuted(boolean muted) {
this.isMuted = muted;
Canary.usersAndGroups().addOrUpdateOfflinePlayer(this);
}
@Override
public Group[] getPlayerGroups() {
return this.groups.toArray(new Group[this.groups.size()]);
}
@Override
public String getFirstJoined() {
if (this.getMetadata() != null && this.getMetadata().hasKey(NbtConstants.FIRST_JOINED)) {
return this.getMetadata().getString(NbtConstants.FIRST_JOINED);
}
return "NEVER";
}
@Override
public long getTimePlayed() {
if (this.getMetadata() != null && this.getMetadata().hasKey(NbtConstants.TIME_PLAYED)) {
return this.getMetadata().getLong(NbtConstants.TIME_PLAYED);
}
return 0;
}
@Override
public GameMode getMode() {
return GameModeConverter.of(WorldSettings.GameType.getByID(this.getModeId()));
}
@Override
public int getModeId() {
if (this.getNBT() != null && this.getNBT().containsKey(NbtConstants.GAME_TYPE)) {
return this.getNBT().getInt(NbtConstants.GAME_TYPE);
}
return 0;
}
@Override
public void setMode(GameMode gameMode) {
this.setModeId(GameModeConverter.of(gameMode).getID());
}
@Override
public void setModeId(int mode) {
if (this.getNBT() != null) {
this.getNBT().put(NbtConstants.GAME_TYPE, mode);
this.save();
}
}
@Override
public boolean isOperator() {
return Canary.ops().isOpped(this);
}
@Override
public boolean isAdmin() {
return this.isOperator() || this.hasPermission(PermissionConstants.Super.ADMINISTRATOR);
}
@Override
public boolean canBuild() {
return this.isAdmin() || this.hasPermission(PermissionConstants.World.BUILD);
}
@Override
public void setCanBuild(boolean canModify) {
this.permissions.addPermission(PermissionConstants.World.BUILD, canModify);
}
@Override
public boolean canIgnoreRestrictions() {
return this.isAdmin() || this.hasPermission(PermissionConstants.Super.IGNORE_RESTRICTIONS);
}
@Override
public void setCanIgnoreRestrictions(boolean canIgnore) {
this.permissions.addPermission(PermissionConstants.Super.IGNORE_RESTRICTIONS, canIgnore, -1);
}
@Override
public void addExhaustion(float v) {
}
@Override
public void setExhaustion(float v) {
}
@Override
public float getExhaustionLevel() {
return 0;
}
@Override
public void addSaturation(float v) {
}
@Override
public void setSaturation(float v) {
}
@Override
public float getSaturationLevel() {
return 0;
}
@Override
public void setHunger(int i) {
}
@Override
public int getHunger() {
return 0;
}
@Override
public void addExperience(int i) {
}
@Override
public void removeExperience(int i) {
}
@Override
public int getExperience() {
return 0;
}
@Override
public void setExperience(int i) {
}
@Override
public int getLevel() {
return 0;
}
@Override
public void setLevel(int i) {
}
@Override
public void addLevel(int i) {
}
@Override
public void removeLevel(int i) {
}
@Override
public void setHome(Location location) {
}
@Override
public Location getHome() {
return null;
}
@Override
public boolean hasHome() {
return false;
}
@Override
public String[] getAllowedIPs() {
return new String[0];
}
@Override
public String getIP() {
if (this.getMetadata() != null && this.getMetadata().hasKey(NbtConstants.PREVIOUS_IP)) {
return this.getMetadata().getString(NbtConstants.PREVIOUS_IP);
}
return "UNKNOWN";
}
@Override
public String getLastJoined() {
if (this.getMetadata() != null && this.getMetadata().hasKey(NbtConstants.LAST_JOINED)) {
return this.getMetadata().getString(NbtConstants.LAST_JOINED);
}
return "NEVER";
}
@Override
public float getHealth() {
return 0;
}
@Override
public void setHealth(float v) {
}
@Override
public void increaseHealth(float v) {
}
@Override
public void setStat(Stat stat, int value) {
this.statisticsFile.unlockAchievement(null, (StatBase) stat, value);
}
@Override
public void setStat(Statistics statistics, int value) {
this.setStat(statistics.getInstance(), value);
}
@Override
public void increaseStat(Stat stat, int value) {
if (value < 0) return;
this.statisticsFile.increaseStat(null, (StatBase) stat, value);
}
@Override
public void increaseStat(Statistics statistics, int value) {
this.increaseStat(statistics.getInstance(), value);
}
@Override
public void decreaseStat(Stat stat, int value) {
if (value < 0) return;
this.setStat(stat, this.getStat(stat) - value);
}
@Override
public void decreaseStat(Statistics statistics, int value) {
this.decreaseStat(statistics.getInstance(), value);
}
@Override
public int getStat(Stat stat) {
return this.statisticsFile.readStat((StatBase) stat);
}
@Override
public int getStat(Statistics statistics) {
return this.getStat(statistics.getInstance());
}
@Override
public boolean hasAchievement(Achievement achievement) {
return this.statisticsFile.hasAchievementUnlocked((net.minecraft.stats.Achievement) achievement);
}
@Override
public boolean hasAchievement(Achievements achievements) {
return this.hasAchievement(achievements.getInstance());
}
@Override
public void removeAchievement(Achievement achievement) {
// Ensure all children achievements are removed
Arrays.stream(Achievements.values())
.map(Achievements::getInstance).map(Achievement::getParent)
.filter(achievement::equals).filter(this::hasAchievement)
.forEach(this::removeAchievement);
this.statisticsFile.unlockAchievement(null, (StatBase) achievement, 0);
}
@Override
public void removeAchievement(Achievements achievements) {
this.removeAchievement(achievements.getInstance());
}
@Override
public void awardAchievement(Achievement achievement) {
// Ensure all parent achievements are awarded
if (!this.hasAchievement(achievement.getParent())) {
this.awardAchievement(achievement.getParent());
}
this.statisticsFile.unlockAchievement(null, (StatBase) achievement, 1);
}
@Override
public void awardAchievement(Achievements achievements) {
this.awardAchievement(achievements.getInstance());
}
@Override
public PlayerInventory getInventory() {
return (PlayerInventory) this.inventory;
}
@Override
public Inventory getEnderChestInventory() {
return null;
}
}