Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [2.0.7] - 2021-02-02

Integration:

Remove com.unity.nuget.newtonsoft-json dependency in favor of the built-in JsonUtility for the VS Test Runner.

## [2.0.6] - 2021-01-20

Project generation:

- Improved language version detection.

Integration:

- Added support for the VS Test Runner.
- Added initial support for displaying asset usage.
- Fixed remaining issues with special characters in file/path.
  • Loading branch information
Unity Technologies committed Feb 2, 2021
1 parent 08ab0fb commit 8cbbe81
Show file tree
Hide file tree
Showing 34 changed files with 999 additions and 70 deletions.
100 changes: 64 additions & 36 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,117 @@
# Code Editor Package for Visual Studio

## [2.0.7] - 2021-02-02

Integration:

Remove com.unity.nuget.newtonsoft-json dependency in favor of the built-in JsonUtility for the VS Test Runner.


## [2.0.6] - 2021-01-20

Project generation:

- Improved language version detection.

Integration:

- Added support for the VS Test Runner.
- Added initial support for displaying asset usage.
- Fixed remaining issues with special characters in file/path.

## [2.0.5] - 2020-10-30

Integration:

Disable legacy pdb symbol checking for Unity packages
- Disable legacy pdb symbol checking for Unity packages.

## [2.0.4] - 2020-10-15

Project generation:

- Added support for embedded Roslyn analyzer DLLs and ruleset files.
- Warn the user when the opened script is not part of the generation scope.
- Warn the user when the selected Visual Studio installation is not found.
- Generate a .vsconfig file to ensure Visual Studio installation is compatible.

Integration:

- Fix automation issues on MacOS, where a new Visual Studio instance is opened every time.

## [2.0.3] - 2020-09-09

Project generation:

Added C#8 language support.
Added UnityProjectGeneratorVersion property.
Local and Embedded packages are now selected by default for generation.
Added support for asmdef root namespace.
- Added C#8 language support.
- Added UnityProjectGeneratorVersion property.
- Local and Embedded packages are now selected by default for generation.
- Added support for asmdef root namespace.

Integration:

When the user disabled auto-refresh in Unity, do not try to force refresh the Asset database.
Fix Visual Studio detection issues with languages using special characters.
- When the user disabled auto-refresh in Unity, do not try to force refresh the Asset database.
- Fix Visual Studio detection issues with languages using special characters.


## [2.0.2] - 2020-05-27

Added support for solution folders.
Only bind the messenger when the VS editor is selected.
Warn when unable to create the messenger.
Fixed an initialization issue triggering legacy code generation.
Allow package source in assembly to be generated when referenced from asmref.
- Added support for solution folders.
- Only bind the messenger when the VS editor is selected.
- Warn when unable to create the messenger.
- Fixed an initialization issue triggering legacy code generation.
- Allow package source in assembly to be generated when referenced from asmref.


## [2.0.1] - 2020-03-19

When Visual Studio installation is compatible with C# 8.0, setup the language version to not prompt the user with unsupported constructs. (So far Unity only supports C# 7.3).
Use Unity's TypeCache to improve project generation speed.
Properly check for a managed assembly before displaying a warning regarding legacy PDB usage.
Add support for selective project generation (embedded, local, registry, git, builtin, player).

- When Visual Studio installation is compatible with C# 8.0, setup the language version to not prompt the user with unsupported constructs. (So far Unity only supports C# 7.3).
- Use Unity's TypeCache to improve project generation speed.
- Properly check for a managed assembly before displaying a warning regarding legacy PDB usage.
- Add support for selective project generation (embedded, local, registry, git, builtin, player).

## [2.0.0] - 2019-11-06

- Improved Visual Studio and Visual Studio for Mac automatic discovery
- Added support for the VSTU messaging system (start/stop features from Visual Studio)
- Added support for solution roundtrip (preserves references to external projects and solution properties)
- Added support for VSTU Analyzers (requires Visual Studio 2019 16.3, Visual Studio for Mac 8.3)
- Improved Visual Studio and Visual Studio for Mac automatic discovery.
- Added support for the VSTU messaging system (start/stop features from Visual Studio).
- Added support for solution roundtrip (preserves references to external projects and solution properties).
- Added support for VSTU Analyzers (requires Visual Studio 2019 16.3, Visual Studio for Mac 8.3).
- Added a warning when using legacy pdb symbol files.
- Fixed issues while Opening Visual Studio on Windows
- Fixed issues while Opening Visual Studio on Mac
- Fixed issues while Opening Visual Studio on Windows.
- Fixed issues while Opening Visual Studio on Mac.

## [1.1.1] - 2019-05-29

Fix Bridge assembly loading with non VS2017 editors
- Fix Bridge assembly loading with non VS2017 editors.

## [1.1.0] - 2019-05-27

Move internal extension handling to package.
- Move internal extension handling to package.

## [1.0.11] - 2019-05-21

Fix detection of visual studio for mac installation.
- Fix detection of visual studio for mac installation.

## [1.0.10] - 2019-05-04

Fix ignored comintegration executable

- Fix ignored comintegration executable.

## [1.0.9] - 2019-03-05

Updated MonoDevelop support, to pass correct arguments, and not import VSTU plugin
Use release build of COMIntegration for Visual Studio

- Updated MonoDevelop support, to pass correct arguments, and not import VSTU plugin.
- Use release build of COMIntegration for Visual Studio.

## [1.0.7] - 2019-04-30

Ensure asset database is refreshed when generating csproj and solution files.
- Ensure asset database is refreshed when generating csproj and solution files.

## [1.0.6] - 2019-04-27

Add support for generating all csproj files.
- Add support for generating all csproj files.

## [1.0.5] - 2019-04-18

Fix relative package paths.
Fix opening editor on mac.
- Fix relative package paths.
- Fix opening editor on mac.

## [1.0.4] - 2019-04-12

Expand All @@ -94,4 +122,4 @@ Fix opening editor on mac.

### This is the first release of *Unity Package visualstudio_editor*.

Using the newly created api to integrate Visual Studio with Unity.
- Using the newly created api to integrate Visual Studio with Unity.
Binary file modified Editor/COMIntegration/Release/COMIntegration.exe
Binary file not shown.
20 changes: 18 additions & 2 deletions Editor/FileUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,31 @@ public static string NormalizeWindowsToUnix(string path)
return path.Replace(WinSeparator, UnixSeparator);
}

internal static bool IsFileInProjectDirectory(string fileName)
internal static bool IsFileInProjectRootDirectory(string fileName)
{
var relative = MakeRelativeToProjectPath(fileName);
if (string.IsNullOrEmpty(relative))
return false;

return relative == Path.GetFileName(relative);
}

// returns null if outside of the project scope
internal static string MakeRelativeToProjectPath(string fileName)
{
var basePath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
fileName = Normalize(fileName);

if (!Path.IsPathRooted(fileName))
fileName = Path.Combine(basePath, fileName);

return string.Equals(Path.GetDirectoryName(fileName), basePath, StringComparison.OrdinalIgnoreCase);
if (!fileName.StartsWith(basePath, StringComparison.OrdinalIgnoreCase))
return null;

return fileName
.Substring(basePath.Length)
.Trim(Path.DirectorySeparatorChar);
}

}
}
5 changes: 1 addition & 4 deletions Editor/Messaging/Deserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ internal class Deserializer
{
private readonly BinaryReader _reader;

// Max UDP packet size is 65507
private const int MaxStringLength = 65000;

public Deserializer(byte[] buffer)
{
_reader = new BinaryReader(new MemoryStream(buffer));
Expand All @@ -27,7 +24,7 @@ public int ReadInt32()
public string ReadString()
{
var length = ReadInt32();
return length > 0 && length <= MaxStringLength
return length > 0
? Encoding.UTF8.GetString(_reader.ReadBytes(length))
: "";
}
Expand Down
14 changes: 14 additions & 0 deletions Editor/Messaging/MessageType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,19 @@ internal enum MessageType
UpdatePackage,

ProjectPath,

// This message is a technical one for big messages, not intended to be used directly
Tcp,

RunStarted,
RunFinished,
TestStarted,
TestFinished,
TestListRetrieved,

RetrieveTestList,
ExecuteTests,

ShowUsage
}
}
46 changes: 45 additions & 1 deletion Editor/Messaging/Messenger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,23 @@ private void ReceiveMessageCallback(IAsyncResult result)
if (message != null)
{
message.Origin = (IPEndPoint)endPoint;
ReceiveMessage?.Invoke(this, new MessageEventArgs(message));

int port;
int bufferSize;
if (IsValidTcpMessage(message, out port, out bufferSize))
{
// switch to TCP mode to handle big messages
TcpClient.Queue(message.Origin.Address, port, bufferSize, buffer =>
{
var originalMessage = DeserializeMessage(buffer);
originalMessage.Origin = message.Origin;
ReceiveMessage?.Invoke(this, new MessageEventArgs(originalMessage));
});
}
else
{
ReceiveMessage?.Invoke(this, new MessageEventArgs(message));
}
}
}
catch (ObjectDisposedException)
Expand All @@ -86,6 +102,22 @@ private void ReceiveMessageCallback(IAsyncResult result)
BeginReceiveMessage();
}

