From 862e868cf0355f6b63323352e6ff0ee1ead3de4e Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:08:04 -0700 Subject: [PATCH 1/2] fix: Fixes codegenning nested classes (#738) --- .../SerializableEntityGeneration.Class.cs | 61 ++++++++++++++++--- ...zableEntityGeneration.DeserializeMethod.cs | 59 +++++++++--------- ...SerializableEntityGeneration.SerialCtor.cs | 9 +-- ...lizableEntityGeneration.SerializeMethod.cs | 27 ++++---- ...alizationEntityGeneration.ContentStruct.cs | 5 +- .../SourceGeneration.Class.cs | 9 +-- 6 files changed, 107 insertions(+), 63 deletions(-) diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs index 6ae601b23..30043cac5 100644 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs +++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs @@ -168,11 +168,13 @@ namespace SerializationGenerator ? Array.Empty() : new ITypeSymbol[] { compilation.GetTypeByMetadataName(SymbolMetadata.RAW_SERIALIZABLE_INTERFACE) }; - source.GenerateClassStart(className, " ", interfaces.ToImmutableArray()); + var indent = " "; - const string indent = " "; + source.RecursiveGenerateClassStart(classSymbol, interfaces.ToImmutableArray(), ref indent); + indent += " "; source.GenerateClassField( + indent, Accessibility.Private, InstanceModifier.Const, "int", @@ -223,7 +225,7 @@ namespace SerializationGenerator if (attrTypeArg.Kind == TypedConstantKind.Primitive && attrTypeArg.Value is string attrStr) { - source.AppendLine($" {attrStr}"); + source.AppendLine($"{indent} {attrStr}"); } else { @@ -298,7 +300,7 @@ namespace SerializationGenerator if (!embedded) { // Serial constructor - source.GenerateSerialCtor(compilation, className, isOverride); + source.GenerateSerialCtor(compilation, className, indent, isOverride); source.AppendLine(); } @@ -309,7 +311,7 @@ namespace SerializationGenerator var migration = migrations[i]; if (migration.Version < version) { - source.GenerateMigrationContentStruct(compilation, migration, classSymbol); + source.GenerateMigrationContentStruct(compilation, indent, migration, classSymbol); source.AppendLine(); } } @@ -318,6 +320,7 @@ namespace SerializationGenerator // Serialize Method source.GenerateSerializeMethod( compilation, + indent, isOverride, encodedVersion, serializableProperties, @@ -329,6 +332,7 @@ namespace SerializationGenerator source.GenerateDeserializeMethod( compilation, classSymbol, + indent, isOverride, version, encodedVersion, @@ -344,22 +348,23 @@ namespace SerializationGenerator source.AppendLine(); source.GenerateEnumStart( "SaveFlag", - " ", + $"{indent} ", true, Accessibility.Private ); - source.GenerateEnumValue(" ", true, "None", -1); + source.GenerateEnumValue($"{indent} ", true, "None", -1); int index = 0; foreach (var (order, _) in serializableFieldSaveFlags) { - source.GenerateEnumValue(" ", true, serializableProperties[order].Name, index++); + source.GenerateEnumValue($"{indent} ", true, serializableProperties[order].Name, index++); } - source.GenerateEnumEnd(" "); + source.GenerateEnumEnd($"{indent} "); } - source.GenerateClassEnd(" "); + indent = indent.Substring(0, indent.Length - 4); + source.RecursiveGenerateClassEnd(classSymbol, ref indent); source.GenerateNamespaceEnd(); if (migrationPath != null) @@ -384,5 +389,41 @@ namespace SerializationGenerator var filePath = Path.Combine(migrationPath, $"{metadata.Type}.v{metadata.Version}.json"); File.WriteAllText(filePath, JsonSerializer.Serialize(metadata, options)); } + + private static void RecursiveGenerateClassStart( + this StringBuilder source, + INamedTypeSymbol classSymbol, + ImmutableArray interfaces, + ref string indent + ) + { + var containingSymbolList = new List(); + + do + { + containingSymbolList.Add(classSymbol); + classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol; + } while (classSymbol != null); + + containingSymbolList.Reverse(); + + for (var i = 0; i < containingSymbolList.Count; i++) + { + var symbol = containingSymbolList[i]; + source.GenerateClassStart(symbol, indent, i == containingSymbolList.Count - 1 ? interfaces : ImmutableArray.Empty); + indent += " "; + } + } + + private static void RecursiveGenerateClassEnd(this StringBuilder source, INamedTypeSymbol classSymbol, ref string indent) + { + do + { + source.GenerateClassEnd(indent); + indent = indent.Substring(0, indent.Length - 4); + + classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol; + } while (classSymbol != null); + } } } diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs index daa88eed4..6a0665b9a 100644 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs +++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs @@ -28,6 +28,7 @@ namespace SerializationGenerator this StringBuilder source, Compilation compilation, INamedTypeSymbol classSymbol, + string indent, bool isOverride, int version, bool encodedVersion, @@ -40,7 +41,7 @@ namespace SerializationGenerator var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE); source.GenerateMethodStart( - " ", + indent, "Deserialize", Accessibility.Public, isOverride, @@ -48,12 +49,12 @@ namespace SerializationGenerator ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader")) ); - const string indent = " "; - const string innerIndent = $"{indent} "; + var bodyIndent = $"{indent} "; + var innerIndent = $"{bodyIndent} "; if (isOverride) { - source.AppendLine($"{indent}base.Deserialize(reader);"); + source.AppendLine($"{bodyIndent}base.Deserialize(reader);"); source.AppendLine(); } @@ -79,7 +80,7 @@ namespace SerializationGenerator ).Where(m => m.Item2 != null).ToList(); // Version - source.AppendLine($"{indent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();"); + source.AppendLine($"{bodyIndent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();"); if (version > 0) { @@ -95,32 +96,32 @@ namespace SerializationGenerator } source.AppendLine(); - source.AppendLine($"{indent}if (version == {migrationVersion})"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} MigrateFrom(new V{migrationVersion}Content(reader, this));"); - source.AppendLine($"{indent} {parent}.MarkDirty();"); - source.GenerateAfterDeserialization($"{indent} ", afterDeserialization); - source.AppendLine($"{indent} return;"); - source.AppendLine($"{indent}}}"); + source.AppendLine($"{bodyIndent}if (version == {migrationVersion})"); + source.AppendLine($"{bodyIndent}{{"); + source.AppendLine($"{bodyIndent} MigrateFrom(new V{migrationVersion}Content(reader, this));"); + source.AppendLine($"{bodyIndent} {parent}.MarkDirty();"); + source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization); + source.AppendLine($"{bodyIndent} return;"); + source.AppendLine($"{bodyIndent}}}"); } if (nextVersion < version) { source.AppendLine(); - source.AppendLine($"{indent}if (version < _version)"); - source.AppendLine($"{indent}{{"); - source.AppendLine($"{indent} Deserialize(reader, version);"); - source.AppendLine($"{indent} {parent}.MarkDirty();"); - source.GenerateAfterDeserialization($"{indent} ", afterDeserialization); - source.AppendLine($"{indent} return;"); - source.AppendLine($"{indent}}}"); + source.AppendLine($"{bodyIndent}if (version < _version)"); + source.AppendLine($"{bodyIndent}{{"); + source.AppendLine($"{bodyIndent} Deserialize(reader, version);"); + source.AppendLine($"{bodyIndent} {parent}.MarkDirty();"); + source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization); + source.AppendLine($"{bodyIndent} return;"); + source.AppendLine($"{bodyIndent}}}"); } } if (serializableFieldSaveFlagMethodsDictionary.Count > 0) { source.AppendLine(); - source.AppendLine($"{indent}var saveFlags = reader.ReadEnum();"); + source.AppendLine($"{bodyIndent}var saveFlags = reader.ReadEnum();"); } foreach (var property in properties) @@ -137,11 +138,11 @@ namespace SerializationGenerator // Special case if (property.Type == "bool") { - source.AppendLine($"{indent}{property.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;"); + source.AppendLine($"{bodyIndent}{property.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;"); } else { - source.AppendLine($"{indent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{indent}{{"); + source.AppendLine($"{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{"); rule.GenerateDeserializationMethod( source, innerIndent, @@ -152,13 +153,13 @@ namespace SerializationGenerator if (serializableFieldSaveFlagMethods.GetFieldDefaultValue != null) { - source.AppendLine($"{indent}}}\n{indent}else\n{indent}{{"); + source.AppendLine($"{bodyIndent}}}\n{bodyIndent}else\n{bodyIndent}{{"); source.AppendLine( - $"{indent} {property.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();" + $"{bodyIndent} {property.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();" ); } - source.AppendLine($"{indent}}}"); + source.AppendLine($"{bodyIndent}}}"); } } else @@ -166,16 +167,16 @@ namespace SerializationGenerator source.AppendLine(); rule.GenerateDeserializationMethod( source, - indent, + bodyIndent, property, parentFieldOrProperty?.Name ?? "this" ); - (rule as IPostDeserializeMethod)?.PostDeserializeMethod(source, indent, property, compilation, classSymbol); + (rule as IPostDeserializeMethod)?.PostDeserializeMethod(source, bodyIndent, property, compilation, classSymbol); } } - source.GenerateAfterDeserialization($"{indent}", afterDeserialization); - source.GenerateMethodEnd(" "); + source.GenerateAfterDeserialization($"{bodyIndent}", afterDeserialization); + source.GenerateMethodEnd(indent); } private static void GenerateAfterDeserialization( diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs index da4685076..7b7ebcb7f 100644 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs +++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs @@ -26,13 +26,14 @@ namespace SerializationGenerator this StringBuilder source, Compilation compilation, string className, + string indent, bool isOverride ) { var serialType = (ITypeSymbol)compilation.GetTypeByMetadataName("Server.Serial"); source.GenerateConstructorStart( - " ", + indent, className, Accessibility.Public, new []{ (serialType, "serial") }.ToImmutableArray(), @@ -41,11 +42,11 @@ namespace SerializationGenerator if (!isOverride) { - source.AppendLine(@$" Serial = serial; - SetTypeRef(typeof({className}));"); + source.AppendLine($"{indent} Serial = serial;"); + source.AppendLine($"{indent} SetTypeRef(typeof({className}));"); } - source.GenerateMethodEnd(" "); + source.GenerateMethodEnd(indent); } } } diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs index d1c2d3344..d0d13653f 100644 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs +++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs @@ -27,6 +27,7 @@ namespace SerializationGenerator public static void GenerateSerializeMethod( this StringBuilder source, Compilation compilation, + string indent, bool isOverride, bool encodedVersion, ImmutableArray properties, @@ -36,7 +37,7 @@ namespace SerializationGenerator var genericWriterInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_WRITER_INTERFACE); source.GenerateMethodStart( - " ", + indent, "Serialize", Accessibility.Public, isOverride, @@ -44,34 +45,34 @@ namespace SerializationGenerator ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer")) ); - const string indent = " "; - const string innerIndent = $"{indent} "; + var bodyIndent = $"{indent} "; + var innerIndent = $"{bodyIndent} "; if (isOverride) { - source.AppendLine($"{indent}base.Serialize(writer);"); + source.AppendLine($"{bodyIndent}base.Serialize(writer);"); source.AppendLine(); } // Version - source.AppendLine($"{indent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);"); + source.AppendLine($"{bodyIndent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);"); // Let's collect the flags if (serializableFieldSaveFlagMethodsDictionary.Count > 0) { - source.AppendLine($"\n{indent}var saveFlags = SaveFlag.None;"); + source.AppendLine($"\n{bodyIndent}var saveFlags = SaveFlag.None;"); foreach (var (order, saveFlagMethods) in serializableFieldSaveFlagMethodsDictionary) { - source.AppendLine($"{indent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{indent}{{"); + source.AppendLine($"{bodyIndent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{bodyIndent}{{"); var propertyName = properties[order].Name; source.AppendLine($"{innerIndent}saveFlags |= SaveFlag.{propertyName};"); - source.AppendLine($"{indent}}}"); + source.AppendLine($"{bodyIndent}}}"); } - source.AppendLine($"{indent}writer.WriteEnum(saveFlags);"); + source.AppendLine($"{bodyIndent}writer.WriteEnum(saveFlags);"); } foreach (var property in properties) @@ -81,13 +82,13 @@ namespace SerializationGenerator // Special case if (property.Type != "bool") { - source.AppendLine($"\n{indent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{indent}{{"); + source.AppendLine($"\n{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{"); SerializableMigrationRulesEngine.Rules[property.Rule].GenerateSerializationMethod( source, innerIndent, property ); - source.AppendLine($"{indent}}}"); + source.AppendLine($"{bodyIndent}}}"); } } else @@ -95,13 +96,13 @@ namespace SerializationGenerator source.AppendLine(); SerializableMigrationRulesEngine.Rules[property.Rule].GenerateSerializationMethod( source, - indent, + bodyIndent, property ); } } - source.GenerateMethodEnd(" "); + source.GenerateMethodEnd(indent); } } } diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs index 712192831..2d84a56ad 100644 --- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs +++ b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs @@ -26,12 +26,11 @@ namespace SerializationGenerator public static void GenerateMigrationContentStruct( this StringBuilder source, Compilation compilation, + string indent, SerializableMetadata migration, INamedTypeSymbol classSymbol ) { - const string indent = " "; - source.AppendLine($"{indent}ref struct V{migration.Version}Content"); source.AppendLine($"{indent}{{"); var properties = migration.Properties ?? ImmutableArray.Empty; @@ -46,7 +45,7 @@ namespace SerializationGenerator source.AppendLine($"{indent} internal readonly {type} {serializableProperty.Name};"); } - const string innerIndent = $"{indent} "; + var innerIndent = $"{indent} "; var usesSaveFlags = properties.Any(p => p.UsesSaveFlag == true); diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs index 9da11a1cc..c25999cd8 100644 --- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs +++ b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs @@ -23,14 +23,14 @@ namespace SerializationGenerator { public static void GenerateClassStart( this StringBuilder source, - string className, + INamedTypeSymbol classSymbol, string indent, ImmutableArray interfaces, - Accessibility accessor = Accessibility.Public, bool isPartial = true ) { - source.Append($"{indent}{accessor.ToFriendlyString()} {(isPartial ? "partial " : "")}class {className}"); + var accessor = classSymbol.DeclaredAccessibility; + source.Append($"{indent}{accessor.ToFriendlyString()} {(isPartial ? "partial " : "")}class {classSymbol.Name}"); if (!interfaces.IsEmpty) { source.Append(" : "); @@ -55,6 +55,7 @@ namespace SerializationGenerator // TODO: Generalize this to any field using dynamic indentation public static void GenerateClassField( this StringBuilder source, + string indent, Accessibility accessors, InstanceModifier instance, string type, @@ -65,7 +66,7 @@ namespace SerializationGenerator var instanceStr = instance == InstanceModifier.None ? "" : $"{instance.ToFriendlyString()} "; var accessorStr = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} "; var valueStr = value == null ? "" : $" = {value}"; - source.AppendLine($" {accessorStr}{instanceStr}{type} {variableName}{valueStr};"); + source.AppendLine($"{indent}{accessorStr}{instanceStr}{type} {variableName}{valueStr};"); } } } From 3bfd5c4d3e5cf4221e9b800728a006bef5a3c436 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:12:32 -0700 Subject: [PATCH 2/2] fix: Adds CanSeeStaffOnly for staff only items (#739) --- Projects/Server/Items/Item.cs | 2 ++ Projects/Server/Maps/Map.cs | 4 +--- Projects/Server/Mobiles/Mobile.cs | 19 +++++++------------ .../UOContent/Engines/Spawners/BaseSpawner.cs | 9 +++++---- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 5bd6eb253..64ce8c5f5 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -408,6 +408,8 @@ namespace Server public virtual bool IsVirtualItem => false; + public virtual bool CanSeeStaffOnly(Mobile from) => from.AccessLevel > AccessLevel.Counselor; + public virtual int LabelNumber { get diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 3ddb12526..0c0e489ec 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -1238,9 +1238,7 @@ namespace Server if (org.X > dest.X || org.X == dest.X && org.Y > dest.Y || org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) { - var swap = org; - org = dest; - dest = swap; + (org, dest) = (dest, org); } int height; diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 751518a26..8c51c64e3 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -5195,7 +5195,7 @@ namespace Server var map = from.Map; - if (DragEffects && map != null && (root == null || root is Item)) + if (DragEffects && map != null && root is null or Item) { var eable = map.GetClientsInRange(from.Location); var rootItem = root as Item; @@ -7181,17 +7181,12 @@ namespace Server public virtual bool CanSee(object o) { - if (o is Item item) + return o switch { - return CanSee(item); - } - - if (o is Mobile mobile) - { - return CanSee(mobile); - } - - return true; + Item item => CanSee(item), + Mobile mobile => CanSee(mobile), + _ => true + }; } public virtual bool CanSee(Item item) @@ -7239,7 +7234,7 @@ namespace Server } } - return !item.Deleted && item.Map == m_Map && (item.Visible || m_AccessLevel > AccessLevel.Counselor); + return !item.Deleted && item.Map == m_Map && (item.Visible || item.CanSeeStaffOnly(this)); } public virtual bool CanSee(Mobile m) diff --git a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs index dcd1689d9..2920ec281 100644 --- a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs @@ -308,12 +308,13 @@ namespace Server.Engines.Spawners DoTimer(TimeSpan.FromSeconds(1)); } + public override bool CanSeeStaffOnly(Mobile from) => from.AccessLevel >= AccessLevel.Developer; + + public override bool IsAccessibleTo(Mobile from) => from.AccessLevel >= AccessLevel.Developer; + public override void OnDoubleClick(Mobile from) { - if (from.AccessLevel >= AccessLevel.Developer) - { - from.SendGump(new SpawnerGump(this)); - } + from.SendGump(new SpawnerGump(this)); } public virtual void GetSpawnerProperties(ObjectPropertyList list)