Skip to content

Commit

Permalink
feat: add game patch information and hide paths
Browse files Browse the repository at this point in the history
closes #300
  • Loading branch information
DorielRivalet committed Feb 21, 2024
1 parent 1019011 commit 20f190e
Show file tree
Hide file tree
Showing 3 changed files with 276 additions and 10 deletions.
29 changes: 29 additions & 0 deletions MHFZ_Overlay/Models/Structures/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -842,3 +842,32 @@ public enum DivaPrayerGemColor
Green,
Blue,
}

public enum GamePatch
{
Vanilla,
Seph,
Ezemania,
Otyav1_1,
Tenrou,
Mezelounge,
/// <summary>
/// TODO
/// </summary>
Standard,
}

public enum GamePatchLanguage
{
JP,
EN,
FR,
}

public enum GamePatchFile
{
dat,
emd,
dll,
hddll,
}
215 changes: 205 additions & 10 deletions MHFZ_Overlay/Services/DatabaseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -941,19 +941,19 @@ FinalTimeValue ASC

using (var cmd = new SQLiteCommand(sql, conn))
{
var gameFolderPath = s.GameFolderPath;
var mhfdatHash = CalculateFileHash(gameFolderPath, @"\dat\mhfdat.bin");
var mhfemdHash = CalculateFileHash(gameFolderPath, @"\dat\mhfemd.bin");
var mhfinfHash = CalculateFileHash(gameFolderPath, @"\dat\mhfinf.bin");
var mhfsqdHash = CalculateFileHash(gameFolderPath, @"\dat\mhfsqd.bin");
var mhfodllHash = CalculateFileHash(gameFolderPath, @"\mhfo.dll");
var mhfohddllHash = CalculateFileHash(gameFolderPath, @"\mhfo-hd.dll");
var mhfexeHash = CalculateFileHash(gameFolderPath, @"\mhf.exe");
var gameFolderPathStatus = s.GameFolderPath == @"C:\Program Files (x86)\CAPCOM\Monster Hunter Frontier Online" ? "Standard" : "Custom";
var mhfdatHash = CalculateFileHash(s.GameFolderPath, @"\dat\mhfdat.bin");
var mhfemdHash = CalculateFileHash(s.GameFolderPath, @"\dat\mhfemd.bin");
var mhfinfHash = CalculateFileHash(s.GameFolderPath, @"\dat\mhfinf.bin");
var mhfsqdHash = CalculateFileHash(s.GameFolderPath, @"\dat\mhfsqd.bin");
var mhfodllHash = CalculateFileHash(s.GameFolderPath, @"\mhfo.dll");
var mhfohddllHash = CalculateFileHash(s.GameFolderPath, @"\mhfo-hd.dll");
var mhfexeHash = CalculateFileHash(s.GameFolderPath, @"\mhf.exe");

var gameFolderData = string.Format(CultureInfo.InvariantCulture,
"{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}",
createdAt, createdBy, runID,
gameFolderPath, mhfdatHash, mhfemdHash,
gameFolderPathStatus, mhfdatHash, mhfemdHash,
mhfinfHash, mhfsqdHash, mhfodllHash,
mhfohddllHash, mhfexeHash);
var gameFolderHash = CalculateStringHash(gameFolderData);
Expand All @@ -962,7 +962,7 @@ FinalTimeValue ASC
cmd.Parameters.AddWithValue("@CreatedAt", createdAt);
cmd.Parameters.AddWithValue("@CreatedBy", createdBy);
cmd.Parameters.AddWithValue("@RunID", runID);
cmd.Parameters.AddWithValue("@GameFolderPath", gameFolderPath);
cmd.Parameters.AddWithValue("@GameFolderPath", gameFolderPathStatus);
cmd.Parameters.AddWithValue("@mhfdatHash", mhfdatHash);
cmd.Parameters.AddWithValue("@mhfemdHash", mhfemdHash);
cmd.Parameters.AddWithValue("@mhfinfHash", mhfinfHash);
Expand Down Expand Up @@ -3151,6 +3151,26 @@ AFTER DELETE ON QuestsQuestVariant
cmd.ExecuteNonQuery();
}

using (var cmd = new SQLiteCommand(conn))
{
cmd.CommandText = @"CREATE TRIGGER IF NOT EXISTS prevent_quests_game_patch_updates
AFTER UPDATE ON QuestsGamePatch
BEGIN
SELECT RAISE(ROLLBACK, 'Updating rows is not allowed. Keep in mind that all attempted modifications are logged into the central database.');
END;";
cmd.ExecuteNonQuery();
}

