From 68ea4dd6c18da8ab52b6d52a3a88dd66eb334147 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 28 Jun 2016 01:38:29 -0400 Subject: [PATCH] v0.4.1: massively improved the efficiency of rankings storage --- AndroidManifest.xml | 2 +- .../shatteredpixeldungeon/Rankings.java | 109 ++++++++++++++---- .../items/ItemStatusHandler.java | 36 +++++- .../items/potions/Potion.java | 4 + .../items/rings/Ring.java | 6 +- .../items/scrolls/Scroll.java | 6 +- .../scenes/RankingsScene.java | 4 +- .../scenes/WelcomeScene.java | 23 ++++ .../windows/WndRanking.java | 9 +- 9 files changed, 161 insertions(+), 38 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c52fda64c..86118cf19 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,7 +1,7 @@ diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/Rankings.java b/src/com/shatteredpixel/shatteredpixeldungeon/Rankings.java index 3726908da..d675d3cbe 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/Rankings.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/Rankings.java @@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Goo; @@ -33,6 +34,10 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.King; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Tengu; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog; import com.shatteredpixel.shatteredpixeldungeon.items.Amulet; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion; +import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll; import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; import com.shatteredpixel.shatteredpixeldungeon.messages.Languages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; @@ -56,7 +61,6 @@ public enum Rankings { public static final int TABLE_SIZE = 11; public static final String RANKINGS_FILE = "rankings.dat"; - public static final String DETAILS_FILE = "game_%d.dat"; public ArrayList records; public int lastRecord; @@ -77,13 +81,9 @@ public enum Rankings { rec.depth = Dungeon.depth; rec.score = score( win ); - String gameFile = Messages.format( DETAILS_FILE, SystemTime.now ); - try { - Dungeon.saveGame( gameFile ); - rec.gameFile = gameFile; - } catch (IOException e) { - rec.gameFile = ""; - } + INSTANCE.saveGameData(rec); + + rec.gameID = String.valueOf(SystemTime.now); records.add( rec ); @@ -92,17 +92,12 @@ public enum Rankings { lastRecord = records.indexOf( rec ); int size = records.size(); while (size > TABLE_SIZE) { - - Record removedGame; + if (lastRecord == size - 1) { - removedGame = records.remove( size - 2 ); + records.remove( size - 2 ); lastRecord--; } else { - removedGame = records.remove( size - 1 ); - } - - if (removedGame.gameFile.length() > 0) { - Game.instance.deleteFile( removedGame.gameFile ); + records.remove( size - 1 ); } size = records.size(); @@ -121,7 +116,63 @@ public enum Rankings { private int score( boolean win ) { return (Statistics.goldCollected + Dungeon.hero.lvl * (win ? 26 : Dungeon.depth ) * 100) * (win ? 2 : 1); } - + + public static final String HERO = "hero"; + public static final String STATS = "stats"; + public static final String BADGES = "badges"; + public static final String HANDLERS = "handlers"; + + public void saveGameData(Record rec){ + rec.gameData = new Bundle(); + + //save the hero and belongings + ArrayList allItems = (ArrayList) Dungeon.hero.belongings.backpack.items.clone(); + //remove items that won't show up in the rankings screen + for (Item item : Dungeon.hero.belongings.backpack.items.toArray( new Item[0])) { + if (!Dungeon.quickslot.contains(item)) Dungeon.hero.belongings.backpack.items.remove(item); + } + rec.gameData.put( HERO, Dungeon.hero ); + + //save stats + Bundle stats = new Bundle(); + Statistics.storeInBundle(stats); + rec.gameData.put( STATS, stats); + + //save badges + Bundle badges = new Bundle(); + Badges.saveLocal(badges); + rec.gameData.put( BADGES, badges); + + //save handler information + Bundle handler = new Bundle(); + Scroll.saveSelectively(handler, Dungeon.hero.belongings.backpack.items); + Potion.saveSelectively(handler, Dungeon.hero.belongings.backpack.items); + Ring.saveSelectively(handler, Dungeon.hero.belongings.backpack.items); + rec.gameData.put( HANDLERS, handler); + + //restore items now that we're done saving + Dungeon.hero.belongings.backpack.items = allItems; + } + + public void loadGameData(Record rec){ + Bundle data = rec.gameData; + + Dungeon.hero = null; + Dungeon.quickslot.reset(); + + Bundle handler = data.getBundle(HANDLERS); + Scroll.restore(handler); + Potion.restore(handler); + Ring.restore(handler); + + Badges.loadLocal(data.getBundle(BADGES)); + + Dungeon.hero = (Hero)data.get(HERO); + + Statistics.restoreFromBundle(data.getBundle(STATS)); + + } + private static final String RECORDS = "records"; private static final String LATEST = "latest"; private static final String TOTAL = "total"; @@ -148,7 +199,7 @@ public enum Rankings { return; } - records = new ArrayList(); + records = new ArrayList<>(); try { InputStream input = Game.instance.openFileInput( RANKINGS_FILE ); @@ -185,13 +236,18 @@ public enum Rankings { public String info; private static final String REASON = "reason"; + //pre 0.4.1 + public String gameFile; + private static final String FILE = "gameFile"; + private static final String CAUSE = "cause"; private static final String WIN = "win"; private static final String SCORE = "score"; private static final String TIER = "tier"; private static final String LEVEL = "level"; private static final String DEPTH = "depth"; - private static final String GAME = "gameFile"; + private static final String DATA = "gameData"; + private static final String ID = "gameID"; public Class cause; public boolean win; @@ -201,9 +257,10 @@ public enum Rankings { public int herolevel; public int depth; + public Bundle gameData; + public String gameID; + public int score; - - public String gameFile; public String desc(){ if (cause == null) { @@ -260,7 +317,12 @@ public enum Rankings { heroClass = HeroClass.restoreInBundle( bundle ); armorTier = bundle.getInt( TIER ); - gameFile = bundle.getString( GAME ); + if (bundle.contains(FILE)) { + gameFile = bundle.getString(FILE); + } else { + gameData = bundle.getBundle(DATA); + gameID = bundle.getString(ID); + } depth = bundle.getInt( DEPTH ); herolevel = bundle.getInt( LEVEL ); @@ -281,7 +343,8 @@ public enum Rankings { bundle.put( LEVEL, herolevel ); bundle.put( DEPTH, depth ); - bundle.put( GAME, gameFile ); + bundle.put( DATA, gameData ); + bundle.put( ID, gameID); } } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/ItemStatusHandler.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/ItemStatusHandler.java index f6aff37f0..f89cba6c8 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/ItemStatusHandler.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/ItemStatusHandler.java @@ -24,8 +24,10 @@ import com.watabou.utils.Bundle; import com.watabou.utils.Random; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.List; public class ItemStatusHandler { @@ -80,8 +82,22 @@ public class ItemStatusHandler { } } + public void saveSelectively( Bundle bundle, ArrayList itemsToSave ){ + List> items = Arrays.asList(this.items); + for (Item item : itemsToSave){ + if (items.contains(item.getClass())){ + Class cls = items.get(items.indexOf(item.getClass())); + String itemName = cls.toString(); + bundle.put( itemName + PFX_LABEL, itemLabels.get( cls ) ); + bundle.put( itemName + PFX_KNOWN, known.contains( cls ) ); + } + } + } + private void restore( Bundle bundle, ArrayList labelsLeft ) { + ArrayList> unlabelled = new ArrayList<>(); + for (int i=0; i < items.length; i++) { Class item = items[i]; @@ -99,14 +115,22 @@ public class ItemStatusHandler { } else { - int index = Random.Int( labelsLeft.size() ); + unlabelled.add(items[i]); - itemLabels.put( item, labelsLeft.get( index ) ); - labelsLeft.remove( index ); + } + } - if (bundle.contains( itemName + PFX_KNOWN ) && bundle.getBoolean( itemName + PFX_KNOWN )) { - known.add( item ); - } + for (Class item : unlabelled){ + + String itemName = item.toString(); + + int index = Random.Int( labelsLeft.size() ); + + itemLabels.put( item, labelsLeft.get( index ) ); + labelsLeft.remove( index ); + + if (bundle.contains( itemName + PFX_KNOWN ) && bundle.getBoolean( itemName + PFX_KNOWN )) { + known.add( item ); } } } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java index c099a18a3..83639dae4 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java @@ -106,6 +106,10 @@ public class Potion extends Item { public static void save( Bundle bundle ) { handler.save( bundle ); } + + public static void saveSelectively( Bundle bundle, ArrayList items ) { + handler.saveSelectively( bundle, items ); + } @SuppressWarnings("unchecked") public static void restore( Bundle bundle ) { diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/rings/Ring.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/rings/Ring.java index 365b781f6..22a9ad0f6 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/rings/Ring.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/rings/Ring.java @@ -26,7 +26,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; -import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.ItemStatusHandler; import com.shatteredpixel.shatteredpixeldungeon.items.KindofMisc; @@ -36,6 +35,7 @@ import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.utils.Bundle; import com.watabou.utils.Random; +import java.util.ArrayList; import java.util.HashMap; public class Ring extends KindofMisc { @@ -89,6 +89,10 @@ public class Ring extends KindofMisc { public static void save( Bundle bundle ) { handler.save( bundle ); } + + public static void saveSelectively( Bundle bundle, ArrayList items ) { + handler.saveSelectively( bundle, items ); + } @SuppressWarnings("unchecked") public static void restore( Bundle bundle ) { diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/Scroll.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/Scroll.java index cb19e625f..b4d7f5199 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/Scroll.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/Scroll.java @@ -95,7 +95,11 @@ public abstract class Scroll extends Item { public static void save( Bundle bundle ) { handler.save( bundle ); } - + + public static void saveSelectively( Bundle bundle, ArrayList items ) { + handler.saveSelectively( bundle, items ); + } + @SuppressWarnings("unchecked") public static void restore( Bundle bundle ) { handler = new ItemStatusHandler<>( (Class[])scrolls, runes, bundle ); diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/scenes/RankingsScene.java b/src/com/shatteredpixel/shatteredpixeldungeon/scenes/RankingsScene.java index 9b3e3c57b..3bbc14dd0 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/scenes/RankingsScene.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/scenes/RankingsScene.java @@ -294,8 +294,8 @@ public class RankingsScene extends PixelScene { @Override protected void onClick() { - if (rec.gameFile.length() > 0) { - parent.add( new WndRanking( rec.gameFile ) ); + if (rec.gameData != null) { + parent.add( new WndRanking( rec ) ); } else { parent.add( new WndError( Messages.get(RankingsScene.class, "no_info") ) ); } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java b/src/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java index 86d83cf53..aac40da96 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/scenes/WelcomeScene.java @@ -22,6 +22,8 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes; import android.opengl.GLES20; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.Rankings; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites; import com.shatteredpixel.shatteredpixeldungeon.effects.Fireball; @@ -144,6 +146,27 @@ public class WelcomeScene extends PixelScene { } private void updateVersion(int previousVersion){ + //rankings conversion + if (previousVersion < 108){ + Rankings.INSTANCE.load(); + for (Rankings.Record rec : Rankings.INSTANCE.records){ + try{ + Dungeon.loadGame(rec.gameFile, false); + rec.gameID = rec.gameFile.replaceAll("\\D", ""); + + Rankings.INSTANCE.saveGameData(rec); + } catch (Exception e){ + rec.gameID = rec.gameFile.replaceAll("\\D", ""); + rec.gameData = null; + } + + String file = rec.gameFile; + rec.gameFile = ""; + Game.instance.deleteFile(file); + } + Rankings.INSTANCE.save(); + } + ShatteredPixelDungeon.version(ShatteredPixelDungeon.versionCode); } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java b/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java index cdd4890ef..c18637432 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.windows; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.Rankings; import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings; import com.shatteredpixel.shatteredpixeldungeon.items.Item; @@ -54,8 +55,8 @@ public class WndRanking extends WndTabbed { private String error = null; private Image busy; - - public WndRanking( final String gameFile ) { + + public WndRanking( final Rankings.Record rec ) { super(); resize( WIDTH, HEIGHT ); @@ -65,8 +66,8 @@ public class WndRanking extends WndTabbed { public void run() { try { Badges.loadGlobal(); - Dungeon.loadGame( gameFile ); - } catch (Exception e ) { + Rankings.INSTANCE.loadGameData( rec ); + } catch ( Exception e ) { error = Messages.get(WndRanking.class, "error"); } }