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.

