diff --git a/.gitignore b/.gitignore index 21a3eb5..eaee2eb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ my.secrets .git.bfg-report/ Documentation-old/ env/ -Documentation/public/ \ No newline at end of file +Documentation/public/ +node_modules/ diff --git a/Documentation/.idea/.gitignore b/Documentation/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/Documentation/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/Documentation/.idea/Documentation.iml b/Documentation/.idea/Documentation.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/Documentation/.idea/Documentation.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Documentation/.idea/modules.xml b/Documentation/.idea/modules.xml new file mode 100644 index 0000000..abf93be --- /dev/null +++ b/Documentation/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Documentation/.idea/vcs.xml b/Documentation/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/Documentation/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Documentation/docs/client/concepts/connecting.md b/Documentation/docs/client/concepts/connecting.md new file mode 100644 index 0000000..1d1d8f7 --- /dev/null +++ b/Documentation/docs/client/concepts/connecting.md @@ -0,0 +1,10 @@ +There are several steps that need to happen before a client can join a room. Most of these can happen automatically using the default `VelNetManager` script. + +## 1. Connecting +First, the TCP connection to the server must be established. If this step fails, offline mode is activated. + +## 2. Logging in +Logging in registers this client with the server. The inputs for this are an app name and device id. `VelNetManager` automatically provides an appName that is appended with the version number if `onlyConnectToSameVersion` is true. The device id is generated from Unity's `SystemInfo.deviceUniqueIdentifier` and the app name to guarantee a different id per app and device. + +## 3. Joining a room +Only after joining a room can normal networking take place between clients in that room. The client can send any string room name to join, and other clients that send the same string will be in that room with them. \ No newline at end of file diff --git a/Documentation/docs/client/implementation/message-types.md b/Documentation/docs/client/implementation/message-types.md new file mode 100644 index 0000000..74b1e31 --- /dev/null +++ b/Documentation/docs/client/implementation/message-types.md @@ -0,0 +1,120 @@ +VelNet uses a single-byte header on all messages that denotes the message type. The set of message types for sent messages is different from the set used when receiving messages. +It is generally not necessary to know or modify these internal data types. + +!!! note + + The server encodes ints with a Big-Endian format, but C# uses Little-Endian on almost all platforms. Use the `BinaryWriter.WriteBigEndian()` extensions to encode in Big-Endian on the C# side. + +## MessageSentType +```cs +public enum MessageSendType +{ + MESSAGE_OTHERS_ORDERED = 7, + MESSAGE_ALL_ORDERED = 8, + MESSAGE_LOGIN = 0, + MESSAGE_GETROOMS = 1, + MESSAGE_JOINROOM = 2, + MESSAGE_OTHERS = 3, + MESSAGE_ALL = 4, + MESSAGE_GROUP = 5, + MESSAGE_SETGROUP = 6, + MESSAGE_GETROOMDATA = 9 +}; +``` +### MESSAGE_LOGIN = 0 +This message contains: +- `byte` - The length of the deviceId string +- `byte[]` - UTF8 encoding of the deviceId string +- `byte` - The length of the appName string +- `byte[]` - UTF8 encoding of the appName string +### MESSAGE_GETROOMS = 1 +This message contains no data, just the single-byte header. +### MESSAGE_JOINROOM = 2 +This message contains: +- `byte` - The length of the roomName string +- `byte[]` - UTF8 encoding of the roomName string +### MESSAGE_OTHERS = 3 +### MESSAGE_ALL = 4 +### MESSAGE_GROUP = 5 +### MESSAGE_SETGROUP = 6 +### MESSAGE_OTHERS_ORDERED = 7 +### MESSAGE_ALL_ORDERED = 8 +### MESSAGE_GETROOMDATA = 9 + +## MessageReceivedType +```cs +public enum MessageReceivedType +{ + LOGGED_IN = 0, + ROOM_LIST = 1, + PLAYER_JOINED = 2, + DATA_MESSAGE = 3, + MASTER_MESSAGE = 4, + YOU_JOINED = 5, + PLAYER_LEFT = 6, + YOU_LEFT = 7, + ROOM_DATA = 8 +} +``` +### LOGGED_IN = 0 +This message contains: +- `int` - The userid given by the server to this user. +### ROOM_LIST = 1 +This message contains: +- `int` - The length of the room mesesage string. This is an int instead of a byte because of the possible string length with many rooms. +- `byte[]` - A UTF8-encoded string for the room message + - This string is encoded as a comma-separated list of rooms, with the format `name:numUsers` for each room. + - e.g. `Common_1:0:3,Auditorium_123:0,room1:10` +### PLAYER_JOINED = 2 +This message contains: +- `int` - The userid of the player that joined +- `byte` - The length of the room name string +- `byte[]` - A UTF8-encoded string for the room name +### DATA_MESSAGE = 3 +This message contains: +- `int` - The userid of the player that sent this message +- `int` - The size of the payload +- `byte[]` - The message data + - Decoding the actual message data is handled in `VelNetPlayer.cs` + - Within DATA_MESSAGE messages, there is an additonal type header: + ```cs + public enum MessageType : byte + { + ObjectSync, + TakeOwnership, + Instantiate, + InstantiateWithTransform, + Destroy, + DeleteSceneObjects, + Custom + } + ``` +### MASTER_MESSAGE = 4 +This message contains: +- `int` - The new master client id. The sender of this message is the master. +### YOU_JOINED = 5 +This is returned after you join a room. +This message contains: +- `int` - The number of players in the room +- For each player: + - `int` - The player's userid +- `byte` - The length of the room name string +- `byte[]` - A UTF8-encoded string for the room name +### PLAYER_LEFT = 6 +This message contains: +- `int` - The player's userid +- `byte` - The length of the room name string +- `byte[]` - A UTF8-encoded string for the room name +### YOU_LEFT = 7 +This message contains: +- `byte` - The length of the room name string +- `byte[]` - A UTF8-encoded string for the room name +### ROOM_DATA = 8 +This message contains: +- `byte` - The length of the room name string +- `byte[]` - A UTF8-encoded string for the room name +- `int` - The number of client data blocks to read +- For each client data block: + - `int` - The userid of this client + - `byte` - The length of the username string + - `byte[]` - A UTF8-encoded string for the username diff --git a/Documentation/docs/client/offline-mode.md b/Documentation/docs/client/offline-mode.md new file mode 100644 index 0000000..84f22f8 --- /dev/null +++ b/Documentation/docs/client/offline-mode.md @@ -0,0 +1,5 @@ +VelNet supports an offline mode that lets you write client code in the same way even in a situation where there is no internet or no server available. + +Offline mode is activated automatically if no initial TCP connection can be established by `VelNetManager.cs` + +Messages are intercepted by VelNetManager and send to a "FakeServer" function instead of to the server, and realistic response messages are constructed and sent to the callback functions. \ No newline at end of file diff --git a/Documentation/mkdocs.yml b/Documentation/mkdocs.yml index e37a4bf..b7d1269 100644 --- a/Documentation/mkdocs.yml +++ b/Documentation/mkdocs.yml @@ -2,7 +2,7 @@ site_name: VelNet Docs site_url: https://docs.velnet.ugavel.com repo_url: https://github.com/velaboratory/VelNetUnity repo_name: velaboratory/VelNetUnity -edit_uri: edit/main/Documentation +edit_uri: edit/main/Documentation/docs theme: name: material diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/BinaryWriterExtensions.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/BinaryWriterExtensions.cs index 45ef835..56389b1 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/BinaryWriterExtensions.cs +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/BinaryWriterExtensions.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace VelNet { - public static class BinaryWriterExtensions + public static partial class BinaryWriterExtensions { #region Writers diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs index 57dd72d..a758270 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs @@ -8,6 +8,7 @@ using UnityEngine; using System.Net; using UnityEngine.SceneManagement; using System.IO; +using System.Threading.Tasks; namespace VelNet { @@ -119,6 +120,8 @@ namespace VelNet public bool connected; private bool wasConnected; private double lastConnectionCheck; + private bool offlineMode; + private string offlineRoomName; public List prefabs = new List(); public NetworkObject[] sceneObjects; @@ -316,7 +319,8 @@ namespace VelNet onlyConnectToSameVersion ? $"{Application.productName}_{Application.version}" : $"{Application.productName}", - Hash128.Compute(SystemInfo.deviceUniqueIdentifier).ToString() + Hash128.Compute(SystemInfo.deviceUniqueIdentifier + Application.productName) + .ToString() ); } @@ -742,137 +746,7 @@ namespace VelNet AddMessage(new ConnectedMessage()); while (socketConnection.Connected) { - //read a byte - int b = stream.ReadByte(); - MessageReceivedType type = (MessageReceivedType)b; - - switch (type) - { - //login - case MessageReceivedType.LOGGED_IN: - { - AddMessage(new LoginMessage - { - // not really the sender... - userId = GetIntFromBytes(ReadExact(stream, 4)) - }); - break; - } - //rooms - case MessageReceivedType.ROOM_LIST: - { - RoomsMessage m = new RoomsMessage(); - m.rooms = new List(); - int N = GetIntFromBytes(ReadExact(stream, 4)); //the size of the payload - byte[] utf8data = ReadExact(stream, N); - string roomMessage = Encoding.UTF8.GetString(utf8data); - - - string[] sections = roomMessage.Split(','); - foreach (string s in sections) - { - string[] pieces = s.Split(':'); - if (pieces.Length == 2) - { - m.rooms.Add(new ListedRoom - { - name = pieces[0], - numUsers = int.Parse(pieces[1]) - }); - } - } - - AddMessage(m); - break; - } - case MessageReceivedType.ROOM_DATA: - { - RoomDataMessage rdm = new RoomDataMessage(); - int N = stream.ReadByte(); - byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 - string roomname = Encoding.UTF8.GetString(utf8data); - - N = GetIntFromBytes(ReadExact(stream, 4)); //the number of client datas to read - rdm.room = roomname; - for (int i = 0; i < N; i++) - { - // client id + short string - int client_id = GetIntFromBytes(ReadExact(stream, 4)); - int s = stream.ReadByte(); //size of string - utf8data = ReadExact(stream, s); //the username - string username = Encoding.UTF8.GetString(utf8data); - rdm.members.Add((client_id, username)); - } - - AddMessage(rdm); - break; - } - //joined - case MessageReceivedType.PLAYER_JOINED: - { - JoinMessage m = new JoinMessage(); - m.userId = GetIntFromBytes(ReadExact(stream, 4)); - int N = stream.ReadByte(); - byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 - m.room = Encoding.UTF8.GetString(utf8data); - AddMessage(m); - break; - } - //data - case MessageReceivedType.DATA_MESSAGE: - { - DataMessage m = new DataMessage(); - m.senderId = GetIntFromBytes(ReadExact(stream, 4)); - int N = GetIntFromBytes(ReadExact(stream, 4)); //the size of the payload - m.data = ReadExact(stream, N); //the message - AddMessage(m); - break; - } - // new master - case MessageReceivedType.MASTER_MESSAGE: - { - ChangeMasterMessage m = new ChangeMasterMessage(); - m.masterId = GetIntFromBytes(ReadExact(stream, 4)); // sender is the new master - AddMessage(m); - break; - } - - case MessageReceivedType.YOU_JOINED: - { - YouJoinedMessage m = new YouJoinedMessage(); - int N = GetIntFromBytes(ReadExact(stream, 4)); - m.playerIds = new List(); - for (int i = 0; i < N; i++) - { - m.playerIds.Add(GetIntFromBytes(ReadExact(stream, 4))); - } - - N = stream.ReadByte(); - byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 - m.room = Encoding.UTF8.GetString(utf8data); - AddMessage(m); - break; - } - case MessageReceivedType.PLAYER_LEFT: - { - PlayerLeftMessage m = new PlayerLeftMessage(); - m.userId = GetIntFromBytes(ReadExact(stream, 4)); - int N = stream.ReadByte(); - byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 - m.room = Encoding.UTF8.GetString(utf8data); - AddMessage(m); - break; - } - case MessageReceivedType.YOU_LEFT: - { - YouLeftMessage m = new YouLeftMessage(); - int N = stream.ReadByte(); - byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 - m.room = Encoding.UTF8.GetString(utf8data); - AddMessage(m); - break; - } - } + HandleIncomingMessage(reader); } } catch (ThreadAbortException) @@ -882,6 +756,9 @@ namespace VelNet catch (SocketException socketException) { VelNetLogger.Error("Socket exception: " + socketException); + VelNetLogger.Error("Switching to offline mode"); + offlineMode = true; + AddMessage(new ConnectedMessage()); } catch (Exception ex) { @@ -891,8 +768,145 @@ namespace VelNet connected = false; } + private void HandleIncomingMessage(BinaryReader reader) + { + MessageReceivedType type = (MessageReceivedType)reader.ReadByte(); + Debug.Log(type); + switch (type) + { + //login + case MessageReceivedType.LOGGED_IN: + { + AddMessage(new LoginMessage + { + // not really the sender... + userId = GetIntFromBytes(reader.ReadBytes(4)) + }); + break; + } + //rooms + case MessageReceivedType.ROOM_LIST: + { + RoomsMessage m = new RoomsMessage(); + m.rooms = new List(); + int N = GetIntFromBytes(reader.ReadBytes(4)); //the size of the payload + byte[] utf8data = reader.ReadBytes(N); + string roomMessage = Encoding.UTF8.GetString(utf8data); + + string[] sections = roomMessage.Split(','); + foreach (string s in sections) + { + string[] pieces = s.Split(':'); + if (pieces.Length == 2) + { + m.rooms.Add(new ListedRoom + { + name = pieces[0], + numUsers = int.Parse(pieces[1]) + }); + } + } + + AddMessage(m); + break; + } + case MessageReceivedType.ROOM_DATA: + { + RoomDataMessage rdm = new RoomDataMessage(); + int N = reader.ReadByte(); + byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 + string roomname = Encoding.UTF8.GetString(utf8data); + + N = GetIntFromBytes(reader.ReadBytes(4)); //the number of client datas to read + rdm.room = roomname; + for (int i = 0; i < N; i++) + { + // client id + short string + int clientId = GetIntFromBytes(reader.ReadBytes(4)); + int s = reader.ReadByte(); //size of string + utf8data = reader.ReadBytes(s); //the username + string username = Encoding.UTF8.GetString(utf8data); + rdm.members.Add((clientId, username)); + } + + AddMessage(rdm); + break; + } + //joined + case MessageReceivedType.PLAYER_JOINED: + { + JoinMessage m = new JoinMessage(); + m.userId = GetIntFromBytes(reader.ReadBytes(4)); + int N = reader.ReadByte(); + byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 + m.room = Encoding.UTF8.GetString(utf8data); + AddMessage(m); + break; + } + //data + case MessageReceivedType.DATA_MESSAGE: + { + DataMessage m = new DataMessage(); + m.senderId = GetIntFromBytes(reader.ReadBytes(4)); + int N = GetIntFromBytes(reader.ReadBytes(4)); //the size of the payload + m.data = reader.ReadBytes(N); //the message + AddMessage(m); + break; + } + // new master + case MessageReceivedType.MASTER_MESSAGE: + { + ChangeMasterMessage m = new ChangeMasterMessage(); + m.masterId = GetIntFromBytes(reader.ReadBytes(4)); // sender is the new master + AddMessage(m); + break; + } + + case MessageReceivedType.YOU_JOINED: + { + YouJoinedMessage m = new YouJoinedMessage(); + int N = GetIntFromBytes(reader.ReadBytes(4)); + m.playerIds = new List(); + for (int i = 0; i < N; i++) + { + m.playerIds.Add(GetIntFromBytes(reader.ReadBytes(4))); + } + + N = reader.ReadByte(); + byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 + m.room = Encoding.UTF8.GetString(utf8data); + AddMessage(m); + break; + } + case MessageReceivedType.PLAYER_LEFT: + { + PlayerLeftMessage m = new PlayerLeftMessage(); + m.userId = GetIntFromBytes(reader.ReadBytes(4)); + int N = reader.ReadByte(); + byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 + m.room = Encoding.UTF8.GetString(utf8data); + AddMessage(m); + break; + } + case MessageReceivedType.YOU_LEFT: + { + YouLeftMessage m = new YouLeftMessage(); + int N = reader.ReadByte(); + byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 + m.room = Encoding.UTF8.GetString(utf8data); + AddMessage(m); + break; + } + default: + VelNetLogger.Error("Unknown message type"); + throw new ArgumentOutOfRangeException(nameof(type), type, null); + } + } + private void ListenForDataUDP() { + if (offlineMode) return; + //I don't yet have a UDP connection try { @@ -900,17 +914,14 @@ namespace VelNet Debug.Assert(addresses.Length > 0); RemoteEndPoint = new IPEndPoint(addresses[0], port); - - udpSocket = new Socket(AddressFamily.InterNetwork, - SocketType.Dgram, ProtocolType.Udp); - + udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); udpConnected = false; byte[] buffer = new byte[1024]; while (true) { buffer[0] = 0; - Array.Copy(get_be_bytes(userid), 0, buffer, 1, 4); + Array.Copy(GetBigEndianBytes(userid), 0, buffer, 1, 4); udpSocket.SendTo(buffer, 5, SocketFlags.None, RemoteEndPoint); if (udpSocket.Available == 0) @@ -981,6 +992,12 @@ namespace VelNet /// True if the message successfully sent. False if it failed and we should quit private static bool SendTcpMessage(byte[] message) { + if (instance.offlineMode) + { + instance.FakeServer(message); + return true; + } + // Logging.Info("Sent: " + clientMessage); if (instance.socketConnection == null) { @@ -1019,7 +1036,7 @@ namespace VelNet return true; } - private static byte[] get_be_bytes(int n) + private static byte[] GetBigEndianBytes(int n) { return BitConverter.GetBytes(n).Reverse().ToArray(); } @@ -1104,10 +1121,10 @@ namespace VelNet MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); - byte[] R = Encoding.UTF8.GetBytes(roomName); + byte[] roomBytes = Encoding.UTF8.GetBytes(roomName); writer.Write((byte)MessageSendType.MESSAGE_JOINROOM); - writer.Write((byte)R.Length); - writer.Write(R); + writer.Write((byte)roomBytes.Length); + writer.Write(roomBytes); SendTcpMessage(stream.ToArray()); } @@ -1168,7 +1185,7 @@ namespace VelNet MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); writer.Write(sendType); - writer.Write(get_be_bytes(message.Length)); + writer.WriteBigEndian(message.Length); writer.Write(message); return SendTcpMessage(mem.ToArray()); } @@ -1176,7 +1193,7 @@ namespace VelNet { //udp message needs the type toSend[0] = sendType; //we don't - Array.Copy(get_be_bytes(instance.userid), 0, toSend, 1, 4); + Array.Copy(GetBigEndianBytes(instance.userid), 0, toSend, 1, 4); Array.Copy(message, 0, toSend, 5, message.Length); SendUdpMessage(toSend, message.Length + 5); //shouldn't be over 1024... return true; @@ -1192,7 +1209,7 @@ namespace VelNet MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); writer.Write((byte)MessageSendType.MESSAGE_GROUP); - writer.Write(get_be_bytes(message.Length)); + writer.WriteBigEndian(message.Length); writer.Write(message); writer.Write((byte)utf8bytes.Length); writer.Write(utf8bytes); @@ -1201,7 +1218,7 @@ namespace VelNet else { toSend[0] = (byte)MessageSendType.MESSAGE_GROUP; - Array.Copy(get_be_bytes(instance.userid), 0, toSend, 1, 4); + Array.Copy(GetBigEndianBytes(instance.userid), 0, toSend, 1, 4); //also need to send the group toSend[5] = (byte)utf8bytes.Length; Array.Copy(utf8bytes, 0, toSend, 6, utf8bytes.Length); @@ -1223,14 +1240,14 @@ namespace VelNet MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); - byte[] R = Encoding.UTF8.GetBytes(groupName); + byte[] groupNameBytes = Encoding.UTF8.GetBytes(groupName); writer.Write((byte)6); - writer.Write((byte)R.Length); - writer.Write(R); - writer.Write(get_be_bytes(clientIds.Count * 4)); + writer.Write((byte)groupNameBytes.Length); + writer.Write(groupNameBytes); + writer.WriteBigEndian(clientIds.Count * 4); foreach (int c in clientIds) { - writer.Write(get_be_bytes(c)); + writer.WriteBigEndian(c); } SendTcpMessage(stream.ToArray()); @@ -1490,5 +1507,100 @@ namespace VelNet return true; } + + /// + /// Pretends to be the server and sends back the result to be handled. Only should be called in offline mode. + /// + /// The message that was meant to be sent to the server. + private void FakeServer(byte[] message) + { + MemoryStream mem = new MemoryStream(message); + BinaryReader reader = new BinaryReader(mem); + MessageSendType messageType = (MessageSendType)reader.ReadByte(); + + MemoryStream outMem = new MemoryStream(); + BinaryWriter outWriter = new BinaryWriter(outMem); + + switch (messageType) + { + case MessageSendType.MESSAGE_OTHERS_ORDERED: + break; + case MessageSendType.MESSAGE_ALL_ORDERED: + break; + case MessageSendType.MESSAGE_LOGIN: + outWriter.Write((byte)MessageReceivedType.LOGGED_IN); + outWriter.WriteBigEndian(0); + break; + case MessageSendType.MESSAGE_GETROOMS: + outWriter.Write((byte)MessageReceivedType.ROOM_LIST); + outWriter.WriteBigEndian(0); + break; + case MessageSendType.MESSAGE_JOINROOM: + { + string roomName = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadByte())); + + // if leaving a room + if (string.IsNullOrEmpty(roomName)) + { + outWriter.Write((byte)MessageReceivedType.YOU_LEFT); + byte[] roomNameBytes = Encoding.UTF8.GetBytes(offlineRoomName); + outWriter.Write((byte)roomNameBytes.Length); + outWriter.Write(roomNameBytes); + } + else + { + outWriter.Write((byte)MessageReceivedType.YOU_JOINED); + outWriter.WriteBigEndian(1); // num players + outWriter.WriteBigEndian(0); // our userid + byte[] roomNameBytes = Encoding.UTF8.GetBytes(roomName); + outWriter.Write((byte)roomNameBytes.Length); + outWriter.Write(roomNameBytes); + } + + offlineRoomName = roomName; + break; + } + case MessageSendType.MESSAGE_OTHERS: + break; + case MessageSendType.MESSAGE_ALL: + break; + case MessageSendType.MESSAGE_GROUP: + break; + case MessageSendType.MESSAGE_SETGROUP: + break; + case MessageSendType.MESSAGE_GETROOMDATA: + { + outWriter.Write((byte)MessageReceivedType.ROOM_DATA); + byte[] roomNameBytes = Encoding.UTF8.GetBytes("OFFLINE"); + outWriter.Write((byte)roomNameBytes.Length); + outWriter.Write(roomNameBytes); + outWriter.WriteBigEndian(0); + break; + } + default: + throw new ArgumentOutOfRangeException(); + } + + outMem.Position = 0; + // if we run this in the same thread, then it is modifying the messages collection while iterating + Task.Run(() => { HandleIncomingMessage(new BinaryReader(outMem)); }); + } + } + + public static partial class BinaryWriterExtensions + { + public static void WriteBigEndian(this BinaryWriter writer, int value) + { + byte[] data = BitConverter.GetBytes(value); + Array.Reverse(data); + writer.Write(data); + } + + public static int ReadBigEndian(this BinaryReader reader) + { + byte[] data = reader.ReadBytes(4); + Array.Reverse(data); + return BitConverter.ToInt32(data, 0); + } } } \ No newline at end of file diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs index de993a8..2fd2530 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System; using System.IO; +using System.Text; using UnityEngine; namespace VelNet @@ -82,12 +83,11 @@ namespace VelNet /// /// The length of the byte[] for message is fixed according to the message type /// - public void HandleMessage(VelNetManager.DataMessage m, bool unknown_sender = false) + public void HandleMessage(VelNetManager.DataMessage m, bool unknownSender = false) { using MemoryStream mem = new MemoryStream(m.data); using BinaryReader reader = new BinaryReader(mem); - //individual message parameters separated by comma VelNetManager.MessageType messageType = (VelNetManager.MessageType)reader.ReadByte(); if (messageType == VelNetManager.MessageType.Custom) @@ -109,7 +109,7 @@ namespace VelNet return; } - if (unknown_sender) + if (unknownSender) { VelNetLogger.Error("Received non-custom message from player that doesn't exist "); return; diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples/BasicExample/Scenes/BasicExample.unity b/TestVelGameServer/Packages/VelNetUnity/Samples/BasicExample/Scenes/BasicExample.unity index eb3602f..50cf8f9 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Samples/BasicExample/Scenes/BasicExample.unity +++ b/TestVelGameServer/Packages/VelNetUnity/Samples/BasicExample/Scenes/BasicExample.unity @@ -104,7 +104,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,7 +117,7 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: @@ -199,7 +199,9 @@ Canvas: m_OverrideSorting: 0 m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 @@ -337,6 +339,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} m_Name: m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -372,7 +375,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &652307109 GameObject: @@ -466,7 +469,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 2 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 25.729, y: -12.365, z: 17.037} --- !u!1 &903768653 GameObject: @@ -500,9 +503,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -542,7 +553,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!81 &903768658 AudioListener: @@ -583,7 +594,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 3 + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1099803616 MonoBehaviour: @@ -597,7 +608,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 233344de094f11341bdb834d564708dc, type: 3} m_Name: m_EditorClassIdentifier: - host: vn.ugavel.com + host: velnet-demo.ugavel.com port: 5000 udpConnected: 0 userid: -1 diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Demo All.unity b/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Demo All.unity index a816e45..88f3398 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Demo All.unity +++ b/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Demo All.unity @@ -104,7 +104,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,7 +117,7 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: @@ -585,7 +585,9 @@ Canvas: m_OverrideSorting: 0 m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 @@ -749,6 +751,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} m_Name: m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -1733,9 +1736,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -2055,7 +2066,7 @@ MonoBehaviour: prefabName: isSceneObject: 1 syncedComponents: - - {fileID: 948755939} + - {fileID: 0} --- !u!114 &948755941 MonoBehaviour: m_ObjectHideFlags: 0 @@ -2518,7 +2529,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 233344de094f11341bdb834d564708dc, type: 3} m_Name: m_EditorClassIdentifier: - host: vn.ugavel.com + host: velnet-demo.ugavel.com port: 5000 udpConnected: 0 userid: -1 @@ -4106,7 +4117,7 @@ MonoBehaviour: prefabName: isSceneObject: 1 syncedComponents: - - {fileID: 2021764945} + - {fileID: 0} --- !u!114 &2021764945 MonoBehaviour: m_ObjectHideFlags: 0 @@ -4372,6 +4383,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 3951900052977689805, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} @@ -4439,4 +4451,7 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Simple Connection Example.unity b/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Simple Connection Example.unity index 0e75daa..d5f9ace 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Simple Connection Example.unity +++ b/TestVelGameServer/Packages/VelNetUnity/Samples/DissonanceExample/Scenes/Simple Connection Example.unity @@ -104,7 +104,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,7 +117,7 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: @@ -152,7 +152,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 233344de094f11341bdb834d564708dc, type: 3} m_Name: m_EditorClassIdentifier: - host: vn.ugavel.com + host: velnet-demo.ugavel.com port: 5000 udpConnected: 0 userid: -1 @@ -301,9 +301,17 @@ BoxCollider: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 958953873} m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 m_IsTrigger: 0 + m_ProvidesContacts: 0 m_Enabled: 1 - serializedVersion: 2 + serializedVersion: 3 m_Size: {x: 1, y: 1, z: 1} m_Center: {x: 0, y: 0, z: 0} --- !u!23 &958953875 @@ -386,6 +394,9 @@ MonoBehaviour: networkObject: {fileID: 958953879} serializationRateHz: 30 hybridOnChangeCompression: 1 + position: 1 + rotation: 1 + scale: 0 useLocalTransform: 0 teleportDistance: 0 teleportAngle: 0 @@ -448,9 +459,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples/FullExample/Scenes/FullExample.unity b/TestVelGameServer/Packages/VelNetUnity/Samples/FullExample/Scenes/FullExample.unity index 25ba695..349946d 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Samples/FullExample/Scenes/FullExample.unity +++ b/TestVelGameServer/Packages/VelNetUnity/Samples/FullExample/Scenes/FullExample.unity @@ -616,7 +616,7 @@ RectTransform: - {fileID: 1020014860} - {fileID: 1536292193} m_Father: {fileID: 0} - m_RootOrder: 1 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -788,7 +788,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &498776799 GameObject: @@ -1319,7 +1319,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 2 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} --- !u!1 &711524766 GameObject: @@ -1779,7 +1779,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 3 + m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!81 &903768658 AudioListener: @@ -2237,7 +2237,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 5 + m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1020014859 GameObject: @@ -2585,7 +2585,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 6 + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1099803616 MonoBehaviour: @@ -2599,7 +2599,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 233344de094f11341bdb834d564708dc, type: 3} m_Name: m_EditorClassIdentifier: - host: velnet-demo.ugavel.com + host: velnet-demo2.ugavel.com port: 5000 udpConnected: 0 userid: -1 @@ -3251,7 +3251,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 4 + m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1536292192 GameObject: diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples/VelVoiceExample/Scenes/VelVoiceExample.unity b/TestVelGameServer/Packages/VelNetUnity/Samples/VelVoiceExample/Scenes/VelVoiceExample.unity index eb1d9ef..d405d29 100644 --- a/TestVelGameServer/Packages/VelNetUnity/Samples/VelVoiceExample/Scenes/VelVoiceExample.unity +++ b/TestVelGameServer/Packages/VelNetUnity/Samples/VelVoiceExample/Scenes/VelVoiceExample.unity @@ -104,7 +104,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,7 +117,7 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: @@ -280,7 +280,9 @@ Canvas: m_OverrideSorting: 0 m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 @@ -517,6 +519,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} m_Name: m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -552,7 +555,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &513088493 GameObject: @@ -722,7 +725,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 2 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 25.729, y: -12.365, z: 17.037} --- !u!1 &686695937 GameObject: @@ -987,9 +990,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -1029,7 +1040,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!81 &903768658 AudioListener: @@ -1305,7 +1316,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 3 + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1099803616 MonoBehaviour: @@ -1319,7 +1330,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 233344de094f11341bdb834d564708dc, type: 3} m_Name: m_EditorClassIdentifier: - host: vn.ugavel.com + host: velnet-demo.ugavel.com port: 5000 udpConnected: 0 userid: -1 diff --git a/TestVelGameServer/Packages/VelNetUnity/package.json b/TestVelGameServer/Packages/VelNetUnity/package.json index 8fd0fb7..cffda62 100644 --- a/TestVelGameServer/Packages/VelNetUnity/package.json +++ b/TestVelGameServer/Packages/VelNetUnity/package.json @@ -1,7 +1,7 @@ { "name": "edu.uga.engr.vel.velnet", "displayName": "VelNet", - "version": "1.2.3", + "version": "1.3.0", "unity": "2019.1", "description": "A custom networking library for Unity.", "keywords": [ diff --git a/TestVelGameServer/Packages/manifest.json b/TestVelGameServer/Packages/manifest.json index d3ce292..7c94732 100644 --- a/TestVelGameServer/Packages/manifest.json +++ b/TestVelGameServer/Packages/manifest.json @@ -1,14 +1,10 @@ { "dependencies": { - "com.franzco.unityutilities": "https://github.com/AntonFranzluebbers/unityutilities.git", - "com.unity.ai.navigation": "1.1.3", - "com.unity.collab-proxy": "2.0.4", - "com.unity.ide.rider": "3.0.21", - "com.unity.ide.visualstudio": "2.0.18", + "com.unity.ide.rider": "3.0.25", + "com.unity.ide.visualstudio": "2.0.21", "com.unity.ide.vscode": "1.2.5", "com.unity.test-framework": "1.3.2", "com.unity.textmeshpro": "3.0.6", - "com.unity.timeline": "1.7.4", "com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.6", "com.unity.ugui": "1.0.0", "com.unity.modules.ai": "1.0.0", diff --git a/TestVelGameServer/Packages/packages-lock.json b/TestVelGameServer/Packages/packages-lock.json index 76c24b0..d3876c0 100644 --- a/TestVelGameServer/Packages/packages-lock.json +++ b/TestVelGameServer/Packages/packages-lock.json @@ -1,31 +1,5 @@ { "dependencies": { - "com.franzco.unityutilities": { - "version": "https://github.com/AntonFranzluebbers/unityutilities.git", - "depth": 0, - "source": "git", - "dependencies": { - "com.unity.nuget.newtonsoft-json": "2.0.0-preview", - "com.unity.xr.legacyinputhelpers": "2.1.7" - }, - "hash": "330ff73d80febbf9b505dd0ebd86d370d12fc73d" - }, - "com.unity.ai.navigation": { - "version": "1.1.3", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.modules.ai": "1.0.0" - }, - "url": "https://packages.unity.com" - }, - "com.unity.collab-proxy": { - "version": "2.0.4", - "depth": 0, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, "com.unity.ext.nunit": { "version": "2.0.3", "depth": 1, @@ -34,7 +8,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.rider": { - "version": "3.0.21", + "version": "3.0.25", "depth": 0, "source": "registry", "dependencies": { @@ -43,7 +17,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.18", + "version": "2.0.21", "depth": 0, "source": "registry", "dependencies": { @@ -58,13 +32,6 @@ "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.nuget.newtonsoft-json": { - "version": "3.2.1", - "depth": 1, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, "com.unity.sysroot": { "version": "2.0.7", "depth": 1, @@ -101,18 +68,6 @@ }, "url": "https://packages.unity.com" }, - "com.unity.timeline": { - "version": "1.7.4", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.modules.director": "1.0.0", - "com.unity.modules.animation": "1.0.0", - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.particlesystem": "1.0.0" - }, - "url": "https://packages.unity.com" - }, "com.unity.toolchain.win-x86_64-linux-x86_64": { "version": "2.0.6", "depth": 0, @@ -132,16 +87,6 @@ "com.unity.modules.imgui": "1.0.0" } }, - "com.unity.xr.legacyinputhelpers": { - "version": "2.1.10", - "depth": 1, - "source": "registry", - "dependencies": { - "com.unity.modules.vr": "1.0.0", - "com.unity.modules.xr": "1.0.0" - }, - "url": "https://packages.unity.com" - }, "edu.uga.engr.vel.velnet": { "version": "file:VelNetUnity", "depth": 0,