예제 #1
0
 public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
 {
     try
     {
         return(new AdaptResult
         {
             Status = MapFileStatus.Compatible,
         });
     }
     catch (NotSupportedException)
     {
         return(new AdaptResult
         {
             Status = MapFileStatus.Unadaptable,
         });
     }
     catch (Exception e)
     {
         return(new AdaptResult
         {
             Status = MapFileStatus.ParseError,
             Diagnostics = new[] { e.Message },
         });
     }
 }
예제 #2
0
 public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
 {
     return(new AdaptResult
     {
         Status = MapFileStatus.Compatible,
     });
 }
예제 #3
0
 public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
 {
     return(new AdaptResult
     {
         Status = targetPatch.Patch >= GamePatch.v1_30_0 && targetPatch.Patch <= GamePatch.v1_30_4 ? MapFileStatus.Compatible : MapFileStatus.Unadaptable,
     });
 }
예제 #4
0
 public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
 {
     try
     {
         using var reader = new BinaryReader(stream);
         var mapEnvironment = reader.ReadMapEnvironment();
         return(new AdaptResult
         {
             Status = MapFileStatus.Compatible,
         });
     }
     catch (NotSupportedException)
     {
         return(new AdaptResult
         {
             Status = MapFileStatus.Unadaptable,
         });
     }
     catch (Exception e)
     {
         return(new AdaptResult
         {
             Status = MapFileStatus.ParseError,
             Diagnostics = new[] { e.Message },
         });
     }
 }
예제 #5
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                using var reader = new BinaryReader(stream);
                var mapSounds = reader.ReadMapSounds();
                if (mapSounds.GetMinimumPatch() <= targetPatch.Patch)
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.Compatible,
                    });
                }

                try
                {
                    if (mapSounds.TryDowngrade(targetPatch.Patch))
                    {
                        var newMapSoundsFileStream = new MemoryStream();
                        using var writer = new BinaryWriter(newMapSoundsFileStream, new UTF8Encoding(false, true), true);
                        writer.Write(mapSounds);

                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Adapted,
                            AdaptedFileStream = newMapSoundsFileStream,
                        });
                    }
                    else
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Unadaptable,
                        });
                    }
                }
                catch
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.AdapterError,
                    });
                }
            }
            catch (NotSupportedException)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.Unadaptable,
                });
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }
예제 #6
0
 public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
 {
     // TODO
     return(new AdaptResult
     {
         Status = MapFileStatus.Unknown,
     });
 }
