[+] TEngineServer

[+] TEngineServer
This commit is contained in:
ALEXTANG
2023-07-13 17:17:26 +08:00
parent a69f53592e
commit 0c8f3a5f92
790 changed files with 52737 additions and 2533 deletions

View File

@@ -0,0 +1,184 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TEngine.DataStructure;
using TEngine.Core;
namespace TEngine
{
public sealed class EntitiesSystem : Singleton<EntitiesSystem>, IUpdateSingleton
{
private readonly OneToManyList<int, Type> _assemblyList = new();
private readonly Dictionary<Type, IAwakeSystem> _awakeSystems = new();
private readonly Dictionary<Type, IUpdateSystem> _updateSystems = new();
private readonly Dictionary<Type, IDestroySystem> _destroySystems = new();
private readonly Dictionary<Type, IEntitiesSystem> _deserializeSystems = new();
private readonly Queue<long> _updateQueue = new Queue<long>();
protected override void OnLoad(int assemblyName)
{
foreach (var entitiesSystemType in AssemblyManager.ForEach(assemblyName, typeof(IEntitiesSystem)))
{
var entity = Activator.CreateInstance(entitiesSystemType);
switch (entity)
{
case IAwakeSystem iAwakeSystem:
{
_awakeSystems.Add(iAwakeSystem.EntitiesType(), iAwakeSystem);
break;
}
case IDestroySystem iDestroySystem:
{
_destroySystems.Add(iDestroySystem.EntitiesType(), iDestroySystem);
break;
}
case IDeserializeSystem iDeserializeSystem:
{
_deserializeSystems.Add(iDeserializeSystem.EntitiesType(), iDeserializeSystem);
break;
}
case IUpdateSystem iUpdateSystem:
{
_updateSystems.Add(iUpdateSystem.EntitiesType(), iUpdateSystem);
break;
}
}
_assemblyList.Add(assemblyName, entitiesSystemType);
}
}
protected override void OnUnLoad(int assemblyName)
{
if (!_assemblyList.TryGetValue(assemblyName, out var assembly))
{
return;
}
_assemblyList.RemoveByKey(assemblyName);
foreach (var type in assembly)
{
_awakeSystems.Remove(type);
_updateSystems.Remove(type);
_destroySystems.Remove(type);
_deserializeSystems.Remove(type);
}
}
public void Awake<T>(T entity) where T : Entity
{
var type = entity.GetType();
if (!_awakeSystems.TryGetValue(type, out var awakeSystem))
{
return;
}
try
{
awakeSystem.Invoke(entity);
}
catch (Exception e)
{
Log.Error($"{type.Name} Error {e}");
}
}
public void Destroy<T>(T entity) where T : Entity
{
var type = entity.GetType();
if (!_destroySystems.TryGetValue(type, out var system))
{
return;
}
try
{
system.Invoke(entity);
}
catch (Exception e)
{
Log.Error($"{type.Name} Error {e}");
}
}
public void Deserialize<T>(T entity) where T : Entity
{
var type = entity.GetType();
if (!_deserializeSystems.TryGetValue(type, out var system))
{
return;
}
try
{
system.Invoke(entity);
}
catch (Exception e)
{
Log.Error($"{type.Name} Error {e}");
}
}
public void StartUpdate(Entity entity)
{
if (!_updateSystems.ContainsKey(entity.GetType()))
{
return;
}
_updateQueue.Enqueue(entity.RuntimeId);
}
public void Update()
{
var updateQueueCount = _updateQueue.Count;
while (updateQueueCount-- > 0)
{
var runtimeId = _updateQueue.Dequeue();
var entity = Entity.GetEntity(runtimeId);
if (entity == null || entity.IsDisposed)
{
continue;
}
var type = entity.GetType();
if (!_updateSystems.TryGetValue(type, out var updateSystem))
{
continue;
}
_updateQueue.Enqueue(runtimeId);
try
{
updateSystem.Invoke(entity);
}
catch (Exception e)
{
Log.Error($"{type} Error {e}");
}
}
}
public override void Dispose()
{
_assemblyList.Clear();
_awakeSystems.Clear();
_updateSystems.Clear();
_destroySystems.Clear();
_deserializeSystems.Clear();
AssemblyManager.OnLoadAssemblyEvent -= OnLoad;
AssemblyManager.OnUnLoadAssemblyEvent -= OnUnLoad;
base.Dispose();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ebd4150be3b67b4bafd633a97a738c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,553 @@
using System;
using System.Collections.Generic;
using TEngine.Core;
using System.Runtime.Serialization;
using TEngine.DataStructure;
using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json;
#pragma warning disable CS8618
#pragma warning disable CS8625
#pragma warning disable CS8601
#pragma warning disable CS8603
#pragma warning disable CS0436
// ReSharper disable SuspiciousTypeConversion.Global
// ReSharper disable InconsistentNaming
namespace TEngine
{
public abstract class Entity : IDisposable
{
#region Entities
private static readonly Dictionary<long, Entity> Entities = new Dictionary<long, Entity>();
private static readonly OneToManyQueue<Type, Entity> Pool = new OneToManyQueue<Type, Entity>();
public static Entity GetEntity(long runTimeId)
{
return Entities.TryGetValue(runTimeId, out var entity) ? entity : null;
}
public static bool TryGetEntity(long runTimeId, out Entity entity)
{
return Entities.TryGetValue(runTimeId, out entity);
}
public static T GetEntity<T>(long runTimeId) where T : Entity, new()
{
if (!Entities.TryGetValue(runTimeId, out var entity))
{
return default;
}
return (T) entity;
}
public static bool TryGetEntity<T>(long runTimeId, out T outEntity) where T : Entity, new()
{
if (!Entities.TryGetValue(runTimeId, out var entity))
{
outEntity = default;
return false;
}
outEntity = (T) entity;
return true;
}
private static T Rent<T>(Type entityType) where T : Entity, new()
{
if (typeof(INotSupportedPool).IsAssignableFrom(entityType))
{
return Activator.CreateInstance<T>();
}
T entity;
if (Pool.TryDequeue(entityType, out var poolEntity))
{
entity = (T) poolEntity;
}
else
{
entity = Activator.CreateInstance<T>();
}
entity._isFromPool = true;
return entity;
}
private static void Return(Entity entity)
{
entity.Id = 0;
if (!entity._isFromPool)
{
return;
}
entity._isFromPool = false;
Pool.Enqueue(entity.GetType(), entity);
}
#endregion
#region Create
public static T Create<T>(Scene scene, bool isRunEvent = true) where T : Entity, new()
{
var entity = Create<T>(scene.RouteId, isRunEvent);
entity.Scene = scene;
return entity;
}
public static T Create<T>(Scene scene, long id, bool isRunEvent = true) where T : Entity, new()
{
var entity = Create<T>(id, scene.RouteId, isRunEvent);
entity.Scene = scene;
return entity;
}
private static T Create<T>(uint routeId, bool isRunEvent = true) where T : Entity, new()
{
var entity = Rent<T>(typeof(T));
#if TENGINE_NET
entity.Id = entity.RuntimeId = IdFactory.NextEntityId(routeId);
#else
entity.Id = entity.RuntimeId = IdFactory.NextRunTimeId();
#endif
Entities.Add(entity.RuntimeId, entity);
if (isRunEvent)
{
EntitiesSystem.Instance.Awake(entity);
EntitiesSystem.Instance.StartUpdate(entity);
}
return entity;
}
private static T Create<T>(long id, uint routeId, bool isRunEvent = true) where T : Entity, new()
{
return Create<T>(id, IdFactory.NextEntityId(routeId), isRunEvent);
}
private static T Create<T>(long id, long runtimeId, bool isRunEvent = true) where T : Entity, new()
{
var entity = Rent<T>(typeof(T));
entity.Id = id;
entity.RuntimeId = runtimeId;
Entities.Add(entity.RuntimeId, entity);
if (isRunEvent)
{
EntitiesSystem.Instance.Awake(entity);
EntitiesSystem.Instance.StartUpdate(entity);
}
return entity;
}
protected static Scene CreateScene(long id, bool isRunEvent = true)
{
var entity = Create<Scene>(id, id, isRunEvent);
entity.Scene = entity;
return entity;
}
#endregion
#region Members
[BsonId]
[BsonElement]
[BsonIgnoreIfDefault]
[BsonDefaultValue(0L)]
public long Id { get; private set; }
[BsonIgnore]
[IgnoreDataMember]
public long RuntimeId { get; private set; }
[BsonIgnore]
[JsonIgnore]
[IgnoreDataMember]
public bool IsDisposed => RuntimeId == 0;
[BsonIgnore]
[JsonIgnore]
[IgnoreDataMember]
public Scene Scene { get; private set; }
[BsonIgnore]
[JsonIgnore]
[IgnoreDataMember]
public Entity Parent { get; private set; }
[BsonElement("t")]
[BsonIgnoreIfNull]
private ListPool<Entity> _treeDb;
[BsonIgnore]
[IgnoreDataMember]
private DictionaryPool<Type, Entity> _tree;
[BsonElement("m")]
[BsonIgnoreIfNull]
private ListPool<Entity> _multiDb;
[BsonIgnore]
[IgnoreDataMember]
private DictionaryPool<long, ISupportedMultiEntity> _multi;
[BsonIgnore]
[IgnoreDataMember]
private bool _isFromPool;
#endregion
#region AddComponent
public T AddComponent<T>() where T : Entity, new()
{
var entity = Create<T>(Scene.RouteId, false);
AddComponent(entity);
EntitiesSystem.Instance.Awake(entity);
EntitiesSystem.Instance.StartUpdate(entity);
return entity;
}
public T AddComponent<T>(long id) where T : Entity, new()
{
var entity = Create<T>(id, Scene.RouteId, false);
AddComponent(entity);
EntitiesSystem.Instance.Awake(entity);
EntitiesSystem.Instance.StartUpdate(entity);
return entity;
}
public void AddComponent(Entity component)
{
if (this == component)
{
Log.Error("Cannot add oneself to one's own components");
return;
}
if (component.IsDisposed)
{
Log.Error($"component is Disposed {component.GetType().FullName}");
return;
}
var type = component.GetType();
component.Parent?.RemoveComponent(component, false);
if (component is ISupportedMultiEntity multiEntity)
{
_multi ??= DictionaryPool<long, ISupportedMultiEntity>.Create();
_multi.Add(component.Id, multiEntity);
if (component is ISupportedDataBase)
{
_multiDb ??= ListPool<Entity>.Create();
_multiDb.Add(component);
}
}
else
{
if (_tree == null)
{
_tree = DictionaryPool<Type, Entity>.Create();
}
else if(_tree.ContainsKey(type))
{
Log.Error($"type:{type.FullName} If you want to add multiple components of the same type, please implement IMultiEntity");
return;
}
_tree.Add(type, component);
if (component is ISupportedDataBase)
{
_treeDb ??= ListPool<Entity>.Create();
_treeDb.Add(component);
}
}
component.Parent = this;
component.Scene = Scene;
}
#endregion
#region GetComponent
public T GetComponent<T>() where T : Entity, new()
{
return GetComponent(typeof(T)) as T;
}
public Entity GetComponent(Type componentType)
{
if (_tree == null)
{
return default;
}
return _tree.TryGetValue(componentType, out var component) ? component : default;
}
public T GetComponent<T>(long id) where T : ISupportedMultiEntity, new()
{
if (_multi == null)
{
return default;
}
return _multi.TryGetValue(id, out var entity) ? (T) entity : default;
}
#endregion
#region RemoveComponent
public void RemoveComponent<T>(bool isDispose = true) where T : Entity, new()
{
if (_tree == null || !_tree.TryGetValue(typeof(T), out var component))
{
return;
}
RemoveComponent(component, isDispose);
}
public void RemoveComponent<T>(long id, bool isDispose = true) where T : ISupportedMultiEntity, new()
{
if (_multi == null || !_multi.TryGetValue(id, out var component))
{
return;
}
RemoveComponent((Entity)component, isDispose);
}
public void RemoveComponent(Entity component, bool isDispose = true)
{
if (this == component)
{
return;
}
if (component is ISupportedMultiEntity)
{
if (_multi != null)
{
#if TENGINE_NET
if (component is ISupportedDataBase && _multiDb != null)
{
_multiDb.Remove(component);
if (_multiDb.Count == 0)
{
_multiDb.Dispose();
_multiDb = null;
}
}
#endif
_multi.Remove(component.Id);
if (_multi.Count == 0)
{
_multi.Dispose();
_multi = null;
}
}
}
else if (_tree != null)
{
#if TENGINE_NET
if (component is ISupportedDataBase && _treeDb != null)
{
_treeDb.Remove(component);
if (_treeDb.Count == 0)
{
_treeDb.Dispose();
_treeDb = null;
}
}
#endif
_tree.Remove(component.GetType());
if (_tree.Count == 0)
{
_tree.Dispose();
_tree = null;
}
}
if (isDispose)
{
component.Dispose();
}
}
#endregion
#region Deserialize
public void Deserialize(Scene scene, bool resetId = false)
{
if (IsDisposed)
{
Log.Error($"component is Disposed {this.GetType().FullName}");
return;
}
if (RuntimeId != 0)
{
return;
}
try
{
#if TENGINE_NET
RuntimeId = IdFactory.NextEntityId(scene.RouteId);
#else
RuntimeId = IdFactory.NextRunTimeId();
#endif
if (resetId)
{
Id = RuntimeId;
}
Entities.Add(RuntimeId, this);
if (_treeDb != null && _treeDb.Count > 0)
{
_tree = DictionaryPool<Type, Entity>.Create();
foreach (var entity in _treeDb)
{
entity.Parent = this;
entity.Scene = scene;
entity.Deserialize(scene, resetId);
_tree.Add(entity.GetType(), entity);
}
}
if (_multiDb != null && _multiDb.Count > 0)
{
_multi = DictionaryPool<long, ISupportedMultiEntity>.Create();
foreach (var entity in _multiDb)
{
entity.Parent = this;
entity.Scene = scene;
entity.Deserialize(scene, resetId);
_multi.Add(entity.Id, (ISupportedMultiEntity)entity);
}
}
}
catch (Exception e)
{
if (RuntimeId != 0)
{
Entities.Remove(RuntimeId);
}
Log.Error(e);
}
}
#endregion
#region Clone
public Entity Clone()
{
#if TENGINE_NET
var entity = MongoHelper.Instance.Clone(this);
entity.Deserialize(Scene, true);
return entity;
#elif TENGINE_UNITY
var entity = ProtoBufHelper.Clone(this);
entity.Deserialize(Scene, true);
return entity;
#endif
}
#endregion
#region Dispose
public virtual void Dispose()
{
if (IsDisposed)
{
return;
}
var runtimeId = RuntimeId;
RuntimeId = 0;
if (_tree != null)
{
foreach (var (_, entity) in _tree)
{
entity.Dispose();
}
_tree.Dispose();
_tree = null;
}
if (_multi != null)
{
foreach (var (_, entity) in _multi)
{
entity.Dispose();
}
_multi.Dispose();
_multi = null;
}
#if TENGINE_NET
if (_treeDb != null)
{
foreach (var entity in _treeDb)
{
entity.Dispose();
}
_treeDb.Dispose();
_treeDb = null;
}
if (_multiDb != null)
{
foreach (var entity in _multiDb)
{
entity.Dispose();
}
_multiDb.Dispose();
_multiDb = null;
}
#endif
EntitiesSystem.Instance?.Destroy(this);
if (Parent != null && Parent != this && !Parent.IsDisposed)
{
Parent.RemoveComponent(this, false);
Parent = null;
}
Entities.Remove(runtimeId);
Scene = null;
Return(this);
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4ac3a7a2c87dab48819ea8ad865ec76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2c5e09a29bcfe7c4f9f84422354a6d2c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0c3ff31e66c8ca44b8e99c068cdcc04a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
namespace TEngine
{
/// <summary>
/// Entity不支持对象池创建和回收
/// </summary>
public interface INotSupportedPool { }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9eceeefe7ee19f47bac590bc44d57d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
namespace TEngine
{
/// <summary>
/// Entity支持数据库
/// </summary>
// ReSharper disable once InconsistentNaming
public interface ISupportedDataBase { }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa02a2282c8866746a60eaaa35afb0de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System;
namespace TEngine
{
/// <summary>
/// 支持再一个组件里添加多个同类型组件
/// </summary>
public interface ISupportedMultiEntity : IDisposable { }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17d0f9fb53e07414991160d50cf133e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3473ee41e6d3cfa489bcf20bc8f6d546
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using System;
namespace TEngine
{
public interface IAwakeSystem : IEntitiesSystem { }
public abstract class AwakeSystem<T> : IAwakeSystem where T : Entity
{
public Type EntitiesType() => typeof(T);
protected abstract void Awake(T self);
public void Invoke(Entity self)
{
Awake((T) self);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e152a700f49f0748bfbdd03108a4a5e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using System;
namespace TEngine
{
public interface IDeserializeSystem : IEntitiesSystem { }
public abstract class DeserializeSystem<T> : IDeserializeSystem where T : Entity
{
public Type EntitiesType() => typeof(T);
protected abstract void Deserialize(T self);
public void Invoke(Entity self)
{
Deserialize((T) self);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be8b21b9058e78343abfeea9277be75e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using System;
namespace TEngine
{
public interface IDestroySystem : IEntitiesSystem { }
public abstract class DestroySystem<T> : IDestroySystem where T : Entity
{
public Type EntitiesType() => typeof(T);
protected abstract void Destroy(T self);
public void Invoke(Entity self)
{
Destroy((T) self);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7140fd5ab56bd3b4ba04cfe40470ad23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
using System;
namespace TEngine
{
public interface IEntitiesSystem
{
public Type EntitiesType();
void Invoke(Entity entity);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4e4fa4e598c849148a0dd63e785716f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using System;
namespace TEngine
{
public interface IUpdateSystem : IEntitiesSystem { }
public abstract class UpdateSystem<T> : IUpdateSystem where T : Entity
{
public Type EntitiesType() => typeof(T);
protected abstract void Update(T self);
public void Invoke(Entity self)
{
Update((T) self);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f39edd76db52bd84aa385cd02fa98db8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3d9f783d00ec372489401151473f8d7e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using TEngine.Core.Network;
using TEngine.Core;
#if TENGINE_NET
using TEngine.Core.DataBase;
#endif
#pragma warning disable CS8625
#pragma warning disable CS8618
namespace TEngine
{
public sealed class Scene : Entity, INotSupportedPool
{
public string Name { get; private set; }
public uint RouteId { get; private set; }
#if TENGINE_UNITY
public Session Session { get; private set; }
public SceneConfigInfo SceneInfo { get; private set; }
#endif
#if TENGINE_NET
public World World { get; private set; }
public Server Server { get; private set; }
public uint SceneConfigId { get; private set; }
public SceneConfigInfo SceneInfo => ConfigTableManage.SceneConfig(SceneConfigId);
#endif
public static readonly List<Scene> Scenes = new List<Scene>();
public override void Dispose()
{
if (IsDisposed)
{
return;
}
Name = null;
RouteId = 0;
#if TENGINE_NET
World = null;
Server = null;
SceneConfigId = 0;
#endif
#if TENGINE_UNITY
SceneInfo = null;
if (Session is { IsDisposed: false })
{
Session.Dispose();
Session = null;
}
#endif
Scenes.Remove(this);
base.Dispose();
}
public static void DisposeAllScene()
{
foreach (var scene in Scenes.ToArray())
{
scene.Dispose();
}
}
#if TENGINE_UNITY
public static Scene Create(string name)
{
var runTimeId = IdFactory.NextRunTimeId();
var scene = CreateScene(runTimeId);
scene.Name = name;
Scenes.Add(scene);
return scene;
}
public void CreateSession(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000)
{
var address = NetworkHelper.ToIPEndPoint(remoteAddress);
var clientNetworkComponent = AddComponent<ClientNetworkComponent>();
clientNetworkComponent.Initialize(networkProtocolType, NetworkTarget.Outer);
clientNetworkComponent.Connect(address, onConnectComplete, onConnectFail, connectTimeout);
Session = clientNetworkComponent.Session;
}
#else
/// <summary>
/// 创建一个Scene
/// </summary>
/// <param name="server"></param>
/// <param name="outerBindIp"></param>
/// <param name="sceneInfo"></param>
/// <param name="runEvent"></param>
/// <param name="onSetNetworkComplete"></param>
/// <returns></returns>
public static async FTask<Scene> Create(Server server, string outerBindIp, SceneConfigInfo sceneInfo, Action<Session> onSetNetworkComplete = null, bool runEvent = true)
{
var scene = CreateScene(sceneInfo.EntityId);
sceneInfo.Scene = scene;
scene.Name = sceneInfo.Name;
scene.RouteId = sceneInfo.RouteId;
scene.Server = server;
scene.SceneConfigId = sceneInfo.Id;
if (sceneInfo.WorldId != 0)
{
// 有可能不需要数据库、所以这里默认0的情况下就不创建数据库了
scene.World = World.Create(sceneInfo.WorldId);
}
if (!string.IsNullOrEmpty(sceneInfo.NetworkProtocol) && !string.IsNullOrEmpty(outerBindIp) && sceneInfo.OuterPort != 0)
{
// 设置Scene的网络、目前只支持KCP和TCP
var networkProtocolType = Enum.Parse<NetworkProtocolType>(sceneInfo.NetworkProtocol);
var serverNetworkComponent = scene.AddComponent<ServerNetworkComponent>();
var address = NetworkHelper.ToIPEndPoint($"{outerBindIp}:{sceneInfo.OuterPort}");
serverNetworkComponent.Initialize(networkProtocolType, NetworkTarget.Outer, address);
}
if (runEvent && sceneInfo.SceneType != null)
{
// 没有SceneType目前只有代码创建的Scene才会这样、目前只有Server的Scene是这样
await EventSystem.Instance.PublishAsync(new OnCreateScene(sceneInfo, onSetNetworkComplete));
}
Scenes.Add(scene);
return scene;
}
/// <summary>
/// 一般用于创建临时Scene、如果不是必要不建议使用这个接口
/// </summary>
/// <param name="name"></param>
/// <param name="server"></param>
/// <param name="entityId"></param>
/// <param name="sceneConfigId"></param>
/// <param name="networkProtocol"></param>
/// <param name="outerBindIp"></param>
/// <param name="outerPort"></param>
/// <param name="runEvent"></param>
/// <param name="onSetNetworkComplete"></param>
/// <returns></returns>
public static async FTask<Scene> Create(string name, Server server, long entityId, uint sceneConfigId = 0, string networkProtocol = null, string outerBindIp = null, int outerPort = 0, Action<Session> onSetNetworkComplete = null, bool runEvent = true)
{
var sceneInfo = new SceneConfigInfo()
{
Name = name,
EntityId = entityId,
Id = sceneConfigId,
NetworkProtocol = networkProtocol,
OuterPort = outerPort,
WorldId = ((EntityIdStruct)entityId).WordId
};
return await Create(server, outerBindIp, sceneInfo, onSetNetworkComplete, runEvent);
}
public static List<SceneConfigInfo> GetSceneInfoByRouteId(uint routeId)
{
var list = new List<SceneConfigInfo>();
var allSceneConfig = ConfigTableManage.AllSceneConfig();
foreach (var sceneConfigInfo in allSceneConfig)
{
if (sceneConfigInfo.RouteId != routeId)
{
continue;
}
list.Add(sceneConfigInfo);
}
return list;
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 12c279f9aa38cab41b3bf04be0eea700
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
#if TENGINE_NET
using System;
using TEngine.Core.Network;
namespace TEngine
{
public struct OnCreateScene
{
public readonly SceneConfigInfo SceneInfo;
public readonly Action<Session> OnSetNetworkComplete;
public OnCreateScene(SceneConfigInfo sceneInfo, Action<Session> onSetNetworkComplete)
{
SceneInfo = sceneInfo;
OnSetNetworkComplete = onSetNetworkComplete;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e237f0cc7a65b51408d828a87535b4dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7cdae026533d88e4684eca7b48850d12
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f3af894a35a86864fa02cf949eb89f03
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
#if TENGINE_UNITY
using System;
namespace MongoDB.Bson.Serialization.Attributes
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class BsonDefaultValueAttribute : Attribute
{
public BsonDefaultValueAttribute(object defaultValue) { }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 49dc7c79f6822c64e927ca4f5cad88f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
#if TENGINE_UNITY
using System;
namespace MongoDB.Bson.Serialization.Attributes
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class BsonElementAttribute : Attribute
{
public BsonElementAttribute() { }
public BsonElementAttribute(string elementName) { }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9218b708df975ba428c2342e978cd473
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
#if TENGINE_UNITY
using System;
namespace MongoDB.Bson.Serialization.Attributes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class BsonIdAttribute : Attribute
{
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3e07e248c36907847adb96b09269689f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
#if TENGINE_UNITY
using System;
namespace MongoDB.Bson.Serialization.Attributes
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class BsonIgnoreAttribute : Attribute
{
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a11815e9c0d9fe24f97da6a976538bfc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
#if TENGINE_UNITY
using System;
namespace MongoDB.Bson.Serialization.Attributes
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class BsonIgnoreIfDefaultAttribute : Attribute
{
public BsonIgnoreIfDefaultAttribute() { }
public BsonIgnoreIfDefaultAttribute(bool value) { }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24366fa27fe479a439c306cae6a2cf98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
#if TENGINE_UNITY
using System;
namespace MongoDB.Bson.Serialization.Attributes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class BsonIgnoreIfNullAttribute : Attribute
{
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb14d1148e275bf4f8220694eab51fc0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: