• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

The Hidden Forest - Trying to get E3 working on RG MQ2 Emu version

Joined
Jul 8, 2015
RedCents
842¢
Ok first of all i am just seeing if it's possible to make it work with the RG compile i am using currently THF server specific version of E3 with the included MQ2 version.
Found here https://github.com/morgs71/RoF2-E3-THF

Step 1.
So from what i understand i will need to find out what Plugins in the macro are used in the MQ2 version i use with E3 and see if they exist in the RG version.
Than i will need to find out if those that don't exist in the RG version if something exist that does the exact same as the missing plugin and is under a different name maybe in RG.

Soo lets start , from what i already know by copying the whole mac including folders to RG and attempting to run it in RG that it ask for some plugins
[2021/07/29 16:14:23] Plugin 'MQ2NetAdvPath' could not be loaded.
[2021/07/29 16:14:26] Plugin 'MQ2Turbo' could not be loaded.

So than lets take a look at the macro and see what other plugins might be needed
Those below are the ones that in both MQ2 version exist
MQ2EQBC
MQ2Netbots
MQ2MoveUtils
MQ2Exchange
MQ2Twist
MQ2ItemDisplay
MQ2Hud


Those below are the problem plugins
MQ2Turbo - since Turbo is used in a lot macros i assume its used by another plugin or maybe directly build in MQ2.exe ?
MQ2NetAdvpath - If its MQ2Advpath i would think renaming it from MQ2NetAdvpath to MQ2Advpath in one of the inc's in the plugin could work.
MQ2IniExt - couldn't find any info about that one
Only thing in the Macro i could find that uses MQ2IniExt would be
from e3.mac
INI:
  /if (${Bool[${Plugin[MQ2IniExt]}]}) {
    /varset IniMode IniExt
    /iniext clear
  }

And then some IniMode and IniExt variables in some of the inc files.

Any ideas or suggestions what to do next ?
 
What are the commands or TLOs from MQ2Turbo? Rather than looking at how you get those plugins, you’re probably better off finding what replaced them.

If I had to guess (since my memory is failing me) MQ2NetAdvPath is probably similar to Netbots in that it just layers on AdvPath functionality for multiple characters. If so, you can achieve this same thing without that plugin. Regardless, first step is finding the macro commands or TLOs that are used and determining a suitable replacement.

If I recall, IniExt is a custom plugin that lets you use non-standard ini. That’s probably something that’s not going to have a replacement.

The best place to start is trying to find the missing functionality and replace that, rather than the actual plugins.
 
What are the commands or TLOs from MQ2Turbo? Rather than looking at how you get those plugins, you’re probably better off finding what replaced them.

If I had to guess (since my memory is failing me) MQ2NetAdvPath is probably similar to Netbots in that it just layers on AdvPath functionality for multiple characters. If so, you can achieve this same thing without that plugin. Regardless, first step is finding the macro commands or TLOs that are used and determining a suitable replacement.

If I recall, IniExt is a custom plugin that lets you use non-standard ini. That’s probably something that’s not going to have a replacement.

The best place to start is trying to find the missing functionality and replace that, rather than the actual plugins.
I think you might be right i believe that someone mentioned once that MQ2iniExt makes it so in a ini you could Go instead of Buff1 Buff2 Buff3 just stick with Buff Buff Buff as a example , so it doesn't requires a number or something like that .
For Turbo not sure if this is something you mean but /turbo 100 and Turbo,${Me.Class.ShortName} (which than loads the Turbo value from an ini) would be the only thing i could find.
The Netbots part i don't know since it is already loaded and wouldn't make sense that Netbots and Netadvpath would be both loaded than would need to look deeper into that one.

However from what you are saying only way i might be able to pull this project is off if i could get ahold of the MQ2Iniext source ? And either compile myself a new version or to see if it maybe could get added to the Emu version of the compile ?
Unless i would try to rewrite the ini reading process.
 
You probably don't need turbo then, I doubt you need to change turbo values based on class at all. I'd just rip all that code out.

I don't see the source for IniExt, but it's not actually an ini at that point~ An ini is a set of sectioned key value pairs, and once they're not unique you're off in a different land than ini. Honestly, if it were me doing it, I'd just change the section of the code that reads those values rather than try to find and compile MQ2IniExt. Save yourself some headaches in the long run.
 
