初始化仓库

This commit is contained in:
SepComet
2026-02-07 19:38:49 +08:00
commit 88641dae11
1540 changed files with 371772 additions and 0 deletions
@@ -0,0 +1,293 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.FileSystem;
using System;
using System.IO;
using UnityEngine;
namespace UnityGameFramework.Runtime
{
/// <summary>
/// 安卓文件系统流。
/// </summary>
public sealed class AndroidFileSystemStream : FileSystemStream
{
private static readonly string SplitFlag = "!/assets/";
private static readonly int SplitFlagLength = SplitFlag.Length;
private static readonly AndroidJavaObject s_AssetManager = null;
private static readonly IntPtr s_InternalReadMethodId = IntPtr.Zero;
private static readonly jvalue[] s_InternalReadArgs = null;
private readonly AndroidJavaObject m_FileStream;
private readonly IntPtr m_FileStreamRawObject;
static AndroidFileSystemStream()
{
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
if (unityPlayer == null)
{
throw new GameFrameworkException("Unity player is invalid.");
}
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
if (currentActivity == null)
{
throw new GameFrameworkException("Current activity is invalid.");
}
AndroidJavaObject assetManager = currentActivity.Call<AndroidJavaObject>("getAssets");
if (assetManager == null)
{
throw new GameFrameworkException("Asset manager is invalid.");
}
s_AssetManager = assetManager;
IntPtr inputStreamClassPtr = AndroidJNI.FindClass("java/io/InputStream");
s_InternalReadMethodId = AndroidJNIHelper.GetMethodID(inputStreamClassPtr, "read", "([BII)I");
s_InternalReadArgs = new jvalue[3];
AndroidJNI.DeleteLocalRef(inputStreamClassPtr);
currentActivity.Dispose();
unityPlayer.Dispose();
}
/// <summary>
/// 初始化安卓文件系统流的新实例。
/// </summary>
/// <param name="fullPath">要加载的文件系统的完整路径。</param>
/// <param name="access">要加载的文件系统的访问方式。</param>
/// <param name="createNew">是否创建新的文件系统流。</param>
public AndroidFileSystemStream(string fullPath, FileSystemAccess access, bool createNew)
{
if (string.IsNullOrEmpty(fullPath))
{
throw new GameFrameworkException("Full path is invalid.");
}
if (access != FileSystemAccess.Read)
{
throw new GameFrameworkException(Utility.Text.Format("'{0}' is not supported in AndroidFileSystemStream.", access));
}
if (createNew)
{
throw new GameFrameworkException("Create new is not supported in AndroidFileSystemStream.");
}
int position = fullPath.LastIndexOf(SplitFlag, StringComparison.Ordinal);
if (position < 0)
{
throw new GameFrameworkException("Can not find split flag in full path.");
}
string fileName = fullPath.Substring(position + SplitFlagLength);
m_FileStream = InternalOpen(fileName);
if (m_FileStream == null)
{
throw new GameFrameworkException(Utility.Text.Format("Open file '{0}' from Android asset manager failure.", fullPath));
}
m_FileStreamRawObject = m_FileStream.GetRawObject();
}
/// <summary>
/// 获取或设置文件系统流位置。
/// </summary>
protected override long Position
{
get
{
throw new GameFrameworkException("Get position is not supported in AndroidFileSystemStream.");
}
set
{
Seek(value, SeekOrigin.Begin);
}
}
/// <summary>
/// 获取文件系统流长度。
/// </summary>
protected override long Length
{
get
{
return InternalAvailable();
}
}
/// <summary>
/// 设置文件系统流长度。
/// </summary>
/// <param name="length">要设置的文件系统流的长度。</param>
protected override void SetLength(long length)
{
throw new GameFrameworkException("SetLength is not supported in AndroidFileSystemStream.");
}
/// <summary>
/// 定位文件系统流位置。
/// </summary>
/// <param name="offset">要定位的文件系统流位置的偏移。</param>
/// <param name="origin">要定位的文件系统流位置的方式。</param>
protected override void Seek(long offset, SeekOrigin origin)
{
if (origin == SeekOrigin.End)
{
Seek(Length + offset, SeekOrigin.Begin);
return;
}
if (origin == SeekOrigin.Begin)
{
InternalReset();
}
while (offset > 0)
{
long skip = InternalSkip(offset);
if (skip < 0)
{
return;
}
offset -= skip;
}
}
/// <summary>
/// 从文件系统流中读取一个字节。
/// </summary>
/// <returns>读取的字节,若已经到达文件结尾,则返回 -1。</returns>
protected override int ReadByte()
{
return InternalRead();
}
/// <summary>
/// 从文件系统流中读取二进制流。
/// </summary>
/// <param name="buffer">存储读取文件内容的二进制流。</param>
/// <param name="startIndex">存储读取文件内容的二进制流的起始位置。</param>
/// <param name="length">存储读取文件内容的二进制流的长度。</param>
/// <returns>实际读取了多少字节。</returns>
protected override int Read(byte[] buffer, int startIndex, int length)
{
byte[] result = null;
int bytesRead = InternalRead(length, out result);
Array.Copy(result, 0, buffer, startIndex, bytesRead);
return bytesRead;
}
/// <summary>
/// 向文件系统流中写入一个字节。
/// </summary>
/// <param name="value">要写入的字节。</param>
protected override void WriteByte(byte value)
{
throw new GameFrameworkException("WriteByte is not supported in AndroidFileSystemStream.");
}
/// <summary>
/// 向文件系统流中写入二进制流。
/// </summary>
/// <param name="buffer">存储写入文件内容的二进制流。</param>
/// <param name="startIndex">存储写入文件内容的二进制流的起始位置。</param>
/// <param name="length">存储写入文件内容的二进制流的长度。</param>
protected override void Write(byte[] buffer, int startIndex, int length)
{
throw new GameFrameworkException("Write is not supported in AndroidFileSystemStream.");
}
/// <summary>
/// 将文件系统流立刻更新到存储介质中。
/// </summary>
protected override void Flush()
{
throw new GameFrameworkException("Flush is not supported in AndroidFileSystemStream.");
}
/// <summary>
/// 关闭文件系统流。
/// </summary>
protected override void Close()
{
InternalClose();
m_FileStream.Dispose();
}
private AndroidJavaObject InternalOpen(string fileName)
{
return s_AssetManager.Call<AndroidJavaObject>("open", fileName);
}
private int InternalAvailable()
{
return m_FileStream.Call<int>("available");
}
private void InternalClose()
{
m_FileStream.Call("close");
}
private int InternalRead()
{
return m_FileStream.Call<int>("read");
}
private int InternalRead(int length, out byte[] result)
{
#if UNITY_2019_2_OR_NEWER
#pragma warning disable CS0618
#endif
IntPtr resultPtr = AndroidJNI.NewByteArray(length);
#if UNITY_2019_2_OR_NEWER
#pragma warning restore CS0618
#endif
int offset = 0;
int bytesLeft = length;
while (bytesLeft > 0)
{
s_InternalReadArgs[0] = new jvalue() { l = resultPtr };
s_InternalReadArgs[1] = new jvalue() { i = offset };
s_InternalReadArgs[2] = new jvalue() { i = bytesLeft };
int bytesRead = AndroidJNI.CallIntMethod(m_FileStreamRawObject, s_InternalReadMethodId, s_InternalReadArgs);
if (bytesRead <= 0)
{
break;
}
offset += bytesRead;
bytesLeft -= bytesRead;
}
#if UNITY_2019_2_OR_NEWER
#pragma warning disable CS0618
#endif
result = AndroidJNI.FromByteArray(resultPtr);
#if UNITY_2019_2_OR_NEWER
#pragma warning restore CS0618
#endif
AndroidJNI.DeleteLocalRef(resultPtr);
return offset;
}
private void InternalReset()
{
m_FileStream.Call("reset");
}
private long InternalSkip(long offset)
{
return m_FileStream.Call<long>("skip", offset);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e91d57307e5c7674c855d299cfb466b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.FileSystem;
using System;
namespace UnityGameFramework.Runtime
{
/// <summary>
/// 默认文件系统辅助器。
/// </summary>
public class DefaultFileSystemHelper : FileSystemHelperBase
{
private const string AndroidFileSystemPrefixString = "jar:";
/// <summary>
/// 创建文件系统流。
/// </summary>
/// <param name="fullPath">要加载的文件系统的完整路径。</param>
/// <param name="access">要加载的文件系统的访问方式。</param>
/// <param name="createNew">是否创建新的文件系统流。</param>
/// <returns>创建的文件系统流。</returns>
public override FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew)
{
if (fullPath.StartsWith(AndroidFileSystemPrefixString, StringComparison.Ordinal))
{
return new AndroidFileSystemStream(fullPath, access, createNew);
}
else
{
return new CommonFileSystemStream(fullPath, access, createNew);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab61553d44f971447856311f2f7aef44
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,146 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework.FileSystem;
using System.Collections.Generic;
using UnityEngine;
namespace UnityGameFramework.Runtime
{
/// <summary>
/// 文件系统件。
/// </summary>
[DisallowMultipleComponent]
[AddComponentMenu("Game Framework/File System")]
public sealed class FileSystemComponent : GameFrameworkComponent
{
private IFileSystemManager m_FileSystemManager = null;
[SerializeField]
private string m_FileSystemHelperTypeName = "UnityGameFramework.Runtime.DefaultFileSystemHelper";
[SerializeField]
private FileSystemHelperBase m_CustomFileSystemHelper = null;
/// <summary>
/// 获取文件系统数量。
/// </summary>
public int Count
{
get
{
return m_FileSystemManager.Count;
}
}
/// <summary>
/// 游戏框架组件初始化。
/// </summary>
protected override void Awake()
{
base.Awake();
m_FileSystemManager = GameFrameworkEntry.GetModule<IFileSystemManager>();
if (m_FileSystemManager == null)
{
Log.Fatal("File system manager is invalid.");
return;
}
FileSystemHelperBase fileSystemHelper = Helper.CreateHelper(m_FileSystemHelperTypeName, m_CustomFileSystemHelper);
if (fileSystemHelper == null)
{
Log.Error("Can not create fileSystem helper.");
return;
}
fileSystemHelper.name = "FileSystem Helper";
Transform transform = fileSystemHelper.transform;
transform.SetParent(this.transform);
transform.localScale = Vector3.one;
m_FileSystemManager.SetFileSystemHelper(fileSystemHelper);
}
private void Start()
{
}
/// <summary>
/// 检查是否存在文件系统。
/// </summary>
/// <param name="fullPath">要检查的文件系统的完整路径。</param>
/// <returns>是否存在文件系统。</returns>
public bool HasFileSystem(string fullPath)
{
return m_FileSystemManager.HasFileSystem(fullPath);
}
/// <summary>
/// 获取文件系统。
/// </summary>
/// <param name="fullPath">要获取的文件系统的完整路径。</param>
/// <returns>获取的文件系统。</returns>
public IFileSystem GetFileSystem(string fullPath)
{
return m_FileSystemManager.GetFileSystem(fullPath);
}
/// <summary>
/// 创建文件系统。
/// </summary>
/// <param name="fullPath">要创建的文件系统的完整路径。</param>
/// <param name="access">要创建的文件系统的访问方式。</param>
/// <param name="maxFileCount">要创建的文件系统的最大文件数量。</param>
/// <param name="maxBlockCount">要创建的文件系统的最大块数据数量。</param>
/// <returns>创建的文件系统。</returns>
public IFileSystem CreateFileSystem(string fullPath, FileSystemAccess access, int maxFileCount, int maxBlockCount)
{
return m_FileSystemManager.CreateFileSystem(fullPath, access, maxFileCount, maxBlockCount);
}
/// <summary>
/// 加载文件系统。
/// </summary>
/// <param name="fullPath">要加载的文件系统的完整路径。</param>
/// <param name="access">要加载的文件系统的访问方式。</param>
/// <returns>加载的文件系统。</returns>
public IFileSystem LoadFileSystem(string fullPath, FileSystemAccess access)
{
return m_FileSystemManager.LoadFileSystem(fullPath, access);
}
/// <summary>
/// 销毁文件系统。
/// </summary>
/// <param name="fileSystem">要销毁的文件系统。</param>
/// <param name="deletePhysicalFile">是否删除文件系统对应的物理文件。</param>
public void DestroyFileSystem(IFileSystem fileSystem, bool deletePhysicalFile)
{
m_FileSystemManager.DestroyFileSystem(fileSystem, deletePhysicalFile);
}
/// <summary>
/// 获取所有文件系统集合。
/// </summary>
/// <returns>获取的所有文件系统集合。</returns>
public IFileSystem[] GetAllFileSystems()
{
return m_FileSystemManager.GetAllFileSystems();
}
/// <summary>
/// 获取所有文件系统集合。
/// </summary>
/// <param name="results">获取的所有文件系统集合。</param>
public void GetAllFileSystems(List<IFileSystem> results)
{
m_FileSystemManager.GetAllFileSystems(results);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc49d78dad061a2418e134fc48856bc9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,27 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.FileSystem;
using UnityEngine;
namespace UnityGameFramework.Runtime
{
/// <summary>
/// 文件系统辅助器基类。
/// </summary>
public abstract class FileSystemHelperBase : MonoBehaviour, IFileSystemHelper
{
/// <summary>
/// 创建文件系统流。
/// </summary>
/// <param name="fullPath">要加载的文件系统的完整路径。</param>
/// <param name="access">要加载的文件系统的访问方式。</param>
/// <param name="createNew">是否创建新的文件系统流。</param>
/// <returns>创建的文件系统流。</returns>
public abstract FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40934320d6b918548891a29641dc0a20
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: