.NET What am I doing wrong?

Moderator: MacroQuest Developers

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

.NET What am I doing wrong?

Post by Burrick » Thu Aug 16, 2012 1:22 am

I am having some difficulty with ISXEQ.NET, contained in the latest Macroquest download. 20120804.

Am I correct in assuming that the "Lavish.InnerSpace.dll" I need to reference is the one located in the InnerSpace "root" folder?

A number of calls in the source code are to "LavishScriptAPI.LavishScript.Objects.GetPersistentObject" as well as "LavishScriptAPI.LavishScriptPersistentObject".

Neither of these two functions exist in the Lavish dll!. Is there another version of this DLL I need to have? I changed all of the GetPersistentObjects to GetObjects, and recompiled ISXEQ.NET with no errors.

I then created a .NET executable which was to connect to my character, and echo the name, and a few stats.

I managed to load the application ("plugin?") in Innerspace. It ran automatically and I did see the text echo'd in the console window. However the plugin did NOT connect to my character and all the data was empty.

I used the code described by "blue" from several years ago.

the code EQMe myGuy = new EQMe() obviously did not actually connect to my character, so am curious as to what I have done wrong.

Thanks for any help ... assuming anyone reads this forum anymore.

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

Re: .NET What am I doing wrong?

Post by Burrick » Sun Aug 19, 2012 4:58 pm

How's that old saying go? God helps those that help themselves?

I originally referenced a post named "Accessing EQ objects from C# code in .NET". This was posted by "Blue" approx 5 years ago. He too was looking for some advice on how to communicate with Everquest using a dot net application.

The gist of it was, that he had written a few lines of code to perform a simple task. It inspired me to try my hand at it. I created an application, included the code I extracted from his post and it failed. I did get the strings I "echoed" but I did not connect to my character nor any mob in game.

The task at hand is described in the code below.

Code: Select all

     class EqWrapper
    {
        static void Main(string[] args)
        {
            using (new FrameLock(true))
            {
                EqMe myGuy = new EqMe();
                IS.Echo("Name: " + myGuy.Name);
                IS.Echo("Loc: " + myGuy.Y.ToString("F") + "," + myGuy.X.ToString("F") + "," + myGuy.Z.ToString("F"));
                IS.Echo("Level: " + myGuy.Level.ToString("D"));
                if (myGuy.Levitating) IS.Echo("Woah I seem to be flying!");
                EqSpawn aMob = new EqSpawn("npc");
                IS.Echo("aMob type: " + aMob.Type);
                IS.Echo("Nearest MOB: " + aMob.Name);
                aMob.Target();
                aMob.Face();
                LS.ExecuteCommand("cast Rend");
            }
        }
    }
There was a lot more code than that of course. For one he had to create wrappers for the Top Level Objects that he referenced. In the end I used these lines of code, and the ISXEQ.Net.dll (source provided with Macroquest download), and the "ISXEQ.DLL (source also provided with Macroquest download). Low and behold ... it worked. (sort of .. there were a few glitches)

The next several posts describe how I got to the point where I ran "dotnet ddbot" and killed a rat. (ddbot is what I named my dot net executable)
Last edited by Burrick on Sun Aug 19, 2012 7:39 pm, edited 1 time in total.

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

Re: .NET What am I doing wrong?

Post by Burrick » Sun Aug 19, 2012 6:12 pm

Step 1. Gather your tools.

I use Visual Studo 2010, professional. Service Pack 1.
I downloaded the latest ISXBoxer Bundle and installed it, which also installed Innerspace.
I downloaded and installed the ISXDK. (There are header files and library files that are required)
I downloaded and unzipped the latest Macroquest source code. MQ2-20120817 at the moment.

One thing I didn't realize when I first attempted this, was that I still needed to compile ISXEQ and load it as an extension, otherwise the dotnet applcation didn't do anything.

Step 2. Compile ISXEQ
I opened the ISXEQ.SLN file located in the root of the Macroquest folder. The solution was created in a previous version of VS or perhaps with a different IDE. Either way Visual Studio converted everything as required.

Before I could compile the code I had to point to the header and library files. To do this I selected "ISXEQ" (which is also the "Startup Project"). Then clicked on the "View" menu item and selected "Property Pages" at the bottom of the menu.

I expanded the "Configuration Properties" and selected "VC++ Directores". I selected the "Include Directores" and added the location of the ISXDK include folder. I chose to install it in the "Innerspace" folder, so on my workstation this path equated to.
"c:\Program Files (x86)\InnerSpace\ISXDK\32\include".

I repeated the process for the "Library Directores" and added the following path.
"c:\Program Files (x86)\InnerSpace\ISXDK\32\lib\vs10".

Note: I read somewhere that you could set these at a "solution level" but I could not find a way to do that. So in the end I had to repeat this process with every project within the solution. At least every project I chose to include in the compile.

I chose to compile ISXEQ (of course) and the following projects.
ISXEQChat
ISXEQCustomBinds
ISXEQEQIM
ISXEQItemDisplay
ISXEQLabels
ISXEQTelnet
ISXEQTemplate (had errors)

I compiled ISXEQ First, then ued Batch Build to select and build the remainder of the projects.

Two of the projects had errors that I didn't know how to deal with so I left them out of the compile. One other had an error that I think I fixed, so it was included.

errors:
ISXEQChatWnd
error C2065: 'Show' : undeclared identifier Line 114 ISXEQChatWnd
The next three errors reference this error.
error C2039: 'Show' : is not a member of 'CMQChatWnd' Line 283 ISXEQChatWnd
This is repeated for lines 318 and 366.

I have no idea where this variable should be declared, nor what value it should be set to. (0 i am guessing). Either way, since I have an ISXEQChat, I figured I don't need an ISXEQChatWnd, so I didn't compile it.

ISXEQTemplate
error C2660: 'ISLavishScriptInterface::GetArgs' : function does not take 4 arguments Line 427 ISXEQTemplate

Code: Select all

char FullText[8192]={0};
pISInterface->GetArgs(1,argc,argv,FullText); // this gets the rest of the arguments, from 1 to argc
The Reason I include line 426, is that the "5th" argument is an unsigned integer indicating buffer length. Since FullText was defined in line 426, I changed the code to.

Code: Select all