You should be able to replace the code in the E3 macro with commands and TLOs from the RG build.

Personally I would just use kissassist/rgmercs, I think the main difference is that e3 didn't provide functionality for auto pulling which is why it's preferred as that is frowned upon.
 
You probably don't need turbo then, I doubt you need to change turbo values based on class at all. I'd just rip all that code out.

I don't see the source for IniExt, but it's not actually an ini at that point~ An ini is a set of sectioned key value pairs, and once they're not unique you're off in a different land than ini. Honestly, if it were me doing it, I'd just change the section of the code that reads those values rather than try to find and compile MQ2IniExt. Save yourself some headaches in the long run.
Hmm ok maybe at some point i might attempt this, but would to spend more time to look into this.

You should be able to replace the code in the E3 macro with commands and TLOs from the RG build.

Personally I would just use kissassist/rgmercs, I think the main difference is that e3 didn't provide functionality for auto pulling which is why it's preferred as that is frowned upon.
I used years ago modbot and briefly Kissassist on THF if the stuff would be just simple Dungeon Crawl or just farming stuff i prob would just use Kissassist.
Thing with this specific E3 version it's a highly custom build one that has some events/scripts for specific THF Raid events and mobs.
 
Well seems like i got my hands on the source for MQ2IniExt
Author from what i heard is a person named Vysra
[CODE lang="cpp" title="MQ2IniExt"]
#include "../MQ2Plugin.h"

#include <string>
#include <map>
using namespace std;

#define SI_CONVERT_WIN32
#include "SimpleIni.h"
#include "IniResult.h"

PreSetup("MQ2IniExt");




map<string, PIniRef> iniMap;
map<string, PIniRef>::iterator iter;
IniData::iterator iniIter;

char DataIniExtTemp[MAX_STRING] = { 0 };
char DataIniExtName[MAX_STRING] = { 0 };
char DataIniExtTemp2[MAX_STRING] = { 0 };
char DataIniRequest[MAX_STRING] = { 0 };
char DataIniTempComment[MAX_STRING] = { 0 };
PCHAR DataIniSection = 0;
PCHAR DataIniKey = 0;
char DataIniDefault[MAX_STRING] = { 0 };
IniData tempData;

void GetIniFilename(PCHAR source, PCHAR dest);

PIniRef LoadIni(const char* filename) {
string fileString = string(filename);
iter = iniMap.find(fileString);

if (iter != iniMap.end()) {
//WriteChatf("File '%s' found!", fileString);
return iter->second;
} else {
SimpleIni *newIni = new SimpleIni(false, true, false);
SIReturnCode rc = newIni->LoadFile(fileString.c_str());
if (rc < 0) {
if (rc == SI_Error::SI_FILE) {
PIniRef newIniRef = new IniRef(newIni);
iniMap[fileString] = newIniRef;
//WriteChatf("File '%s' loaded!", fileString);
return newIniRef;
}
return 0;
} else {
PIniRef newIniRef = new IniRef(newIni);
iniMap[fileString] = newIniRef;
//WriteChatf("File '%s' loaded!", fileString);
return newIniRef;
}
}
return 0;
}

BOOL dataIniExt(PCHAR szIndex, MQ2TYPEVAR &Ret) {
if (szIndex) {
PCHAR pIniFile = 0;
PCHAR pKey = 0;
PCHAR pDefault = "";
char *Next_Token1 = 0;
if (pIniFile = strtok_s(szIndex, ",", &Next_Token1)) {
if (DataIniSection = strtok_s(NULL, ",", &Next_Token1)) {
if (!strcmp(DataIniSection, "-1"))
DataIniSection = 0;
if (DataIniKey = strtok_s(NULL, ",", &Next_Token1)) {
if (!strcmp(DataIniKey, "-1"))
DataIniKey = 0;
pDefault = strtok_s(NULL, "¦", &Next_Token1);
if (!pDefault) {
pDefault = "";
}
}
}
} else {
return false;
}

CHAR FileName[MAX_STRING] = { 0 };

GetIniFilename(pIniFile, &FileName[0]);
ZeroMemory(&DataIniRequest[0], MAX_STRING);

strcpy_s(DataIniExtName, FileName);
strcpy_s(DataIniRequest, DataIniExtName);

if (DataIniSection) strcat_s(DataIniRequest, DataIniSection);
if (DataIniKey) strcat_s(DataIniRequest, DataIniKey);
if (pDefault) strcpy_s(DataIniDefault, pDefault);

if (PIniRef iniRef = LoadIni(DataIniExtName)) {
PSimpleIni ini = iniRef->pIni;
if (DataIniSection) {
if (DataIniKey) {

/* oututs the whole map
map<string, PIniRefResult>::iterator iter;
for (iter = iniRef->cache->begin(); iter != iniRef->cache->end(); iter++)
{
WriteChatf("iniresults: %d, %s, %s", iter->second->type, iter->second->str, iter->second->data->front().pItem);
}*/

//make it lower case for consistency
_strlwr_s(DataIniRequest);

//check if we've found this key before
auto it = iniRef->cache->find(DataIniRequest);
//if we have
if (it != iniRef->cache->end()) {
Ret.Ptr = it->second;
Ret.Type = pMQ2IniResultType;
return true;
}
PIniData newData = new IniData();

ini->GetAllValues(DataIniSection, DataIniKey, *newData);
if (newData->size() == 0) {
PIniRefResult newResult = 0;
if (strlen(pDefault)) {
PCHAR newString = new char[MAX_STRING];
ZeroMemory(newString, MAX_STRING);
strncpy_s(newString, MAX_STRING, pDefault, MAX_STRING - 1);
newResult = new IniRefResult(newString);
} else {
newResult = new IniRefResult();
}
newResult->isDefault = true;
Ret.Ptr = newResult;
Ret.Type = pMQ2IniResultType;
return true;
}

PIniRefResult newResult = new IniRefResult(newData);

(*iniRef->cache)[DataIniRequest] = newResult;
Ret.Ptr = newResult;
Ret.Type = pMQ2IniResultType;
return true;

} else {
ini->GetAllKeys(DataIniSection, tempData);
ZeroMemory(DataIniExtTemp, 2048);
if (tempData.size() == 0) {
return false;
} else {
for (auto x : tempData) {
sprintf_s(DataIniExtTemp2, "%s|", x.pItem);
strcat_s(DataIniExtTemp, DataIniExtTemp2);
}
}
Ret.Ptr = &DataIniExtTemp[0];
Ret.Type = pStringType;
return true;
}
} else {
ini->GetAllSections(tempData);
ZeroMemory(DataIniExtTemp, 2048);
if (tempData.size() == 0) {
return false;
} else {
for (auto x : tempData) {
sprintf_s(DataIniExtTemp2, "%s|", x.pItem);
strcat_s(DataIniExtTemp, DataIniExtTemp2);
}
}
Ret.Ptr = &DataIniExtTemp[0];
Ret.Type = pStringType;
return true;
}
}
}
return false;
}

char Arg1[MAX_STRING] = { 0 };
char Arg2[MAX_STRING] = { 0 };
char Arg3[MAX_STRING] = { 0 };
char Arg4[MAX_STRING] = { 0 };
char Arg5[MAX_STRING] = { 0 };
char Arg6[MAX_STRING] = { 0 };

