Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor create log topic in dialog function fixes #374

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 5 additions & 109 deletions src/Ninja/G1CP/Content/Fixes/Gamesave/fix037_LogEntryGravoMerchant.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,99 +7,10 @@
*/
func int G1CP_037_LogEntryGravoMerchant_Toggle(var int apply) {
// Define possibly missing symbols locally
const int LOG_MISSION = 0;
const int LOG_NOTE = 1;
const int LOG_NOTE = 1;

// Parameters of this fix
const int topicSection = LOG_NOTE;
const string topicSymbName = "GE_TraderOC";
const string infoSymbName = "DIA_Gravo_HelpHow";
const string funcSymbName = "DIA_Gravo_HelpHow_Info";
const string hookSymbName = "G1CP_037_LogEntryGravoMerchant_Intercept";

// Retrieve the topic and entry strings once and modify the info function
const int infoId = -2; // -1 is reserved for invalid symbols
const int topicId = -1;
const int entryId = -1;
const string topic = "G1CP invalid topic name";
const string entry = "G1CP invalid topic entry";
if (infoId == -2) {
infoId = G1CP_GetInfoInstId(infoSymbName);
topicId = G1CP_GetStringConstId(topicSymbName, 0);
var int funcId; funcId = G1CP_GetFuncId(funcSymbName, "void|none");
var int b_logentry_id; b_logentry_id = G1CP_GetFuncId("B_LogEntry", "void|string|string");

// Do this only once (this is never reverted, i.e. session fix)
if (infoId == -1) || (funcId == -1) || (b_logentry_id == -1) || (topicId == -1) {
return FALSE;
};

// Find all calls to 'B_LogEntry' within the dialog function
const int bytes[2] = {zPAR_TOK_CALL<<24, -1};
var zCPar_Symbol needleSymb; needleSymb = _^(MEM_GetSymbolByIndex(b_logentry_id));
bytes[1] = needleSymb.content;
var int matches; matches = G1CP_FindInFunc(funcId, _@(bytes)+3, 5);

/* We are looking for:
zPAR_TOK_PUSHVAR topic
zPAR_TOK_PUSHVAR xxxx
zPAR_TOK_CALL B_LogEntry
*/

// Narrow down the search to calls with the correct topic as first argument to find the pushed entry
repeat(i, MEM_ArraySize(matches)); var int i;
var int pos; pos = MEM_ArrayRead(matches, i);
if (MEM_ReadByte(pos-10) == zPAR_TOK_PUSHVAR) && (MEM_ReadInt(pos-9) == topicId)
&& (MEM_ReadByte(pos-5) == zPAR_TOK_PUSHVAR) {
entryId = MEM_ReadInt(pos-4);
break;
};
end;
MEM_ArrayFree(matches);

// Check if we have found a valid entry
if (entryId <= 0) || (entryId >= MEM_Parser.symtab_table_numInArray) {
return FALSE;
};

// Get the topic strings
topic = G1CP_GetStringConstI(topicId, 0, topic);
entry = G1CP_GetStringI(entryId, 0, entry);

// Now that all is established, let's replace the call to 'B_LogEntry' to squeeze in the creation of the topic
i = G1CP_ReplaceCall(funcId, 0, b_logentry_id, MEM_GetSymbolIndex(hookSymbName));
if (i <= 0) {
return FALSE;
};
};

// Now, on to the actual revertible fix
if (infoId == -1) || (entryId == -1) || (topicId == -1) {
return FALSE;
};

// Apply or revert
if (apply) {

// Add the log entry silently if it should be there
if (Npc_KnowsInfo(hero, infoId))
&& (!G1CP_LogHasEntry(topic, entry)) {
Log_CreateTopic(topic, topicSection);
Log_AddEntry(topic, entry);
G1CP_LogMoveEntryToTop(topic, entry); // Move entry to the top otherwise it is always the newest entry
return TRUE;
};
} else {

// Revert the fix by removing the entry again
G1CP_LogRemoveEntry(topic, entry);
if (!G1CP_LogHasEntry(topic, entry)) {
return TRUE;
};
};

// Even if the dialog function is fixed, the fix is not marked as applied here!
return FALSE;
return G1CP_LogCreateTopicInDialog(LOG_NOTE, "GE_TraderOC", "DIA_Gravo_HelpHow", "DIA_Gravo_HelpHow_Info",
"G1CP_037_LogEntryGravoMerchant_Intercept", apply);
};

