619 lines
16 KiB
C#
619 lines
16 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using I2.Loc;
|
|
using Steamworks;
|
|
using Unity.IO.Compression;
|
|
using UnityEngine;
|
|
using UnityEngine.Profiling;
|
|
|
|
public class Utilities : MonoBehaviour
|
|
{
|
|
public enum LogColor
|
|
{
|
|
YELLOW = 0
|
|
}
|
|
|
|
public enum BlendMode
|
|
{
|
|
Opaque = 0,
|
|
Cutout = 1,
|
|
Fade = 2,
|
|
Transparent = 3
|
|
}
|
|
|
|
public static string serverTimeUrl = "www.bitgolemgames.com/server_time.php";
|
|
|
|
public static DateTime epochDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
public static void SetLayerRecursively(GameObject go, int layerNumber)
|
|
{
|
|
Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true);
|
|
Transform[] array = componentsInChildren;
|
|
foreach (Transform transform in array)
|
|
{
|
|
transform.gameObject.layer = layerNumber;
|
|
}
|
|
}
|
|
|
|
public static void SetLayerRecursively(GameObject go, string layerName)
|
|
{
|
|
SetLayerRecursively(go, LayerMask.NameToLayer(layerName));
|
|
}
|
|
|
|
public static int AddToLayerMask(int mask, string layer)
|
|
{
|
|
return mask |= 1 << LayerMask.NameToLayer(layer);
|
|
}
|
|
|
|
public static int RemoveFromLayerMask(int mask, string layer)
|
|
{
|
|
return mask ^= 1 << LayerMask.NameToLayer(layer);
|
|
}
|
|
|
|
public static bool IsLayerInLayerMask(LayerMask mask, string layer)
|
|
{
|
|
return (int)mask == ((int)mask | (1 << LayerMask.NameToLayer(layer)));
|
|
}
|
|
|
|
public static void DisableAllScripts(GameObject go)
|
|
{
|
|
MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>();
|
|
MonoBehaviour[] array = componentsInChildren;
|
|
foreach (MonoBehaviour monoBehaviour in array)
|
|
{
|
|
monoBehaviour.enabled = false;
|
|
}
|
|
}
|
|
|
|
public static void CheckCommanLineArguments()
|
|
{
|
|
string[] commandLineArgs = Environment.GetCommandLineArgs();
|
|
Debug.Log("GetCommandLineArgs " + commandLineArgs.Length);
|
|
for (int i = 0; i < commandLineArgs.Length; i++)
|
|
{
|
|
Debug.Log("arg " + commandLineArgs[i]);
|
|
if (GlobalSettings.Instance.currentPlatform == GlobalSettings.Platform.ARCADE)
|
|
{
|
|
if (commandLineArgs[i] == "-multi_room_name" && commandLineArgs.Length > i + 1)
|
|
{
|
|
GlobalSettings.Instance.levelsManager.multiRoomNameArcade = commandLineArgs[i + 1];
|
|
}
|
|
}
|
|
else if (i > 0)
|
|
{
|
|
SteamStatsManager.Instance.ProcessInviteMessage(commandLineArgs[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static byte[] CompressText(string text)
|
|
{
|
|
using (MemoryStream memoryStream = new MemoryStream())
|
|
{
|
|
using (GZipStream stream = new GZipStream(memoryStream, CompressionMode.Compress))
|
|
{
|
|
using (StreamWriter streamWriter = new StreamWriter(stream))
|
|
{
|
|
streamWriter.Write(text);
|
|
}
|
|
}
|
|
Debug.Log("Compression: Text - " + Encoding.Unicode.GetByteCount(text) + " Compressed - " + memoryStream.ToArray().Length);
|
|
return memoryStream.ToArray();
|
|
}
|
|
}
|
|
|
|
public static string DecompressText(byte[] text)
|
|
{
|
|
using (MemoryStream stream = new MemoryStream(text))
|
|
{
|
|
using (GZipStream stream2 = new GZipStream(stream, CompressionMode.Decompress))
|
|
{
|
|
using (StreamReader streamReader = new StreamReader(stream2))
|
|
{
|
|
return streamReader.ReadToEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static int[] Long2DoubleInt(long a)
|
|
{
|
|
int num = (int)(a & 0xFFFFFFFFu);
|
|
int num2 = (int)(a >> 32);
|
|
return new int[2] { num, num2 };
|
|
}
|
|
|
|
public static long DoubleInt2Long(int a1, int a2)
|
|
{
|
|
long num = a2;
|
|
num <<= 32;
|
|
return num | (uint)a1;
|
|
}
|
|
|
|
public static uint[] ULong2DoubleInt(ulong value)
|
|
{
|
|
uint num = (uint)(value & 0xFFFFFFFFu);
|
|
uint num2 = (uint)(value >> 32);
|
|
return new uint[2] { num, num2 };
|
|
}
|
|
|
|
public static ulong DoubleUInt2ULong(uint low, uint high)
|
|
{
|
|
return ((ulong)high << 32) | low;
|
|
}
|
|
|
|
public static string FormatTime(float TimeValue, bool ShowFraction, float FractionDecimals)
|
|
{
|
|
string result = "00:00:00";
|
|
if (!ShowFraction)
|
|
{
|
|
result = "00:00";
|
|
}
|
|
if (TimeValue > 0f)
|
|
{
|
|
TimeSpan timeSpan = TimeSpan.FromSeconds(TimeValue);
|
|
float num = timeSpan.Minutes;
|
|
float num2 = timeSpan.Seconds;
|
|
float num3 = TimeValue * 100f % 100f;
|
|
if (num3 >= 99f)
|
|
{
|
|
num3 = 0f;
|
|
}
|
|
result = ((!ShowFraction) ? string.Format("{0:00}:{1:00}", num, num2) : ((FractionDecimals != 2f) ? string.Format("{0:00}:{1:00}:{2:0}", num, num2, num3) : string.Format("{0:00}:{1:00}:{2:00}", num, num2, num3)));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static string GetTranslation(string key, bool fixSpaces = false)
|
|
{
|
|
string text = LocalizationManager.GetTermTranslation(key);
|
|
if (string.IsNullOrEmpty(text))
|
|
{
|
|
return key;
|
|
}
|
|
if (fixSpaces && LocalizationManager.CurrentLanguageCode == "ja")
|
|
{
|
|
text = text.Replace("。", "。 ");
|
|
text = text.Replace("、", "、 ");
|
|
}
|
|
return text;
|
|
}
|
|
|
|
public static Vector3 RotateVector(Vector3 vector, Vector3 rotation)
|
|
{
|
|
return Quaternion.Euler(rotation.x, rotation.y, rotation.z) * vector;
|
|
}
|
|
|
|
public static AnimationClip GetAnimationClipFromAnimator(Animator animator, string name)
|
|
{
|
|
if (animator == null)
|
|
{
|
|
return null;
|
|
}
|
|
for (int i = 0; i < animator.runtimeAnimatorController.animationClips.Length; i++)
|
|
{
|
|
if (animator.runtimeAnimatorController.animationClips[i].name == name)
|
|
{
|
|
return animator.runtimeAnimatorController.animationClips[i];
|
|
}
|
|
}
|
|
Debug.LogError("Animation clip: " + name + " not found");
|
|
return null;
|
|
}
|
|
|
|
public static Vector3 OrthoNormalize(Vector3 vector1, Vector3 vector2)
|
|
{
|
|
vector1.Normalize();
|
|
Vector3 lhs = Vector3.Cross(vector1, vector2);
|
|
lhs.Normalize();
|
|
vector2 = Vector3.Cross(lhs, vector2);
|
|
return vector2;
|
|
}
|
|
|
|
public static void AddTorqueAtPosition(Rigidbody thisRigidbody, Vector3 torque, Vector3 position)
|
|
{
|
|
Vector3 normalized = torque.normalized;
|
|
Vector3 vector = new Vector3(1f, 0f, 0f);
|
|
if ((normalized - vector).sqrMagnitude < float.Epsilon)
|
|
{
|
|
vector = new Vector3(0f, 1f, 0f);
|
|
}
|
|
Vector3 vector2 = OrthoNormalize(normalized, vector);
|
|
Vector3 vector3 = Vector3.Cross(0.5f * torque, vector2);
|
|
thisRigidbody.AddForceAtPosition(vector3, position + vector2);
|
|
thisRigidbody.AddForceAtPosition(-vector3, position - vector2);
|
|
}
|
|
|
|
public static float GetVectorAngle(Vector3 v)
|
|
{
|
|
float num = Mathf.Atan2(v.x, v.y) * 57.29578f;
|
|
if (num < 0f)
|
|
{
|
|
num += 360f;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
public static float AngleWithDirection(Vector3 v1, Vector3 v2, Vector3 normal)
|
|
{
|
|
return Vector3.Angle(v1, v2) * Mathf.Sign(Vector3.Dot(Vector3.Cross(v1, v2), normal));
|
|
}
|
|
|
|
public static Vector3 NearestPointOnFiniteLine(Vector3 start, Vector3 end, Vector3 pnt)
|
|
{
|
|
Vector3 vector = end - start;
|
|
float magnitude = vector.magnitude;
|
|
vector.Normalize();
|
|
Vector3 lhs = pnt - start;
|
|
float value = Vector3.Dot(lhs, vector);
|
|
value = Mathf.Clamp(value, 0f, magnitude);
|
|
return start + vector * value;
|
|
}
|
|
|
|
public static bool ClosestPointsOnTwoLines(out Vector3 closestPointLine1, out Vector3 closestPointLine2, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2)
|
|
{
|
|
closestPointLine1 = Vector3.zero;
|
|
closestPointLine2 = Vector3.zero;
|
|
float num = Vector3.Dot(lineVec1, lineVec1);
|
|
float num2 = Vector3.Dot(lineVec1, lineVec2);
|
|
float num3 = Vector3.Dot(lineVec2, lineVec2);
|
|
float num4 = num * num3 - num2 * num2;
|
|
if (num4 != 0f)
|
|
{
|
|
Vector3 rhs = linePoint1 - linePoint2;
|
|
float num5 = Vector3.Dot(lineVec1, rhs);
|
|
float num6 = Vector3.Dot(lineVec2, rhs);
|
|
float num7 = (num2 * num6 - num5 * num3) / num4;
|
|
float num8 = (num * num6 - num5 * num2) / num4;
|
|
closestPointLine1 = linePoint1 + lineVec1 * num7;
|
|
closestPointLine2 = linePoint2 + lineVec2 * num8;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static float GetSmoothFactor(float currentValue, float maxValue, float threshold)
|
|
{
|
|
if (maxValue == 0f)
|
|
{
|
|
return 1f;
|
|
}
|
|
float num = currentValue / maxValue;
|
|
if (num < threshold || num < 0f)
|
|
{
|
|
return 1f;
|
|
}
|
|
return (1f - num) / (1f - threshold);
|
|
}
|
|
|
|
public static float GetAngleNormalRange(float angle)
|
|
{
|
|
if (angle < 0f)
|
|
{
|
|
angle += 360f;
|
|
}
|
|
else if (angle >= 360f)
|
|
{
|
|
angle -= 360f;
|
|
}
|
|
return angle;
|
|
}
|
|
|
|
public static Vector3 GetVectorAnglesNormalRange(Vector3 angles)
|
|
{
|
|
angles.x = GetAngleNormalRange(angles.x);
|
|
angles.y = GetAngleNormalRange(angles.y);
|
|
angles.z = GetAngleNormalRange(angles.z);
|
|
return angles;
|
|
}
|
|
|
|
public static float GetAngle180Range(float angle)
|
|
{
|
|
if (angle > 180f)
|
|
{
|
|
angle -= 360f;
|
|
}
|
|
if (angle < -180f)
|
|
{
|
|
angle += 360f;
|
|
}
|
|
return angle;
|
|
}
|
|
|
|
public static Vector3 GetVectorAngles180Range(Vector3 angles)
|
|
{
|
|
angles.x = GetAngle180Range(angles.x);
|
|
angles.y = GetAngle180Range(angles.y);
|
|
angles.z = GetAngle180Range(angles.z);
|
|
return angles;
|
|
}
|
|
|
|
public static float PingPongValue(float value, float min, float max)
|
|
{
|
|
if (value > max)
|
|
{
|
|
value = max - (value - max);
|
|
}
|
|
else if (value < min)
|
|
{
|
|
value = min - (value - min);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static void RenderTextureToPng(RenderTexture rt, string pngOutPath)
|
|
{
|
|
RenderTexture active = RenderTexture.active;
|
|
Texture2D texture2D = new Texture2D(rt.width, rt.height);
|
|
RenderTexture.active = rt;
|
|
texture2D.ReadPixels(new Rect(0f, 0f, rt.width, rt.height), 0, 0);
|
|
texture2D.Apply();
|
|
File.WriteAllBytes(pngOutPath, texture2D.EncodeToPNG());
|
|
RenderTexture.active = active;
|
|
Debug.Log("RenderTexture saved to file: " + pngOutPath);
|
|
}
|
|
|
|
public static void Shuffle<T>(List<T> ts)
|
|
{
|
|
int count = ts.Count;
|
|
int num = count - 1;
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
int index = UnityEngine.Random.Range(i, count);
|
|
T value = ts[i];
|
|
ts[i] = ts[index];
|
|
ts[index] = value;
|
|
}
|
|
}
|
|
|
|
public static IEnumerator CleanUp()
|
|
{
|
|
GC.Collect();
|
|
yield return Resources.UnloadUnusedAssets();
|
|
GC.Collect();
|
|
}
|
|
|
|
public static void DestroyWaterTextures()
|
|
{
|
|
HideFlags hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector;
|
|
HideFlags hideFlags2 = HideFlags.HideInHierarchy | HideFlags.DontSaveInEditor | HideFlags.NotEditable | HideFlags.DontUnloadUnusedAsset;
|
|
UnityEngine.Object[] array = Resources.FindObjectsOfTypeAll(typeof(Texture));
|
|
UnityEngine.Object[] array2 = array;
|
|
for (int i = 0; i < array2.Length; i++)
|
|
{
|
|
Texture texture = (Texture)array2[i];
|
|
if (texture.hideFlags != HideFlags.HideAndDontSave && texture.hideFlags != hideFlags && texture.hideFlags != hideFlags2 && (texture.name == "WaterSimulationArea" || texture.name == "[UWS] - Depth"))
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(texture);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void CheckTextureMemory()
|
|
{
|
|
if (!Application.isEditor)
|
|
{
|
|
return;
|
|
}
|
|
float num = 0f;
|
|
int num2 = 0;
|
|
HideFlags hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector;
|
|
HideFlags hideFlags2 = HideFlags.HideInHierarchy | HideFlags.DontSaveInEditor | HideFlags.NotEditable | HideFlags.DontUnloadUnusedAsset;
|
|
UnityEngine.Object[] array = Resources.FindObjectsOfTypeAll(typeof(Texture));
|
|
UnityEngine.Object[] array2 = array;
|
|
for (int i = 0; i < array2.Length; i++)
|
|
{
|
|
Texture texture = (Texture)array2[i];
|
|
if (texture.hideFlags != HideFlags.HideAndDontSave && texture.hideFlags != hideFlags && texture.hideFlags != hideFlags2)
|
|
{
|
|
num2++;
|
|
if (Application.isEditor)
|
|
{
|
|
int runtimeMemorySize = Profiler.GetRuntimeMemorySize(texture);
|
|
num += (float)runtimeMemorySize / 1000000f;
|
|
}
|
|
}
|
|
}
|
|
Debug.Log("Textures: " + num2 + " totalTextureMemorySize MB: " + num);
|
|
}
|
|
|
|
public static void CopyDirectory(string sourcePath, string destPath)
|
|
{
|
|
if (!Directory.Exists(destPath))
|
|
{
|
|
Directory.CreateDirectory(destPath);
|
|
}
|
|
if (!Directory.Exists(sourcePath))
|
|
{
|
|
Directory.CreateDirectory(sourcePath);
|
|
}
|
|
FileInfo[] files = new DirectoryInfo(sourcePath).GetFiles();
|
|
for (int i = 0; i < files.Length; i++)
|
|
{
|
|
files[i].CopyTo(destPath + "/" + files[i].Name, true);
|
|
}
|
|
}
|
|
|
|
public static DateTime GetCurrentDateTime()
|
|
{
|
|
if (SteamManager.Initialized)
|
|
{
|
|
return epochDateTime.AddSeconds(SteamUtils.GetServerRealTime());
|
|
}
|
|
return epochDateTime;
|
|
}
|
|
|
|
public static void ServerTimeToInts(string timeString, out uint dayInt, out uint hourInt)
|
|
{
|
|
timeString = timeString.Replace(".", string.Empty);
|
|
string[] array = timeString.Split("#"[0]);
|
|
if (array.Length < 2 || array[0] == string.Empty || array[1] == string.Empty)
|
|
{
|
|
Debug.Log("ServerTimeToInts empty: " + timeString);
|
|
dayInt = 0u;
|
|
hourInt = 0u;
|
|
}
|
|
else
|
|
{
|
|
dayInt = Convert.ToUInt32(array[0]);
|
|
hourInt = Convert.ToUInt32(array[1]);
|
|
}
|
|
}
|
|
|
|
public static void PlatformTimeToInts(DateTime dateTime, out uint dayInt, out uint hourInt)
|
|
{
|
|
hourInt = (uint)(dateTime.Minute + dateTime.Hour * 100);
|
|
dayInt = (uint)(dateTime.Day + dateTime.Month * 100 + dateTime.Year * 10000);
|
|
}
|
|
|
|
public static void IsServerMonthOdd(string timeString)
|
|
{
|
|
string[] array = timeString.Split("."[0]);
|
|
int num;
|
|
int num2;
|
|
int num3;
|
|
if (array.Length < 4 || array[0] == string.Empty || array[1] == string.Empty)
|
|
{
|
|
Debug.Log("IsMonthOdd empty: " + timeString);
|
|
num = -1;
|
|
num2 = -1;
|
|
num3 = -1;
|
|
}
|
|
else
|
|
{
|
|
num = Convert.ToInt32(array[0]);
|
|
num2 = Convert.ToInt32(array[1]);
|
|
num3 = ((num2 % 2 != 0) ? 1 : 0);
|
|
Debug.Log("IsMonthOdd: " + num2 + ": " + num3);
|
|
}
|
|
if ((bool)LeaderboardsManager.Instance)
|
|
{
|
|
LeaderboardsManager.Instance.isServerMonthOdd = num3;
|
|
LeaderboardsManager.Instance.currentServerYear = num;
|
|
LeaderboardsManager.Instance.currentServerMonth = num2;
|
|
}
|
|
}
|
|
|
|
public static IEnumerator PrintServerTime()
|
|
{
|
|
WWW www = new WWW(serverTimeUrl);
|
|
yield return www;
|
|
Debug.Log("Server Time:" + www.text);
|
|
uint dayInt;
|
|
uint hourInt;
|
|
ServerTimeToInts(www.text, out dayInt, out hourInt);
|
|
Debug.Log("PrintServerTime ServerTimeToInts: " + dayInt + " " + hourInt);
|
|
}
|
|
|
|
public static float GetAverage(List<float> floatList)
|
|
{
|
|
float num = 0f;
|
|
for (int i = 0; i < floatList.Count; i++)
|
|
{
|
|
num += floatList[i];
|
|
}
|
|
if (floatList.Count > 0)
|
|
{
|
|
num /= (float)floatList.Count;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
public static bool CheckUndergroundAndFix(Transform trans)
|
|
{
|
|
if (GameController.Instance.oceanLevel)
|
|
{
|
|
return true;
|
|
}
|
|
RaycastHit hitInfo;
|
|
if (Physics.Raycast(trans.position, Vector3.down, out hitInfo, 50f, LayerMask.GetMask("Default", "Terrain")))
|
|
{
|
|
return true;
|
|
}
|
|
if (Physics.Raycast(trans.position, -Vector3.down, out hitInfo, 50f, LayerMask.GetMask("Default", "Terrain")))
|
|
{
|
|
trans.position = hitInfo.point + -Vector3.down * 0.1f;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static string DirtyWordsFilter(string words)
|
|
{
|
|
return words;
|
|
}
|
|
|
|
public static void OpenURL(string url)
|
|
{
|
|
Application.OpenURL(url);
|
|
}
|
|
|
|
public static void LogError(bool condition, string log, string color = "white", bool bold = false)
|
|
{
|
|
if (condition)
|
|
{
|
|
LogError(log, color, bold);
|
|
}
|
|
}
|
|
|
|
public static void LogError(string log, string color = "white", bool bold = false)
|
|
{
|
|
log = string.Format("{0}<color={1}>{2}</color>{3}", (!bold) ? string.Empty : "<b>", color, log, (!bold) ? string.Empty : "</b>");
|
|
Debug.LogError(log);
|
|
}
|
|
|
|
public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode)
|
|
{
|
|
switch (blendMode)
|
|
{
|
|
case BlendMode.Opaque:
|
|
material.SetOverrideTag("RenderType", "TransparentCutout");
|
|
material.SetInt("_SrcBlend", 1);
|
|
material.SetInt("_DstBlend", 0);
|
|
material.SetInt("_ZWrite", 1);
|
|
material.DisableKeyword("_ALPHATEST_ON");
|
|
material.DisableKeyword("_ALPHABLEND_ON");
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
material.renderQueue = -1;
|
|
break;
|
|
case BlendMode.Cutout:
|
|
material.SetOverrideTag("RenderType", "TransparentCutout");
|
|
material.SetInt("_SrcBlend", 1);
|
|
material.SetInt("_DstBlend", 0);
|
|
material.SetInt("_ZWrite", 1);
|
|
material.EnableKeyword("_ALPHATEST_ON");
|
|
material.DisableKeyword("_ALPHABLEND_ON");
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
material.renderQueue = 2450;
|
|
break;
|
|
case BlendMode.Fade:
|
|
material.SetOverrideTag("RenderType", "Transparent");
|
|
material.SetInt("_SrcBlend", 5);
|
|
material.SetInt("_DstBlend", 10);
|
|
material.SetInt("_ZWrite", 0);
|
|
material.DisableKeyword("_ALPHATEST_ON");
|
|
material.EnableKeyword("_ALPHABLEND_ON");
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
material.renderQueue = 3000;
|
|
break;
|
|
case BlendMode.Transparent:
|
|
material.SetOverrideTag("RenderType", "Transparent");
|
|
material.SetInt("_SrcBlend", 1);
|
|
material.SetInt("_DstBlend", 10);
|
|
material.SetInt("_ZWrite", 0);
|
|
material.DisableKeyword("_ALPHATEST_ON");
|
|
material.DisableKeyword("_ALPHABLEND_ON");
|
|
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
material.renderQueue = 3000;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static void TestThrowException()
|
|
{
|
|
throw new Exception("TestThrowException");
|
|
}
|
|
}
|