PDA

View Full Version : The Three Map Regions



Emily
July 21st, 2011, 09:37
Title should say "The Three Map Region Types".


At first, after investigating the client I believed there were four. Both Sinisoul and I saw that there were four calculations similar to how the map regions are calculated. Well, after further investigation. I'm assuming this is how they are/what they do:


Map Region 1:
Also known as the 'main map region'. Is the common map region that you are in, in Runescape.
Example Code:


static final void loadMainMapRegion(byte i) {
anInt8383++;
Class372.anInt4574 = 0;
RSBuffer_Sub1 rsbuffer_sub1 = Node_Sub29.aClass345_7615.aRSBuffer_Sub1_4263;
boolean bool = rsbuffer_sub1.readUByteC() == 1;
int playerRegionY = rsbuffer_sub1.method2745((byte) -116);
int i_18_ = rsbuffer_sub1.readUByte();
int playerRegionX = rsbuffer_sub1.method2726(false);
Class132.method1560(-7593);
Class249_Sub4.method3283(i_18_, (byte) -125);
if (i != 116) {
aClass303_8396 = null;
}
int i_20_ = (Node_Sub29.aClass345_7615.anInt4275 + -rsbuffer_sub1.offset) / 16;
Class295.anIntArrayArray3672 = new int[i_20_][4];
for (int i_21_ = 0; i_20_ > i_21_; i_21_++) {
for (int i_22_ = 0; i_22_ < 4; i_22_++)
Class295.anIntArrayArray3672[i_21_][i_22_] = rsbuffer_sub1.readInt();
}
Class315.aByteArrayArray3965 = new byte[i_20_][];
Class203_Sub1.anIntArray8541 = null;
Class205.anIntArray5086 = new int[i_20_];
Class309.aByteArrayArray3855 = new byte[i_20_][];
RSCanvas.anIntArray75 = new int[i_20_];
Class315.aByteArrayArray3975 = null;
Node_Sub38_Sub1.anIntArray9419 = new int[i_20_];
EntityNode_Sub5_Sub2_Sub1.aByteArrayArray10315 = new byte[i_20_][];
Node_Sub27.anIntArray7575 = new int[i_20_];
Class199.anIntArray2538 = new int[i_20_];
SubNode_Sub2.aByteArrayArray9937 = new byte[i_20_][];
i_20_ = 0;
for (int xCalc = (playerRegionX + -(Class85.regionParamX >> 4)) / 8; (xCalc ^ 0xffffffff) >= ((playerRegionX + (Class85.regionParamX >> 4)) / 8 ^ 0xffffffff); xCalc++) {
for (int yCalc = (-(SubNode_Sub14.regionParamY >> 4) + playerRegionY) / 8; (((SubNode_Sub14.regionParamY >> 4) + playerRegionY) / 8 ^ 0xffffffff) <= (yCalc ^ 0xffffffff); yCalc++) {
Class199.anIntArray2538[i_20_] = yCalc + (xCalc << 8);
RSCanvas.anIntArray75[i_20_] = Node_Sub37.aDecompressor7751.method716("m" + xCalc + "_" + yCalc, (byte) -119);
Node_Sub38_Sub1.anIntArray9419[i_20_] = Node_Sub37.aDecompressor7751.method716("l" + xCalc + "_" + yCalc, (byte) -128);
Class205.anIntArray5086[i_20_] = Node_Sub37.aDecompressor7751.method716("um" + xCalc + "_" + yCalc, (byte) -119);
Node_Sub27.anIntArray7575[i_20_] = Node_Sub37.aDecompressor7751.method716("ul" + xCalc + "_" + yCalc, (byte) 80);
i_20_++;
}
}
System.out.println("Region 1");
Class152.sendMapRegion(-106, playerRegionY, bool, playerRegionX, 12);
}



Map Region 2:
Also known as the secondary map region, it is the map region used with construction, dungeoneering, quests, and soon Citadels.
Example Code:


