feat: initial commit - HJHA game server full source

6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) +
game logic (GameFix/GameDAL/ServerData) +
network layer (NetWorkMessage) +
data layer (ObjectModel) +
utilities (MrWu/Core/Config/CloudAPI/dll) +
adapters (zyxAdapter/base)

.NET 8.0 C# solution, 16 projects, 958 source files
This commit is contained in:
2026-07-07 12:02:15 +08:00
commit e9616125ce
958 changed files with 158203 additions and 0 deletions

View File

@ -0,0 +1,9 @@
using System;
namespace Server.Core
{
public interface IScheduler : IDisposable
{
void Add(int actorTypeId);
}
}

View File

@ -0,0 +1,124 @@
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using ActorCore;
using Server.Core.Extend;
namespace Server.Core
{
/// <summary>
/// 主线程调度器
/// </summary>
public class MainThreadScheduler : IScheduler
{
private readonly ConcurrentQueue<int> idQueue = new ConcurrentQueue<int>();
/// <summary>
/// 等待加入的
/// </summary>
private readonly ConcurrentQueue<int> addIds = new ConcurrentQueue<int>();
private readonly ActorManager _actorManager;
private readonly ThreadSynchronizationContext
_threadSynchronizationContext = new ThreadSynchronizationContext();
private bool IsDisposed;
public MainThreadScheduler(ActorManager actorManager)
{
SynchronizationContext.SetSynchronizationContext(_threadSynchronizationContext);
this._actorManager = actorManager;
}
public void Update()
{
if (IsDisposed)
{
return;
}
SynchronizationContext.SetSynchronizationContext(_threadSynchronizationContext);
this._threadSynchronizationContext.Update();
int count = this.idQueue.Count;
while (count -- > 0)
{
if (!this.idQueue.TryDequeue(out int id))
{
continue;
}
IActor actor = this._actorManager.Get(id);
if (actor == null)
{
continue;
}
if (actor.IsDisposed)
{
continue;
}
ActorManager.Current = actor;
SynchronizationContext.SetSynchronizationContext(actor.ThreadSynchronizationContext);
actor.IUpdate();
ActorManager.Current = null;
this.idQueue.Enqueue(id);
}
}
public void LateUpdate()
{
if (IsDisposed)
{
return;
}
int count = this.idQueue.Count;
while (count -- > 0)
{
if (!this.idQueue.TryDequeue(out int id))
{
continue;
}
IActor actor = this._actorManager.Get(id);
if (actor == null)
{
continue;
}
if (actor.IsDisposed)
{
continue;
}
ActorManager.Current = actor;
SynchronizationContext.SetSynchronizationContext(actor.ThreadSynchronizationContext);
actor.ILateUpdate();
actor.ThreadSynchronizationContext.Update();
ActorManager.Current = null;
this.idQueue.Enqueue(id);
}
while (this.addIds.Count > 0)
{
this.addIds.TryDequeue(out int result);
this.idQueue.Enqueue(result);
}
}
public void Add(int actorTypeId)
{
this.addIds.Enqueue(actorTypeId);
}
public void Dispose()
{
IsDisposed = true;
//.Net 才有这个方法
this.idQueue.Clear();
this.addIds.Clear();
}
}
}

View File

@ -0,0 +1,98 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using ActorCore;
using MrWu.Debug;
namespace Server.Core
{
public class ThreadPoolScheduler : IScheduler
{
private readonly List<Thread> _threads;
private readonly ConcurrentQueue<int> idQueue = new ConcurrentQueue<int>();
private readonly ActorManager _actorManager;
public ThreadPoolScheduler(ActorManager actorManager)
{
_actorManager = actorManager;
int threadCount = Environment.ProcessorCount;
if (threadCount > 2)
{
threadCount = 2;
}
this._threads = new List<Thread>(threadCount);
for (int i = 0; i < threadCount; i++)
{
Thread thread = new Thread(this.Loop);
this._threads.Add(thread);
thread.Start();
}
}
private void Loop()
{
int count = 0;
uint threadId = ThreadHelper.GetOSThreadId();
Debug.Info($"ThreadStart ThreadPoolScheduler {threadId}");
while (true)
{
if (count <= 0)
{
Thread.Sleep(1);
count = this._actorManager.Count() / this._threads.Count + 1;
}
--count;
if (this._actorManager.IsDisposed())
{
return;
}
if (!this.idQueue.TryDequeue(out int id))
{
Thread.Sleep(1);
continue;
}
IActor actor = this._actorManager.Get(id);
if (actor == null)
{
continue;
}
if (actor.IsDisposed)
{
continue;
}
ActorManager.Current = actor;
SynchronizationContext.SetSynchronizationContext(actor.ThreadSynchronizationContext);
actor.IUpdate();
actor.ILateUpdate();
actor.ThreadSynchronizationContext.Update();
SynchronizationContext.SetSynchronizationContext(null);
ActorManager.Current = null;
this.idQueue.Enqueue(id);
}
}
public void Add(int actorTypeId)
{
this.idQueue.Enqueue(actorTypeId);
}
public void Dispose()
{
foreach (Thread thread in this._threads)
{
thread.Join();
}
}
}
}

View File

@ -0,0 +1,73 @@
using System.Collections.Concurrent;
using System.Threading;
using ActorCore;
using MrWu.Debug;
namespace Server.Core
{
public class ThreadScheduler : IScheduler
{
private readonly ConcurrentDictionary<int, Thread> _dictionary = new ConcurrentDictionary<int, Thread>();
private readonly ActorManager _actorManager;
public ThreadScheduler(ActorManager actorManager)
{
this._actorManager = actorManager;
}
private void Loop(int actorTypeId)
{
#if DEBUG
uint threadId = ThreadHelper.GetOSThreadId();
Debug.Info($"ThreadStart ThreadScheduler {threadId} {Thread.CurrentThread.ManagedThreadId} {actorTypeId}");
#endif
IActor actor = _actorManager.Get(actorTypeId);
ActorManager.Current = null;
SynchronizationContext.SetSynchronizationContext(actor.ThreadSynchronizationContext);
while (true)
{
if (this._actorManager.IsDisposed())
{
return;
}
actor = _actorManager.Get(actorTypeId);
if (actor == null)
{
this._dictionary.TryRemove(actorTypeId, out _);
return;
}
if (actor.IsDisposed)
{
this._dictionary.TryRemove(actorTypeId, out _);
return;
}
actor.IUpdate();
actor.ILateUpdate();
actor.ThreadSynchronizationContext.Update();
Thread.Sleep(1);
}
}
public void Add(int actorTypeId)
{
Thread thread = new Thread(() => this.Loop(actorTypeId));
this._dictionary.TryAdd(actorTypeId, thread);
thread.Start();
}
public void Dispose()
{
foreach (var kv in this._dictionary.ToArray())
{
kv.Value.Join();
}
}
}
}