Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Sharables #363

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,27 @@
import com.onarandombox.multiverseinventories.profile.PlayerProfile;
import com.onarandombox.multiverseinventories.util.MinecraftTools;
import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.Keyed;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.NamespacedKey;
import org.bukkit.Statistic;
import org.bukkit.advancement.Advancement;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
Expand Down Expand Up @@ -582,6 +590,149 @@ public boolean updatePlayer(Player player, PlayerProfile profile) {
}).serializer(new ProfileEntry(false, "potions"), new PotionEffectSerializer())
.altName("potion").altName("potions").build();

/**
* Sharing Advancements.
*/
public static final Sharable<List> ADVANCEMENTS = new Sharable.Builder<List>("advancements", List.class,
nicegamer7 marked this conversation as resolved.
Show resolved Hide resolved
new SharableHandler<List>() {
@Override
public void updateProfile(PlayerProfile profile, Player player) {
Set<String> completedAdvancements = new HashSet<>();
nicegamer7 marked this conversation as resolved.
Show resolved Hide resolved
Iterator<Advancement> advancementIterator = inventories.getServer().advancementIterator();

while (advancementIterator.hasNext()) {
Advancement advancement = advancementIterator.next();
Collection<String> awardedCriteria = player.getAdvancementProgress(advancement).getAwardedCriteria();
completedAdvancements.addAll(awardedCriteria);
}

profile.set(ADVANCEMENTS, new ArrayList<>(completedAdvancements));
}

@Override
public boolean updatePlayer(Player player, PlayerProfile profile) {
List<String> advancements = profile.get(ADVANCEMENTS);
Set<String> processedAdvancements = new HashSet<>();
Set<String> completedAdvancements = (advancements != null) ? new HashSet<>(advancements) : new HashSet<>();
Iterator<Advancement> advancementIterator = inventories.getServer().advancementIterator();

boolean announceAdvancements = player.getWorld().getGameRuleValue(GameRule.ANNOUNCE_ADVANCEMENTS);
if (announceAdvancements) player.getWorld().setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, false);
while (advancementIterator.hasNext()) {
Advancement advancement = advancementIterator.next();
// the set of Advancements to revoke
Set<String> revoke = new HashSet<>(advancement.getCriteria());
// the set of Advancements to grant
Set<String> intersection = new HashSet<>(advancement.getCriteria());

revoke.removeAll(processedAdvancements);
revoke.removeAll(completedAdvancements);
intersection.removeAll(processedAdvancements);
intersection.retainAll(completedAdvancements);

for (String criteria: revoke) {
processedAdvancements.add(criteria);
completedAdvancements.remove(criteria);
player.getAdvancementProgress(advancement).revokeCriteria(criteria);
}
for (String criteria: intersection) {
processedAdvancements.add(criteria);
completedAdvancements.remove(criteria);
player.getAdvancementProgress(advancement).awardCriteria(criteria);
}

// here's the idea: revoke all (criteria \ completedAdvancements), grant (criteria intersect completedAdvancements)
// also, we don't need to grant/revoke anything in processedAdvancements since they've already been granted/revoked!
benwoo1110 marked this conversation as resolved.
Show resolved Hide resolved
}
if (announceAdvancements) player.getWorld().setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, true);
return advancements != null;
}
}).defaultSerializer(new ProfileEntry(false, "advancements")).altName("achievements").build();

/**
* Sharing Statistics.
*/
public static final Sharable<Map> GAME_STATISTICS = new Sharable.Builder<Map>("game_statistics", Map.class,
new SharableHandler<Map>() {
@Override
public void updateProfile(PlayerProfile profile, Player player) {
Map<String, Integer> playerStats = new HashMap<>();
for (Statistic stat: Statistic.values()) {
if (stat.getType() == Statistic.Type.UNTYPED) {
int val = player.getStatistic(stat);
// no need to save values of 0, that's the default!
if (val != 0) playerStats.put(stat.name(), val);
nicegamer7 marked this conversation as resolved.
Show resolved Hide resolved
}
}
profile.set(GAME_STATISTICS, playerStats);
}

@Override
public boolean updatePlayer(Player player, PlayerProfile profile) {
Map<String, Integer> playerStats = profile.get(GAME_STATISTICS);
for (Statistic stat : Statistic.values()) {
if (stat.getType() == Statistic.Type.UNTYPED) player.setStatistic(stat, 0);
}
if (playerStats == null) {
return false;
}
for (String stringStat : playerStats.keySet()) {
Statistic stat = Statistic.valueOf(stringStat);
if (stat.getType() == Statistic.Type.UNTYPED) player.setStatistic(stat, playerStats.get(stat.name()));
}
nicegamer7 marked this conversation as resolved.
Show resolved Hide resolved
return true;
}
}).defaultSerializer(new ProfileEntry(false, "game_statistics")).altName("game_stats").build();