예제 #7
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                // TODO: War3Net.Modeling.BinaryModelParser.Parse(stream)

                using var reader = new BinaryReader(stream);
                reader.ReadInt32();

                while (stream.Length - stream.Position > 8)
                {
                    // Find VERS chunk.
                    var chunkTag  = new string(reader.ReadChars(4));
                    var chunkSize = reader.ReadInt32();
                    if (chunkTag == "VERS")
                    {
                        var version = reader.ReadUInt32();
                        if (version > 800 && targetPatch.Patch < GamePatch.v1_32_0)
                        {
                            return(new AdaptResult
                            {
                                Status = MapFileStatus.Unadaptable,
                                Diagnostics = new[] { $"Model version not supported: v{version}" },
                            });
                        }
                        else
                        {
                            return(new AdaptResult
                            {
                                Status = MapFileStatus.Compatible,
                            });
                        }
                    }
                    else
                    {
                        reader.ReadBytes(chunkSize);
                    }
                }

                // Unable to find VERS chunk.
                return(new AdaptResult
                {
                    // Status = MapFileStatus.ParseError,
                    Status = MapFileStatus.Unknown,
                });
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }
예제 #8
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                using var reader = new BinaryReader(stream);
                var campaignInfo = reader.ReadCampaignInfo();

                var targetPatchEditorVersion = targetPatch.Patch.GetEditorVersion();
                if (campaignInfo.EditorVersion == targetPatchEditorVersion)
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.Compatible,
                    });
                }

                try
                {
                    campaignInfo.EditorVersion = targetPatchEditorVersion;

                    var newCampaignInfoFileStream = new MemoryStream();
                    using var writer = new BinaryWriter(newCampaignInfoFileStream, new UTF8Encoding(false, true), true);
                    writer.Write(campaignInfo);

                    return(new AdaptResult
                    {
                        Status = MapFileStatus.Adapted,
                        AdaptedFileStream = newCampaignInfoFileStream,
                    });
                }
                catch
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.AdapterError,
                    });
                }
            }
            catch (NotSupportedException)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.Unadaptable,
                });
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }
예제 #9
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                var upgradeDataPath = Path.Combine(targetPatch.GameDataPath, PathConstants.UpgradeDataPath);
                if (!File.Exists(upgradeDataPath))
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.ConfigError,
                        Diagnostics = upgradeDataPath.GetFileNotFoundDiagnostics(),
                    });
                }

                var upgradeMetaDataPath = Path.Combine(targetPatch.GameDataPath, PathConstants.UpgradeMetaDataPath);
                if (!File.Exists(upgradeMetaDataPath))
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.ConfigError,
                        Diagnostics = upgradeMetaDataPath.GetFileNotFoundDiagnostics(),
                    });
                }

                using var reader = new BinaryReader(stream);
                var mapUpgradeObjectData = reader.ReadMapUpgradeObjectData();

                try
                {
                    var knownIds = new HashSet <int>();
                    knownIds.AddItemsFromSylkTable(upgradeDataPath, DataConstants.UpgradeDataKeyColumn);

                    var knownProperties = new HashSet <int>();
                    knownProperties.AddItemsFromSylkTable(upgradeMetaDataPath, DataConstants.MetaDataIdColumn);

                    var diagnostics = new List <string>();

                    var baseUpgrades = new List <LevelObjectModification>();
                    foreach (var upgrade in mapUpgradeObjectData.BaseUpgrades)
                    {
                        if (!knownIds.Contains(upgrade.OldId))
                        {
                            diagnostics.Add($"Unknown base upgrade: '{upgrade.OldId.ToRawcode()}'");
                            continue;
                        }

                        if (upgrade.Modifications.Any(property => !knownProperties.Contains(property.Id)))
                        {
                            diagnostics.AddRange(upgrade.Modifications.Where(property => !knownProperties.Contains(property.Id)).Select(property => $"Unknown property: '{property.Id.ToRawcode()}'"));
                            upgrade.Modifications.RemoveAll(property => !knownProperties.Contains(property.Id));
                        }

                        baseUpgrades.Add(upgrade);
                    }

                    var newUpgrades = new List <LevelObjectModification>();
                    foreach (var upgrade in mapUpgradeObjectData.NewUpgrades)
                    {
                        if (!knownIds.Contains(upgrade.OldId))
                        {
                            diagnostics.Add($"Unknown base upgrade: '{upgrade.OldId.ToRawcode()}'");
                            continue;
                        }

                        if (knownIds.Contains(upgrade.NewId))
                        {
                            diagnostics.Add($"Conflicting upgrade: '{upgrade.NewId.ToRawcode()}'");
                            continue;
                        }

                        if (upgrade.Modifications.Any(property => !knownProperties.Contains(property.Id)))
                        {
                            diagnostics.AddRange(upgrade.Modifications.Where(property => !knownProperties.Contains(property.Id)).Select(property => $"Unknown property: '{property.Id.ToRawcode()}'"));
                            upgrade.Modifications.RemoveAll(property => !knownProperties.Contains(property.Id));
                        }

                        newUpgrades.Add(upgrade);
                    }

                    if (diagnostics.Count > 0)
                    {
                        var memoryStream = new MemoryStream();
                        using var writer = new BinaryWriter(memoryStream, new UTF8Encoding(false, true), true);
                        writer.Write(new MapUpgradeObjectData(mapUpgradeObjectData.FormatVersion)
                        {
                            BaseUpgrades = baseUpgrades,
                            NewUpgrades  = newUpgrades,
                        });

                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Adapted,
                            Diagnostics = diagnostics.ToArray(),
                            AdaptedFileStream = memoryStream,
                        });
                    }
                    else
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Compatible,
                        });
                    }
                }
                catch
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.AdapterError,
                    });
                }
            }
            catch (NotSupportedException)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.Unadaptable,
                });
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }
예제 #10
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                var commonJPath = Path.Combine(targetPatch.GameDataPath, PathConstants.CommonJPath);
                if (!File.Exists(commonJPath))
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.ConfigError,
                        Diagnostics = commonJPath.GetFileNotFoundDiagnostics(),
                    });
                }

                var blizzardJPath = Path.Combine(targetPatch.GameDataPath, PathConstants.BlizzardJPath);
                if (!File.Exists(blizzardJPath))
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.ConfigError,
                        Diagnostics = blizzardJPath.GetFileNotFoundDiagnostics(),
                    });
                }

                var commonJText            = File.ReadAllText(commonJPath);
                var commonJCompilationUnit = JassSyntaxFactory.ParseCompilationUnit(commonJText);

                var blizzardJText            = File.ReadAllText(blizzardJPath);
                var blizzardJCompilationUnit = JassSyntaxFactory.ParseCompilationUnit(blizzardJText);

                string scriptText;
                using (var reader = new StreamReader(stream, leaveOpen: true))
                {
                    scriptText = reader.ReadToEnd();
                }

                var compilationUnit = JassSyntaxFactory.ParseCompilationUnit(scriptText);

                try
                {
                    var context = new JassMapScriptAdapterContext();

                    foreach (var declaration in commonJCompilationUnit.Declarations)
                    {
                        RegisterDeclaration(declaration, context);
                    }

                    foreach (var declaration in blizzardJCompilationUnit.Declarations)
                    {
                        RegisterDeclaration(declaration, context);
                    }

                    // Common.j and Blizzard.j should not cause any diagnostics.
                    if (context.Diagnostics.Count > 0)
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.AdapterError,
                            Diagnostics = context.Diagnostics.ToArray(),
                        });
                    }

                    if (TryAdaptCompilationUnit(context, compilationUnit, out var adaptedCompilationUnit))
                    {
                        var memoryStream = new MemoryStream();
                        using var writer = new StreamWriter(memoryStream, new UTF8Encoding(false, true), leaveOpen: true);

                        var renderer = new JassRenderer(writer);
                        renderer.Render(adaptedCompilationUnit);

                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Adapted,
                            Diagnostics = context.Diagnostics.ToArray(),
                            AdaptedFileStream = memoryStream,
                        });
                    }

                    if (context.Diagnostics.Count == 0)
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Compatible,
                        });
                    }
                    else
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Incompatible,
                            Diagnostics = context.Diagnostics.ToArray(),
                        });
                    }
                }
                catch
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.AdapterError,
                    });
                }
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }
예제 #11
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                string scriptText;
                using (var reader = new StreamReader(stream, null, true, -1, true))
                {
                    scriptText = reader.ReadToEnd();
                }

                try
                {
                    var diagnostics      = new List <string>();
                    var regexDiagnostics = new List <RegexDiagnostic>();

                    // Find incompatible identifiers
                    var incompatibleIdentifiers = new HashSet <string>();
                    incompatibleIdentifiers.UnionWith(CommonIdentifiersProvider.GetIdentifiers(targetPatch.Patch, originPatch));
                    incompatibleIdentifiers.UnionWith(BlizzardIdentifiersProvider.GetIdentifiers(targetPatch.Patch, originPatch));

                    foreach (var incompatibleIdentifier in incompatibleIdentifiers)
                    {
                        var regex      = new Regex($"\\b{incompatibleIdentifier}\\b");
                        var matches    = regex.Matches(scriptText);
                        var usageCount = matches.Count;
                        if (usageCount > 0)
                        {
                            diagnostics.Add($"Found incompatible identifier: '{incompatibleIdentifier}' ({usageCount}x)");
                            regexDiagnostics.Add(new RegexDiagnostic
                            {
                                DisplayText = $"Identifier: '{incompatibleIdentifier}'",
                                Matches     = usageCount,
                                Regex       = regex,
                            });
                        }
                    }

                    // Find incompatible audio formats
                    var incompatibleAudioFormats = new HashSet <string>();
                    if (targetPatch.Patch < GamePatch.v1_32_0)
                    {
                        incompatibleAudioFormats.Add("flac");
                    }
                    if (targetPatch.Patch < GamePatch.v1_30_0 || targetPatch.Patch > GamePatch.v1_30_4)
                    {
                        incompatibleAudioFormats.Add("ogg");
                    }

                    foreach (var incompatibleAudioFormat in incompatibleAudioFormats)
                    {
                        var regex      = new Regex($"\"(\\w|/|\\\\)+.{incompatibleAudioFormat}\"");
                        var matches    = regex.Matches(scriptText);
                        var usageCount = matches.Count;
                        if (usageCount > 0)
                        {
                            diagnostics.Add($"Found incompatible audio formats: '{incompatibleAudioFormat}' ({usageCount}x)");
                            regexDiagnostics.Add(new RegexDiagnostic
                            {
                                DisplayText = $"Audio file format: '{incompatibleAudioFormat}'",
                                Matches     = usageCount,
                                Regex       = regex,
                            });
                        }
                    }

                    // Find incompatible frame names
                    var incompatibleFrameNames = new HashSet <string>();
                    if (targetPatch.Patch >= GamePatch.v1_31_0)
                    {
                        incompatibleFrameNames.UnionWith(FrameNamesProvider.GetFrameNames(targetPatch.Patch, originPatch).Select(frame => frame.name));
                    }

                    foreach (var incompatibleFrameName in incompatibleFrameNames)
                    {
                        var regex      = new Regex($"{nameof(War3Api.Common.BlzGetFrameByName)}( |\t)*\\(\"{incompatibleFrameName}\"( |\t)*,( |\t)*");
                        var matches    = regex.Matches(scriptText);
                        var usageCount = matches.Count;
                        if (usageCount > 0)
                        {
                            diagnostics.Add($"Found incompatible frame names: '{incompatibleFrameName}' ({usageCount}x)");
                            regexDiagnostics.Add(new RegexDiagnostic
                            {
                                DisplayText = $"Frame name: '{incompatibleFrameName}'",
                                Matches     = usageCount,
                                Regex       = regex,
                            });
                        }
                    }

                    if (diagnostics.Count == 0)
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Compatible,
                        });
                    }
                    else
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Incompatible,
                            Diagnostics = diagnostics.ToArray(),
                            RegexDiagnostics = regexDiagnostics.ToArray(),
                        });
                    }
                }
                catch
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.AdapterError,
                    });
                }
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }
예제 #12
0
        public AdaptResult AdaptFile(Stream stream, TargetPatch targetPatch, GamePatch originPatch)
        {
            try
            {
                var triggerDataPath = Path.Combine(targetPatch.GameDataPath, PathConstants.TriggerDataPath);
                if (!File.Exists(triggerDataPath))
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.ConfigError,
                        Diagnostics = triggerDataPath.GetFileNotFoundDiagnostics(),
                    });
                }

                using var reader = new BinaryReader(stream);
                var mapTriggers = reader.ReadMapTriggers();

                try
                {
                    var triggerDataText   = File.ReadAllText(triggerDataPath);
                    var triggerDataReader = new StringReader(triggerDataText);
                    var triggerData       = triggerDataReader.ReadTriggerData();

                    stream.Position = 0;
                    reader.ReadMapTriggers(triggerData);
                }
                catch (KeyNotFoundException e)
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.Incompatible,
                        Diagnostics = new[] { e.Message },
                    });
                }
                catch (Exception e)
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.ParseError,
                        Diagnostics = new[] { e.Message },
                    });
                }

                if (mapTriggers.GetMinimumPatch() <= targetPatch.Patch)
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.Compatible,
                    });
                }

                try
                {
                    if (mapTriggers.TryDowngrade(targetPatch.Patch))
                    {
                        var newMapTriggersFileStream = new MemoryStream();
                        using var writer = new BinaryWriter(newMapTriggersFileStream, new UTF8Encoding(false, true), true);
                        writer.Write(mapTriggers);

                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Adapted,
                            AdaptedFileStream = newMapTriggersFileStream,
                        });
                    }
                    else
                    {
                        return(new AdaptResult
                        {
                            Status = MapFileStatus.Unadaptable,
                        });
                    }
                }
                catch
                {
                    return(new AdaptResult
                    {
                        Status = MapFileStatus.AdapterError,
                    });
                }
            }
            catch (Exception e)
            {
                return(new AdaptResult
                {
                    Status = MapFileStatus.ParseError,
                    Diagnostics = new[] { e.Message },
                });
            }
        }