This requires Mgi's cache packer.
This was tested on 525, should work on 562.
Difficulty: 3/10
Step 1:
Download Mgi's cache packer. Here
Step 2:
Extract it to your desktop.
Step 3:
Open the src folder and extract the contents into your servers src folder.
Step 4:
In the data folder location in your server create a new folder called cache.
Step 5:
Move your client cache into this folder. no dlls are needed
Step 6:
create a package called regions in src/com/rs2hd/
Step 7:
Create these classes and put them in this package created on step 6.
Code:
package com.rs2hd.regions;
import java.util.ArrayList;
import java.util.HashMap;
import com.rs2hd.model.Entity;
import com.rs2hd.model.Location;
import com.rs2hd.model.NPC;
import com.rs2hd.model.Player;
public class RegionManager {
private HashMap<Integer, Region> regions;
public RegionManager() {
this.regions = new HashMap<Integer, Region>();
}
public void addRegion(int region, int regionX, int regionY) {
regions.put(region, new Region(regionX, regionY));
}
public void removeRegion(int region) {
regions.remove(region);
}
public Region getRegion(int region) {
return regions.get(region);
}
public ArrayList<Player> getPlayersFromRegions(Location location, ArrayList<Integer> regions) {
ArrayList<Player> players = new ArrayList<Player>();
for(int region : regions) {
if(this.regions.get(region) != null) {
for(Entity entity : this.regions.get(region).getEntities()) {
if(entity instanceof Player) {
if(((Player) entity).getLocation().withinDistance(location, 16))
players.add((Player) entity);
}
}
}
}
return players;
}
public ArrayList<NPC> getNPCFromRegions(Location location, ArrayList<Integer> regions) {
ArrayList<NPC> npcs = new ArrayList<NPC>();
for(int region : regions) {
if(this.regions.get(region) != null) {
for(Entity entity : this.regions.get(region).getEntities()) {
if(entity instanceof NPC) {
if(((NPC) entity).getLocation().withinDistance(location, 16))
npcs.add((NPC) entity);
}
}
}
}
return npcs;
}
}
Code:
package com.rs2hd.regions;
import java.util.ArrayList;
import mgi.tools.jagcached.cache.Cache;
import mgi.tools.jagcached.cache.File;
import mgi.tools.jagcached.cache.FileSystem;
import mgi.tools.jagcached.cache.Folder;
import mgi.utilities.ByteBuffer;
import com.rs2hd.model.Entity;
import com.rs2hd.model.Location;
import com.rs2hd.model.Bounds;
import com.rs2hd.model.World;
public class Region {
private ArrayList<Entity> entitiesInRegion;
private Tile[][][] tile;
private int regionX, regionY;
static final FileSystem INDEX_5 = new FileSystem(5, Cache.openCache("./Data/cache/"));
static {
INDEX_5.load();
}
public Region(int regionX, int regionY) {
entitiesInRegion = new ArrayList<Entity>();
tile = new Tile[4][64][64];
this.regionY = regionY;
this.regionX = regionX;
loadObjects(regionX, regionY);
}
public boolean canWalk(int locX, int locY, Location location) {
Bounds bound = new Bounds(regionX*64, regionY*64, (regionX*64)+63, (regionY*64)+63);
if(!bound.withinArea(location) || tile[location.getZ()][locX][locY] == null)
return true;
return false;
}
public boolean objectExistsAt(Location location, int id) {
Bounds bound = new Bounds(regionX*64, regionY*64, (regionX*64)+63, (regionY*64)+63);
int x = location.getX() - ((location.getX()/64)*64), y = location.getY() - ((location.getY()/64)*64);
if(!bound.withinArea(location) || tile[location.getZ()][x][y] == null)
return false;
for(GameObject object : tile[location.getZ()][x][y].getObjects())
if(object.getId() == id)
return true;
return false;
}
public ArrayList<Entity> getEntities() {
return entitiesInRegion;
}
public void addEntityToRegion(Entity e) {
entitiesInRegion.add(e);
}
public void removeEntityFromRegion(Entity e) {
entitiesInRegion.remove(e);
}
public void loadObjects(int locX, int locY) {
try {
Folder folder = INDEX_5.findFolderByName("l"+locX+"_"+locY, World.getInstance().getMapData525((locX << 8) + locY));
for (int i = 0; i < folder.filesCount(); i++) {
File fid = folder.findFileByID(i);
if (fid == null)
continue;
ByteBuffer buffer = fid.getData();
buffer.setPosition(0);
int id = -1;
boolean bool_4_ = false;
do {
int i_6_ = buffer.specialRead1();
if (-1 == (i_6_ ^ 0xffffffff) && !bool_4_)
break;
id += i_6_;
int i_7_ = 0;
do {
int i_8_ = buffer.readUnsignedSmart();
if ((i_8_ ^ 0xffffffff) == -1)
break;
i_7_ += i_8_ + -1;
int y = i_7_ & 0x3f;
int height = i_7_ >> -1887294292;
int x = (i_7_ & 0xfe7) >> -952356218;
int i_12_ = buffer.readUByte();
final int type = i_12_ >> -2109364606;
final int face = i_12_ & 0x3;
if (x > 0 && -1 > (y ^ 0xffffffff) && x < 103 && y < 103) {
if(tile[height][x][y] == null)
tile[height][x][y] = new Tile(height, x, y);
tile[height][x][y].getObjects().add(new GameObject(id, type, face));
}
} while (!bool_4_);
} while (!bool_4_);
}
} catch (Exception e) {
}
}
public void removeTile(int z, int x, int y) {
tile[z][x][y] = null;
}
}
Code:
package com.rs2hd.regions;
import java.util.ArrayList;
import com.rs2hd.model.World;
public class Tile {
private ArrayList<GameObject> objectsOnTile;
private int x, y, z;
public Tile(int z, int x, int y) {
objectsOnTile = new ArrayList<GameObject>();
this.z = z;
this.x = x;
this.y = y;
}
public ArrayList<GameObject> getObjects() {
return objectsOnTile;
}
public void removeObject(int type) {
for(int i = 0; i < objectsOnTile.size(); i++) {
GameObject obj = objectsOnTile.get(i);
if(obj.getType() == type) {
objectsOnTile.remove(i);
break;
}
}
if(objectsOnTile.size() == 0)
World.getInstance().getRegionManager().getRegion(y + (x << 8)).removeTile(z, x, y);
}
}
Code:
package com.rs2hd.regions;
public class GameObject {
int id, type, face;
public GameObject(int id, int type, int face) {
this.id = id;
this.type = type;
this.face = face;
}
public int getId() {
return id;
}
public int getType() {
return type;
}
public int getFace() {
return face;
}
}
Step 8:
Entity.java
add this field -
Code:
private transient int currentRegion;
add these methods -
Code:
public void addToRegion(int region) {
if(World.getInstance().getRegionManager().getRegion(region) == null)
World.getInstance().getRegionManager().addRegion(region, location.getX() / 64, location.getY() / 64);
World.getInstance().getRegionManager().getRegion(region).addEntityToRegion(this);
}
public void removeFromRegion(int region) {
World.getInstance().getRegionManager().getRegion(region).removeEntityFromRegion(this);
}
public int getCurrentRegion() {
return currentRegion;
}
public void setCurrentRegion(int newRegion) {
currentRegion = newRegion;
}
replace
Code:
public void setLocation(Location location) {
this.location = location;
}
with
Code:
public void setLocation(Location location) {
this.location = location;
int newRegion = (location.getY() / 64) + ((location.getX() / 64) << 8);
if(newRegion != getCurrentRegion()) {
removeFromRegion(getCurrentRegion());
setCurrentRegion(newRegion);
addToRegion(getCurrentRegion());
}
}
Step 9 -
Player.java
add this field
Code:
private transient ArrayList<Integer> regions;
add this in the readResolve() method
Code:
regions = new ArrayList<Integer>();
add this method
Code:
public ArrayList<Integer> regions() {
return regions;
}
Step 10:
World.java
add this field
Code:
public static final RegionManager REGIONMANAGER = new RegionManager();
add this method
Code:
public RegionManager getRegionManager() {
return REGIONMANAGER;
}
Step 11:
ActionSender.java
in the method sendMapRegion add this
Code:
player.regions().clear();
above
Code:
for(int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
and add this
Code:
player.regions().add(region);
above
Code:
spb.addInt(mapData[0]);
spb.addInt(mapData[1]);
spb.addInt(mapData[2]);
spb.addInt(mapData[3]);
Step 12:
PlayerUpdate.java
replace
Code:
for (Player p2 : World.getInstance().getPlayerList()) {
with
Code:
for(Player p2 : World.getInstance().getRegionManager().getPlayersFromRegions(p.getLocation(), p.regions())) {
Step 13:
NPCUpdate.java
Code:
for (NPC npc : World.getInstance().getNpcList()) {
with
Code:
for(NPC npc : World.getInstance().getRegionManager().getNPCFromRegions(p.getLocation(), p.regions())) {
Step 14:
add this in objectpackethandler
Code:
boolean exists = false;
final Location location = Location.location(objectX, objectY, player.getLocation().getZ());
for(int regionid : player.regions()) {
if(World.getInstance().getRegionManager().getRegion(regionid) == null) {
boolean regionfound = false;
for(int xCalc = (location.getRegionX() - 6) / 8; xCalc <= ((location.getRegionX() + 6) / 8); xCalc++) {
for(int yCalc = (location.getRegionY() - 6) / 8; yCalc <= ((location.getRegionY() + 6) / 8); yCalc++) {
int region = yCalc + (xCalc << 8);
if(regionid == region) {
regionfound = true;
World.getInstance().getRegionManager().addRegion(regionid, xCalc, yCalc);
break;
}
}
if(regionfound)
break;
}
if(!regionfound)
return;
}
if(World.getInstance().getRegionManager().getRegion(regionid).objectExistsAt(location, objectId)) {
exists = true;
break;
}
}
if(exists == false) {
player.getWalkingQueue().reset();
player.sm("This Object is fake!");
return;
} else {
player.sm("This Object exists.");
}
Edit***
You will have to put this in the ByteBuffer class.
Code:
public final int specialRead1() {
int i_2_;
int i_3_ = 0;
int i_4_ = readUnsignedSmart();
while (i_4_ == 32767) {
i_4_ = readUnsignedSmart();
i_3_ += 32767;
break;
}
i_3_ += i_4_;
i_2_ = i_3_;
return i_2_;
}
and you'll need to add this class in model.
Code:
package com.rs2hd.model;
public class Bounds {
int minX, minY, maxX, maxY;
public Bounds(int minX, int minY, int maxX, int maxY) {
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;
}
public Bounds(int minX, int minY) {
this.minX = minX;
this.minY = minY;
this.maxX = -1;
this.maxY = -1;
}
public boolean withinArea(Location location) {
int x = location.getX();
int y = location.getY();
if(maxX == -1 && maxY == -1)
return minX == x && minY == y;
return x >= minX && x <= maxX && y >= minY && y <= maxY;
}
}
Credits:
Mgi for Cache Packer
Me for all code you see above.