pISInterface->GetArgs(1,argc,argv,FullText,8192);
This resolved the error. (I don't know if it fixed it, but it resolved it).

ISXEQMAP
unresolved external symbol "void __cdecl CMyMapViewWnd__HandleRButtonDown(unsigned long,unsigned long)" (?CMyMapViewWnd__HandleRButtonDown@@YAXKK@Z) referenced in function "public: virtual bool __thiscall ISXEQMap::Initialize(class ISInterface *)" (?Initialize@ISXEQMap@@UAE_NPAVISInterface@@@Z)

I took one look at this error, and shrugged my shoulders. I hope I don't miss having ISXEQMap.

Step 3. Once the ISXEQ projects have been compiled they are placed in the "Release" sub folder contained in the "MacroQuest" main folder.
Copy DLL's ISXEQ.DLL, ISXEQChat.DLL ... etc... to the innerspace "extensions" folder. On my workstation that would be.
"c:\Program Files (x86)\InnerSpace\Extensions"

NOTE: The release folder is also where the Macroquest2 executable and DLL's will be (if you chose to compile the). They should not be relevent to this excersize though.

Anyone who knows better, please correct me at any point in this disertation, so that I and anyone else who might be interested can do it the right way.

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

Re: .NET What am I doing wrong?

Post by Burrick » Sun Aug 19, 2012 7:37 pm

Step 4. Compile ISXEQ.NET.dll

Your dot net application needs to be able to access Top Level Objects, such as your character, and all the properties that come with it such as name, ID, class etc...
If you examined the code I mentioned earlier that was posted by "Blue" you will see that he included a number of classes and methods within these classes to obtain access to these objects. My first attempt I copied his code outright and used it.

However, someone has gone to the effort of creating a wrapper that does exactly what you need. It is written in C# (which is what got me going on this in the first place). If you have been following the steps you will have downloaded the latest version of Macroquest source and unzipped it. In the main Macroquest folder (named MQ2-20120817, if you didn't bother renaming it.) There you will find a sub folder named ISXEQ.NET.

I clicked on the ISXEQ.NET.csproj file contained within the folder, as there was no solution file. This too needed to be convereted for Visual Studio 2010, implying it was created in an earlier version. A solution file was created and saved to the folder.

The project needs to reference the Lavish.InnerSpace DLL. The first time I accessed this project this reference could not be found, I had to locate it within the innerspace root folder. However when I (properly) reinstalled innerspace the DLL was registered with windows, and was found. If everything is properly installed it should be located in "c:\Windows\assembly\GAC_MSIL\Lavish.InnerSpace\1.0.0.0_9029a3ab4cbe108d\Lavish.InnerSpace.dll". The locattion could be different from yours, as I have Windows 7 as my operationg system. The numbers will likely differ as well (in the future), based on the version of Innerspace. Regardless, the project found the DLL on its own and I did not have to locate it. It also exists in the Innnerspace root folder as mentioned earlier.

There is one more thing you need to do before you can compile this project. The code has a number of references to the following methods.

LavishScriptAPI.LavishScript.Objects.GetPersistentObject
LavishScriptAPI.LavishScriptPersistenObject
GetPersistentMember

These methods DO NOT EXIST in the Lavish.InnerSpace.DLL. They may have once, when this code was first created, but I suspect that nobody has updated this for some time, with the onus being on keeping MacroQuest and the basic ISXEQ information up to date. I noticed that the Lavishware WIKI contains these objects but, like I said they don't exist.

I changed them as follows.

LavishScript.LavishScript.Objects.GetObject
LavishScriptAPI.LavishScriptObject
GetMember

I then compiled the DLL. In this case you can simply compile the solution, as there is only one project with multiple classes as opposed to multiple projects in a single solution.

You will reference this DLL in your dot net code. It can stay in the debug or release folder it was created in.

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

Re: .NET What am I doing wrong?

Post by Burrick » Sun Aug 19, 2012 8:18 pm

Step 5. Create a dot net application.

I won't go into too much detail here. It is assumed that you have some ability and interest in programming in C#.

The project must reference the Lavish.InnerSpace.DLL, as mentioned in Step 4.

Original Code

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Threading;
using InnerSpaceAPI;
using LavishVMAPI;
using IS = InnerSpaceAPI.InnerSpace;
using LS = LavishScriptAPI.LavishScript;


// This is an experiment to understand how to access ISXEQ Top Level Objects from .NET.
// It's a console app that should display a few stats about your character and a nearby MOB on the InnerSpace console.
// If you happen to be a baby Wizard, it will also cast a baby nuke on said MOB, so don't test it in the wrong zone.
// To run it, so far I am feeding the IS dotnet command the full line of text that gacutil creates.  For example,
// at the InnerSpace console I type:
// dotnet "ISXBasicAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=48f786b573cdbb7f, processorArchitecture=MSIL"
// There has to be a better way to do this, but it works for now.
// 
// To set this up in VS2005, follow the instructions in 
// http://www.lavishsoft.com/wiki/index.php/NET:Tutorials:HelloWorld


namespace ISXEQWrapper
{
    class EqWrapper
    {
        static void Main(string[] args)
        {
            using (new FrameLock(true))
            {
                EqMe myGuy = new EqMe();
                IS.Echo("Name: " + myGuy.Name);
                IS.Echo("Loc: " + myGuy.Y.ToString("F") + "," + myGuy.X.ToString("F") + "," + myGuy.Z.ToString("F"));
                IS.Echo("Level: " + myGuy.Level.ToString("D"));
                if (myGuy.Levitating) IS.Echo("Woah I seem to be flying!");
                EqSpawn aMob = new EqSpawn("npc");
                IS.Echo("aMob type: " + aMob.Type);
                IS.Echo("Nearest MOB: " + aMob.Name);
                aMob.Target();
                aMob.Face();
                LS.ExecuteCommand("cast Rend");
            }
        }
    }
That, and a whole whack of classes such as EQMe and EQSpawn. This code was replaced with the ISXEQ.NET.dll as explained in step 4.

The exceptions in my code is adding a reference to the "ISXEQ.NET.dll" that was created in step 4. Because of that I had to make slight changes when instantiating objects.

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Threading;
using InnerSpaceAPI;
using LavishVMAPI;
using IS = InnerSpaceAPI.InnerSpace;
using LS = LavishScriptAPI.LavishScript;
using IX = ISXEQ.EQTypes;

namespace ISXEQWrapper
{
    class EqWrapper
   {
      static void Main(string[] args)
      {
         using (new FrameLock(true))
         {
            IX.EQCharacter myGuy = new IX.EQCharacter();
            IS.Echo("Name: " + myGuy.Name);
            IS.Echo("Loc: " + myGuy.Y.ToString("F") + "," + myGuy.X.ToString("F") + "," + myGuy.Z.ToString("F"));
            IS.Echo("Level: " + myGuy.Level.ToString("D"));
            if (myGuy.Levitating) IS.Echo("Woah I seem to be flying!");
            [b]IX.EQSpawn aMob = new IX.EQSpawn("npc");[/b]
            IS.Echo("aMob type: " + aMob.Type);
            IS.Echo("Nearest MOB: " + aMob.Name);
            aMob.Target();
            aMob.Face();
            LS.ExecuteCommandEx("cast","Disease Cloud");
         }
      }
   }
}
Note the differences in our code. The ISXEQ.Types being "used" is from the ISXEQ.NET.dll, which requires me to change how I instantiate an object, otherwise the code is identical.

One other difference is that the ExecuteCommand("cast rend") did nothing. When I changed it to ExecuteCommandEx("cast", "spellname"), it then worked.

Step 6.
Once compiled you need to copy this executable to the innerspace ".NET Programs" folder. I simplified this process by having Visual Studio output to that folder bypassing the need to copy it everytime I made a change.

Copy or output "ddbot.exe" (my dot net application) to (on my workstation) "c:\Program Files (x86)\InnerSpace\.Net Programs.

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

Re: .NET What am I doing wrong?

Post by Burrick » Sun Aug 19, 2012 8:45 pm

Finally.

I won't go into any detail on how to use innerspace or isboxer as there is plenty of information available.

I have an Ogre ShadowKnight running around the tutorial area. Once he was logged in i opened the innerspace console, and typed "ext isxeq". This is what I failed to do the first time I tried this, and thus was unable to actually connect to any in game objects.

Walk your character somewhere safe :) ... type "dotnet ddbot" (or whatever you named your application). There you go ... one dead rat. (in my case).

It took a lot of digging to get to this point. Information is everywhere but scattered. I do best with examples, and if it wasn't for Blues post showing a smidgen of code, I probably would have dropped this whole idea and moved on.

Much can be gleaned from the object classes within ISXEQ.NET along with intellisense you get a pretty good idea of what you can do. The area I still have problems with (mostly because I have found no useful information or examples) is what "commands" I can use. This is something that cannot be "gleaned" from the information at hand, and something you must know.

For example once I targetted that rat, and diseased it, I wanted to whack it with my sword. But any attempts at ExecuteCommand("attack"), or "/attack" or variations thereof simply failed as the method did not understand my "command". I finally came up with ExecuteCommandEx("keypress", "1") which worked as the hot key 1 was attached to melee.

Another thing I don't know how to do is respond to events, such as a tell, group say, or better yet a relay link. I figured out if I program a hotkey I can send a relay message, although it would be nice to pass an ID with that message, which I can't macro.

I figure if I overcome this next hurdle I'm on my way to a functional dotnet bot. I don't know about the rest of you, but for me the fun is in the coding and not really the playing so much. I played Everquest back when it first came out (opening night in fact). My first MMORPG, and no other game has come close to the first time exitting the gates of Qeynos to see hundreds of toons running around bashing the crap out of snakes and rats.

So ... any good tutorials, forums, videos, ... code samples!!! I can connect to, to further my understanding ISXEQ dot net??

TMS
a hill giant
a hill giant
Posts: 151
Joined: Sun Nov 07, 2004 6:55 am

Re: .NET What am I doing wrong?

Post by TMS » Mon Aug 20, 2012 2:27 am

The problem will be, i think, no one uses isxeq. Everyone uses MQ2. So i think you are on your own if you want to go this route.

AFAIK isxeq is a dead project. Take a look at MQ2, everything you need you will find there.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Re: .NET What am I doing wrong?

Post by ascii38 » Mon Aug 20, 2012 7:01 pm

Burrick wrote: ISXEQChatWnd
error C2065: 'Show' : undeclared identifier Line 114 ISXEQChatWnd
The next three errors reference this error.
error C2039: 'Show' : is not a member of 'CMQChatWnd' Line 283 ISXEQChatWnd
This is repeated for lines 318 and 366.

I have no idea where this variable should be declared, nor what value it should be set to. (0 i am guessing). Either way, since I have an ISXEQChat, I figured I don't need an ISXEQChatWnd, so I didn't compile it.
Try changing "Show" to "dShow" as referenced here. If the relationship between ISXEQChatWnd and ISXEQChat is the same as they are in the MQ2 version, you do want ISXEQChatWnd as the output to that window is protected from being sent to Sony.

Burrick
orc pawn
orc pawn
Posts: 11
Joined: Thu May 15, 2003 7:49 pm

Re: .NET What am I doing wrong?

Post by Burrick » Mon Aug 20, 2012 9:46 pm

Thanks ascii38. That fixed ISXEQChatWnd. :)