/**
* Sharing Recipes.
*/
public static final Sharable<Map> RECIPES = new Sharable.Builder<Map>("recipes", Map.class,
benwoo1110 marked this conversation as resolved.
Show resolved Hide resolved
new SharableHandler<Map>() {
@Override
public void updateProfile(PlayerProfile profile, Player player) {
Set<NamespacedKey> recipes = new HashSet<>();
Iterator<Recipe> recipeIterator = inventories.getServer().recipeIterator();

while (recipeIterator.hasNext()) {
Recipe recipe = recipeIterator.next();
if (recipe instanceof Keyed) {
NamespacedKey key = ((Keyed) recipe).getKey();
if (player.undiscoverRecipe(key)) recipes.add(key);
}
}

player.discoverRecipes(recipes);

Map<String, List<String>> recipesMap = new HashMap<>();
for (NamespacedKey recipe: recipes) {
recipesMap.putIfAbsent(recipe.getNamespace(), new ArrayList<>());
recipesMap.get(recipe.getNamespace()).add(recipe.getKey());
}

profile.set(RECIPES, recipesMap);
}

@Override
public boolean updatePlayer(Player player, PlayerProfile profile) {
Map<String, List<String>> recipes = profile.get(RECIPES);
if (recipes == null) recipes = new HashMap<>();
Iterator<Recipe> recipeIterator = inventories.getServer().recipeIterator();

while (recipeIterator.hasNext()) {
Recipe recipe = recipeIterator.next();
if (recipe instanceof Keyed) {
NamespacedKey key = ((Keyed) recipe).getKey();
if (recipes.containsKey(key.getNamespace()) && recipes.get(key.getNamespace()).contains(key.getKey())) {
nicegamer7 marked this conversation as resolved.
Show resolved Hide resolved
player.discoverRecipe(key);
} else player.undiscoverRecipe(key);
}
}

return !recipes.isEmpty();
}
}).defaultSerializer(new ProfileEntry(false, "recipes")).build();

/**
* Grouping for inventory sharables.
*/
Expand Down Expand Up @@ -617,15 +768,16 @@ public boolean updatePlayer(Player player, PlayerProfile profile) {
*/
public static final SharableGroup STATS = new SharableGroup("stats",
fromSharables(HEALTH, FOOD_LEVEL, SATURATION, EXHAUSTION, EXPERIENCE, TOTAL_EXPERIENCE, LEVEL,
REMAINING_AIR, MAXIMUM_AIR, FALL_DISTANCE, FIRE_TICKS, POTIONS));
REMAINING_AIR, MAXIMUM_AIR, FALL_DISTANCE, FIRE_TICKS, POTIONS, GAME_STATISTICS));

/**
* Grouping for ALL default sharables.
* TODO: make this really mean all, including 3rd party.
*/
public static final SharableGroup ALL_DEFAULT = new SharableGroup("all", fromSharables(HEALTH, ECONOMY,
FOOD_LEVEL, SATURATION, EXHAUSTION, EXPERIENCE, TOTAL_EXPERIENCE, LEVEL, INVENTORY, ARMOR, BED_SPAWN,
MAXIMUM_AIR, REMAINING_AIR, FALL_DISTANCE, FIRE_TICKS, POTIONS, LAST_LOCATION, ENDER_CHEST, OFF_HAND),
MAXIMUM_AIR, REMAINING_AIR, FALL_DISTANCE, FIRE_TICKS, POTIONS, LAST_LOCATION, ENDER_CHEST, OFF_HAND,
ADVANCEMENTS, GAME_STATISTICS, RECIPES),
"*", "everything");


Expand Down