static final void loadSecondaryMapRegion(int i) {
anInt9486++;
RSBuffer_Sub1 rsbuffer_sub1 = Node_Sub29.aClass345_7615.aRSBuffer_Sub1_4263;
Class372.anInt4574 = rsbuffer_sub1.method2710(255);
boolean forceSend = rsbuffer_sub1.readUByteC() == 1;
int i_0_ = rsbuffer_sub1.method2726(false);
if (i <= -61) {
int i_1_ = rsbuffer_sub1.method2717((byte) -15);
int i_2_ = rsbuffer_sub1.method2745((byte) -74);
Class132.method1560(-7593);
Class249_Sub4.method3283(i_1_, (byte) -127);
rsbuffer_sub1.method2752(false);
for (int i_3_ = 0; i_3_ < 4; i_3_++) {
for (int i_4_ = 0; Class85.regionParamX >> 3 > i_4_; i_4_++) {
for (int i_5_ = 0; (SubNode_Sub14.regionParamY >> 3 ^ 0xffffffff) < (i_5_ ^ 0xffffffff); i_5_++) {
int i_6_ = rsbuffer_sub1.method2754(4756, 1);
if (i_6_ == 1) {
Class325.anIntArrayArrayArray4086[i_3_][i_4_][i_5_] = rsbuffer_sub1.method2754(4756, 26);
} else {
Class325.anIntArrayArrayArray4086[i_3_][i_4_][i_5_] = -1;
}
}
}
}
rsbuffer_sub1.method2747(true);
int i_7_ = (Node_Sub29.aClass345_7615.anInt4275 + -rsbuffer_sub1.offset) / 16;
Class295.anIntArrayArray3672 = new int[i_7_][4];
for (int i_8_ = 0; i_8_ < i_7_; i_8_++) {
for (int i_9_ = 0; i_9_ < 4; i_9_++)
Class295.anIntArrayArray3672[i_8_][i_9_] = rsbuffer_sub1.readInt();
}
Class315.aByteArrayArray3975 = null;
EntityNode_Sub5_Sub2_Sub1.aByteArrayArray10315 = new byte[i_7_][];
SubNode_Sub2.aByteArrayArray9937 = new byte[i_7_][];
Class309.aByteArrayArray3855 = new byte[i_7_][];
RSCanvas.anIntArray75 = new int[i_7_];
Class205.anIntArray5086 = new int[i_7_];
Class199.anIntArray2538 = new int[i_7_];
Node_Sub27.anIntArray7575 = new int[i_7_];
Class315.aByteArrayArray3965 = new byte[i_7_][];
Class203_Sub1.anIntArray8541 = null;
Node_Sub38_Sub1.anIntArray9419 = new int[i_7_];
i_7_ = 0;
for (int i_10_ = 0; i_10_ < 4; i_10_++) {
for (int i_11_ = 0; i_11_ < Class85.regionParamX >> 3; i_11_++) {
for (int i_12_ = 0; (SubNode_Sub14.regionParamY >> 3 ^ 0xffffffff) < (i_12_ ^ 0xffffffff); i_12_++) {
int i_13_ = Class325.anIntArrayArrayArray4086[i_10_][i_11_][i_12_];
if (i_13_ != -1) {
int i_14_ = i_13_ >> 14 & 0x3ff;
int i_15_ = (i_13_ & 0x3ffd) >> 3;
int i_16_ = (i_14_ / 8 << 8) - -(i_15_ / 8);
for (int i_17_ = 0; (i_17_ ^ 0xffffffff) > (i_7_ ^ 0xffffffff); i_17_++) {
if (i_16_ == Class199.anIntArray2538[i_17_]) {
i_16_ = -1;
break;
}
}
if (i_16_ != -1) {
Class199.anIntArray2538[i_7_] = i_16_;
int xCalc = i_16_ >> 8 & 0xff;
int yCalc = 0xff & i_16_;
RSCanvas.anIntArray75[i_7_] = Node_Sub37.aDecompressor7751.method716("m" + xCalc + "_" + yCalc, (byte) 73);
Node_Sub38_Sub1.anIntArray9419[i_7_] = Node_Sub37.aDecompressor7751.method716("l" + xCalc + "_" + yCalc, (byte) 111);
Class205.anIntArray5086[i_7_] = Node_Sub37.aDecompressor7751.method716("um" + xCalc + "_" + yCalc, (byte) -124);
Node_Sub27.anIntArray7575[i_7_] = Node_Sub37.aDecompressor7751.method716("ul" + xCalc + "_" + yCalc, (byte) 104);
i_7_++;
}
}
}
}
}
Class152.sendMapRegion(-121, i_0_, forceSend, i_2_, 12);
}
}