using (var cmd = new SQLiteCommand(conn))
{
cmd.CommandText = @"CREATE TRIGGER IF NOT EXISTS prevent_quests_game_patch_deletion
AFTER DELETE ON QuestsGamePatch
BEGIN
SELECT RAISE(ROLLBACK, 'Updating rows is not allowed. Keep in mind that all attempted modifications are logged into the central database.');
END;";
cmd.ExecuteNonQuery();
}

using (var cmd = new SQLiteCommand(conn))
{
cmd.CommandText = @"CREATE TRIGGER IF NOT EXISTS prevent_bingo_updates
Expand Down Expand Up @@ -6174,6 +6194,20 @@ FOREIGN KEY(RunID) REFERENCES Quests(RunID)
cmd.ExecuteNonQuery();
}

sql = @"CREATE TABLE IF NOT EXISTS QuestsGamePatch(
QuestsGamePatchID INTEGER PRIMARY KEY AUTOINCREMENT,
mhfdatInfo TEXT NOT NULL DEFAULT '',
mhfemdInfo TEXT NOT NULL DEFAULT '',
mhfodllInfo TEXT NOT NULL DEFAULT '',
mhfohddllInfo TEXT NOT NULL DEFAULT '',
RunID INTEGER NOT NULL,
FOREIGN KEY(RunID) REFERENCES Quests(RunID)
)";
using (var cmd = new SQLiteCommand(sql, conn))
{
cmd.ExecuteNonQuery();
}

// a mh game but like a MUD. hunt in-game to get many kinds of points for this game. hunt and tame monsters. challenge other CPU players/monsters.
sql = @"CREATE TABLE IF NOT EXISTS GachaMaterial(
GachaMaterialID INTEGER PRIMARY KEY,
Expand Down Expand Up @@ -17732,6 +17766,167 @@ private void PerformUpdateToVersion_0_37_0(SQLiteConnection connection, DataLoad

UpdateQuestsObjectiveImage(connection);
UpdateQuestsMonsterDictionaries(connection, dataLoader);
FillQuestsGamePatch(connection, dataLoader);

// for privacy
ChangeGameFolderPath(connection);
}

private void ChangeGameFolderPath(SQLiteConnection conn)
{
if (string.IsNullOrEmpty(this.dataSource))
{
Logger.Warn(CultureInfo.InvariantCulture, "Cannot change game folder path. dataSource: {0}", this.dataSource);
return;
}

// Start a transaction
using (var transaction = conn.BeginTransaction())
{
try
{
using (var cmd0 = new SQLiteCommand(conn))
{
cmd0.CommandText = @"DROP TRIGGER IF EXISTS prevent_game_folder_updates";
cmd0.ExecuteNonQuery();
}

using (var cmd = new SQLiteCommand(conn))
{
cmd.CommandText = "SELECT * FROM GameFolder";

using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var path = reader["GameFolderPath"]?.ToString() ?? string.Empty;
var runID = long.Parse(reader["RunID"]?.ToString() ?? "0", CultureInfo.InvariantCulture);

if (path == string.Empty || path == null || runID == 0)
{
continue;
}

var newPath = path == @"C:\Program Files (x86)\CAPCOM\Monster Hunter Frontier Online" ? "Standard" : "Custom";

using (var cmd2 = new SQLiteCommand(conn))
{
cmd2.CommandText =
@"UPDATE GameFolder SET GameFolderPath = @GameFolderPath WHERE RunID = @RunID";
cmd2.Parameters.AddWithValue("@RunID", runID);
cmd2.Parameters.AddWithValue("@GameFolderPath", newPath);

cmd2.ExecuteNonQuery();
}
}
}
}

using (var cmd1 = new SQLiteCommand(conn))
{
cmd1.CommandText = @"CREATE TRIGGER IF NOT EXISTS prevent_game_folder_updates
AFTER UPDATE ON GameFolder
BEGIN
SELECT RAISE(ROLLBACK, 'Updating rows is not allowed. Keep in mind that all attempted modifications are logged into the central database.');
END;";
cmd1.ExecuteNonQuery();
}

// Commit the transaction
transaction.Commit();
}
catch (Exception ex)
{
HandleError(transaction, ex);
}
}

Logger.Debug("Changed game folder paths in GameFolder table");
}

