예제 #1
0
 protected abstract void AddEach(AddEachOperation operation);
        public void ApplyPatch(int patchIndex, AssetLocation patchSourcefile, JsonPatch jsonPatch, ref int applied, ref int notFound, ref int errorCount)
        {
            EnumAppSide targetSide = jsonPatch.Side == null ? jsonPatch.File.Category.SideType : (EnumAppSide)jsonPatch.Side;

            if (targetSide != EnumAppSide.Universal && jsonPatch.Side != api.Side)
            {
                return;
            }

            if (jsonPatch.File == null)
            {
                api.World.Logger.Error("Patch {0} in {1} failed because it is missing the target file property", patchIndex, patchSourcefile);
                return;
            }

            var loc = jsonPatch.File.Clone();

            if (jsonPatch.File.Path.EndsWith("*"))
            {
                List <IAsset> assets = api.Assets.GetMany(jsonPatch.File.Path.TrimEnd('*'), jsonPatch.File.Domain, false);
                foreach (var val in assets)
                {
                    jsonPatch.File = val.Location;
                    ApplyPatch(patchIndex, patchSourcefile, jsonPatch, ref applied, ref notFound, ref errorCount);
                }

                jsonPatch.File = loc;

                return;
            }



            if (!loc.Path.EndsWith(".json"))
            {
                loc.Path += ".json";
            }

            var asset = api.Assets.TryGet(loc);

            if (asset == null)
            {
                if (jsonPatch.File.Category == null)
                {
                    api.World.Logger.VerboseDebug("Patch {0} in {1}: File {2} not found. Wrong asset category", patchIndex, patchSourcefile, loc);
                }
                else
                {
                    EnumAppSide catSide = jsonPatch.File.Category.SideType;
                    if (catSide != EnumAppSide.Universal && api.Side != catSide)
                    {
                        api.World.Logger.VerboseDebug("Patch {0} in {1}: File {2} not found. Hint: This asset is usually only loaded {3} side", patchIndex, patchSourcefile, loc, catSide);
                    }
                    else
                    {
                        api.World.Logger.VerboseDebug("Patch {0} in {1}: File {2} not found", patchIndex, patchSourcefile, loc);
                    }
                }


                notFound++;
                return;
            }

            Operation op = null;

            switch (jsonPatch.Op)
            {
            case EnumJsonPatchOp.Add:
                if (jsonPatch.Value == null)
                {
                    api.World.Logger.Error("Patch {0} in {1} failed probably because it is an add operation and the value property is not set or misspelled", patchIndex, patchSourcefile);
                    errorCount++;
                    return;
                }
                op = new AddOperation()
                {
                    Path = new Tavis.JsonPointer(jsonPatch.Path), Value = jsonPatch.Value.Token
                };
                break;

            case EnumJsonPatchOp.AddEach:
                if (jsonPatch.Value == null)
                {
                    api.World.Logger.Error("Patch {0} in {1} failed probably because it is an add each operation and the value property is not set or misspelled", patchIndex, patchSourcefile);
                    errorCount++;
                    return;
                }
                op = new AddEachOperation()
                {
                    Path = new Tavis.JsonPointer(jsonPatch.Path), Value = jsonPatch.Value.Token
                };
                break;

            case EnumJsonPatchOp.Remove:
                op = new RemoveOperation()
                {
                    Path = new Tavis.JsonPointer(jsonPatch.Path)
                };
                break;

            case EnumJsonPatchOp.Replace:
                if (jsonPatch.Value == null)
                {
                    api.World.Logger.Error("Patch {0} in {1} failed probably because it is a replace operation and the value property is not set or misspelled", patchIndex, patchSourcefile);
                    errorCount++;
                    return;
                }
                op = new ReplaceOperation()
                {
                    Path = new Tavis.JsonPointer(jsonPatch.Path), Value = jsonPatch.Value.Token
                };
                break;

            case EnumJsonPatchOp.Copy:
                op = new CopyOperation()
                {
                    Path = new Tavis.JsonPointer(jsonPatch.Path), FromPath = new JsonPointer(jsonPatch.FromPath)
                };
                break;

            case EnumJsonPatchOp.Move:
                op = new MoveOperation()
                {
                    Path = new Tavis.JsonPointer(jsonPatch.Path), FromPath = new JsonPointer(jsonPatch.FromPath)
                };
                break;
            }

            PatchDocument patchdoc = new PatchDocument(op);
            JToken        token;

            try
            {
                token = JToken.Parse(asset.ToText());
            }
            catch (Exception e)
            {
                api.World.Logger.Error("Patch {0} (target: {3}) in {1} failed probably because the syntax of the value is broken: {2}", patchIndex, patchSourcefile, e, loc);
                errorCount++;
                return;
            }

            try
            {
                patchdoc.ApplyTo(token);
            }
            catch (PathNotFoundException p)
            {
                api.World.Logger.Error("Patch {0} (target: {4}) in {1} failed because supplied path {2} is invalid: {3}", patchIndex, patchSourcefile, jsonPatch.Path, p.Message, loc);
                errorCount++;
                return;
            }
            catch (Exception e)
            {
                api.World.Logger.Error("Patch {0} (target: {3}) in {1} failed, following Exception was thrown: {2}", patchIndex, patchSourcefile, e.Message, loc);
                errorCount++;
                return;
            }

            string text = token.ToString();

            asset.Data = Encoding.UTF8.GetBytes(text);

            applied++;
        }