mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
[+] 接入ET8服务端
[+] 接入ET8服务端
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
namespace ET
|
||||
{
|
||||
public class FixedTimeCounter
|
||||
{
|
||||
private long startTime;
|
||||
private int startFrame;
|
||||
public int Interval { get; private set; }
|
||||
|
||||
public FixedTimeCounter(long startTime, int startFrame, int interval)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
this.startFrame = startFrame;
|
||||
this.Interval = interval;
|
||||
}
|
||||
|
||||
public void ChangeInterval(int interval, int frame)
|
||||
{
|
||||
this.startTime += (frame - this.startFrame) * this.Interval;
|
||||
this.startFrame = frame;
|
||||
this.Interval = interval;
|
||||
}
|
||||
|
||||
public long FrameTime(int frame)
|
||||
{
|
||||
return this.startTime + (frame - this.startFrame) * this.Interval;
|
||||
}
|
||||
|
||||
public void Reset(long time, int frame)
|
||||
{
|
||||
this.startTime = time;
|
||||
this.startFrame = frame;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a78339a190b64d92ba482cd00b239f52
|
||||
timeCreated: 1682422635
|
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public class FrameBuffer
|
||||
{
|
||||
public int MaxFrame { get; private set; }
|
||||
private readonly List<OneFrameInputs> frameInputs;
|
||||
private readonly List<MemoryBuffer> snapshots;
|
||||
private readonly List<long> hashs;
|
||||
|
||||
public FrameBuffer(int frame = 0, int capacity = LSConstValue.FrameCountPerSecond * 60)
|
||||
{
|
||||
this.MaxFrame = frame + LSConstValue.FrameCountPerSecond * 30;
|
||||
this.frameInputs = new List<OneFrameInputs>(capacity);
|
||||
this.snapshots = new List<MemoryBuffer>(capacity);
|
||||
this.hashs = new List<long>(capacity);
|
||||
|
||||
for (int i = 0; i < this.snapshots.Capacity; ++i)
|
||||
{
|
||||
this.hashs.Add(0);
|
||||
this.frameInputs.Add(new OneFrameInputs());
|
||||
MemoryBuffer memoryBuffer = new(10240);
|
||||
memoryBuffer.SetLength(0);
|
||||
memoryBuffer.Seek(0, SeekOrigin.Begin);
|
||||
this.snapshots.Add(memoryBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHash(int frame, long hash)
|
||||
{
|
||||
EnsureFrame(frame);
|
||||
this.hashs[frame % this.frameInputs.Capacity] = hash;
|
||||
}
|
||||
|
||||
public long GetHash(int frame)
|
||||
{
|
||||
EnsureFrame(frame);
|
||||
return this.hashs[frame % this.frameInputs.Capacity];
|
||||
}
|
||||
|
||||
public bool CheckFrame(int frame)
|
||||
{
|
||||
if (frame < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frame > this.MaxFrame)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void EnsureFrame(int frame)
|
||||
{
|
||||
if (!CheckFrame(frame))
|
||||
{
|
||||
throw new Exception($"frame out: {frame}, maxframe: {this.MaxFrame}");
|
||||
}
|
||||
}
|
||||
|
||||
public OneFrameInputs FrameInputs(int frame)
|
||||
{
|
||||
EnsureFrame(frame);
|
||||
OneFrameInputs oneFrameInputs = this.frameInputs[frame % this.frameInputs.Capacity];
|
||||
return oneFrameInputs;
|
||||
}
|
||||
|
||||
public void MoveForward(int frame)
|
||||
{
|
||||
if (this.MaxFrame - frame > LSConstValue.FrameCountPerSecond) // 至少留出1秒的空间
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
++this.MaxFrame;
|
||||
|
||||
OneFrameInputs oneFrameInputs = this.FrameInputs(this.MaxFrame);
|
||||
oneFrameInputs.Inputs.Clear();
|
||||
}
|
||||
|
||||
public MemoryBuffer Snapshot(int frame)
|
||||
{
|
||||
EnsureFrame(frame);
|
||||
MemoryBuffer memoryBuffer = this.snapshots[frame % this.snapshots.Capacity];
|
||||
return memoryBuffer;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 248572437c2f47728e0191da78943fe5
|
||||
timeCreated: 1681719619
|
@@ -0,0 +1,7 @@
|
||||
namespace ET
|
||||
{
|
||||
public interface IActorRoom: IActorMessage
|
||||
{
|
||||
long PlayerId { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88154111be2b445c295e7208376f428b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public interface ILSRollback
|
||||
{
|
||||
}
|
||||
|
||||
public interface ILSRollbackSystem: ISystemType
|
||||
{
|
||||
void Run(Entity o);
|
||||
}
|
||||
|
||||
[LSEntitySystem]
|
||||
public abstract class LSRollbackSystem<T> : ILSRollbackSystem where T: Entity, ILSRollback
|
||||
{
|
||||
void ILSRollbackSystem.Run(Entity o)
|
||||
{
|
||||
this.LSRollback((T)o);
|
||||
}
|
||||
|
||||
Type ISystemType.Type()
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
|
||||
Type ISystemType.SystemType()
|
||||
{
|
||||
return typeof(ILSRollbackSystem);
|
||||
}
|
||||
|
||||
int ISystemType.GetInstanceQueueIndex()
|
||||
{
|
||||
return InstanceQueueIndex.None;
|
||||
}
|
||||
|
||||
protected abstract void LSRollback(T self);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27067471cd1c7d045bb855b9f4f4c9b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public interface ILSUpdate
|
||||
{
|
||||
}
|
||||
|
||||
public interface ILSUpdateSystem: ISystemType
|
||||
{
|
||||
void Run(LSEntity o);
|
||||
}
|
||||
|
||||
[LSEntitySystem]
|
||||
public abstract class LSUpdateSystem<T> : ILSUpdateSystem where T: LSEntity, ILSUpdate
|
||||
{
|
||||
void ILSUpdateSystem.Run(LSEntity o)
|
||||
{
|
||||
this.LSUpdate((T)o);
|
||||
}
|
||||
|
||||
Type ISystemType.Type()
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
|
||||
Type ISystemType.SystemType()
|
||||
{
|
||||
return typeof(ILSUpdateSystem);
|
||||
}
|
||||
|
||||
int ISystemType.GetInstanceQueueIndex()
|
||||
{
|
||||
return LSQueneUpdateIndex.LSUpdate;
|
||||
}
|
||||
|
||||
protected abstract void LSUpdate(T self);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dc2986d4ec384cad9cf41a6eef3f6eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,10 @@
|
||||
namespace ET
|
||||
{
|
||||
public static class LSConstValue
|
||||
{
|
||||
public const int MatchCount = 1;
|
||||
public const int UpdateInterval = 50;
|
||||
public const int FrameCountPerSecond = 1000 / UpdateInterval;
|
||||
public const int SaveLSWorldFrameCount = 60 * FrameCountPerSecond;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1af7fd8703b4dc3a521ef52d538d168
|
||||
timeCreated: 1681819811
|
72
Assets/GameScripts/DotNet/Model/Share/LockStep/LSEntity.cs
Normal file
72
Assets/GameScripts/DotNet/Model/Share/LockStep/LSEntity.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public interface IRegisterLSEntitySystem
|
||||
{
|
||||
void RegisterSystem(LSEntity entity);
|
||||
}
|
||||
|
||||
[EnableMethod]
|
||||
public class LSEntity: Entity
|
||||
{
|
||||
public new K AddComponent<K>(bool isFromPool = false) where K : LSEntity, IAwake, new()
|
||||
{
|
||||
return this.AddComponentWithId<K>(this.GetId(), isFromPool);
|
||||
}
|
||||
|
||||
public new K AddComponent<K, P1>(P1 p1, bool isFromPool = false) where K : LSEntity, IAwake<P1>, new()
|
||||
{
|
||||
return this.AddComponentWithId<K, P1>(this.GetId(), p1, isFromPool);
|
||||
}
|
||||
|
||||
public new K AddComponent<K, P1, P2>(P1 p1, P2 p2, bool isFromPool = false) where K : LSEntity, IAwake<P1, P2>, new()
|
||||
{
|
||||
return this.AddComponentWithId<K, P1, P2>(this.GetId(), p1, p2, isFromPool);
|
||||
}
|
||||
|
||||
public new K AddComponent<K, P1, P2, P3>(P1 p1, P2 p2, P3 p3, bool isFromPool = false) where K : LSEntity, IAwake<P1, P2, P3>, new()
|
||||
{
|
||||
return this.AddComponentWithId<K, P1, P2, P3>(this.GetId(), p1, p2, p3, isFromPool);
|
||||
}
|
||||
|
||||
[EnableAccessEntiyChild]
|
||||
public new T AddChild<T>(bool isFromPool = false) where T : LSEntity, IAwake
|
||||
{
|
||||
return this.AddChildWithId<T>(this.GetId(), isFromPool);
|
||||
}
|
||||
|
||||
[EnableAccessEntiyChild]
|
||||
public new T AddChild<T, A>(A a, bool isFromPool = false) where T : LSEntity, IAwake<A>
|
||||
{
|
||||
return this.AddChildWithId<T, A>(this.GetId(), a, isFromPool);
|
||||
}
|
||||
|
||||
[EnableAccessEntiyChild]
|
||||
public new T AddChild<T, A, B>(A a, B b, bool isFromPool = false) where T : LSEntity, IAwake<A, B>
|
||||
{
|
||||
return this.AddChildWithId<T, A, B>(this.GetId(), a, b, isFromPool);
|
||||
}
|
||||
|
||||
[EnableAccessEntiyChild]
|
||||
public new T AddChild<T, A, B, C>(A a, B b, C c, bool isFromPool = false) where T : LSEntity, IAwake<A, B, C>
|
||||
{
|
||||
return this.AddChildWithId<T, A, B, C>(this.GetId(), a, b, c, isFromPool);
|
||||
}
|
||||
|
||||
protected override void RegisterSystem()
|
||||
{
|
||||
IRegisterLSEntitySystem iRegisterLsEntitySystem = (IRegisterLSEntitySystem)this.IScene;
|
||||
TypeSystems.OneTypeSystems oneTypeSystems = LSEntitySystemSingleton.Instance.GetOneTypeSystems(this.GetType());
|
||||
if (oneTypeSystems == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (oneTypeSystems.QueueFlag[LSQueneUpdateIndex.LSUpdate])
|
||||
{
|
||||
iRegisterLsEntitySystem.RegisterSystem(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c56b3bb10000446c8e48f82b6969093
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class LSEntitySystemAttribute: BaseAttribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83785c2329d8c4847b6fab0468c7f4d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[UniqueId(-1, 1)]
|
||||
public static class LSQueneUpdateIndex
|
||||
{
|
||||
public const int None = -1;
|
||||
public const int LSUpdate = 0;
|
||||
public const int Max = 1;
|
||||
}
|
||||
|
||||
public class LSEntitySystemSingleton: SingletonLock<LSEntitySystemSingleton>, ISingletonAwake
|
||||
{
|
||||
public TypeSystems TypeSystems { get; private set; }
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
this.TypeSystems = new(LSQueneUpdateIndex.Max);
|
||||
foreach (Type type in EventSystem.Instance.GetTypes(typeof (LSEntitySystemAttribute)))
|
||||
{
|
||||
object obj = Activator.CreateInstance(type);
|
||||
|
||||
if (obj is not ISystemType iSystemType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TypeSystems.OneTypeSystems oneTypeSystems = this.TypeSystems.GetOrCreateOneTypeSystems(iSystemType.Type());
|
||||
oneTypeSystems.Map.Add(iSystemType.SystemType(), obj);
|
||||
int index = iSystemType.GetInstanceQueueIndex();
|
||||
if (index > LSQueneUpdateIndex.None && index < LSQueneUpdateIndex.Max)
|
||||
{
|
||||
oneTypeSystems.QueueFlag[index] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
World.Instance.AddSingleton<LSEntitySystemSingleton>(true);
|
||||
}
|
||||
|
||||
public TypeSystems.OneTypeSystems GetOneTypeSystems(Type type)
|
||||
{
|
||||
return this.TypeSystems.GetOneTypeSystems(type);
|
||||
}
|
||||
|
||||
public void LSRollback(Entity entity)
|
||||
{
|
||||
if (entity is not ILSRollback)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<object> iLSRollbackSystems = this.TypeSystems.GetSystems(entity.GetType(), typeof (ILSRollbackSystem));
|
||||
if (iLSRollbackSystems == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ILSRollbackSystem iLSRollbackSystem in iLSRollbackSystems)
|
||||
{
|
||||
if (iLSRollbackSystem == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
iLSRollbackSystem.Run(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LSUpdate(LSEntity entity)
|
||||
{
|
||||
if (entity is not ILSUpdate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<object> iLSUpdateSystems = TypeSystems.GetSystems(entity.GetType(), typeof (ILSUpdateSystem));
|
||||
if (iLSUpdateSystems == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ILSUpdateSystem iLSUpdateSystem in iLSUpdateSystems)
|
||||
{
|
||||
try
|
||||
{
|
||||
iLSUpdateSystem.Run(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d43f6155cef5380498803ee6c4e00d63
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
50
Assets/GameScripts/DotNet/Model/Share/LockStep/LSInput.cs
Normal file
50
Assets/GameScripts/DotNet/Model/Share/LockStep/LSInput.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using MemoryPack;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[MemoryPackable]
|
||||
public partial struct LSInput
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public TrueSync.TSVector2 V;
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public int Button;
|
||||
|
||||
public bool Equals(LSInput other)
|
||||
{
|
||||
return this.V == other.V && this.Button == other.Button;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is LSInput other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(this.V, this.Button);
|
||||
}
|
||||
|
||||
public static bool operator==(LSInput a, LSInput b)
|
||||
{
|
||||
if (a.V != b.V)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.Button != b.Button)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator !=(LSInput a, LSInput b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2411352b8bd84ed8bf43aa625cf3d44
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
namespace ET
|
||||
{
|
||||
[ComponentOf(typeof(LSUnit))]
|
||||
public class LSInputComponent: LSEntity, ILSUpdate, IAwake, ISerializeToEntity
|
||||
{
|
||||
public LSInput LSInput { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0df77bdfbbb4a5fa2e9de116dabaaa2
|
||||
timeCreated: 1682051388
|
29
Assets/GameScripts/DotNet/Model/Share/LockStep/LSUnit.cs
Normal file
29
Assets/GameScripts/DotNet/Model/Share/LockStep/LSUnit.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using TrueSync;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[ChildOf(typeof(LSUnitComponent))]
|
||||
public class LSUnit: LSEntity, IAwake, ISerializeToEntity
|
||||
{
|
||||
public TSVector Position
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[BsonIgnore]
|
||||
public TSVector Forward
|
||||
{
|
||||
get => this.Rotation * TSVector.forward;
|
||||
set => this.Rotation = TSQuaternion.LookRotation(value, TSVector.up);
|
||||
}
|
||||
|
||||
public TSQuaternion Rotation
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c62694a15545f4b599f146f8a44e417c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,7 @@
|
||||
namespace ET
|
||||
{
|
||||
[ComponentOf(typeof(LSWorld))]
|
||||
public class LSUnitComponent: LSEntity, IAwake, ISerializeToEntity
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9b77ec7663d54ec88ba2a0297314aef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
46
Assets/GameScripts/DotNet/Model/Share/LockStep/LSUpdater.cs
Normal file
46
Assets/GameScripts/DotNet/Model/Share/LockStep/LSUpdater.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public class LSUpdater
|
||||
{
|
||||
private List<long> updateIds = new();
|
||||
private List<long> newUpdateIds = new();
|
||||
|
||||
private readonly Dictionary<long, EntityRef<LSEntity>> lsEntities = new();
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (this.newUpdateIds.Count > 0)
|
||||
{
|
||||
foreach (long id in this.newUpdateIds)
|
||||
{
|
||||
this.updateIds.Add(id);
|
||||
}
|
||||
this.updateIds.Sort();
|
||||
this.newUpdateIds.Clear();
|
||||
}
|
||||
|
||||
foreach (long id in this.updateIds)
|
||||
{
|
||||
LSEntity entity = lsEntities[id];
|
||||
if (entity == null)
|
||||
{
|
||||
this.lsEntities.Remove(id);
|
||||
continue;
|
||||
}
|
||||
this.newUpdateIds.Add(id);
|
||||
LSEntitySystemSingleton.Instance.LSUpdate(entity);
|
||||
}
|
||||
this.updateIds.Clear();
|
||||
ObjectHelper.Swap(ref this.updateIds, ref this.newUpdateIds);
|
||||
}
|
||||
|
||||
public void Add(LSEntity entity)
|
||||
{
|
||||
this.newUpdateIds.Add(entity.Id);
|
||||
this.lsEntities.Add(entity.Id, entity);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 654b3240c49c34319877c2dc7da81a5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
75
Assets/GameScripts/DotNet/Model/Share/LockStep/LSWorld.cs
Normal file
75
Assets/GameScripts/DotNet/Model/Share/LockStep/LSWorld.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TrueSync;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public static class LSWorldSystem
|
||||
{
|
||||
public static LSWorld LSWorld(this LSEntity entity)
|
||||
{
|
||||
return entity.IScene as LSWorld;
|
||||
}
|
||||
|
||||
public static long GetId(this LSEntity entity)
|
||||
{
|
||||
return entity.LSWorld().GetId();
|
||||
}
|
||||
|
||||
public static TSRandom GetRandom(this LSEntity entity)
|
||||
{
|
||||
return entity.LSWorld().Random;
|
||||
}
|
||||
}
|
||||
|
||||
[EnableMethod]
|
||||
[ChildOf]
|
||||
[ComponentOf]
|
||||
public class LSWorld: LSEntity, IAwake, IScene, IRegisterLSEntitySystem
|
||||
{
|
||||
public LSWorld()
|
||||
{
|
||||
}
|
||||
|
||||
public LSWorld(SceneType sceneType)
|
||||
{
|
||||
this.Id = this.GetId();
|
||||
|
||||
this.SceneType = sceneType;
|
||||
|
||||
Log.Info($"LSScene create: {this.Id} {this.InstanceId}");
|
||||
}
|
||||
|
||||
private readonly LSUpdater updater = new();
|
||||
|
||||
[BsonIgnore]
|
||||
public Fiber Fiber { get; set; }
|
||||
|
||||
[BsonElement]
|
||||
private long idGenerator;
|
||||
|
||||
public long GetId()
|
||||
{
|
||||
return ++this.idGenerator;
|
||||
}
|
||||
|
||||
public TSRandom Random { get; set; }
|
||||
|
||||
[BsonIgnore]
|
||||
public SceneType SceneType { get; set; }
|
||||
|
||||
public int Frame { get; set; }
|
||||
|
||||
public void Update()
|
||||
{
|
||||
this.updater.Update();
|
||||
++this.Frame;
|
||||
}
|
||||
|
||||
public void RegisterSystem(LSEntity entity)
|
||||
{
|
||||
this.updater.Add(entity);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55f4993cd749b4da984b60fc8d0720a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public partial class OneFrameInputs
|
||||
{
|
||||
protected bool Equals(OneFrameInputs other)
|
||||
{
|
||||
return Equals(this.Inputs, other.Inputs);
|
||||
}
|
||||
|
||||
public void CopyTo(OneFrameInputs to)
|
||||
{
|
||||
to.Inputs.Clear();
|
||||
foreach (var kv in this.Inputs)
|
||||
{
|
||||
to.Inputs.Add(kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != this.GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((OneFrameInputs) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(this.Inputs);
|
||||
}
|
||||
|
||||
public OneFrameInputs()
|
||||
{
|
||||
this.Inputs = new Dictionary<long, LSInput>(LSConstValue.MatchCount);
|
||||
}
|
||||
|
||||
public static bool operator==(OneFrameInputs a, OneFrameInputs b)
|
||||
{
|
||||
if (a is null || b is null)
|
||||
{
|
||||
if (a is null && b is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.Inputs.Count != b.Inputs.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var kv in a.Inputs)
|
||||
{
|
||||
if (!b.Inputs.TryGetValue(kv.Key, out LSInput inputInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kv.Value != inputInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator !=(OneFrameInputs a, OneFrameInputs b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Room2C_Start
|
||||
{
|
||||
public Room2C_Start()
|
||||
{
|
||||
this.UnitInfo = new List<LockStepUnitInfo>(LSConstValue.MatchCount);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc7d50658d3c844c8b32167be54851c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/GameScripts/DotNet/Model/Share/LockStep/Replay.cs
Normal file
18
Assets/GameScripts/DotNet/Model/Share/LockStep/Replay.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using MemoryPack;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[MemoryPackable]
|
||||
public partial class Replay
|
||||
{
|
||||
[MemoryPackOrder(1)]
|
||||
public List<LockStepUnitInfo> UnitInfos;
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public List<OneFrameInputs> FrameInputs = new();
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public List<byte[]> Snapshots = new();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83a7335c9271d4f848460aedf23c1b70
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
Assets/GameScripts/DotNet/Model/Share/LockStep/Room.cs
Normal file
53
Assets/GameScripts/DotNet/Model/Share/LockStep/Room.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[ChildOf]
|
||||
[ComponentOf]
|
||||
public class Room: Entity, IScene, IAwake, IUpdate
|
||||
{
|
||||
public Fiber Fiber { get; set; }
|
||||
public SceneType SceneType { get; set; } = SceneType.Room;
|
||||
public string Name { get; set; }
|
||||
|
||||
public long StartTime { get; set; }
|
||||
|
||||
// 帧缓存
|
||||
public FrameBuffer FrameBuffer { get; set; }
|
||||
|
||||
// 计算fixedTime,fixedTime在客户端是动态调整的,会做时间膨胀缩放
|
||||
public FixedTimeCounter FixedTimeCounter { get; set; }
|
||||
|
||||
// 玩家id列表
|
||||
public List<long> PlayerIds { get; } = new(LSConstValue.MatchCount);
|
||||
|
||||
// 预测帧
|
||||
public int PredictionFrame { get; set; } = -1;
|
||||
|
||||
// 权威帧
|
||||
public int AuthorityFrame { get; set; } = -1;
|
||||
|
||||
// 存档
|
||||
public Replay Replay { get; set; } = new();
|
||||
|
||||
private EntityRef<LSWorld> lsWorld;
|
||||
|
||||
// LSWorld做成child,可以有多个lsWorld,比如守望先锋有两个
|
||||
public LSWorld LSWorld
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.lsWorld;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.AddChild(value);
|
||||
this.lsWorld = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReplay { get; set; }
|
||||
|
||||
public int SpeedMultiply { get; set; }
|
||||
}
|
||||
}
|
11
Assets/GameScripts/DotNet/Model/Share/LockStep/Room.cs.meta
Normal file
11
Assets/GameScripts/DotNet/Model/Share/LockStep/Room.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51fde8d44ce33433b9523076002f8831
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user