PLUGIN_API VOID IniX(PSPAWNINFO pChar, PCHAR szLine) {
GetArg(Arg1, szLine, 1);
GetArg(Arg2, szLine, 2);
if (!Arg1) return;
CHAR FileName[MAX_STRING] = { 0 };
*DataIniTempComment = 0;
if (!_strnicmp(Arg1, "clear", 5)) {
if (Arg2[0]) {
GetIniFilename(Arg2, &FileName[0]);

string fileString = string(FileName);
iter = iniMap.find(fileString);

if (iter != iniMap.end()) {
//WriteChatf("File '%s' found and cleared!", fileString);
if (iter->second) delete iter->second;
iniMap.erase(iter);
}
} else {
for (auto it : iniMap) {
if (it.second) delete it.second;
}
iniMap.clear();
}
return;
}
if (!_strnicmp(Arg1, "save", 4) && Arg2[0]) {
GetIniFilename(Arg2, &FileName[0]);
if (PIniRef iniRef = LoadIni(FileName)) {
PSimpleIni ini = iniRef->pIni;
ini->SaveFile(FileName);
}
return;
}
if (!_strnicmp(Arg1, "set", 3) || !_strnicmp(Arg1, "write", 5)) {
// /iniext set "Filename" "Section" "Key" "Value" "Comment"
// 1 2 3 4 5 6
GetArg(Arg3, szLine, 3);
GetArg(Arg4, szLine, 4);
GetArg(Arg5, szLine, 5);
GetArg(Arg6, szLine, 6);
GetIniFilename(Arg2, &FileName[0]);
if (Arg3[0]) {
if (PIniRef iniRef = LoadIni(FileName)) {
PSimpleIni ini = iniRef->pIni;
ini->SetSpaces(false);
if (strlen(Arg6)) {
if (Arg6[0] != '#' && Arg6[0] != ';') {
sprintf_s(&DataIniTempComment[0], MAX_STRING, "#%s", Arg6);
} else {
strcpy_s(&DataIniTempComment[0], MAX_STRING, Arg6);
}
}
ini->SetValue(Arg3, strlen(Arg4) ? Arg4 : NULL, strlen(Arg5) ? Arg5 : NULL, strlen(Arg6) ? DataIniTempComment : NULL);
//WriteChatf("writing [%s] %s=%s with comment %s", Arg3, Arg4 ? Arg4 : "NULL", Arg5 ? Arg5 : "NULL", Arg6 ? Arg6 : "NULL");
}
}
return;
}
if (!_strnicmp(Arg1, "delete", 6)) {
// /iniext delete "Filename" "Section" "Key" remove
GetArg(Arg3, szLine, 3);
GetArg(Arg4, szLine, 4);
GetArg(Arg5, szLine, 5);
GetIniFilename(Arg2, &FileName[0]);
if (Arg3[0]) {
if (PIniRef iniRef = LoadIni(FileName)) {
PSimpleIni ini = iniRef->pIni;
bool removeEmpty = false;
if (!_strnicmp(Arg5, "remove", 6)) removeEmpty = true;
ini->Delete(Arg3, strlen(Arg4) ? Arg4 : NULL, removeEmpty);

string fileString = string(FileName);
iter = iniMap.find(fileString);

if (iter != iniMap.end()) {
//WriteChatf("File '%s' found and cleared!", fileString);
if (iter->second) delete iter->second;
iniMap.erase(iter);
}
}
}
return;
}
if (!_strnicmp(Arg1, "test", 4) && Arg2[0]) {
GetIniFilename(Arg2, &FileName[0]);
WriteChatf("File '%s' referenced", FileName);
return;
}
}

void GetIniFilename(PCHAR source, PCHAR dest) {
PCHAR pTemp = source;

while (pTemp[0]) {
if (pTemp[0] == '/')
pTemp[0] = '\\';
pTemp++;
}

if (source[0] != '\\' && !strchr(source, ':'))
sprintf_s(dest, MAX_STRING, "%s\\%s", gszMacroPath, source);
else
strcpy_s(dest, MAX_STRING, source);

if (!strchr(source, '.'))
strcat_s(dest, MAX_STRING, ".ini");
_strlwr_s(dest, MAX_STRING);
return;
}

PLUGIN_API VOID InitializePlugin(VOID)
{
DebugSpewAlways("Initializing MQ2IniExt");
pMQ2IniResultType = new MQ2IniResultType();
AddMQ2Data("IniExt", dataIniExt);
AddCommand("/iniext", IniX, 0, 1, 1);
}

void CleanupIniData() {
for (auto x : iniMap) {
if (x.second) delete x.second;
}
iniMap.clear();
}

PLUGIN_API VOID ShutdownPlugin(VOID)
{
DebugSpewAlways("Shutting down MQ2IniExt");
RemoveMQ2Data("IniExt");
RemoveCommand("/iniext");
CleanupIniData();
delete pMQ2IniResultType;
}[/CODE]
 
I've been working on this as well. I was able to successfully remove the need for MQ2NetAdvPath (Changed to MQ2AdvPath) and have been able to successfully compile MQ2IniExt with VV(test), but have not fully tested it yet until I figure out MQ2Turbo (either compiling the plugin fo VV or ripping it out)

Also, I'll probably need to check with Vysra and see if he'd be cool with me including MQ2IniExt with VV.

Other than than, there will likely be significant testing needed to make sure everything else works in e3 as well.
 
