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:
144
GameDAL/ExpressionsParser/ValueComparer.cs
Normal file
144
GameDAL/ExpressionsParser/ValueComparer.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ExpressionsParser {
|
||||
|
||||
/// <summary>
|
||||
/// Generic "by value" comparer that uses IComparable and can compare arrays/lists.
|
||||
/// </summary>
|
||||
public class ValueComparer : IComparer, IComparer<object>, IValueComparer {
|
||||
|
||||
internal readonly static ValueComparer _Instance = new ValueComparer();
|
||||
|
||||
public static IValueComparer Instance {
|
||||
get {
|
||||
return _Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets format provider used for Convert.ChangeType (InvariantCulture by default).
|
||||
/// </summary>
|
||||
public IFormatProvider FormatProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines how ValueComparer handles comparison exceptions (by default is false: convert exceptions are thrown).
|
||||
/// </summary>
|
||||
public bool SuppressErrors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines how ValueComparer handles comparison with nulls (default is "MinValue" mode).
|
||||
/// </summary>
|
||||
public NullComparisonMode NullComparison { get; set; }
|
||||
|
||||
public ValueComparer() {
|
||||
FormatProvider = System.Globalization.CultureInfo.InvariantCulture;
|
||||
SuppressErrors = false;
|
||||
}
|
||||
|
||||
private bool IsAssignableFrom(Type a, Type b) {
|
||||
#if NET40
|
||||
return a.IsAssignableFrom(b);
|
||||
#else
|
||||
return a.GetTypeInfo().IsAssignableFrom(b.GetTypeInfo() );
|
||||
#endif
|
||||
}
|
||||
|
||||
int IComparer.Compare(object a, object b) {
|
||||
var res = CompareInternal(a, b);
|
||||
if (!res.HasValue)
|
||||
throw new ArgumentException(string.Format("Cannot compare {0} and {1}", a.GetType(), b.GetType()));
|
||||
return res.Value;
|
||||
}
|
||||
|
||||
int IComparer<object>.Compare(object a, object b) {
|
||||
return ((IComparer)this).Compare(a, b);
|
||||
}
|
||||
|
||||
public int? Compare(object a, object b) {
|
||||
try {
|
||||
if (NullComparison == NullComparisonMode.Sql)
|
||||
if (a == null || b == null)
|
||||
return null;
|
||||
return CompareInternal(a, b);
|
||||
} catch {
|
||||
if (SuppressErrors)
|
||||
return null;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual int? CompareInternal(object a, object b) {
|
||||
if (a == null && b == null)
|
||||
return 0;
|
||||
if (a == null && b != null)
|
||||
return -1;
|
||||
if (a != null && b == null)
|
||||
return 1;
|
||||
|
||||
if ((a is IList) && (b is IList)) {
|
||||
IList aList = (IList)a;
|
||||
IList bList = (IList)b;
|
||||
if (aList.Count < bList.Count)
|
||||
return -1;
|
||||
if (aList.Count > bList.Count)
|
||||
return +1;
|
||||
for (int i = 0; i < aList.Count; i++) {
|
||||
int? r = Compare(aList[i], bList[i]);
|
||||
if (!r.HasValue || r != 0)
|
||||
return r;
|
||||
}
|
||||
// lists are equal
|
||||
return 0;
|
||||
}
|
||||
// test for quick compare if a type is assignable from b
|
||||
if (a is IComparable) {
|
||||
var aComp = (IComparable)a;
|
||||
// quick compare if types are fully compatible
|
||||
if (IsAssignableFrom( a.GetType(), b.GetType() ))
|
||||
return aComp.CompareTo(b);
|
||||
}
|
||||
if (b is IComparable) {
|
||||
var bComp = (IComparable)b;
|
||||
// quick compare if types are fully compatible
|
||||
if (IsAssignableFrom( b.GetType(), a.GetType() ))
|
||||
return -bComp.CompareTo(a);
|
||||
}
|
||||
|
||||
// try to convert b to a and then compare
|
||||
if (a is IComparable) {
|
||||
var aComp = (IComparable)a;
|
||||
var bConverted = Convert.ChangeType(b, a.GetType(), FormatProvider);
|
||||
return aComp.CompareTo(bConverted);
|
||||
}
|
||||
// try to convert a to b and then compare
|
||||
if (b is IComparable) {
|
||||
var bComp = (IComparable)b;
|
||||
var aConverted = Convert.ChangeType(a, b.GetType(), FormatProvider);
|
||||
return -bComp.CompareTo(aConverted);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum NullComparisonMode {
|
||||
|
||||
/// <summary>
|
||||
/// Null compared as "MinValue" (affects less-than and greater-than comparisons).
|
||||
/// </summary>
|
||||
/// <remarks>This is default behaviour expected for <see cref="IComparer"/> and described in MSDN.</remarks>
|
||||
MinValue = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Null cannot be compared to any other value (even if it is null). This is SQL-like nulls handling.
|
||||
/// </summary>
|
||||
Sql = 1,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user