Skip to content

Conversation

@Nickelony
Copy link
Collaborator

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a comprehensive refactoring of the TombIDE.ProjectMaster project, introducing modern C# patterns and a service-oriented architecture.

Key Changes:

  • Enabled nullable reference types and upgraded to C# 12
  • Introduced service layer abstractions with dependency injection support
  • Extracted engine update, plugin management, and archive creation logic into dedicated services
  • Modernized code with file-scoped namespaces, expression-bodied members, and pattern matching

Reviewed Changes

Copilot reviewed 73 out of 75 changed files in this pull request and generated 26 comments.

Show a summary per file
File Description
TombIDE.ProjectMaster.csproj Enabled nullable reference types and C# 12
Services/EngineUpdate/*.cs Extracted engine update logic into game-specific services
Services/Plugins/*.cs Refactored plugin management into discovery, installation, deployment services
Services/ArchiveCreation/*.cs Created service layer for game archive generation with async support
Services/Settings/*.cs Introduced services for managing startup images, splash screens, logos, etc.
PluginManager.cs Simplified by delegating to plugin services
LevelManager.cs Refactored to use version and update services
FormGameArchive.cs Converted to async/await pattern with progress reporting
Files not reviewed (2)
  • TombIDE/TombIDE.ProjectMaster/Forms/FormGameArchive.Designer.cs: Language not supported
  • TombIDE/TombIDE.ProjectMaster/Forms/FormPleaseWait.Designer.cs: Language not supported
Comments suppressed due to low confidence (1)

TombIDE/TombIDE.ProjectMaster/Sections/SectionLevelProperties.cs:406

				foreach (DarkTreeNode node in treeView_AllPrjFiles.Nodes)
				{
					if (node.Text.Equals(_ide.SelectedLevel.TargetPrj2FileName, StringComparison.OrdinalIgnoreCase))
					{
						treeView_AllPrjFiles.SelectNode(node);
						nodeFound = true;

						break;
					}
				}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 73 out of 75 changed files in this pull request and generated 8 comments.

Files not reviewed (2)
  • TombIDE/TombIDE.ProjectMaster/Forms/FormGameArchive.Designer.cs: Language not supported
  • TombIDE/TombIDE.ProjectMaster/Forms/FormPleaseWait.Designer.cs: Language not supported
Comments suppressed due to low confidence (1)

TombIDE/TombIDE.ProjectMaster/Sections/SectionLevelProperties.cs:406

				foreach (DarkTreeNode node in treeView_AllPrjFiles.Nodes)
				{
					if (node.Text.Equals(_ide.SelectedLevel.TargetPrj2FileName, StringComparison.OrdinalIgnoreCase))
					{
						treeView_AllPrjFiles.SelectNode(node);
						nodeFound = true;

						break;
					}
				}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +45 to +47
var settingsUpdate16 = latestVersion.Major == 1 && latestVersion.Minor >= 6
&& currentVersion.Major == 1 && currentVersion.Minor <= 6
&& currentVersion <= latestVersion;
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition logic appears incorrect. When latestVersion is 1.6+ and currentVersion is 1.6 or below, the condition should trigger. However, the current logic checks currentVersion.Minor <= 6 which would be true for 1.6, but then requires currentVersion <= latestVersion which is also true. The issue is that when current is 1.6 and latest is 1.6, this will still trigger the settings update unnecessarily. The condition should be currentVersion.Minor < 6 (strictly less than) instead of <=.

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +24
foreach (ILevelProject level in levels)
{
string prj2Path = GetPrj2Path(level);
batchList.Files.Add(prj2Path);
}
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +86
catch
{
// Ignore cleanup errors
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generic catch clause.

Suggested change
catch
{
// Ignore cleanup errors
catch (Exception ex)
{
// Ignore cleanup errors, but log for debugging purposes
System.Diagnostics.Debug.WriteLine($"Failed to delete partial archive file: {ex}");

Copilot uses AI. Check for mistakes.
Comment on lines +94 to 101
catch (Exception ex)
{
string tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

if (!Directory.Exists(tempDirectory))
Directory.CreateDirectory(tempDirectory);

string engineDirectory = _ide.Project.GetEngineRootDirectoryPath();
string targetTempEngineDirectory = Path.Combine(tempDirectory, "Engine");
waitForm.Close();

foreach (string folder in importantFolders)
{
if (!Directory.Exists(folder))
continue;

string pathPart = folder.Remove(0, engineDirectory.Length);
string targetPath = Path.Combine(targetTempEngineDirectory, pathPart.Trim('\\'));

SharedMethods.CopyFilesRecursively(folder, targetPath);
}

if (createSavesFolder)
Directory.CreateDirectory(Path.Combine(targetTempEngineDirectory, "saves"));

foreach (string file in importantFiles)
{
if (!File.Exists(file))
continue;

string pathPart = file.Remove(0, engineDirectory.Length);
string targetPath = Path.Combine(targetTempEngineDirectory, pathPart.Trim('\\'));

string targetDirectory = Path.GetDirectoryName(targetPath);

if (!Directory.Exists(targetDirectory))
Directory.CreateDirectory(targetDirectory);

File.Copy(file, targetPath);
}
DarkMessageBox.Show(this, $"Archive creation failed:\n{ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

// Copy launch.exe
string launchFilePath = _ide.Project.GetLauncherFilePath();

if (File.Exists(launchFilePath))
File.Copy(launchFilePath, Path.Combine(tempDirectory, Path.GetFileName(launchFilePath)), true);

if (!string.IsNullOrWhiteSpace(readmeText))
File.WriteAllText(Path.Combine(tempDirectory, "README.txt"), readmeText);

if (File.Exists(filePath))
File.Delete(filePath);

ZipFile.CreateFromDirectory(tempDirectory, filePath);

if (Directory.Exists(tempDirectory))
Directory.Delete(tempDirectory, true);
DialogResult = DialogResult.None;
}
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generic catch clause.

Copilot uses AI. Check for mistakes.
UpdatePlugins();
}
catch (Exception ex)
{
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generic catch clause.

Suggested change
{
{
// Rethrow critical exceptions
if (ex is OutOfMemoryException || ex is StackOverflowException || ex is System.Threading.ThreadAbortException)
throw;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants