(acf0cb343) Fixes to EnableWorkShopItem: - Don't allow enabling if the item is not compatible with the user's version of Barotrauma or if it's a core package that's missing some required files. - Don't allow enabling if the item external files referenced in the content package are not found (e.g. if a mod uses vanilla files but the vanilla files aren't found).

This commit is contained in:
Joonas Rikkonen
2019-04-29 21:10:51 +03:00
parent 6c4bf4ea44
commit 2ffb8d922d
5 changed files with 121 additions and 20 deletions

View File

@@ -152,6 +152,32 @@ namespace Barotrauma
}
if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120);
character.MemState.Clear();
}
}
partial void ImpactProjSpecific(float impact, Body body)
{
float volume = MathHelper.Clamp(impact - 3.0f, 0.5f, 1.0f);
if (body.UserData is Limb limb && character.Stun <= 0f)
{
if (impact > 3.0f) { PlayImpactSound(limb); }
}
else if (body.UserData is Limb || body == Collider.FarseerBody)
{
if (!character.IsRemotePlayer && impact > ImpactTolerance)
{
SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider);
}
}
if (Character.Controlled == character)
{
GameMain.GameScreen.Cam.Shake = Math.Min(Math.Max(strongestImpact, GameMain.GameScreen.Cam.Shake), 3.0f);
}
}
if (character.MemState.Count < 1) return;
overrideTargetMovement = Vector2.Zero;

View File

@@ -583,6 +583,23 @@ namespace Barotrauma.Steam
ContentPackage contentPackage = new ContentPackage(metaDataFilePath);
string newContentPackagePath = GetWorkshopItemContentPackagePath(contentPackage);
if (!contentPackage.IsCompatible())
{
errorMsg = TextManager.Get(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
.Replace("[packagename]", contentPackage.Name)
.Replace("[packageversion]", contentPackage.GameVersion.ToString())
.Replace("[gameversion]", GameMain.Version.ToString());
return false;
}
if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes))
{
errorMsg = TextManager.Get("ContentPackageMissingCoreFiles")
.Replace("[packagename]", contentPackage.Name)
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes));
return false;
}
var allPackageFiles = Directory.GetFiles(item.Directory.FullName, "*", SearchOption.AllDirectories);
List<string> nonContentFiles = new List<string>();
foreach (string file in allPackageFiles)
@@ -599,8 +616,6 @@ namespace Barotrauma.Steam
if (!allowFileOverwrite)
{
// TODO: If you create a new mod via the workshop interface and enable it, it will show the error msg, but still allows you to enable the content.
if (File.Exists(newContentPackagePath) && !CheckFileEquality(newContentPackagePath, metaDataFilePath))
{
errorMsg = TextManager.Get("WorkshopErrorOverwriteOnEnable")
@@ -629,12 +644,41 @@ namespace Barotrauma.Steam
foreach (ContentFile contentFile in contentPackage.Files)
{
string sourceFile = Path.Combine(item.Directory.FullName, contentFile.Path);
if (!File.Exists(sourceFile)) { continue; }
//path not allowed -> the content file must be a reference to an external file (such as some vanilla file outside the Mods folder)
if (!ContentPackage.IsModFilePathAllowed(contentFile))
{
DebugConsole.ThrowError(TextManager.Get("WorkshopErrorIllegalPathOnEnable").Replace("[filename]", contentFile.Path));
//the content package is trying to copy a file to a prohibited path, which is not allowed
if (File.Exists(sourceFile))
{
errorMsg = TextManager.Get("WorkshopErrorIllegalPathOnEnable").Replace("[filename]", contentFile.Path);
return false;
}
//not trying to copy anything, so this is a reference to an external file
//if the external file doesn't exist, we cannot enable the package
else if (!File.Exists(contentFile.Path))
{
//TODO: add the error message to localization
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " {File \"" + contentFile.Path + "\" not found.}";
return false;
}
continue;
}
else if (!File.Exists(sourceFile))
{
if (File.Exists(contentFile.Path))
{
//the file is already present in the game folder, all good
continue;
}
else
{
//file not present in either the mod or the game folder -> cannot enable the package
//TODO: add the error message to localization
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " {File \"" + contentFile.Path + "\" not found.}";
return false;
}
}
//make sure the destination directory exists
Directory.CreateDirectory(Path.GetDirectoryName(contentFile.Path));
@@ -656,7 +700,7 @@ namespace Barotrauma.Steam
}
catch (Exception e)
{
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " " + e.Message;
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " {" + e.Message + "}";
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
return false;
}
@@ -827,7 +871,7 @@ namespace Barotrauma.Steam
{
foreach (ContentFile contentFile in contentPackage.Files)
{
if (!File.Exists(contentFile.Path)) return false;
if (!File.Exists(contentFile.Path)) { return false; }
}
}

View File

@@ -383,6 +383,7 @@ namespace Barotrauma
var titleText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), rightColumn.RectTransform), EnsureUTF8(item.Title), textAlignment: Alignment.CenterLeft, wrap: true)
{
UserData = "titletext",
CanBeFocused = false
};
@@ -575,8 +576,7 @@ namespace Barotrauma
private bool ToggleItemEnabled(GUITickBox tickBox)
{
Facepunch.Steamworks.Workshop.Item item = tickBox.UserData as Facepunch.Steamworks.Workshop.Item;
if (item == null) { return false; }
if (!(tickBox.UserData is Facepunch.Steamworks.Workshop.Item item)) { return false; }
var updateButton = tickBox.Parent.FindChild("updatebutton");
@@ -585,7 +585,9 @@ namespace Barotrauma
{
if (!SteamManager.EnableWorkShopItem(item, false, out errorMsg))
{
tickBox.Enabled = false;
tickBox.Visible = false;
tickBox.Selected = false;
if (tickBox.Parent.GetChildByUserData("titletext") is GUITextBlock titleText) { titleText.TextColor = Color.Red; }
}
}
else

View File

@@ -217,6 +217,7 @@ namespace Barotrauma
{
return corePackageRequiredFiles.All(fileType => Files.Any(file => file.Type == fileType));
}
public bool ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes)
{
missingContentTypes = new List<ContentType>();
@@ -230,6 +231,25 @@ namespace Barotrauma
return missingContentTypes.Count == 0;
}
/// <summary>
/// Make sure all the files defined in the content package are present
/// </summary>
/// <returns></returns>
public bool VerifyFiles(out List<string> errorMessages)
{
errorMessages = new List<string>();
foreach (ContentFile file in Files)
{
if (!File.Exists(file.Path))
{
errorMessages.Add("File \"" + file.Path + "\" not found.");
continue;
}
}
return errorMessages.Count == 0;
}
public static ContentPackage CreatePackage(string name, string path, bool corePackage)
{
ContentPackage newPackage = new ContentPackage()
@@ -398,6 +418,13 @@ namespace Barotrauma
return path == "Mods";
}
}
/// <summary>
/// Are mods allowed to install a file into the specified path. If a content package XML includes files
/// with a prohibited path, they are treated as references to external files. For example, a mod could include
/// some vanilla files in the XML, in which case the game will simply use the vanilla files present in the game folder.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static bool IsModFilePathAllowed(string path)
{
while (true)
@@ -426,7 +453,7 @@ namespace Barotrauma
{
return Files.Where(f => f.Type == type).Select(f => f.Path);
}
public static void LoadAll(string folder)
{
if (!Directory.Exists(folder))

View File

@@ -604,13 +604,14 @@ namespace Barotrauma
}
foreach (ContentPackage contentPackage in SelectedContentPackages)
{
bool packageOk = contentPackage.VerifyFiles(out List<string> errorMessages);
if (!packageOk)
{
DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\":\n" + string.Join("\n", errorMessages));
continue;
}
foreach (ContentFile file in contentPackage.Files)
{
if (!System.IO.File.Exists(file.Path))
{
DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found.");
continue;
}
ToolBox.IsProperFilenameCase(file.Path);
}
}
@@ -970,13 +971,14 @@ namespace Barotrauma
foreach (ContentPackage contentPackage in SelectedContentPackages)
{
bool packageOk = contentPackage.VerifyFiles(out List<string> errorMessages);
if (!packageOk)
{
DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\":\n" + string.Join("\n", errorMessages));
continue;
}
foreach (ContentFile file in contentPackage.Files)
{
if (!System.IO.File.Exists(file.Path))
{
DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found.");
continue;
}
ToolBox.IsProperFilenameCase(file.Path);
}
}