mirror of
https://github.com/BentoBoxWorld/Challenges.git
synced 2024-11-26 04:25:13 +01:00
Add ability to migrate challenges from 0.5.0 - 0.7.5 data storage mode to new 0.8.0 format.
Part of implementing #105
This commit is contained in:
parent
3985efa4d0
commit
76fb30be36
@ -23,6 +23,7 @@ import world.bentobox.challenges.events.ChallengeResetAllEvent;
|
||||
import world.bentobox.challenges.events.ChallengeResetEvent;
|
||||
import world.bentobox.challenges.events.LevelCompletedEvent;
|
||||
import world.bentobox.challenges.utils.LevelStatus;
|
||||
import world.bentobox.challenges.utils.Utils;
|
||||
|
||||
|
||||
/**
|
||||
@ -148,6 +149,7 @@ public class ChallengesManager
|
||||
|
||||
this.challengeDatabase.loadObjects().forEach(this::loadChallenge);
|
||||
this.levelDatabase.loadObjects().forEach(this::loadLevel);
|
||||
|
||||
// It is not necessary to load all players in memory.
|
||||
// this.playersDatabase.loadObjects().forEach(this::loadPlayerData);
|
||||
}
|
||||
@ -494,6 +496,180 @@ public class ChallengesManager
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Wipe data
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This method migrated all challenges addon data from worldName to addonID formant.
|
||||
*/
|
||||
public void migrateDatabase(User user, World world)
|
||||
{
|
||||
world = Util.getWorld(world);
|
||||
|
||||
if (user.isPlayer())
|
||||
{
|
||||
user.sendMessage("challenges.messages.admin.migrate-start");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.addon.log("Starting migration to new data format.");
|
||||
}
|
||||
|
||||
boolean challenges = this.migrateChallenges(world);
|
||||
boolean levels = this.migrateLevels(world);
|
||||
|
||||
if (challenges || levels)
|
||||
{
|
||||
this.migratePlayers(world);
|
||||
|
||||
if (user.isPlayer())
|
||||
{
|
||||
user.sendMessage("challenges.messages.admin.migrate-end");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.addon.log("Migration to new data format completed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (user.isPlayer())
|
||||
{
|
||||
user.sendMessage("challenges.messages.admin.migrate-not");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.addon.log("All data is valid. Migration is not necessary.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method collects all data from levels database and migrates them.
|
||||
*/
|
||||
private boolean migrateLevels(World world)
|
||||
{
|
||||
String addonName = Utils.getGameMode(world);
|
||||
|
||||
if (addonName == null || addonName.equalsIgnoreCase(world.getName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean updated = false;
|
||||
List<ChallengeLevel> levelList = this.levelDatabase.loadObjects();
|
||||
for (ChallengeLevel level : levelList)
|
||||
{
|
||||
if (level.getUniqueId().regionMatches(true, 0, world.getName() + "_", 0, world.getName().length() + 1))
|
||||
{
|
||||
this.levelDatabase.deleteID(level.getUniqueId());
|
||||
this.levelCacheData.remove(level.getUniqueId());
|
||||
|
||||
level.setUniqueId(
|
||||
addonName + level.getUniqueId().substring(world.getName().length()));
|
||||
|
||||
Set<String> challengesID = new HashSet<>(level.getChallenges());
|
||||
level.getChallenges().clear();
|
||||
|
||||
challengesID.forEach(challenge ->
|
||||
level.getChallenges().add(addonName + challenge.substring(world.getName().length())));
|
||||
|
||||
this.levelDatabase.saveObject(level);
|
||||
this.levelCacheData.put(level.getUniqueId(), level);
|
||||
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method collects all data from challenges database and migrates them.
|
||||
*/
|
||||
private boolean migrateChallenges(World world)
|
||||
{
|
||||
String addonName = Utils.getGameMode(world);
|
||||
|
||||
if (addonName == null || addonName.equalsIgnoreCase(world.getName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean updated = false;
|
||||
|
||||
List<Challenge> challengeList = this.challengeDatabase.loadObjects();
|
||||
|
||||
for (Challenge challenge : challengeList)
|
||||
{
|
||||
if (challenge.getUniqueId().regionMatches(true, 0, world.getName() + "_", 0, world.getName().length() + 1))
|
||||
{
|
||||
this.challengeDatabase.deleteID(challenge.getUniqueId());
|
||||
this.challengeCacheData.remove(challenge.getUniqueId());
|
||||
|
||||
challenge.setUniqueId(addonName + challenge.getUniqueId().substring(world.getName().length()));
|
||||
updated = true;
|
||||
|
||||
this.challengeDatabase.saveObject(challenge);
|
||||
this.challengeCacheData.put(challenge.getUniqueId(), challenge);
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method collects all data from players database and migrates them.
|
||||
*/
|
||||
private void migratePlayers(World world)
|
||||
{
|
||||
String addonName = Utils.getGameMode(world);
|
||||
|
||||
if (addonName == null || addonName.equalsIgnoreCase(world.getName()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<ChallengesPlayerData> playerDataList = this.playersDatabase.loadObjects();
|
||||
|
||||
playerDataList.forEach(playerData -> {
|
||||
Set<String> levelsDone = new TreeSet<>(playerData.getLevelsDone());
|
||||
levelsDone.forEach(level -> {
|
||||
if (level.regionMatches(true, 0, world.getName() + "_", 0, world.getName().length() + 1))
|
||||
{
|
||||
playerData.getLevelsDone().remove(level);
|
||||
playerData.getLevelsDone().add(addonName + level.substring(world.getName().length()));
|
||||
}
|
||||
});
|
||||
|
||||
Map<String, Integer> challengeStatus = new TreeMap<>(playerData.getChallengeStatus());
|
||||
challengeStatus.forEach((challenge, count) -> {
|
||||
if (challenge.regionMatches(true, 0, world.getName() + "_", 0, world.getName().length() + 1))
|
||||
{
|
||||
playerData.getChallengeStatus().remove(challenge);
|
||||
playerData.getChallengeStatus().put(addonName + challenge.substring(world.getName().length()), count);
|
||||
}
|
||||
});
|
||||
|
||||
Map<String, Long> challengeTimestamp = new TreeMap<>(playerData.getChallengesTimestamp());
|
||||
challengeTimestamp.forEach((challenge, timestamp) -> {
|
||||
if (challenge.regionMatches(true, 0, world.getName() + "_", 0, world.getName().length() + 1))
|
||||
{
|
||||
playerData.getChallengesTimestamp().remove(challenge);
|
||||
playerData.getChallengesTimestamp().put(addonName + challenge.substring(world.getName().length()), timestamp);
|
||||
}
|
||||
});
|
||||
|
||||
this.playersDatabase.saveObject(playerData);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Saving methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
@ -43,6 +43,10 @@ public class Challenges extends CompositeCommand
|
||||
|
||||
// Reset challenge command
|
||||
new ResetCommand(this.getAddon(), this);
|
||||
|
||||
new ShowChallenges(this.getAddon(), this);
|
||||
|
||||
new MigrateCommand(this.getAddon(), this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package world.bentobox.challenges.commands.admin;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.challenges.ChallengesAddon;
|
||||
|
||||
|
||||
public class MigrateCommand extends CompositeCommand {
|
||||
|
||||
/**
|
||||
* Migrates challenges
|
||||
* @param addon
|
||||
* @param cmd
|
||||
*/
|
||||
public MigrateCommand(Addon addon, CompositeCommand cmd) {
|
||||
super(addon, cmd, "migrate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
((ChallengesAddon)getAddon()).getChallengesManager().migrateDatabase(user, getWorld());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
this.setPermission("challenges.admin");
|
||||
this.setParametersHelp("challenges.commands.admin.migrate.parameters");
|
||||
this.setDescription("challenges.commands.admin.migrate.description");
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package world.bentobox.challenges.commands.admin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import world.bentobox.challenges.ChallengesAddon;
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
@ -28,8 +29,19 @@ public class ShowChallenges extends CompositeCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
((ChallengesAddon)getAddon()).getChallengesManager().getAllChallengesNames(this.getWorld()).forEach(user::sendRawMessage);
|
||||
if (user.isPlayer())
|
||||
{
|
||||
((ChallengesAddon) getAddon()).getChallengesManager().
|
||||
getAllChallengesNames(this.getWorld()).forEach(user::sendRawMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
((ChallengesAddon) getAddon()).getChallengesManager().
|
||||
getAllChallengesNames(this.getWorld()).forEach(c -> this.getAddon().log(c));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,6 +36,9 @@ challenges:
|
||||
reset:
|
||||
description: 'This command allows to reset challenge for player without GUI. If "challenge_id" is set to "all", then it will reset all challenges.'
|
||||
parameters: '<player> <challenge_id>'
|
||||
migrate:
|
||||
description: 'This method allows to migrate challenges data that refers to current game mode world to new 0.8.0 storage format.'
|
||||
parameters: ''
|
||||
user:
|
||||
main:
|
||||
description: 'This method opens Challenges GUI.'
|
||||
@ -341,6 +344,10 @@ challenges:
|
||||
reset: '&2You reset challenge [name] for [player]!'
|
||||
reset-all: '&2All [player] challenges were reset!'
|
||||
not-completed: '&2This challenge is not completed yet!'
|
||||
|
||||
migrate-start: '&2Start migrating challenges addon data.'
|
||||
migrate-end: '&2Challenges addon data is updated to new format.'
|
||||
migrate-not: '&2All data is valid.'
|
||||
you-completed-challenge: '&2You completed the [value] &r&2challenge!'
|
||||
you-repeated-challenge: '&2You repeated the [value] &r&2challenge!'
|
||||
you-repeated-challenge-multiple: '&2You repeated the [value] &r&2challenge [count] times!'
|
||||
|
Loading…
Reference in New Issue
Block a user