private void FillQuestsGamePatch(SQLiteConnection conn, DataLoader dataLoader)
{
if (string.IsNullOrEmpty(this.dataSource))
{
Logger.Warn(CultureInfo.InvariantCulture, "Cannot fill game patch. dataSource: {0}", this.dataSource);
return;
}

// Start a transaction
using (var transaction = conn.BeginTransaction())
{
try
{
using (var cmd0 = new SQLiteCommand(conn))
{
cmd0.CommandText = @"DROP TRIGGER IF EXISTS prevent_quests_game_patch_updates";
cmd0.ExecuteNonQuery();
}

using (var cmd = new SQLiteCommand(conn))
{
cmd.CommandText = "SELECT * FROM GameFolder";

using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var runID = long.Parse(reader["RunID"]?.ToString() ?? "0", CultureInfo.InvariantCulture);
var dat = reader["mhfdatHash"]?.ToString() ?? "0";
var emd = reader["mhfemdHash"]?.ToString() ?? "0";
var mhfodll = reader["mhfodllHash"]?.ToString() ?? "0";
var mhfohddll = reader["mhfohddllHash"]?.ToString() ?? "0";

if (runID == 0)
{
continue;
}

using (var cmd2 = new SQLiteCommand(conn))
{
cmd2.CommandText =
@"INSERT INTO
QuestsGamePatch(RunID, mhfdatInfo, mhfemdInfo, mhfodllInfo, mhfohddllInfo)
VALUES
(
@RunID,
@mhfdatInfo,
@mhfemdInfo,
@mhfodllInfo,
@mhfohddllInfo
)";
cmd2.Parameters.AddWithValue("@RunID", runID);
cmd2.Parameters.AddWithValue("@mhfdatInfo", dataLoader.Model.GetGamePatchInfo(GamePatchFile.dat, dat));
cmd2.Parameters.AddWithValue("@mhfemdInfo", dataLoader.Model.GetGamePatchInfo(GamePatchFile.emd, emd));
cmd2.Parameters.AddWithValue("@mhfodllInfo", dataLoader.Model.GetGamePatchInfo(GamePatchFile.dll, mhfodll));
cmd2.Parameters.AddWithValue("@mhfohddllInfo", dataLoader.Model.GetGamePatchInfo(GamePatchFile.hddll, mhfohddll));

cmd2.ExecuteNonQuery();
}
}
}
}

using (var cmd1 = new SQLiteCommand(conn))
{
cmd1.CommandText = @"CREATE TRIGGER IF NOT EXISTS prevent_quests_game_patch_updates
AFTER UPDATE ON QuestsGamePatch
BEGIN
SELECT RAISE(ROLLBACK, 'Updating rows is not allowed. Keep in mind that all attempted modifications are logged into the central database.');
END;";
cmd1.ExecuteNonQuery();
}

// Commit the transaction
transaction.Commit();
}
catch (Exception ex)
{
HandleError(transaction, ex);
}
}

Logger.Debug("Filled game patches values in table");
}

/// <summary>
Expand Down
42 changes: 42 additions & 0 deletions MHFZ_Overlay/ViewModels/Windows/AddressModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1956,6 +1956,48 @@ public bool GetNotRoad()
return this.IsNotRoad();
}

public string GetGamePatchInfo(GamePatchFile file, string hash)
{
var result = "Unknown";

switch (file)
{
case GamePatchFile.dat:
QuestsGamePatches.datHashInfo.TryGetValue(hash, out var datInfo);
if (datInfo != null)
{
var a = datInfo.Keys.FirstOrDefault();
var b = datInfo.Keys.FirstOrDefault().ToString();

return $"{datInfo.Keys.FirstOrDefault().ToString()}-{datInfo.Values.FirstOrDefault().ToString()}";
}
break;
case GamePatchFile.emd:
QuestsGamePatches.datHashInfo.TryGetValue(hash, out var emdInfo);
if (emdInfo != null)
{
return $"{emdInfo.Keys.FirstOrDefault().ToString()}-{emdInfo.Values.FirstOrDefault().ToString()}";
}
break;
case GamePatchFile.dll:
QuestsGamePatches.datHashInfo.TryGetValue(hash, out var dllInfo);
if (dllInfo != null)
{
return $"{dllInfo.Keys.FirstOrDefault().ToString()}-{dllInfo.Values.FirstOrDefault().ToString()}";
}
break;
case GamePatchFile.hddll:
QuestsGamePatches.datHashInfo.TryGetValue(hash, out var hddllInfo);
if (hddllInfo != null)
{
return $"{hddllInfo.Keys.FirstOrDefault().ToString()}-{hddllInfo.Values.FirstOrDefault().ToString()}";
}
break;
}

return result;
}

// assumption: it follows ferias' monster part order top to bottom, presumably (e.g. head is at the top, so part 0 is head, and so on)
// grouping by skeleton too

Expand Down

0 comments on commit 20f190e

Please sign in to comment.