Emberveil sourcetests/EmberveilCheck.java
import com.rs2.game.content.emberveil.Emberveil;
import com.rs2.game.players.Client;
import com.rs2.game.players.PlayerHandler;
import com.rs2.game.players.PlayerSave;
import com.rs2.game.items.ItemDefinitions;
import org.apollo.cache.IndexedFileSystem;
import org.apollo.cache.decoder.ItemDefinitionDecoder;
import java.nio.file.*;
import java.util.Arrays;
/** Integration checks using the real cache, inventory and character serializer. */
public class EmberveilCheck {
static class TestPlayer extends Client {
TestPlayer() { super(null, 1); getOutStream().packetEncryption = new org.apollo.util.security.IsaacRandom(new int[] {1,2,3,4}); }
@Override public void flushOutStream() { getOutStream().currentOffset = 0; }
}
static int checks;
static void check(boolean result, String label) {
if (!result) throw new AssertionError(label);
checks++;
}
static void command(TestPlayer p, String cmd, String... args) {
p.getOutStream().currentOffset = 0;
check(Emberveil.handle(p,cmd,args), "command recognized: " + cmd);
}
static void position(TestPlayer p, int x, int y) { p.absX=x; p.absY=y; p.heightLevel=0; }
static void clear(TestPlayer p) { Arrays.fill(p.playerItems,0); Arrays.fill(p.playerItemsN,0); }
public static void main(String[] args) throws Exception {
new ItemDefinitionDecoder(new IndexedFileSystem(Paths.get("data/cache"), true)).run();
ItemDefinitions.load();
TestPlayer p = new TestPlayer();
position(p,0,0);
command(p,"ember","begin"); check(p.emberStage==0,"cannot begin remotely");
position(p,3221,3218);
command(p,"ember","begin"); check(p.emberStage==1,"begin near Hans");
command(p,"ember","offer"); check(p.emberStage==1,"missing items cannot advance");
p.getItemAssistant().addItem(1511,5);
p.inTrade=true;
command(p,"ember","offer"); check(p.emberStage==1,"trade blocks hand-in");
p.inTrade=false;
command(p,"ember","offer"); check(p.emberStage==2,"logs advance story");
check(!p.getItemAssistant().playerHasItem(1511),"story consumes supplies");
command(p,"ember","listen"); check(p.emberStage==2,"wrong location cannot advance");
position(p,3109,3167); command(p,"ember","listen"); check(p.emberStage==3,"tower clue");
position(p,3087,3335); p.getItemAssistant().addItem(526,3);
command(p,"ember","offer"); check(p.emberStage==4,"fountain offering");
position(p,2985,3293); p.getItemAssistant().addItem(2349,3);
command(p,"ember","offer"); check(p.emberStage==5,"altar offering");
position(p,3221,3218);
Arrays.fill(p.playerItems,1512); Arrays.fill(p.playerItemsN,1);
command(p,"ember","finish"); check(p.emberStage==5 && p.emberSigils==0,"full inventory does not claim story reward");
clear(p); command(p,"ember","finish");
check(p.emberStage==6 && p.emberSigils==10 && p.emberReputation==10,"story rewards");
check(p.getItemAssistant().playerHasItem(995,2000),"story coin payment");
command(p,"ember","finish"); check(p.emberSigils==10,"story reward cannot repeat");
command(p,"deliver"); check(p.emberContracts==0,"missing delivery refused");
p.getItemAssistant().addItem(1511,10); command(p,"deliver");
check(p.emberContracts==1 && p.emberSigils==12,"contract completion");
command(p,"deliver"); check(p.emberContracts==1,"contract cannot repeat without next supplies");
command(p,"redeem","axe"); check(p.emberSigils==0 && p.emberReputation==12,"redeem spends only sigils");
check(p.getItemAssistant().playerHasItem(1353),"correct reward item");
command(p,"redeem","axe"); check(p.emberSigils==0,"insufficient sigils refused");
clear(p); p.playerItems[0]=996; p.playerItemsN[0]=Integer.MAX_VALUE;
p.getItemAssistant().addItem(315,10);
command(p,"deliver");
check(p.emberContracts==1 && p.getItemAssistant().playerHasItem(315,10),"coin overflow rejects delivery without consuming supplies");
clear(p); p.getItemAssistant().addItem(316,10);
command(p,"deliver"); check(p.emberContracts==1,"noted supplies cannot satisfy contract");
clear(p); p.getItemAssistant().addItem(315,10); p.heightLevel=1;
command(p,"deliver"); check(p.emberContracts==1,"wrong height cannot hand in"); p.heightLevel=0;
TestPlayer other=new TestPlayer(); position(other,3221,3218);
command(other,"ember","begin"); check(other.emberStage==1 && p.emberStage==6,"story state is independent between characters");
clear(p);
p.tutorialProgress=36; position(p,3109,3167);
Emberveil.discover(p); Emberveil.discover(p);
check(p.emberDiscoveries==1 && p.emberSigils==1,"landmark reward only once");
p.playerName=p.playerName2="emberveil_qa"; p.playerPass="qa-local-only";
p.saveFile=true; p.newPlayer=false; p.saveCharacter=true;
PlayerHandler.players[1]=p;
Path saved=Paths.get("data/characters/emberveil_qa.txt");
check(!Files.exists(saved),"QA name must not overwrite an existing character");
try {
check(PlayerSave.saveGame(p),"save succeeds");
TestPlayer restored=new TestPlayer(); restored.playerName="emberveil_qa";
check(PlayerSave.loadPlayerInfo(restored,"emberveil_qa","qa-local-only",false)==1,"load succeeds");
check(restored.emberStage==6 && restored.emberContracts==1 && restored.emberSigils==1 && restored.emberReputation==13 && restored.emberDiscoveries==1,"all custom progress survives reload");
check(PlayerSave.loadPlayerInfo(newNamedPlayer(),"emberveil_qa","wrong-password",true)==3,"wrong password rejected");
check(PlayerSave.loadPlayerInfo(newNamedPlayer(),"emberveil_qa","qa-local-only",true)==1,"correct password accepted");
p.emberSigils=9;
check(PlayerSave.saveGame(p),"second save succeeds");
check(Files.exists(Paths.get(saved.toString()+".bak")),"previous save backed up");
check(new String(Files.readAllBytes(Paths.get(saved.toString()+".bak")),java.nio.charset.StandardCharsets.UTF_8).contains("ember-sigils = 1"),"backup contains previous committed state");
check(new String(Files.readAllBytes(saved),java.nio.charset.StandardCharsets.UTF_8).contains("ember-sigils = 9"),"replacement contains new state");
clear(p); position(p,3221,3218);
command(p,"charter","claim"); check(p.emberCharter==0,"incomplete atlas cannot claim charter");
p.emberDiscoveries=63;
Arrays.fill(p.playerItems,1512); Arrays.fill(p.playerItemsN,1);
command(p,"charter","claim"); check(p.emberCharter==0,"full inventory preserves charter reward");
clear(p); command(p,"charter","claim");
check(p.emberCharter==1 && p.emberSigils==24 && p.emberReputation==28,"charter rewards correct");
check(p.getItemAssistant().playerHasItem(995,5000) && p.getItemAssistant().playerHasItem(1009),"charter equipment and coins");
command(p,"charter","claim"); check(p.emberSigils==24,"charter cannot be claimed twice");
check(PlayerSave.saveGame(p),"charter save succeeds");
TestPlayer charterReload=newNamedPlayer(); PlayerSave.loadPlayerInfo(charterReload,"emberveil_qa","qa-local-only",false);
check(charterReload.emberCharter==1,"charter claim survives reload");
TestPlayer menu=new TestPlayer(); position(menu,3221,3218);
Emberveil.talk(menu); check(menu.nextChat==Emberveil.WATCH_GREETING,"Hans greeting has continuation");
menu.getDialogueHandler().sendDialogues(menu.nextChat,0);
check(Emberveil.handleButton(menu,9190) && menu.emberStage==1,"clickable Hans menu starts story");
check(!Emberveil.handleButton(menu,9190),"stale dialogue click ignored");
Emberveil.watchMenu(menu); position(menu,0,0);
check(Emberveil.handleButton(menu,9192) && menu.emberContracts==0,"menu cannot deliver from another location");
position(menu,3221,3218); Emberveil.watchMenu(menu);
check(Emberveil.handleButton(menu,9193),"quartermaster menu opens");
menu.emberSigils=3;
check(Emberveil.handleButton(menu,9190) && menu.emberSigils==0 && menu.getItemAssistant().playerHasItem(1061),"clickable quartermaster purchases correctly");
} finally { Files.deleteIfExists(saved); Files.deleteIfExists(Paths.get(saved.toString()+".bak")); PlayerHandler.players[1]=null; }
Path stop=Files.createTempFile("emberveil-stop-test-", ".request");
System.setProperty("emberveil.stopFile",stop.toAbsolutePath().toString());
try {
Files.write(stop,"IGNORE".getBytes(java.nio.charset.StandardCharsets.UTF_8));
check(!com.rs2.game.content.emberveil.ServerControl.poll(),"invalid shutdown signal ignored");
Files.write(stop,"STOP".getBytes(java.nio.charset.StandardCharsets.UTF_8));
check(com.rs2.game.content.emberveil.ServerControl.poll() && !Files.exists(stop),"valid local shutdown consumed");
} finally { Files.deleteIfExists(stop); System.clearProperty("emberveil.stopFile"); }
System.out.println("PASS: " + checks + " Emberveil integration checks.");
System.exit(0);
}
static TestPlayer newNamedPlayer() { TestPlayer p=new TestPlayer(); p.playerName="emberveil_qa"; return p; }
}