Emberveil sourcetests/GlobalDropCheck.java
package com.rs2.world;
import com.rs2.game.players.*;
import com.rs2.net.PacketSender;
import com.rs2.event.CycleEventHandler;
import com.rs2.game.items.ItemDefinitions;
import org.apollo.cache.IndexedFileSystem;
import org.apollo.cache.decoder.ItemDefinitionDecoder;
import java.nio.file.Paths;
import java.util.*;
import java.lang.reflect.Field;
public final class GlobalDropCheck {
static int checks;static void check(boolean ok,String message){if(!ok)throw new AssertionError(message);checks++;}
static class Capture extends PacketSender {
final Map<String,Integer> creates=new HashMap<>();Capture(Player p){super(p);}
static String key(int id,int x,int y,int h){return id+":"+x+":"+y+":"+h;}
public PacketSender createGroundItem(int id,int x,int y,int amount,int h){String k=key(id,x,y,h);creates.put(k,creates.getOrDefault(k,0)+1);return this;}
public PacketSender removeGroundItem(int id,int x,int y,int amount){return this;}
}
static class Fixture extends Client {
Capture capture;Fixture(int id){super(null,id);getOutStream().packetEncryption=new org.apollo.util.security.IsaacRandom(new int[]{1,2,3,4});capture=new Capture(this);isActive=true;}
public PacketSender getPacketSender(){return capture==null?super.getPacketSender():capture;}
public void flushOutStream(){getOutStream().currentOffset=0;}
}
public static void main(String[] args)throws Exception {
new ItemDefinitionDecoder(new IndexedFileSystem(Paths.get("data/cache"),true)).run();ItemDefinitions.load();
GlobalDropsHandler.initialize();
Field f=GlobalDropsHandler.class.getDeclaredField("globalDrops");f.setAccessible(true);
@SuppressWarnings("unchecked") List<GlobalDropsHandler.GlobalDrop> drops=(List<GlobalDropsHandler.GlobalDrop>)f.get(null);
GlobalDropsHandler.GlobalDrop drop=drops.stream().filter(d->d.getHeight()==0).findFirst().get();
Fixture a=new Fixture(1),b=new Fixture(2),upper=new Fixture(3);PlayerHandler.players[1]=a;PlayerHandler.players[2]=b;PlayerHandler.players[3]=upper;
for(Fixture p:new Fixture[]{a,b,upper}){p.absX=drop.getX();p.absY=drop.getY();p.heightLevel=0;}upper.heightLevel=1;
String key=Capture.key(drop.getId(),drop.getX(),drop.getY(),drop.getHeight());
GlobalDropsHandler.load(a);GlobalDropsHandler.load(b);GlobalDropsHandler.load(upper);
check(a.capture.creates.containsKey(key)&&b.capture.creates.containsKey(key),"both players receive available ground item");check(!upper.capture.creates.containsKey(key),"wrong floor excluded");
GlobalDropsHandler.pickup(a,drop.getId(),drop.getX(),drop.getY());check(drop.isTaken(),"pickup starts cooldown");int amount=a.getItemAssistant().getItemAmount(drop.getId());
GlobalDropsHandler.pickup(a,drop.getId(),drop.getX(),drop.getY());check(a.getItemAssistant().getItemAmount(drop.getId())==amount,"repeat pickup cannot duplicate item");
int eventCount=CycleEventHandler.getSingleton().getEventsCount(),size=drops.size();
for(int i=0;i<100;i++){GlobalDropsHandler.reset(a);GlobalDropsHandler.reset(b);}
check(CycleEventHandler.getSingleton().getEventsCount()==eventCount,"200 region changes add no background events");check(drops.size()==size,"region changes retain cached definitions");check(drop.isTaken(),"region changes preserve cooldown");
GlobalDropsHandler.respawn(drop.getTakenAt()+19999);check(drop.isTaken(),"no early respawn");
int first=a.capture.creates.get(key),second=b.capture.creates.get(key);GlobalDropsHandler.respawn(drop.getTakenAt()+20000);
check(!drop.isTaken(),"respawn after twenty seconds");check(a.capture.creates.get(key)==first+1&&b.capture.creates.get(key)==second+1,"respawn reaches both nearby players");check(!upper.capture.creates.containsKey(key),"respawn respects floor");
System.out.println("PASS "+checks+" global drop visibility/cooldown/duplicate/event-growth checks; "+size+" definitions loaded once");
}
}