253 lines
8.5 KiB
C#
253 lines
8.5 KiB
C#
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using BITKit;
|
||
|
using BITKit.UX;
|
||
|
using BITKit.HttpNet;
|
||
|
using Cysharp.Threading.Tasks;
|
||
|
using Net.Client;
|
||
|
using UnityEngine.UIElements;
|
||
|
using System.Text;
|
||
|
using Net.Share;
|
||
|
using Object = System.Object;
|
||
|
|
||
|
namespace BITKit
|
||
|
{
|
||
|
public interface INetClientProvider
|
||
|
{
|
||
|
ClientBase GetClient();
|
||
|
}
|
||
|
[CreateOnStart(BITAppForUnity.Path.Services,nameof(BITNet))]
|
||
|
public class BITNet : MonoBehaviour
|
||
|
{
|
||
|
[UnityEngine.RuntimeInitializeOnLoadMethod]
|
||
|
static void Reload()
|
||
|
{
|
||
|
OnStartConnect = null;
|
||
|
OnConnected = null;
|
||
|
OnConnectFailed = null;
|
||
|
OnTryToConnect = null;
|
||
|
OnTryToConnectFailed = null;
|
||
|
OnDisconnect = null;
|
||
|
OnConnectLost = null;
|
||
|
OnConnection = null;
|
||
|
OnReconnect = null;
|
||
|
OnOnWhenQueuing = null;
|
||
|
OnOnQueueCancellation = null;
|
||
|
RpcHandles.Clear();
|
||
|
}
|
||
|
public static event Action OnStartConnect;
|
||
|
public static event Action OnConnected;
|
||
|
public static event Action OnConnectFailed;
|
||
|
public static event Action OnTryToConnect;
|
||
|
public static event Action OnTryToConnectFailed;
|
||
|
public static event Action OnDisconnect;
|
||
|
public static event Action OnConnectLost;
|
||
|
public static event Action OnConnection;
|
||
|
public static event Action OnReconnect;
|
||
|
public static event Action OnOnWhenQueuing;
|
||
|
public static event Action OnOnQueueCancellation;
|
||
|
|
||
|
private static BITNet Singleton;
|
||
|
private static readonly List<object> RpcHandles = new();
|
||
|
private static readonly Queue<(string name,Object[] pars)> Rpcs = new();
|
||
|
[BITCommand]
|
||
|
public static void Connect(string address, int port)
|
||
|
{
|
||
|
Singleton.ConnectInternal(address, port);
|
||
|
}
|
||
|
public static Action<object> AddRpcHandle => RpcHandles.Add;
|
||
|
public static void SendRT(string rpcName, params object[] pars)
|
||
|
{
|
||
|
Rpcs.Enqueue(new()
|
||
|
{
|
||
|
name = rpcName,
|
||
|
pars = pars
|
||
|
});
|
||
|
}
|
||
|
[Header(Constant.Header.Settings)]
|
||
|
public string address = "localhost";
|
||
|
public int port = 666;
|
||
|
public int apiPort = 27014;
|
||
|
[Header(Constant.Header.Settings)]
|
||
|
[SerializeReference, SubclassSelector] public IWebProvider webProvider;
|
||
|
[SerializeReference, SubclassSelector] public INetClientProvider clientProvider;
|
||
|
[Header(Constant.Header.InternalVariables)]
|
||
|
ClientBase client;
|
||
|
private string GetApiUrl(string address) => $"http://{address}:{apiPort}/api";
|
||
|
public string GetAPI(params string[] path)
|
||
|
{
|
||
|
return GetApiUrl(address) + "/" + String.Join("/", path);
|
||
|
}
|
||
|
[BIT]
|
||
|
public void ConnectToServer()
|
||
|
{
|
||
|
ConnectInternal(address, port);
|
||
|
}
|
||
|
[BIT]
|
||
|
public void ConnectToLocal()
|
||
|
{
|
||
|
ConnectInternal("localhost", port);
|
||
|
}
|
||
|
[BIT]
|
||
|
public void Disconnect()
|
||
|
{
|
||
|
client.Close();
|
||
|
//clientManager.client.Close();
|
||
|
}
|
||
|
async void ConnectInternal(string address, int port)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
foreach (var x in RpcHandles)
|
||
|
{
|
||
|
client.AddRpcHandle(x);
|
||
|
}
|
||
|
|
||
|
OnStartConnect?.Invoke();
|
||
|
var message = $"正在获取api:{GetApiUrl(address)}";
|
||
|
|
||
|
Data.Set<IProgress>(new ProgressInfo()
|
||
|
{
|
||
|
Progress = 0.1f,
|
||
|
Message = message,
|
||
|
});
|
||
|
|
||
|
Debug.Log(message);
|
||
|
await webProvider
|
||
|
.GetAsync<Package>(GetApiUrl(address),this.GetCancellationTokenOnDestroy());
|
||
|
|
||
|
message = $"已获取到服务器信息,正在连接到服务器";
|
||
|
|
||
|
Data.Set<IProgress>(new ProgressInfo()
|
||
|
{
|
||
|
Progress = 0.2f,
|
||
|
Message = message,
|
||
|
});
|
||
|
client.host = address;
|
||
|
client.port = port;
|
||
|
//client.ip=address;
|
||
|
//clientManager.port=port;
|
||
|
|
||
|
if (await client.Connect())
|
||
|
{
|
||
|
Data.Set<IProgress>(new ProgressInfo()
|
||
|
{
|
||
|
Progress = 0.1f,
|
||
|
Message = "已获取到在线服务器",
|
||
|
});
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool isConnected = false;
|
||
|
for (int i = 0; i < 3; i++)
|
||
|
{
|
||
|
if(await client.Connect())
|
||
|
{
|
||
|
isConnected=true;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Data.Set<IProgress>(new ProgressInfo()
|
||
|
{
|
||
|
Progress = 0.1f + i*0.1f,
|
||
|
Message = "正在尝试重新连接到服务器",
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
if(isConnected)
|
||
|
{
|
||
|
Data.Set<IProgress>(new ProgressInfo()
|
||
|
{
|
||
|
Progress = 0.5f,
|
||
|
Message = "已连接,正在加载中...",
|
||
|
});
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Alert.Print(new()
|
||
|
{
|
||
|
title = "连接失败",
|
||
|
message = "已找到服务端但未找到服务器",
|
||
|
});
|
||
|
OnConnectFailed?.Invoke();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch (System.Net.Http.HttpRequestException e)
|
||
|
{
|
||
|
Alert.Print(new AlertMessage()
|
||
|
{
|
||
|
title = "未找到服务端:",
|
||
|
message = e.Message,
|
||
|
});
|
||
|
OnConnectFailed?.Invoke();
|
||
|
}
|
||
|
catch (System.Exception e)
|
||
|
{
|
||
|
Alert.Print(new AlertMessage()
|
||
|
{
|
||
|
title = "无法连接到服务端",
|
||
|
message = e.Message,
|
||
|
});
|
||
|
Debug.Log(e.GetType().FullName);
|
||
|
BIT4Log.LogException(e);
|
||
|
OnConnectFailed?.Invoke();
|
||
|
}
|
||
|
}
|
||
|
void Awake()
|
||
|
{
|
||
|
Singleton = this;
|
||
|
DI.Register(this);
|
||
|
client = clientProvider.GetClient();
|
||
|
DI.Register(client);
|
||
|
|
||
|
}
|
||
|
void Start()
|
||
|
{
|
||
|
/*
|
||
|
* None,
|
||
|
Connected,
|
||
|
ConnectFailed,
|
||
|
TryToConnect,
|
||
|
TryToConnectFailed,
|
||
|
Disconnect,
|
||
|
ConnectLost,
|
||
|
ConnectClosed,
|
||
|
Connection,
|
||
|
Reconnect,
|
||
|
OnWhenQueuing,
|
||
|
OnQueueCancellation,
|
||
|
*/
|
||
|
client.AddStateHandler(NetworkState.Connected,OnConnected);
|
||
|
client.AddStateHandler(NetworkState.ConnectFailed,OnConnectFailed);
|
||
|
client.AddStateHandler(NetworkState.TryToConnect,OnTryToConnect);
|
||
|
client.AddStateHandler(NetworkState.TryToConnectFailed,OnTryToConnectFailed);
|
||
|
client.AddStateHandler(NetworkState.Disconnect,OnDisconnect);
|
||
|
client.AddStateHandler(NetworkState.ConnectLost,OnConnectLost);
|
||
|
client.AddStateHandler(NetworkState.ConnectClosed,OnConnectLost);
|
||
|
client.AddStateHandler(NetworkState.Connection,OnConnection);
|
||
|
client.AddStateHandler(NetworkState.Reconnect,OnReconnect);
|
||
|
client.AddStateHandler(NetworkState.OnWhenQueuing,OnOnWhenQueuing);
|
||
|
client.AddStateHandler(NetworkState.OnQueueCancellation,OnOnQueueCancellation);
|
||
|
}
|
||
|
|
||
|
void Update()
|
||
|
{
|
||
|
if (client is null || client.Client is null || client.Client.Connected is false) return;
|
||
|
while (Rpcs.TryDequeue(out var rpc))
|
||
|
{
|
||
|
client.SendRT(rpc.name,rpc.pars);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#if UNITY_EDITOR
|
||
|
[UnityEditor.CustomEditor(typeof(BITNet))]
|
||
|
public class BITNetInspector : BITInspector<BITNet>
|
||
|
{
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
}
|