I am using the Ferr2D Terrain Tool to build my scene:
And I met a problem, when I load a scene contains the Ferr2D object from asset bundle, the editor and player will crash. But when I load it using the EditorApplicaition to load the scene, everything is OK.
I am using the latest version of the Unity2018.2b10 with the .Net 4.x Equivalent and .Net Standard2.0. And the crash report is like below:
I find the crash is because I use the AssetBundle.LoadFromStream from a custom stream, with a very simple crypt process.
I load the asset bundle like this:
var file = File.OpenRead(path);
var stream = new CryptStream(file, this.Keyt);
return AssetBundle.LoadFromStream(stream, 0, this.ReadBufferSize);
And the CryptStream is like this:
/// <summary>
/// The crypt stream used to crypt a stream.
/// </summary>
public sealed class CryptStream : Stream, IDisposable
{
private Stream source;
private byte[] keyt;
/// <summary>
/// Initializes a new instance of the <see cref="CryptStream"/> class.
/// </summary>
public CryptStream(Stream source, byte[] keyt)
{
this.source = source;
this.keyt = keyt;
}
/// <inheritdoc/>
public override long Position
{
get { return this.source.Position; }
set { this.source.Position = value; }
}
/// <inheritdoc/>
public override long Length
{
get { return this.source.Length; }
}
/// <inheritdoc/>
public override bool CanWrite
{
get { return this.source.CanWrite; }
}
/// <inheritdoc/>
public override bool CanSeek
{
get { return this.source.CanSeek; }
}
/// <inheritdoc/>
public override bool CanRead
{
get { return this.source.CanRead; }
}
/// <inheritdoc/>
public new void Dispose()
{
base.Dispose();
this.source.Dispose();
}
/// <inheritdoc/>
public override void Close()
{
base.Close();
this.source.Close();
}
/// <inheritdoc/>
public override void Flush()
{
this.source.Flush();
}
/// <inheritdoc/>
public override long Seek(long offset, SeekOrigin origin)
{
return this.source.Seek(offset, origin);
}
/// <inheritdoc/>
public override void SetLength(long value)
{
this.source.SetLength(value);
}
/// <inheritdoc/>
public override void Write(byte[] buffer, int offset, int count)
{
var keptLen = this.keyt.Length;
var keptStart = this.source.Position % keptLen;
for (int i = 0; i < count; ++i)
{
var keptPos = (keptStart + i) % keptLen;
var bufPos = offset + i;
buffer[bufPos] = (byte)(buffer[bufPos] ^ this.keyt[keptPos]);
}
this.source.Write(buffer, offset, count);
}
/// <inheritdoc/>
public override int Read(byte[] buffer, int offset, int count)
{
var keptLen = this.keyt.Length;
var keptStart = this.source.Position % keptLen;
var readCount = this.source.Read(buffer, offset, count);
for (int i = 0; i < readCount; ++i)
{
var keptPos = (keptStart + i) % keptLen;
var bufPos = offset + i;
buffer[bufPos] = (byte)(buffer[bufPos] ^ this.keyt[keptPos]);
}
return readCount;
}
}
I test the encrypt and decrypt with my own code with this stream is OK. And I read the document really carefully from here:
Especially the section:
The following are restrictions on a Stream object to optimize AssetBundle data loading: