Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🚀 Add unity playback #365

Merged
merged 3 commits into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions interface/interface_playback/Assets/Plugins.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions interface/interface_playback/Assets/Scripts/Playback.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

134 changes: 134 additions & 0 deletions interface/interface_playback/Assets/Scripts/Playback/MessageReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@

using Google.Protobuf;
using Protobuf;
using System;
using System.IO;
using System.IO.Compression;

namespace Playback
{
public class FileFormatNotLegalException : Exception
{
public FileFormatNotLegalException()
{

}
public override string Message => $"The file is not a legal playback file for THUAI6.";
}

public class MessageReader : IDisposable
{
private MemoryStream stream;
private CodedInputStream cos;
private GZipStream gzs;
private byte[] buffer;
public bool Finished { get; private set; } = false;

public readonly uint teamCount;
public readonly uint playerCount;

const int bufferMaxSize = 10 * 1024 * 1024; // 10M

public MessageReader(byte[] bytes)
{
stream = new MemoryStream(bytes);
var prefixLen = PlayBackConstant.Prefix.Length;
byte[] bt = new byte[prefixLen + sizeof(UInt32) * 2];
stream.Read(bt, 0, bt.Length);
for (int i = 0; i < prefixLen; ++i)
{
if (bt[i] != PlayBackConstant.Prefix[i]) throw new FileFormatNotLegalException();
}

teamCount = BitConverter.ToUInt32(bt, prefixLen);
playerCount = BitConverter.ToUInt32(bt, prefixLen + sizeof(UInt32));

gzs = new GZipStream(stream, CompressionMode.Decompress);
var tmpBuffer = new byte[bufferMaxSize];
var bufferSize = gzs.Read(tmpBuffer);
if (bufferSize == 0)
{
buffer = tmpBuffer;
Finished = true;
}
else if (bufferSize != bufferMaxSize) // 不留空位,防止 CodedInputStream 获取信息错误
{
if (bufferSize == 0)
{
Finished = true;
}
buffer = new byte[bufferSize];
Array.Copy(tmpBuffer, buffer, bufferSize);
}
else
{
buffer = tmpBuffer;
}
cos = new CodedInputStream(buffer);
}

public MessageToClient? ReadOne()
{
beginRead:
if (Finished)
return null;
var pos = cos.Position;
try
{
MessageToClient? msg = new MessageToClient();
cos.ReadMessage(msg);
return msg;
}
catch (InvalidProtocolBufferException)
{
var leftByte = buffer.Length - pos; // 上次读取剩余的字节
if (buffer.Length < bufferMaxSize / 2)
{
var newBuffer = new byte[bufferMaxSize];
for (int i = 0; i < leftByte; i++)
{
newBuffer[i] = buffer[pos + i];
}
buffer = newBuffer;
}
else
{
for (int i = 0; i < leftByte; ++i)
{
buffer[i] = buffer[pos + i];
}
}
var bufferSize = gzs.Read(buffer, (int)leftByte, (int)(buffer.Length - leftByte)) + leftByte;
if (bufferSize == leftByte)
{
Finished = true;
return null;
}
if (bufferSize != buffer.Length) // 不留空位,防止 CodedInputStream 获取信息错误
{
var tmpBuffer = new byte[bufferSize];
Array.Copy(buffer, tmpBuffer, bufferSize);
buffer = tmpBuffer;
}
cos = new CodedInputStream(buffer);
goto beginRead;
}
}

public void Dispose()
{
Finished = true;
if (stream == null)
return;
if (stream.CanRead)
{
stream.Close();
}
}

~MessageReader()
{
Dispose();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Playback
{
public static class PlayBackConstant
{
public static string ExtendedName = ".thuaipb";
public static byte[] Prefix = { (byte)'P', (byte)'B', 7, 0 }; // 文件前缀,用于标识文件类型,版本号为6
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading