Skip to content

Commit

Permalink
Merge pull request #397 from FabianTerhorst/dev
Browse files Browse the repository at this point in the history
rc
  • Loading branch information
FabianTerhorst committed Nov 30, 2021
2 parents 8c79da1 + e250237 commit 752a410
Show file tree
Hide file tree
Showing 135 changed files with 313 additions and 61,883 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/release.yml
Expand Up @@ -192,6 +192,8 @@ jobs:
echo "$(echo "`cat ./api/AltV.Net.Resources.Chat.Api/AltV.Net.Resources.Chat.Api.csproj`" | perl -pe 's/<PackageReleaseNotes>(.*)<\/PackageReleaseNotes>/<PackageReleaseNotes>Changelog can be found here https:\/\/github.com\/FabianTerhorst\/coreclr-module\/releases\/tag\/'${GITHUB_REF##*/}'<\/PackageReleaseNotes>/g')" > ./api/AltV.Net.Resources.Chat.Api/AltV.Net.Resources.Chat.Api.csproj
echo "$(echo "`cat ./api/AltV.Net.EntitySync.ServerEvent/AltV.Net.EntitySync.ServerEvent.csproj`" | perl -pe 's/<PackageVersion>(.*)<\/PackageVersion>/<PackageVersion>'${GITHUB_REF##*/}'<\/PackageVersion>/g')" > ./api/AltV.Net.EntitySync.ServerEvent/AltV.Net.EntitySync.ServerEvent.csproj
echo "$(echo "`cat ./api/AltV.Net.EntitySync.ServerEvent/AltV.Net.EntitySync.ServerEvent.csproj`" | perl -pe 's/<PackageReleaseNotes>(.*)<\/PackageReleaseNotes>/<PackageReleaseNotes>Changelog can be found here https:\/\/github.com\/FabianTerhorst\/coreclr-module\/releases\/tag\/'${GITHUB_REF##*/}'<\/PackageReleaseNotes>/g')" > ./api/AltV.Net.EntitySync.ServerEvent/AltV.Net.EntitySync.ServerEvent.csproj
echo "$(echo "`cat ./api/AltV.Net.Client/AltV.Net.Client.csproj`" | perl -pe 's/<PackageVersion>(.*)<\/PackageVersion>/<PackageVersion>'${GITHUB_REF##*/}'<\/PackageVersion>/g')" > ./api/AltV.Net.Client/AltV.Net.Client.csproj
echo "$(echo "`cat ./api/AltV.Net.Client/AltV.Net.Client.csproj`" | perl -pe 's/<PackageReleaseNotes>(.*)<\/PackageReleaseNotes>/<PackageReleaseNotes>Changelog can be found here https:\/\/github.com\/FabianTerhorst\/coreclr-module\/releases\/tag\/'${GITHUB_REF##*/}'<\/PackageReleaseNotes>/g')" > ./api/AltV.Net.Client/AltV.Net.Client.csproj
- uses: rohith/publish-nuget@v2
with:
PROJECT_FILE_PATH: ./api/AltV.Net/AltV.Net.csproj
Expand Down Expand Up @@ -234,6 +236,13 @@ jobs:
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
INCLUDE_SYMBOLS: true
TAG_COMMIT: false
- uses: rohith/publish-nuget@v2
with:
PROJECT_FILE_PATH: ./api/AltV.Net.Client/AltV.Net.Client.csproj
VERSION_REGEX: <PackageVersion>(.*)<\/PackageVersion>
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
INCLUDE_SYMBOLS: true
TAG_COMMIT: false
deploy-cdn:
runs-on: ubuntu-latest
needs: deploy-nuget
Expand Down
106 changes: 65 additions & 41 deletions api/AltV.Net.Async.CodeGen/AsyncEntityGenerator.cs
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Linq;
Expand Down Expand Up @@ -47,39 +48,20 @@ public AsyncEntityAttribute(Type interfaceType)
{
}
}
}";
public void Initialize(GeneratorInitializationContext context)
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false)]
sealed class AsyncPropertyAttribute : Attribute
{
public bool ThreadSafe { get; set; } = false;
public AsyncPropertyAttribute()
{
context.RegisterForSyntaxNotifications(() => new SyntaxTreeReceiver());
}

private static IEnumerable<ISymbol> GetInterfaceMembers(INamedTypeSymbol @interface)
{
var members = @interface.GetMembers().ToList();
foreach (var namedTypeSymbol in @interface.Interfaces)
{
if (namedTypeSymbol.ToString().StartsWith("AltV.Net.Elements.Entities.")) continue;
foreach (var interfaceMember in GetInterfaceMembers(namedTypeSymbol))
{
if (members.All(e => e.Name != interfaceMember.Name)) members.Add(interfaceMember);
}
}

return members;
}
}
}";

private static IEnumerable<ISymbol> GetClassMembers(INamedTypeSymbol @class)
public void Initialize(GeneratorInitializationContext context)
{
var members = @class.GetMembers().ToList();
if (@class.BaseType is null || @class.BaseType.ToString().StartsWith("AltV.Net.Elements.Entities."))
return members;
foreach (var classMember in GetClassMembers(@class.BaseType))
{
if (members.All(e => e.Name != classMember.Name)) members.Add(classMember);
}

return members;
context.RegisterForSyntaxNotifications(() => new SyntaxTreeReceiver());
}

private static IList<INamedTypeSymbol> GetBaseTypes(INamedTypeSymbol @class)
Expand Down Expand Up @@ -108,6 +90,8 @@ public void Execute(GeneratorExecutionContext context)
CSharpSyntaxTree.ParseText(SourceText.From(AttributeText, Encoding.UTF8), options));

var attributeSymbol = compilation.GetTypeByMetadataName("AltV.Net.Async.CodeGen.AsyncEntityAttribute");
var propertyAttributeSymbol =
compilation.GetTypeByMetadataName("AltV.Net.Async.CodeGen.AsyncPropertyAttribute");

var validClasses = new List<INamedTypeSymbol>();

Expand Down Expand Up @@ -164,18 +148,22 @@ public void Execute(GeneratorExecutionContext context)

var members = new List<string>();

var interfaceMembers = GetInterfaceMembers(@interface);
var classMembers = GetClassMembers(@class).ToArray();

foreach (var member in interfaceMembers)
foreach (var member in @interface.GetMembers())
{
var classMember = classMembers.FirstOrDefault(m => m.Name == member.Name);
var classMember = @class.FindImplementationForInterfaceMember(member);

// does member hide base class property (new keyword)
var isNew = classMember?.DeclaringSyntaxReferences.Any(s =>
s.GetSyntax() is MemberDeclarationSyntax declarationSyntax &&
declarationSyntax.Modifiers.Any(SyntaxKind.NewKeyword)) ?? false;

var propertyAttribute = classMember?.GetAttributes().FirstOrDefault(a =>
a.AttributeClass?.Equals(propertyAttributeSymbol, SymbolEqualityComparer.Default) == true);

var propertySettings = propertyAttribute?.NamedArguments
.ToDictionary(e => e.Key, e => e.Value) ??
new Dictionary<string, TypedConstant>();

switch (member)
{
case IPropertySymbol property:
Expand Down Expand Up @@ -209,19 +197,37 @@ public void Execute(GeneratorExecutionContext context)

if (property.GetMethod is not null || property.SetMethod is not null)
{
var getter = $"=> BaseObject.{member.Name}; ";
var setter = $"=> BaseObject.{member.Name} = value; ";

if (propertySettings.TryGetValue("ThreadSafe", out var threadSafe) &&
threadSafe.ToCSharpString() == "true")
{
getter =
$"{{ {property.Type} res = default; AsyncContext.RunOnMainThreadBlockingAndRunAll(() => res = BaseObject.{property.Name}); return res; }}";
setter =
$"{{ AsyncContext.Enqueue(() => BaseObject.{property.Name} = value); }}";
}

var propertyValue = "";
if (property.GetMethod is not null)
propertyValue += $"get => BaseObject.{member.Name}; ";
if (property.SetMethod is not null)
propertyValue += $"set => BaseObject.{member.Name} = value; ";

var attributes = classProperty.GetAttributes();
propertyValue += $"\n get {getter} ";
if (property.SetMethod is not null && !property.SetMethod.IsInitOnly)
propertyValue += $"\n set {setter} ";
else if (property.SetMethod is not null)
propertyValue +=
@$"init => throw new System.MemberAccessException(""Manual construction of Async class is prohibited. Property {property.Name} is marked as init-only and therefore cannot be set on the async entity.""); ";

var attributes = classProperty.GetAttributes().Where(a => !a.Equals(propertyAttribute)).ToArray();
var formattedAttributes =
attributes.Length == 0 ? "" : FormatAttributes(attributes) + "\n";
var @new = isNew ? "new " : "";

var newline = property.GetMethod is not null && property.SetMethod is not null
? "\n"
: "";
members.Add(formattedAttributes +
$"public {@new}{property.Type} {member.Name} {{ {propertyValue}}}");
$"public {@new}{property.Type} {member.Name} {{ {propertyValue}{newline}}}");
}

break;
Expand Down Expand Up @@ -272,12 +278,30 @@ public void Execute(GeneratorExecutionContext context)
var returnAction = classMethod.ReturnsVoid ? "" : "return ";
var name = member.Name;

var attributes = classMethod.GetAttributes();
var attributes = classMethod.GetAttributes().Where(a => !a.Equals(propertyAttribute)).ToArray();
var formattedAttributes = attributes.Length == 0 ? "" : FormatAttributes(attributes) + "\n";
var @new = isNew ? "new " : "";

var methodCall = $"BaseObject.{name}({callArguments})";
var methodValue = "";

if (propertySettings.TryGetValue("ThreadSafe", out var threadSafe) &&
threadSafe.ToCSharpString() == "true")
{
if (classMethod.ReturnsVoid)
methodValue =
$"AsyncContext.RunOnMainThreadBlockingAndRunAll(() => {methodCall});";
else
methodValue =
$"{classMethod.ReturnType} res = default; AsyncContext.RunOnMainThreadBlockingAndRunAll(() => res = {methodCall}); return res;";
}
else
{
methodValue = $"{returnAction}{methodCall};";
}

members.Add(formattedAttributes +
$"public {@new}{classMethod.ReturnType} {name}({arguments})\n{{\n {returnAction}BaseObject.{name}({callArguments});\n}}");
$"public {@new}{classMethod.ReturnType} {name}({arguments})\n{{\n{Indent(methodValue)}\n}}");