Map Region 3: The 'unused' region
This map region actually confused the shit out of me until I started thinking of it on simpler terms. Do you all know of the 'animated' background. Now this is all based on assumptions but I believe this actually is calling data from this 'unused' map region data, and that is how you get the animated background.


Example Code:


static final void preloadingMapRegion() {
anInt1672++;
Class249_Sub4.method3283(Class4.aNode_Sub33_5291.a Class29_Sub6_7690.method327(-18033), (byte) -115);
int playerRegionX = (Node_Sub25.anInt7562 >> 12) + (Class147.anInt1911 >> 3);
int playerRegionY = (Class239_Sub1.anInt8042 >> 12) + (za_Sub2.anInt10224 >> 3);
Class141.anInt1862 = Class79.localPlayer.aByte5856 = (byte) 0;
Class79.localPlayer.method925((byte) -114, 8, 8);
int i_2_ = 18;
Class315.aByteArrayArray3965 = new byte[i_2_][];
Class315.aByteArrayArray3975 = new byte[i_2_][];
Node_Sub38_Sub1.anIntArray9419 = new int[i_2_];
SubNode_Sub2.aByteArrayArray9937 = new byte[i_2_][];
RSCanvas.anIntArray75 = new int[i_2_];
Class205.anIntArray5086 = new int[i_2_];
Class309.aByteArrayArray3855 = new byte[i_2_][];
Node_Sub27.anIntArray7575 = new int[i_2_];
Class199.anIntArray2538 = new int[i_2_];
EntityNode_Sub5_Sub2_Sub1.aByteArrayArray10315 = new byte[i_2_][];
Class203_Sub1.anIntArray8541 = new int[i_2_];
Class295.anIntArrayArray3672 = new int[i_2_][4];
i_2_ = 0;
for (int xCalc = (playerRegionX - (Class85.regionParamX >> 4 ))/ 8; (playerRegionX + (Class85.regionParamX >> 4)) / 8 >= xCalc; xCalc++) {
for (int yCalc = (playerRegionY - (SubNode_Sub14.regionParamY >> 4)) / 8; ((SubNode_Sub14.regionParamY >> 4) + playerRegionY) / 8 >= yCalc; yCalc++) {
int region = yCalc + (xCalc << 8);
Class199.anIntArray2538[i_2_] = region;
RSCanvas.anIntArray75[i_2_] = Node_Sub37.aDecompressor7751.method716("m" + xCalc + "_" + yCalc, (byte) -92);
Node_Sub38_Sub1.anIntArray9419[i_2_] = Node_Sub37.aDecompressor7751.method716("l" + xCalc + "_" + yCalc, (byte) 78);
Class203_Sub1.anIntArray8541[i_2_] = Node_Sub37.aDecompressor7751.method716("n" + xCalc + "_" + yCalc, (byte) -84);
Class205.anIntArray5086[i_2_] = Node_Sub37.aDecompressor7751.method716("um" + xCalc + "_" + yCalc, (byte) -91);
Node_Sub27.anIntArray7575[i_2_] = Node_Sub37.aDecompressor7751.method716("ul" + xCalc + "_" + yCalc, (byte) 58);
if ((Class203_Sub1.anIntArray8541[i_2_] ^ 0xffffffff) == 0) {
RSCanvas.anIntArray75[i_2_] = -1;
Node_Sub38_Sub1.anIntArray9419[i_2_] = -1;
Class205.anIntArray5086[i_2_] = -1;
Node_Sub27.anIntArray7575[i_2_] = -1;
}
i_2_++;
}
}
for (int i_7_ = i_2_; Class203_Sub1.anIntArray8541.length > i_7_; i_7_++) {
Class203_Sub1.anIntArray8541[i_7_] = -1;
RSCanvas.anIntArray75[i_7_] = -1;
Node_Sub38_Sub1.anIntArray9419[i_7_] = -1;
Class205.anIntArray5086[i_7_] = -1;
Node_Sub27.anIntArray7575[i_7_] = -1;
}
int i_8_;
if (Class155.anInt2050 == 3) {
i_8_ = 4;
} else if (Class155.anInt2050 == 9) {
i_8_ = 10;
} else if (Class155.anInt2050 == 7) {
i_8_ = 8;
} else {
throw new RuntimeException("");
}
Class152.sendMapRegion(-119, playerRegionY, false, playerRegionX, i_8_);
}



Now this mysterious 'fourth' region that we were predicting is actually just this:


if ((Class372.anInt4574 ^ 0xffffffff) == -1) {
int i_11_ = (Node_Sub43_Sub28.anInt9790 + -(Class85.regionParamX >> 4)) / 8;
int i_12_ = ((Class85.regionParamX >> 4) + Node_Sub43_Sub28.anInt9790) / 8;
int i_13_ = (Class4_Sub1.anInt8788 - (SubNode_Sub14.regionParamY >> 4)) / 8;
int i_14_ = ((SubNode_Sub14.regionParamY >> 4) + Class4_Sub1.anInt8788) / 8;
for (int xCalc = i_11_ + -1; 1 + i_12_ >= xCalc; xCalc++) {
for (int yCalc = -1 + i_13_; (yCalc ^ 0xffffffff) >= (1 + i_14_ ^ 0xffffffff); yCalc++) {
if ((xCalc ^ 0xffffffff) > (i_11_ ^ 0xffffffff) || (i_12_ ^ 0xffffffff) > (xCalc ^ 0xffffffff) || i_13_ > yCalc || (i_14_ ^ 0xffffffff) > (yCalc ^ 0xffffffff)) {
Node_Sub37.aDecompressor7751.method691("m" + xCalc + "_" + yCalc, (byte) 114);
Node_Sub37.aDecompressor7751.method691("l" + xCalc + "_" + yCalc, (byte) 96);
}
}
}
}



Which actually doesn't submit a region, so there for it can't be it's own map region configuration.


Correct me if I am wrong =)

dragonkk
July 21st, 2011, 09:44
Class203_Sub1.anIntArray8541[i_2_] = Node_Sub37.aDecompressor7751.method716("n" + xCalc + "_" + yCalc, (byte) -84);

Guess what, npc spawns there. lol thats where it gets container id.

aDecompressor7751 is index 5(maps inside). method716 is getContainerId(String name);

The 4th code there doesn't load anything, but will make map containers requested if they don't exist.

Edit:
Showme method691.

SiniSoul
July 21st, 2011, 09:46
Client auto loads the lumb area (48) and varrock as I said in the conversation. Now strangely enough the client is loading map data with out encryption keys which I never thought about much. I wonder how :/

Dkk we were talking about the packets, not how things loaded.

Emily
July 21st, 2011, 09:47
Class203_Sub1.anIntArray8541[i_2_] = Node_Sub37.aDecompressor7751.method716("n" + xCalc + "_" + yCalc, (byte) -84);

Guess what, npc spawns there. lol thats where it gets container id.

aDecompressor7751 is index 5(maps inside). method716 is getContainerId(String name);

So they are storing npc spawns inside the preLoading Region o.0 interesting :3



Client auto loads the lumb area (48) and varrock as I said in the conversation. Now strangely enough the client is loading map data with out encryption keys which I never thought about much. I wonder how :/


Yep, I wonder if there is any relevance between the regions shown in the animated client vs. the areas auto loaded.

dragonkk
July 21st, 2011, 09:49
So they are storing npc spawns inside the preLoading Region o.0 interesting :3





Yep, I wonder if there is any relevance between the regions shown in the animated client vs. the areas auto loaded.


Read where I edited, and where do you think i dumped my 1.5k perfect npc spawns from? And cache has also inform of which are walkable npcs and their respawns dirs.

dragonkk
July 21st, 2011, 09:50
And the maps for background never used xteas.... thats from the begin. xteas aren't needed, theyre optional, 0,0,0,0 will tell client not use them. Why do you think i never reelase 0,0,0,0 xteas on my xtea dumps.. .theyre default no encryption.

Emily
July 21st, 2011, 09:51
Read where I edited, and where do you think i dumped my 1.5k perfect npc spawns from? And cache has also inform of which are walkable npcs and their respawns dirs.



final void method691(String string, byte i) {
anInt833++;
if (method713(-1)) {
string = string.toLowerCase();
int i_58_ = aClass78_854.aClass363_998.method3957(Class153.met hod1699(-53, string), (byte) 100);
if (i > 88) {
method681((byte) 126, i_58_);
}
}
}


Those methods inside are:


final int method3957(int i, byte i_3_) {
anInt4449++;
if (i_3_ <= 23) {
method3957(-15, (byte) -29);
}
int i_4_ = -1 + (anIntArray4448.length >> 1);
int i_5_ = i_4_ & i;
for (;;) {
int i_6_ = anIntArray4448[1 + (i_5_ - -i_5_)];
if ((i_6_ ^ 0xffffffff) == 0) {
return -1;
}
if (anIntArray4448[i_5_ + i_5_] == i) {
return i_6_;
}
i_5_ = i_4_ & i_5_ - -1;
}
}




private final boolean method713(int i) {
anInt825++;
if (aClass78_854 == null) {
aClass78_854 = aClass136_852.method1577((byte) -40);
if (aClass78_854 == null) {
return false;
}
anObjectArray839 = new Object[aClass78_854.entryIndexCount];
anObjectArrayArray829 = new Object[aClass78_854.entryIndexCount][];
}
if (i != -1) {
anObjectArray839 = null;
}
return true;
}


Method681 is a dummy.

SiniSoul
July 21st, 2011, 09:51
So they are storing npc spawns inside the preLoading Region o.0 interesting :3



Yep, I wonder if there is any relevance between the regions shown in the animated client vs. the areas auto loaded.


l = landscape
n = nps
ul = underwater landscape

And that loop calculation is getting the amount of regions to load and the exact regions to load.

Emily
July 21st, 2011, 09:52
l = landscape
n = nps
ul = underwater landscape

And that loop calculation is getting the smount of regions to load and the exact regions to load.

But it's "m" not "n". o.0 Deobfuscation problem?

dragonkk
July 21st, 2011, 09:52
l = landscape
n = nps
ul = underwater landscape

And that loop calculation is getting the smount of regions to load and the exact regions to load.


for (int xCalc = i_11_ + -1; 1 + i_12_ >= xCalc; xCalc++) {
for (int yCalc = -1 + i_13_; (yCalc ^ 0xffffffff) >= (1 + i_14_ ^ 0xffffffff); yCalc++) {
if ((xCalc ^ 0xffffffff) > (i_11_ ^ 0xffffffff) || (i_12_ ^ 0xffffffff) > (xCalc ^ 0xffffffff) || i_13_ > yCalc || (i_14_ ^ 0xffffffff) > (yCalc ^ 0xffffffff)) {
Node_Sub37.aDecompressor7751.method691("m" + xCalc + "_" + yCalc, (byte) 114);
Node_Sub37.aDecompressor7751.method691("l" + xCalc + "_" + yCalc, (byte) 96);
}
}
}
}

As you see that code doesn't do anything exept request the map files. like a preload

SiniSoul
July 21st, 2011, 09:54
for (int xCalc = i_11_ + -1; 1 + i_12_ >= xCalc; xCalc++) {
for (int yCalc = -1 + i_13_; (yCalc ^ 0xffffffff) >= (1 + i_14_ ^ 0xffffffff); yCalc++) {
if ((xCalc ^ 0xffffffff) > (i_11_ ^ 0xffffffff) || (i_12_ ^ 0xffffffff) > (xCalc ^ 0xffffffff) || i_13_ > yCalc || (i_14_ ^ 0xffffffff) > (yCalc ^ 0xffffffff)) {
Node_Sub37.aDecompressor7751.method691("m" + xCalc + "_" + yCalc, (byte) 114);
Node_Sub37.aDecompressor7751.method691("l" + xCalc + "_" + yCalc, (byte) 96);
}
}
}
}

As you see that code doesn't do anything exept request the map files. like a preload

What he said, m is for map like erm...objects.

dragonkk
July 21st, 2011, 09:57
l - land objects (contains all objects data, this file may be encrypted with xteas)
m - map floors(contains all information about floor, example bridges, montains and that)
n - npc spawns (contains the map npc spawns, this file may be encrypted and may even not exist for most of maps)
ul - works like land objects but just 1height
um - works like map floors but just 1height

dragonkk
July 21st, 2011, 09:58
What he said, m is for map like erm...objects.

Dude that code is calling cache, probably checks if file exists and if not requests. it not loading anything to client and you can see it.

