gg.easy.airship 0.1.2143 → 0.1.2144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Runtime/Code/AirshipConst.cs +2 -2
- package/Runtime/Code/Authentication/EasyAuthenticator.cs +2 -2
- package/Runtime/Code/Authentication/TransferData.cs +1 -1
- package/Runtime/Code/Bootstrap/LuauScriptsDtoSerializer.cs +48 -19
- package/Runtime/Code/Easy.Airship.asmdef +2 -1
- package/Runtime/Code/Health/AirshipProfileExporter.cs +14 -9
- package/Runtime/Code/Luau/LuauCore.cs +1 -1
- package/Runtime/Code/Luau/LuauCoreCallbacks.cs +26 -57
- package/Runtime/Code/Luau/LuauPlugin.cs +2 -2
- package/Runtime/Code/Network/ServerConsole.cs +14 -7
- package/Runtime/Code/Player/Character/MovementSystems/Character/CharacterMovement.cs +51 -34
- package/Runtime/Code/Player/PlayerInfo.cs +4 -0
- package/Runtime/Code/Player/PlayerManagerBridge.cs +2 -1
- package/Runtime/Code/VoxelWorld/ChunkSerializer.cs +37 -30
- package/Runtime/Code/Zstd/Zstd.cs +85 -19
- package/Runtime/Plugins/Android/libLuauPlugin.so +0 -0
- package/Runtime/Plugins/Linux/libLuauPlugin.so +0 -0
- package/Runtime/Plugins/Mac/LuauPlugin.bundle/Contents/MacOS/LuauPlugin +0 -0
- package/Runtime/Plugins/Windows/x64/LuauPlugin.dll +0 -0
- package/Runtime/Plugins/Windows/x64/LuauPlugin.pdb +0 -0
- package/Runtime/Plugins/iOS/LuauPluginIos.a +0 -0
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// ReSharper disable InconsistentNaming
|
|
2
2
|
namespace Code {
|
|
3
3
|
public static class AirshipConst {
|
|
4
|
-
public const int playerVersion =
|
|
4
|
+
public const int playerVersion = 9;
|
|
5
5
|
|
|
6
6
|
/// <summary>
|
|
7
7
|
/// The server will kick clients that have a playerVersion lower than this value.
|
|
8
8
|
/// </summary>
|
|
9
|
-
public const int minAcceptedPlayerVersionOnServer =
|
|
9
|
+
public const int minAcceptedPlayerVersionOnServer = 9;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -205,14 +205,14 @@ namespace Code.Authentication {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
})).Then((res) => {
|
|
208
|
-
// print($"[Transfer Packet]
|
|
208
|
+
// print($"[Transfer Packet] {res.Text}");
|
|
209
209
|
string fullTransferPacket = res.Text;
|
|
210
210
|
TransferData transferData = JsonUtility.FromJson<TransferData>(fullTransferPacket);
|
|
211
211
|
tcs.SetResult(new UserData() {
|
|
212
212
|
uid = transferData.user.uid,
|
|
213
213
|
username = transferData.user.username,
|
|
214
214
|
profileImageId = transferData.user.profileImageId,
|
|
215
|
-
orgRoleName = transferData.
|
|
215
|
+
orgRoleName = transferData.orgRoleName,
|
|
216
216
|
fullTransferPacket = fullTransferPacket
|
|
217
217
|
});
|
|
218
218
|
}).Catch((err) => {
|
|
@@ -12,11 +12,11 @@ public class User {
|
|
|
12
12
|
public string usernameLower;
|
|
13
13
|
public string lastUsernameChangeTime;
|
|
14
14
|
public string profileImageId;
|
|
15
|
-
public string orgRoleName;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
[Serializable]
|
|
20
19
|
public class TransferData {
|
|
21
20
|
public User user;
|
|
21
|
+
public string orgRoleName;
|
|
22
22
|
}
|
|
@@ -1,14 +1,36 @@
|
|
|
1
1
|
using System;
|
|
2
|
+
using System.Buffers;
|
|
2
3
|
using System.Collections.Generic;
|
|
3
4
|
using System.IO;
|
|
4
5
|
using System.IO.Compression;
|
|
5
6
|
using Mirror;
|
|
6
7
|
using UnityEngine;
|
|
8
|
+
using UnityEngine.Profiling;
|
|
7
9
|
|
|
8
10
|
namespace Code.Bootstrap {
|
|
11
|
+
|
|
12
|
+
class CachedCompressedFile {
|
|
13
|
+
public byte[] compressedBytes;
|
|
14
|
+
public int compressedLength;
|
|
15
|
+
|
|
16
|
+
public CachedCompressedFile(byte[] compressedBytes, int compressedLength) {
|
|
17
|
+
this.compressedBytes = compressedBytes;
|
|
18
|
+
this.compressedLength = compressedLength;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
9
22
|
public static class LuauScriptsDtoSerializer {
|
|
23
|
+
private static Zstd.Zstd zstd = new(1024 * 4);
|
|
24
|
+
private static readonly Dictionary<string, CachedCompressedFile> compressedFileCache = new();
|
|
25
|
+
|
|
26
|
+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
27
|
+
private static void OnReload() {
|
|
28
|
+
compressedFileCache.Clear();
|
|
29
|
+
}
|
|
30
|
+
|
|
10
31
|
public static void WriteLuauScriptsDto(this NetworkWriter writer, LuauScriptsDto scripts) {
|
|
11
|
-
|
|
32
|
+
Profiler.BeginSample("WriteLuauScriptsDto");
|
|
33
|
+
writer.WriteInt(scripts.files.Count);
|
|
12
34
|
foreach (var pair in scripts.files) {
|
|
13
35
|
string packageId = pair.Key;
|
|
14
36
|
writer.WriteString(packageId);
|
|
@@ -16,22 +38,30 @@ namespace Code.Bootstrap {
|
|
|
16
38
|
foreach (var file in pair.Value) {
|
|
17
39
|
writer.WriteString(file.path);
|
|
18
40
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
41
|
+
string cacheId = $"{packageId}:{file.path}";
|
|
42
|
+
if (compressedFileCache.TryGetValue(cacheId, out var cache)) {
|
|
43
|
+
writer.WriteInt(cache.compressedLength);
|
|
44
|
+
writer.WriteBytes(cache.compressedBytes, 0, cache.compressedLength);
|
|
45
|
+
} else {
|
|
46
|
+
// Compress the byte array
|
|
47
|
+
Profiler.BeginSample("Luau Compress");
|
|
48
|
+
var maxCompressionSize = Zstd.Zstd.GetCompressionBound(file.bytes);
|
|
49
|
+
byte[] compressedBytes = new byte[maxCompressionSize];
|
|
50
|
+
var compressedSize = zstd.Compress(file.bytes, compressedBytes);
|
|
51
|
+
writer.WriteInt(compressedSize);
|
|
52
|
+
writer.WriteBytes(compressedBytes, 0, compressedSize);
|
|
53
|
+
|
|
54
|
+
compressedFileCache.Add(cacheId, new CachedCompressedFile(compressedBytes, compressedSize));
|
|
26
55
|
}
|
|
27
|
-
|
|
56
|
+
|
|
28
57
|
writer.WriteBool(file.airshipBehaviour);
|
|
58
|
+
Profiler.EndSample();
|
|
29
59
|
}
|
|
30
60
|
}
|
|
61
|
+
Profiler.EndSample();
|
|
31
62
|
}
|
|
32
63
|
|
|
33
64
|
public static LuauScriptsDto ReadLuauScriptsDto(this NetworkReader reader) {
|
|
34
|
-
var totalBytes = reader.Remaining;
|
|
35
65
|
LuauScriptsDto dto = new LuauScriptsDto();
|
|
36
66
|
int packagesLength = reader.ReadInt();
|
|
37
67
|
for (int pkgI = 0; pkgI < packagesLength; pkgI++) {
|
|
@@ -44,15 +74,14 @@ namespace Code.Bootstrap {
|
|
|
44
74
|
LuauFileDto script = new LuauFileDto();
|
|
45
75
|
script.path = reader.ReadString();
|
|
46
76
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
77
|
+
// Read the compressed bytes
|
|
78
|
+
var compressedBytesLen = reader.ReadInt();
|
|
79
|
+
byte[] compressedBytes = ArrayPool<byte>.Shared.Rent(compressedBytesLen);
|
|
80
|
+
reader.ReadBytes(compressedBytes, compressedBytesLen);
|
|
81
|
+
|
|
82
|
+
// Decompress the bytes
|
|
83
|
+
script.bytes = new byte[Zstd.Zstd.GetDecompressionBound(compressedBytes)];
|
|
84
|
+
zstd.Decompress(new ReadOnlySpan<byte>(compressedBytes, 0, compressedBytesLen), script.bytes);
|
|
56
85
|
|
|
57
86
|
script.airshipBehaviour = reader.ReadBool();
|
|
58
87
|
|
|
@@ -52,7 +52,8 @@
|
|
|
52
52
|
"GUID:325984b52e4128546bc7558552f8b1d2",
|
|
53
53
|
"GUID:3b5390adca4e2bb4791cb930316d6f3e",
|
|
54
54
|
"GUID:725ee7191c021de4dbf9269590ded755",
|
|
55
|
-
"GUID:2a0340569ab0e1245a38e0d6c7b2529b"
|
|
55
|
+
"GUID:2a0340569ab0e1245a38e0d6c7b2529b",
|
|
56
|
+
"GUID:befe48b9a36afc04ea625c93daad910e"
|
|
56
57
|
],
|
|
57
58
|
"includePlatforms": [],
|
|
58
59
|
"excludePlatforms": [],
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
using System;
|
|
2
|
-
using System.Diagnostics;
|
|
3
2
|
using System.IO;
|
|
4
3
|
using System.Threading.Tasks;
|
|
5
4
|
using Airship.DevConsole;
|
|
6
5
|
using Code.Http.Internal;
|
|
7
6
|
using Code.Platform.Shared;
|
|
8
|
-
using Code.
|
|
7
|
+
using Code.Player;
|
|
9
8
|
using JetBrains.Annotations;
|
|
10
9
|
using Mirror;
|
|
11
10
|
using UnityEngine;
|
|
@@ -56,6 +55,7 @@ namespace Code.Health
|
|
|
56
55
|
|
|
57
56
|
public struct StartServerProfileMessage : NetworkMessage {
|
|
58
57
|
public int DurationSecs;
|
|
58
|
+
public bool CallstacksEnabled;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
public struct ServerProfileCompleteMessage : NetworkMessage
|
|
@@ -88,13 +88,14 @@ namespace Code.Health
|
|
|
88
88
|
NetworkClient.RegisterHandler<ClientProfileUploadResponse>(OnClientUploadResponse);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
DevConsole.AddCommand(Command.Create<string, int>(
|
|
91
|
+
DevConsole.AddCommand(Command.Create<string, int, bool>(
|
|
92
92
|
"profile",
|
|
93
93
|
"",
|
|
94
94
|
"Starts and uploads a profile. Once complete the download link will be printed.",
|
|
95
95
|
Parameter.Create("Context", "Options: Server | Client"),
|
|
96
96
|
Parameter.Create("Duration", "Duration of profile in seconds (max 5s)"),
|
|
97
|
-
(
|
|
97
|
+
Parameter.Create("Callstacks", "Enable callstacks for profile (this is laggy)"),
|
|
98
|
+
(context, d, callstacks) => {
|
|
98
99
|
if (d is < 0 or > 5) {
|
|
99
100
|
Debug.LogError("You can only profile for a max of 5s.");
|
|
100
101
|
return;
|
|
@@ -106,10 +107,10 @@ namespace Code.Health
|
|
|
106
107
|
"Unable to capture profile log because debug mode is not enabled. Use the development build branch on Steam to enable debug mode.");
|
|
107
108
|
return;
|
|
108
109
|
}
|
|
109
|
-
StartProfiling(d, null);
|
|
110
|
+
StartProfiling(d, null, callstacks);
|
|
110
111
|
} else if (context.Equals("server", StringComparison.OrdinalIgnoreCase)) {
|
|
111
112
|
Debug.Log("Starting a server profile, view server console to monitor progress.");
|
|
112
|
-
NetworkClient.Send(new StartServerProfileMessage { DurationSecs = d });
|
|
113
|
+
NetworkClient.Send(new StartServerProfileMessage { DurationSecs = d, CallstacksEnabled = callstacks });
|
|
113
114
|
}
|
|
114
115
|
}));
|
|
115
116
|
}
|
|
@@ -142,8 +143,10 @@ namespace Code.Health
|
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
public void OnStartProfilingMessage(NetworkConnectionToClient sender, StartServerProfileMessage msg) {
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
var player = PlayerManagerBridge.Instance.GetPlayerInfoByConnectionId(sender.connectionId);
|
|
147
|
+
if (player.IsInGameOrg()) {
|
|
148
|
+
StartProfiling(msg.DurationSecs, sender, msg.CallstacksEnabled);
|
|
149
|
+
}
|
|
147
150
|
}
|
|
148
151
|
|
|
149
152
|
public async void OnServerProfileCompleteMessage(ServerProfileCompleteMessage msg)
|
|
@@ -163,7 +166,7 @@ namespace Code.Health
|
|
|
163
166
|
GUIUtility.systemCopyBuffer = data.url;
|
|
164
167
|
}
|
|
165
168
|
|
|
166
|
-
public void StartProfiling(int durationSecs, [CanBeNull] NetworkConnectionToClient profileInitiator) {
|
|
169
|
+
public void StartProfiling(int durationSecs, [CanBeNull] NetworkConnectionToClient profileInitiator, bool enableCallstacks) {
|
|
167
170
|
// TODO check that sender is game dev
|
|
168
171
|
// if (Profiler.enabled) {
|
|
169
172
|
// Debug.LogWarning("Profiler is already running.");
|
|
@@ -183,12 +186,14 @@ namespace Code.Health
|
|
|
183
186
|
|
|
184
187
|
Debug.Log($"Starting profiler for {durationSecs} seconds.");
|
|
185
188
|
Profiler.enabled = true;
|
|
189
|
+
Profiler.enableAllocationCallstacks = enableCallstacks;
|
|
186
190
|
StopProfilingAfterDelay(logPath, fileName, durationSecs, profileInitiator);
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
private async void StopProfilingAfterDelay(string logPath, string fileName, float durationSecs, [CanBeNull] NetworkConnectionToClient profileInitiator) {
|
|
190
194
|
await Task.Delay((int)(durationSecs * 1000));
|
|
191
195
|
Profiler.enabled = false;
|
|
196
|
+
Profiler.enableAllocationCallstacks = false;
|
|
192
197
|
var info = new FileInfo(logPath);
|
|
193
198
|
|
|
194
199
|
Debug.Log($"Profiling completed. Retrieving upload URL...");
|
|
@@ -173,8 +173,8 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
173
173
|
requirePathCallback = requirePathCallback_holder,
|
|
174
174
|
constructorCallback = constructorCallback_holder,
|
|
175
175
|
toStringCallback = toStringCallback_holder,
|
|
176
|
-
toggleProfilerCallback = toggleProfilerCallback_holder,
|
|
177
176
|
isObjectDestroyedCallback = isObjectDestroyedCallback_holder,
|
|
177
|
+
getUnityObjectNameCallback = getUnityObjectNameCallback_holder,
|
|
178
178
|
staticList = stringAddresses.AddrOfPinnedObject(),
|
|
179
179
|
staticCount = stringCount,
|
|
180
180
|
isServer = RunCore.IsServer() ? 1 : 0,
|
|
@@ -41,8 +41,8 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
41
41
|
private LuauPlugin.ConstructorCallback constructorCallback_holder;
|
|
42
42
|
private LuauPlugin.RequirePathCallback requirePathCallback_holder;
|
|
43
43
|
private LuauPlugin.ToStringCallback toStringCallback_holder;
|
|
44
|
-
private LuauPlugin.ToggleProfilerCallback toggleProfilerCallback_holder;
|
|
45
44
|
private LuauPlugin.IsObjectDestroyedCallback isObjectDestroyedCallback_holder;
|
|
45
|
+
private LuauPlugin.GetUnityObjectName getUnityObjectNameCallback_holder;
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
private struct AwaitingTask {
|
|
@@ -116,8 +116,8 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
116
116
|
requirePathCallback_holder = RequirePathCallback;
|
|
117
117
|
toStringCallback_holder = ToStringCallback;
|
|
118
118
|
componentSetEnabledCallback_holder = SetComponentEnabledCallback;
|
|
119
|
-
toggleProfilerCallback_holder = ToggleProfilerCallback;
|
|
120
119
|
isObjectDestroyedCallback_holder = IsObjectDestroyedCallback;
|
|
120
|
+
getUnityObjectNameCallback_holder = GetUnityObjectNameCallback;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
private static int LuauError(IntPtr thread, string err) {
|
|
@@ -190,41 +190,27 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
190
190
|
|
|
191
191
|
Marshal.Copy(bytes, 0, str, len);
|
|
192
192
|
}
|
|
193
|
-
|
|
194
|
-
[AOT.MonoPInvokeCallback(typeof(LuauPlugin.ToggleProfilerCallback))]
|
|
195
|
-
static void ToggleProfilerCallback(int componentId, IntPtr strPtr, int strLen) {
|
|
196
|
-
// Disable
|
|
197
|
-
if (componentId == -1) {
|
|
198
|
-
Profiler.EndSample();
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
// Not tagged to component
|
|
202
|
-
if (componentId < -1) {
|
|
203
|
-
if (strLen > 0) {
|
|
204
|
-
// No need to free strPtr -- it is stack allocated
|
|
205
|
-
var str = PtrToStringUTF8(strPtr, strLen);
|
|
206
|
-
Profiler.BeginSample($"{str}");
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (AirshipComponent.ComponentIdToScriptName.TryGetValue(componentId, out var componentName)) {
|
|
213
|
-
if (strLen > 0) {
|
|
214
|
-
var str = PtrToStringUTF8(strPtr, strLen);
|
|
215
|
-
Profiler.BeginSample($"{componentName}{str}");
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
Profiler.BeginSample($"{componentName}");
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
193
|
|
|
223
194
|
[AOT.MonoPInvokeCallback(typeof(LuauPlugin.IsObjectDestroyedCallback))]
|
|
224
195
|
static int IsObjectDestroyedCallback(int instanceId) {
|
|
225
196
|
return ThreadDataManager.IsUnityObjectReferenceDestroyed(instanceId) ? 1 : 0;
|
|
226
197
|
}
|
|
227
198
|
|
|
199
|
+
[AOT.MonoPInvokeCallback(typeof(LuauPlugin.GetUnityObjectName))]
|
|
200
|
+
static void GetUnityObjectNameCallback(IntPtr thread, int instanceId, IntPtr str, int maxLen, out int len) {
|
|
201
|
+
var obj = ThreadDataManager.GetObjectReference(thread, instanceId, true, true);
|
|
202
|
+
if (obj is UnityEngine.Object unityObj) {
|
|
203
|
+
var n = unityObj.name;
|
|
204
|
+
var bytes = Encoding.UTF8.GetBytes(n);
|
|
205
|
+
len = bytes.Length > maxLen ? maxLen : bytes.Length;
|
|
206
|
+
Marshal.Copy(bytes, 0, str, len);
|
|
207
|
+
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
len = 0;
|
|
212
|
+
}
|
|
213
|
+
|
|
228
214
|
//when a lua thread gc releases an object, make sure our GC knows too
|
|
229
215
|
[AOT.MonoPInvokeCallback(typeof(LuauPlugin.ObjectGCCallback))]
|
|
230
216
|
static unsafe int ObjectGcCallback(int instanceId, IntPtr objectDebugPointer) {
|
|
@@ -713,16 +699,22 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
713
699
|
private static int GetPropertySafeCallback(LuauContext context, IntPtr thread, int instanceId, IntPtr classNamePtr, int classNameSize, IntPtr propertyName, int propertyNameLength) {
|
|
714
700
|
var ret = 0;
|
|
715
701
|
try {
|
|
716
|
-
|
|
717
|
-
|
|
702
|
+
Profiler.BeginSample("GetProperty");
|
|
703
|
+
ret = GetProperty(context, thread, instanceId, classNamePtr, classNameSize, propertyName,
|
|
704
|
+
propertyNameLength);
|
|
705
|
+
}
|
|
706
|
+
catch (Exception e) {
|
|
718
707
|
ret = LuauError(thread, e.Message);
|
|
708
|
+
} finally {
|
|
709
|
+
Profiler.EndSample();
|
|
719
710
|
}
|
|
720
711
|
|
|
721
712
|
return ret;
|
|
722
713
|
}
|
|
723
714
|
|
|
715
|
+
// private static readonly ProfilerMarker<string> getPropertyMarker = new ProfilerMarker<string>("LuauCore.GetProperty", "asd");
|
|
716
|
+
|
|
724
717
|
private static int GetProperty(LuauContext context, IntPtr thread, int instanceId, IntPtr classNamePtr, int classNameSize, IntPtr propertyName, int propertyNameLength) {
|
|
725
|
-
Profiler.BeginSample("LuauCore.GetProperty");
|
|
726
718
|
CurrentContext = context;
|
|
727
719
|
|
|
728
720
|
string propName = LuauCore.PtrToStringUTF8(propertyName, propertyNameLength, out ulong propNameHash);
|
|
@@ -756,14 +748,12 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
756
748
|
// Type t = propertyInfo.PropertyType;
|
|
757
749
|
System.Object value = cacheData.Value.propertyInfo.GetValue(null);
|
|
758
750
|
WritePropertyToThread(thread, value, cacheData.Value.t);
|
|
759
|
-
Profiler.EndSample();
|
|
760
751
|
return 1;
|
|
761
752
|
}
|
|
762
753
|
|
|
763
754
|
// Get C# event:
|
|
764
755
|
var eventInfo = objectType.GetRuntimeEvent(propName);
|
|
765
756
|
if (eventInfo != null) {
|
|
766
|
-
Profiler.EndSample();
|
|
767
757
|
return LuauSignalWrapper.HandleCsEvent(context, thread, staticClassApi, instanceId, propNameHash,
|
|
768
758
|
eventInfo, true);
|
|
769
759
|
}
|
|
@@ -774,11 +764,9 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
774
764
|
Type t = fieldInfo.FieldType;
|
|
775
765
|
System.Object value = fieldInfo.GetValue(null);
|
|
776
766
|
WritePropertyToThread(thread, value, t);
|
|
777
|
-
Profiler.EndSample();
|
|
778
767
|
return 1;
|
|
779
768
|
}
|
|
780
769
|
|
|
781
|
-
Profiler.EndSample();
|
|
782
770
|
return LuauError(thread, "ERROR - " + propName + " get property not found on class " + staticClassName);
|
|
783
771
|
}
|
|
784
772
|
else {
|
|
@@ -788,7 +776,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
788
776
|
System.Object objectReference = ThreadDataManager.GetObjectReference(thread, instanceId);
|
|
789
777
|
// Profiler.EndSample();
|
|
790
778
|
if (objectReference == null) {
|
|
791
|
-
Profiler.EndSample();
|
|
792
779
|
return LuauError(thread,
|
|
793
780
|
"Error: InstanceId not currently available:" + instanceId + ". propName=" + propName);
|
|
794
781
|
}
|
|
@@ -801,7 +788,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
801
788
|
if (objectReference is GameObject targetGo) {
|
|
802
789
|
// var target = (GameObject)objectReference;
|
|
803
790
|
if (IsAccessBlocked(context, targetGo)) {
|
|
804
|
-
Profiler.EndSample();
|
|
805
791
|
return LuauError(thread,
|
|
806
792
|
"[Airship] Access denied when trying to read " + targetGo.name + ".");
|
|
807
793
|
}
|
|
@@ -809,7 +795,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
809
795
|
else if (sourceType.IsAssignableFrom(typeof(Component))) {
|
|
810
796
|
var target = (Component)objectReference;
|
|
811
797
|
if (target && IsAccessBlocked(context, target.gameObject)) {
|
|
812
|
-
Profiler.EndSample();
|
|
813
798
|
return LuauError(thread,
|
|
814
799
|
"[Airship] Access denied when trying to read " + target.name + ".");
|
|
815
800
|
}
|
|
@@ -821,7 +806,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
821
806
|
if (valueTypeAPI != null) {
|
|
822
807
|
var retValue = valueTypeAPI.OverrideMemberGetter(context, thread, objectReference, propName);
|
|
823
808
|
if (retValue >= 0) {
|
|
824
|
-
Profiler.EndSample();
|
|
825
809
|
return retValue;
|
|
826
810
|
}
|
|
827
811
|
}
|
|
@@ -841,7 +825,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
841
825
|
try {
|
|
842
826
|
// Try a fast write on value type (Vector3, int, etc. Not objects)
|
|
843
827
|
if (FastGetAndWriteValueProperty(thread, objectReference, cacheData.Value)) {
|
|
844
|
-
Profiler.EndSample();
|
|
845
828
|
return 1;
|
|
846
829
|
}
|
|
847
830
|
|
|
@@ -876,16 +859,11 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
876
859
|
}
|
|
877
860
|
}
|
|
878
861
|
|
|
879
|
-
// Profiler.BeginSample("WriteToThread");
|
|
880
862
|
WritePropertyToThread(thread, value, t);
|
|
881
|
-
// Profiler.EndSample();
|
|
882
|
-
Profiler.EndSample();
|
|
883
863
|
return 1;
|
|
884
864
|
}
|
|
885
865
|
else {
|
|
886
|
-
// Debug.Log("Value was null in dictionary. propName=" + propName + ", object=" + sourceType.Name);
|
|
887
866
|
WritePropertyToThread(thread, null, null);
|
|
888
|
-
Profiler.EndSample();
|
|
889
867
|
return 1;
|
|
890
868
|
}
|
|
891
869
|
}
|
|
@@ -902,11 +880,8 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
902
880
|
// If we failed to get a reference to a non-primitive, just assume a null value (write nil to the stack):
|
|
903
881
|
if (!cacheData.Value.propertyInfo.PropertyType.IsPrimitive) {
|
|
904
882
|
WritePropertyToThread(thread, null, null);
|
|
905
|
-
Profiler.EndSample();
|
|
906
883
|
return 1;
|
|
907
884
|
}
|
|
908
|
-
|
|
909
|
-
Profiler.EndSample();
|
|
910
885
|
return LuauError(thread, "Failed to get property in dictionary. propName=" + propName +
|
|
911
886
|
", object=" +
|
|
912
887
|
sourceType.Name + ", msg=" + e.Message);
|
|
@@ -936,7 +911,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
936
911
|
// print("key: " + propName + " " + keyInt);
|
|
937
912
|
// Debug.Log("[Luau]: Dictionary had key but value was null. propName=" + propName + ", sourceType=" + sourceType.Name + ", obj=" + objectReference);
|
|
938
913
|
WritePropertyToThread(thread, null, null);
|
|
939
|
-
Profiler.EndSample();
|
|
940
914
|
return 1;
|
|
941
915
|
}
|
|
942
916
|
|
|
@@ -944,14 +918,12 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
944
918
|
object value = dict[propName];
|
|
945
919
|
Type t = value.GetType();
|
|
946
920
|
WritePropertyToThread(thread, value, t);
|
|
947
|
-
Profiler.EndSample();
|
|
948
921
|
return 1;
|
|
949
922
|
}
|
|
950
923
|
else {
|
|
951
924
|
// Debug.Log("[Luau]: Dictionary was found but key was not found. propName=" + propName +
|
|
952
925
|
// ", sourceType=" + sourceType.Name);
|
|
953
926
|
WritePropertyToThread(thread, null, null);
|
|
954
|
-
Profiler.EndSample();
|
|
955
927
|
return 1;
|
|
956
928
|
}
|
|
957
929
|
}
|
|
@@ -959,7 +931,6 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
959
931
|
// Get C# event:
|
|
960
932
|
var eventInfo = sourceType.GetRuntimeEvent(propName);
|
|
961
933
|
if (eventInfo != null) {
|
|
962
|
-
Profiler.EndSample();
|
|
963
934
|
return LuauSignalWrapper.HandleCsEvent(context, thread, objectReference, instanceId, propNameHash,
|
|
964
935
|
eventInfo, false);
|
|
965
936
|
}
|
|
@@ -970,11 +941,9 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
970
941
|
Type t = field.FieldType;
|
|
971
942
|
System.Object value = field.GetValue(objectReference);
|
|
972
943
|
WritePropertyToThread(thread, value, t);
|
|
973
|
-
Profiler.EndSample();
|
|
974
944
|
return 1;
|
|
975
945
|
}
|
|
976
946
|
|
|
977
|
-
Profiler.EndSample();
|
|
978
947
|
return LuauError(thread, $"ERROR - ({sourceType.Name}).{propName} property/field not found");
|
|
979
948
|
}
|
|
980
949
|
}
|
|
@@ -22,8 +22,8 @@ public static class LuauPlugin {
|
|
|
22
22
|
public delegate void RequirePathCallback(LuauContext context, IntPtr thread, IntPtr scriptName, int scriptNameLen, IntPtr fileName, int fileNameLen);
|
|
23
23
|
public delegate void ToStringCallback(IntPtr thread, int instanceId, IntPtr str, int maxLen, out int len);
|
|
24
24
|
public delegate void ComponentSetEnabledCallback(IntPtr thread, int instanceId, int componentId, int enabled);
|
|
25
|
-
public delegate void ToggleProfilerCallback(int componentId, IntPtr str, int strLen);
|
|
26
25
|
public delegate int IsObjectDestroyedCallback(int instanceId);
|
|
26
|
+
public delegate void GetUnityObjectName(IntPtr thread, int instanceId, IntPtr str, int maxLen, out int len);
|
|
27
27
|
|
|
28
28
|
public static int unityMainThreadId = -1;
|
|
29
29
|
public static bool s_currentlyExecuting = false;
|
|
@@ -62,8 +62,8 @@ public static class LuauPlugin {
|
|
|
62
62
|
public RequirePathCallback requirePathCallback;
|
|
63
63
|
public ConstructorCallback constructorCallback;
|
|
64
64
|
public ToStringCallback toStringCallback;
|
|
65
|
-
public ToggleProfilerCallback toggleProfilerCallback;
|
|
66
65
|
public IsObjectDestroyedCallback isObjectDestroyedCallback;
|
|
66
|
+
public GetUnityObjectName getUnityObjectNameCallback;
|
|
67
67
|
|
|
68
68
|
public IntPtr staticList;
|
|
69
69
|
public int staticCount;
|
|
@@ -35,7 +35,9 @@ namespace Code.RemoteConsole {
|
|
|
35
35
|
private Task writeTask;
|
|
36
36
|
|
|
37
37
|
private void Awake() {
|
|
38
|
-
|
|
38
|
+
if (RunCore.IsClient() && !RunCore.IsServer()) {
|
|
39
|
+
writeTask = Task.Run(ProcessQueue);
|
|
40
|
+
}
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
private async Task ProcessQueue() {
|
|
@@ -74,8 +76,11 @@ namespace Code.RemoteConsole {
|
|
|
74
76
|
Application.logMessageReceived += LogCallback;
|
|
75
77
|
}
|
|
76
78
|
NetworkServer.RegisterHandler<RequestServerConsoleStartupLogs>((conn, data) => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
var player = PlayerManagerBridge.Instance.GetPlayerInfoByConnectionId(conn.connectionId);
|
|
80
|
+
if (player.IsInGameOrg()) {
|
|
81
|
+
foreach (var startupMessage in startupMessages) {
|
|
82
|
+
conn.Send(startupMessage);
|
|
83
|
+
}
|
|
79
84
|
}
|
|
80
85
|
}, false);
|
|
81
86
|
}
|
|
@@ -127,7 +132,10 @@ namespace Code.RemoteConsole {
|
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
private void SendServerLogMessage(string message, LogType logType = LogType.Log, string stackTrace = "") {
|
|
130
|
-
if (RunCore.
|
|
135
|
+
if (RunCore.IsEditor()) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (RunCore.IsServer()) {
|
|
131
139
|
var time = DateTime.Now.ToString("HH:mm:ss");
|
|
132
140
|
if (this.startupMessages.Count < maxStartupMessages) {
|
|
133
141
|
this.startupMessages.Add(new ServerConsoleBroadcast() {
|
|
@@ -147,10 +155,9 @@ namespace Code.RemoteConsole {
|
|
|
147
155
|
stackTrace = stackTrace,
|
|
148
156
|
time = time,
|
|
149
157
|
};
|
|
150
|
-
// bool sendToReadyOnly = Application.isEditor;
|
|
151
158
|
foreach (var player in PlayerManagerBridge.Instance.players) {
|
|
152
|
-
if (
|
|
153
|
-
player.connectionToClient.Send(packet
|
|
159
|
+
if (player.IsInGameOrg()) {
|
|
160
|
+
player.connectionToClient.Send(packet);
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
}
|
|
@@ -412,12 +412,13 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
412
412
|
// If we have transitioned to airborne
|
|
413
413
|
if (!grounded && currentMoveSnapshot.isGrounded) {
|
|
414
414
|
// Set canJump to the number of ticks of coyote time we have
|
|
415
|
-
currentMoveSnapshot.canJump
|
|
415
|
+
currentMoveSnapshot.canJump
|
|
416
|
+
= (byte)Math.Min(Math.Floor(movementSettings.jumpCoyoteTime / Time.fixedDeltaTime), 255);
|
|
416
417
|
}
|
|
417
418
|
|
|
418
419
|
if (!grounded && !currentMoveSnapshot.isGrounded) {
|
|
419
420
|
// If we've now ticked once in the air, remove a tick of canJump time.
|
|
420
|
-
currentMoveSnapshot.canJump = (byte)
|
|
421
|
+
currentMoveSnapshot.canJump = (byte)Math.Max(currentMoveSnapshot.canJump - 1, 0);
|
|
421
422
|
}
|
|
422
423
|
|
|
423
424
|
var groundSlopeDir = detectedGround
|
|
@@ -474,7 +475,7 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
474
475
|
// currentMoveSnapshot.timeSinceWasGrounded <= movementSettings.jumpCoyoteTime &&
|
|
475
476
|
// currentMoveSnapshot.timeSinceJump > movementSettings.jumpCoyoteTime
|
|
476
477
|
currentMoveSnapshot.canJump > 0
|
|
477
|
-
|
|
478
|
+
) {
|
|
478
479
|
canJump = true;
|
|
479
480
|
}
|
|
480
481
|
//the first jump requires grounded, so if in the air bump the currentMoveState.jumpCount up
|
|
@@ -575,7 +576,7 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
575
576
|
currentMoveSnapshot.isSprinting = false;
|
|
576
577
|
}
|
|
577
578
|
|
|
578
|
-
|
|
579
|
+
#region CROUCH
|
|
579
580
|
|
|
580
581
|
// Prevent falling off blocks while crouching
|
|
581
582
|
currentMoveSnapshot.isCrouching = groundedState == CharacterState.Crouching;
|
|
@@ -610,7 +611,7 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
610
611
|
}
|
|
611
612
|
}
|
|
612
613
|
|
|
613
|
-
|
|
614
|
+
#endregion
|
|
614
615
|
|
|
615
616
|
// Modify colliders size based on movement state
|
|
616
617
|
var offsetExtent = movementSettings.colliderGroundOffset / 2;
|
|
@@ -826,8 +827,7 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
826
827
|
Debug.DrawLine(checkPoint, rayTestHit.point, Color.magenta);
|
|
827
828
|
GizmoUtils.DrawSphere(rayTestHit.point, .15f, Color.magenta);
|
|
828
829
|
}
|
|
829
|
-
}
|
|
830
|
-
else if (drawDebugGizmos_WALLCLIPPING) {
|
|
830
|
+
} else if (drawDebugGizmos_WALLCLIPPING) {
|
|
831
831
|
GizmoUtils.DrawSphere(checkPoint, .05f, Color.white);
|
|
832
832
|
Debug.DrawLine(checkPoint, checkPoint + (forwardHit.point - checkPoint), Color.white);
|
|
833
833
|
}
|
|
@@ -978,7 +978,9 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
978
978
|
var didStepUp = false;
|
|
979
979
|
if (movementSettings.detectStepUps && //Want to check step ups
|
|
980
980
|
(!command.crouch || !movementSettings.preventStepUpWhileCrouching) && //Not blocked by crouch
|
|
981
|
-
(movementSettings.assistedLedgeJump ||
|
|
981
|
+
(movementSettings.assistedLedgeJump ||
|
|
982
|
+
currentMoveSnapshot.canJump >
|
|
983
|
+
0) && //Grounded // Used to be currentMoveSnapshot.timeSinceBecameGrounded > .05
|
|
982
984
|
Mathf.Abs(newVelocity.x) + Mathf.Abs(newVelocity.z) > .05f) {
|
|
983
985
|
//Moveing
|
|
984
986
|
var (hitStepUp, onRamp, pointOnRamp, stepUpVel) = physics.StepUp(rootPosition,
|
|
@@ -1015,12 +1017,13 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1015
1017
|
// Prevent falling off blocks while crouching
|
|
1016
1018
|
if (movementSettings.preventFallingWhileCrouching && !currentMoveSnapshot.prevStepUp &&
|
|
1017
1019
|
currentMoveSnapshot.isCrouching && !didJump && grounded) {
|
|
1018
|
-
var distanceCheck = movementSettings.characterRadius *
|
|
1020
|
+
var distanceCheck = movementSettings.characterRadius * 3 + newVelocity.magnitude * deltaTime;
|
|
1019
1021
|
var normalizedVel = newVelocity.normalized;
|
|
1020
1022
|
var projectedPosition = rootPosition + normalizedVel * distanceCheck;
|
|
1021
1023
|
if (drawDebugGizmos_CROUCH) {
|
|
1022
1024
|
GizmoUtils.DrawSphere(projectedPosition, .1f, Color.blue, 4, .1f);
|
|
1023
1025
|
}
|
|
1026
|
+
|
|
1024
1027
|
var (groundedInMoveDirection, _, _) =
|
|
1025
1028
|
physics.CheckIfGrounded(projectedPosition, newVelocity, normalizedVel);
|
|
1026
1029
|
var foundGroundedDir = false;
|
|
@@ -1035,7 +1038,6 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1035
1038
|
if (Physics.Raycast(projectedPosition + new Vector3(0, -.25f, 0), -normalizedVel,
|
|
1036
1039
|
out var cliffHit, distanceCheck,
|
|
1037
1040
|
movementSettings.groundCollisionLayerMask, QueryTriggerInteraction.Ignore)) {
|
|
1038
|
-
|
|
1039
1041
|
if (drawDebugGizmos_CROUCH) {
|
|
1040
1042
|
GizmoUtils.DrawSphere(cliffHit.point, .1f, Color.red, 4, .1f);
|
|
1041
1043
|
}
|
|
@@ -1052,21 +1054,34 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1052
1054
|
var flatPoint = new Vector3(cliffHit.point.x, transform.position.y, cliffHit.point.z);
|
|
1053
1055
|
//If we are too close to the edge or if there is an obstruction in the way
|
|
1054
1056
|
if (Vector3.Distance(flatPoint, transform.position) < bumpSize - forwardMargin
|
|
1055
|
-
|| Physics.Raycast(transform.position + new Vector3(0
|
|
1057
|
+
|| Physics.Raycast(transform.position + new Vector3(0, .25f, 0), newVelocity, distanceCheck,
|
|
1058
|
+
movementSettings.groundCollisionLayerMask)) {
|
|
1056
1059
|
//Snap back to the bump distance so you never inch your way to the edge
|
|
1057
1060
|
//newVelocity = new Vector3(0, newVelocity.y, 0);
|
|
1058
1061
|
//var newPos = cliffHit.point - normalizedVel * (bumpSize-forwardMargin);
|
|
1059
1062
|
//transform.position = new Vector3(newPos.x, transform.position.y, newPos.z);
|
|
1060
|
-
|
|
1061
|
-
newVelocity = -
|
|
1063
|
+
|
|
1064
|
+
newVelocity = -cliffHit.normal;
|
|
1062
1065
|
} else {
|
|
1063
1066
|
//limit movement dir based on how straight you are walking into the edge
|
|
1064
|
-
characterMoveVelocity = Vector3.ProjectOnPlane(characterMoveVelocity, -cliffHit.normal);
|
|
1065
|
-
characterMoveVelocity.y = 0;
|
|
1066
|
-
characterMoveVelocity *= colliderDot;
|
|
1067
|
-
normalizedMoveDir = characterMoveVelocity.normalized;
|
|
1067
|
+
// characterMoveVelocity = Vector3.ProjectOnPlane(characterMoveVelocity, -cliffHit.normal);
|
|
1068
|
+
// characterMoveVelocity.y = 0;
|
|
1069
|
+
// characterMoveVelocity *= colliderDot;
|
|
1070
|
+
// normalizedMoveDir = characterMoveVelocity.normalized;
|
|
1068
1071
|
|
|
1069
1072
|
newVelocity -= colliderDot * -cliffHit.normal;
|
|
1073
|
+
//newVelocity *= Mathf.Max(0, -colliderDot);
|
|
1074
|
+
if (newVelocity.sqrMagnitude < 2f) {
|
|
1075
|
+
newVelocity = Vector3.zero;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
//With this new velocity are we going to fall off a different ledge?
|
|
1079
|
+
if (!Physics.Raycast(
|
|
1080
|
+
new Vector3(0, 1.25f, 0) + transform.position +
|
|
1081
|
+
newVelocity.normalized * distanceCheck, Vector3.down, 1.5f)) {
|
|
1082
|
+
//Nothing in the direction of the new velocity
|
|
1083
|
+
newVelocity = Vector3.zero;
|
|
1084
|
+
}
|
|
1070
1085
|
//newVelocity *= colliderDot;
|
|
1071
1086
|
}
|
|
1072
1087
|
}
|
|
@@ -1076,23 +1091,25 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1076
1091
|
#endregion
|
|
1077
1092
|
|
|
1078
1093
|
#region APPLY FORCES
|
|
1094
|
+
|
|
1079
1095
|
//Stop character from moveing into colliders (Helps prevent axis aligned box colliders from colliding when they shouldn't like jumping in a voxel world)
|
|
1080
1096
|
if (movementSettings.preventWallClipping && !currentMoveSnapshot.prevStepUp) {
|
|
1081
1097
|
var velY = newVelocity.y;
|
|
1082
1098
|
flatVelocity = new Vector3(newVelocity.x, 0, newVelocity.z);
|
|
1083
|
-
var minDistance =
|
|
1099
|
+
var minDistance = characterRadius + forwardMargin;
|
|
1084
1100
|
var forwardDistance = Mathf.Max(flatVelocity.magnitude * deltaTime, minDistance);
|
|
1085
1101
|
var forwardVector = flatVelocity.normalized * Mathf.Max(forwardDistance, bumpSize);
|
|
1086
1102
|
//print("Forward vec: " + forwardVector);
|
|
1087
1103
|
|
|
1088
1104
|
//Do raycasting after we have claculated our move direction
|
|
1089
1105
|
var forwardHits =
|
|
1090
|
-
physics.CheckAllForwardHits(rootPosition - flatVelocity.normalized * -forwardMargin, forwardVector,
|
|
1106
|
+
physics.CheckAllForwardHits(rootPosition - flatVelocity.normalized * -forwardMargin, forwardVector,
|
|
1107
|
+
true,
|
|
1091
1108
|
true);
|
|
1092
1109
|
|
|
1093
1110
|
float i = 0;
|
|
1094
|
-
|
|
1095
|
-
|
|
1111
|
+
var label = "ForwardHitCounts: " + forwardHits.Length + "\n";
|
|
1112
|
+
var forcedCount = 0;
|
|
1096
1113
|
foreach (var forwardHitResult in forwardHits) {
|
|
1097
1114
|
label += "Hit " + i + " Point: " + forwardHitResult.point + " Normal: " + forwardHitResult.normal;
|
|
1098
1115
|
//Check if this is a valid wall and not something behind a surface
|
|
@@ -1112,7 +1129,8 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1112
1129
|
}
|
|
1113
1130
|
|
|
1114
1131
|
var checkDir = (forwardHit.point - checkPoint).normalized;
|
|
1115
|
-
var checkDistance = forwardMargin +
|
|
1132
|
+
var checkDistance = forwardMargin +
|
|
1133
|
+
Mathf.Max(forwardHit.distance, movementSettings.characterRadius * 2);
|
|
1116
1134
|
if (Physics.Raycast(checkPoint, checkDir,
|
|
1117
1135
|
out var rayTestHit, checkDistance,
|
|
1118
1136
|
movementSettings.groundCollisionLayerMask, QueryTriggerInteraction.Ignore)) {
|
|
@@ -1150,24 +1168,24 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1150
1168
|
//|| forwardHit.distance < bumpSize) {
|
|
1151
1169
|
colliderDot = 0;
|
|
1152
1170
|
}
|
|
1153
|
-
|
|
1171
|
+
|
|
1154
1172
|
// flatVelocity = Vector3.ClampMagnitude(newVelocity,
|
|
1155
1173
|
// forwardHit.distance - characterRadius - forwardMargin);
|
|
1156
1174
|
// //print("FLAT VEL: " + flatVelocity);
|
|
1157
1175
|
// newVelocity.x -= flatVelocity.x;
|
|
1158
1176
|
// newVelocity.z -= flatVelocity.z;
|
|
1159
|
-
|
|
1177
|
+
|
|
1160
1178
|
var flatPoint = new Vector3(forwardHit.point.x, transform.position.y, forwardHit.point.z);
|
|
1161
1179
|
if (Vector3.Distance(flatPoint, transform.position) < minDistance) {
|
|
1162
1180
|
//Snap back to the bump distance so you never inch your way to the edge
|
|
1163
|
-
var newPos = forwardHit.point + forwardHit.normal * (bumpSize+forwardMargin);
|
|
1181
|
+
var newPos = forwardHit.point + forwardHit.normal * (bumpSize + forwardMargin);
|
|
1164
1182
|
if (forcedCount == 0) {
|
|
1165
1183
|
transform.position = new Vector3(newPos.x, transform.position.y, newPos.z);
|
|
1166
1184
|
} else {
|
|
1167
1185
|
transform.position = new Vector3(
|
|
1168
|
-
(transform.position.x + newPos.x) /2f,
|
|
1169
|
-
transform.position.y,
|
|
1170
|
-
(transform.position.z + newPos.z) /2f);
|
|
1186
|
+
(transform.position.x + newPos.x) / 2f,
|
|
1187
|
+
transform.position.y,
|
|
1188
|
+
(transform.position.z + newPos.z) / 2f);
|
|
1171
1189
|
}
|
|
1172
1190
|
|
|
1173
1191
|
forcedCount++;
|
|
@@ -1175,10 +1193,9 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1175
1193
|
|
|
1176
1194
|
// var normalVel = forwardHit.normal * (Math.Abs(newVelocity.x) + Math.Abs(newVelocity.z));
|
|
1177
1195
|
// newVelocity = new Vector3(normalVel.x, velY , normalVel.z);
|
|
1178
|
-
} else {
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
newVelocity = Vector3.ProjectOnPlane( flatVelocity, forwardHit.normal);
|
|
1196
|
+
} else { }
|
|
1197
|
+
|
|
1198
|
+
newVelocity = Vector3.ProjectOnPlane(flatVelocity, forwardHit.normal);
|
|
1182
1199
|
//newVelocity.y = 0;
|
|
1183
1200
|
newVelocity *= colliderDot * .9f;
|
|
1184
1201
|
newVelocity.y = velY;
|
|
@@ -1565,7 +1582,7 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1565
1582
|
|
|
1566
1583
|
// TS listens to this to update the local camera.
|
|
1567
1584
|
// Position will update from reconcile, but we handle look direction manually.
|
|
1568
|
-
if (mode == NetworkedStateSystemMode.Authority && isServer && !
|
|
1585
|
+
if (mode == NetworkedStateSystemMode.Authority && isServer && !manager.serverGeneratesCommands) {
|
|
1569
1586
|
RpcSetLookVector(lookVector);
|
|
1570
1587
|
}
|
|
1571
1588
|
|
|
@@ -1782,4 +1799,4 @@ namespace Code.Player.Character.MovementSystems.Character {
|
|
|
1782
1799
|
|
|
1783
1800
|
#endregion
|
|
1784
1801
|
}
|
|
1785
|
-
}
|
|
1802
|
+
}
|
|
@@ -59,6 +59,10 @@ public class PlayerInfo : NetworkBehaviour {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
public bool IsInGameOrg() {
|
|
63
|
+
return !string.IsNullOrEmpty(this.orgRoleName);
|
|
64
|
+
}
|
|
65
|
+
|
|
62
66
|
public override void OnStopServer() {
|
|
63
67
|
PlayerManagerBridge.Instance.HandlePlayerLeave(this);
|
|
64
68
|
base.OnStopServer();
|
|
@@ -115,7 +115,7 @@ namespace Code.Player {
|
|
|
115
115
|
Debug.Log($"Players ({this.players.Count}):");
|
|
116
116
|
int i = 1;
|
|
117
117
|
foreach (var player in this.players) {
|
|
118
|
-
Debug.Log($" {i}. {player.username} - connectionId: {player.connectionId}, userId: {player.userId}");
|
|
118
|
+
Debug.Log($" {i}. {player.username} - connectionId: {player.connectionId}, userId: {player.userId}, orgRole: {player.orgRoleName}");
|
|
119
119
|
i++;
|
|
120
120
|
}
|
|
121
121
|
}));
|
|
@@ -167,6 +167,7 @@ namespace Code.Player {
|
|
|
167
167
|
|
|
168
168
|
private void OnDestroy() {
|
|
169
169
|
NetworkServer.OnConnectedEvent -= NetworkServer_OnConnected;
|
|
170
|
+
DevConsole.RemoveCommand("players");
|
|
170
171
|
}
|
|
171
172
|
|
|
172
173
|
public void AddBotPlayer(string username, string userId, string profilePictureId) {
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
using System;
|
|
2
|
-
using System.
|
|
3
|
-
using
|
|
2
|
+
using System.Buffers;
|
|
3
|
+
using Code.Zstd;
|
|
4
4
|
using Mirror;
|
|
5
5
|
using UnityEngine;
|
|
6
|
+
using UnityEngine.Profiling;
|
|
6
7
|
using VoxelWorldStuff;
|
|
7
8
|
|
|
8
9
|
public static class ChunkSerializer {
|
|
10
|
+
private static Zstd zstd = new Zstd(1024 * 4);
|
|
9
11
|
|
|
10
12
|
public static void WriteChunk(this NetworkWriter writer, Chunk value) {
|
|
13
|
+
Profiler.BeginSample("WriteChunk");
|
|
11
14
|
Vector3Int key = value.GetKey();
|
|
12
15
|
|
|
13
16
|
writer.WriteVector3Int(key);
|
|
@@ -15,25 +18,29 @@ public static class ChunkSerializer {
|
|
|
15
18
|
var voxelDataLengthBytes = value.readWriteVoxel.Length * sizeof(short);
|
|
16
19
|
var colDataLengthBytes = value.color.Length * sizeof(uint);
|
|
17
20
|
|
|
21
|
+
// Keep track of uncompressed byte size of voxels and colors:
|
|
18
22
|
writer.WriteInt(voxelDataLengthBytes);
|
|
19
23
|
writer.WriteInt(colDataLengthBytes);
|
|
20
24
|
|
|
21
25
|
// Input byte array
|
|
22
|
-
byte[]
|
|
23
|
-
Buffer.BlockCopy(value.readWriteVoxel, 0,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
byte[] voxelByteAndColorArray = ArrayPool<byte>.Shared.Rent(voxelDataLengthBytes + colDataLengthBytes);
|
|
27
|
+
Buffer.BlockCopy(value.readWriteVoxel, 0, voxelByteAndColorArray, 0, voxelDataLengthBytes);
|
|
28
|
+
Buffer.BlockCopy(value.color, 0, voxelByteAndColorArray, voxelDataLengthBytes, colDataLengthBytes);
|
|
29
|
+
|
|
27
30
|
// Compress the byte array
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
Profiler.BeginSample("WriteChunk.Compress");
|
|
32
|
+
|
|
33
|
+
var maxCompressionSize = Zstd.GetCompressionBound(voxelByteAndColorArray);
|
|
34
|
+
var compressionBuffer = ArrayPool<byte>.Shared.Rent(maxCompressionSize);
|
|
35
|
+
var voxelDataCompressedSize = zstd.Compress(voxelByteAndColorArray, compressionBuffer);
|
|
36
|
+
writer.WriteInt(voxelDataCompressedSize);
|
|
37
|
+
writer.WriteBytes(compressionBuffer, 0, voxelDataCompressedSize);
|
|
38
|
+
|
|
39
|
+
ArrayPool<byte>.Shared.Return(voxelByteAndColorArray);
|
|
40
|
+
ArrayPool<byte>.Shared.Return(compressionBuffer);
|
|
41
|
+
|
|
42
|
+
Profiler.EndSample();
|
|
43
|
+
Profiler.EndSample();
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
public static Chunk ReadChunk(this NetworkReader reader) {
|
|
@@ -42,23 +49,23 @@ public static class ChunkSerializer {
|
|
|
42
49
|
|
|
43
50
|
var voxelDataLength = reader.ReadInt();
|
|
44
51
|
var colorDataLength = reader.ReadInt();
|
|
52
|
+
var compressedBytesLen = reader.ReadInt();
|
|
45
53
|
|
|
46
54
|
Chunk chunk = VoxelWorld.CreateChunk(key);
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
56
|
+
byte[] voxelByteAndColorArray = ArrayPool<byte>.Shared.Rent(compressedBytesLen);
|
|
57
|
+
|
|
58
|
+
reader.ReadBytes(voxelByteAndColorArray, compressedBytesLen);
|
|
59
|
+
var decompressedData = ArrayPool<byte>.Shared.Rent(Zstd.GetDecompressionBound(voxelByteAndColorArray));
|
|
60
|
+
zstd.Decompress(new ReadOnlySpan<byte>(voxelByteAndColorArray, 0, compressedBytesLen), decompressedData);
|
|
61
|
+
|
|
62
|
+
Buffer.BlockCopy(decompressedData, 0, chunk.readWriteVoxel, 0, voxelDataLength);
|
|
63
|
+
Buffer.BlockCopy(decompressedData, voxelDataLength, chunk.color, 0, colorDataLength);
|
|
64
|
+
|
|
65
|
+
ArrayPool<byte>.Shared.Return(voxelByteAndColorArray);
|
|
66
|
+
ArrayPool<byte>.Shared.Return(decompressedData);
|
|
67
|
+
|
|
61
68
|
chunk.MarkKeysWithVoxelsDirty();
|
|
62
69
|
return chunk;
|
|
63
70
|
}
|
|
64
|
-
}
|
|
71
|
+
}
|
|
@@ -27,14 +27,6 @@ namespace Code.Zstd {
|
|
|
27
27
|
_ctx = new ZstdContext(scratchBufferSize);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/// <summary>
|
|
31
|
-
/// Compress the data. The compression level can be between <c>Zstd.MinCompressionLevel</c>
|
|
32
|
-
/// and <c>Zstd.MaxCompressionLevel</c>. Most use-cases should use <c>Zstd.DefaultCompressionLevel</c>.
|
|
33
|
-
/// </summary>
|
|
34
|
-
public byte[] Compress(byte[] data, int compressionLevel) {
|
|
35
|
-
return Compress(new ReadOnlySpan<byte>(data), compressionLevel);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
30
|
/// <summary>
|
|
39
31
|
/// Compress the data. The compression level can be between <c>Zstd.MinCompressionLevel</c>
|
|
40
32
|
/// and <c>Zstd.MaxCompressionLevel</c>. Most use-cases should use <c>Zstd.DefaultCompressionLevel</c>.
|
|
@@ -43,13 +35,6 @@ namespace Code.Zstd {
|
|
|
43
35
|
return Compress(new ReadOnlySpan<byte>(data, start, length), compressionLevel);
|
|
44
36
|
}
|
|
45
37
|
|
|
46
|
-
/// <summary>
|
|
47
|
-
/// Compress the data using the default compression level.
|
|
48
|
-
/// </summary>
|
|
49
|
-
public byte[] Compress(byte[] data) {
|
|
50
|
-
return Compress(new ReadOnlySpan<byte>(data));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
38
|
/// <summary>
|
|
54
39
|
/// Compress the data using the default compression level.
|
|
55
40
|
/// </summary>
|
|
@@ -71,12 +56,24 @@ namespace Code.Zstd {
|
|
|
71
56
|
public byte[] Compress(ReadOnlySpan<byte> data, int compressionLevel) {
|
|
72
57
|
return CompressData(data, compressionLevel, _ctx);
|
|
73
58
|
}
|
|
74
|
-
|
|
59
|
+
|
|
75
60
|
/// <summary>
|
|
76
|
-
///
|
|
61
|
+
/// Compress the data with a destination buffer. This buffer must be the correct size. Use the
|
|
62
|
+
/// <c>Zstd.GetCompressionBound</c> method to ensure the buffer is large enough. The returned
|
|
63
|
+
/// span is a slice of the input destination buffer.
|
|
64
|
+
/// </summary>
|
|
65
|
+
/// <returns>The number of bytes written to the buffer.</returns>
|
|
66
|
+
public int Compress(ReadOnlySpan<byte> data, byte[] dstBuffer, int compressionLevel) {
|
|
67
|
+
return CompressWithBuffer(data, dstBuffer, compressionLevel, _ctx);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// <summary>
|
|
71
|
+
/// Compress the data into the given destination buffer. This buffer must be the correct size.
|
|
72
|
+
/// Use the <c>Zstd.GetCompressionBound</c> method to ensure the buffer is large enough.
|
|
77
73
|
/// </summary>
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
/// <returns>The number of bytes written to the buffer.</returns>
|
|
75
|
+
public int Compress(ReadOnlySpan<byte> data, byte[] dstBuffer) {
|
|
76
|
+
return Compress(data, dstBuffer, DefaultCompressionLevel);
|
|
80
77
|
}
|
|
81
78
|
|
|
82
79
|
/// <summary>
|
|
@@ -92,6 +89,15 @@ namespace Code.Zstd {
|
|
|
92
89
|
public byte[] Decompress(ReadOnlySpan<byte> data) {
|
|
93
90
|
return DecompressData(data, _ctx);
|
|
94
91
|
}
|
|
92
|
+
|
|
93
|
+
/// <summary>
|
|
94
|
+
/// Decompress the data into the given destination buffer.
|
|
95
|
+
/// Use the <c>Zstd.GetDecompressionBound</c> method to ensure the buffer is large enough.
|
|
96
|
+
/// </summary>
|
|
97
|
+
/// <returns>The number of bytes written to the buffer.</returns>
|
|
98
|
+
public int Decompress(ReadOnlySpan<byte> data, byte[] dstBuffer) {
|
|
99
|
+
return DecompressWithBuffer(data, dstBuffer, _ctx);
|
|
100
|
+
}
|
|
95
101
|
|
|
96
102
|
public void Dispose() {
|
|
97
103
|
Dispose(true);
|
|
@@ -106,6 +112,31 @@ namespace Code.Zstd {
|
|
|
106
112
|
Dispose(false);
|
|
107
113
|
}
|
|
108
114
|
|
|
115
|
+
/// <summary>
|
|
116
|
+
/// Get the maximum buffer size needed for compression.
|
|
117
|
+
/// </summary>
|
|
118
|
+
public static int GetCompressionBound(ReadOnlySpan<byte> uncompressedData) {
|
|
119
|
+
var bound = ZSTD_compressBound((ulong)uncompressedData.Length);
|
|
120
|
+
if (ZSTD_isError(bound)) {
|
|
121
|
+
throw new ZstdException(bound);
|
|
122
|
+
}
|
|
123
|
+
return (int)bound;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/// <summary>
|
|
127
|
+
/// Get the maximum buffer size needed for decompression.
|
|
128
|
+
/// </summary>
|
|
129
|
+
public static unsafe int GetDecompressionBound(ReadOnlySpan<byte> compressedData) {
|
|
130
|
+
ulong rSize;
|
|
131
|
+
fixed (byte* src = compressedData) {
|
|
132
|
+
rSize = ZSTD_getFrameContentSize(new IntPtr(src), (ulong)compressedData.Length);
|
|
133
|
+
}
|
|
134
|
+
if (ZSTD_isError(rSize)) {
|
|
135
|
+
throw new ZstdException(rSize);
|
|
136
|
+
}
|
|
137
|
+
return (int)rSize;
|
|
138
|
+
}
|
|
139
|
+
|
|
109
140
|
/// <summary>
|
|
110
141
|
/// Compress the bytes. The compression level can be between <c>Zstd.MinCompressionLevel</c>
|
|
111
142
|
/// and <c>Zstd.MaxCompressionLevel</c>. Most use-cases should use <c>Zstd.DefaultCompressionLevel</c>.
|
|
@@ -181,6 +212,23 @@ namespace Code.Zstd {
|
|
|
181
212
|
return decompressedData;
|
|
182
213
|
}
|
|
183
214
|
|
|
215
|
+
private static unsafe int DecompressWithBuffer(ReadOnlySpan<byte> data, byte[] dstBuffer, ZstdContext ctx) {
|
|
216
|
+
ulong decompressedSize;
|
|
217
|
+
fixed (byte* src = data) {
|
|
218
|
+
fixed (byte* dst = dstBuffer) {
|
|
219
|
+
if (ctx != null) {
|
|
220
|
+
decompressedSize = ZSTD_decompressDCtx(ctx.Dctx, new IntPtr(dst), (ulong)dstBuffer.Length, new IntPtr(src), (ulong)data.Length);
|
|
221
|
+
} else {
|
|
222
|
+
decompressedSize = ZSTD_decompress(new IntPtr(dst), (ulong)dstBuffer.Length, new IntPtr(src), (ulong)data.Length);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (ZSTD_isError(decompressedSize)) {
|
|
227
|
+
throw new ZstdException(decompressedSize);
|
|
228
|
+
}
|
|
229
|
+
return (int)decompressedSize;
|
|
230
|
+
}
|
|
231
|
+
|
|
184
232
|
private static unsafe byte[] CompressWithStack(ReadOnlySpan<byte> data, ulong bound, int compressionLevel, ZstdContext ctx) {
|
|
185
233
|
var dst = stackalloc byte[(int)bound];
|
|
186
234
|
ulong compressedSize;
|
|
@@ -221,6 +269,24 @@ namespace Code.Zstd {
|
|
|
221
269
|
Array.Resize(ref dstBuf, (int)compressedSize);
|
|
222
270
|
return dstBuf;
|
|
223
271
|
}
|
|
272
|
+
|
|
273
|
+
private static unsafe int CompressWithBuffer(ReadOnlySpan<byte> data, byte[] dstBuffer, int compressionLevel, ZstdContext ctx) {
|
|
274
|
+
ulong compressedSize;
|
|
275
|
+
fixed (byte* src = data) {
|
|
276
|
+
fixed (byte* dst = dstBuffer) {
|
|
277
|
+
if (ctx != null) {
|
|
278
|
+
compressedSize = ZSTD_compressCCtx(ctx.Cctx, new IntPtr(dst), (ulong)dstBuffer.Length, new IntPtr(src), (ulong)data.Length, compressionLevel);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
compressedSize = ZSTD_compress(new IntPtr(dst), (ulong)dstBuffer.Length, new IntPtr(src), (ulong)data.Length, compressionLevel);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (ZSTD_isError(compressedSize)) {
|
|
286
|
+
throw new ZstdException(compressedSize);
|
|
287
|
+
}
|
|
288
|
+
return (int)compressedSize;
|
|
289
|
+
}
|
|
224
290
|
}
|
|
225
291
|
|
|
226
292
|
public sealed class ZstdContext : IDisposable {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|