ISXEQ Crash on Zoning
Posted: Mon Mar 03, 2008 8:52 am
Download the source here.
Hey, everybody. The goal of my post here is to be informative as well as help resolve the issue. The problem is ISXEQ crashing very easily whenever you zone. I am going to provide some very simple examples that you can use to re-create the crashes. The code that I am providing will directly access ISXEQ with no wrapping, so forgive the lengthy lines. I find that it helps to strip everything down to its roots when you're trying to figure out stuff like this, anyways.
Example 1
Ok, so here is the first example. It is very simple. We are only retrieving 2 values using IS. It would seem that the code is well behaved because it verifies that the lavish objects are valid before accessing them, but you will find out later that this is not the case.
You can end the macro in game by doing a /cry which is what I feel like doing sometimes.
I have not been able to make example 1 crash ISXEQ while zoning, but it seems that if you go any farther than a hello world you need to be very meticulous and careful how you interact with ISXEQ or you will get the game window replaced with a notepad full of crash barf.
Example 2
Now we are going to start crashing the client. Let's just add a simple for loop in 2 places and zone some to see what happens.
For my testing the first zone crashed the .NET program, but IS was able to capture it and just echo the crash info in the console. The second zone crashed the game entirely. Just a subtle change in code made this example completely unstable.
Example 3
Here is another way to crash ISXEQ that I've found while zoning. Let's go back to example 1, but access the disk a little.
This example crashes the game on the first zone.
Conclusion
All of this could be avoided if there were a reliable way to know when you are zoning. Unfortunately I haven't been able to find one. Nothing that I've tried causes a crash unless you zone. When that happens even a try { } catch { } block won't save you, because it is ISXEQ crashing and not your program.
If anyone knows how to work around this issue, please chime in. I will post a solution here if I can find one.
Hey, everybody. The goal of my post here is to be informative as well as help resolve the issue. The problem is ISXEQ crashing very easily whenever you zone. I am going to provide some very simple examples that you can use to re-create the crashes. The code that I am providing will directly access ISXEQ with no wrapping, so forgive the lengthy lines. I find that it helps to strip everything down to its roots when you're trying to figure out stuff like this, anyways.
Example 1
Ok, so here is the first example. It is very simple. We are only retrieving 2 values using IS. It would seem that the code is well behaved because it verifies that the lavish objects are valid before accessing them, but you will find out later that this is not the case.
You can end the macro in game by doing a /cry which is what I feel like doing sometimes.
Code: Select all
static void Main()
{
const int emote_cry = 28, emote_cry2 = 162;
int myAnimation = 0;
IS.Echo("Crasher loaded.");
do
{
using (new FrameLock(true))
{
LavishScriptObject obj = LavishScript.Objects.GetObject("Me");
if (obj.IsValid)
myAnimation = obj.GetMember<int>("Animation");
obj = null;
obj = LavishScript.Objects.GetObject("NearestSpawn", "pc", "radius", "400");
if (obj.IsValid)
obj.GetMember<int>("ID");
obj = null;
}
Frame.Wait(false);
} while (myAnimation != emote_cry && myAnimation != emote_cry2);
IS.Echo("Crasher exiting.");
}Example 2
Now we are going to start crashing the client. Let's just add a simple for loop in 2 places and zone some to see what happens.
Code: Select all
static void Main()
{
const int emote_cry = 28, emote_cry2 = 162;
int myAnimation = 0, y = 0;
IS.Echo("Crasher loaded.");
do
{
using (new FrameLock(true))
{
LavishScriptObject obj = LavishScript.Objects.GetObject("Me");
for (int i = 0; i < 4000; i++) y = i; //<-- New line
if (obj.IsValid)
myAnimation = obj.GetMember<int>("Animation");
obj = null;
obj = LavishScript.Objects.GetObject("NearestSpawn", "pc", "radius", "400");
for (int i = 0; i < 4000; i++) y = i; //<-- New line
if (obj.IsValid)
obj.GetMember<int>("ID");
obj = null;
}
Frame.Wait(false);
} while (myAnimation != emote_cry && myAnimation != emote_cry2);
IS.Echo("Crasher exiting.");
}Example 3
Here is another way to crash ISXEQ that I've found while zoning. Let's go back to example 1, but access the disk a little.
Code: Select all
static void Main()
{
const int emote_cry = 28, emote_cry2 = 162;
int myAnimation = 0;
string s = "";
IS.Echo("Crasher loaded.");
do
{
using (new FrameLock(true))
{
LavishScriptObject obj = LavishScript.Objects.GetObject("Me");
if (obj.IsValid)
myAnimation = obj.GetMember<int>("Animation");
obj = null;
obj = LavishScript.Objects.GetObject("NearestSpawn", "pc", "radius", "400");
if (obj.IsValid)
obj.GetMember<int>("ID");
obj = null;
obj = LavishScript.Objects.GetObject("MacroQuest");
if (obj.IsValid)
s = obj.GetMember<string>("GameState");
else
s = "NOT VALID";
}
DebugLogger(s);
Frame.Wait(false);
} while (myAnimation != emote_cry && myAnimation != emote_cry2);
IS.Echo("Crasher exiting.");
}
public static void DebugLogger(string msg)
{
FileStream file = new FileStream("c:\\debug.txt", FileMode.Append);
StreamWriter sw = new StreamWriter(file);
sw.WriteLine(msg);
sw.Close();
file.Close();
}Conclusion
All of this could be avoided if there were a reliable way to know when you are zoning. Unfortunately I haven't been able to find one. Nothing that I've tried causes a crash unless you zone. When that happens even a try { } catch { } block won't save you, because it is ISXEQ crashing and not your program.
If anyone knows how to work around this issue, please chime in. I will post a solution here if I can find one.