|
4 | 4 | using References::Newtonsoft.Json; |
5 | 5 | using References::Newtonsoft.Json.Converters; |
6 | 6 | using References::Newtonsoft.Json.Linq; |
| 7 | +using References::ProtoBuf; |
7 | 8 | using System; |
8 | 9 | using System.Collections.Generic; |
| 10 | +using System.Globalization; |
| 11 | +using System.IO; |
| 12 | +using System.Text; |
9 | 13 | using UnityEngine; |
10 | 14 | using UnityEngine.UI; |
11 | 15 |
|
12 | 16 | namespace Oxide.Game.Rust.Cui |
13 | 17 | { |
| 18 | + public sealed class JsonArrayPool<T> : IArrayPool<T> |
| 19 | + { |
| 20 | + public static readonly JsonArrayPool<T> Shared = new JsonArrayPool<T>(); |
| 21 | + public T[] Rent(int minimumLength) => System.Buffers.ArrayPool<T>.Shared.Rent(minimumLength); |
| 22 | + public void Return(T[] array) => System.Buffers.ArrayPool<T>.Shared.Return(array); |
| 23 | + } |
| 24 | + |
14 | 25 | public static class CuiHelper |
15 | 26 | { |
16 | | - public static string ToJson(List<CuiElement> elements, bool format = false) |
| 27 | + private static readonly StringBuilder sb = new StringBuilder(64 * 1024); |
| 28 | + |
| 29 | + private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings |
17 | 30 | { |
18 | | - return JsonConvert.SerializeObject(elements, format ? Formatting.Indented : Formatting.None, new JsonSerializerSettings |
19 | | - { |
20 | | - DefaultValueHandling = DefaultValueHandling.Ignore |
21 | | - }).Replace("\\n", "\n"); |
| 31 | + DefaultValueHandling = DefaultValueHandling.Ignore, |
| 32 | + NullValueHandling = NullValueHandling.Ignore, |
| 33 | + DateParseHandling = DateParseHandling.None, |
| 34 | + FloatFormatHandling = FloatFormatHandling.Symbol, |
| 35 | + StringEscapeHandling = StringEscapeHandling.Default |
| 36 | + }; |
| 37 | + |
| 38 | + private static readonly JsonSerializer _serializer = JsonSerializer.Create(Settings); |
| 39 | + private static readonly StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); |
| 40 | + private static readonly JsonTextWriter jw = new JsonTextWriter(sw) |
| 41 | + { |
| 42 | + Formatting = Formatting.None, |
| 43 | + ArrayPool = JsonArrayPool<char>.Shared, |
| 44 | + CloseOutput = false |
| 45 | + }; |
| 46 | + private static readonly JsonTextWriter jwFormated = new JsonTextWriter(sw) |
| 47 | + { |
| 48 | + Formatting = Formatting.Indented, |
| 49 | + ArrayPool = JsonArrayPool<char>.Shared, |
| 50 | + CloseOutput = false |
| 51 | + }; |
| 52 | + |
| 53 | + public static string ToJson(IReadOnlyList<CuiElement> elements, bool format = false) |
| 54 | + { |
| 55 | + sb.Clear(); |
| 56 | + var writer = format ? jwFormated : jw; |
| 57 | + _serializer.Serialize(writer, elements); |
| 58 | + var json = sb.ToString().Replace("\\n", "\n"); |
| 59 | + return json; |
22 | 60 | } |
23 | 61 |
|
24 | 62 | public static List<CuiElement> FromJson(string json) => JsonConvert.DeserializeObject<List<CuiElement>>(json); |
25 | 63 |
|
26 | | - public static string GetGuid() => Guid.NewGuid().ToString().Replace("-", string.Empty); |
| 64 | + public static string GetGuid() => Guid.NewGuid().ToString("N"); |
27 | 65 |
|
28 | | - public static bool AddUi(BasePlayer player, List<CuiElement> elements) => AddUi(player, ToJson(elements)); |
| 66 | + public static bool AddUi(BasePlayer player, List<CuiElement> elements) |
| 67 | + { |
| 68 | + if (player?.net == null) |
| 69 | + return false; |
| 70 | + |
| 71 | + var json = ToJson(elements); |
| 72 | + |
| 73 | + if (Interface.CallHook("CanUseUI", player, json) != null) |
| 74 | + return false; |
| 75 | + |
| 76 | + CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("AddUI", player.net.connection), json); |
| 77 | + return true; |
| 78 | + } |
29 | 79 |
|
30 | 80 | public static bool AddUi(BasePlayer player, string json) |
31 | 81 | { |
32 | | - if (player?.net != null && Interface.CallHook("CanUseUI", player, json) == null) |
33 | | - { |
34 | | - CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("AddUI", player.net.connection ), json); |
35 | | - return true; |
36 | | - } |
| 82 | + if (player?.net == null || Interface.CallHook("CanUseUI", player, json) != null) |
| 83 | + return false; |
37 | 84 |
|
38 | | - return false; |
| 85 | + CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("AddUI", player.net.connection), json); |
| 86 | + return true; |
39 | 87 | } |
40 | 88 |
|
41 | 89 | public static bool DestroyUi(BasePlayer player, string elem) |
42 | 90 | { |
43 | | - if (player?.net != null) |
44 | | - { |
45 | | - Interface.CallHook("OnDestroyUI", player, elem); |
46 | | - CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("DestroyUI", player.net.connection ), elem); |
47 | | - return true; |
48 | | - } |
| 91 | + if (player?.net == null) |
| 92 | + return false; |
49 | 93 |
|
50 | | - return false; |
| 94 | + Interface.CallHook("OnDestroyUI", player, elem); |
| 95 | + CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("DestroyUI", player.net.connection ), elem); |
| 96 | + return true; |
51 | 97 | } |
52 | 98 |
|
53 | 99 | public static void SetColor(this ICuiColor elem, Color color) |
54 | 100 | { |
55 | | - elem.Color = $"{color.r} {color.g} {color.b} {color.a}"; |
| 101 | + sb.Clear(); |
| 102 | + sb.Append(color.r).Append(' ') |
| 103 | + .Append(color.g).Append(' ') |
| 104 | + .Append(color.b).Append(' ') |
| 105 | + .Append(color.a); |
| 106 | + elem.Color = sb.ToString(); |
56 | 107 | } |
57 | 108 |
|
58 | 109 | public static Color GetColor(this ICuiColor elem) => ColorEx.Parse(elem.Color); |
@@ -299,7 +350,7 @@ public class CuiRawImageComponent : ICuiComponent, ICuiColor |
299 | 350 |
|
300 | 351 | [JsonProperty("png")] |
301 | 352 | public string Png { get; set; } |
302 | | - |
| 353 | + |
303 | 354 | [JsonProperty("steamid")] |
304 | 355 | public string SteamId { get; set; } |
305 | 356 |
|
|
0 commit comments