First, let me give thanks for this:
GirlPlaysGame.
Read the site before continuing here. You'll get an idea of what is possible.
At least it got me started. And no, still no JailBreak is needed to do this.
Tap Paradise Cove is an enjoyable game, but it is WAY too greedy!! I mean, you need to spend at least €100 a month to be able to play comfortably... In my opinion: way too much. Plus you can't achieve everything with a lot of patience... Also a bad no no. Ok, make it difficult, but not impossible you know.
Lucky for us most of the information is stored on the iPad (well, their systems would overload I think if everyone logging on needed to download/upload a 1 mega database all the time :)).
Necessary utils:
iFunBox, some kind SQLite database utility, PHP or something alike.
This is not a step-by-step guide. Just a brain dump of what I found out and what is working with the most current version as of January 2014.
What did I discover?
- A lot of interesting files are present in \Library\Application Support\resources
- If you want to add something, watch out for the metadata table. See that the Z_PK value of the table you changed (this will likely be zgameobject) match the Z_PRIMARYKEY table. This should contain the maximum value.
- in most tables you'll have a ZWORLD parameter. 0 = main world, 1 = atlantis, 2 = asgard. Watch out. Sometimes it's something like "0;1;2" or with a comma. Just watch out by using an update there.
- Always create a backup of your survivor.sqlite file before you start messing things up! (I generally do copy/paste in the same dir & remove them after a while).
- Pirates can be reset (when defeated) by setting ZCURRENTHEALTHPERCENTAGE=1.0, ZTIMEOFLASTDAMAGE=0. If you want to go fast in a quest to defeat someone till level xxx. Just set the ZCURRENTLEVEL to 1 level lower (for example if the quest is to defeat him at level 5, set it at 4, defeat him & you've completed the quest). [Check Fleets.csv for the ZFLEETIDENTIFIER/ZPIRATEIDENTIFIER]
update ZPIRATE
set ZCURRENTHEALTHPERCENTAGE=1.0, ZTIMEOFLASTDAMAGE=0
WHERE ZCURRENTHEALTHPERCENTAGE != 1.0 and zfleetidentifier=299;
- There are some special ruby decorations. Well, if you don't want to pay for them (199 rubies)... Why you don't just make them (well, you don't need them anyhow as I will show you later on)?
Find a good x/y coordinates on the map and place them (my personal favorite is 'sugarplum', it's small and nets 4 rubies in 4 days). [Check Decorations.csv for others, check for 'rubies' - keep in mind the size!]
To fasten ruby generation:
update zgameobject
set ZTIMEATWHICHOBJECTWILLBECOMEHARVESTABLENUM=strftime('%s', 'now')
where z_ent=21 and zcanpayoutnum=1;
- You feel powerless? Like can't beat any pirate? Why don't you just upgrade your ships? Or downgrade them for whatever reason necessary? zupgradecount1 45 means fully upgraded for a ship. For a shop that is zupgradecount (mind the missing 1) 25.
update zgameobject
set zupgradecount1=45
where z_ent=27;
- You've been beaten by a pirate, and just want to repair all your ships? No stress :-)
update zgameobject
set ZREPAIRENDTIMENUM=0, ZISCURRENTLYREPAIREDATDOCKNUM=0,ZCURRENTHEALTHPERCENTAGE=1.0
where z_ent=27;
- Expanding land? Tired of waiting 4 hours, and don't want to waste any rubies?
update ZBUILDABLEAREA
set ZEXPANSIONCOMPLETETIMESTAMP=strftime('%s', 'now')
where ZEXPANSIONSTATE=2;
- Or you just want to expand all the available land at once? Remember, you still got to chop trees/seaweed!
ZEXPANSIONSTATE = 2 means you still got to click yourself to 'finish' the expansion. This is sometimes needed as a trigger for quests. ZEXPANSIONSTATE = 3 means expanded, and 1 means dark/in need of expansion.
$s = new SQLite3('survivor.sqlite');
# 0 = main
# 1 = Atlantis
# 2 = Asgard
$zworld = '2';
$last_expansion = min(time(), $s->querySingle("select max(ZEXPANSIONCOMPLETETIMESTAMP) from ZBUILDABLEAREA where zworld=$zworld"));
if ( $last_expansion <= 0 ) {
$last_expansion = time();
}
$last_number = $s->querySingle("select max(ZEXPANSIONPURCHASENUMBER) from ZBUILDABLEAREA where zworld=$zworld");
$s->query('begin transaction');
while ( true ) {
$z_pk = $s->querySingle("SELECT z_pk FROM ZBUILDABLEAREA where zworld=$zworld and ZEXPANSIONCOMPLETETIMESTAMP=0 AND ZEXPANSIONSTATE=1");
if ( !$z_pk ) {
break;
}
echo $z_pk . "\n";
$last_expansion++;
$last_number++;
$s->query("UPDATE ZBUILDABLEAREA set ZEXPANSIONCOMPLETETIMESTAMP=$last_expansion, ZEXPANSIONPURCHASENUMBER=$last_number, ZEXPANSIONSTATE=2 Where z_pk=$z_pk");
}
$s->query('commit');
- Tired of waiting to build your buildings, and don't want to spend rubies? Well... Why not...Watch out here, because the atlantis merchants and the asgard one are a little special. Hence the additional restrictions (or you won't be able to finish that quest).
update zgameobject
set ZCURRENTHEALTHPERCENTAGE=1.0, ZTIMEATWHICHOBJECTWILLFINISHCONSTRUCTIONNUM=strftime('%s', 'now'), zupgradecount=25
where zstatenum=2 and (ZCURRENTHEALTHPERCENTAGE is null or ziscraftingnum=1);
- Want to send ALL your ships on a long voyage to get back a lot of stuff? And without spending coins to do that? This query just enables the voyage, it doesn't finish it necessarily. The additional restrictions is because sometimes you need to go on short/medium voyages, so these will not get erased by the query. Read more below how to finish the voyages immediately.
update zgameobject
set zonvoyagenum=1, zcurrentvoyageindex=2
where (zonvoyagenum != 1 or zonvoyagenum is null) and z_ent=27;
- Next step: finish the voyages instantaneously:
update zgameobject
set zendofvoyagetime=strftime('%s', 'now')
where zonvoyagenum = 1 and z_ent=27 and zendofvoyagetime > strftime('%s', 'now');
- Well, I do have a workshop and I want to build something (I used this hack in fact for Eric. I just couldn't get any map fragments, so I just set the workshop to build me a compass anyhow, without using any resources :-)). This query will not clear out if you already are building something. More information on things you can craft in CraftingRecipes.csv (check for workshop/armorsmith in there).
update zgameobject
set ZRECIPEIDINPROGRESS='Upgrade_Chest'
where zname = 'workshop' and (ZRECIPEIDINPROGRESS is null or ZRECIPEIDINPROGRESS = '');
- Same thing for the armorsmith:
update zgameobject
set ZRECIPEIDINPROGRESS=114
where zname = 'armorsmith' and (ZRECIPEIDINPROGRESS is null or ZRECIPEIDINPROGRESS = '');
- And now to finish these craftings immediately:
update zgameobject
set ZTIMEATWHICHOBJECTWILLBECOMEHARVESTABLENUM1=strftime('%s', 'now')
where zname IN ('workshop', 'armorsmith') and (ZRECIPEIDINPROGRESS is not null or ZRECIPEIDINPROGRESS != '');
- Fasten coin collection from buildings (I generally do this only on 'reward' buildings so I can get more ropes/canvasses etc etc). Just remove the ZNAMEDREWARD restriction if you want everything.
update zgameobject
set ZTIMEATWHICHOBJECTWILLBECOMEHARVESTABLENUM=strftime('%s', 'now'), zupgradecount=25
where ZTIMEATWHICHOBJECTWILLBECOMEHARVESTABLENUM != 0 and z_ent=23 and (ZNAMEDREWARD is not null);
- Fasten coin collection from ruby buildings:
update zgameobject
set ZTIMEATWHICHOBJECTWILLBECOMEHARVESTABLENUM=strftime('%s', 'now')
where ZTIMEATWHICHOBJECTWILLBECOMEHARVESTABLENUM != 0 and z_ent=22 and (ZNAMEDREWARD is not null);
- Another interesting stuff is quests. That can go wrong a lot of times, but just check out the URL on top of this article. You can just skip stuff, or add achievements and so on.
- How to get new ships? Like to top10-pvp Ships? :-). Easy Peasy... What I generally do is export my database. Get in the game & move a few ships. Export the database again & see what coordinates they were BEFORE (watch out, you need to modify 2x the coordinates in the same insert statement!).
Then set Z_PK to null (it will autoincrement that way). Change the ship you want (like pvpShip3 for the midnight ship which is running now). Check that the gameobject identifier in Z_PRIMARYKEY is still ok & you have a freaking new ship :-). For safety reasons I set ZCREWONEFBID/ZCREWTHREEFBID/ZCREWTWOFBID to null and ZEQUIPMENTSDATA=null. But I think the ZEQUIPMENTSDATA can be left as-is, and I believe it will duplicate the equipment into your new ship as well. But didn't bother trying that. It's faster to just re-assign new equipments anyhow than starting the game anew.
- Now what you've all been waiting for... How the **** can I get free rubies/coins? In fact it's fairly simple :-).
Adjust the ZMONEY (anything from cannons to hulls to boosts and ropes etc etc) or the ZUSERMODEL (wood, xp, coins, rubies) table. Well, 1 caveat... The ZROWHASH... Here's how to calculate it:
(PHP code follows)
$openUDID = '';
$currency = '';
$amount = '';
$wood = '';
$xp = '';
$coins = '';
$gems = '';
$energy = '';
# For currency:
$hash = base64_encode( sha1("$currency,$amount,$openUDID", true) );
echo "$currency: '$hash'\n";
# For usermodel:
$hash = base64_encode( sha1("$wood,$xp,$coins,$gems,$energy,$openUDID", true) );
echo "user: '$hash'\n";
Or simpler:
http://www.salvania.be/calculate.ZROWHASH.php
Where to find the openUDID? Also simple... Once you know it of course :). It's in Library\Preferences\com.pocketgems.paradisecove.plist. It's just an XML file. Just search for OpenUDID, and you'll see something 40 characters long consisting of 0-9a-z. That's the OpenUDID! Now you can update this ZROWHASH whenever and however you want...
Unlimited midnight cannons (+520 attack)? You got it... Unlimited rubies? Sand dollars (atlantis money), silver rings (asgard money)? You got it :-).
And no, I don't feel bad one single bit... Greedy games should be hacked.
Still figuring out how to cheat at the pvp competitions, but I think it's not that difficult :-).
As Finch says in PoI: "If they don't want you to get inside, they ought to build it better."
Update @ 2014-03-20:
What is the name of that ship again? Or that nifty cannon? Don't know it? Well, quite easy to get it...
Go to Library\Application Support\resources. You'll see a lot of CSV files.
* Shipnames are in ... Ships.csv (duh ;)). The first entry is the name in the database, the second the name in the game. Easy.
* Cannons and stuff is in ... Money.csv (remember the database table is ZMONEY?) Again, the first entry is the name in the database, the second the name in the game...
Have fun!