private static bool IsValidTcpMessage(Message message, out int port, out int bufferSize)
{
port = 0;
bufferSize = 0;
if (message.Value == null)
return false;
if (message.Type != MessageType.Tcp)
return false;
var parts = message.Value.Split(':');
if (parts.Length != 2)
return false;
if (!int.TryParse(parts[0], out port))
return false;
return int.TryParse(parts[1], out bufferSize);
}

private void RaiseMessagerException(Exception e)
{
MessagerException?.Invoke(this, new ExceptionEventArgs(e));
Expand All @@ -108,6 +140,18 @@ public void SendMessage(IPEndPoint target, MessageType type, string value = "")
if (_disposed)
return;

if (buffer.Length >= UdpSocket.BufferSize)
{
// switch to TCP mode to handle big messages
var port = TcpListener.Queue(buffer);
if (port > 0)
{
// success, replace original message with "switch to tcp" marker + port information + buffer length
message = MessageFor(MessageType.Tcp, string.Concat(port, ':', buffer.Length));
buffer = SerializeMessage(message);
}
}

_socket.BeginSendTo(buffer, 0, Math.Min(buffer.Length, UdpSocket.BufferSize), SocketFlags.None, target, SendMessageCallback, null);
}
}
Expand Down
93 changes: 93 additions & 0 deletions Editor/Messaging/TcpClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Microsoft.Unity.VisualStudio.Editor.Messaging
{
internal class TcpClient
{
private const int ConnectOrReadTimeoutMilliseconds = 5000;

private class State
{
public System.Net.Sockets.TcpClient TcpClient;
public NetworkStream NetworkStream;
public byte[] Buffer;
public Action<byte[]> OnBufferAvailable;
}

public static void Queue(IPAddress address, int port, int bufferSize, Action<byte[]> onBufferAvailable)
{
var client = new System.Net.Sockets.TcpClient();
var state = new State {OnBufferAvailable = onBufferAvailable, TcpClient = client, Buffer = new byte[bufferSize]};

try
{
ThreadPool.QueueUserWorkItem(_ =>
{
var handle = client.BeginConnect(address, port, OnClientConnected, state);
if (!handle.AsyncWaitHandle.WaitOne(ConnectOrReadTimeoutMilliseconds))
Cleanup(state);
});
}
catch (Exception)
{
Cleanup(state);
}
}

private static void OnClientConnected(IAsyncResult result)
{
var state = (State)result.AsyncState;

try
{
state.TcpClient.EndConnect(result);
state.NetworkStream = state.TcpClient.GetStream();
var handle = state.NetworkStream.BeginRead(state.Buffer, 0, state.Buffer.Length, OnEndRead, state);
if (!handle.AsyncWaitHandle.WaitOne(ConnectOrReadTimeoutMilliseconds))
Cleanup(state);
}
catch (Exception)
{
Cleanup(state);
}
}

private static void OnEndRead(IAsyncResult result)
{
var state = (State)result.AsyncState;

try
{
var count = state.NetworkStream.EndRead(result);
if (count == state.Buffer.Length)
state.OnBufferAvailable?.Invoke(state.Buffer);
}
catch (Exception)
{
// Ignore and cleanup
}
finally
{
Cleanup(state);
}
}

private static void Cleanup(State state)
{
state.NetworkStream?.Dispose();
state.TcpClient?.Close();

state.NetworkStream = null;
state.TcpClient = null;
state.Buffer = null;
state.OnBufferAvailable = null;
}
}
}
Loading

0 comments on commit 8cbbe81

Please sign in to comment.