Two Things

Gaming and Programming.. maybe programming for some games, who knows. Either way, I'm a geek, right?

Weapon Delay Mechanics, and QuickTime/HHE

Just in case we have any min/maxers that read this, I thought I'd share something that I've researched and seen in a few places but didn't see one handy table that satisfied my own curiosity, namely as it related to the effectiveness of my bard on melee performance.

NOTE: Smarter people than me on other forums figured this stuff out through extensive parsing of combat dummy testing over weeks and various weapon combinations and untold analysis of those parses. In other words, this is NOT my work. The chart at the end is mine, but it's just an assembly of other people's knowledge into a format that makes sense to me.

WEAPON DELAY MECHANICS

The EverQuest server runs combat in 128 slices of time per second. This is to keep the server from overloading its CPU I suppose. That means your weapon delay is run in increments of 0.0078125 of a second, rounded up to the next slice. Your 20 delay weapon (2 seconds) actually runs at 20.3125 (2.03125 seconds).

Your maximum haste (worn + spells) is capped at 100%.

Your maximum overhaste (v3) is capped at 25%.

There is an additional type of haste referred to as the Hundred Hands Effect, which directly lowers the delay of the weapon. Some disciplines and temporary buffs have HHE. It's like an over-over haste that ranges from 1-25% and is subtracted at the very end of the haste calculation.

For the mathematically inclined, the formula is:

DELAY = (WEAPON DELAY) / (100 + HASTE + OVERHASTE) AS A PERCENT (/100)] - [(WEAPON DELAY) * (HHE PERCENT)]

Example: 20 delay weapon, max haste, max overhaste, 5% HHE

DELAY = [(20) / (2.00 + .25)] - [(20 * 0.05)]
DELAY = (8.889) - (1)
DELAY = 7.889

Given the 1/128th slices of EQ combat time, the nearest delay would be 8.5938

The interesting effect of this slicing is that there are many cases where a slower weapon will hit at the exact same frequency as a faster weapon. Apparently there was a "myth" that there was no difference between a 18 and 19 delay weapon when maxed out on haste & overhaste. Similarly, a 20 and 21 delay weapon were mythed to be the same. The numbers back this up.  Myth confirmed?

The result of this allows you to use a slightly higher damage weapon (if you can find one) and suffer no penalty in speed - in effect have slightly better damage output.

There was no handy chart to look at this stuff, so I made one.

TL;DR: It may behoove you to find a slightly slower weapon if one is available.

[forcezoom]

LEGEND:

The EQ columns are the adjusted values to match the 1/128 combat slices of time.

QT = Quick Time (bard temp buff)
NAT FURY = Nature's Fury (beastlord temp buff)

-----------------------------------------------

HHE Reference (I may have missed a couple)

BER 30 GROUP: Battle Cry - 1%
BER 50 GROUP: War Cry - 2%
BER 57 GROUP: Battle Cry of Dravel - 3%
BER 64 GROUP: War Cry of Dravel - 4%
BER 65 GROUP: Battle Cry of Mastruq - 4%
BER 65 GROUP: Ancient: Cry of Chaos - 5%
BER 89 SELF DISC: Avenging Flurry - 8% / 9% / 11%
BER 70 SELF DISC: Vengeful Flurry - 6%

ROG 58 SELF DISC: Blinding Speed - 15%
ROG 73 SELF AA: Rogue's Fury - 5% All Ranks

CLR 65 SELF AA: Divine Avatar - 15% All Ranks

MNK 57 SELF DISC: Hundred Fists - 15%
MNK 63 SELF DISC: Speed Focus - 25%

BST 59 SELF AA: Frenzy of Spirit - 10% / 20% / 24%
BST 88 GROUP: Nature's Fury - 10% / 12% / 15%
BST 93 GROUP: Kolo's Fury - 15% All Ranks
BST 98 GROUP: Ruaabri's Fury - 15% All Ranks

BRD 78 GROUP AA: Quick Time - 2% / 3% / 4% / 5% / 6%

PAL 86 SELF AA: Valorous Rage - 5% / 10 % / 20%

BARD QUICKTIME AA

All of this tells me that for several delays of weaponry, Quick Time rank 1 (or any 2% HHE) does absolutely nothing if you're already at your haste cap:

15
17
19
21
24
26
28
35

And for these delays, Quick Time Rank 2 (or any 3% HHE) has no effect:

17
19
21

Looks like my bard needs at least rank 3 of QT to have an effect across the board.  Yay for needing level 91 before you're effective.

SOLUTION

Bard QT needs to start at 4% instead of 2%, and scale up to 10%.

UseItem and Timer

In a recent patch they added the ability to add your item clickies into a social through the command /useitem

Format: /useitem [slot] [sub slot]

Slot being either a worn inventory spot, or one of your bag spots. If it is a bag, the sub-slot comes into effect to pick which spot in the bag to activate.

Slot definitions:
0 = Charm
1 = Left Ear
2 = Head
3 = Face
4 = Right Ear
5 = Neck
6 = Shoulders
7 = Arms
8 = Back
9 = Left Wrist
10 = Right Wrist
11 = Range
12 = Hands
13 = Primary
14 = Secondary
15 = Left Ring
16 = Right Ring
17 = Chest
18 = Legs
19 = Feet
20 = Waist
21 = Power Source
22 = Ammo

23 = Bag Slot 1
24 = Bag Slot 2
25 = Bag Slot 3
26 = Bag Slot 4
27 = Bag Slot 5
28 = Bag Slot 6
29 = Bag Slot 7
30 = Bag Slot 8
31 = Bag Slot 9
32 = Bag Slot 10

Bags in your inventory are numbered going DOWN the left column first (1-5) and then down the right column (6-10). HOWEVER. Some UIs have bag 9 and 10 at the bottom since they were new additions, making this thoroughly confusing. You may have to put a clicky in the bag slot and experiment with /useitem 23-32 until you hit that one, then you'll know the bag #.

INSIDE your bag is a different story. The slots start at 0 and go up to 7 (if you have an 8 slot bag), and go LEFT-RIGHT then DOWN.

i.e. Inventory Bags:

1 6
2 7
3 8
4 9
5 10

OR - note where 9 & 10 are, entirely depending on your UI..

1 5
2 6
3 7
4 8
9 10


Inside a bag:

0 1
2 3
4 5
6 7

So if you wanted to click an item in your third bag down, in the last slot of an 8-slot bag:

/useitem 25 7

You can chain items with appropriate formatting of the social:

/pause 10, /useitem 1
/pause 10, /useitem 3
/pause 10, /useitem 5
/pause 33, /useitem 25 7
/timer 6000, /useitem 23 0

Remember: /pause will come AFTER the command following it when used in this way.

So this social will:

1. Click your Left Ear Item, then wait 1 second while that happens.
2. Click your Face Item, then wait 1 second while that happens.
3. Click your Neck Item, then wait 1 second while that happens.
4. Click the item in your 3rd bag, 8th slot, then wait 3.3 seconds while that happens.
5. Click the item in your 1st bag, 1st slot
6. Activate the button's cool-down overlay for 10 minutes.

/timer is new to me. Apparently you can use it to make your hotkey have a cool-down timer like other activated abilities.

If you set the /timer to equal the shortest duration buff you're getting from the clickies, you'll know when to click it again to rebuff yourself.

Also, the /pause should be slightly longer than the cast times of the items. If they are instant-cast, maybe /pause 5 (half a second). In the example above I assumed everything was a half-second cast time except the in-bag clickie which I chose to be a 3 second cast.

Remember also, /pause is similar to weapon delay in that 10 = 1 second.

Blockspells

Nothing is more annoying than sitting in the Guild Lobby on your melee class, soaking up buffs overnight, only to come back in the morning with a cursor full of crap.

You can apparently place some of the items in your house/yard and won't receive them anymore since they are marked Lore (mod rods, I'm looking at you), but some others you can't.  It's easiest to just block them and be done with it.

Here is my ongoing list of things to block.  As I find more, I'll edit the post.

 

/blockspell add me 2198 2199

Blocks "Blessing of the Harvest" and "Blessing of the Storm" .. aka MGB Food & Water


/blockspell add me 3188 2538 1503 10700 10765 36017 27467 29971 29896 14733 14677 26843 18744 26774

Blocks all mod rods.  I'm sure this isn't all of them either.


/blockspell add me 13121 9084

Blocks the "Party Mugs" that aren't very common (Fan Faire item) but still something extra to have to delete.

 

/blockspell add me 13 18272 18254

Blocks three inefficient cleric spells that your merc might use.  See this post for more on that.  For this you'll also want to /blockspell add pet as well

Accessing a Page Property from HTTPModule

This was some years ago so .NET might have changed so that there's a way to do this now.

Given a generic page with a public property defined in it:

public partial class TestPage: System.Web.UI.Page {
	string _hello = "test";
 	public string Hello { get { return _hello ;} set { _hello = value; } }
 	protected void Page_Load(object sender, EventArgs e) { }
}

Using a HTTPModule with an event hooked into Application_PreRequestHandlerExecute.  This will fail:

private void Application_PreRequestHandlerExecute(object source, EventArgs e) {
	HttpApplication application = (HttpApplication)source;
	IHttpHandler handler = application.Context.Handler;
	if (handler is Page) {
		string test = ((Page)handler).Hello; //this bombs out
	}
}

This will not:

private void Application_PreRequestHandlerExecute(object source, EventArgs e) {
	HttpApplication application = (HttpApplication)source;
	IHttpHandler handler = application.Context.Handler;
	if (handler is Page) {
		PropertyInfo checkHello = handler.GetType().BaseType.GetProperty("Hello");
		string test;
		if (checkHello != null) {
			test = checkHello.GetValue(handler, null).ToString();
		} 
	}
}

Another option might be to use a custom page type, but in this case it wasn't an option so Reflection won the day.

 

IIS Current Requests

As part of an ongoing IIS forensics to figure out why a website is spontaneously hanging for 1-3 minutes, I came across a command to show the in-process requests in IIS.  This information is supposedly in the IIS Management Console as well but a) it's not capturable easily, and b) it never seems to refresh for me.  So I put on my Clever Hat and decided to go old school and go to the command line.

cd %windir%/system32/inetsrv
appcmd list request

This lists out the current request queue.  I went one step further and created a .bat file to poll this command every 5 seconds, logging it to a text file.

:LOOP
@ECHO OFF
SET Now=%Time%
ECHO It's %Now% now
ECHO %Now% >> request.log
appcmd list request >> request.log
ping -n 6 127.0.0.1 >nul
goto :LOOP

The ping command acts as a sleep timer.  Windows ping command executes every second, so this is pinging localhost 6 times (5 seconds total), sent to NUL so I don't see it in the console, then loops around.

The output of the file is similar to this:

20:46:43.49
20:46:48.70
20:46:53.92
REQUEST "e600000180000137" (url:GET /home.asp, time:1216 msec, client:127.0.0.1, stage:ExecuteRequestHandler, module:IsapiModule)
REQUEST "d300000080000582" (url:GET /menu.asp, time:1216 msec, client:127.0.0.1, stage:ExecuteRequestHandler, module:IsapiModule)
20:46:58.12
20:47:03.32

Where nothing was queued when the first few polls happened, then there were 2 requests in process at 20:46:53.92.  It shows the internal IIS Request ID, what it was, the time (so far) that it's taken, the remote IP address, and where it is in the request process.  While the timestamp doesn't give millisecond precision, centiseconds are still pretty good to help narrow things down in other logs.  You can subtract the request time's milliseconds from the polling timestamp to figure out a rough starting place for the beginning time of the request.  There will be some precision errors since you're subtracting milliseconds from centiseconds, but you'll be very close.

Also, I'm polling every 5 seconds above, which is sorta overkill for this specific exercise.  If a request hangs for 1-3 minutes, a 30 second poll of this command is more than sufficient to catch it "in the act" and figure out which request is hanging the longest.  Most likely that's the one that will be the culprit for further analysis.

From here you could look at Failed Request Trace logs, Process Monitor, etc. to help narrow down the root cause of your problem.

IIS Log Timestamps.. Beginning? End?

I recently had the "opportunity" to do some forensics on a web server that was having errors.  During the course of the investigation I looked into the IIS Logfiles, and a question arose.  Does the timestamp inside the logfile represent the start of the request, the end of the request, the time it was written to the text file, what?

Microsoft documentation  states:

Date (date): the date on which the request occurred.
Time (time): the time, in Coordinated Universal Time (UTC), at which the request occurred.

But I got to thinking about this because of another item that is logged: time-taken

That is a very handy metric, but in this case it made me confused.  If the log timestamp was the beginning of the request as most seem to think, how can it possibly know how long it took to process?  Does IIS buffer its log entries and then insert them into the text file after the request has finished, figuring out where in the file it should insert?  The timestamps in the log are sequential, not out of order, so this lead me to think that perhaps the timestamp did not represent the beginning of the request.

I decided to run a test.  I wrote some ASP with a ScriptTimeout of 180 seconds, and put an endless loop in it so it would reach that timeout.  I ran it as close to 15:18:00 as I could.

Here's the log entry:

2013-06-04 15:21:15 ::1 GET /timeout.asp |-|ASP_0113|Script_timed_out 80 - ::1 (User Agent snipped) 500 0 0 194821

As you can see, the timestamp isn't 15:18:00, but rather 15:21:15.  Also notice the time-taken: 194821, or 194.8 seconds.  or 3 minutes, 14.8 seconds.  15:18:00 + 3 min 14.8 sec.. timestamp 15:21:15.  Coincidence?

Then I found this post by someone who worked at Microsoft which confirms my tested suspicion.  The timestamp is the time that it is inserted into the logfile itself, which is very shortly after the end of request.

If you want the beginning, subtract time-taken from the timestamp.  You'll have a margin of error though, as the IIS timestamp stops at seconds, and you're subtracting milliseconds.  Your margin of error will be up to 999ms.