break;
}
Expand Down
9 changes: 4 additions & 5 deletions api/AltV.Net.Async/AltAsync.RegisterEvents.cs
Expand Up @@ -50,14 +50,13 @@ public static void RegisterEvents(object target)
break;
case ScriptEventType.PlayerBeforeConnect:
scriptFunction = ScriptFunction.Create(eventMethodDelegate,
new[] { typeof(IPlayer), typeof(ulong), typeof(string) }, true);
new[] { typeof(PlayerConnectionInfo) }, true);
if (scriptFunction == null) return;
OnPlayerBeforeConnect += (player, passwordHash, cdnUrl) =>
OnPlayerBeforeConnect += (connectionInfo, reason) =>
{
var currScriptFunction = scriptFunction.Clone();
currScriptFunction.Set(player);
currScriptFunction.Set(passwordHash);
currScriptFunction.Set(cdnUrl);
currScriptFunction.Set(connectionInfo);
currScriptFunction.Set(reason);
return currScriptFunction.CallAsync();
};
break;
Expand Down
11 changes: 3 additions & 8 deletions api/AltV.Net.Async/AsyncModule.cs
Expand Up @@ -180,19 +180,14 @@ public override void OnPlayerConnectEvent(IPlayer player, string reason)
});
}

public override void OnPlayerBeforeConnectEvent(IntPtr eventPointer, IPlayer player, ulong passwordHash, string cdnUrl)
public override void OnPlayerBeforeConnectEvent(IntPtr eventPointer, PlayerConnectionInfo connectionInfo, string reason)
{
base.OnPlayerBeforeConnectEvent(eventPointer, player, passwordHash, cdnUrl);
base.OnPlayerBeforeConnectEvent(eventPointer, connectionInfo, reason);
if (!PlayerBeforeConnectAsyncEventHandler.HasEvents()) return;
var playerReference = new PlayerRef(player);
CheckRef(in playerReference, player);
Task.Run(async () =>
{
playerReference.DebugCountUp();
await PlayerBeforeConnectAsyncEventHandler.CallAsync(@delegate =>
@delegate(player, passwordHash, cdnUrl));
playerReference.DebugCountDown();
playerReference.Dispose();
@delegate(connectionInfo, reason));
});
}

Expand Down
2 changes: 1 addition & 1 deletion api/AltV.Net.Async/Events/Events.cs
Expand Up @@ -10,7 +10,7 @@ namespace AltV.Net.Async.Events

public delegate Task PlayerConnectAsyncDelegate(IPlayer player, string reason);

public delegate Task PlayerBeforeConnectAsyncDelegate(IPlayer player, ulong passwordHash, string cdnUrl);
public delegate Task PlayerBeforeConnectAsyncDelegate(PlayerConnectionInfo connectionInfo, string reason);

public delegate Task PlayerDamageAsyncDelegate(IPlayer player, IEntity attacker, ushort oldHealth, ushort oldArmor,
ushort oldMaxHealth, ushort oldMaxArmor, uint weapon, ushort healthDamage, ushort armourDamage);
Expand Down
22 changes: 0 additions & 22 deletions api/AltV.Net.Client/Alt.Blips.cs

This file was deleted.

18 changes: 0 additions & 18 deletions api/AltV.Net.Client/Alt.WebView.cs

This file was deleted.

0 comments on commit 752a410

Please sign in to comment.