Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 06-07-2012, 09:38 AM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default Test Results & Analysis

I ran a few tests and I believe that what I was saying about the default 'open' state is true, only in regards to server-side
code though. I don't believe the client is involved at all with the exception of a click event. I'm going to add some 'door check'
code to 'HandleClick' next, to handle the GFay lifts and see if that's successful. If it is, I'll work on a suggestion/code
submission for this. (Do you guys have a list of 'broken' doors that I can check with this test code on my server to determine
their operating states?)


For this test, I added 'sender->Message()' code at four points and moved the 'clientqueue' statement just below the door state/timer
conditional check instead of above it. I had to move it to get the status at this point since the packet is sent to the client
before this action occurs currently (code-wise.)

This is what the code move looks like:

Code:
// entity_list.QueueClients(sender, outapp, false); // unremark after test

if(!IsDoorOpen() || (opentype == 58))
{
	close_timer.Start();
	SetOpenState(true);
	[test code]
}
else
{
	close_timer.Disable();
	SetOpenState(false);
	[test code]
}

entity_list.QueueClients(sender, outapp, false); // delete after test
This is the [test code] that I used for the check:

Code:
if (isopen) {
	if (close_timer.Enabled()) {
		sender->Message(4, "[<testpoint>] door:%i-><action>(ds:O|ti:E)", door_id);
	}
	else {
		sender->Message(4, "[<testpoint>] door:%i-><action>(ds:O|ti:D)", door_id);
	}
}
else {
	if (close_timer.Enabled()) {
		sender->Message(4, "[<testpoint>] door:%i-><action>(ds:C|ti:E)", door_id);
	}
	else {
		sender->Message(4, "[<testpoint>] door:%i-><action>(ds:C|ti:D)", door_id);
	}
}
I was running into issues crashing the zone and created the above [test code] before I realized that my string was too long. I just
left it in place since it worked, but this is an untested line that could probably be used instead (if it works...):

Code:
sender->Message(4, "[<testpoint>] door:%i-><action>(ds:%s|ti:%s)", door_id, ! isopen ? "O" : "C", ! close_timer.Enabled() ? "E" : "D");
In the above code:

<testpoint> is where in the code the test originates
"enter" - code inserted just before the LDoN door check
"1/255" - code inserted inside of triggered door check, after 'md->action = <action>'
"0/0" - code inserted inside of unlocked door check, after 'md->action = <action>'
"exit" - code inserted inside of SetOpenState([t/f])/close_timer.[e/d] code, after command lines

"door:%i" is the current value of 'door_id'

<action> is what the major action is near where the test originates
"start" - no 'door processing' has occurred
"open" - after line 'md->action = OPEN_DOOR'
"close" - after line 'md->action = CLOSE_DOOR'
"queue" - last action performed before packet queued to client

"ds:%s" is the door state value from 'isopen' [O|C] ("O" is open [t], "C" is closed [f])

"ti:%s" is the 'close_timer' enabled state [E|D] ("E" is enabled [t], "D" is disabled [f])


Now to what I'm sure you've been wait for... The results!

I tried this test on all of the lower lift actuators at Kelethin with the same results, and the inner/bottom lift in Crescent Reach
proper. At least one minute was allowed to pass before performing each GFay lift check. (They're different, yes, but they're also
the same..read the analysis below to find out why.)


Code:
(CRESCENT - DOOR 1, ONE-CLICK, LIFT ACTIVATED)+++
<Click 1>
[enter] door:10->start(ds:C|ti:D)  [line 1]
[0/0] door:10->open(ds:C|ti:D)     [line 2]
[exit] door:10->queue(ds:O|ti:E)   [line 3]
[enter] door:1->start(ds:C|ti:D)   [line 4]
[1/255] door:1->open(ds:C|ti:D)    [line 5]
[0/0] door:1->open(ds:C|ti:D)      [line 6]
[exit] door:1->queue(ds:O|ti:E)    [line 7]


(GFAY - DOOR 80, ONE-CLICK, NO LIFT ACTIVATION)---
<Click 1>
[enter] door:81->start(ds:C|ti:D)  [line 8]
[0/0] door:81->open(ds:C|ti:D)     [line 9]
[exit] door:81->queue(ds:O|ti:E)   [line 10]
[enter] door:80->start(ds:C|ti:D)  [line 11]
[0/0] door:80->open(ds:C|ti:D)     [line 12]
[exit] door:80->queue(ds:O|ti:E )  [line 13]

(GFAY - DOOR 80, TWO-CLICKS, NO LIFT ACTIVATION)---
<Click 1>
[enter] door:81->start(ds:C|ti:D)  [line 14]
[0/0] door:81->open(ds:C|ti:D)     [line 15]
[exit] door:81->queue(ds:O|ti:E)   [line 16]
[enter] door:80->start(ds:C|ti:D)  [line 17]
[0/0] door:80->open(ds:C|ti:D)     [line 18]
[exit] door:80->queue(ds:O|ti:E)   [line 19]

<Click 2>
[enter] door:81->start(ds:O|ti:E)  [line 20]
[0/0] door:81->close(ds:O|ti:E)    [line 21]
[exit] door:81->queue(ds:C|ti:D)   [line 22]

