Client side:
Code:
int heightLevel = Class68_Sub13_Sub8.packetStream.readUnsignedByteA();
int regionY = Class68_Sub13_Sub8.packetStream.readUnsignedWord(i + 1355769449);
int localX = Class68_Sub13_Sub8.packetStream.readUnsignedWordA();
Class68_Sub13_Sub8.packetStream.initBitAccess(i + 17);
for (int partId = 0; (partId ^ 0xffffffff) > -5; partId++) {
for (int xCalc = 0; (xCalc ^ 0xffffffff) > -14; xCalc++) {
for (int yCalc = 0; (yCalc ^ 0xffffffff) > -14; yCalc++) {
int flag = Class68_Sub13_Sub8.packetStream.readBits((byte) 0, 1);
if (flag == 1)
Class68_Sub2.mapBitDataArray[partId][xCalc][yCalc] = Class68_Sub13_Sub8.packetStream.readBits((byte) 0, 26);
else
Class68_Sub2.mapBitDataArray[partId][xCalc][yCalc] = -1;
}
}
}
Class68_Sub13_Sub8.packetStream.finishBitAccess((byte) -59);
int length = (-Class68_Sub13_Sub8.packetStream.currentOffset + Class106.packetSize) / 16;
Class68_Sub20_Sub6.mapDataArray = new int[length][4];
for (int pointer = 0; pointer < length; pointer++) {
for (int partId = 0; ~partId > -5; partId++)
Class68_Sub20_Sub6.mapDataArray[pointer][partId] = Class68_Sub13_Sub8.packetStream.readDWord((byte) 115);
}
int localY = Class68_Sub13_Sub8.packetStream.readUnsignedWordA();
int regionX = Class68_Sub13_Sub8.packetStream.readUnsignedWordA();
Class68_Sub20_Sub11.aByteArrayArray4332 = new byte[length][];
Class7.aByteArrayArray133 = null;
Class96.cacheIndicesM = new int[length];
NPCDef.anIntArray1406 = null;
Class119.regionIndices = new int[length];
Class23.aByteArrayArray490 = new byte[length][];
Class68_Sub13_Sub29.cacheIndicesL = new int[length];
length = 0;
for (int partId = 0; partId < 4; partId++) {
for (int xCalc = 0; (xCalc ^ 0xffffffff) > -14; xCalc++) {
for (int yCalc = 0; yCalc < 13; yCalc++) {
int bitPackedData = (Class68_Sub2.mapBitDataArray[partId][xCalc][yCalc]);
if (bitPackedData != -1) {
int regionX = 0x3ff & bitPackedData >> 14;
int regionY = (bitPackedData & 0x3fff) >> 3;
int regionIndex = regionY / 8 + (regionX / 8 << 8);
for (int i_59_ = 0; i_59_ < length; i_59_++) {
if (Class119.regionIndices[i_59_] == regionIndex) {
regionIndex = -1;
break;
}
}
if (regionIndex != -1) {
int x = (regionIndex & 0xff02) >> 8;
int y = regionIndex & 0xff;
Class119.regionIndices[length] = regionIndex;
Class96.cacheIndicesM[length] = (Class92.aClass21_Sub1_1644.method335((Class68_Sub20_Sub13_Sub2.method1166(2, (new RSString[] { Class83.M, Class68_Sub13_Sub24.method816(x, i + -95), Class68_Sub20_Sub5.UNDERSCORE, (Class68_Sub13_Sub24.method816(y, Class15.method278(i, 95))) }))), (byte) -99));
Class68_Sub13_Sub29.cacheIndicesL[length] = (Class92.aClass21_Sub1_1644.method335((Class68_Sub20_Sub13_Sub2.method1166(2, (new RSString[] { (Class68_Sub20_Sub16.L), Class68_Sub13_Sub24.method816(x, 0), Class68_Sub20_Sub5.UNDERSCORE, Class68_Sub13_Sub24.method816(y, 0) }))), (byte) -88));
Class128.uploadMapData(regionIndex, Class68_Sub20_Sub6.mapDataArray[length]);
dumpData(regionIndex, Class68_Sub20_Sub6.mapDataArray[length]);
length++;
}
}
}
}
}
Class81.loadMapRegionStep2((byte) -45, localY, heightLevel, false, localX, regionX, regionY);
Server side:
Code:
public void sendMapRegion2() {
if(!validateMapRegion()) {
player.getActionSender().sendMessage("This area of the world is unavailable, teleporting to spawn point...");
player.setLocation(Entity.DEFAULT_LOCATION);
sendMapRegion();
return;
}
StaticPacketBuilder spb = new StaticPacketBuilder().setId(173).setSize(Packet.Size.VariableShort);
spb.addByteA(player.getLocation().getZ());
spb.addShort(player.getLocation().getRegionY());
spb.addShortA(player.getLocation().getLocalX());
spb.initBitAccess();
for(int height = 0; height < 4; height++) {
for(int xCalc = (player.getLocation().getRegionX() - 6); xCalc <= (player.getLocation().getRegionX() + 6); xCalc++) {
for(int yCalc = (player.getLocation().getRegionY() - 6); yCalc <= (player.getLocation().getRegionY() + 6); yCalc++) {
if(height == player.getLocation().getZ()) {
spb.addBits(1, 1);
spb.addBits(26, (xCalc << 14) | (yCalc << 3));
} else {
spb.addBits(1, 0);
}
}
}
}
spb.finishBitAccess();
for(int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
for(int yCalc = (player.getLocation().getRegionY() - 6) / 8; yCalc <= ((player.getLocation().getRegionY() + 6) / 8); yCalc++) {
int region = yCalc + (xCalc << 8);
int[] mapData = World.getInstance().getMapData(region);
if(mapData == null) {
mapData = new int[4];
for(int i = 0; i < 4; i++) {
mapData[i] = 0;
}
}
spb.addInt(mapData[0]);
spb.addInt(mapData[1]);
spb.addInt(mapData[2]);
spb.addInt(mapData[3]);
}
}
spb.addShortA(player.getLocation().getLocalY());
spb.addShortA(player.getLocation().getRegionX());
player.getSession().write(spb.toPacket());
player.getUpdateFlags().setLastRegion(player.getLocation());
World.getInstance().getItemManager().refresh(player);
}
public void sendMapRegion() {
if(!validateMapRegion()) {
player.getActionSender().sendMessage("This area of the world is unavailable, teleporting to spawn point...");
player.setLocation(Entity.DEFAULT_LOCATION);
}
StaticPacketBuilder spb = new StaticPacketBuilder().setId(142).setSize(Packet.Size.VariableShort);
boolean forceSend = true;
if((((player.getLocation().getRegionX() / 8) == 48) || ((player.getLocation().getRegionX() / 8) == 49)) && ((player.getLocation().getRegionY() / 8) == 48)) {
forceSend = false;
}
if(((player.getLocation().getRegionX() / 8) == 48) && ((player.getLocation().getRegionY() / 8) == 148)) {
forceSend = false;
}
spb.addShortA(player.getLocation().getRegionX());
spb.addLEShortA(player.getLocation().getLocalY());
spb.addShortA(player.getLocation().getLocalX());
for(int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
for(int yCalc = (player.getLocation().getRegionY() - 6) / 8; yCalc <= ((player.getLocation().getRegionY() + 6) / 8); yCalc++) {
int region = yCalc + (xCalc << 8); // 1786653352
if(forceSend || ((yCalc != 49) && (yCalc != 149) && (yCalc != 147) && (xCalc != 50) && ((xCalc != 49) || (yCalc != 47)))) {
if(Misc.isSecondaryRegion(region)) {
sendMapRegion2();
return;
}
int[] mapData = World.getInstance().getMapData(region);
if(mapData == null) {
mapData = new int[4];
for(int i = 0; i < 4; i++) {
mapData[i] = 0;
}
}
spb.addInt(mapData[0]);
spb.addInt(mapData[1]);
spb.addInt(mapData[2]);
spb.addInt(mapData[3]);
}
}
}
spb.addByteC(player.getLocation().getZ());
spb.addShort(player.getLocation().getRegionY());
player.getSession().write(spb.toPacket());
player.getUpdateFlags().setLastRegion(player.getLocation());
World.getInstance().getItemManager().refresh(player);
}
private boolean validateMapRegion() {
boolean hasMapData = true;
boolean forceSend = true;
if((((player.getLocation().getRegionX() / 8) == 48) || ((player.getLocation().getRegionX() / 8) == 49)) && ((player.getLocation().getRegionY() / 8) == 48)) {
forceSend = false;
}
if(((player.getLocation().getRegionX() / 8) == 48) && ((player.getLocation().getRegionY() / 8) == 148)) {
forceSend = false;
}
for(int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
for(int yCalc = (player.getLocation().getRegionY() - 6) / 8; yCalc <= ((player.getLocation().getRegionY() + 6) / 8); yCalc++) {
int region = yCalc + (xCalc << 8); // 1786653352
if(forceSend || ((yCalc != 49) && (yCalc != 149) && (yCalc != 147) && (xCalc != 50) && ((xCalc != 49) || (yCalc != 47)))) {
int[] mapData = World.getInstance().getMapData(region);
if(mapData == null) {
hasMapData = false;
}
}
}
}
return hasMapData;
}
Code:
public static boolean isSecondaryRegion(int region) {
return region == 10536;
}
Pali's 523 implementation:
Code:
public void setMapRegion2() {
p.stream.writeOpcodeVarShort(252)
.writeShortBigEndian(p.getLocalX())
.initBitAccess();
for (int height = 0; height < 4; height++) {
for (int xCalc = p.getRegionX() - 6; xCalc <= p.getRegionX() + 6; xCalc++) {
for (int yCalc = p.getRegionY() - 6; yCalc <= p.getRegionY() + 6; yCalc++) {
p.stream.writeBits(1, height == p.height() ? 1 : 0);
if (height == p.height()) {
p.stream.writeBits(26, (xCalc << 1854022254 | (yCalc << -1044042941)));
}
}
}
}
p.stream.finishBitAccess();
for (int xCalc = (p.getRegionX() - 6) / 8; xCalc <= (p.getRegionX() + 6) / 8; xCalc++) {
for (int yCalc = (p.getRegionY() - 6) / 8; yCalc <= (p.getRegionY() + 6) / 8; yCalc++) {
int region = yCalc + (xCalc << 8);
int[] mapData = ObjectManager.getRegionData(region);
p.stream.writeIntV1(mapData[0])
.writeIntV1(mapData[1])
.writeIntV1(mapData[2])
.writeIntV1(mapData[3]);
}
}
p.stream.writeShortBigEndian128(p.getLocalY())
.writeShort(p.getRegionY())
.writeByte(p.height())
.writeShort(p.getRegionX())
.endOpcodeVarShort();
}
Coords I'm teleporting to (pest control game):
2667, 2594
Map data for that area (10536):
Code:
349537117
1202512092
-698870718
-2083455397
Error I receive:
Code:
RuntimeException_Sub1
at Class107.method1652(Class107.java:91)
at Class21.method336(Class21.java:190)
at Class21.method350(Class21.java:520)
at Class61.method598(Class61.java:338)
at client.method33(client.java:765)
at Applet_Sub1.method30(Applet_Sub1.java:522)
at Applet_Sub1.run(Applet_Sub1.java:160)
at java.lang.Thread.run(Unknown Source)
Error: T3 - true,0,104,-968772399,-1159658993,-1125057849,-1186152368 | RSString
:855 Class21:188 Class21:520 Class61:338 client:765 Applet_Sub1:522 Applet_Sub1:
160 java.lang.Thread.run | java.lang.RuntimeException
error_game_crash
Anyone have any ideas as to what is causing this? I've checked the packet structure against the client one, and I'm pretty sure I'm calculating everything right (looked at Pali's 523 version).
EDIT: sometimes I also get an OutOfMemoryError.
---------- Post added at 11:18 AM ---------- Previous post was at 09:38 AM ----------
Okay peter gave some insight into it, I'll keep this topic up though.
(.) Peter says (11:23):
T3 means error decompressing JAGCONTAINER
Your cache is corrupt