初始化
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b32bd69d879747c8bdf5a3e8c313560c
|
||||
timeCreated: 1752544984
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ae98d1b6ba74880a5bdbd3cefd09faa
|
||||
timeCreated: 1752544970
|
||||
@@ -1,59 +0,0 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Luban;
|
||||
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
public sealed partial class Language : Luban.BeanBase
|
||||
{
|
||||
public Language(ByteBuf _buf)
|
||||
{
|
||||
Id = _buf.ReadString();
|
||||
CN = _buf.ReadString();
|
||||
EN = _buf.ReadString();
|
||||
}
|
||||
|
||||
public static Language DeserializeLanguage(ByteBuf _buf)
|
||||
{
|
||||
return new Language(_buf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// id
|
||||
/// </summary>
|
||||
public readonly string Id;
|
||||
/// <summary>
|
||||
/// 中文
|
||||
/// </summary>
|
||||
public readonly string CN;
|
||||
/// <summary>
|
||||
/// 英文
|
||||
/// </summary>
|
||||
public readonly string EN;
|
||||
|
||||
public const int __ID__ = -1548945544;
|
||||
public override int GetTypeId() => __ID__;
|
||||
|
||||
public void ResolveRef(Tables tables)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{ "
|
||||
+ "id:" + Id + ","
|
||||
+ "CN:" + CN + ","
|
||||
+ "EN:" + EN + ","
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Luban;
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
public partial class Tables
|
||||
{
|
||||
public TbLanguage TbLanguage {get; }
|
||||
|
||||
public Tables(System.Func<string, ByteBuf> loader)
|
||||
{
|
||||
TbLanguage = new TbLanguage(loader("tblanguage"));
|
||||
ResolveRef();
|
||||
}
|
||||
|
||||
private void ResolveRef()
|
||||
{
|
||||
TbLanguage.ResolveRef(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Luban;
|
||||
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
public partial class TbLanguage
|
||||
{
|
||||
private readonly System.Collections.Generic.Dictionary<string, Language> _dataMap;
|
||||
private readonly System.Collections.Generic.List<Language> _dataList;
|
||||
|
||||
public TbLanguage(ByteBuf _buf)
|
||||
{
|
||||
_dataMap = new System.Collections.Generic.Dictionary<string, Language>();
|
||||
_dataList = new System.Collections.Generic.List<Language>();
|
||||
|
||||
for(int n = _buf.ReadSize() ; n > 0 ; --n)
|
||||
{
|
||||
Language _v;
|
||||
_v = global::cfg.Language.DeserializeLanguage(_buf);
|
||||
_dataList.Add(_v);
|
||||
_dataMap.Add(_v.Id, _v);
|
||||
}
|
||||
}
|
||||
|
||||
public System.Collections.Generic.Dictionary<string, Language> DataMap => _dataMap;
|
||||
public System.Collections.Generic.List<Language> DataList => _dataList;
|
||||
|
||||
public Language GetOrDefault(string key) => _dataMap.TryGetValue(key, out var v) ? v : null;
|
||||
public Language Get(string key) => _dataMap[key];
|
||||
public Language this[string key] => _dataMap[key];
|
||||
|
||||
public void ResolveRef(Tables tables)
|
||||
{
|
||||
foreach(var _v in _dataList)
|
||||
{
|
||||
_v.ResolveRef(tables);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Luban;
|
||||
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
public partial struct vector2
|
||||
{
|
||||
public vector2(ByteBuf _buf)
|
||||
{
|
||||
X = _buf.ReadFloat();
|
||||
Y = _buf.ReadFloat();
|
||||
}
|
||||
|
||||
public static vector2 Deserializevector2(ByteBuf _buf)
|
||||
{
|
||||
return new vector2(_buf);
|
||||
}
|
||||
|
||||
public readonly float X;
|
||||
public readonly float Y;
|
||||
|
||||
|
||||
public void ResolveRef(Tables tables)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{ "
|
||||
+ "x:" + X + ","
|
||||
+ "y:" + Y + ","
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Luban;
|
||||
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
public partial struct vector3
|
||||
{
|
||||
public vector3(ByteBuf _buf)
|
||||
{
|
||||
X = _buf.ReadFloat();
|
||||
Y = _buf.ReadFloat();
|
||||
Z = _buf.ReadFloat();
|
||||
}
|
||||
|
||||
public static vector3 Deserializevector3(ByteBuf _buf)
|
||||
{
|
||||
return new vector3(_buf);
|
||||
}
|
||||
|
||||
public readonly float X;
|
||||
public readonly float Y;
|
||||
public readonly float Z;
|
||||
|
||||
|
||||
public void ResolveRef(Tables tables)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{ "
|
||||
+ "x:" + X + ","
|
||||
+ "y:" + Y + ","
|
||||
+ "z:" + Z + ","
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76805dce6fb46a24d9adcbe822387088
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Luban;
|
||||
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
public partial struct vector4
|
||||
{
|
||||
public vector4(ByteBuf _buf)
|
||||
{
|
||||
X = _buf.ReadFloat();
|
||||
Y = _buf.ReadFloat();
|
||||
Z = _buf.ReadFloat();
|
||||
W = _buf.ReadFloat();
|
||||
}
|
||||
|
||||
public static vector4 Deserializevector4(ByteBuf _buf)
|
||||
{
|
||||
return new vector4(_buf);
|
||||
}
|
||||
|
||||
public readonly float X;
|
||||
public readonly float Y;
|
||||
public readonly float Z;
|
||||
public readonly float W;
|
||||
|
||||
|
||||
public void ResolveRef(Tables tables)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{ "
|
||||
+ "x:" + X + ","
|
||||
+ "y:" + Y + ","
|
||||
+ "z:" + Z + ","
|
||||
+ "w:" + W + ","
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8b419c77ca0c9847ab9b9bf509dc546
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,25 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public partial class UIMainView : UIViewBase
|
||||
{
|
||||
public override string PrefabPath => "Prefabs/UI/MainView";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Button StarBtn;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Text StarBtnText;
|
||||
public override void PreLoad(GameObject view)
|
||||
{
|
||||
base.PreLoad(view);
|
||||
|
||||
StarBtn = GetGameObject(nameof(StarBtn)).GetComponent<Button>();
|
||||
StarBtnText = GetGameObject(nameof(StarBtnText)).GetComponent<Text>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c5ae2248a663cd4f9fc66ca55751f19
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Collections;
|
||||
using CreatGame.UI;
|
||||
using UnityEditor.VersionControl;
|
||||
|
||||
namespace CreatGame
|
||||
{
|
||||
public class GameLogic : Singleton<GameLogic>
|
||||
{
|
||||
public IEnumerator Start()
|
||||
{
|
||||
AssetBundle.AssetBundleManager.Instance.Initialize();
|
||||
while (true)
|
||||
{
|
||||
if (AssetBundle.AssetBundleManager.Instance.IsInitializeAsync)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
UIManager.Instance.OpenView<UI.UIMainView>(UILayer.Main);
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
AssetBundle.AssetBundleManager.Instance.ReleaseAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bed5572501d4f149c84589085bec321
|
||||
timeCreated: 1752463362
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 341fa7946cf046c1ae980f1f3efabbda
|
||||
timeCreated: 1752547061
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12e2e1bf012c4e74951a89b77d46f08c
|
||||
timeCreated: 1752547082
|
||||
@@ -1,101 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.ResourceLocations;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||
|
||||
public class AddressableUpdater : MonoBehaviour
|
||||
{
|
||||
public string remoteCatalogUrl; // CDN catalog 路径
|
||||
|
||||
public Action<float> OnProgressChanged; // 进度更新回调 0~1
|
||||
public Action<float> OnSpeedChanged; // 下载速度更新 (KB/s)
|
||||
public Action<float> OnDownloadSizeFetched; // 总下载大小回调 (MB)
|
||||
public Action OnCompleted; // 下载完成
|
||||
|
||||
private float lastDownloadedBytes = 0;
|
||||
private float updateCheckInterval = 0.5f;
|
||||
|
||||
void Start()
|
||||
{
|
||||
StartCoroutine(UpdateAddressables());
|
||||
}
|
||||
|
||||
IEnumerator UpdateAddressables()
|
||||
{
|
||||
// 1. 初始化 Addressables
|
||||
var initHandle = Addressables.InitializeAsync();
|
||||
yield return initHandle;
|
||||
|
||||
// 2. 更新 Catalog
|
||||
var catalogHandle = Addressables.UpdateCatalogs();
|
||||
yield return catalogHandle;
|
||||
|
||||
List<IResourceLocator> catalogs = catalogHandle.Result;
|
||||
|
||||
// 3. 获取资源下载大小
|
||||
var sizeHandle = Addressables.GetDownloadSizeAsync(Addressables.ResourceManager.ResourceProviders);
|
||||
yield return sizeHandle;
|
||||
|
||||
long totalDownloadSize = sizeHandle.Result;
|
||||
|
||||
if (totalDownloadSize <= 0)
|
||||
{
|
||||
Debug.Log("无需更新");
|
||||
OnCompleted?.Invoke();
|
||||
yield break;
|
||||
}
|
||||
|
||||
OnDownloadSizeFetched?.Invoke(totalDownloadSize / (1024f * 1024f)); // MB
|
||||
|
||||
// 4. 开始下载所有资源
|
||||
var downloadHandle = Addressables.DownloadDependenciesAsync(Addressables.ResourceManager.ResourceProviders, true);
|
||||
StartCoroutine(TrackDownloadProgress(downloadHandle, totalDownloadSize));
|
||||
yield return downloadHandle;
|
||||
|
||||
if (downloadHandle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
Debug.Log("热更完成!");
|
||||
OnCompleted?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("热更失败!");
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator TrackDownloadProgress(AsyncOperationHandle handle, long totalSize)
|
||||
{
|
||||
float lastTime = Time.realtimeSinceStartup;
|
||||
float lastDownloaded = 0;
|
||||
|
||||
while (!handle.IsDone)
|
||||
{
|
||||
float percent = handle.PercentComplete;
|
||||
OnProgressChanged?.Invoke(percent);
|
||||
|
||||
float currentTime = Time.realtimeSinceStartup;
|
||||
float elapsed = currentTime - lastTime;
|
||||
|
||||
if (elapsed >= updateCheckInterval)
|
||||
{
|
||||
float currentDownloaded = percent * totalSize;
|
||||
float speed = (currentDownloaded - lastDownloaded) / elapsed / 1024f; // KB/s
|
||||
|
||||
OnSpeedChanged?.Invoke(speed);
|
||||
|
||||
lastTime = currentTime;
|
||||
lastDownloaded = currentDownloaded;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
OnProgressChanged?.Invoke(1f);
|
||||
OnSpeedChanged?.Invoke(0);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bbf6478f2ed4dd0ac123f2a03fe3695
|
||||
timeCreated: 1752549280
|
||||
@@ -1,209 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.ResourceManagement.ResourceLocations;
|
||||
using UnityEngine.U2D;
|
||||
|
||||
namespace CreatGame.AssetBundle
|
||||
{
|
||||
public class AssetBundleManager : Singleton<AssetBundleManager>
|
||||
{
|
||||
private class AssetBundleData
|
||||
{
|
||||
public string assetBundleName;
|
||||
public GameObject assetBundle;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private Dictionary<string, AssetBundleData> m_AssetBundles;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private Dictionary<string, SpriteAtlas> m_SpriteAtlasCache;
|
||||
/// <summary>
|
||||
/// 是否初始化完成
|
||||
/// </summary>
|
||||
public bool IsInitializeAsync;
|
||||
/// <summary>
|
||||
/// 需要初始化Addressble系统
|
||||
/// </summary>
|
||||
public AssetBundleManager()
|
||||
{
|
||||
IsInitializeAsync = false;
|
||||
m_AssetBundles = new Dictionary<string, AssetBundleData>();
|
||||
m_SpriteAtlasCache = new Dictionary<string, SpriteAtlas>();
|
||||
|
||||
|
||||
Addressables.InitializeAsync();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Addressables.InitializeAsync().Completed += OnInitializeCompleted;
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化信息回调
|
||||
/// </summary>
|
||||
private void OnInitializeCompleted(AsyncOperationHandle<IResourceLocator> operationHandle)
|
||||
{
|
||||
if (operationHandle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
Debug.Log("Addressables initialization succeeded");
|
||||
#region MyRegion
|
||||
// IResourceLocator locator = operationHandle.Result;
|
||||
// foreach (object locatorKey in locator.Keys)
|
||||
// {
|
||||
// locator.Locate(locatorKey,typeof(UnityEngine.Object),out IList<IResourceLocation> locations);
|
||||
// if (locations == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// foreach (var location in locations)
|
||||
// {
|
||||
// string key = location.PrimaryKey;
|
||||
// Addressables.LoadAssetAsync<UnityEngine.Object>(key).Completed += (handle) =>
|
||||
// {
|
||||
// if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
// {
|
||||
// Debug.Log("Addressables load asset succeeded");
|
||||
// var asset = handle.Result;
|
||||
// GameObject.Instantiate(asset);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
IsInitializeAsync = true;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 异步加载资源
|
||||
/// </summary>
|
||||
/// <param name="assetBundleName"></param>
|
||||
/// <param name="callback"></param>
|
||||
public void LoadGameObjectAsync(string assetBundleName, Action<GameObject> callback)
|
||||
{
|
||||
if (m_AssetBundles.TryGetValue(assetBundleName, out var bundle))
|
||||
{
|
||||
callback.Invoke(GameObject.Instantiate(bundle.assetBundle));
|
||||
return;
|
||||
}
|
||||
|
||||
Addressables.LoadAssetAsync<GameObject>(assetBundleName).Completed += (handle) =>
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
var assetData = CacheAssetBundles(assetBundleName, handle.Result);
|
||||
Addressables.Release(handle);
|
||||
callback?.Invoke(GameObject.Instantiate(assetData.assetBundle));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"assetBundleName = {assetBundleName} 加载失败 Status = {handle.Status}");
|
||||
callback?.Invoke(null);
|
||||
}
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 同步等待加载资源
|
||||
/// </summary>
|
||||
/// <param name="assetBundleName"></param>
|
||||
public GameObject LoadGameObject(string assetBundleName)
|
||||
{
|
||||
if (m_AssetBundles.TryGetValue(assetBundleName, out var bundle))
|
||||
{
|
||||
return GameObject.Instantiate(bundle.assetBundle);
|
||||
}
|
||||
|
||||
var handle = Addressables.LoadAssetAsync<GameObject>(assetBundleName);
|
||||
handle.WaitForCompletion();
|
||||
if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
bundle = CacheAssetBundles(assetBundleName, handle.Result);
|
||||
Addressables.Release(handle);
|
||||
|
||||
return GameObject.Instantiate(bundle.assetBundle);
|
||||
}
|
||||
|
||||
Debug.LogError("资源加载失败");
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 缓存加载出来的资源
|
||||
/// </summary>
|
||||
/// <param name="bundleName"></param>
|
||||
/// <param name="bundle"></param>
|
||||
/// <returns></returns>
|
||||
private AssetBundleData CacheAssetBundles(string bundleName, GameObject bundle = null)
|
||||
{
|
||||
var data = new AssetBundleData(){assetBundleName = bundleName, assetBundle = bundle};
|
||||
m_AssetBundles.Add(bundleName, data);
|
||||
return data;
|
||||
}
|
||||
/// <summary>
|
||||
/// 同步加载图集
|
||||
/// </summary>
|
||||
/// <param name="atlasName"></param>
|
||||
/// <returns></returns>
|
||||
public SpriteAtlas LoadSpriteAtlas(string atlasName)
|
||||
{
|
||||
if (m_SpriteAtlasCache.TryGetValue(atlasName, out var atlas))
|
||||
{
|
||||
return atlas;
|
||||
}
|
||||
|
||||
var handle = Addressables.LoadAssetAsync<SpriteAtlas>(atlasName);
|
||||
handle.WaitForCompletion();
|
||||
if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
atlas = handle.Result;
|
||||
Addressables.Release(handle);
|
||||
m_SpriteAtlasCache.Add(atlasName, atlas);
|
||||
return atlas;
|
||||
}
|
||||
|
||||
Debug.LogError($"图集加载失败 atlasName = {atlasName} Status = {handle.Status}");
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 异步加载图集
|
||||
/// </summary>
|
||||
/// <param name="assetBundleName"></param>
|
||||
/// <param name="callback"></param>
|
||||
public void LoadSpriteAsync(string atlasName, Action<SpriteAtlas> callback)
|
||||
{
|
||||
if (m_SpriteAtlasCache.TryGetValue(atlasName, out var atlas))
|
||||
{
|
||||
callback.Invoke(atlas);
|
||||
return;
|
||||
}
|
||||
Addressables.LoadAssetAsync<SpriteAtlas>(atlasName).Completed += (handle) =>
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
atlas = handle.Result;
|
||||
Addressables.Release(handle);
|
||||
m_SpriteAtlasCache.Add(atlasName, atlas);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"图集加载失败 atlasName = {atlasName} Status = {handle.Status}");
|
||||
callback?.Invoke(null);
|
||||
}
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 释放所有的资源
|
||||
/// </summary>
|
||||
public void ReleaseAll()
|
||||
{
|
||||
m_AssetBundles.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01bfbdbb68f24f39bf248e1ce2907783
|
||||
timeCreated: 1752547273
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 726911973e4b4b129678928347fc1de4
|
||||
timeCreated: 1752547090
|
||||
@@ -1,35 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Net.Mime;
|
||||
using Luban;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CreatGame
|
||||
{
|
||||
/// <summary>
|
||||
/// 表格
|
||||
/// </summary>
|
||||
public class ConfigManager : Singleton<ConfigManager>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private readonly cfg.Tables tables;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public cfg.Tables Tables => tables;
|
||||
|
||||
public ConfigManager()
|
||||
{
|
||||
var tablesCtor = typeof(cfg.Tables).GetConstructors()[0];
|
||||
// 根据cfg.Tables的构造函数的Loader的返回值类型决定使用json还是ByteBuf Loader
|
||||
System.Delegate loader = new System.Func<string, ByteBuf>(LoadByteBuf);
|
||||
tables = (cfg.Tables)tablesCtor.Invoke(new object[] {loader});
|
||||
}
|
||||
|
||||
private static ByteBuf LoadByteBuf(string file)
|
||||
{
|
||||
return new ByteBuf(File.ReadAllBytes($"{Application.dataPath}/AssetBundle/Config/{file}.bytes"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60fd032406824917a60af497b179c08f
|
||||
timeCreated: 1752717676
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f912db237c54e96b83e9c11a7ab6889
|
||||
timeCreated: 1752547100
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f208809c54934f6f911cc29d97c3519a
|
||||
timeCreated: 1752550099
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 窗口层级
|
||||
/// </summary>
|
||||
public enum UILayer
|
||||
{
|
||||
Main,
|
||||
Popup,
|
||||
Notify,
|
||||
System,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a02dc47e9bb442079f60800e51c49b6e
|
||||
timeCreated: 1752551035
|
||||
@@ -1,76 +0,0 @@
|
||||
using UnityEngine;
|
||||
using CreatGame.AssetBundle;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.U2D;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// ui上的资源加载器
|
||||
/// </summary>
|
||||
public class UILoader
|
||||
{
|
||||
private List<GameObject> m_GameObjectCache = new List<GameObject>();
|
||||
private List<Sprite> m_SpriteCache = new List<Sprite>();
|
||||
/// <summary>
|
||||
/// 同步资源加载
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public GameObject LoadGameObject(string name)
|
||||
{
|
||||
var gameObj = AssetBundleManager.Instance.LoadGameObject(name);
|
||||
if (gameObj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
m_GameObjectCache.Add(gameObj);
|
||||
|
||||
return gameObj;
|
||||
}
|
||||
/// <summary>
|
||||
/// 异步加载预制件
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="callback"></param>
|
||||
public void LoadGameObjectAsync(string name, System.Action<GameObject> callback)
|
||||
{
|
||||
AssetBundleManager.Instance.LoadGameObjectAsync(name, (obj) =>
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
m_GameObjectCache.Add(obj);
|
||||
}
|
||||
callback(obj);
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="atlasName"></param>
|
||||
/// <param name="spriteName"></param>
|
||||
/// <returns></returns>
|
||||
public Sprite LoadSprite(string atlasName, string spriteName)
|
||||
{
|
||||
var spriteAtlas = AssetBundleManager.Instance.LoadSpriteAtlas(atlasName);
|
||||
if (spriteAtlas == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return spriteAtlas.GetSprite(spriteName);
|
||||
}
|
||||
|
||||
public void DisposeGameObjectCache()
|
||||
{
|
||||
var count = m_GameObjectCache.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var obj = m_GameObjectCache[0];
|
||||
m_GameObjectCache.RemoveAt(0);
|
||||
GameObject.Destroy(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd77ddfde9dc430eb31244ee82bc2147
|
||||
timeCreated: 1753323201
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0631ad95508b427c96e7748c13e0eb59
|
||||
timeCreated: 1752550115
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2e66ce219a441108094ae188afcc745
|
||||
timeCreated: 1752663372
|
||||
@@ -1,20 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public class MainItem : MonoBehaviour
|
||||
{
|
||||
public Text text;
|
||||
|
||||
void ScrollCellIndex (int idx)
|
||||
{
|
||||
string name = "Cell " + idx.ToString ();
|
||||
if (text != null)
|
||||
{
|
||||
text.text = name;
|
||||
}
|
||||
gameObject.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 391eb6d877254380bf561b14e4be836f
|
||||
timeCreated: 1752925668
|
||||
@@ -1,20 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public partial class UIMainView
|
||||
{
|
||||
public override void InitView()
|
||||
{
|
||||
base.InitView();
|
||||
StarBtn.onClick.AddListener(OnStarBtnClick);
|
||||
}
|
||||
|
||||
private void OnStarBtnClick()
|
||||
{
|
||||
StarBtnText.text = ConfigManager.Instance.Tables.TbLanguage.Get("Main_BtnTitle_Star").CN;
|
||||
Debug.Log("OnStarBtnClick");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19a056c97ef74d2697f0bd0e7efc3651
|
||||
timeCreated: 1752663384
|
||||
@@ -1,29 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用的导出预制件的基类
|
||||
/// </summary>
|
||||
public class UIComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 窗口预制件
|
||||
/// </summary>
|
||||
protected GameObject m_ComponentObject;
|
||||
/// <summary>
|
||||
/// 导出脚本
|
||||
/// </summary>
|
||||
protected UIComponentExport m_ViewExport;
|
||||
/// <summary>
|
||||
/// 是否加载完成
|
||||
/// </summary>
|
||||
public bool IsPreLoad = false;
|
||||
public virtual void PreLoad(GameObject obj)
|
||||
{
|
||||
m_ComponentObject = obj;
|
||||
m_ViewExport = obj.GetComponent<UIComponentExport>();
|
||||
IsPreLoad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba52eedd767b46ae90e720030c75503f
|
||||
timeCreated: 1752945611
|
||||
@@ -1,95 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using CreatGame.AssetBundle;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public class UIManager : Singleton<UIManager>
|
||||
{
|
||||
private GameObject m_UIRoot;
|
||||
private Dictionary<UILayer,GameObject> m_UILayers;
|
||||
private Dictionary<UILayer, Queue<UIViewBase>> m_Windows;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public UIManager()
|
||||
{
|
||||
m_UIRoot = GameObject.Find("UIRoot");
|
||||
InitLayer();
|
||||
m_Windows = new Dictionary<UILayer, Queue<UIViewBase>>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化layer层的预制件
|
||||
/// </summary>
|
||||
private void InitLayer()
|
||||
{
|
||||
if (m_UIRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_UILayers = new Dictionary<UILayer, GameObject>();
|
||||
|
||||
foreach (var layer in Enum.GetValues(typeof(UILayer)))
|
||||
{
|
||||
var layerObj = m_UIRoot.transform.Find(Enum.GetName(typeof(UILayer), layer)).gameObject;
|
||||
layerObj.transform.SetParent(m_UIRoot.transform);
|
||||
layerObj.transform.localScale = Vector3.one;
|
||||
layerObj.transform.localPosition = Vector3.zero;
|
||||
layerObj.layer = LayerMask.NameToLayer("UI");
|
||||
m_UILayers.Add((UILayer)layer,layerObj);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="layer"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public UIViewBase OpenView<T>(UILayer layer) where T : UIViewBase , new()
|
||||
{
|
||||
var view = new T();
|
||||
//加载预制件
|
||||
AssetBundleManager.Instance.LoadGameObjectAsync(view.PrefabPath, (obj) =>
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
Debug.LogError($"窗口加载失败{typeof(T).Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
view.PreLoad(obj);
|
||||
if (m_UILayers.TryGetValue(layer, out var uiLayer))
|
||||
{
|
||||
obj.transform.SetParent(uiLayer.transform);
|
||||
obj.transform.localPosition = Vector3.zero;
|
||||
obj.transform.localScale = Vector3.one;
|
||||
}
|
||||
view.InitView();
|
||||
|
||||
if (m_Windows.ContainsKey(layer) == false)
|
||||
{
|
||||
m_Windows.Add(layer, new Queue<UIViewBase>());
|
||||
}
|
||||
|
||||
m_Windows[layer].Enqueue(view);
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="layer"></param>
|
||||
public void CloseView(UILayer layer)
|
||||
{
|
||||
if (m_Windows.ContainsKey(layer))
|
||||
{
|
||||
var view = m_Windows[layer].Dequeue();
|
||||
view.CloseView();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b62361e051d040d696ac9c2485f57a3b
|
||||
timeCreated: 1752550917
|
||||
@@ -1,49 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public class UIViewBase : UILoader
|
||||
{
|
||||
/// <summary>
|
||||
/// 预制件的Addressables地址
|
||||
/// 由导出代码自己添加
|
||||
/// </summary>
|
||||
public virtual string PrefabPath { get; set; }
|
||||
/// <summary>
|
||||
/// 窗口预制件
|
||||
/// </summary>
|
||||
protected GameObject m_ViewObject;
|
||||
/// <summary>
|
||||
/// 导出脚本
|
||||
/// </summary>
|
||||
protected UIViewExport m_ViewExport;
|
||||
/// <summary>
|
||||
/// 是否加载完成
|
||||
/// </summary>
|
||||
public bool IsPreLoad = false;
|
||||
/// <summary>
|
||||
/// 加载窗口的时候需要预先加载的东西
|
||||
/// </summary>
|
||||
public virtual void PreLoad(GameObject viewObject)
|
||||
{
|
||||
m_ViewObject = viewObject;
|
||||
m_ViewExport = viewObject.GetComponent<UIViewExport>();
|
||||
IsPreLoad = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化界面
|
||||
/// </summary>
|
||||
public virtual void InitView()
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 关闭窗口的时候的调用
|
||||
/// </summary>
|
||||
public virtual void CloseView()
|
||||
{
|
||||
DisposeGameObjectCache();
|
||||
GameObject.Destroy(m_ViewObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f48b029bf9fe4664a47a4ede05f4d396
|
||||
timeCreated: 1752550141
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class GameStar : MonoBehaviour
|
||||
{
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
DontDestroyOnLoad(gameObject);
|
||||
StartCoroutine(CreatGame.GameLogic.Instance.Start());
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
CreatGame.GameLogic.Instance.Destroy();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dab0061814d076f4781a6ca28229dc2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 574ee34052894bd79966fa8ad35a0335
|
||||
timeCreated: 1752463436
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05649470a3a64898bac0e32fd05aac14
|
||||
timeCreated: 1753497036
|
||||
@@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CreatGame
|
||||
{
|
||||
public class CoroutineManager : MonoBehaviour
|
||||
{
|
||||
#region Instance
|
||||
private static CoroutineManager _instance;
|
||||
|
||||
public static CoroutineManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
var gameObj = new GameObject("CoroutineManager");
|
||||
_instance = gameObj.AddComponent<CoroutineManager>();
|
||||
DontDestroyOnLoad(gameObj);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private ulong coroutineId = 0;
|
||||
private ulong GetNextId()
|
||||
{
|
||||
return ++coroutineId;
|
||||
}
|
||||
|
||||
private Dictionary<ulong,Coroutine> coroutines = new Dictionary<ulong,Coroutine>();
|
||||
|
||||
public ulong StartC(IEnumerator routine)
|
||||
{
|
||||
var id = GetNextId();
|
||||
var coroutine = StartCoroutine(routine);
|
||||
coroutines.Add(id, coroutine);
|
||||
return id;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="time">间隔时间</param>
|
||||
/// <param name="isFirst">是否立即执行</param>
|
||||
/// <param name="loop">是否循环</param>
|
||||
/// <param name="action">方法</param>
|
||||
public ulong StartC(float time,bool isFirst , bool loop, Action action)
|
||||
{
|
||||
var id = StartC(LoopCoroutine(time,isFirst,loop,action));
|
||||
return id;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator LoopCoroutine(float time,bool isFirst ,bool loop, Action action)
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
action.Invoke();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(time);
|
||||
action.Invoke();
|
||||
if (!loop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StopC(ulong id)
|
||||
{
|
||||
if (coroutines.ContainsKey(id))
|
||||
{
|
||||
StopCoroutine(coroutines[id]);
|
||||
coroutines.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7089d863c3ed4fb0bc6d7ddcb8488817
|
||||
timeCreated: 1753497047
|
||||
@@ -1,36 +0,0 @@
|
||||
namespace CreatGame
|
||||
{
|
||||
public class Singleton<T> where T : class, new()
|
||||
{
|
||||
private static T _instance;
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
protected Singleton()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单例对象(线程安全,双重锁定)
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06769352e6416554e8adc475a44e9d43
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07fbcc20f70d4d90bce50c964419e32d
|
||||
timeCreated: 1752636609
|
||||
@@ -1,38 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public class UIComponentExport : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public class UIEntry
|
||||
{
|
||||
public string key;
|
||||
public GameObject prefab;
|
||||
public string selectedComponentName; // 存储选择的组件类型名
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<UIEntry> entries = new List<UIEntry>();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public GameObject GetGameObject(string name)
|
||||
{
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
if (entries[i].key == name)
|
||||
{
|
||||
return entries[i].prefab;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d94101161a144f17b4b80530abe93975
|
||||
timeCreated: 1752945103
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7741c712b36544fc99b98679783c3129
|
||||
timeCreated: 1753339331
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public delegate void OnSelectCallback(int index);
|
||||
/// <summary>
|
||||
/// 选中列表
|
||||
/// </summary>
|
||||
public class UISelectList : MonoBehaviour
|
||||
{
|
||||
public OnSelectCallback onSelectCallback;
|
||||
private List<Button> m_buttonList = new List<Button>();
|
||||
private void Awake()
|
||||
{
|
||||
m_buttonList = new List<Button>();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void Start()
|
||||
{
|
||||
var childCount= transform.childCount;
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
var button = transform.GetChild(i).GetComponent<Button>();
|
||||
if (button != null)
|
||||
{
|
||||
m_buttonList.Add(button);
|
||||
button.onClick.AddListener(() => { OnClick(button); });
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="btn"></param>
|
||||
private void OnClick(Button btn)
|
||||
{
|
||||
onSelectCallback?.Invoke(m_buttonList.IndexOf(btn));
|
||||
}
|
||||
|
||||
public int Count => m_buttonList.Count;
|
||||
|
||||
public Transform this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= m_buttonList.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return m_buttonList[index].transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52241bceb69a4f07be09e3dc319276dc
|
||||
timeCreated: 1753341533
|
||||
@@ -1,17 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CreatGame.UI
|
||||
{
|
||||
public class UISelected : MonoBehaviour
|
||||
{
|
||||
public int index = -1;
|
||||
/// <summary>
|
||||
/// 选中状态
|
||||
/// </summary>
|
||||
public GameObject selected;
|
||||
/// <summary>
|
||||
/// 未选中状态
|
||||
/// </summary>
|
||||
public GameObject unSelected;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20f38d816dc54bcb9ef57888b31a481d
|
||||
timeCreated: 1753339357
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class UIViewExport : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public class UIEntry
|
||||
{
|
||||
public string key;
|
||||
public GameObject prefab;
|
||||
public string selectedComponentName; // 存储选择的组件类型名
|
||||
}
|
||||
|
||||
public List<UIEntry> entries = new List<UIEntry>();
|
||||
|
||||
public GameObject GetGameObject(string name)
|
||||
{
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
if (entries[i].key == name)
|
||||
{
|
||||
return entries[i].prefab;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7f07a01cdb5c7c4aa72a3a420035842
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dce5d6d618839f4f9e0e9d32c5d0699
|
||||
guid: 217bb07fcea56ab42b8e338a8d59c9a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
99
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/ConsoleProDebug.cs
vendored
Normal file
99
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/ConsoleProDebug.cs
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
#if UNITY_EDITOR
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
public static class ConsoleProDebug
|
||||
{
|
||||
// Clear the console and the native console
|
||||
public static void Clear()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if(ConsoleClearMethod != null)
|
||||
{
|
||||
ConsoleClearMethod.Invoke(null, null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send a log to a specific filter regardless of contents
|
||||
// Ex: ConsoleProDebug.LogToFilter("Hi", "CustomFilter");
|
||||
public static void LogToFilter(string inLog, string inFilterName, UnityEngine.Object inContext = null)
|
||||
{
|
||||
Debug.Log(inLog + "\nCPAPI:{\"cmd\":\"Filter\", \"name\":\"" + inFilterName + "\"}", inContext);
|
||||
}
|
||||
|
||||
// Send a log as a regular log but change its type in ConsolePro
|
||||
// Ex: ConsoleProDebug.LogAsType("Hi", "Error");
|
||||
public static void LogAsType(string inLog, string inTypeName, UnityEngine.Object inContext = null)
|
||||
{
|
||||
Debug.Log(inLog + "\nCPAPI:{\"cmd\":\"LogType\", \"name\":\"" + inTypeName + "\"}", inContext);
|
||||
}
|
||||
|
||||
// Watch a variable. This will only produce one log entry regardless of how many times it is logged, allowing you to track variables without spam.
|
||||
// Ex:
|
||||
// void Update() {
|
||||
// ConsoleProDebug.Watch("Player X Position", transform.position.x);
|
||||
// }
|
||||
public static void Watch(string inName, string inValue)
|
||||
{
|
||||
Debug.Log(inName + " : " + inValue + "\nCPAPI:{\"cmd\":\"Watch\", \"name\":\"" + inName + "\"}");
|
||||
}
|
||||
|
||||
public static void Search(string inText)
|
||||
{
|
||||
Debug.Log("\nCPAPI:{\"cmd\":\"Search\", \"text\":\"" + inText + "\"}");
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Reflection calls to access Console Pro from runtime
|
||||
private static bool _checkedConsoleClearMethod = false;
|
||||
private static MethodInfo _consoleClearMethod = null;
|
||||
private static MethodInfo ConsoleClearMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_consoleClearMethod == null || !_checkedConsoleClearMethod)
|
||||
{
|
||||
_checkedConsoleClearMethod = true;
|
||||
if(ConsoleWindowType == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_consoleClearMethod = ConsoleWindowType.GetMethod("ClearEntries", BindingFlags.Static | BindingFlags.Public);
|
||||
}
|
||||
|
||||
return _consoleClearMethod;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _checkedConsoleWindowType = false;
|
||||
private static Type _consoleWindowType = null;
|
||||
private static Type ConsoleWindowType
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_consoleWindowType == null || !_checkedConsoleWindowType)
|
||||
{
|
||||
_checkedConsoleWindowType = true;
|
||||
Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
|
||||
for(int iAssembly = 0; iAssembly < assemblies.Length; iAssembly++)
|
||||
{
|
||||
Type[] types = assemblies[iAssembly].GetTypes();
|
||||
for(int iType = 0; iType < types.Length; iType++)
|
||||
{
|
||||
if(types[iType].Name == "ConsolePro3Window")
|
||||
{
|
||||
_consoleWindowType = types[iType];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _consoleWindowType;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
12
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/ConsoleProDebug.cs.meta
vendored
Normal file
12
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/ConsoleProDebug.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30f42e8a12eb842acbe9a63057fb00e4
|
||||
timeCreated: 1469329295
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor Console Pro Documentation.pdf
vendored
Normal file
BIN
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor Console Pro Documentation.pdf
vendored
Normal file
Binary file not shown.
8
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor Console Pro Documentation.pdf.meta
vendored
Normal file
8
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor Console Pro Documentation.pdf.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5de782a9528f04b41a8ba70afba32a61
|
||||
timeCreated: 1498113024
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48f786d98d3d1d24296e6825756cf55a
|
||||
guid: 4bb9fa3b2a6b341a9af20d3b5f03ee13
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
BIN
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor/ConsolePro.Editor.dll
vendored
Normal file
BIN
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor/ConsolePro.Editor.dll
vendored
Normal file
Binary file not shown.
33
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor/ConsolePro.Editor.dll.meta
vendored
Normal file
33
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Editor/ConsolePro.Editor.dll.meta
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2284c517ee274c19a6ba4c1a8c96fb6
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42130aa0870f6df4bb6217cc2e5805c3
|
||||
guid: 3f14d07c8a9074483a59436a3caaad09
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
249
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/ConsoleProRemoteServer.cs
vendored
Normal file
249
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/ConsoleProRemoteServer.cs
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
// Uncomment to use in Editor
|
||||
#define USECONSOLEPROREMOTESERVERINEDITOR
|
||||
|
||||
// #if (UNITY_WP_8_1 || UNITY_WSA)
|
||||
// #define UNSUPPORTEDCONSOLEPROREMOTESERVER
|
||||
// #endif
|
||||
|
||||
#if (!UNITY_EDITOR && DEBUG) || (UNITY_EDITOR && USECONSOLEPROREMOTESERVERINEDITOR)
|
||||
#if !UNSUPPORTEDCONSOLEPROREMOTESERVER
|
||||
#define USECONSOLEPROREMOTESERVER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR && !USECONSOLEPROREMOTESERVER
|
||||
#elif UNSUPPORTEDCONSOLEPROREMOTESERVER
|
||||
#elif !USECONSOLEPROREMOTESERVER
|
||||
#else
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
#if USECONSOLEPROREMOTESERVER
|
||||
using FlyingWormConsole3.LiteNetLib;
|
||||
using FlyingWormConsole3.LiteNetLib.Utils;
|
||||
#endif
|
||||
|
||||
namespace FlyingWormConsole3
|
||||
{
|
||||
#if USECONSOLEPROREMOTESERVER
|
||||
public class ConsoleProRemoteServer : MonoBehaviour, INetEventListener
|
||||
#else
|
||||
public class ConsoleProRemoteServer : MonoBehaviour
|
||||
#endif
|
||||
{
|
||||
public bool useNATPunch = false;
|
||||
public int port = 51000;
|
||||
|
||||
#if UNITY_EDITOR && !USECONSOLEPROREMOTESERVER
|
||||
|
||||
#elif UNSUPPORTEDCONSOLEPROREMOTESERVER
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Debug.Log("Console Pro Remote Server is not supported on this platform");
|
||||
}
|
||||
|
||||
#elif !USECONSOLEPROREMOTESERVER
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Debug.Log("Console Pro Remote Server is disabled in release mode, please use a Development build or define DEBUG to use it");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
private NetManager _netServer;
|
||||
private NetPeer _ourPeer;
|
||||
private NetDataWriter _dataWriter;
|
||||
|
||||
[System.SerializableAttribute]
|
||||
public class QueuedLog
|
||||
{
|
||||
public string timestamp;
|
||||
public string message;
|
||||
public string logType;
|
||||
}
|
||||
|
||||
[NonSerializedAttribute]
|
||||
public List<QueuedLog> logs = new List<QueuedLog>();
|
||||
|
||||
private static ConsoleProRemoteServer instance = null;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if(instance != null)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
instance = this;
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
Debug.Log("#Remote# Starting Console Pro Server on port : " + port);
|
||||
|
||||
_dataWriter = new NetDataWriter();
|
||||
_netServer = new NetManager(this);
|
||||
_netServer.Start(port);
|
||||
_netServer.BroadcastReceiveEnabled = true;
|
||||
_netServer.UpdateTime = 15;
|
||||
_netServer.NatPunchEnabled = useNATPunch;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(_netServer != null)
|
||||
{
|
||||
_netServer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPeerConnected(NetPeer peer)
|
||||
{
|
||||
Debug.Log("#Remote# Connected to " + peer.EndPoint);
|
||||
_ourPeer = peer;
|
||||
}
|
||||
|
||||
public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
|
||||
{
|
||||
Debug.Log("#Remote# Disconnected from " + peer.EndPoint + ", info: " + disconnectInfo.Reason);
|
||||
if (peer == _ourPeer)
|
||||
{
|
||||
_ourPeer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnNetworkError(IPEndPoint endPoint, SocketError socketError)
|
||||
{
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
|
||||
{
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
|
||||
{
|
||||
if(messageType == UnconnectedMessageType.Broadcast)
|
||||
{
|
||||
// Debug.Log("#Remote# Received discovery request. Send discovery response");
|
||||
_netServer.SendUnconnectedMessage(new byte[] {1}, remoteEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPeerDisconnected(NetPeer peer, DisconnectReason reason, int socketErrorCode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnNetworkLatencyUpdate(NetPeer peer, int latency)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnConnectionRequest(ConnectionRequest request)
|
||||
{
|
||||
// Debug.Log("#Remote# Connection requested, accepting");
|
||||
request.AcceptIfKey("Console Pro");
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
Application.RegisterLogCallback(LogCallback);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
Application.RegisterLogCallback(LogCallback);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
Application.RegisterLogCallback(null);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
Application.logMessageReceivedThreaded += LogCallback;
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
Application.logMessageReceivedThreaded -= LogCallback;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public void LogCallback(string logString, string stackTrace, LogType type)
|
||||
{
|
||||
if(!logString.StartsWith("CPIGNORE"))
|
||||
{
|
||||
QueueLog(logString, stackTrace, type);
|
||||
}
|
||||
}
|
||||
|
||||
void QueueLog(string logString, string stackTrace, LogType type)
|
||||
{
|
||||
if(logs.Count > 1000)
|
||||
{
|
||||
while(logs.Count > 1000)
|
||||
{
|
||||
logs.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
#if CSHARP_7_3_OR_NEWER
|
||||
logString = $"{logString}\n{stackTrace}\n";
|
||||
logs.Add(new QueuedLog() { message = logString, logType = type.ToString(), timestamp = $"[{DateTime.Now.ToString("HH:mm:ss")}]" } );
|
||||
#else
|
||||
logString = logString + "\n" + stackTrace + "\n";
|
||||
logs.Add(new QueuedLog() { message = logString, logType = type.ToString(), timestamp = "[" + DateTime.Now.ToString("HH:mm:ss") + "]" } );
|
||||
#endif
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if(_netServer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_netServer.PollEvents();
|
||||
|
||||
if(_ourPeer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(logs.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string cMessage = "";
|
||||
|
||||
foreach(var cLog in logs)
|
||||
{
|
||||
cMessage = JsonUtility.ToJson(cLog);
|
||||
_dataWriter.Reset();
|
||||
_dataWriter.Put(cMessage);
|
||||
_ourPeer.Send(_dataWriter, DeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
logs.Clear();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
12
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/ConsoleProRemoteServer.cs.meta
vendored
Normal file
12
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/ConsoleProRemoteServer.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6bcfaced529e418bb75980b297fda2a
|
||||
timeCreated: 1437614101
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib.meta
vendored
Normal file
9
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib.meta
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c6bd635eeaa04c228b6d342c4758ad7
|
||||
folderAsset: yes
|
||||
timeCreated: 1494014730
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
52
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/BaseChannel.cs
vendored
Normal file
52
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/BaseChannel.cs
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
internal abstract class BaseChannel
|
||||
{
|
||||
protected readonly NetPeer Peer;
|
||||
protected readonly Queue<NetPacket> OutgoingQueue;
|
||||
private int _isAddedToPeerChannelSendQueue;
|
||||
|
||||
public int PacketsInQueue
|
||||
{
|
||||
get { return OutgoingQueue.Count; }
|
||||
}
|
||||
|
||||
protected BaseChannel(NetPeer peer)
|
||||
{
|
||||
Peer = peer;
|
||||
OutgoingQueue = new Queue<NetPacket>(64);
|
||||
}
|
||||
|
||||
public void AddToQueue(NetPacket packet)
|
||||
{
|
||||
lock (OutgoingQueue)
|
||||
{
|
||||
OutgoingQueue.Enqueue(packet);
|
||||
}
|
||||
AddToPeerChannelSendQueue();
|
||||
}
|
||||
|
||||
protected void AddToPeerChannelSendQueue()
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref _isAddedToPeerChannelSendQueue, 1, 0) == 0)
|
||||
{
|
||||
Peer.AddToReliableChannelSendQueue(this);
|
||||
}
|
||||
}
|
||||
|
||||
public bool SendAndCheckQueue()
|
||||
{
|
||||
bool hasPacketsToSend = SendNextPackets();
|
||||
if (!hasPacketsToSend)
|
||||
Interlocked.Exchange(ref _isAddedToPeerChannelSendQueue, 0);
|
||||
|
||||
return hasPacketsToSend;
|
||||
}
|
||||
|
||||
protected abstract bool SendNextPackets();
|
||||
public abstract bool ProcessPacket(NetPacket packet);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43eea21323b017e498f0f0f6de63abf7
|
||||
guid: 763566e7d03d94946afed98596540971
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
137
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/ConnectionRequest.cs
vendored
Normal file
137
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/ConnectionRequest.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using FlyingWormConsole3.LiteNetLib.Utils;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
internal enum ConnectionRequestResult
|
||||
{
|
||||
None,
|
||||
Accept,
|
||||
Reject,
|
||||
RejectForce
|
||||
}
|
||||
|
||||
public class ConnectionRequest
|
||||
{
|
||||
private readonly NetManager _listener;
|
||||
private int _used;
|
||||
|
||||
public readonly NetDataReader Data;
|
||||
|
||||
internal ConnectionRequestResult Result { get; private set; }
|
||||
internal long ConnectionTime;
|
||||
internal byte ConnectionNumber;
|
||||
public readonly IPEndPoint RemoteEndPoint;
|
||||
|
||||
private bool TryActivate()
|
||||
{
|
||||
return Interlocked.CompareExchange(ref _used, 1, 0) == 0;
|
||||
}
|
||||
|
||||
internal void UpdateRequest(NetConnectRequestPacket connRequest)
|
||||
{
|
||||
if (connRequest.ConnectionTime >= ConnectionTime)
|
||||
{
|
||||
ConnectionTime = connRequest.ConnectionTime;
|
||||
ConnectionNumber = connRequest.ConnectionNumber;
|
||||
}
|
||||
}
|
||||
|
||||
internal ConnectionRequest(
|
||||
long connectionId,
|
||||
byte connectionNumber,
|
||||
NetDataReader netDataReader,
|
||||
IPEndPoint endPoint,
|
||||
NetManager listener)
|
||||
{
|
||||
ConnectionTime = connectionId;
|
||||
ConnectionNumber = connectionNumber;
|
||||
RemoteEndPoint = endPoint;
|
||||
Data = netDataReader;
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
public NetPeer AcceptIfKey(string key)
|
||||
{
|
||||
if (!TryActivate())
|
||||
return null;
|
||||
try
|
||||
{
|
||||
if (Data.GetString() == key)
|
||||
Result = ConnectionRequestResult.Accept;
|
||||
}
|
||||
catch
|
||||
{
|
||||
NetDebug.WriteError("[AC] Invalid incoming data");
|
||||
}
|
||||
if (Result == ConnectionRequestResult.Accept)
|
||||
return _listener.OnConnectionSolved(this, null, 0, 0);
|
||||
|
||||
Result = ConnectionRequestResult.Reject;
|
||||
_listener.OnConnectionSolved(this, null, 0, 0);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accept connection and get new NetPeer as result
|
||||
/// </summary>
|
||||
/// <returns>Connected NetPeer</returns>
|
||||
public NetPeer Accept()
|
||||
{
|
||||
if (!TryActivate())
|
||||
return null;
|
||||
Result = ConnectionRequestResult.Accept;
|
||||
return _listener.OnConnectionSolved(this, null, 0, 0);
|
||||
}
|
||||
|
||||
public void Reject(byte[] rejectData, int start, int length, bool force)
|
||||
{
|
||||
if (!TryActivate())
|
||||
return;
|
||||
Result = force ? ConnectionRequestResult.RejectForce : ConnectionRequestResult.Reject;
|
||||
_listener.OnConnectionSolved(this, rejectData, start, length);
|
||||
}
|
||||
|
||||
public void Reject(byte[] rejectData, int start, int length)
|
||||
{
|
||||
Reject(rejectData, start, length, false);
|
||||
}
|
||||
|
||||
|
||||
public void RejectForce(byte[] rejectData, int start, int length)
|
||||
{
|
||||
Reject(rejectData, start, length, true);
|
||||
}
|
||||
|
||||
public void RejectForce()
|
||||
{
|
||||
Reject(null, 0, 0, true);
|
||||
}
|
||||
|
||||
public void RejectForce(byte[] rejectData)
|
||||
{
|
||||
Reject(rejectData, 0, rejectData.Length, true);
|
||||
}
|
||||
|
||||
public void RejectForce(NetDataWriter rejectData)
|
||||
{
|
||||
Reject(rejectData.Data, 0, rejectData.Length, true);
|
||||
}
|
||||
|
||||
public void Reject()
|
||||
{
|
||||
Reject(null, 0, 0, false);
|
||||
}
|
||||
|
||||
public void Reject(byte[] rejectData)
|
||||
{
|
||||
Reject(rejectData, 0, rejectData.Length, false);
|
||||
}
|
||||
|
||||
public void Reject(NetDataWriter rejectData)
|
||||
{
|
||||
Reject(rejectData.Data, 0, rejectData.Length, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a19e815a8e895d44d8ecd983ec7322a2
|
||||
guid: 01553ccc867ec43bbb1ae69d3de1ddda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
247
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/INetEventListener.cs
vendored
Normal file
247
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/INetEventListener.cs
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using FlyingWormConsole3.LiteNetLib.Utils;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of message that you receive in OnNetworkReceiveUnconnected event
|
||||
/// </summary>
|
||||
public enum UnconnectedMessageType
|
||||
{
|
||||
BasicMessage,
|
||||
Broadcast
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnect reason that you receive in OnPeerDisconnected event
|
||||
/// </summary>
|
||||
public enum DisconnectReason
|
||||
{
|
||||
ConnectionFailed,
|
||||
Timeout,
|
||||
HostUnreachable,
|
||||
NetworkUnreachable,
|
||||
RemoteConnectionClose,
|
||||
DisconnectPeerCalled,
|
||||
ConnectionRejected,
|
||||
InvalidProtocol,
|
||||
UnknownHost,
|
||||
Reconnect,
|
||||
PeerToPeerConnection
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Additional information about disconnection
|
||||
/// </summary>
|
||||
public struct DisconnectInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Additional info why peer disconnected
|
||||
/// </summary>
|
||||
public DisconnectReason Reason;
|
||||
|
||||
/// <summary>
|
||||
/// Error code (if reason is SocketSendError or SocketReceiveError)
|
||||
/// </summary>
|
||||
public SocketError SocketErrorCode;
|
||||
|
||||
/// <summary>
|
||||
/// Additional data that can be accessed (only if reason is RemoteConnectionClose)
|
||||
/// </summary>
|
||||
public NetPacketReader AdditionalData;
|
||||
}
|
||||
|
||||
public interface INetEventListener
|
||||
{
|
||||
/// <summary>
|
||||
/// New remote peer connected to host, or client connected to remote host
|
||||
/// </summary>
|
||||
/// <param name="peer">Connected peer object</param>
|
||||
void OnPeerConnected(NetPeer peer);
|
||||
|
||||
/// <summary>
|
||||
/// Peer disconnected
|
||||
/// </summary>
|
||||
/// <param name="peer">disconnected peer</param>
|
||||
/// <param name="disconnectInfo">additional info about reason, errorCode or data received with disconnect message</param>
|
||||
void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Network error (on send or receive)
|
||||
/// </summary>
|
||||
/// <param name="endPoint">From endPoint (can be null)</param>
|
||||
/// <param name="socketError">Socket error</param>
|
||||
void OnNetworkError(IPEndPoint endPoint, SocketError socketError);
|
||||
|
||||
/// <summary>
|
||||
/// Received some data
|
||||
/// </summary>
|
||||
/// <param name="peer">From peer</param>
|
||||
/// <param name="reader">DataReader containing all received data</param>
|
||||
/// <param name="deliveryMethod">Type of received packet</param>
|
||||
void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod);
|
||||
|
||||
/// <summary>
|
||||
/// Received unconnected message
|
||||
/// </summary>
|
||||
/// <param name="remoteEndPoint">From address (IP and Port)</param>
|
||||
/// <param name="reader">Message data</param>
|
||||
/// <param name="messageType">Message type (simple, discovery request or response)</param>
|
||||
void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType);
|
||||
|
||||
/// <summary>
|
||||
/// Latency information updated
|
||||
/// </summary>
|
||||
/// <param name="peer">Peer with updated latency</param>
|
||||
/// <param name="latency">latency value in milliseconds</param>
|
||||
void OnNetworkLatencyUpdate(NetPeer peer, int latency);
|
||||
|
||||
/// <summary>
|
||||
/// On peer connection requested
|
||||
/// </summary>
|
||||
/// <param name="request">Request information (EndPoint, internal id, additional data)</param>
|
||||
void OnConnectionRequest(ConnectionRequest request);
|
||||
}
|
||||
|
||||
public interface IDeliveryEventListener
|
||||
{
|
||||
/// <summary>
|
||||
/// On reliable message delivered
|
||||
/// </summary>
|
||||
/// <param name="peer"></param>
|
||||
/// <param name="userData"></param>
|
||||
void OnMessageDelivered(NetPeer peer, object userData);
|
||||
}
|
||||
|
||||
public interface INtpEventListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Ntp response
|
||||
/// </summary>
|
||||
/// <param name="packet"></param>
|
||||
void OnNtpResponse(NtpPacket packet);
|
||||
}
|
||||
|
||||
public class EventBasedNetListener : INetEventListener, IDeliveryEventListener, INtpEventListener
|
||||
{
|
||||
public delegate void OnPeerConnected(NetPeer peer);
|
||||
public delegate void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);
|
||||
public delegate void OnNetworkError(IPEndPoint endPoint, SocketError socketError);
|
||||
public delegate void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod);
|
||||
public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType);
|
||||
public delegate void OnNetworkLatencyUpdate(NetPeer peer, int latency);
|
||||
public delegate void OnConnectionRequest(ConnectionRequest request);
|
||||
public delegate void OnDeliveryEvent(NetPeer peer, object userData);
|
||||
public delegate void OnNtpResponseEvent(NtpPacket packet);
|
||||
|
||||
public event OnPeerConnected PeerConnectedEvent;
|
||||
public event OnPeerDisconnected PeerDisconnectedEvent;
|
||||
public event OnNetworkError NetworkErrorEvent;
|
||||
public event OnNetworkReceive NetworkReceiveEvent;
|
||||
public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent;
|
||||
public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent;
|
||||
public event OnConnectionRequest ConnectionRequestEvent;
|
||||
public event OnDeliveryEvent DeliveryEvent;
|
||||
public event OnNtpResponseEvent NtpResponseEvent;
|
||||
|
||||
public void ClearPeerConnectedEvent()
|
||||
{
|
||||
PeerConnectedEvent = null;
|
||||
}
|
||||
|
||||
public void ClearPeerDisconnectedEvent()
|
||||
{
|
||||
PeerDisconnectedEvent = null;
|
||||
}
|
||||
|
||||
public void ClearNetworkErrorEvent()
|
||||
{
|
||||
NetworkErrorEvent = null;
|
||||
}
|
||||
|
||||
public void ClearNetworkReceiveEvent()
|
||||
{
|
||||
NetworkReceiveEvent = null;
|
||||
}
|
||||
|
||||
public void ClearNetworkReceiveUnconnectedEvent()
|
||||
{
|
||||
NetworkReceiveUnconnectedEvent = null;
|
||||
}
|
||||
|
||||
public void ClearNetworkLatencyUpdateEvent()
|
||||
{
|
||||
NetworkLatencyUpdateEvent = null;
|
||||
}
|
||||
|
||||
public void ClearConnectionRequestEvent()
|
||||
{
|
||||
ConnectionRequestEvent = null;
|
||||
}
|
||||
|
||||
public void ClearDeliveryEvent()
|
||||
{
|
||||
DeliveryEvent = null;
|
||||
}
|
||||
|
||||
public void ClearNtpResponseEvent()
|
||||
{
|
||||
NtpResponseEvent = null;
|
||||
}
|
||||
|
||||
void INetEventListener.OnPeerConnected(NetPeer peer)
|
||||
{
|
||||
if (PeerConnectedEvent != null)
|
||||
PeerConnectedEvent(peer);
|
||||
}
|
||||
|
||||
void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
|
||||
{
|
||||
if (PeerDisconnectedEvent != null)
|
||||
PeerDisconnectedEvent(peer, disconnectInfo);
|
||||
}
|
||||
|
||||
void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode)
|
||||
{
|
||||
if (NetworkErrorEvent != null)
|
||||
NetworkErrorEvent(endPoint, socketErrorCode);
|
||||
}
|
||||
|
||||
void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
|
||||
{
|
||||
if (NetworkReceiveEvent != null)
|
||||
NetworkReceiveEvent(peer, reader, deliveryMethod);
|
||||
}
|
||||
|
||||
void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
|
||||
{
|
||||
if (NetworkReceiveUnconnectedEvent != null)
|
||||
NetworkReceiveUnconnectedEvent(remoteEndPoint, reader, messageType);
|
||||
}
|
||||
|
||||
void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency)
|
||||
{
|
||||
if (NetworkLatencyUpdateEvent != null)
|
||||
NetworkLatencyUpdateEvent(peer, latency);
|
||||
}
|
||||
|
||||
void INetEventListener.OnConnectionRequest(ConnectionRequest request)
|
||||
{
|
||||
if (ConnectionRequestEvent != null)
|
||||
ConnectionRequestEvent(request);
|
||||
}
|
||||
|
||||
void IDeliveryEventListener.OnMessageDelivered(NetPeer peer, object userData)
|
||||
{
|
||||
if (DeliveryEvent != null)
|
||||
DeliveryEvent(peer, userData);
|
||||
}
|
||||
|
||||
void INtpEventListener.OnNtpResponse(NtpPacket packet)
|
||||
{
|
||||
if (NtpResponseEvent != null)
|
||||
NtpResponseEvent(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b01c530301ff8ad4191edef0fdbb9434
|
||||
guid: d391f9565d58e44a798d680ec5c11906
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
8
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers.meta
vendored
Normal file
8
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38985fb72fd8c40eb9de4ce7bfaf401b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/Crc32cLayer.cs
vendored
Normal file
41
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/Crc32cLayer.cs
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
using FlyingWormConsole3.LiteNetLib.Utils;
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib.Layers
|
||||
{
|
||||
public sealed class Crc32cLayer : PacketLayerBase
|
||||
{
|
||||
public Crc32cLayer() : base(CRC32C.ChecksumSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ProcessInboundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
|
||||
{
|
||||
if (length < NetConstants.HeaderSize + CRC32C.ChecksumSize)
|
||||
{
|
||||
NetDebug.WriteError("[NM] DataReceived size: bad!");
|
||||
//Set length to 0 to have netManager drop the packet.
|
||||
length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int checksumPoint = length - CRC32C.ChecksumSize;
|
||||
if (CRC32C.Compute(data, offset, checksumPoint) != BitConverter.ToUInt32(data, checksumPoint))
|
||||
{
|
||||
NetDebug.Write("[NM] DataReceived checksum: bad!");
|
||||
//Set length to 0 to have netManager drop the packet.
|
||||
length = 0;
|
||||
return;
|
||||
}
|
||||
length -= CRC32C.ChecksumSize;
|
||||
}
|
||||
|
||||
public override void ProcessOutBoundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
|
||||
{
|
||||
FastBitConverter.GetBytes(data, length, CRC32C.Compute(data, offset, length));
|
||||
length += CRC32C.ChecksumSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fc14253f6e36724eb657932e1084248
|
||||
guid: 03f6f2696c6e848c69a6af33539c5adc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
17
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/PacketLayerBase.cs
vendored
Normal file
17
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/PacketLayerBase.cs
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.Net;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib.Layers
|
||||
{
|
||||
public abstract class PacketLayerBase
|
||||
{
|
||||
public readonly int ExtraPacketSizeForLayer;
|
||||
|
||||
protected PacketLayerBase(int extraPacketSizeForLayer)
|
||||
{
|
||||
ExtraPacketSizeForLayer = extraPacketSizeForLayer;
|
||||
}
|
||||
|
||||
public abstract void ProcessInboundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length);
|
||||
public abstract void ProcessOutBoundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length);
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/PacketLayerBase.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/PacketLayerBase.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20d4d1cdad986436a8f2f4fcc8e3e47d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
60
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/XorEncryptLayer.cs
vendored
Normal file
60
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/XorEncryptLayer.cs
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib.Layers
|
||||
{
|
||||
public class XorEncryptLayer : PacketLayerBase
|
||||
{
|
||||
private byte[] _byteKey;
|
||||
|
||||
public XorEncryptLayer() : base(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public XorEncryptLayer(byte[] key) : this()
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
public XorEncryptLayer(string key) : this()
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
public void SetKey(string key)
|
||||
{
|
||||
_byteKey = Encoding.UTF8.GetBytes(key);
|
||||
}
|
||||
|
||||
public void SetKey(byte[] key)
|
||||
{
|
||||
if (_byteKey == null || _byteKey.Length != key.Length)
|
||||
_byteKey = new byte[key.Length];
|
||||
Buffer.BlockCopy(key, 0, _byteKey, 0, key.Length);
|
||||
}
|
||||
|
||||
public override void ProcessInboundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
|
||||
{
|
||||
if (_byteKey == null)
|
||||
return;
|
||||
var cur = offset;
|
||||
for (var i = 0; i < length; i++, cur++)
|
||||
{
|
||||
data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessOutBoundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
|
||||
{
|
||||
if (_byteKey == null)
|
||||
return;
|
||||
var cur = offset;
|
||||
for (var i = 0; i < length; i++, cur++)
|
||||
{
|
||||
data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/XorEncryptLayer.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/Layers/XorEncryptLayer.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ee39ab3e39a742f59665fde4e2c4f27
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
245
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NatPunchModule.cs
vendored
Normal file
245
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NatPunchModule.cs
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using FlyingWormConsole3.LiteNetLib.Utils;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
public enum NatAddressType
|
||||
{
|
||||
Internal,
|
||||
External
|
||||
}
|
||||
|
||||
public interface INatPunchListener
|
||||
{
|
||||
void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token);
|
||||
void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token);
|
||||
}
|
||||
|
||||
public class EventBasedNatPunchListener : INatPunchListener
|
||||
{
|
||||
public delegate void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token);
|
||||
public delegate void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token);
|
||||
|
||||
public event OnNatIntroductionRequest NatIntroductionRequest;
|
||||
public event OnNatIntroductionSuccess NatIntroductionSuccess;
|
||||
|
||||
void INatPunchListener.OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token)
|
||||
{
|
||||
if(NatIntroductionRequest != null)
|
||||
NatIntroductionRequest(localEndPoint, remoteEndPoint, token);
|
||||
}
|
||||
|
||||
void INatPunchListener.OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token)
|
||||
{
|
||||
if (NatIntroductionSuccess != null)
|
||||
NatIntroductionSuccess(targetEndPoint, type, token);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Module for UDP NAT Hole punching operations. Can be accessed from NetManager
|
||||
/// </summary>
|
||||
public sealed class NatPunchModule
|
||||
{
|
||||
struct RequestEventData
|
||||
{
|
||||
public IPEndPoint LocalEndPoint;
|
||||
public IPEndPoint RemoteEndPoint;
|
||||
public string Token;
|
||||
}
|
||||
|
||||
struct SuccessEventData
|
||||
{
|
||||
public IPEndPoint TargetEndPoint;
|
||||
public NatAddressType Type;
|
||||
public string Token;
|
||||
}
|
||||
|
||||
class NatIntroduceRequestPacket
|
||||
{
|
||||
public IPEndPoint Internal { get; set; }
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
class NatIntroduceResponsePacket
|
||||
{
|
||||
public IPEndPoint Internal { get; set; }
|
||||
public IPEndPoint External { get; set; }
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
class NatPunchPacket
|
||||
{
|
||||
public string Token { get; set; }
|
||||
public bool IsExternal { get; set; }
|
||||
}
|
||||
|
||||
private readonly NetSocket _socket;
|
||||
private readonly Queue<RequestEventData> _requestEvents = new Queue<RequestEventData>();
|
||||
private readonly Queue<SuccessEventData> _successEvents = new Queue<SuccessEventData>();
|
||||
private readonly NetDataReader _cacheReader = new NetDataReader();
|
||||
private readonly NetDataWriter _cacheWriter = new NetDataWriter();
|
||||
private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(MaxTokenLength);
|
||||
private INatPunchListener _natPunchListener;
|
||||
public const int MaxTokenLength = 256;
|
||||
|
||||
internal NatPunchModule(NetSocket socket)
|
||||
{
|
||||
_socket = socket;
|
||||
_netPacketProcessor.SubscribeReusable<NatIntroduceResponsePacket>(OnNatIntroductionResponse);
|
||||
_netPacketProcessor.SubscribeReusable<NatIntroduceRequestPacket, IPEndPoint>(OnNatIntroductionRequest);
|
||||
_netPacketProcessor.SubscribeReusable<NatPunchPacket, IPEndPoint>(OnNatPunch);
|
||||
}
|
||||
|
||||
internal void ProcessMessage(IPEndPoint senderEndPoint, NetPacket packet)
|
||||
{
|
||||
lock (_cacheReader)
|
||||
{
|
||||
_cacheReader.SetSource(packet.RawData, NetConstants.HeaderSize, packet.Size);
|
||||
_netPacketProcessor.ReadAllPackets(_cacheReader, senderEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(INatPunchListener listener)
|
||||
{
|
||||
_natPunchListener = listener;
|
||||
}
|
||||
|
||||
private void Send<T>(T packet, IPEndPoint target) where T : class, new()
|
||||
{
|
||||
SocketError errorCode = 0;
|
||||
_cacheWriter.Reset();
|
||||
_cacheWriter.Put((byte)PacketProperty.NatMessage);
|
||||
_netPacketProcessor.Write(_cacheWriter, packet);
|
||||
_socket.SendTo(_cacheWriter.Data, 0, _cacheWriter.Length, target, ref errorCode);
|
||||
}
|
||||
|
||||
public void NatIntroduce(
|
||||
IPEndPoint hostInternal,
|
||||
IPEndPoint hostExternal,
|
||||
IPEndPoint clientInternal,
|
||||
IPEndPoint clientExternal,
|
||||
string additionalInfo)
|
||||
{
|
||||
var req = new NatIntroduceResponsePacket
|
||||
{
|
||||
Token = additionalInfo
|
||||
};
|
||||
|
||||
//First packet (server) send to client
|
||||
req.Internal = hostInternal;
|
||||
req.External = hostExternal;
|
||||
Send(req, clientExternal);
|
||||
|
||||
//Second packet (client) send to server
|
||||
req.Internal = clientInternal;
|
||||
req.External = clientExternal;
|
||||
Send(req, hostExternal);
|
||||
}
|
||||
|
||||
public void PollEvents()
|
||||
{
|
||||
if (_natPunchListener == null || (_successEvents.Count == 0 && _requestEvents.Count == 0))
|
||||
return;
|
||||
lock (_successEvents)
|
||||
{
|
||||
while (_successEvents.Count > 0)
|
||||
{
|
||||
var evt = _successEvents.Dequeue();
|
||||
_natPunchListener.OnNatIntroductionSuccess(
|
||||
evt.TargetEndPoint,
|
||||
evt.Type,
|
||||
evt.Token);
|
||||
}
|
||||
}
|
||||
lock (_requestEvents)
|
||||
{
|
||||
while (_requestEvents.Count > 0)
|
||||
{
|
||||
var evt = _requestEvents.Dequeue();
|
||||
_natPunchListener.OnNatIntroductionRequest(evt.LocalEndPoint, evt.RemoteEndPoint, evt.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendNatIntroduceRequest(string host, int port, string additionalInfo)
|
||||
{
|
||||
SendNatIntroduceRequest(NetUtils.MakeEndPoint(host, port), additionalInfo);
|
||||
}
|
||||
|
||||
public void SendNatIntroduceRequest(IPEndPoint masterServerEndPoint, string additionalInfo)
|
||||
{
|
||||
//prepare outgoing data
|
||||
string networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv4);
|
||||
if (string.IsNullOrEmpty(networkIp))
|
||||
{
|
||||
networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv6);
|
||||
}
|
||||
|
||||
Send(
|
||||
new NatIntroduceRequestPacket
|
||||
{
|
||||
Internal = NetUtils.MakeEndPoint(networkIp, _socket.LocalPort),
|
||||
Token = additionalInfo
|
||||
},
|
||||
masterServerEndPoint);
|
||||
}
|
||||
|
||||
//We got request and must introduce
|
||||
private void OnNatIntroductionRequest(NatIntroduceRequestPacket req, IPEndPoint senderEndPoint)
|
||||
{
|
||||
lock (_requestEvents)
|
||||
{
|
||||
_requestEvents.Enqueue(new RequestEventData
|
||||
{
|
||||
LocalEndPoint = req.Internal,
|
||||
RemoteEndPoint = senderEndPoint,
|
||||
Token = req.Token
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//We got introduce and must punch
|
||||
private void OnNatIntroductionResponse(NatIntroduceResponsePacket req)
|
||||
{
|
||||
NetDebug.Write(NetLogLevel.Trace, "[NAT] introduction received");
|
||||
|
||||
// send internal punch
|
||||
var punchPacket = new NatPunchPacket {Token = req.Token};
|
||||
Send(punchPacket, req.Internal);
|
||||
NetDebug.Write(NetLogLevel.Trace, "[NAT] internal punch sent to " + req.Internal);
|
||||
|
||||
// hack for some routers
|
||||
SocketError errorCode = 0;
|
||||
_socket.Ttl = 2;
|
||||
_socket.SendTo(new[] { (byte)PacketProperty.Empty }, 0, 1, req.External, ref errorCode);
|
||||
|
||||
// send external punch
|
||||
_socket.Ttl = NetConstants.SocketTTL;
|
||||
punchPacket.IsExternal = true;
|
||||
Send(punchPacket, req.External);
|
||||
NetDebug.Write(NetLogLevel.Trace, "[NAT] external punch sent to " + req.External);
|
||||
}
|
||||
|
||||
//We got punch and can connect
|
||||
private void OnNatPunch(NatPunchPacket req, IPEndPoint senderEndPoint)
|
||||
{
|
||||
//Read info
|
||||
NetDebug.Write(NetLogLevel.Trace, "[NAT] punch received from {0} - additional info: {1}",
|
||||
senderEndPoint, req.Token);
|
||||
|
||||
//Release punch success to client; enabling him to Connect() to Sender if token is ok
|
||||
lock (_successEvents)
|
||||
{
|
||||
_successEvents.Enqueue(new SuccessEventData
|
||||
{
|
||||
TargetEndPoint = senderEndPoint,
|
||||
Type = req.IsExternal ? NatAddressType.External : NatAddressType.Internal,
|
||||
Token = req.Token
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NatPunchModule.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NatPunchModule.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11f3508667cc14e3797a49d4695ffdd8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
74
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetConstants.cs
vendored
Normal file
74
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetConstants.cs
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
/// <summary>
|
||||
/// Sending method type
|
||||
/// </summary>
|
||||
public enum DeliveryMethod : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Unreliable. Packets can be dropped, can be duplicated, can arrive without order.
|
||||
/// </summary>
|
||||
Unreliable = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Reliable. Packets won't be dropped, won't be duplicated, can arrive without order.
|
||||
/// </summary>
|
||||
ReliableUnordered = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Unreliable. Packets can be dropped, won't be duplicated, will arrive in order.
|
||||
/// </summary>
|
||||
Sequenced = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Reliable and ordered. Packets won't be dropped, won't be duplicated, will arrive in order.
|
||||
/// </summary>
|
||||
ReliableOrdered = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Reliable only last packet. Packets can be dropped (except the last one), won't be duplicated, will arrive in order.
|
||||
/// Cannot be fragmented
|
||||
/// </summary>
|
||||
ReliableSequenced = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Network constants. Can be tuned from sources for your purposes.
|
||||
/// </summary>
|
||||
public static class NetConstants
|
||||
{
|
||||
//can be tuned
|
||||
public const int DefaultWindowSize = 64;
|
||||
public const int SocketBufferSize = 1024 * 1024; //1mb
|
||||
public const int SocketTTL = 255;
|
||||
|
||||
public const int HeaderSize = 1;
|
||||
public const int ChanneledHeaderSize = 4;
|
||||
public const int FragmentHeaderSize = 6;
|
||||
public const int FragmentedHeaderTotalSize = ChanneledHeaderSize + FragmentHeaderSize;
|
||||
public const ushort MaxSequence = 32768;
|
||||
public const ushort HalfMaxSequence = MaxSequence / 2;
|
||||
|
||||
//protocol
|
||||
internal const int ProtocolId = 11;
|
||||
internal const int MaxUdpHeaderSize = 68;
|
||||
|
||||
internal static readonly int[] PossibleMtu =
|
||||
{
|
||||
576 - MaxUdpHeaderSize, //minimal (RFC 1191)
|
||||
1024, //most games standard
|
||||
1232 - MaxUdpHeaderSize,
|
||||
1460 - MaxUdpHeaderSize, //google cloud
|
||||
1472 - MaxUdpHeaderSize, //VPN
|
||||
1492 - MaxUdpHeaderSize, //Ethernet with LLC and SNAP, PPPoE (RFC 1042)
|
||||
1500 - MaxUdpHeaderSize //Ethernet II (RFC 1191)
|
||||
};
|
||||
|
||||
internal static readonly int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1];
|
||||
|
||||
//peer specific
|
||||
public const byte MaxConnectionNumber = 4;
|
||||
|
||||
public const int PacketPoolSize = 1000;
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetConstants.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetConstants.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02abb4740bff94f28bdd538839339932
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
92
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetDebug.cs
vendored
Normal file
92
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetDebug.cs
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
public class InvalidPacketException : ArgumentException
|
||||
{
|
||||
public InvalidPacketException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class TooBigPacketException : InvalidPacketException
|
||||
{
|
||||
public TooBigPacketException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public enum NetLogLevel
|
||||
{
|
||||
Warning,
|
||||
Error,
|
||||
Trace,
|
||||
Info
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface to implement for your own logger
|
||||
/// </summary>
|
||||
public interface INetLogger
|
||||
{
|
||||
void WriteNet(NetLogLevel level, string str, params object[] args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Static class for defining your own LiteNetLib logger instead of Console.WriteLine
|
||||
/// or Debug.Log if compiled with UNITY flag
|
||||
/// </summary>
|
||||
public static class NetDebug
|
||||
{
|
||||
public static INetLogger Logger = null;
|
||||
private static readonly object DebugLogLock = new object();
|
||||
private static void WriteLogic(NetLogLevel logLevel, string str, params object[] args)
|
||||
{
|
||||
lock (DebugLogLock)
|
||||
{
|
||||
if (Logger == null)
|
||||
{
|
||||
#if UNITY_4 || UNITY_5 || UNITY_5_3_OR_NEWER
|
||||
UnityEngine.Debug.Log(string.Format(str, args));
|
||||
#else
|
||||
Console.WriteLine(str, args);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteNet(logLevel, str, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG_MESSAGES")]
|
||||
internal static void Write(string str, params object[] args)
|
||||
{
|
||||
WriteLogic(NetLogLevel.Trace, str, args);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG_MESSAGES")]
|
||||
internal static void Write(NetLogLevel level, string str, params object[] args)
|
||||
{
|
||||
WriteLogic(level, str, args);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")]
|
||||
internal static void WriteForce(string str, params object[] args)
|
||||
{
|
||||
WriteLogic(NetLogLevel.Trace, str, args);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")]
|
||||
internal static void WriteForce(NetLogLevel level, string str, params object[] args)
|
||||
{
|
||||
WriteLogic(level, str, args);
|
||||
}
|
||||
|
||||
internal static void WriteError(string str, params object[] args)
|
||||
{
|
||||
WriteLogic(NetLogLevel.Error, str, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetDebug.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetDebug.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78dc00ceb66ac4fdfa8c3957763522ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1829
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetManager.cs
vendored
Normal file
1829
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetManager.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetManager.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetManager.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0197124da84847d8855d5f690b8c653
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
270
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacket.cs
vendored
Normal file
270
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacket.cs
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using FlyingWormConsole3.LiteNetLib.Utils;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
internal enum PacketProperty : byte
|
||||
{
|
||||
Unreliable,
|
||||
Channeled,
|
||||
Ack,
|
||||
Ping,
|
||||
Pong,
|
||||
ConnectRequest,
|
||||
ConnectAccept,
|
||||
Disconnect,
|
||||
UnconnectedMessage,
|
||||
MtuCheck,
|
||||
MtuOk,
|
||||
Broadcast,
|
||||
Merged,
|
||||
ShutdownOk,
|
||||
PeerNotFound,
|
||||
InvalidProtocol,
|
||||
NatMessage,
|
||||
Empty
|
||||
}
|
||||
|
||||
internal sealed class NetPacket
|
||||
{
|
||||
private static readonly int LastProperty = Enum.GetValues(typeof(PacketProperty)).Length;
|
||||
private static readonly int[] HeaderSizes;
|
||||
|
||||
static NetPacket()
|
||||
{
|
||||
HeaderSizes = new int[LastProperty+1];
|
||||
for (int i = 0; i < HeaderSizes.Length; i++)
|
||||
{
|
||||
switch ((PacketProperty)i)
|
||||
{
|
||||
case PacketProperty.Channeled:
|
||||
case PacketProperty.Ack:
|
||||
HeaderSizes[i] = NetConstants.ChanneledHeaderSize;
|
||||
break;
|
||||
case PacketProperty.Ping:
|
||||
HeaderSizes[i] = NetConstants.HeaderSize + 2;
|
||||
break;
|
||||
case PacketProperty.ConnectRequest:
|
||||
HeaderSizes[i] = NetConnectRequestPacket.HeaderSize;
|
||||
break;
|
||||
case PacketProperty.ConnectAccept:
|
||||
HeaderSizes[i] = NetConnectAcceptPacket.Size;
|
||||
break;
|
||||
case PacketProperty.Disconnect:
|
||||
HeaderSizes[i] = NetConstants.HeaderSize + 8;
|
||||
break;
|
||||
case PacketProperty.Pong:
|
||||
HeaderSizes[i] = NetConstants.HeaderSize + 10;
|
||||
break;
|
||||
default:
|
||||
HeaderSizes[i] = NetConstants.HeaderSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Header
|
||||
public PacketProperty Property
|
||||
{
|
||||
get { return (PacketProperty)(RawData[0] & 0x1F); }
|
||||
set { RawData[0] = (byte)((RawData[0] & 0xE0) | (byte)value); }
|
||||
}
|
||||
|
||||
public byte ConnectionNumber
|
||||
{
|
||||
get { return (byte)((RawData[0] & 0x60) >> 5); }
|
||||
set { RawData[0] = (byte) ((RawData[0] & 0x9F) | (value << 5)); }
|
||||
}
|
||||
|
||||
public ushort Sequence
|
||||
{
|
||||
get { return BitConverter.ToUInt16(RawData, 1); }
|
||||
set { FastBitConverter.GetBytes(RawData, 1, value); }
|
||||
}
|
||||
|
||||
public bool IsFragmented
|
||||
{
|
||||
get { return (RawData[0] & 0x80) != 0; }
|
||||
}
|
||||
|
||||
public void MarkFragmented()
|
||||
{
|
||||
RawData[0] |= 0x80; //set first bit
|
||||
}
|
||||
|
||||
public byte ChannelId
|
||||
{
|
||||
get { return RawData[3]; }
|
||||
set { RawData[3] = value; }
|
||||
}
|
||||
|
||||
public ushort FragmentId
|
||||
{
|
||||
get { return BitConverter.ToUInt16(RawData, 4); }
|
||||
set { FastBitConverter.GetBytes(RawData, 4, value); }
|
||||
}
|
||||
|
||||
public ushort FragmentPart
|
||||
{
|
||||
get { return BitConverter.ToUInt16(RawData, 6); }
|
||||
set { FastBitConverter.GetBytes(RawData, 6, value); }
|
||||
}
|
||||
|
||||
public ushort FragmentsTotal
|
||||
{
|
||||
get { return BitConverter.ToUInt16(RawData, 8); }
|
||||
set { FastBitConverter.GetBytes(RawData, 8, value); }
|
||||
}
|
||||
|
||||
//Data
|
||||
public byte[] RawData;
|
||||
public int Size;
|
||||
|
||||
//Delivery
|
||||
public object UserData;
|
||||
|
||||
//Pool node
|
||||
public NetPacket Next;
|
||||
|
||||
#if DEBUG_REFCOUNT
|
||||
public int RefCount = 1;
|
||||
#endif
|
||||
|
||||
public NetPacket(int size)
|
||||
{
|
||||
RawData = new byte[size];
|
||||
Size = size;
|
||||
}
|
||||
|
||||
public NetPacket(PacketProperty property, int size)
|
||||
{
|
||||
size += GetHeaderSize(property);
|
||||
RawData = new byte[size];
|
||||
Property = property;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
public static int GetHeaderSize(PacketProperty property)
|
||||
{
|
||||
return HeaderSizes[(int)property];
|
||||
}
|
||||
|
||||
public int GetHeaderSize()
|
||||
{
|
||||
return HeaderSizes[RawData[0] & 0x1F];
|
||||
}
|
||||
|
||||
public bool Verify()
|
||||
{
|
||||
byte property = (byte)(RawData[0] & 0x1F);
|
||||
if (property > LastProperty)
|
||||
return false;
|
||||
int headerSize = HeaderSizes[property];
|
||||
bool fragmented = (RawData[0] & 0x80) != 0;
|
||||
return Size >= headerSize && (!fragmented || Size >= headerSize + NetConstants.FragmentHeaderSize);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class NetConnectRequestPacket
|
||||
{
|
||||
public const int HeaderSize = 14;
|
||||
public readonly long ConnectionTime;
|
||||
public readonly byte ConnectionNumber;
|
||||
public readonly byte[] TargetAddress;
|
||||
public readonly NetDataReader Data;
|
||||
|
||||
private NetConnectRequestPacket(long connectionTime, byte connectionNumber, byte[] targetAddress, NetDataReader data)
|
||||
{
|
||||
ConnectionTime = connectionTime;
|
||||
ConnectionNumber = connectionNumber;
|
||||
TargetAddress = targetAddress;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public static int GetProtocolId(NetPacket packet)
|
||||
{
|
||||
return BitConverter.ToInt32(packet.RawData, 1);
|
||||
}
|
||||
|
||||
public static NetConnectRequestPacket FromData(NetPacket packet)
|
||||
{
|
||||
if (packet.ConnectionNumber >= NetConstants.MaxConnectionNumber)
|
||||
return null;
|
||||
|
||||
//Getting new id for peer
|
||||
long connectionId = BitConverter.ToInt64(packet.RawData, 5);
|
||||
|
||||
//Get target address
|
||||
int addrSize = packet.RawData[13];
|
||||
if (addrSize != 16 && addrSize != 28)
|
||||
return null;
|
||||
byte[] addressBytes = new byte[addrSize];
|
||||
Buffer.BlockCopy(packet.RawData, 14, addressBytes, 0, addrSize);
|
||||
|
||||
// Read data and create request
|
||||
var reader = new NetDataReader(null, 0, 0);
|
||||
if (packet.Size > HeaderSize+addrSize)
|
||||
reader.SetSource(packet.RawData, HeaderSize + addrSize, packet.Size);
|
||||
|
||||
return new NetConnectRequestPacket(connectionId, packet.ConnectionNumber, addressBytes, reader);
|
||||
}
|
||||
|
||||
public static NetPacket Make(NetDataWriter connectData, SocketAddress addressBytes, long connectId)
|
||||
{
|
||||
//Make initial packet
|
||||
var packet = new NetPacket(PacketProperty.ConnectRequest, connectData.Length+addressBytes.Size);
|
||||
|
||||
//Add data
|
||||
FastBitConverter.GetBytes(packet.RawData, 1, NetConstants.ProtocolId);
|
||||
FastBitConverter.GetBytes(packet.RawData, 5, connectId);
|
||||
packet.RawData[13] = (byte)addressBytes.Size;
|
||||
for (int i = 0; i < addressBytes.Size; i++)
|
||||
packet.RawData[14+i] = addressBytes[i];
|
||||
Buffer.BlockCopy(connectData.Data, 0, packet.RawData, 14+addressBytes.Size, connectData.Length);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class NetConnectAcceptPacket
|
||||
{
|
||||
public const int Size = 11;
|
||||
public readonly long ConnectionId;
|
||||
public readonly byte ConnectionNumber;
|
||||
public readonly bool IsReusedPeer;
|
||||
|
||||
private NetConnectAcceptPacket(long connectionId, byte connectionNumber, bool isReusedPeer)
|
||||
{
|
||||
ConnectionId = connectionId;
|
||||
ConnectionNumber = connectionNumber;
|
||||
IsReusedPeer = isReusedPeer;
|
||||
}
|
||||
|
||||
public static NetConnectAcceptPacket FromData(NetPacket packet)
|
||||
{
|
||||
if (packet.Size > Size)
|
||||
return null;
|
||||
|
||||
long connectionId = BitConverter.ToInt64(packet.RawData, 1);
|
||||
//check connect num
|
||||
byte connectionNumber = packet.RawData[9];
|
||||
if (connectionNumber >= NetConstants.MaxConnectionNumber)
|
||||
return null;
|
||||
//check reused flag
|
||||
byte isReused = packet.RawData[10];
|
||||
if (isReused > 1)
|
||||
return null;
|
||||
|
||||
return new NetConnectAcceptPacket(connectionId, connectionNumber, isReused == 1);
|
||||
}
|
||||
|
||||
public static NetPacket Make(long connectId, byte connectNum, bool reusedPeer)
|
||||
{
|
||||
var packet = new NetPacket(PacketProperty.ConnectAccept, 0);
|
||||
FastBitConverter.GetBytes(packet.RawData, 1, connectId);
|
||||
packet.RawData[9] = connectNum;
|
||||
packet.RawData[10] = (byte)(reusedPeer ? 1 : 0);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacket.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacket.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aa9ed55f53fa48569ccd0963c50d8da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
76
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacketPool.cs
vendored
Normal file
76
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacketPool.cs
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
internal sealed class NetPacketPool
|
||||
{
|
||||
private NetPacket _head;
|
||||
private int _count;
|
||||
private readonly object _lock = new object();
|
||||
|
||||
public NetPacket GetWithData(PacketProperty property, byte[] data, int start, int length)
|
||||
{
|
||||
int headerSize = NetPacket.GetHeaderSize(property);
|
||||
NetPacket packet = GetPacket(length + headerSize);
|
||||
packet.Property = property;
|
||||
Buffer.BlockCopy(data, start, packet.RawData, headerSize, length);
|
||||
return packet;
|
||||
}
|
||||
|
||||
//Get packet with size
|
||||
public NetPacket GetWithProperty(PacketProperty property, int size)
|
||||
{
|
||||
NetPacket packet = GetPacket(size + NetPacket.GetHeaderSize(property));
|
||||
packet.Property = property;
|
||||
return packet;
|
||||
}
|
||||
|
||||
public NetPacket GetWithProperty(PacketProperty property)
|
||||
{
|
||||
NetPacket packet = GetPacket(NetPacket.GetHeaderSize(property));
|
||||
packet.Property = property;
|
||||
return packet;
|
||||
}
|
||||
|
||||
public NetPacket GetPacket(int size)
|
||||
{
|
||||
if (size > NetConstants.MaxPacketSize)
|
||||
return new NetPacket(size);
|
||||
|
||||
NetPacket packet;
|
||||
lock (_lock)
|
||||
{
|
||||
packet = _head;
|
||||
if (packet == null)
|
||||
return new NetPacket(size);
|
||||
_head = _head.Next;
|
||||
}
|
||||
|
||||
Interlocked.Decrement(ref _count);
|
||||
packet.Size = size;
|
||||
if (packet.RawData.Length < size)
|
||||
packet.RawData = new byte[size];
|
||||
return packet;
|
||||
}
|
||||
|
||||
public void Recycle(NetPacket packet)
|
||||
{
|
||||
if (packet.RawData.Length > NetConstants.MaxPacketSize || _count >= NetConstants.PacketPoolSize)
|
||||
{
|
||||
//Don't pool big packets. Save memory
|
||||
return;
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref _count);
|
||||
|
||||
//Clean fragmented flag
|
||||
packet.RawData[0] = 0;
|
||||
lock (_lock)
|
||||
{
|
||||
packet.Next = _head;
|
||||
_head = packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacketPool.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPacketPool.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3637381933a4745b996d4dd48cd71efe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1206
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPeer.cs
vendored
Normal file
1206
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPeer.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPeer.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetPeer.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39ca2e83856ea4ba0a0100a00089e695
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
543
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetSocket.cs
vendored
Normal file
543
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetSocket.cs
vendored
Normal file
@@ -0,0 +1,543 @@
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
#define UNITY
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
#endif
|
||||
#endif
|
||||
#if NETSTANDARD || NETCOREAPP
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
|
||||
namespace FlyingWormConsole3.LiteNetLib
|
||||
{
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
public class UnitySocketFix : MonoBehaviour
|
||||
{
|
||||
internal IPAddress BindAddrIPv4;
|
||||
internal IPAddress BindAddrIPv6;
|
||||
internal bool Reuse;
|
||||
internal IPv6Mode IPv6;
|
||||
internal int Port;
|
||||
internal bool Paused;
|
||||
internal NetSocket Socket;
|
||||
internal bool ManualMode;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Socket == null)
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void OnApplicationPause(bool pause)
|
||||
{
|
||||
if (Socket == null)
|
||||
return;
|
||||
if (pause)
|
||||
{
|
||||
Paused = true;
|
||||
Socket.Close(true);
|
||||
}
|
||||
else if (Paused)
|
||||
{
|
||||
if (!Socket.Bind(BindAddrIPv4, BindAddrIPv6, Port, Reuse, IPv6, ManualMode))
|
||||
{
|
||||
NetDebug.WriteError("[S] Cannot restore connection \"{0}\",\"{1}\" port {2}", BindAddrIPv4, BindAddrIPv6, Port);
|
||||
Socket.OnErrorRestore();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal sealed class NetSocket
|
||||
{
|
||||
public const int ReceivePollingTime = 500000; //0.5 second
|
||||
|
||||
private Socket _udpSocketv4;
|
||||
private Socket _udpSocketv6;
|
||||
private Thread _threadv4;
|
||||
private Thread _threadv6;
|
||||
private IPEndPoint _bufferEndPointv4;
|
||||
private IPEndPoint _bufferEndPointv6;
|
||||
|
||||
private readonly NetManager _listener;
|
||||
|
||||
private const int SioUdpConnreset = -1744830452; //SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
|
||||
private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse("ff02::1");
|
||||
internal static readonly bool IPv6Support;
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
private UnitySocketFix _unitySocketFix;
|
||||
|
||||
public void OnErrorRestore()
|
||||
{
|
||||
Close(false);
|
||||
_listener.OnMessageReceived(null, SocketError.NotConnected, new IPEndPoint(0,0));
|
||||
}
|
||||
#endif
|
||||
public int LocalPort { get; private set; }
|
||||
public volatile bool IsRunning;
|
||||
|
||||
public short Ttl
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_SWITCH
|
||||
return 0;
|
||||
#else
|
||||
if (_udpSocketv4.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
return (short)_udpSocketv4.GetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.HopLimit);
|
||||
return _udpSocketv4.Ttl;
|
||||
#endif
|
||||
}
|
||||
set
|
||||
{
|
||||
#if !UNITY_SWITCH
|
||||
if (_udpSocketv4.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
_udpSocketv4.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.HopLimit, value);
|
||||
else
|
||||
_udpSocketv4.Ttl = value;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static NetSocket()
|
||||
{
|
||||
#if DISABLE_IPV6 || (!UNITY_EDITOR && ENABLE_IL2CPP && !UNITY_2018_3_OR_NEWER)
|
||||
IPv6Support = false;
|
||||
#elif !UNITY_2019_1_OR_NEWER && !UNITY_2018_4_OR_NEWER && (!UNITY_EDITOR && ENABLE_IL2CPP && UNITY_2018_3_OR_NEWER)
|
||||
string version = UnityEngine.Application.unityVersion;
|
||||
IPv6Support = Socket.OSSupportsIPv6 && int.Parse(version.Remove(version.IndexOf('f')).Split('.')[2]) >= 6;
|
||||
#elif UNITY_2018_2_OR_NEWER
|
||||
IPv6Support = Socket.OSSupportsIPv6;
|
||||
#elif UNITY
|
||||
#pragma warning disable 618
|
||||
IPv6Support = Socket.SupportsIPv6;
|
||||
#pragma warning restore 618
|
||||
#else
|
||||
IPv6Support = Socket.OSSupportsIPv6;
|
||||
#endif
|
||||
}
|
||||
|
||||
public NetSocket(NetManager listener)
|
||||
{
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
private bool IsActive()
|
||||
{
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
var unitySocketFix = _unitySocketFix; //save for multithread
|
||||
if (unitySocketFix != null && unitySocketFix.Paused)
|
||||
return false;
|
||||
#endif
|
||||
return IsRunning;
|
||||
}
|
||||
|
||||
private bool ProcessError(SocketException ex, EndPoint bufferEndPoint)
|
||||
{
|
||||
switch (ex.SocketErrorCode)
|
||||
{
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
case SocketError.NotConnected:
|
||||
#endif
|
||||
case SocketError.Interrupted:
|
||||
case SocketError.NotSocket:
|
||||
return true;
|
||||
case SocketError.ConnectionReset:
|
||||
case SocketError.MessageSize:
|
||||
case SocketError.TimedOut:
|
||||
NetDebug.Write(NetLogLevel.Trace, "[R]Ignored error: {0} - {1}",
|
||||
(int)ex.SocketErrorCode, ex.ToString());
|
||||
break;
|
||||
default:
|
||||
NetDebug.WriteError("[R]Error code: {0} - {1}", (int)ex.SocketErrorCode,
|
||||
ex.ToString());
|
||||
_listener.OnMessageReceived(null, ex.SocketErrorCode, (IPEndPoint)bufferEndPoint);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ManualReceive()
|
||||
{
|
||||
ManualReceive(_udpSocketv4, _bufferEndPointv4);
|
||||
if (_udpSocketv6 != null && _udpSocketv6 != _udpSocketv4)
|
||||
ManualReceive(_udpSocketv6, _bufferEndPointv6);
|
||||
}
|
||||
|
||||
private bool ManualReceive(Socket socket, EndPoint bufferEndPoint)
|
||||
{
|
||||
//Reading data
|
||||
try
|
||||
{
|
||||
int available = socket.Available;
|
||||
if (available == 0)
|
||||
return false;
|
||||
while (available > 0)
|
||||
{
|
||||
var packet = _listener.NetPacketPool.GetPacket(NetConstants.MaxPacketSize);
|
||||
packet.Size = socket.ReceiveFrom(packet.RawData, 0, NetConstants.MaxPacketSize, SocketFlags.None,
|
||||
ref bufferEndPoint);
|
||||
NetDebug.Write(NetLogLevel.Trace, "[R]Received data from {0}, result: {1}", bufferEndPoint.ToString(), packet.Size);
|
||||
_listener.OnMessageReceived(packet, 0, (IPEndPoint)bufferEndPoint);
|
||||
available -= packet.Size;
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
return ProcessError(ex, bufferEndPoint);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ReceiveLogic(object state)
|
||||
{
|
||||
Socket socket = (Socket)state;
|
||||
EndPoint bufferEndPoint = new IPEndPoint(socket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, 0);
|
||||
|
||||
while (IsActive())
|
||||
{
|
||||
NetPacket packet;
|
||||
|
||||
//Reading data
|
||||
try
|
||||
{
|
||||
if (socket.Available == 0 && !socket.Poll(ReceivePollingTime, SelectMode.SelectRead))
|
||||
continue;
|
||||
packet = _listener.NetPacketPool.GetPacket(NetConstants.MaxPacketSize);
|
||||
packet.Size = socket.ReceiveFrom(packet.RawData, 0, NetConstants.MaxPacketSize, SocketFlags.None,
|
||||
ref bufferEndPoint);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
if (ProcessError(ex, bufferEndPoint))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//All ok!
|
||||
NetDebug.Write(NetLogLevel.Trace, "[R]Received data from {0}, result: {1}", bufferEndPoint.ToString(), packet.Size);
|
||||
_listener.OnMessageReceived(packet, 0, (IPEndPoint)bufferEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Bind(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool reuseAddress, IPv6Mode ipv6Mode, bool manualMode)
|
||||
{
|
||||
if (IsActive())
|
||||
return false;
|
||||
bool dualMode = ipv6Mode == IPv6Mode.DualMode && IPv6Support;
|
||||
|
||||
_udpSocketv4 = new Socket(
|
||||
dualMode ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork,
|
||||
SocketType.Dgram,
|
||||
ProtocolType.Udp);
|
||||
|
||||
if (!BindSocket(_udpSocketv4, new IPEndPoint(dualMode ? addressIPv6 : addressIPv4, port), reuseAddress, ipv6Mode))
|
||||
return false;
|
||||
|
||||
LocalPort = ((IPEndPoint) _udpSocketv4.LocalEndPoint).Port;
|
||||
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
if (_unitySocketFix == null)
|
||||
{
|
||||
var unityFixObj = new GameObject("LiteNetLib_UnitySocketFix");
|
||||
GameObject.DontDestroyOnLoad(unityFixObj);
|
||||
_unitySocketFix = unityFixObj.AddComponent<UnitySocketFix>();
|
||||
_unitySocketFix.Socket = this;
|
||||
_unitySocketFix.BindAddrIPv4 = addressIPv4;
|
||||
_unitySocketFix.BindAddrIPv6 = addressIPv6;
|
||||
_unitySocketFix.Reuse = reuseAddress;
|
||||
_unitySocketFix.Port = LocalPort;
|
||||
_unitySocketFix.IPv6 = ipv6Mode;
|
||||
_unitySocketFix.ManualMode = manualMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
_unitySocketFix.Paused = false;
|
||||
}
|
||||
#endif
|
||||
if (dualMode)
|
||||
_udpSocketv6 = _udpSocketv4;
|
||||
|
||||
IsRunning = true;
|
||||
if (!manualMode)
|
||||
{
|
||||
_threadv4 = new Thread(ReceiveLogic)
|
||||
{
|
||||
Name = "SocketThreadv4(" + LocalPort + ")",
|
||||
IsBackground = true
|
||||
};
|
||||
_threadv4.Start(_udpSocketv4);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bufferEndPointv4 = new IPEndPoint(IPAddress.Any, 0);
|
||||
}
|
||||
|
||||
//Check IPv6 support
|
||||
if (!IPv6Support || ipv6Mode != IPv6Mode.SeparateSocket)
|
||||
return true;
|
||||
|
||||
_udpSocketv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
|
||||
//Use one port for two sockets
|
||||
if (BindSocket(_udpSocketv6, new IPEndPoint(addressIPv6, LocalPort), reuseAddress, ipv6Mode))
|
||||
{
|
||||
if (manualMode)
|
||||
{
|
||||
_bufferEndPointv6 = new IPEndPoint(IPAddress.IPv6Any, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_threadv6 = new Thread(ReceiveLogic)
|
||||
{
|
||||
Name = "SocketThreadv6(" + LocalPort + ")",
|
||||
IsBackground = true
|
||||
};
|
||||
_threadv6.Start(_udpSocketv6);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool BindSocket(Socket socket, IPEndPoint ep, bool reuseAddress, IPv6Mode ipv6Mode)
|
||||
{
|
||||
//Setup socket
|
||||
socket.ReceiveTimeout = 500;
|
||||
socket.SendTimeout = 500;
|
||||
socket.ReceiveBufferSize = NetConstants.SocketBufferSize;
|
||||
socket.SendBufferSize = NetConstants.SocketBufferSize;
|
||||
#if !UNITY || UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
|
||||
#if NETSTANDARD || NETCOREAPP
|
||||
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
#endif
|
||||
try
|
||||
{
|
||||
socket.IOControl(SioUdpConnreset, new byte[] { 0 }, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//ignored
|
||||
}
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
socket.ExclusiveAddressUse = !reuseAddress;
|
||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, reuseAddress);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Unity with IL2CPP throws an exception here, it doesn't matter in most cases so just ignore it
|
||||
}
|
||||
if (socket.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
Ttl = NetConstants.SocketTTL;
|
||||
|
||||
#if NETSTANDARD || NETCOREAPP
|
||||
if(!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
#endif
|
||||
try { socket.DontFragment = true; }
|
||||
catch (SocketException e)
|
||||
{
|
||||
NetDebug.WriteError("[B]DontFragment error: {0}", e.SocketErrorCode);
|
||||
}
|
||||
|
||||
try { socket.EnableBroadcast = true; }
|
||||
catch (SocketException e)
|
||||
{
|
||||
NetDebug.WriteError("[B]Broadcast error: {0}", e.SocketErrorCode);
|
||||
}
|
||||
}
|
||||
else //IPv6 specific
|
||||
{
|
||||
if (ipv6Mode == IPv6Mode.DualMode)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Disable IPv6 only mode
|
||||
socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
NetDebug.WriteError("[B]Bind exception (dualmode setting): {0}", e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Bind
|
||||
try
|
||||
{
|
||||
socket.Bind(ep);
|
||||
NetDebug.Write(NetLogLevel.Trace, "[B]Successfully binded to port: {0}", ((IPEndPoint)socket.LocalEndPoint).Port);
|
||||
|
||||
//join multicast
|
||||
if (socket.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if !UNITY
|
||||
socket.SetSocketOption(
|
||||
SocketOptionLevel.IPv6,
|
||||
SocketOptionName.AddMembership,
|
||||
new IPv6MulticastOption(MulticastAddressV6));
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Unity3d throws exception - ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException bindException)
|
||||
{
|
||||
switch (bindException.SocketErrorCode)
|
||||
{
|
||||
//IPv6 bind fix
|
||||
case SocketError.AddressAlreadyInUse:
|
||||
if (socket.AddressFamily == AddressFamily.InterNetworkV6 && ipv6Mode != IPv6Mode.DualMode)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Set IPv6Only
|
||||
socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, true);
|
||||
socket.Bind(ep);
|
||||
}
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
||||
//because its fixed in 2018_3
|
||||
NetDebug.WriteError("[B]Bind exception: {0}, errorCode: {1}", ex.ToString(), ex.SocketErrorCode);
|
||||
#else
|
||||
catch(SocketException)
|
||||
{
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
//hack for iOS (Unity3D)
|
||||
case SocketError.AddressFamilyNotSupported:
|
||||
return true;
|
||||
}
|
||||
NetDebug.WriteError("[B]Bind exception: {0}, errorCode: {1}", bindException.ToString(), bindException.SocketErrorCode);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SendBroadcast(byte[] data, int offset, int size, int port)
|
||||
{
|
||||
if (!IsActive())
|
||||
return false;
|
||||
bool broadcastSuccess = false;
|
||||
bool multicastSuccess = false;
|
||||
try
|
||||
{
|
||||
broadcastSuccess = _udpSocketv4.SendTo(
|
||||
data,
|
||||
offset,
|
||||
size,
|
||||
SocketFlags.None,
|
||||
new IPEndPoint(IPAddress.Broadcast, port)) > 0;
|
||||
|
||||
if (_udpSocketv6 != null)
|
||||
{
|
||||
multicastSuccess = _udpSocketv6.SendTo(
|
||||
data,
|
||||
offset,
|
||||
size,
|
||||
SocketFlags.None,
|
||||
new IPEndPoint(MulticastAddressV6, port)) > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NetDebug.WriteError("[S][MCAST]" + ex);
|
||||
return broadcastSuccess;
|
||||
}
|
||||
return broadcastSuccess || multicastSuccess;
|
||||
}
|
||||
|
||||
public int SendTo(byte[] data, int offset, int size, IPEndPoint remoteEndPoint, ref SocketError errorCode)
|
||||
{
|
||||
if (!IsActive())
|
||||
return 0;
|
||||
try
|
||||
{
|
||||
var socket = _udpSocketv4;
|
||||
if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6 && IPv6Support)
|
||||
socket = _udpSocketv6;
|
||||
int result = socket.SendTo(data, offset, size, SocketFlags.None, remoteEndPoint);
|
||||
NetDebug.Write(NetLogLevel.Trace, "[S]Send packet to {0}, result: {1}", remoteEndPoint, result);
|
||||
return result;
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
switch (ex.SocketErrorCode)
|
||||
{
|
||||
case SocketError.NoBufferSpaceAvailable:
|
||||
case SocketError.Interrupted:
|
||||
return 0;
|
||||
case SocketError.MessageSize: //do nothing
|
||||
break;
|
||||
default:
|
||||
NetDebug.WriteError("[S]" + ex);
|
||||
break;
|
||||
}
|
||||
errorCode = ex.SocketErrorCode;
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NetDebug.WriteError("[S]" + ex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void Close(bool suspend)
|
||||
{
|
||||
if (!suspend)
|
||||
{
|
||||
IsRunning = false;
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
_unitySocketFix.Socket = null;
|
||||
_unitySocketFix = null;
|
||||
#endif
|
||||
}
|
||||
//cleanup dual mode
|
||||
if (_udpSocketv4 == _udpSocketv6)
|
||||
_udpSocketv6 = null;
|
||||
|
||||
if (_udpSocketv4 != null)
|
||||
_udpSocketv4.Close();
|
||||
if (_udpSocketv6 != null)
|
||||
_udpSocketv6.Close();
|
||||
_udpSocketv4 = null;
|
||||
_udpSocketv6 = null;
|
||||
|
||||
if (_threadv4 != null && _threadv4 != Thread.CurrentThread)
|
||||
_threadv4.Join();
|
||||
if (_threadv6 != null && _threadv6 != Thread.CurrentThread)
|
||||
_threadv6.Join();
|
||||
_threadv4 = null;
|
||||
_threadv6 = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetSocket.cs.meta
vendored
Normal file
11
UnityGame/Assets/Scripts/ThirdParty/ConsolePro/Remote/LiteNetLib/NetSocket.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c517b909a8c704eae91d4eccf06bc8a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user