Add project files.
This commit is contained in:
9
Assets/Cryville/Common.meta
Normal file
9
Assets/Cryville/Common.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d213440bfd40d0d49a2950e04f3008ab
|
||||
folderAsset: yes
|
||||
timeCreated: 1594270605
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Cryville/Common/AsyncDelivery.cs
Normal file
14
Assets/Cryville/Common/AsyncDelivery.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public class AsyncDelivery<T> {
|
||||
public Action CancelSource { private get; set; }
|
||||
public Action<bool, T> Destination { private get; set; }
|
||||
public void Deliver(bool succeeded, T result) {
|
||||
if (Destination != null) Destination(succeeded, result);
|
||||
}
|
||||
public void Cancel() {
|
||||
if (CancelSource != null) CancelSource();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/AsyncDelivery.cs.meta
Normal file
12
Assets/Cryville/Common/AsyncDelivery.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 857c1f0e990462a47bd0ed83448f923b
|
||||
timeCreated: 1637755775
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
59
Assets/Cryville/Common/BinderAttribute.cs
Normal file
59
Assets/Cryville/Common/BinderAttribute.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public class BinderAttribute : Attribute {
|
||||
public BinderAttribute(Type type) {
|
||||
BinderType = type;
|
||||
}
|
||||
|
||||
public Type BinderType;
|
||||
|
||||
public static Binder CreateBinderOfType(Type type) {
|
||||
var l = type.GetCustomAttributes(typeof(BinderAttribute), true);
|
||||
if (l.Length > 0) {
|
||||
return (Binder)ReflectionHelper.InvokeEmptyConstructor(
|
||||
((BinderAttribute)l[0]).BinderType
|
||||
);
|
||||
}
|
||||
return new EmptyBinder();
|
||||
}
|
||||
}
|
||||
|
||||
public class EmptyBinder : Binder {
|
||||
/*static readonly Type[] emptyTypeArray = {};
|
||||
static readonly object[] emptyObjectArray = {};*/
|
||||
|
||||
public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override object ChangeType(object value, Type type, CultureInfo culture) {
|
||||
if (value == null)
|
||||
return null;
|
||||
else if (type == value.GetType())
|
||||
return value;
|
||||
else if (type.IsEnum && value is string) {
|
||||
return Enum.Parse(type, (string)value);
|
||||
}
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
|
||||
public override void ReorderArgumentArray(ref object[] args, object state) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/BinderAttribute.cs.meta
Normal file
12
Assets/Cryville/Common/BinderAttribute.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 146a308dba289ad4f91c07c69bb4688b
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Cryville/Common/Buffers.meta
Normal file
8
Assets/Cryville/Common/Buffers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53f4e3167a1eee2478b0abc6302aee8f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
65
Assets/Cryville/Common/Buffers/ArrayPool.cs
Normal file
65
Assets/Cryville/Common/Buffers/ArrayPool.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of arrays of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The item type of the arrays in the pool.</typeparam>
|
||||
public class ArrayPool<T> {
|
||||
private class Bucket : ObjectPool<T[]> {
|
||||
readonly int _size;
|
||||
public Bucket(int size, int capacity) : base(capacity) {
|
||||
_size = size;
|
||||
}
|
||||
protected override T[] Construct() {
|
||||
return new T[_size];
|
||||
}
|
||||
}
|
||||
Bucket[] _buckets;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ArrayPool{T}" /> class with the default maximum list size and bucket capacity.
|
||||
/// </summary>
|
||||
public ArrayPool() : this(0x40000000, 256) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ArrayPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="maxSize">The maximum size of the arrays in the pool.</param>
|
||||
/// <param name="capacityPerBucket">The capacity of each bucket. The pool groups arrays of similar sizes into buckets for faster access.</param>
|
||||
public ArrayPool(int maxSize, int capacityPerBucket) {
|
||||
if (maxSize < 16) maxSize = 16;
|
||||
int num = GetID(maxSize) + 1;
|
||||
_buckets = new Bucket[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
_buckets[i] = new Bucket(GetSize(i), capacityPerBucket);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Rents an array that is at least the specified size from the pool.
|
||||
/// </summary>
|
||||
/// <param name="size">The minimum size of the array.</param>
|
||||
/// <returns>An array of type <see cref="T" /> that is at least the specified size.</returns>
|
||||
public T[] Rent(int size) {
|
||||
int len2 = size;
|
||||
if (len2 < 16) len2 = 16;
|
||||
var arr = _buckets[GetID(len2)].Rent();
|
||||
return arr;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented array to the pool.
|
||||
/// </summary>
|
||||
/// <param name="arr">The array to return.</param>
|
||||
public void Return(T[] arr) {
|
||||
int len2 = arr.Length;
|
||||
if (len2 < 16) len2 = 16;
|
||||
_buckets[GetID(len2)].Return(arr);
|
||||
}
|
||||
static int GetID(int size) {
|
||||
size -= 1;
|
||||
size >>= 4;
|
||||
int num = 0;
|
||||
for (; size != 0; size >>= 1) num++;
|
||||
return num;
|
||||
}
|
||||
static int GetSize(int id) {
|
||||
return 0x10 << id;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/Buffers/ArrayPool.cs.meta
Normal file
11
Assets/Cryville/Common/Buffers/ArrayPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df66519fa93e1b94ea5bb1702cc91b3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
71
Assets/Cryville/Common/Buffers/ListPool.cs
Normal file
71
Assets/Cryville/Common/Buffers/ListPool.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of lists of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The item type of the lists in the pool.</typeparam>
|
||||
public class ListPool<T> {
|
||||
private class Bucket : ObjectPool<List<T>> {
|
||||
readonly int _size;
|
||||
public Bucket(int size, int capacity) : base(capacity) {
|
||||
_size = size;
|
||||
}
|
||||
protected override List<T> Construct() {
|
||||
return new List<T>(_size);
|
||||
}
|
||||
}
|
||||
Bucket[] _buckets;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ListPool{T}" /> class with the default maximum list size and bucket capacity.
|
||||
/// </summary>
|
||||
public ListPool() : this(0x40000000, 256) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ListPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="maxSize">The maximum size of the lists in the pool.</param>
|
||||
/// <param name="capacityPerBucket">The capacity of each bucket. The pool groups lists of similar sizes into buckets for faster access.</param>
|
||||
public ListPool(int maxSize, int capacityPerBucket) {
|
||||
if (maxSize < 16) maxSize = 16;
|
||||
int num = GetID(maxSize) + 1;
|
||||
_buckets = new Bucket[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
_buckets[i] = new Bucket(GetSize(i), capacityPerBucket);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Rents a list of the specified size from the pool. The size of the list must not be changed when it is rented.
|
||||
/// </summary>
|
||||
/// <param name="size">The size of the list.</param>
|
||||
/// <returns>A <see cref="List{T}" /> of the specified size.</returns>
|
||||
public List<T> Rent(int size) {
|
||||
int len2 = size;
|
||||
if (len2 < 16) len2 = 16;
|
||||
var list = _buckets[GetID(len2)].Rent();
|
||||
if (list.Count < size)
|
||||
for (int i = list.Count; i < size; i++) list.Add(default(T));
|
||||
else if (list.Count > size)
|
||||
list.RemoveRange(size, list.Count - size);
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented list to the pool.
|
||||
/// </summary>
|
||||
/// <param name="list">The list to return.</param>
|
||||
public void Return(List<T> list) {
|
||||
int len2 = list.Capacity;
|
||||
if (len2 < 16) len2 = 16;
|
||||
_buckets[GetID(len2)].Return(list);
|
||||
}
|
||||
static int GetID(int size) {
|
||||
size -= 1;
|
||||
size >>= 4;
|
||||
int num = 0;
|
||||
for (; size != 0; size >>= 1) num++;
|
||||
return num;
|
||||
}
|
||||
static int GetSize(int id) {
|
||||
return 0x10 << id;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/Buffers/ListPool.cs.meta
Normal file
11
Assets/Cryville/Common/Buffers/ListPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b7b45ff20c33ac47b476371673b037c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
Assets/Cryville/Common/Buffers/ObjectPool.cs
Normal file
42
Assets/Cryville/Common/Buffers/ObjectPool.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the objects in the pool.</typeparam>
|
||||
public abstract class ObjectPool<T> where T : class {
|
||||
int _index;
|
||||
readonly T[] _objs;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ObjectPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The capacity of the pool.</param>
|
||||
public ObjectPool(int capacity) {
|
||||
_objs = new T[capacity];
|
||||
}
|
||||
/// <summary>
|
||||
/// Rents a object from the pool.
|
||||
/// </summary>
|
||||
/// <returns>The rented object.</returns>
|
||||
public T Rent() {
|
||||
T obj = null;
|
||||
if (_index < _objs.Length) {
|
||||
obj = _objs[_index];
|
||||
_objs[_index++] = null;
|
||||
}
|
||||
if (obj == null) obj = Construct();
|
||||
return obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented object to the pool.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to return.</param>
|
||||
public void Return(T obj) {
|
||||
if (_index > 0) _objs[--_index] = obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructs a new instance of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <returns>The new instance.</returns>
|
||||
protected abstract T Construct();
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/Buffers/ObjectPool.cs.meta
Normal file
11
Assets/Cryville/Common/Buffers/ObjectPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2745c44c3cc32be4ab3a43888c14b9a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/Cryville/Common/Buffers/SimpleObjectPool.cs
Normal file
16
Assets/Cryville/Common/Buffers/SimpleObjectPool.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of type <typeparamref name="T" />, which has a parameterless constructor.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the objects in the pool.</typeparam>
|
||||
public class SimpleObjectPool<T> : ObjectPool<T> where T : class, new() {
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="SimpleObjectPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The capacity of the pool.</param>
|
||||
public SimpleObjectPool(int capacity) : base(capacity) { }
|
||||
protected override T Construct() {
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/Buffers/SimpleObjectPool.cs.meta
Normal file
11
Assets/Cryville/Common/Buffers/SimpleObjectPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8cd439340f088d4eb83711a5bc6384d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/Cryville/Common/Buffers/WStringPool.cs
Normal file
10
Assets/Cryville/Common/Buffers/WStringPool.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Cryville.Common.Buffers {
|
||||
public class WStringPool {
|
||||
public WStringPool() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/Buffers/WStringPool.cs.meta
Normal file
11
Assets/Cryville/Common/Buffers/WStringPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 704270b37917aa1458db9d14bab07073
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Cryville/Common/ComponentModel.meta
Normal file
8
Assets/Cryville/Common/ComponentModel.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c27afc8f4f76d04dac0f0914798ccc0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class LogarithmicScaleAttribute : Attribute {
|
||||
public LogarithmicScaleAttribute() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1e8a5b839ed6a64dbb9fc6b0bcf7cc2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
12
Assets/Cryville/Common/ComponentModel/PrecisionAttribute.cs
Normal file
12
Assets/Cryville/Common/ComponentModel/PrecisionAttribute.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
|
||||
public class PrecisionAttribute : Attribute {
|
||||
public PrecisionAttribute(double precision) {
|
||||
Precision = precision;
|
||||
}
|
||||
|
||||
public double Precision { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea83b8e303a1b8b43a2f2ff74a7a9a7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Cryville/Common/ComponentModel/RangeAttribute.cs
Normal file
14
Assets/Cryville/Common/ComponentModel/RangeAttribute.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class RangeAttribute : Attribute {
|
||||
public RangeAttribute(float min, float max) {
|
||||
Min = min;
|
||||
Max = max;
|
||||
}
|
||||
|
||||
public float Min { get; set; }
|
||||
public float Max { get; set; }
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/ComponentModel/RangeAttribute.cs.meta
Normal file
11
Assets/Cryville/Common/ComponentModel/RangeAttribute.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 569e766a56b73244dbade8de4c525faa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
Assets/Cryville/Common/ComponentModel/StepAttribute.cs
Normal file
11
Assets/Cryville/Common/ComponentModel/StepAttribute.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class StepAttribute : Attribute {
|
||||
public StepAttribute(float step) {
|
||||
Step = step;
|
||||
}
|
||||
public float Step { get; set; }
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/ComponentModel/StepAttribute.cs.meta
Normal file
11
Assets/Cryville/Common/ComponentModel/StepAttribute.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94340a38155591146ada89db63bc4aeb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/Cryville/Common/FileStringAttribute.cs
Normal file
17
Assets/Cryville/Common/FileStringAttribute.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public class FileStringAttribute : Attribute {
|
||||
private readonly string filter;
|
||||
|
||||
public string[] Filter {
|
||||
get {
|
||||
return filter.Split('|');
|
||||
}
|
||||
}
|
||||
|
||||
public FileStringAttribute(string ext) {
|
||||
filter = ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/FileStringAttribute.cs.meta
Normal file
12
Assets/Cryville/Common/FileStringAttribute.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3041eaac507d7548ae3460b33230271
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Cryville/Common/Font.meta
Normal file
8
Assets/Cryville/Common/Font.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ad09f227a3c83141b6d9a0f55b4cb38
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Cryville/Common/Font/FontUtil.cs
Normal file
9
Assets/Cryville/Common/Font/FontUtil.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace Cryville.Common.Font {
|
||||
public static class FontUtil {
|
||||
/*public static string MatchFontNameWithLang(string lang) {
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Common/Font/FontUtil.cs.meta
Normal file
11
Assets/Cryville/Common/Font/FontUtil.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3cd70779125d96409f5a299a8034f5f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/Cryville/Common/IOExtensions.cs
Normal file
27
Assets/Cryville/Common/IOExtensions.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public static class IOExtensions {
|
||||
public static DirectoryInfo GetSubdirectory(this DirectoryInfo dir, string name) {
|
||||
var l1 = dir.GetDirectories(name);
|
||||
if (l1.Length == 0) return dir.CreateSubdirectory(name);
|
||||
else return l1[0];
|
||||
}
|
||||
|
||||
public static string ReadUInt16String(this BinaryReader reader, Encoding encoding = null) {
|
||||
if (encoding == null) encoding = Encoding.UTF8;
|
||||
var len = reader.ReadUInt16();
|
||||
byte[] buffer = reader.ReadBytes(len);
|
||||
return encoding.GetString(buffer);
|
||||
}
|
||||
|
||||
public static void WriteUInt16String(this BinaryWriter writer, string value, Encoding encoding = null) {
|
||||
if (encoding == null) encoding = Encoding.UTF8;
|
||||
byte[] buffer = encoding.GetBytes(value);
|
||||
writer.Write((ushort)buffer.Length);
|
||||
writer.Write(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/IOExtensions.cs.meta
Normal file
12
Assets/Cryville/Common/IOExtensions.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49f85de87c5e683429e4790c0dc3fd2c
|
||||
timeCreated: 1620706538
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
79
Assets/Cryville/Common/Logger.cs
Normal file
79
Assets/Cryville/Common/Logger.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Ionic.Zip;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public abstract class Logger {
|
||||
static readonly Dictionary<string, Logger> Instances = new Dictionary<string, Logger>();
|
||||
static readonly Dictionary<string, StreamWriter> Files = new Dictionary<string, StreamWriter>();
|
||||
static string logPath = null;
|
||||
public static void SetLogPath(string path) {
|
||||
logPath = path;
|
||||
var dir = new DirectoryInfo(path);
|
||||
if (!dir.Exists) Directory.CreateDirectory(dir.FullName);
|
||||
}
|
||||
public static void Log(string key, int level, string module, string format, params object[] args) {
|
||||
if (!Instances.ContainsKey(key)) return;
|
||||
Instances[key].Log(level, module, string.Format(format, args));
|
||||
if (Files.ContainsKey(key)) Files[key].WriteLine("[{0:O}] [{1}] <{2}> {3}", DateTime.UtcNow, level, module, string.Format(format, args));
|
||||
}
|
||||
public static void Create(string key, Logger logger) {
|
||||
Instances[key] = logger;
|
||||
if (logPath != null) {
|
||||
Files[key] = new StreamWriter(logPath + "/" + ((int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString() + "-" + key + ".log");
|
||||
Files[key].AutoFlush = true;
|
||||
}
|
||||
}
|
||||
public static void Close() {
|
||||
Instances.Clear();
|
||||
foreach (var f in Files) f.Value.Dispose();
|
||||
Files.Clear();
|
||||
}
|
||||
|
||||
public virtual void Log(int level, string module, string msg) { }
|
||||
}
|
||||
|
||||
public class InstantLogger : Logger {
|
||||
readonly Action<int, string, string> callback;
|
||||
public InstantLogger(Action<int, string, string> callback) {
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException("callback");
|
||||
this.callback = callback;
|
||||
}
|
||||
public override void Log(int level, string module, string msg) {
|
||||
base.Log(level, module, msg);
|
||||
callback(level, module, msg);
|
||||
}
|
||||
}
|
||||
|
||||
public class BufferedLogger : Logger {
|
||||
readonly List<LogEntry> buffer = new List<LogEntry>();
|
||||
public BufferedLogger() { }
|
||||
public override void Log(int level, string module, string msg) {
|
||||
base.Log(level, module, msg);
|
||||
lock (buffer) {
|
||||
buffer.Add(new LogEntry(level, module, msg));
|
||||
}
|
||||
}
|
||||
public void Enumerate(Action<int, string, string> callback) {
|
||||
lock (buffer) {
|
||||
foreach (var i in buffer) {
|
||||
callback(i.level, i.module, i.msg);
|
||||
}
|
||||
}
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public struct LogEntry {
|
||||
public int level;
|
||||
public string module;
|
||||
public string msg;
|
||||
public LogEntry(int level, string module, string msg) {
|
||||
this.level = level;
|
||||
this.module = module;
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Logger.cs.meta
Normal file
12
Assets/Cryville/Common/Logger.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c1729cfde78f1c479c9f7eb166e0107
|
||||
timeCreated: 1611126212
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Cryville/Common/Math.meta
Normal file
9
Assets/Cryville/Common/Math.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7912778bf022c34592b3ebf16782635
|
||||
folderAsset: yes
|
||||
timeCreated: 1616377089
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
37
Assets/Cryville/Common/Math/ColumnVector.cs
Normal file
37
Assets/Cryville/Common/Math/ColumnVector.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
namespace Cryville.Common.Math {
|
||||
public class ColumnVector<T> {
|
||||
readonly T[] content;
|
||||
public int Size {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public ColumnVector(int size) {
|
||||
content = new T[size];
|
||||
Size = size;
|
||||
}
|
||||
public ColumnVector(T[] c) {
|
||||
Size = c.Length;
|
||||
content = c;
|
||||
}
|
||||
public T this[int i] {
|
||||
get {
|
||||
return content[i];
|
||||
}
|
||||
set {
|
||||
content[i] = value;
|
||||
}
|
||||
}
|
||||
public T Dot(ColumnVector<float> lhs, IVectorOperator<T> o) {
|
||||
T res = default(T);
|
||||
for (var i = 0; i < Size; i++)
|
||||
res = o.Add(res, o.ScalarMultiply(lhs[i], content[i]));
|
||||
return res;
|
||||
}
|
||||
public static ColumnVector<float> WithPolynomialCoefficients(int size, float num) {
|
||||
var m = new ColumnVector<float>(size);
|
||||
for (var i = 0; i < size; i++)
|
||||
m[i] = (float)System.Math.Pow(num, i);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Math/ColumnVector.cs.meta
Normal file
12
Assets/Cryville/Common/Math/ColumnVector.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b99c66d83f1330841a0c5a23e87bf873
|
||||
timeCreated: 1616406828
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
6
Assets/Cryville/Common/Math/IVectorOperator.cs
Normal file
6
Assets/Cryville/Common/Math/IVectorOperator.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Cryville.Common.Math {
|
||||
public interface IVectorOperator<T> {
|
||||
T Add(T lhs, T rhs);
|
||||
T ScalarMultiply(float lhs, T rhs);
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Math/IVectorOperator.cs.meta
Normal file
12
Assets/Cryville/Common/Math/IVectorOperator.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bd0295c670699c49b6f0944832387a9
|
||||
timeCreated: 1616379780
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
63
Assets/Cryville/Common/Math/SquareMatrix.cs
Normal file
63
Assets/Cryville/Common/Math/SquareMatrix.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
namespace Cryville.Common.Math {
|
||||
public class SquareMatrix {
|
||||
readonly float[,] content;
|
||||
public int Size {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public SquareMatrix(int size) {
|
||||
content = new float[size, size];
|
||||
Size = size;
|
||||
}
|
||||
public float this[int r, int c] {
|
||||
get { return content[r, c]; }
|
||||
set { content[r, c] = value; }
|
||||
}
|
||||
public ColumnVector<T> Eliminate<T>(ColumnVector<T> v, IVectorOperator<T> o) {
|
||||
int s = Size;
|
||||
float[,] d = (float[,])content.Clone();
|
||||
int[] refl = new int[s];
|
||||
for (int i = 0; i < s; i++)
|
||||
refl[i] = i;
|
||||
for (int r = 0; r < s; r++) {
|
||||
for (int r0 = r; r0 < s; r0++)
|
||||
if (d[refl[r0], r] != 0) {
|
||||
refl[r] = r0;
|
||||
refl[r0] = r;
|
||||
break;
|
||||
}
|
||||
int or = refl[r];
|
||||
float sf0 = d[or, r];
|
||||
for (int c0 = r; c0 < s; c0++)
|
||||
d[or, c0] /= sf0;
|
||||
v[or] = o.ScalarMultiply(1 / sf0, v[or]);
|
||||
for (int r1 = r + 1; r1 < s; r1++) {
|
||||
int or1 = refl[r1];
|
||||
float sf1 = d[or1, r];
|
||||
for (int c1 = r; c1 < s; c1++)
|
||||
d[or1, c1] -= d[or, c1] * sf1;
|
||||
v[or1] = o.Add(v[or1], o.ScalarMultiply(-sf1, v[or]));
|
||||
}
|
||||
}
|
||||
T[] res = new T[s];
|
||||
for (int r2 = s - 1; r2 >= 0; r2--) {
|
||||
var v2 = v[refl[r2]];
|
||||
for (int c2 = r2 + 1; c2 < s; c2++)
|
||||
v2 = o.Add(v2, o.ScalarMultiply(-d[refl[r2], c2], res[refl[c2]]));
|
||||
res[refl[r2]] = v2;
|
||||
}
|
||||
return new ColumnVector<T>(res);
|
||||
}
|
||||
public static SquareMatrix WithPolynomialCoefficients(int size) {
|
||||
var m = new SquareMatrix(size);
|
||||
for (var r = 0; r < size; r++) {
|
||||
int d = 1;
|
||||
for (var c = 0; c < size; c++) {
|
||||
m[r, c] = d;
|
||||
d *= r;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Math/SquareMatrix.cs.meta
Normal file
12
Assets/Cryville/Common/Math/SquareMatrix.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bceea65ebaa5052409eb85086645232e
|
||||
timeCreated: 1616377102
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Cryville/Common/Network.meta
Normal file
9
Assets/Cryville/Common/Network.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8303a3eeefeacf4ca0c02b5d32e0cff
|
||||
folderAsset: yes
|
||||
timeCreated: 1621071543
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
142
Assets/Cryville/Common/Network/HttpClient.cs
Normal file
142
Assets/Cryville/Common/Network/HttpClient.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class HttpClient {
|
||||
private readonly string _directHost;
|
||||
protected string DirectHost { get { return _directHost; } }
|
||||
|
||||
private readonly int _directPort;
|
||||
protected int DirectPort { get { return _directPort; } }
|
||||
|
||||
readonly Uri _baseUri;
|
||||
readonly int origPort;
|
||||
|
||||
protected string Version = "HTTP/1.1";
|
||||
protected TcpClient TcpClient;
|
||||
protected virtual Stream Stream {
|
||||
get {
|
||||
return TcpClient.GetStream();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly bool _proxied = false;
|
||||
|
||||
public Dictionary<string, string> Headers { get; set; }
|
||||
|
||||
public HttpClient(Uri baseUri, int port = 80) {
|
||||
_directHost = baseUri.Host;
|
||||
_directPort = port;
|
||||
_baseUri = baseUri;
|
||||
origPort = _baseUri.Port;
|
||||
Headers = new Dictionary<string, string>();
|
||||
_proxied = GetProxy(ref _directHost, ref _directPort);
|
||||
Logger.Log("main", 0, "Network", "Connecting to {0}:{1}", DirectHost, DirectPort);
|
||||
TcpClient = new TcpClient(DirectHost, DirectPort);
|
||||
}
|
||||
|
||||
public virtual void Connect() {
|
||||
if (_proxied) {
|
||||
Request("CONNECT", _baseUri.Host + ":" + origPort.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Close() {
|
||||
TcpClient.Close();
|
||||
}
|
||||
|
||||
public HttpResponse Request(string method, Uri uri, string body = null, Encoding encoding = null) {
|
||||
string struri = GetUri(uri).PathAndQuery;
|
||||
// if (_proxied) struri = GetUri(uri).AbsoluteUri;
|
||||
return Request(method, struri, body, encoding);
|
||||
}
|
||||
|
||||
public HttpResponse Request(string method, string uri, string body = null, Encoding encoding = null) {
|
||||
var headers = new Dictionary<string, string>();
|
||||
// if (Stream.CanTimeout) Stream.ReadTimeout = Stream.WriteTimeout = 5000;
|
||||
foreach (var h in Headers)
|
||||
headers.Add(h.Key, h.Value);
|
||||
// headers["Accept"] = "text/plain, */*";
|
||||
// headers["Connection"] = "close";
|
||||
headers["Host"] = _baseUri.Host;
|
||||
byte[] payload = new byte[0];
|
||||
if (body != null) {
|
||||
if (encoding == null)
|
||||
encoding = Encoding.UTF8;
|
||||
payload = encoding.GetBytes(body);
|
||||
headers.Add("Content-Encoding", encoding.EncodingName);
|
||||
headers.Add("Content-Length", payload.Length.ToString());
|
||||
}
|
||||
string request_line = string.Format(
|
||||
"{0} {1} {2}\r\n", method, uri, Version
|
||||
);
|
||||
string header_fields = string.Concat((
|
||||
from h in headers select h.Key + ":" + h.Value + "\r\n"
|
||||
).ToArray());
|
||||
byte[] buffer0 = Encoding.ASCII.GetBytes(string.Format(
|
||||
"{0}{1}\r\n", request_line, header_fields
|
||||
));
|
||||
byte[] buffer1 = new byte[buffer0.Length + payload.Length];
|
||||
Array.Copy(buffer0, buffer1, buffer0.Length);
|
||||
Array.Copy(payload, 0, buffer1, buffer0.Length, payload.Length);
|
||||
Logger.Log("main", 0, "Network", Encoding.UTF8.GetString(buffer1));
|
||||
Stream.Write(buffer1, 0, buffer1.Length);
|
||||
Stream.Flush();
|
||||
var response = new HttpResponse(Stream);
|
||||
Logger.Log("main", 0, "Network", "{0}", response);
|
||||
return response;
|
||||
}
|
||||
|
||||
protected virtual bool GetProxy(ref string host, ref int port) {
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
|
||||
var reg = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings");
|
||||
var proxyEnable = (int)reg.GetValue("ProxyEnable");
|
||||
if (proxyEnable == 0) return false;
|
||||
var proxyStr = (string)reg.GetValue("ProxyServer");
|
||||
if (!string.IsNullOrEmpty(proxyStr)) {
|
||||
string[] proxies = proxyStr.Split(';');
|
||||
foreach (var p in proxies) {
|
||||
if (p.StartsWith("http=")) {
|
||||
string[] s = p.Split('=', ':');
|
||||
host = s[1];
|
||||
port = int.Parse(s[2]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Uri GetUri(string path) {
|
||||
Uri address;
|
||||
if (_baseUri != null) {
|
||||
if (!Uri.TryCreate(_baseUri, path, out address)) {
|
||||
return new Uri(Path.GetFullPath(path));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!Uri.TryCreate(path, UriKind.Absolute, out address)) {
|
||||
return new Uri(Path.GetFullPath(path));
|
||||
}
|
||||
}
|
||||
return GetUri(address);
|
||||
}
|
||||
|
||||
protected Uri GetUri(Uri address) {
|
||||
if (address == null) {
|
||||
throw new ArgumentNullException("address");
|
||||
}
|
||||
Uri uri = address;
|
||||
if (!address.IsAbsoluteUri && _baseUri != null && !Uri.TryCreate(_baseUri, address, out uri)) {
|
||||
return address;
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Network/HttpClient.cs.meta
Normal file
12
Assets/Cryville/Common/Network/HttpClient.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ea931bf5488011468f3d1243a038874
|
||||
timeCreated: 1622589817
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
61
Assets/Cryville/Common/Network/HttpResponse.cs
Normal file
61
Assets/Cryville/Common/Network/HttpResponse.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class HttpResponse {
|
||||
static readonly char[] spchar = new char[]{ ' ' };
|
||||
public string HttpVersion { get; private set; }
|
||||
public string StatusCode { get; private set; }
|
||||
public string ReasonPhase { get; private set; }
|
||||
public Dictionary<string, string> Headers { get; private set; }
|
||||
public HttpResponseStream MessageBody { get; private set; }
|
||||
internal HttpResponse(Stream stream) {
|
||||
var reader = new BinaryReader(stream, Encoding.ASCII);
|
||||
var statu_line = ReadLine(reader).Split(spchar, 3);
|
||||
HttpVersion = statu_line[0];
|
||||
StatusCode = statu_line[1];
|
||||
ReasonPhase = statu_line[2];
|
||||
Logger.Log("main", 0, "Network", "Receive Response: {0} {1} {2}", HttpVersion, StatusCode, ReasonPhase);
|
||||
Headers = new Dictionary<string, string>();
|
||||
while (ParseHeader(reader, Headers)) ;
|
||||
if (Headers.ContainsKey("content-length")) {
|
||||
int length = int.Parse(Headers["content-length"]);
|
||||
MessageBody = new HttpResponseBlockStream(reader, length);
|
||||
}
|
||||
else if (Headers.ContainsKey("transfer-encoding") && Headers["transfer-encoding"] == "chunked") {
|
||||
MessageBody = new HttpResponseChunkedStream(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format("<{0} {1} {2}>", HttpVersion, StatusCode, ReasonPhase);
|
||||
}
|
||||
|
||||
internal static bool ParseHeader(BinaryReader reader, Dictionary<string,string> headers) {
|
||||
// TODO Multiline header
|
||||
var header = ReadLine(reader);
|
||||
if (header == "") return false;
|
||||
var s = header.Split(':');
|
||||
string field_name = s[0].Trim().ToLower();
|
||||
string field_value = s[1].Trim();
|
||||
if (headers.ContainsKey(field_name)) headers[field_name] += "," + field_value;
|
||||
else headers.Add(field_name, field_value);
|
||||
Logger.Log("main", 0, "Network", "Receive Header {0}: {1}", field_name, field_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static string ReadLine(BinaryReader reader) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
char c;
|
||||
while (true) {
|
||||
c = reader.ReadChar();
|
||||
if (c == '\r') break;
|
||||
result.Append(c);
|
||||
}
|
||||
// TODO Unseekable
|
||||
reader.ReadByte();
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Network/HttpResponse.cs.meta
Normal file
12
Assets/Cryville/Common/Network/HttpResponse.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07e8215a93e3eb1418685009f0c58dcd
|
||||
timeCreated: 1622596274
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
135
Assets/Cryville/Common/Network/HttpResponseStream.cs
Normal file
135
Assets/Cryville/Common/Network/HttpResponseStream.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public abstract class HttpResponseStream : Stream {
|
||||
public override bool CanRead { get { return true; } }
|
||||
|
||||
public override bool CanSeek { get { return false; } }
|
||||
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override long Length { get { throw new NotSupportedException(); } }
|
||||
|
||||
public override long Position {
|
||||
get { throw new NotSupportedException(); }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public override void Flush() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public abstract byte[] ReadToEnd();
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value) {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count) {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class HttpResponseBlockStream : HttpResponseStream {
|
||||
readonly BinaryReader _reader;
|
||||
readonly int _length;
|
||||
int _pos = 0;
|
||||
internal HttpResponseBlockStream(BinaryReader reader, int length) {
|
||||
_reader = reader;
|
||||
_length = length;
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
int recv = 0;
|
||||
int recv_len = System.Math.Min(count, _length - _pos);
|
||||
if (recv_len == 0) return 0;
|
||||
while (recv < recv_len) {
|
||||
recv += _reader.Read(buffer, offset + recv, count - recv);
|
||||
Logger.Log("main", 0, "Network", "Message body received: {0}/{1}/{2}", recv, recv_len, _length);
|
||||
}
|
||||
_pos += recv_len;
|
||||
return recv_len;
|
||||
}
|
||||
public override byte[] ReadToEnd() {
|
||||
byte[] buffer = new byte[_length - _pos];
|
||||
Read(buffer, 0, buffer.Length);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class HttpResponseChunkedStream : HttpResponseStream {
|
||||
readonly BinaryReader _reader;
|
||||
byte[] _chunk = null;
|
||||
int _pos = 0;
|
||||
internal HttpResponseChunkedStream(BinaryReader reader) {
|
||||
_reader = reader;
|
||||
ReadChunk();
|
||||
}
|
||||
public void ReadChunk() {
|
||||
if (_chunk != null && _chunk.Length == 0) return;
|
||||
string[] chunkHeader = HttpResponse.ReadLine(_reader).Split(';');
|
||||
// int chunkSize = Array.IndexOf(LEN, chunkHeader[0].ToLower()[0]);
|
||||
int chunkSize = int.Parse(chunkHeader[0], NumberStyles.HexNumber);
|
||||
if (chunkSize == -1)
|
||||
throw new IOException("Corrupted chunk received");
|
||||
if (chunkSize == 0) {
|
||||
_chunk = new byte[0];
|
||||
// TODO TE Header, now just discard
|
||||
var headers = new Dictionary<string, string>();
|
||||
while (HttpResponse.ParseHeader(_reader, headers)) ;
|
||||
return;
|
||||
}
|
||||
_chunk = new byte[chunkSize];
|
||||
int recv = 0;
|
||||
while (recv < chunkSize) {
|
||||
recv += _reader.Read(_chunk, recv, chunkSize - recv);
|
||||
Logger.Log("main", 0, "Network", "Message chunk received: {0}/{1}", recv, chunkSize);
|
||||
}
|
||||
_pos = 0;
|
||||
if (HttpResponse.ReadLine(_reader) != "")
|
||||
throw new IOException("Corrupted chunk received");
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
if (_chunk.Length == 0) return 0;
|
||||
int recv = 0;
|
||||
while (true) {
|
||||
if (count - recv <= _chunk.Length - _pos) break;
|
||||
Array.Copy(_chunk, _pos, buffer, recv, _chunk.Length - _pos);
|
||||
recv += _chunk.Length - _pos;
|
||||
ReadChunk();
|
||||
if (_chunk.Length == 0) return recv;
|
||||
}
|
||||
Array.Copy(_chunk, _pos, buffer, recv, count - recv);
|
||||
return count;
|
||||
}
|
||||
public override byte[] ReadToEnd() {
|
||||
if (_chunk.Length == 0) return new byte[0];
|
||||
List<byte[]> segs = new List<byte[]>();
|
||||
while (true) {
|
||||
if (_pos != 0) {
|
||||
var buffer = new byte[_chunk.Length - _pos];
|
||||
Array.Copy(_chunk, _pos, buffer, 0, buffer.Length);
|
||||
segs.Add(buffer);
|
||||
}
|
||||
else segs.Add(_chunk);
|
||||
ReadChunk();
|
||||
if (_chunk.Length == 0) {
|
||||
var result = new byte[segs.Sum(i => i.Length)];
|
||||
int p = 0;
|
||||
foreach (var i in segs) {
|
||||
Array.Copy(i, 0, result, p, i.Length);
|
||||
p += i.Length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Network/HttpResponseStream.cs.meta
Normal file
12
Assets/Cryville/Common/Network/HttpResponseStream.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f191de447a708da4f9d230e6545ce0a6
|
||||
timeCreated: 1635470462
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
51
Assets/Cryville/Common/Network/HttpsClient.cs
Normal file
51
Assets/Cryville/Common/Network/HttpsClient.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class HttpsClient : HttpClient {
|
||||
readonly TlsTcpClient _tlsTcpClient;
|
||||
|
||||
protected override Stream Stream {
|
||||
get {
|
||||
return _tlsTcpClient.Stream;
|
||||
}
|
||||
}
|
||||
|
||||
public HttpsClient(Uri baseUri) : base(baseUri, 443) {
|
||||
_tlsTcpClient = new TlsTcpClient(DirectHost, DirectPort);
|
||||
}
|
||||
|
||||
public override void Connect() {
|
||||
_tlsTcpClient.Connect();
|
||||
base.Connect();
|
||||
}
|
||||
|
||||
public override void Close() {
|
||||
base.Close();
|
||||
_tlsTcpClient.Close();
|
||||
}
|
||||
|
||||
protected override bool GetProxy(ref string host, ref int port) {
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
|
||||
var reg = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings");
|
||||
var proxyEnable = (int)reg.GetValue("ProxyEnable");
|
||||
if (proxyEnable == 0) return false;
|
||||
var proxyStr = (string)reg.GetValue("ProxyServer");
|
||||
if (!string.IsNullOrEmpty(proxyStr)) {
|
||||
string[] proxies = proxyStr.Split(';');
|
||||
foreach (var p in proxies) {
|
||||
if (p.StartsWith("https=")) {
|
||||
string[] s = p.Split('=', ':');
|
||||
host = s[1];
|
||||
port = int.Parse(s[2]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Common/Network/HttpsClient.cs.meta
Normal file
12
Assets/Cryville/Common/Network/HttpsClient.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b35290e0e147a342acc29a20c8fceaf
|
||||
timeCreated: 1622503538
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user