(GFAY - DOOR 80, THREE-CLICKS, LIFT ACTIVATED)+++
<Click 1>
[enter] door:81->start(ds:C|ti:D)  [line 23]
[0/0] door:81->open(ds:C|ti:D)     [line 24]
[exit] door:81->queue(ds:O|ti:E)   [line 25]
[enter] door:80->start(ds:C|ti:D)  [line 26]
[0/0] door:80->open(ds:C|ti:D)     [line 27]
[exit] door:80->queue(ds:O|ti:E)   [line 28]

<Click 2>
[enter] door:81->start(ds:O|ti:E)  [line 29]
[0/0] door:81->close(ds:O|ti:E)    [line 30]
[exit] door:81->queue(ds:C|ti:D)   [line 31]

<Click 3>
[enter] door:81->start(ds:C|ti:D)  [line 32]
[0/0] door:81->open(ds:C|ti:D)     [line 33]
[exit] door:81->queue(ds:O|ti:E)   [line 34]
[enter] door:80->start(ds:O|ti:E)  [line 35]
[0/0] door:80->close(ds:O|ti:E)    [line 36]
[exit] door:80->queue(ds:C|ti:D)   [line 37]

If you notice in the 'Crescent' test, this is how a triggered door should operate. Line 3 shows where the status has changed on
the actuator. Line 6 shows an apparent 'double-true' condition, but end result is not affected. (If the gm flag was set, I think
you could actually get a 'triple-true' condition..but again the end result is not affected.) Line 7 is the actual state change
that shows the lift (door 1) has activated. (Lines 5 and 6 both perform the same action, but one just overwrites the other before
the command is pushed to the client. That occurs after the [exit] <testpoint>.)

In the 'Greater Fay' test series, I believe that I can prove my theory about what is causing the 'wacky' lift performance.
Obviously, Line 12 of the first test shows the 'open' client action with current states of [closed|disabled]. Line 13 shows that
the server thinks the door is now open.

In the second test, lines 14 to 19 are the same as in the first test. With <Click 2>, door 81 (the actuator) shows that it is
currently [open|enabled]. But, what happened to the response from door 80? Line 19 answers that. It is set to an open state.
When the code processes door 80 during the second click, no !IsDoorOpen() conditional code is processed. And because my test code
is located exclusively inside of closed door checks, it never get processed.

With the third test... This is where it gets interesting. Lines 23 to 31 are the same results as in the 'two-click' test. Notice
how the states in <Click 1> show the same states at the corresponding <testpoints> in each door? Now notice how <Click 2> shows
that door 81 has flipped all of its states.

So, why does the lift work on the third click? Thank you <Click 2>! It changed the state of door 81, but not door 80 because it
was not an 'open' request. <Click 2> was processing a close request for door 81 and door 80's states were not changed. Now, with
<Click 3>, the door (lift) is in a state to be lowered. As door 81 'opens', it triggers door 80 again, as it did in <Click 1>.
This time, however, door 80 is in an 'open' state and the conditional checks tell the door to close 'md->action = CLOSE_DOOR').
And, voila! The lift now comes down and the states are reset to the original resting state in line 37 (unless you played with the
acutator and messed up the states.)

The close_timer event handler might normally allow the lift to actually come down after 5 seconds, but the hidden processing in
<Click 2> is seeing that the door is open and doesn't seem to mark the door as closed server-side and send the 'CLOSE_DOOR'
event to the client, or it is not being triggered at all.


The problem: Greater Faydark lifts are in a default state of 'Open' and a 'md->action = CLOSE_DOOR' is required to make them work.


Now that we can see what is causing the problem, how do we fix it? I have a few ideas, but I'm still working on that...


U
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #2  
Old 06-08-2012, 08:04 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default One-click GFay lifts: Check (maybe)

I fixed my mistake in the test code. My c++ ignorance was showing..I mistakingly used '!' as 'If' in the single line conditional.
(I know that it's the 'not' operator, !duh, err, duh!.) Test code now shows proper state, and I added some additional 'value' reports.


I can operate the GFay lifts with one click now, and they can be ridden as well. There's still something in the code causing state
conflict on the 'triggered' actions, but I'm looking at that now. This problem may be what was causing that erratic behavior that
you saw Stonehive Trev...

(Are these calls thread-safe?)

In addition, I was using the melee key to insert 'click' separators at one point and got some very strange report for door_id. (This
was before I added the 'fix' code.) It reported the value of door_id as some 8~12 digit number on some iterations. I didn't write it
down, but it definitely exceeded the door_id range and even the 'door' table ID range. Haven't seen it since fix added though.

(I'll check as many different door types as I can before I submit the code.)


This is going to end up being a bug. Should I bump this conversation to 'bug report' or to 'code submission'?

(pre-p.s. Cave_Dude, GFaydark door 78 (orc-top) is set to invert_state = 1. Can you look into setting it to '0' for published peq, like
the other actuators for GFay lifts? Lifts themselves need to stay '1' though.)


U
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 07:57 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3