More filesystem stuff

This commit is contained in:
LazyDuchess 2022-09-14 11:52:12 -03:00
parent 7608e9d26c
commit 32eecf033e
7 changed files with 197 additions and 12 deletions

View file

@ -178,6 +178,7 @@ MonoBehaviour:
text: {fileID: 93897976}
testChanges: 1
testDeletion: 0
testSaving: 1
--- !u!114 &93897976
MonoBehaviour:
m_ObjectHideFlags: 0

View file

@ -26,11 +26,12 @@ namespace OpenTS2.Content.Changes
{
this.asset = asset;
this.codec = codec;
this.entry = new DBPFEntry()
this.entry = new DynamicDBPFEntry()
{
tgi = this.asset.tgi,
internalTGI = this.asset.internalTGI,
dynamic = true
dynamic = true,
change = this
};
}
public ChangedAsset(AbstractAsset asset) : this(asset, Codecs.Get(asset.TGI.TypeID))

View file

@ -149,12 +149,15 @@ namespace OpenTS2.Content
public void RemovePackage(DBPFFile package)
{
//package.Dispose();
Cache.RemoveAllForPackage(package);
_contentEntries.Remove(package);
entryByGroupID.Remove(package.GroupID);
entryByPath.Remove(package.FilePath);
entryByFile.Remove(package);
package.OnRenameEvent -= PackageOnRename;
if (entryByFile.ContainsKey(package))
{
Cache.RemoveAllForPackage(package);
_contentEntries.Remove(package);
entryByGroupID.Remove(package.GroupID);
entryByPath.Remove(package.FilePath);
entryByFile.Remove(package);
package.OnRenameEvent -= PackageOnRename;
}
}
/// <summary>

View file

@ -45,7 +45,18 @@ namespace OpenTS2.Files
_UserDirectory = FileUtils.CleanPath(pathProvider.GetUserPath()) + "/";
_BinDirectory = FileUtils.CleanPath(pathProvider.GetGameRootPath()) + "/TSBin/";
}
/// <summary>
/// Checks if two paths, unparsed or parsed, are equal.
/// </summary>
/// <param name="path1">Path to check</param>
/// <param name="path2">Path to check against</param>
/// <returns>True if equal, false if not.</returns>
public bool PathsEqual(string path1, string path2)
{
path1 = GetRealPath(path1).ToLowerInvariant();
path2 = GetRealPath(path2).ToLowerInvariant();
return (path1 == path2);
}
/// <summary>
/// Returns short relative path. (Eg. Replaces the game's directory with the %DataDirectory% shorthand)
/// </summary>
@ -100,12 +111,25 @@ namespace OpenTS2.Files
/// <param name="path">Path to output file.</param>
/// <param name="bytes">Byte array to write.</param>
public void Write(string path, byte[] bytes)
{
Write(path, bytes, bytes.Length);
}
/// <summary>
/// Writes a byte array into a file.
/// </summary>
/// <param name="path">Path to output file.</param>
/// <param name="bytes">Byte array to write.</param>
public void Write(string path, byte[] bytes, int size)
{
var realPath = GetRealPath(path);
var dir = Path.GetDirectoryName(realPath);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
File.WriteAllBytes(realPath, bytes);
var fStream = new FileStream(realPath, FileMode.Create, FileAccess.Write);
fStream.Write(bytes, 0, size);
fStream.Dispose();
//File.WriteAllBytes(realPath, bytes);
}
/// <summary>

View file

@ -9,6 +9,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTS2.Common;
using OpenTS2.Content.Changes;
namespace OpenTS2.Files.Formats.DBPF
{
/// <summary>
@ -61,8 +63,19 @@ namespace OpenTS2.Files.Formats.DBPF
public uint FileOffset;
//A 4-byte unsigned integer specifying the size of the entry's data
public uint FileSize;
public virtual uint FileSize { get; set; }
public bool dynamic = false;
}
public class DynamicDBPFEntry : DBPFEntry
{
public ChangedAsset change;
public override uint FileSize {
get
{
return (uint)change.bytes.Length;
}
}
}
}

View file

@ -171,7 +171,14 @@ namespace OpenTS2.Files.Formats.DBPF
Dirty = true;
}
}
public bool Deleted
{
get
{
return _deleted;
}
}
bool _deleted = false;
public bool DeleteIfEmpty = true;
private DBPFFileChanges m_changes;
/// <summary>
@ -231,6 +238,8 @@ namespace OpenTS2.Files.Formats.DBPF
continue;
if (Changes.ChangedEntries.ContainsKey(element.internalTGI))
finalEntries.Add(Changes.ChangedEntries[element.internalTGI].entry);
else
finalEntries.Add(element);
}
return finalEntries;
}
@ -397,14 +406,104 @@ namespace OpenTS2.Files.Formats.DBPF
ContentManager.Provider.RemovePackage(this);
ContentManager.FileSystem.Delete(FilePath);
Changes.Clear();
_deleted = true;
return;
}
var memStream = new MemoryStream();
var size = Write(memStream);
var finalData = memStream.GetBuffer();
memStream.Dispose();
Dispose();
ContentManager.FileSystem.Write(FilePath, finalData, size);
var stream = ContentManager.FileSystem.OpenRead(FilePath);
Read(stream);
Changes.Clear();
return;
}
public int Write(Stream wStream)
{
var entries = Entries;
var writer = new BinaryWriter(wStream);
//HeeeADER
writer.Write(new char[] { 'D', 'B', 'P', 'F' });
//major version
writer.Write((int)1);
//minor version
writer.Write((int)2);
//unknown
writer.Write(new byte[12]);
//Date stuff
writer.Write((int)0);
writer.Write((int)0);
//Index major
writer.Write((int)7);
//Num entries
writer.Write((int)entries.Count);
//Index offset
var indexOff = wStream.Position;
//Placeholder
writer.Write((int)0);
//Index size
var indexSize = wStream.Position;
//Placeholder
writer.Write((int)0);
//Trash Entry Stuff
writer.Write((int)0);
writer.Write((int)0);
writer.Write((int)0);
//Index Minor Ver
writer.Write((int)2);
//Padding
writer.Write(new byte[32]);
//Go back and write index offset
var lastPos = wStream.Position;
wStream.Position = indexOff;
writer.Write((int)lastPos);
wStream.Position = lastPos;
var entryOffset = new List<long>();
for(var i=0;i<entries.Count;i++)
{
var element = entries[i];
writer.Write(element.internalTGI.TypeID);
writer.Write(element.internalTGI.GroupID);
writer.Write(element.internalTGI.InstanceID);
writer.Write(element.internalTGI.InstanceHigh);
entryOffset.Add(wStream.Position);
writer.Write(0);
//File Size
writer.Write(element.FileSize);
}
//Write files
for (var i = 0; i < entries.Count; i++)
{
var filePosition = wStream.Position;
wStream.Position = entryOffset[i];
writer.Write((int)filePosition);
wStream.Position = filePosition;
var entry = GetEntry(entries[i]);
writer.Write(entry, 0, (int)entries[i].FileSize);
}
lastPos = wStream.Position;
var siz = lastPos - indexOff;
wStream.Position = indexSize;
writer.Write((int)siz);
writer.Dispose();
return (int)lastPos;
}
/// <summary>
/// Gets a DBPFEntry's data from this DBPF instance.
/// </summary>

View file

@ -12,6 +12,7 @@ using OpenTS2.Files.Utils;
using OpenTS2.Content;
using OpenTS2.Common;
using OpenTS2.Content.DBPF;
using System.Text;
namespace OpenTS2.Files.Formats.DBPF
{
@ -56,5 +57,48 @@ namespace OpenTS2.Files.Formats.DBPF
var ast = new StringSetAsset(stringTableData);
return ast;
}
public class StringForSerialization
{
public byte languageCode;
public string value;
public string description;
}
public override byte[] Serialize(AbstractAsset asset)
{
var stringAsset = asset as StringSetAsset;
var stream = new MemoryStream();
var writer = new BinaryWriter(stream);
writer.Write(new byte[64]);
writer.Seek(0, SeekOrigin.Begin);
var ascii = Encoding.UTF8.GetBytes(stringAsset.StringData.fileName + char.MinValue);
writer.Write(ascii);
writer.Seek(64, SeekOrigin.Begin);
writer.Write(new byte[2] { 253, 255 });
var stringList = new List<StringForSerialization>();
foreach(var element in stringAsset.StringData.strings)
{
foreach(var listElement in element.Value)
{
var item = new StringForSerialization();
item.languageCode = element.Key;
item.value = listElement.value;
item.description = listElement.description;
stringList.Add(item);
}
}
writer.Write((short)stringList.Count);
foreach(var element in stringList)
{
writer.Write(element.languageCode);
ascii = Encoding.UTF8.GetBytes(element.value + char.MinValue);
writer.Write(ascii);
ascii = Encoding.UTF8.GetBytes(element.description + char.MinValue);
writer.Write(ascii);
}
writer.Dispose();
stream.Close();
return stream.GetBuffer();
}
}
}