[GUIDE] AlmostNoCooldown (limit rate of skills)

Hacking CABAL Online

Moderators: g3nuin3, SpeedWing, WhiteHat, mezzo

[GUIDE] AlmostNoCooldown (limit rate of skills)

Postby cobr_h » Tue Jan 04, 2011 9:32 am

If you follow my guide at http://www.memoryhacking.com/forums/viewtopic.php?f=32&t=8663&sid=a81c7eaff7d88789e57c9d423acbffb3, you will get bumped in an eye blink. That's cause just locking the value makes you resend the command (skill) as fast as your computer/bandwidth/whatever permits. Thus you get flooded quickly. What to do? 'Time' your skills. Too hard to time it, as a single keypress sends billion commands.

What can be done is set the lock to be updated only at a given time interval. Not possible via simple lock. Solution? Scripted locks.

Well, for that, I've used the 'Dash' skill. If you just lock, you can see you are not bumped off (dc'ed)!! But you can see your mana being drained like popcorn. No matter how quick you press the key, it just bugs. And also bugs server logs. Come on, we can get most from the hack and annoy the less the admins. ;) Also it makes harder to find our doing on the game...

Okay. Let's get into the scripted locks. Know that you apply the nocooldown hack not for a given skill but for a given sword or magic slot on your skill bar. Refer to my other guide at http://www.memoryhacking.com/forums/viewtopic.php?f=32&t=8663&sid=a81c7eaff7d88789e57c9d423acbffb3 for details on the NoCooldown procedure.

Once you have the correct entry in MHS, open it to modify, open the 'script lock' tab, and paste the code below
Code: Select all
int lasthit = 0;
VOID Lock(MHS_ADDRESS sAddress, INT iItemSize) {
extern float val = { "", sAddress };
extern float secval = { "", sAddress+0x8 };
int timenow=Time();
int forcetime=800; // 800ms
if (val && (lasthit > timenow ||
     lasthit < timenow-forcetime)) {
  lasthit=timenow;
  val=0;
  secval=0;
}
}


Mark the 'Use script to apply lock'.

For clarity, I defined the 'forcetime' variable, in milisseconds for how often to enforce the lock. Although it blindly writes 0 (shall calculate correct time in float and write it given the game's provided value), it just works, and does not spam the server, and the time (for the dash) is enough 0.5s to end one and apply the other. Maybe 0.8 is the perfect time for this skill as it takes 0.8 secs to be released.

Once you have the code in place and box checked, click 'Ok' to close the modify window, it will freeze for a moment (while it compiles the code you just 'wrote'), and then, when you lock the value (given you have the right address for the skill locking) voila, you will be dashing quick as wind! :) And your mana goes for every dash not once and for all. :)

This 'flood control' helps preventing DC on the guide from the links above. It just does make it not happen, just controls the spamming rate so it takes longer for you to take a DC. You may put a very short value (20ms) to avoid just a single keypress being sent a thousand times.
Last edited by cobr_h on Wed Jan 05, 2011 12:42 am, edited 2 times in total.
cobr_h
Acker
 
Posts: 72
Joined: Wed Dec 02, 2009 6:15 am

Re: [GUIDE] AlmostNoCooldown (limit rate of skills)

Postby cobr_h » Tue Jan 04, 2011 11:46 am

Okay, just a heads up: it seems that if you make up many entries in MHS (for example, one for each skill slot availble) and lock everything at once, you get a client crash. I enabled (one by one) two adjacent slots and three and it did not crash the game. I don't see anything else writing the address (that stays at 00 00 00 00) I store the time the skill was last used so, use this with care. :)
cobr_h
Acker
 
Posts: 72
Joined: Wed Dec 02, 2009 6:15 am

Re: [GUIDE] AlmostNoCooldown (limit rate of skills)

Postby cobr_h » Wed Jan 12, 2011 1:43 pm

It seems not many people is interested on this these days, anyway, I am enjoying studying the power of MHS and, while having a break of a Hooks stuff, I decided to improve my AlmostNoCooldown skill limit.

