服务端跟随新用户槽位 更改管理 ,以及对象池
This commit is contained in:
parent
ff3c511895
commit
5caff2dbda
401
AxibugEmuOnline.Server/Common/ObjectPoolAuto.cs
Normal file
401
AxibugEmuOnline.Server/Common/ObjectPoolAuto.cs
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AxibugEmuOnline.Server
|
||||||
|
{
|
||||||
|
public static class ObjectPoolAuto
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或者创建一个新的
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
|
||||||
|
public static T Acquire<T>()
|
||||||
|
where T : class, new()
|
||||||
|
=> ObjectPool<T>.Acquire();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或者创建一个新的
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
|
||||||
|
public static void Acquire<T>(out T item)
|
||||||
|
where T : class, new()
|
||||||
|
=> item = ObjectPool<T>.Acquire();
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(T item)
|
||||||
|
where T : class, new()
|
||||||
|
=> ObjectPool<T>.Release(item);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(ref T item) where T : class, new()
|
||||||
|
{
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
ObjectPool<T>.Release(item);
|
||||||
|
item = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
public const string
|
||||||
|
NotClearError = " They must be cleared before being released to the pool and not modified after that.";
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或创建List
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(List{T})"/> 回收参见此方法</remarks>
|
||||||
|
public static List<T> AcquireList<T>()
|
||||||
|
{
|
||||||
|
var list = ObjectPool<List<T>>.Acquire();
|
||||||
|
AppSrv.g_Log.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收List
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(List<T> list)
|
||||||
|
{
|
||||||
|
list.Clear();
|
||||||
|
ObjectPool<List<T>>.Release(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或创建Queue
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(Queue{T})"/> 回收参见此方法</remarks>
|
||||||
|
public static Queue<T> AcquireQueue<T>()
|
||||||
|
{
|
||||||
|
var queue = ObjectPool<Queue<T>>.Acquire();
|
||||||
|
AppSrv.g_Log.Assert(queue.Count == 0, "A pooled list is not empty." + NotClearError);
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收Queue
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(Queue<T> list)
|
||||||
|
{
|
||||||
|
list.Clear();
|
||||||
|
ObjectPool<Queue<T>>.Release(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或创建HashSet
|
||||||
|
/// </summary>
|
||||||
|
public static HashSet<T> AcquireSet<T>()
|
||||||
|
{
|
||||||
|
var set = ObjectPool<HashSet<T>>.Acquire();
|
||||||
|
AppSrv.g_Log.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放HashSet
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(HashSet<T> set)
|
||||||
|
{
|
||||||
|
set.Clear();
|
||||||
|
ObjectPool<HashSet<T>>.Release(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个字符串StringBuilder
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release(StringBuilder)"/>回收参见这个</remarks>
|
||||||
|
public static StringBuilder AcquireStringBuilder()
|
||||||
|
{
|
||||||
|
var builder = ObjectPool<StringBuilder>.Acquire();
|
||||||
|
AppSrv.g_Log.Assert(builder.Length == 0, $"A pooled {nameof(StringBuilder)} is not empty." + NotClearError);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收 StringBuilder
|
||||||
|
/// </summary>
|
||||||
|
public static void Release(StringBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Length = 0;
|
||||||
|
ObjectPool<StringBuilder>.Release(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收 StringBuilder
|
||||||
|
/// </summary>
|
||||||
|
public static string ReleaseToString(this StringBuilder builder)
|
||||||
|
{
|
||||||
|
var result = builder.ToString();
|
||||||
|
Release(builder);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private static class Cache<T>
|
||||||
|
{
|
||||||
|
public static readonly Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>
|
||||||
|
Results = new Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 此方法主要用于频繁绘制缓存,比如说GUI绘制
|
||||||
|
/// </summary>
|
||||||
|
public static T GetCachedResult<T>(Func<T> function)
|
||||||
|
{
|
||||||
|
var method = function.Method;
|
||||||
|
if (!Cache<T>.Results.TryGetValue(method, out var result))
|
||||||
|
{
|
||||||
|
|
||||||
|
result = new KeyValuePair<Func<T>, T>(function, function());
|
||||||
|
Cache<T>.Results.Add(method, result);
|
||||||
|
}
|
||||||
|
else if (result.Key != function)
|
||||||
|
{
|
||||||
|
AppSrv.g_Log.Warning(
|
||||||
|
$"{nameof(GetCachedResult)}<{typeof(T).Name}>" +
|
||||||
|
$" was previously called on {method.Name} with a different target." +
|
||||||
|
" This likely means that a new delegate is being passed into every call" +
|
||||||
|
" so it can't actually return the same cached object.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
public static class Disposable
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable Acquire<T>(out T item)
|
||||||
|
where T : class, new()
|
||||||
|
=> ObjectPool<T>.Disposable.Acquire(out item);
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable AcquireList<T>(out List<T> list)
|
||||||
|
{
|
||||||
|
var disposable = ObjectPool<List<T>>.Disposable.Acquire(out list, onRelease: (l) => l.Clear());
|
||||||
|
AppSrv.g_Log.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="HashSet{T}"/> if
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable AcquireSet<T>(out HashSet<T> set)
|
||||||
|
{
|
||||||
|
var disposable = ObjectPool<HashSet<T>>.Disposable.Acquire(out set, onRelease: (s) => s.Clear());
|
||||||
|
AppSrv.g_Log.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
}
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ObjectPool<T> where T : class, new()
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private static readonly List<T>
|
||||||
|
Items = new List<T>();
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>The number of spare items currently in the pool.</summary>
|
||||||
|
public static int Count
|
||||||
|
{
|
||||||
|
get => Items.Count;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
var count = Items.Count;
|
||||||
|
if (count < value)
|
||||||
|
{
|
||||||
|
if (Items.Capacity < value)
|
||||||
|
Items.Capacity = NextPowerOfTwo(value);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Items.Add(new T());
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
while (count < value);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (count > value)
|
||||||
|
{
|
||||||
|
Items.RemoveRange(value, count - value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int NextPowerOfTwo(int value)
|
||||||
|
{
|
||||||
|
if (value <= 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Value must be greater than zero.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int powerOfTwo = 1;
|
||||||
|
while (powerOfTwo < value)
|
||||||
|
{
|
||||||
|
powerOfTwo <<= 1; // equivalent to multiplying by 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return powerOfTwo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the <see cref="Count"/> is less than the specified value, this method increases it to that value by
|
||||||
|
/// creating new objects.
|
||||||
|
/// </summary>
|
||||||
|
public static void SetMinCount(int count)
|
||||||
|
{
|
||||||
|
if (Count < count)
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>The <see cref="List{T}.Capacity"/> of the internal list of spare items.</summary>
|
||||||
|
public static int Capacity
|
||||||
|
{
|
||||||
|
get => Items.Capacity;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Items.Count > value)
|
||||||
|
Items.RemoveRange(value, Items.Count - value);
|
||||||
|
Items.Capacity = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>Returns a spare item if there are any, or creates a new one.</summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release(T)"/> it when you are done.</remarks>
|
||||||
|
public static T Acquire()
|
||||||
|
{
|
||||||
|
var count = Items.Count;
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count--;
|
||||||
|
var item = Items[count];
|
||||||
|
Items.RemoveAt(count);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>Adds the `item` to the list of spares so it can be reused.</summary>
|
||||||
|
public static void Release(T item)
|
||||||
|
{
|
||||||
|
Items.Add(item);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>Returns a description of the state of this pool.</summary>
|
||||||
|
public static string GetDetails()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
$"{typeof(T).Name}" +
|
||||||
|
$" ({nameof(Count)} = {Items.Count}" +
|
||||||
|
$", {nameof(Capacity)} = {Items.Capacity}" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="IDisposable"/> system to allow pooled objects to be acquired and released within <c>using</c>
|
||||||
|
/// statements instead of needing to manually release everything.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class Disposable : IDisposable
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private static readonly List<Disposable> LazyStack = new List<Disposable>();
|
||||||
|
|
||||||
|
private static int _ActiveDisposables;
|
||||||
|
|
||||||
|
private T _Item;
|
||||||
|
private Action<T> _OnRelease;
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private Disposable() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Acquire"/> to set the `item` and returns an <see cref="IDisposable"/>
|
||||||
|
/// that will call <see cref="Release(T)"/> on the `item` when disposed.
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable Acquire(out T item, Action<T> onRelease = null)
|
||||||
|
{
|
||||||
|
Disposable disposable;
|
||||||
|
|
||||||
|
if (LazyStack.Count <= _ActiveDisposables)
|
||||||
|
{
|
||||||
|
LazyStack.Add(disposable = new Disposable());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disposable = LazyStack[_ActiveDisposables];
|
||||||
|
}
|
||||||
|
|
||||||
|
_ActiveDisposables++;
|
||||||
|
|
||||||
|
disposable._Item = item = ObjectPool<T>.Acquire();
|
||||||
|
disposable._OnRelease = onRelease;
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
_OnRelease?.Invoke(_Item);
|
||||||
|
Release(_Item);
|
||||||
|
_ActiveDisposables--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +50,10 @@ namespace AxibugEmuOnline.Server.Event
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eventDic.Add(evt, new List<Delegate>() { callback });
|
//eventDic.Add(evt, new List<Delegate>() { callback });
|
||||||
|
List<Delegate> delList = ObjectPoolAuto.AcquireList<Delegate>();
|
||||||
|
delList.Add(callback);
|
||||||
|
eventDic.Add(evt, delList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -92,7 +95,12 @@ namespace AxibugEmuOnline.Server.Event
|
|||||||
if (eventDic.ContainsKey(evt))
|
if (eventDic.ContainsKey(evt))
|
||||||
{
|
{
|
||||||
eventDic[evt].Remove(callback);
|
eventDic[evt].Remove(callback);
|
||||||
if (eventDic[evt].Count == 0) eventDic.Remove(evt);
|
if (eventDic[evt].Count == 0)
|
||||||
|
{
|
||||||
|
//eventDic.Remove(evt);
|
||||||
|
ObjectPoolAuto.Release(eventDic[evt]);
|
||||||
|
eventDic.Remove(evt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -20,12 +20,12 @@ namespace AxibugEmuOnline.Server
|
|||||||
|
|
||||||
public static void InitServer(int port)
|
public static void InitServer(int port)
|
||||||
{
|
{
|
||||||
|
g_Log = new LogManager();
|
||||||
Config.LoadConfig();
|
Config.LoadConfig();
|
||||||
Haoyue_SQLPoolManager.InitConnMgr();
|
Haoyue_SQLPoolManager.InitConnMgr();
|
||||||
g_Tick = new TickManager();
|
g_Tick = new TickManager();
|
||||||
g_ClientMgr = new ClientManager();
|
g_ClientMgr = new ClientManager();
|
||||||
g_ClientMgr.Init(45000, 120);
|
g_ClientMgr.Init(45000, 120);
|
||||||
g_Log = new LogManager();
|
|
||||||
g_Login = new LoginManager();
|
g_Login = new LoginManager();
|
||||||
g_Chat = new ChatManager();
|
g_Chat = new ChatManager();
|
||||||
g_UserMgr = new UserManager();
|
g_UserMgr = new UserManager();
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
using AxibugEmuOnline.Server.Common;
|
using AxibugEmuOnline.Server.Common;
|
||||||
using AxibugEmuOnline.Server.Event;
|
|
||||||
using AxibugEmuOnline.Server.NetWork;
|
using AxibugEmuOnline.Server.NetWork;
|
||||||
using AxibugProtobuf;
|
using AxibugProtobuf;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using static AxibugEmuOnline.Server.RoomManager;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Server.Manager
|
namespace AxibugEmuOnline.Server.Manager
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace AxibugEmuOnline.Server.Manager
|
using AxibugProtobuf;
|
||||||
|
using static Mysqlx.Expect.Open.Types;
|
||||||
|
|
||||||
|
namespace AxibugEmuOnline.Server.Manager
|
||||||
{
|
{
|
||||||
public class LogManager
|
public class LogManager
|
||||||
{
|
{
|
||||||
@ -19,6 +22,14 @@
|
|||||||
//Console.WriteLine(str);
|
//Console.WriteLine(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Assert(bool conditional, string message)
|
||||||
|
{
|
||||||
|
if (!conditional)
|
||||||
|
{
|
||||||
|
Debug(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Warning(string str)
|
public void Warning(string str)
|
||||||
{
|
{
|
||||||
Console.WriteLine(str);
|
Console.WriteLine(str);
|
||||||
|
@ -4,6 +4,7 @@ using AxibugEmuOnline.Server.NetWork;
|
|||||||
using AxibugProtobuf;
|
using AxibugProtobuf;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@ -70,6 +71,8 @@ namespace AxibugEmuOnline.Server
|
|||||||
{
|
{
|
||||||
if (mDictRoom.ContainsKey(RoomID))
|
if (mDictRoom.ContainsKey(RoomID))
|
||||||
{
|
{
|
||||||
|
mDictRoom[RoomID].Dispose();
|
||||||
|
|
||||||
mDictRoom.Remove(RoomID);
|
mDictRoom.Remove(RoomID);
|
||||||
mKeyRoomList.Remove(RoomID);
|
mKeyRoomList.Remove(RoomID);
|
||||||
}
|
}
|
||||||
@ -83,16 +86,14 @@ namespace AxibugEmuOnline.Server
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Data_RoomData> GetRoomList()
|
public void GetRoomList(ref List<Data_RoomData> roomList)
|
||||||
{
|
{
|
||||||
lock (mDictRoom)
|
lock (mDictRoom)
|
||||||
{
|
{
|
||||||
List<Data_RoomData> temp = new List<Data_RoomData>();
|
|
||||||
foreach (var room in mDictRoom)
|
foreach (var room in mDictRoom)
|
||||||
{
|
{
|
||||||
temp.AddRange(mDictRoom.Values);
|
roomList.AddRange(mDictRoom.Values);
|
||||||
}
|
}
|
||||||
return temp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,9 +178,11 @@ namespace AxibugEmuOnline.Server
|
|||||||
Protobuf_Room_List msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_List>(reqData);
|
Protobuf_Room_List msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_List>(reqData);
|
||||||
|
|
||||||
Protobuf_Room_List_RESP resp = new Protobuf_Room_List_RESP();
|
Protobuf_Room_List_RESP resp = new Protobuf_Room_List_RESP();
|
||||||
List<Data_RoomData> temp = GetRoomList();
|
List<Data_RoomData> temp = ObjectPoolAuto.AcquireList<Data_RoomData>();
|
||||||
|
GetRoomList(ref temp);
|
||||||
foreach (var room in temp)
|
foreach (var room in temp)
|
||||||
resp.RoomMiniInfoList.Add(GetProtoDataRoom(room));
|
resp.RoomMiniInfoList.Add(GetProtoDataRoom(room));
|
||||||
|
ObjectPoolAuto.Release(temp);
|
||||||
AppSrv.g_ClientMgr.ClientSend(_c, (int)CommandID.CmdRoomList, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp));
|
AppSrv.g_ClientMgr.ClientSend(_c, (int)CommandID.CmdRoomList, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp));
|
||||||
}
|
}
|
||||||
public void CmdRoomGetScreen(Socket sk, byte[] reqData)
|
public void CmdRoomGetScreen(Socket sk, byte[] reqData)
|
||||||
@ -513,12 +516,15 @@ namespace AxibugEmuOnline.Server
|
|||||||
RoomMiniInfo = GetProtoDataRoom(room)
|
RoomMiniInfo = GetProtoDataRoom(room)
|
||||||
};
|
};
|
||||||
|
|
||||||
List<ClientInfo> userlist = room.GetAllPlayerClientList();
|
List<ClientInfo> userlist = ObjectPoolAuto.AcquireList<ClientInfo>();
|
||||||
|
room.GetAllPlayerClientList(ref userlist);
|
||||||
|
|
||||||
foreach (ClientInfo _c in userlist)
|
foreach (ClientInfo _c in userlist)
|
||||||
{
|
{
|
||||||
AppSrv.g_ClientMgr.ClientSend(_c, (int)CommandID.CmdRoomMyRoomStateChanged, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp));
|
AppSrv.g_ClientMgr.ClientSend(_c, (int)CommandID.CmdRoomMyRoomStateChanged, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectPoolAuto.Release(userlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -527,7 +533,10 @@ namespace AxibugEmuOnline.Server
|
|||||||
/// <param name="room"></param>
|
/// <param name="room"></param>
|
||||||
public void SendRoomStepChange(Data_RoomData room)
|
public void SendRoomStepChange(Data_RoomData room)
|
||||||
{
|
{
|
||||||
List<ClientInfo> roomClient = room.GetAllPlayerClientList();
|
|
||||||
|
List<ClientInfo> roomClient = ObjectPoolAuto.AcquireList<ClientInfo>();
|
||||||
|
room.GetAllPlayerClientList(ref roomClient);
|
||||||
|
|
||||||
switch (room.GameState)
|
switch (room.GameState)
|
||||||
{
|
{
|
||||||
case RoomGameState.WaitRawUpdate:
|
case RoomGameState.WaitRawUpdate:
|
||||||
@ -562,6 +571,8 @@ namespace AxibugEmuOnline.Server
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectPoolAuto.Release(roomClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 房间帧循环
|
#region 房间帧循环
|
||||||
@ -591,7 +602,7 @@ namespace AxibugEmuOnline.Server
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Data_RoomData
|
public class Data_RoomData : IDisposable
|
||||||
{
|
{
|
||||||
public int RoomID { get; private set; }
|
public int RoomID { get; private set; }
|
||||||
public int GameRomID { get; private set; }
|
public int GameRomID { get; private set; }
|
||||||
@ -612,9 +623,13 @@ namespace AxibugEmuOnline.Server
|
|||||||
public uint mCurrServerFrameId = 0;
|
public uint mCurrServerFrameId = 0;
|
||||||
public ServerInputSnapShot mCurrInputData;
|
public ServerInputSnapShot mCurrInputData;
|
||||||
public Queue<(uint, ServerInputSnapShot)> mInputQueue;
|
public Queue<(uint, ServerInputSnapShot)> mInputQueue;
|
||||||
|
|
||||||
|
public List<double> send2time;
|
||||||
|
const int SynLimitOnSec = 63;
|
||||||
|
|
||||||
object synInputLock = new object();
|
object synInputLock = new object();
|
||||||
//TODO
|
//TODO
|
||||||
public Dictionary<int, Queue<byte[]>> mDictPlayerIdx2SendQueue;
|
//public Dictionary<int, Queue<byte[]>> mDictPlayerIdx2SendQueue;
|
||||||
public RoomGameState GameState
|
public RoomGameState GameState
|
||||||
{
|
{
|
||||||
get { return mGameState; }
|
get { return mGameState; }
|
||||||
@ -641,6 +656,7 @@ namespace AxibugEmuOnline.Server
|
|||||||
public uint SrvForwardFrames { get; set; }
|
public uint SrvForwardFrames { get; set; }
|
||||||
public void Init(int roomID, int gameRomID, string roomHash, long hostUId, bool bloadState = false)
|
public void Init(int roomID, int gameRomID, string roomHash, long hostUId, bool bloadState = false)
|
||||||
{
|
{
|
||||||
|
Dispose();
|
||||||
RoomID = roomID;
|
RoomID = roomID;
|
||||||
GameRomID = gameRomID;
|
GameRomID = gameRomID;
|
||||||
RomHash = roomHash;
|
RomHash = roomHash;
|
||||||
@ -658,12 +674,39 @@ namespace AxibugEmuOnline.Server
|
|||||||
PlayerSlot[i].Init(i);
|
PlayerSlot[i].Init(i);
|
||||||
|
|
||||||
//PlayerReadyState = new bool[4];
|
//PlayerReadyState = new bool[4];
|
||||||
SynUIDs = new List<long>();//广播角色列表
|
SynUIDs = ObjectPoolAuto.AcquireList<long>();//new List<long>();//广播角色列表
|
||||||
GameState = RoomGameState.NoneGameState;
|
GameState = RoomGameState.NoneGameState;
|
||||||
mCurrInputData = new ServerInputSnapShot();
|
mCurrInputData = new ServerInputSnapShot();
|
||||||
mInputQueue = new Queue<(uint, ServerInputSnapShot)>();
|
mInputQueue = ObjectPoolAuto.AcquireQueue<(uint, ServerInputSnapShot)>();
|
||||||
mDictPlayerIdx2SendQueue = new Dictionary<int, Queue<byte[]>>();
|
// new Queue<(uint, ServerInputSnapShot)>();
|
||||||
|
//mDictPlayerIdx2SendQueue = new Dictionary<int, Queue<byte[]>>();
|
||||||
|
send2time = ObjectPoolAuto.AcquireList<double>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 房间释放时,需要调用
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (SynUIDs != null)
|
||||||
|
{
|
||||||
|
ObjectPoolAuto.Release(SynUIDs);
|
||||||
|
SynUIDs = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mInputQueue != null)
|
||||||
|
{
|
||||||
|
ObjectPoolAuto.Release(mInputQueue);
|
||||||
|
mInputQueue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send2time != null)
|
||||||
|
{
|
||||||
|
ObjectPoolAuto.Release(send2time);
|
||||||
|
send2time = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Dictionary<uint, uint> GetSlotDataByUID(long uid)
|
public Dictionary<uint, uint> GetSlotDataByUID(long uid)
|
||||||
{
|
{
|
||||||
Dictionary<uint, uint> slotIdx2JoyIdx = new Dictionary<uint, uint>();
|
Dictionary<uint, uint> slotIdx2JoyIdx = new Dictionary<uint, uint>();
|
||||||
@ -736,13 +779,13 @@ namespace AxibugEmuOnline.Server
|
|||||||
else if (Player2_UID == uid) bHad = true;
|
else if (Player2_UID == uid) bHad = true;
|
||||||
else if (Player3_UID == uid) bHad = true;
|
else if (Player3_UID == uid) bHad = true;
|
||||||
else if (Player4_UID == uid) bHad = true;
|
else if (Player4_UID == uid) bHad = true;
|
||||||
if (bHad)
|
if (!bHad)
|
||||||
SynUIDs.RemoveAt(i);
|
SynUIDs.RemoveAt(i);
|
||||||
}
|
}
|
||||||
if (!SynUIDs.Contains(Player1_UID)) SynUIDs.Add(Player1_UID);
|
if (Player1_UID > 0 && !SynUIDs.Contains(Player1_UID)) SynUIDs.Add(Player1_UID);
|
||||||
if (!SynUIDs.Contains(Player2_UID)) SynUIDs.Add(Player2_UID);
|
if (Player2_UID > 0 && !SynUIDs.Contains(Player2_UID)) SynUIDs.Add(Player2_UID);
|
||||||
if (!SynUIDs.Contains(Player3_UID)) SynUIDs.Add(Player3_UID);
|
if (Player3_UID > 0 && !SynUIDs.Contains(Player3_UID)) SynUIDs.Add(Player3_UID);
|
||||||
if (!SynUIDs.Contains(Player4_UID)) SynUIDs.Add(Player4_UID);
|
if (Player4_UID > 0 && !SynUIDs.Contains(Player4_UID)) SynUIDs.Add(Player4_UID);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 准备状态管理
|
#region 准备状态管理
|
||||||
@ -790,7 +833,7 @@ namespace AxibugEmuOnline.Server
|
|||||||
public void SetPlayerSlotData(ClientInfo _c, ref readonly Dictionary<uint, uint> newSlotIdx2JoyIdx)
|
public void SetPlayerSlotData(ClientInfo _c, ref readonly Dictionary<uint, uint> newSlotIdx2JoyIdx)
|
||||||
{
|
{
|
||||||
Dictionary<uint, uint> oldSlotIdx2JoyIdx = GetSlotDataByUID(_c.UID);
|
Dictionary<uint, uint> oldSlotIdx2JoyIdx = GetSlotDataByUID(_c.UID);
|
||||||
HashSet<uint> diffSlotIdxs = new HashSet<uint>();
|
HashSet<uint> diffSlotIdxs = ObjectPoolAuto.AcquireSet<uint>();// new HashSet<uint>();
|
||||||
foreach (var old in oldSlotIdx2JoyIdx)
|
foreach (var old in oldSlotIdx2JoyIdx)
|
||||||
{
|
{
|
||||||
uint old_slotIdx = old.Key;
|
uint old_slotIdx = old.Key;
|
||||||
@ -830,6 +873,8 @@ namespace AxibugEmuOnline.Server
|
|||||||
//更新需要同步的UID
|
//更新需要同步的UID
|
||||||
UpdateSynUIDs();
|
UpdateSynUIDs();
|
||||||
_c.RoomState.SetRoomData(this.RoomID);
|
_c.RoomState.SetRoomData(this.RoomID);
|
||||||
|
|
||||||
|
ObjectPoolAuto.Release(diffSlotIdxs);
|
||||||
}
|
}
|
||||||
public void RemovePlayer(ClientInfo _c)
|
public void RemovePlayer(ClientInfo _c)
|
||||||
{
|
{
|
||||||
@ -873,9 +918,8 @@ namespace AxibugEmuOnline.Server
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public List<ClientInfo> GetAllPlayerClientList()
|
public void GetAllPlayerClientList(ref List<ClientInfo> list)
|
||||||
{
|
{
|
||||||
List<ClientInfo> list = new List<ClientInfo>();
|
|
||||||
List<long> Uids = SynUIDs;
|
List<long> Uids = SynUIDs;
|
||||||
foreach (long uid in Uids)
|
foreach (long uid in Uids)
|
||||||
{
|
{
|
||||||
@ -883,7 +927,6 @@ namespace AxibugEmuOnline.Server
|
|||||||
continue;
|
continue;
|
||||||
list.Add(_c);
|
list.Add(_c);
|
||||||
}
|
}
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetInputBySlotIdxJoyIdx(uint SlotIdx, uint LocalJoyIdx, ServerInputSnapShot clieninput)
|
void SetInputBySlotIdxJoyIdx(uint SlotIdx, uint LocalJoyIdx, ServerInputSnapShot clieninput)
|
||||||
@ -902,7 +945,10 @@ namespace AxibugEmuOnline.Server
|
|||||||
}
|
}
|
||||||
public void UpdateRoomForwardNum()
|
public void UpdateRoomForwardNum()
|
||||||
{
|
{
|
||||||
List<ClientInfo> playerlist = GetAllPlayerClientList();
|
|
||||||
|
List<ClientInfo> playerlist = ObjectPoolAuto.AcquireList<ClientInfo>();
|
||||||
|
GetAllPlayerClientList(ref playerlist);
|
||||||
|
|
||||||
double maxNetDelay = 0;
|
double maxNetDelay = 0;
|
||||||
for (int i = 0; i < playerlist.Count; i++)
|
for (int i = 0; i < playerlist.Count; i++)
|
||||||
{
|
{
|
||||||
@ -914,13 +960,15 @@ namespace AxibugEmuOnline.Server
|
|||||||
if (SrvForwardFrames < 2)
|
if (SrvForwardFrames < 2)
|
||||||
SrvForwardFrames = 2;
|
SrvForwardFrames = 2;
|
||||||
//AppSrv.g_Log.Debug($"服务器提前跑帧数:Max(2,({maxNetDelay} / {0.016f}) + {MustTaskFrame}) = {SrvForwardFrames}");
|
//AppSrv.g_Log.Debug($"服务器提前跑帧数:Max(2,({maxNetDelay} / {0.016f}) + {MustTaskFrame}) = {SrvForwardFrames}");
|
||||||
|
|
||||||
|
ObjectPoolAuto.Release(playerlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 帧相关
|
#region 帧相关
|
||||||
void StartNewTick()
|
void StartNewTick()
|
||||||
{
|
{
|
||||||
mInputQueue.Clear();
|
mInputQueue.Clear();
|
||||||
mDictPlayerIdx2SendQueue.Clear();
|
//mDictPlayerIdx2SendQueue.Clear();
|
||||||
|
|
||||||
mCurrServerFrameId = 0;
|
mCurrServerFrameId = 0;
|
||||||
mCurrInputData.all = 1;
|
mCurrInputData.all = 1;
|
||||||
@ -951,8 +999,6 @@ namespace AxibugEmuOnline.Server
|
|||||||
ulong LastTestSend = 0;
|
ulong LastTestSend = 0;
|
||||||
internal ulong LastTestRecv;
|
internal ulong LastTestRecv;
|
||||||
|
|
||||||
public List<double> send2time = new List<double>();
|
|
||||||
const int SynLimitOnSec = 63;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广播数据
|
/// 广播数据
|
||||||
@ -978,7 +1024,8 @@ namespace AxibugEmuOnline.Server
|
|||||||
if (!flagInitList)
|
if (!flagInitList)
|
||||||
{
|
{
|
||||||
flagInitList = true;
|
flagInitList = true;
|
||||||
temp = new List<(uint frameId, ServerInputSnapShot inputdata)>();
|
//temp = new List<(uint frameId, ServerInputSnapShot inputdata)>();
|
||||||
|
temp = ObjectPoolAuto.AcquireList<(uint frameId, ServerInputSnapShot inputdata)>();
|
||||||
}
|
}
|
||||||
temp.Add(mInputQueue.Dequeue());
|
temp.Add(mInputQueue.Dequeue());
|
||||||
send2time.Add(timeNow);
|
send2time.Add(timeNow);
|
||||||
@ -1010,6 +1057,8 @@ namespace AxibugEmuOnline.Server
|
|||||||
// AppSrv.g_Log.Debug($" {DateTime.Now.ToString("hh:mm:ss.fff")} SynInput=> RoomID->{RoomID} ServerFrameID->{mCurrServerFrameId} SynUIDs=>{string.Join(",", SynUIDs)} ");
|
// AppSrv.g_Log.Debug($" {DateTime.Now.ToString("hh:mm:ss.fff")} SynInput=> RoomID->{RoomID} ServerFrameID->{mCurrServerFrameId} SynUIDs=>{string.Join(",", SynUIDs)} ");
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectPoolAuto.Release(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckRoomStateChange(int oldPlayerCount, int newPlayerCount)
|
bool CheckRoomStateChange(int oldPlayerCount, int newPlayerCount)
|
||||||
@ -1174,6 +1223,7 @@ namespace AxibugEmuOnline.Server
|
|||||||
forwaFrame = targetFrame - mCurrServerFrameId;
|
forwaFrame = targetFrame - mCurrServerFrameId;
|
||||||
return forwaFrame > 0;
|
return forwaFrame > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,10 @@ namespace AxibugEmuOnline.Server.NetWork
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
netEventDic.Add(cmd, new List<Delegate>() { callback });
|
//netEventDic.Add(cmd, new List<Delegate>() { callback });
|
||||||
|
List<Delegate> delList = ObjectPoolAuto.AcquireList<Delegate>();
|
||||||
|
delList.Add(callback);
|
||||||
|
netEventDic.Add(cmd, delList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -49,7 +52,12 @@ namespace AxibugEmuOnline.Server.NetWork
|
|||||||
if (netEventDic.ContainsKey(cmd))
|
if (netEventDic.ContainsKey(cmd))
|
||||||
{
|
{
|
||||||
netEventDic[cmd].Remove(callback);
|
netEventDic[cmd].Remove(callback);
|
||||||
if (netEventDic[cmd].Count == 0) netEventDic.Remove(cmd);
|
if (netEventDic[cmd].Count == 0)
|
||||||
|
{
|
||||||
|
//netEventDic.Remove(cmd);
|
||||||
|
ObjectPoolAuto.Release(netEventDic[cmd]);
|
||||||
|
netEventDic.Remove(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -21,7 +21,10 @@ namespace AxibugEmuOnline.Server
|
|||||||
{
|
{
|
||||||
case "rlist":
|
case "rlist":
|
||||||
{
|
{
|
||||||
var roomlist = AppSrv.g_Room.GetRoomList();
|
|
||||||
|
List<Data_RoomData> roomlist = ObjectPoolAuto.AcquireList<Data_RoomData>();
|
||||||
|
AppSrv.g_Room.GetRoomList(ref roomlist);
|
||||||
|
|
||||||
AppSrv.g_Log.Info($"RoomCount:{roomlist.Count}");
|
AppSrv.g_Log.Info($"RoomCount:{roomlist.Count}");
|
||||||
foreach (var room in roomlist)
|
foreach (var room in roomlist)
|
||||||
{
|
{
|
||||||
@ -55,6 +58,7 @@ namespace AxibugEmuOnline.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ObjectPoolAuto.Release(roomlist);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "list":
|
case "list":
|
||||||
|
Loading…
Reference in New Issue
Block a user