So I've successfully gotten MQ2IniExt and MQ2Turbo compiled and working with VeryVanilla and e3. I took the base e3 v7.0 and modified it so everything seems to work with VV. I'm sure the changes can be easily translated to THF's version of e3 since it is different than the base release. I'm still doing testing but everything seems to be just working so far. I'm still waiting on permission to include MQ2IniExt and MQ2Turbo with VV. If I cannot get it, I already have a plan to remove the need for those two plugins altogether. Turbo is easier since all it does is all allow you to change the Turbo speed on on the fly, IniExt will take a bit more work but is doable.

--Edit: Got permission to distribute MQ2IniExt and MQ2Turbo, woohoo!
 
Last edited:
So I've successfully gotten MQ2IniExt and MQ2Turbo compiled and working with VeryVanilla and e3. I took the base e3 v7.0 and modified it so everything seems to work with VV. I'm sure the changes can be easily translated to THF's version of e3 since it is different than the base release. I'm still doing testing but everything seems to be just working so far. I'm still waiting on permission to include MQ2IniExt and MQ2Turbo with VV. If I cannot get it, I already have a plan to remove the need for those two plugins altogether. Turbo is easier since all it does is all allow you to change the Turbo speed on on the fly, IniExt will take a bit more work but is doable.

--Edit: Got permission to distribute MQ2IniExt and MQ2Turbo, woohoo!

This is awesome! Where are you distributing?
 
So I've successfully gotten MQ2IniExt and MQ2Turbo compiled and working with VeryVanilla and e3. I took the base e3 v7.0 and modified it so everything seems to work with VV. I'm sure the changes can be easily translated to THF's version of e3 since it is different than the base release. I'm still doing testing but everything seems to be just working so far. I'm still waiting on permission to include MQ2IniExt and MQ2Turbo with VV. If I cannot get it, I already have a plan to remove the need for those two plugins altogether. Turbo is easier since all it does is all allow you to change the Turbo speed on on the fly, IniExt will take a bit more work but is doable.

--Edit: Got permission to distribute MQ2IniExt and MQ2Turbo, woohoo!
Heck yeah, I am guilded with Vysra on PEQ, I wonder if I could get a link for this so I could try and get E3 running on Test server. Really appreciate it.
 
This is awesome! Where are you distributing?
Probably here on RedGuides. Need to work that out with RedBot and the crew here still.
Heck yeah, I am guilded with Vysra on PEQ, I wonder if I could get a link for this so I could try and get E3 running on Test server. Really appreciate it.
I cannot distribute just yet. There are some issues I'm still working through including client crashing bugs having to deal with IniExt and the way e3 tries to pull from files. After that, I've got to test each class individually and all together to make sure it works cohesively. Hoping to have things all worked out within a month or so.
 
I wonder if I could get a link for this so I could try and get E3 running on Test server. Really appreciate it.
I just reread this. Do you mean the actual Darkpaw test server, or an EMU test server you set up? I ask because at this time, I have no idea how e3 would work on the Darkpaw test servers since it was created specifically for EMU by the original authors. All my efforts have been to get it working with VV for EMU at the moment as that is all I play on. Perhaps some time down the line I can see about what is need to get it working for Test/Live or leave that someone else to modify.
 
I just reread this. Do you mean the actual Darkpaw test server, or an EMU test server you set up? I ask because at this time, I have no idea how e3 would work on the Darkpaw test servers since it was created specifically for EMU by the original authors. All my efforts have been to get it working with VV for EMU at the moment as that is all I play on. Perhaps some time down the line I can see about what is need to get it working for Test/Live or leave that someone else to modify.
Yes, I was referring to live (darkpaw) test center/server. I 0layed on peq for several years and just got used to net bots and net follow. It's just familiar to me, that's the only reason I was inquiring.
 
Yes, I was referring to live (darkpaw) test center/server. I 0layed on peq for several years and just got used to net bots and net follow. It's just familiar to me, that's the only reason I was inquiring.
Ok Gotcha. Once I get it out there, you are more than welcome to give it a shot. Perhaps we can work together to fix any issues for Live/Test.
 
The Hidden Forest - Trying to get E3 working on RG MQ2 Emu version

Users who are viewing this thread

Back
Top
Cart