Note that this does not work on all skills well. Only some (low level/rank) skills and buffs accepts this blindly. For example, Art of Cure (if it is the right name of it) cools earlier, but you just can't use the skill until the cooldown time has reached. Seems server-sided but I have not tested deeply. Maybe the timer is just somewhere else. For Cure, buffs (for buffs its useless, noDelay suffices for buffs), sword and magic skills until maybe nv60 rank, they work. For attack skills, if you spam too much the same skill in too few seconds, you get booted off. You can spam cure as you wish but the actual cure comes only by ~0.8 to 0.8 secs. You can flood with dash and retreat as much as you like and your MP allows.

So, instead of one address for every skill slot, this time we will add a single address. You still have to find the main address. The main advantage is you don't need to change every address if the address shifts from one update to another. You are now allowed to right click and 'move selected' (which you couldn't on complex address -- at least I did not find out how). As before, you will add a script lock which is the script below. Remember you are no longer using complex address, so leave the box of complex address unchecked. We are using normal address and script lock.

To the script:
Code: Select all
int timenow=0;

// Reduce cooldown for this slot?
bool lock_slot[]={
// Sword slots
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0..15
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 16..31
// Magic slots
0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, // 0..15
0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0  // 16..31
};

// Reduce cooldown time by 'cd_reduce' seconds (one for each slot)
float cd_reduce[]= {
// sword
0.5, 0.5, 0.5, 0.5, //0..3
0.5, 0.5, 0.5, 0.5, //4..7
0.5, 0.5, 0.5, 0.5, //8..11
0.5, 0.5, 0.5, 0.5, //12..15
0.5, 0.5, 0.5, 0.5, //16..19
0.5, 0.5, 0.5, 0.5, //20..23
0.5, 0.5, 0.5, 0.5, //24..27
0.5, 0.5, 0.5, 0.5, //28..31
// magic
0.5, 0.5, 0.5, 1.5, //0..3
0.5, 0.5, 0.5, 0.5, //4..7
0.5, 0.5, 0.5, 0.5, //8..11
0.5, 0.5, 0.5, 0.5, //12..15
0.5, 0.5, 1.0, 0.5, //16..19
100.5, 0.5, 0.5, 0.5, //20..23
0.5, 0.5, 0.5, 0.5, //24..27
0.5, 0.5, 0.5, 0.5, //28..31
};

float lastused[]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

VOID Lock(MHS_ADDRESS address, INT ItemID) {
extern UINT_PTR slotsptr={"",address};
int time=Time();
int i=0;
if (time - timenow > 250) { // limit the rate to save CPU cycles
  timenow=time;
  for (i=0;i<64;i++) {
   if (lock_slot[i]) {
    lockSlotById(slotsptr,i);
   }
  }
}
}

VOID lockSlotById(UINT_PTR address, INT sid) {
extern UINT_PTR slotptr={"",address+(sid*4)};
UINT_PTR test;

//if (IsBadReadPtr((void *)slotptr, sizeof(DWORD))) return;
if (!slotptr) {
  PrintF("ERROR: coulnd't get a pointer to the desired skill slot!");
  return;
}
test=slotptr;
extern float cdvalue={"",slotptr+0x20};
extern float cdvaltwo={"",slotptr+0x28};
// Avoid catching multiple keypresses on one by waiting 250ms between triggers for a single cooldown
if (cdvalue-lastused[sid] > 0.250) {
  lastused[sid]=cdvalue;
  cdvalue-=cd_reduce[sid];
  cdvaltwo=cdvalue;
  PrintF("Applying lowCoolDown to %s skill on slot %i. Time reduced by %f secs.",(sid>31)?"magic":"sword",(sid>31)?sid-31:sid+1,cd_reduce[sid]);
} else if(cdvalue < lastused[sid])
  lastused[sid]=cdvalue;
}
// [[05A9B924]+(i*4)]+0x20