SiniSoul
July 21st, 2011, 09:59
l - land objects (contains all objects data, this file may be encrypted with xteas)
m - map floors(contains all information about floor, example bridges, montains and that)
n - npc spawns (contains the map npc spawns, this file may be encrypted and may even not exist for most of maps)
ul - works like land objects but just 1height
um - works like map floors but just 1height

What he said, now if we were to take a look st the origin of this system you would find it improved ten fold. X.x

Sry dkk gay iPad can't respond very well ik what u mean

dragonkk
July 21st, 2011, 10:01
What he said, now if we were to take a look st the origin of this system you would find it improved ten fold. X.x

Sry dkk gay iPad can't respond very well ik what u mean

And what do you mean? with origin of this system? btw ive before made client use ul and um only, it seems theyre like corrupted maps.. only 1height and some missing objects.

SiniSoul
July 21st, 2011, 10:02
And what do you mean? with origin of this system?

You aren't familiar with the MapLoader? Oh it's a bundle if joy.
4 types of objects n shiz, good times.

dragonkk
July 21st, 2011, 10:04
You aren't familiar with the MapLoader? Oh it's a bundle if joy.


Ofc I understand how load happens, both cache and map, and predraw. I just didn't understand what do you mean with origin of this system. you mean if rs copied any known map loader system?

SiniSoul
July 21st, 2011, 10:05
Ofc I understand how load happens, both cache and map, and predraw. I just didn't understand what do you mean with origin of this system. you mean if rs copied any known map loader system?

I'll explain when I wake up.

dragonkk
July 21st, 2011, 10:13
final void method691(String string, byte i) {
anInt833++;
if (method713(-1)) {
string = string.toLowerCase();
int i_58_ = aClass78_854.aClass363_998.method3957(Class153.met hod1699(-53, string), (byte) 100);
if (i > 88) {
method681((byte) 126, i_58_);
}
}
}


Those methods inside are:


final int method3957(int i, byte i_3_) {
anInt4449++;
if (i_3_ <= 23) {
method3957(-15, (byte) -29);
}
int i_4_ = -1 + (anIntArray4448.length >> 1);
int i_5_ = i_4_ & i;
for (;;) {
int i_6_ = anIntArray4448[1 + (i_5_ - -i_5_)];
if ((i_6_ ^ 0xffffffff) == 0) {
return -1;
}
if (anIntArray4448[i_5_ + i_5_] == i) {
return i_6_;
}
i_5_ = i_4_ & i_5_ - -1;
}
}




private final boolean method713(int i) {
anInt825++;
if (aClass78_854 == null) {
aClass78_854 = aClass136_852.method1577((byte) -40);
if (aClass78_854 == null) {
return false;
}
anObjectArray839 = new Object[aClass78_854.entryIndexCount];
anObjectArrayArray829 = new Object[aClass78_854.entryIndexCount][];
}
if (i != -1) {
anObjectArray839 = null;
}
return true;
}


Method681 is a dummy.

From what i see method681 can't be dummy. may you showme it?

Emily
July 21st, 2011, 10:16
From what i see method681 can't be dummy. may you showme it?

I read it as


i < 88


:L
5:14 am lol.

Becomes:


final void method691(String string) {
anInt833++;
if (method713()) {
string = string.toLowerCase();
int i_58_ = aClass78_854.aClass363_998.method3957(Class153.met hod1699(-53, string), (byte) 100);
method681(i_58_);
}
}

dragonkk
July 21st, 2011, 10:22
K code doesn't seem to do anything special.

teemuzz
July 23rd, 2011, 07:16
int i_58_ = aClass78_854.aClass363_998.method3957(Class153.met hod1699(-53, string), (byte) 100);
if (i > 88) {
method681((byte) 126, i_58_);

How is that a dummy :P

Emily
July 23rd, 2011, 07:18
int i_58_ = aClass78_854.aClass363_998.method3957(Class153.met hod1699(-53, string), (byte) 100);
if (i > 88) {
method681((byte) 126, i_58_);

How is that a dummy :P


Do you read comments?

teemuzz
July 28th, 2011, 19:23
Do you read comments? if (i > 88) {
is the dummy part. The method called isn't a dummy. also the preload isn't junk, it checks if the cache contains a file and if not request it.