/*
Expand All @@ -109,24 +20,9 @@ func void G1CP_037_LogEntryGravoMerchant_Intercept(var string topic, var string
G1CP_ReportFuncToSpy();

// Define possibly missing symbols locally
const int LOG_MISSION = 0;
const int LOG_NOTE = 1;

// Parameters of this fix
const string topicSymbName = "GE_TraderOC";
const int topicSection = LOG_NOTE;

// Check if this is the correct topic
if (Hlp_StrCmp(topic, G1CP_GetStringConst(topicSymbName, 0, "G1CP invalid topic string")))
&& (!G1CP_LogGetTopic(topic)) {
Log_CreateTopic(topic, topicSection);
G1CP_SetFixStatus(37, G1CP_FIX_APPLIED); // If it did not exist before, our fix will have to be reverted
};
const int LOG_NOTE = 1;

// Go on with the original call
MEM_PushStringParam(topic);
MEM_PushStringParam(entry);
MEM_CallByString("B_LogEntry"); // Does exist as established by the function above
G1CP_LogInterceptEntry("GE_TraderOC", topic, LOG_NOTE, entry, 37);
};

/*
Expand Down
114 changes: 5 additions & 109 deletions src/Ninja/G1CP/Content/Fixes/Gamesave/fix203_LogEntryGrahamMerchant.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,99 +7,10 @@
*/
func int G1CP_203_LogEntryGrahamMerchant_Toggle(var int apply) {
// Define possibly missing symbols locally
const int LOG_MISSION = 0;
const int LOG_NOTE = 1;
const int LOG_NOTE = 1;

// Parameters of this fix
const int topicSection = LOG_NOTE;
const string topicSymbName = "GE_TraderOC";
const string infoSymbName = "DIA_Graham_Hello";
const string funcSymbName = "DIA_Graham_Hello_Info";
const string hookSymbName = "G1CP_203_LogEntryGrahamMerchant_Intercept";

// Retrieve the topic and entry strings once and modify the info function
const int infoId = -2; // -1 is reserved for invalid symbols
const int topicId = -1;
const int entryId = -1;
const string topic = "G1CP invalid topic name";
const string entry = "G1CP invalid topic entry";
if (infoId == -2) {
infoId = G1CP_GetInfoInstId(infoSymbName);
topicId = G1CP_GetStringConstId(topicSymbName, 0);
var int funcId; funcId = G1CP_GetFuncId(funcSymbName, "void|none");
var int b_logentry_id; b_logentry_id = G1CP_GetFuncId("B_LogEntry", "void|string|string");

// Do this only once (this is never reverted, i.e. session fix)
if (infoId == -1) || (funcId == -1) || (b_logentry_id == -1) || (topicId == -1) {
return FALSE;
};

// Find all calls to 'B_LogEntry' within the dialog function
const int bytes[2] = {zPAR_TOK_CALL<<24, -1};
var zCPar_Symbol needleSymb; needleSymb = _^(MEM_GetSymbolByIndex(b_logentry_id));
bytes[1] = needleSymb.content;
var int matches; matches = G1CP_FindInFunc(funcId, _@(bytes)+3, 5);

/* We are looking for:
zPAR_TOK_PUSHVAR topic
zPAR_TOK_PUSHVAR xxxx
zPAR_TOK_CALL B_LogEntry
*/

// Narrow down the search to calls with the correct topic as first argument to find the pushed entry
repeat(i, MEM_ArraySize(matches)); var int i;
var int pos; pos = MEM_ArrayRead(matches, i);
if (MEM_ReadByte(pos-10) == zPAR_TOK_PUSHVAR) && (MEM_ReadInt(pos-9) == topicId)
&& (MEM_ReadByte(pos-5) == zPAR_TOK_PUSHVAR) {
entryId = MEM_ReadInt(pos-4);
break;
};
end;
MEM_ArrayFree(matches);

// Check if we have found a valid entry
if (entryId <= 0) || (entryId >= MEM_Parser.symtab_table_numInArray) {
return FALSE;
};

// Get the topic strings
topic = G1CP_GetStringConstI(topicId, 0, topic);
entry = G1CP_GetStringI(entryId, 0, entry);

// Now that all is established, let's replace the call to 'B_LogEntry' to squeeze in the creation of the topic
i = G1CP_ReplaceCall(funcId, 0, b_logentry_id, MEM_GetSymbolIndex(hookSymbName));
if (i <= 0) {
return FALSE;
};
};

// Now, on to the actual revertible fix
if (infoId == -1) || (entryId == -1) || (topicId == -1) {
return FALSE;
};

// Apply or revert
if (apply) {

// Add the log entry silently if it should be there
if (Npc_KnowsInfo(hero, infoId))
&& (!G1CP_LogHasEntry(topic, entry)) {
Log_CreateTopic(topic, topicSection);
Log_AddEntry(topic, entry);
G1CP_LogMoveEntryToTop(topic, entry); // Move entry to the top otherwise it is always the newest entry
return TRUE;
};
} else {

// Revert the fix by removing the entry again
G1CP_LogRemoveEntry(topic, entry);
if (!G1CP_LogHasEntry(topic, entry)) {
return TRUE;
};
};

// Even if the dialog function is fixed, the fix is not marked as applied here!
return FALSE;
return G1CP_LogCreateTopicInDialog(LOG_NOTE, "GE_TraderOC", "DIA_Graham_Hello", "DIA_Graham_Hello_Info",
"G1CP_203_LogEntryGrahamMerchant_Intercept", apply);
};

/*
Expand All @@ -109,24 +20,9 @@ func void G1CP_203_LogEntryGrahamMerchant_Intercept(var string topic, var string
G1CP_ReportFuncToSpy();

// Define possibly missing symbols locally
const int LOG_MISSION = 0;
const int LOG_NOTE = 1;

// Parameters of this fix
const string topicSymbName = "GE_TraderOC";
const int topicSection = LOG_NOTE;

// Check if this is the correct topic
if (Hlp_StrCmp(topic, G1CP_GetStringConst(topicSymbName, 0, "G1CP invalid topic string")))
&& (!G1CP_LogGetTopic(topic)) {
Log_CreateTopic(topic, topicSection);
G1CP_SetFixStatus(203, G1CP_FIX_APPLIED); // If it did not exist before, our fix will have to be reverted
};
const int LOG_NOTE = 1;

// Go on with the original call
MEM_PushStringParam(topic);
MEM_PushStringParam(entry);
MEM_CallByString("B_LogEntry"); // Does exist as established by the function above
G1CP_LogInterceptEntry("GE_TraderOC", topic, LOG_NOTE, entry, 203);
};

/*
Expand Down
114 changes: 5 additions & 109 deletions src/Ninja/G1CP/Content/Fixes/Gamesave/fix205_LogEntryWolfMerchant.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,99 +7,10 @@
*/
func int G1CP_205_LogEntryWolfMerchant_Toggle(var int apply) {
// Define possibly missing symbols locally
const int LOG_MISSION = 0;
const int LOG_NOTE = 1;
const int LOG_NOTE = 1;

// Parameters of this fix
const int topicSection = LOG_NOTE;
const string topicSymbName = "GE_TraderNC";
const string infoSymbName = "DIA_Wolf_Hello";
const string funcSymbName = "DIA_Wolf_Hello_Info";
const string hookSymbName = "G1CP_205_LogEntryWolfMerchant_Intercept";

// Retrieve the topic and entry strings once and modify the info function
const int infoId = -2; // -1 is reserved for invalid symbols
const int topicId = -1;
const int entryId = -1;
const string topic = "G1CP invalid topic name";
const string entry = "G1CP invalid topic entry";
if (infoId == -2) {
infoId = G1CP_GetInfoInstId(infoSymbName);
topicId = G1CP_GetStringConstId(topicSymbName, 0);
var int funcId; funcId = G1CP_GetFuncId(funcSymbName, "void|none");
var int b_logentry_id; b_logentry_id = G1CP_GetFuncId("B_LogEntry", "void|string|string");

// Do this only once (this is never reverted, i.e. session fix)
if (infoId == -1) || (funcId == -1) || (b_logentry_id == -1) || (topicId == -1) {
return FALSE;
};

// Find all calls to 'B_LogEntry' within the dialog function
const int bytes[2] = {zPAR_TOK_CALL<<24, -1};
var zCPar_Symbol needleSymb; needleSymb = _^(MEM_GetSymbolByIndex(b_logentry_id));
bytes[1] = needleSymb.content;
var int matches; matches = G1CP_FindInFunc(funcId, _@(bytes)+3, 5);

/* We are looking for:
zPAR_TOK_PUSHVAR topic
zPAR_TOK_PUSHVAR xxxx
zPAR_TOK_CALL B_LogEntry
*/

// Narrow down the search to calls with the correct topic as first argument to find the pushed entry
repeat(i, MEM_ArraySize(matches)); var int i;
var int pos; pos = MEM_ArrayRead(matches, i);
if (MEM_ReadByte(pos-10) == zPAR_TOK_PUSHVAR) && (MEM_ReadInt(pos-9) == topicId)
&& (MEM_ReadByte(pos-5) == zPAR_TOK_PUSHVAR) {
entryId = MEM_ReadInt(pos-4);
break;
};
end;
MEM_ArrayFree(matches);

// Check if we have found a valid entry
if (entryId <= 0) || (entryId >= MEM_Parser.symtab_table_numInArray) {
return FALSE;
};

// Get the topic strings
topic = G1CP_GetStringConstI(topicId, 0, topic);
entry = G1CP_GetStringI(entryId, 0, entry);

// Now that all is established, let's replace the call to 'B_LogEntry' to squeeze in the creation of the topic
i = G1CP_ReplaceCall(funcId, 0, b_logentry_id, MEM_GetSymbolIndex(hookSymbName));
if (i <= 0) {
return FALSE;
};
};

// Now, on to the actual revertible fix
if (infoId == -1) || (entryId == -1) || (topicId == -1) {
return FALSE;
};

// Apply or revert
if (apply) {

// Add the log entry silently if it should be there
if (Npc_KnowsInfo(hero, infoId))
&& (!G1CP_LogHasEntry(topic, entry)) {
Log_CreateTopic(topic, topicSection);
Log_AddEntry(topic, entry);
G1CP_LogMoveEntryToTop(topic, entry); // Move entry to the top otherwise it is always the newest entry
return TRUE;
};
} else {

// Revert the fix by removing the entry again
G1CP_LogRemoveEntry(topic, entry);
if (!G1CP_LogHasEntry(topic, entry)) {
return TRUE;
};
};

// Even if the dialog function is fixed, the fix is not marked as applied here!
return FALSE;
return G1CP_LogCreateTopicInDialog(LOG_NOTE, "GE_TraderNC", "DIA_Wolf_Hello", "DIA_Wolf_Hello_Info",
"G1CP_205_LogEntryWolfMerchant_Intercept", apply);
};

/*
Expand All @@ -109,24 +20,9 @@ func void G1CP_205_LogEntryWolfMerchant_Intercept(var string topic, var string e
G1CP_ReportFuncToSpy();

// Define possibly missing symbols locally
const int LOG_MISSION = 0;
const int LOG_NOTE = 1;

// Parameters of this fix
const string topicSymbName = "GE_TraderNC";
const int topicSection = LOG_NOTE;

// Check if this is the correct topic
if (Hlp_StrCmp(topic, G1CP_GetStringConst(topicSymbName, 0, "G1CP invalid topic string")))
&& (!G1CP_LogGetTopic(topic)) {
Log_CreateTopic(topic, topicSection);
G1CP_SetFixStatus(205, G1CP_FIX_APPLIED); // If it did not exist before, our fix will have to be reverted
};
const int LOG_NOTE = 1;

// Go on with the original call
MEM_PushStringParam(topic);
MEM_PushStringParam(entry);
MEM_CallByString("B_LogEntry"); // Does exist as established by the function above
G1CP_LogInterceptEntry("GE_TraderNC", topic, LOG_NOTE, entry, 205);
};

/*
Expand Down
Loading