So, what we have here:
- lock_slot: there are 32 of each. 32 for sword skills and 32 for magic skills. You set '1' to the corresponding skill slot you wanna the cooldown 'faster' than normal.
- cd_reduce: there, you set by how many seconds you want the skill to cool faster. For example if it takes 3.2s to cooldown, you can put 1.2 seconds to make it cooldown as quick as 2 seconds (in average, you will see why later).
- lastused: this is just a control to avoid double-usages, specially if you have set the timer below too low. This makes it count a single skill usage by every 250ms. Before, it would just use the skill repeatedly both banning you faster and making you waste mana. This is initialized as 0, and might not be changed. It is updated as you use the skill. If you put arbitrary values here will not make anything faster, they will just be zeroed again.
- time - timenow > 250: here I've imposed a time limit (not the one I told above) to reduce cycles calculating pointers and checking the actual value of the cooldown. This value of 250ms is good enough to use the skills very fast. Yet, I valorize the connection keeping not the flooding and DC'ing.
- cdvalue-lastused[sid] > 0.250: almost in the end of the script there's another 0.250. This is the actual skill timer to avoid multiple skill usage. Maybe this has rendered useless due to the above timer but it is here shall you feel like you wanna let your CPU keep resolving those pointer addresses.
- Last, there's a PrintF. Why, if it can't be shown anywhere?.. Wrong. If you open the script editor in MHS, you will see the output and see the script working on your cooldown. If you don't want it, just comment it out, it makes no difference.

I thing the most CPU intensive change on the script you can make is changing the 'time-timenow > 250' (notice here we speak in milisseconds, on the other places, seconds, thus 0.250). If you make this like 'time-timenow > 1' or so, you might not be harmed in performance but you are truly wasting cpu cycles on calculations that would not change your 'gaming experience'.

Now, a question to L'Spiro or whom knows about it. I saw in a recent post about an unreal tournament hack (team hack) about using ::IsBadReadPtr() to check pointers' reachability. I just couldn't compile the script lock using it, and I believe the syntax and parameters are correct despite I did use a different casting syntax sugar (which worked among the script). Any light to why it does not work? I know the alternative I chosen does not guarantee MHS wouldn't crash but the fact I extracted the address via extern <blahblah> should help at least by giving a null pointer where I can't reach a memory address.

Have fun!
cobr_h
Acker
 
Posts: 72
Joined: Wed Dec 02, 2009 6:15 am

Re: [GUIDE] AlmostNoCooldown (limit rate of skills)

Postby L. Spiro » Wed Jan 12, 2011 1:52 pm

IsBadReadPtr() is a Windows® API function that provides a hacky way of testing memory.
It does not exist in MHS, nor does it need to exist.

You are checking memory outside of MHS, which is not the purpose of IsBadReadPtr() anyway.
MHS will never crash due to an invalid remote address on an extern. If the address is not value, as an expression, reading from it results in a return of 0.
Therefore you can assign any address to an extern and read/write safely.

If you need to know for-sure if an address is valid, use VirtualQueryEx().


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3126
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Re: [GUIDE] AlmostNoCooldown (limit rate of skills)

Postby cobr_h » Wed Jan 12, 2011 2:37 pm

I just crashed MHS a couple times while doing this script. I had to build that auxiliary function (lockSlotById()) just because I couldn't (at least not in plain c/c++) define 'extern type someting={...}' from inside a 'for' loop, and couldn't just 'extern type something;' outside the 'for' in order to later associate to it the desired address. I think I could have done this with something similar to ReadProcessMemory() but.. I think the overhead of the function call wouldn't kill anyone. :)

Thanks for the quick replies. I'm going to bed now, tomorrow I plan on studying more that stuff of hooks. The list of kernel functions seems pretty extensive yet tempting. Let's see how many more reboots I will have to do before I understand all this. :)
cobr_h
Acker
 
Posts: 72
Joined: Wed Dec 02, 2009 6:15 am


Return to CABAL Online

Who is online

Users browsing this forum: No registered users and 1 guest