Terraria ModLoader  0.11.5
A framework for Terraria mods
MissingResourceException.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using Terraria.Localization;
5 
6 namespace Terraria.ModLoader.Exceptions
7 {
9  {
10  public override string HelpLink => "https://github.com/tModLoader/tModLoader/wiki/Basic-tModLoader-Modding-FAQ#terrariamodloadermodgettexturestring-name-error";
11 
13  }
14 
15  public MissingResourceException(string message)
16  : base(message) {
17  }
18 
19  public MissingResourceException(string message, Exception inner)
20  : base(message, inner) {
21  }
22 
23  public MissingResourceException(string message, ICollection<string> keys) : this(ProcessMessage(message, keys)) {
24  }
25 
26  public static string ProcessMessage(string message, ICollection<string> keys) {
27  string closestMatch = "";
28  closestMatch = LevenshteinDistance.FolderAwareEditDistance(message, keys.ToArray());
29  if (closestMatch != null && closestMatch != "") {
30  return Language.GetTextValue("tModLoader.LoadErrorResourceNotFoundPathHint", message, closestMatch) + "\n";
31  }
32  return message;
33  }
34  }
35 
36  static class LevenshteinDistance
37  {
38  internal static string FolderAwareEditDistance(string source, string[] targets) {
39  if (targets.Length == 0) return null;
40  var separator = '/';
41  var sourceParts = source.Split(separator);
42  var sourceFolders = sourceParts.Reverse().Skip(1).ToList();
43  var sourceFile = sourceParts.Last();
44 
45  int missingFolderPenalty = 4;
46  int extraFolderPenalty = 3;
47 
48  var scores = targets.Select(target => {
49  var targetParts = target.Split(separator);
50  var targetFolders = targetParts.Reverse().Skip(1).ToList();
51  var targetFile = targetParts.Last();
52 
53  var commonFolders = sourceFolders.Where(x => targetFolders.Contains(x));
54  var reducedSourceFolders = sourceFolders.Except(commonFolders).ToList();
55  var reducedTargetFolders = targetFolders.Except(commonFolders).ToList();
56 
57  int score = 0;
58  int folderDiff = reducedSourceFolders.Count - reducedTargetFolders.Count;
59  if (folderDiff > 0)
60  score += folderDiff * missingFolderPenalty;
61  else if (folderDiff < 0)
62  score += -folderDiff * extraFolderPenalty;
63 
64  if (reducedSourceFolders.Count > 0 && reducedSourceFolders.Count >= reducedTargetFolders.Count) {
65  foreach (var item in reducedTargetFolders) {
66  int min = Int32.MaxValue;
67  foreach (var item2 in reducedSourceFolders) {
68  min = Math.Min(min, LevenshteinDistance.Compute(item, item2));
69  }
70  score += min;
71  }
72  }
73  else if (reducedSourceFolders.Count > 0) {
74  foreach (var item in reducedSourceFolders) {
75  int min = Int32.MaxValue;
76  foreach (var item2 in reducedTargetFolders) {
77  min = Math.Min(min, LevenshteinDistance.Compute(item, item2));
78  }
79  score += min;
80  }
81  }
82  score += LevenshteinDistance.Compute(targetFile, sourceFile);
83 
84  return new {
85  Target = target,
86  Score = score
87  };
88  });
89  var b = scores.OrderBy(x => x.Score);
90  return scores.OrderBy(x => x.Score).First().Target;
91  }
92 
93  public static int Compute(string s, string t) {
94  int n = s.Length;
95  int m = t.Length;
96  int[,] d = new int[n + 1, m + 1];
97 
98  // Step 1
99  if (n == 0) {
100  return m;
101  }
102 
103  if (m == 0) {
104  return n;
105  }
106 
107  // Step 2
108  for (int i = 0; i <= n; d[i, 0] = i++) {
109  }
110 
111  for (int j = 0; j <= m; d[0, j] = j++) {
112  }
113 
114  // Step 3
115  for (int i = 1; i <= n; i++) {
116  //Step 4
117  for (int j = 1; j <= m; j++) {
118  // Step 5
119  int cost = (t[j - 1] == s[i - 1]) ? 0 : 2; // substitution
120 
121  // Step 6
122  d[i, j] = Math.Min(
123  Math.Min(d[i - 1, j] + 2, d[i, j - 1] + 2),
124  d[i - 1, j - 1] + cost);
125  }
126  }
127  // Step 7
128  return d[n, m];
129  }
130  }
131 }
MissingResourceException(string message, ICollection< string > keys)
static string ProcessMessage(string message, ICollection< string > keys)