private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundAheadTime = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundAheadTime &&
                    instructionList[i].opcode == OpCodes.Ldfld &&
                    ((FieldInfo)instructionList[i].operand).Name == "aheadTime")
                {
                    foundAheadTime = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, _getAheadTime));
                    instructionList.Insert(i - 1, new CodeInstruction(OpCodes.Ldloc_3));
                    instructionList.Insert(i - 1, new CodeInstruction(OpCodes.Ldloc_1));
                }
            }

            if (!foundAheadTime)
            {
                NoodleLogger.Log("Failed to find aheadTime ldfld!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
        public static void TryGetPointData(dynamic customData, string pointName, out PointDefinition pointData, Dictionary <string, PointDefinition> pointDefinitions)
        {
            dynamic pointString = Trees.at(customData, pointName);

            switch (pointString)
            {
            case null:
                pointData = null;
                break;

            case PointDefinition castedData:
                pointData = castedData;
                break;

            case string castedString:
                if (!pointDefinitions.TryGetValue(castedString, out pointData))
                {
                    NoodleLogger.Log($"Could not find point definition {castedString}!", IPA.Logging.Logger.Level.Error);
                    pointData = null;
                }

                break;

            default:
                pointData = PointDefinition.DynamicToPointData(pointString);
                if (pointData != null)
                {
                    ((IDictionary <string, object>)customData)[pointName] = pointData;
                }

                break;
            }
        }
Ejemplo n.º 3
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundHeadLocalPos = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundHeadLocalPos &&
                    instructionList[i].opcode == OpCodes.Call &&
                    ((MethodInfo)instructionList[i].operand).Name == "HeadOffsetZ")
                {
                    foundHeadLocalPos          = true;
                    instructionList[i].operand = _headOffsetZNotPsuedo;

                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldfld, _headTransformField));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Callvirt, _localPositionMethod));

                    instructionList.RemoveAt(0);
                }
            }

            if (!foundHeadLocalPos)
            {
                NoodleLogger.Log("Failed to find call to HeadOffsetZ!", IPA.Logging.Logger.Level.Error);
            }

            instructionList.ForEach(n => NoodleLogger.Log(n));

            return(instructionList.AsEnumerable());
        }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundJumpDuration = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundJumpDuration &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_jumpDuration")
                {
                    foundJumpDuration = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, _getJumpDuration));
                    instructionList.Insert(i - 2, new CodeInstruction(OpCodes.Ldarg_1));
                }
            }

            if (!foundJumpDuration)
            {
                NoodleLogger.Log("Failed to find get_jumpDuration call!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 5
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundTime = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundTime &&
                    instructionList[i].opcode == OpCodes.Stloc_0)
                {
                    foundTime = true;
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldfld, _obstacleDataField));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 3, new CodeInstruction(OpCodes.Ldfld, _move1DurationField));
                    instructionList.Insert(i + 4, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 5, new CodeInstruction(OpCodes.Ldfld, _finishMovementTime));
                    instructionList.Insert(i + 6, new CodeInstruction(OpCodes.Call, _obstacleTimeAdjust));
                }
            }

            if (!foundTime)
            {
                NoodleLogger.Log("Failed to find stloc.0!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundBeatmapData = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundBeatmapData &&
                    instructionList[i].opcode == OpCodes.Call &&
                    ((MethodInfo)instructionList[i].operand).Name == "CreateTransformedBeatmapData")
                {
                    foundBeatmapData = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldloc_S, 9));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Ldloc_S, 10));
                    instructionList.Insert(i + 3, new CodeInstruction(OpCodes.Call, _reorderLineData));
                }
            }

            if (!foundBeatmapData)
            {
                NoodleLogger.Log("Failed to find V_12 stloc.s!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundCondition = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundCondition &&
                    instructionList[i].operand is Label &&
                    instructionList[i].operand.GetHashCode() == 1)
                {
                    foundCondition = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldloc_1));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Call, FakeNoteHelper._boundsNullCheck));
                    instructionList.Insert(i + 3, new CodeInstruction(OpCodes.Brtrue_S, instructionList[i].operand));
                }
            }

            if (!foundCondition)
            {
                NoodleLogger.Log("Failed to find brtrue.s to IL_004E!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 8
0
        public static IEnumerable <Track> GetTrackArray(dynamic customData, string name = TRACK)
        {
            IEnumerable <string> trackNames = ((List <object>)Trees.at(customData, name)).Cast <string>();

            if (trackNames == null)
            {
                return(null);
            }

            HashSet <Track> tracks = new HashSet <Track>();

            foreach (string trackName in trackNames)
            {
                if (Tracks.TryGetValue(trackName, out Track track))
                {
                    tracks.Add(track);
                }
                else
                {
                    NoodleLogger.Log($"Could not find track {trackName}!", IPA.Logging.Logger.Level.Error);
                }
            }

            return(tracks);
        }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundSpawnFlyingSprite            = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundSpawnFlyingSprite &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "SpawnFlyingSprite")
                {
                    foundSpawnFlyingSprite = true;

                    instructionList[i] = new CodeInstruction(OpCodes.Call, SpawnFlyingSpriteHelper._conditionedSpawnFlyingSprite);
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_2));
                }
            }

            if (!foundSpawnFlyingSprite)
            {
                NoodleLogger.Log("Failed to find call to SpawnFlyingSprite", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 10
0
        // This stupid assert runs a Contains() which is laggy when spawning an insane amount of walls
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundAssert           = false;
            int  instructrionListCount = instructionList.Count;

            for (int i = 0; i < instructrionListCount; i++)
            {
                if (!foundAssert &&
                    instructionList[i].opcode == OpCodes.Call &&
                    ((MethodInfo)instructionList[i].operand).Name == "That")
                {
                    foundAssert = true;

                    instructionList.RemoveRange(i - 9, 10);
                }
            }

            if (!foundAssert)
            {
                NoodleLogger.Log("Failed to find call to That!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 11
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundFlipYSide = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundFlipYSide &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_flipYSide")
                {
                    foundFlipYSide = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, _getFlipYSide));
                    instructionList.Insert(i - 2, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i - 1, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(NoteController), "_noteData")));
                }
            }

            if (!foundFlipYSide)
            {
                NoodleLogger.Log("Failed to find Get_flipYSide call!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 12
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundBeatmapData = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundBeatmapData &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "GetCopy")
                {
                    foundBeatmapData = true;

                    // yoink label5 so we can insert our code w/o breaking shit
                    CodeInstruction sourceLabel = instructionList[i - 4];
                    CodeInstruction newLabel    = new CodeInstruction(instructionList[i - 4]);
                    sourceLabel.labels.Clear();

                    instructionList.Insert(i - 4, newLabel);
                    instructionList.Insert(i - 3, new CodeInstruction(OpCodes.Call, _reorderLineData));
                    instructionList.Insert(i - 2, new CodeInstruction(OpCodes.Stloc_0));
                }
            }

            if (!foundBeatmapData)
            {
                NoodleLogger.Log("Failed to find GetCopy!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 13
0
        private static IReadonlyBeatmapData ReorderLineData(IReadonlyBeatmapData beatmapData)
        {
            if (beatmapData is CustomBeatmapData)
            {
                CustomBeatmapData customBeatmapData = (CustomBeatmapData)beatmapData.GetCopy();

                // there is some ambiguity with these variables but who frikkin cares
                float startHalfJumpDurationInBeats = 4;
                float maxHalfJumpDistance          = 18;
                float moveDuration = 0.5f;

                for (int i = 0; i < customBeatmapData.beatmapLinesData.Count; i++)
                {
                    BeatmapLineData beatmapLineData = customBeatmapData.beatmapLinesData[i] as BeatmapLineData;
                    foreach (BeatmapObjectData beatmapObjectData in beatmapLineData.beatmapObjectsData)
                    {
                        dynamic customData;
                        if (beatmapObjectData is CustomObstacleData || beatmapObjectData is CustomNoteData || beatmapObjectData is CustomWaypointData)
                        {
                            customData = beatmapObjectData;
                        }
                        else
                        {
                            NoodleLogger.Log("beatmapObjectData was not CustomObstacleData, CustomNoteData, or CustomWaypointData");
                            continue;
                        }

                        dynamic dynData = customData.customData;
                        float   noteJumpMovementSpeed   = (float?)Trees.at(dynData, NOTEJUMPSPEED) ?? GameplayCoreInstallerInstallBindings.CachedNoteJumpMovementSpeed;
                        float   noteJumpStartBeatOffset = (float?)Trees.at(dynData, NOTESPAWNOFFSET) ?? GameplayCoreInstallerInstallBindings.CachedNoteJumpStartBeatOffset;

                        // how do i not repeat this in a reasonable way
                        float num  = 60f / (float)Trees.at(dynData, "bpm");
                        float num2 = startHalfJumpDurationInBeats;
                        while (noteJumpMovementSpeed * num * num2 > maxHalfJumpDistance)
                        {
                            num2 /= 2f;
                        }

                        num2 += noteJumpStartBeatOffset;
                        if (num2 < 1f)
                        {
                            num2 = 1f;
                        }

                        float jumpDuration = num * num2 * 2f;
                        dynData.aheadTime = moveDuration + (jumpDuration * 0.5f);
                    }

                    _beatmapObjectsDataAccessor(ref beatmapLineData) = beatmapLineData.beatmapObjectsData.OrderBy(n => n.time - (float)((dynamic)n).customData.aheadTime).ToList();
                }

                return(customBeatmapData);
            }

            NoodleLogger.Log("beatmapData was not CustomBeatmapData", IPA.Logging.Logger.Level.Error);
            return(beatmapData);
        }
 private void Update()
 {
     if (_hitsoundQueue.Count > 0 && Time.frameCount != _lastFrame)
     {
         List <NoteController> noteControllers = new List <NoteController>(_hitsoundQueue);
         _hitsoundQueue.Clear();
         noteControllers.ForEach(n => _noteCutSoundEffectManager.HandleNoteWasSpawned(n));
         NoodleLogger.Log($"{noteControllers.Count} cut sounds moved to next frame!");
     }
 }
Ejemplo n.º 15
0
 internal void AddPoint(string pointDataName, PointDefinition pointData)
 {
     if (!PointData.TryGetValue(pointDataName, out _))
     {
         PointData.Add(pointDataName, pointData);
     }
     else
     {
         NoodleLogger.Log($"Duplicate point defintion name, {pointDataName} could not be registered!", IPA.Logging.Logger.Level.Error);
     }
 }
 internal static void Callback(CustomEventData customEventData)
 {
     if (customEventData.type == ASSIGNTRACKPARENT)
     {
         NoodleParentTrackEventData noodleData = (NoodleParentTrackEventData)NoodleEventDatas[customEventData];
         IEnumerable <Track>        tracks     = noodleData.ChildrenTracks;
         Track parentTrack = noodleData.ParentTrack;
         if (tracks != null && parentTrack != null)
         {
             ParentObject.AssignTrack(tracks, parentTrack, noodleData.Position, noodleData.Rotation, noodleData.LocalRotation, noodleData.Scale);
         }
         else
         {
             NoodleLogger.Log($"Missing _parentTrack or _childrenTracks!", IPA.Logging.Logger.Level.Error);
         }
     }
 }
        /*public static Track GetTrack(dynamic customData, string name = TRACK)
         * {
         *  string trackName = Trees.at(customData, name);
         *  if (trackName == null)
         *  {
         *      return null;
         *  }
         *
         *  if (Tracks.TryGetValue(trackName, out Track track))
         *  {
         *      return track;
         *  }
         *  else
         *  {
         *      NoodleLogger.Log($"Could not find track {trackName}!", IPA.Logging.Logger.Level.Error);
         *      return null;
         *  }
         * }*/

        public static Track GetTrackPreload(dynamic customData, IReadonlyBeatmapData beatmapData, string name = TRACK)
        {
            string trackName = Trees.at(customData, name);

            if (trackName == null)
            {
                return(null);
            }

            if (((CustomBeatmapData)beatmapData).customData.tracks.TryGetValue(trackName, out Track track))
            {
                return(track);
            }
            else
            {
                NoodleLogger.Log($"Could not find track {trackName}!", IPA.Logging.Logger.Level.Error);
                return(null);
            }
        }
Ejemplo n.º 18
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool  foundLabel  = false;
            bool  foundBounds = false;
            Label?label       = null;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundLabel &&
                    instructionList[i].operand is Label operandLabel &&
                    instructionList[i].operand.GetHashCode() == 0)
                {
                    foundLabel = true;

                    label = operandLabel;
                }

                if (!foundBounds &&
                    label.HasValue &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_bounds")
                {
                    foundBounds = true;

                    instructionList.Insert(i - 1, new CodeInstruction(OpCodes.Ldloc_1));
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Call, FakeNoteHelper._boundsNullCheck));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Brtrue_S, label.Value));
                }
            }

            if (!foundLabel)
            {
                NoodleLogger.Log("Failed to find br to IL_0134!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundBounds)
            {
                NoodleLogger.Log("Failed to find callvirt to get_bounds!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 19
0
        public static Track GetTrack(dynamic customData, string name = TRACK)
        {
            string trackName = Trees.at(customData, name);

            if (trackName == null)
            {
                return(null);
            }

            if (Tracks.TryGetValue(trackName, out Track track))
            {
                return(track);
            }
            else
            {
                NoodleLogger.Log($"Could not find track {trackName}!", IPA.Logging.Logger.Level.Error);
                return(null);
            }
        }
Ejemplo n.º 20
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundInit         = false;
            bool foundJumpStartPos = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundJumpStartPos &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_jumpStartPos")
                {
                    foundJumpStartPos = true;

                    instructionList.RemoveRange(i - 2, 4);
                    instructionList.Insert(i - 2, new CodeInstruction(OpCodes.Call, _getNoteControllerPosition));
                }
            }

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundInit &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "Init")
                {
                    foundInit = true;

                    instructionList[i - 1] = new CodeInstruction(OpCodes.Call, _getNoteControllerRotation);
                }
            }

            if (!foundJumpStartPos)
            {
                NoodleLogger.Log("Failed to find callvirt to get_jumpStartPos!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundInit)
            {
                NoodleLogger.Log("Failed to find callvirt to Init!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundFinalPosition = false;
            bool foundPosition      = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundFinalPosition &&
                    instructionList[i].opcode == OpCodes.Stfld &&
                    ((FieldInfo)instructionList[i].operand).Name == "_localPosition")
                {
                    foundFinalPosition = true;
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, _definiteNoteFloorMovement));
                }

                if (!foundPosition &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "set_position")
                {
                    foundPosition = true;
                    instructionList[i].operand = _setLocalPosition;
                }
            }

            if (!foundFinalPosition)
            {
                NoodleLogger.Log("Failed to find _localPosition stfld!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundPosition)
            {
                NoodleLogger.Log("Failed to find callvirt to set_position!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 22
0
        // Because we reorder beatmapLinesData for per object njs/offset, it messes up this script (which is super pepega pls beat games fix), so we resort beatmapLinesData in here
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundLinesData = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundLinesData &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_beatmapLinesData")
                {
                    foundLinesData = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, _sortBeatmapLinesData));
                }
            }

            if (!foundLinesData)
            {
                NoodleLogger.Log("Failed to find callvirt to get_beatmapLinesData!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundIntersectingObstacles        = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundIntersectingObstacles &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_intersectingObstacles")
                {
                    foundIntersectingObstacles = true;

                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, FakeNoteHelper._obstacleFakeCheck));
                }
            }

            if (!foundIntersectingObstacles)
            {
                NoodleLogger.Log("Failed to find callvirt to get_intersectingObstacles!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 24
0
        private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
        {
            List<CodeInstruction> instructionList = instructions.ToList();
            bool foundTime = false;
            bool foundFinalPosition = false;
            bool foundZOffset = false;
            bool foundLook = false;
            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundTime &&
                    instructionList[i].opcode == OpCodes.Stloc_0)
                {
                    foundTime = true;
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldfld, _jumpDurationField));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Call, _noteJumpTimeAdjust));
                }

                if (!foundFinalPosition &&
                    instructionList[i].opcode == OpCodes.Stind_R4)
                {
                    foundFinalPosition = true;
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 3, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 4, new CodeInstruction(OpCodes.Ldfld, _localPositionField));
                    instructionList.Insert(i + 5, new CodeInstruction(OpCodes.Ldloc_1));
                    instructionList.Insert(i + 6, new CodeInstruction(OpCodes.Call, _definiteNoteJump));
                    instructionList.Insert(i + 7, new CodeInstruction(OpCodes.Stfld, _localPositionField));
                }

                // is there a better way of checking labels?
                if (!foundZOffset &&
                    instructionList[i].operand is Label &&
                    instructionList[i].operand.GetHashCode() == 21)
                {
                    foundZOffset = true;

                    // Add addition check to our quirky little variable to skip end position offset when we are using definitePosition
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldsfld, _definitePositionField));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Brtrue_S, instructionList[i].operand));
                }

                // Override all the rotation stuff
                if (!foundLook &&
                    instructionList[i].opcode == OpCodes.Bge_Un &&
                    instructionList[i].operand.GetHashCode() == 6)
                {
                    Label label = (Label)instructionList[i].operand;
                    int endIndex = instructionList.FindIndex(n => n.labels.Contains(label));

                    foundLook = true;

                    instructionList.RemoveRange(i + 1, endIndex - i - 1);

                    // This is where the fun begins
                    CodeInstruction[] codeInstructions = new CodeInstruction[]
                    {
                        new CodeInstruction(OpCodes.Ldloc_1),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld, _startRotationField),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld, _middleRotationField),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld, _endRotationField),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld, _playerTransformsField),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld, _rotatedObjectField),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Call, _getTransform),
                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld, _inverseWorldRotationField),
                        new CodeInstruction(OpCodes.Call, _doNoteLook),
                    };
                    instructionList.InsertRange(i + 1, codeInstructions);
                }
            }

            if (!foundTime)
            {
                NoodleLogger.Log("Failed to find stloc.0!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundFinalPosition)
            {
                NoodleLogger.Log("Failed to find stind.r4!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundZOffset)
            {
                NoodleLogger.Log("Failed to find brfalse.s to Label21!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundLook)
            {
                NoodleLogger.Log("Failed to find bge.un to Label6!", IPA.Logging.Logger.Level.Error);
            }

            return instructionList.AsEnumerable();
        }
Ejemplo n.º 25
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundTime          = false;
            bool foundFinalPosition = false;
            bool foundTransformUp   = false;
            bool foundZOffset       = false;

            for (int i = 0; i < instructionList.Count; i++)
            {
                if (!foundTime &&
                    instructionList[i].opcode == OpCodes.Stloc_0)
                {
                    foundTime = true;
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldfld, _jumpDurationField));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Call, _noteJumpTimeAdjust));
                }

                if (!foundFinalPosition &&
                    instructionList[i].opcode == OpCodes.Stind_R4)
                {
                    foundFinalPosition = true;
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 3, new CodeInstruction(OpCodes.Ldarg_0));
                    instructionList.Insert(i + 4, new CodeInstruction(OpCodes.Ldfld, _localPositionField));
                    instructionList.Insert(i + 5, new CodeInstruction(OpCodes.Ldloc_1));
                    instructionList.Insert(i + 6, new CodeInstruction(OpCodes.Call, _definiteNoteJump));
                    instructionList.Insert(i + 7, new CodeInstruction(OpCodes.Stfld, _localPositionField));
                }

                if (!foundTransformUp &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_up")
                {
                    foundTransformUp   = true;
                    instructionList[i] = new CodeInstruction(OpCodes.Call, _convertToLocalSpace);
                    instructionList.RemoveRange(i + 1, 8);
                    instructionList.RemoveRange(i - 5, 3);
                    instructionList.Insert(i - 5, new CodeInstruction(OpCodes.Ldloc_S, 5));
                    instructionList.Insert(i - 5, new CodeInstruction(OpCodes.Ldloca_S, 6));
                }

                // is there a better way of checking labels?
                if (!foundZOffset &&
                    instructionList[i].operand is Label &&
                    instructionList[i].operand.GetHashCode() == 21)
                {
                    foundZOffset = true;

                    // Add addition check to our quirky little variable to skip end position offset when we are using definitePosition
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Ldsfld, _definitePositionField));
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Brtrue_S, instructionList[i].operand));
                }
            }

            if (!foundTime)
            {
                NoodleLogger.Log("Failed to find stloc.0!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundFinalPosition)
            {
                NoodleLogger.Log("Failed to find stind.r4!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundTransformUp)
            {
                NoodleLogger.Log("Failed to find call to get_up!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundZOffset)
            {
                NoodleLogger.Log("Failed to find brfalse.s to Label21!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 26
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> instructionList = instructions.ToList();
            bool foundRotation         = false;
            bool foundWidth            = false;
            bool foundLength           = false;
            int  instructrionListCount = instructionList.Count;

            for (int i = 0; i < instructrionListCount; i++)
            {
                if (!foundRotation &&
                    instructionList[i].opcode == OpCodes.Stfld &&
                    ((FieldInfo)instructionList[i].operand).Name == "_worldRotation")
                {
                    foundRotation = true;

                    instructionList[i - 1] = new CodeInstruction(OpCodes.Call, _getWorldRotation);
                    instructionList[i - 4] = new CodeInstruction(OpCodes.Ldarg_1);
                    instructionList.RemoveAt(i - 2);

                    instructionList.RemoveRange(i + 1, 2);
                    instructionList[i + 1] = new CodeInstruction(OpCodes.Ldarg_0);
                    instructionList[i + 2] = new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ObstacleController), "_worldRotation"));
                    instructionList[i + 3] = new CodeInstruction(OpCodes.Call, _invertQuaternion);
                }

                if (!foundWidth &&
                    instructionList[i].opcode == OpCodes.Callvirt &&
                    ((MethodInfo)instructionList[i].operand).Name == "get_width")
                {
                    foundWidth = true;
                    instructionList.Insert(i + 2, new CodeInstruction(OpCodes.Ldarg_1));
                    instructionList.Insert(i + 3, new CodeInstruction(OpCodes.Call, _getCustomWidth));
                }

                if (!foundLength &&
                    instructionList[i].opcode == OpCodes.Stloc_2)
                {
                    foundLength = true;
                    instructionList.Insert(i, new CodeInstruction(OpCodes.Ldarg_1));
                    instructionList.Insert(i + 1, new CodeInstruction(OpCodes.Call, _getCustomLength));
                }
            }

            if (!foundRotation)
            {
                NoodleLogger.Log("Failed to find _worldRotation stfld!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundWidth)
            {
                NoodleLogger.Log("Failed to find get_width call!", IPA.Logging.Logger.Level.Error);
            }

            if (!foundLength)
            {
                NoodleLogger.Log("Failed to find stloc.2!", IPA.Logging.Logger.Level.Error);
            }

            return(instructionList.AsEnumerable());
        }
Ejemplo n.º 27
0
        internal static void StartEventCoroutine(CustomEventData customEventData, EventType eventType)
        {
            Track track = GetTrack(customEventData.data);

            if (track != null)
            {
                float duration = (float?)Trees.at(customEventData.data, DURATION) ?? 0f;
                duration = 60f * duration / Instance.BeatmapObjectSpawnController.currentBpm; // Convert to real time;

                string    easingString = (string)Trees.at(customEventData.data, EASING);
                Functions easing       = Functions.easeLinear;
                if (easingString != null)
                {
                    easing = (Functions)Enum.Parse(typeof(Functions), easingString);
                }

                List <string> excludedStrings = new List <string> {
                    TRACK, DURATION, EASING
                };
                IDictionary <string, object>   eventData  = new Dictionary <string, object>(customEventData.data as IDictionary <string, object>); // Shallow copy
                IDictionary <string, Property> properties = null;
                switch (eventType)
                {
                case EventType.AnimateTrack:
                    properties = track.Properties;
                    break;

                case EventType.AssignPathAnimation:
                    properties = track.PathProperties;
                    break;

                default:
                    return;
                }

                foreach (KeyValuePair <string, object> valuePair in eventData)
                {
                    if (!excludedStrings.Any(n => n == valuePair.Key))
                    {
                        if (!properties.TryGetValue(valuePair.Key, out Property property))
                        {
                            NoodleLogger.Log($"Could not find property {valuePair.Key}!", IPA.Logging.Logger.Level.Error);
                            continue;
                        }

                        TryGetPointData(customEventData.data, valuePair.Key, out PointDefinition pointData);

                        if (property.Coroutine != null)
                        {
                            Instance.StopCoroutine(property.Coroutine);
                        }

                        if (pointData == null)
                        {
                            switch (eventType)
                            {
                            case EventType.AnimateTrack:
                                property.Value = null;
                                break;

                            case EventType.AssignPathAnimation:
                                ((PointDefinitionInterpolation)property.Value).Init(null);
                                break;
                            }
                        }
                        else
                        {
                            switch (eventType)
                            {
                            case EventType.AnimateTrack:
                                property.Coroutine = Instance.StartCoroutine(AnimateTrack.AnimateTrackCoroutine(pointData, property, duration, customEventData.time, easing));
                                break;

                            case EventType.AssignPathAnimation:
                                ((PointDefinitionInterpolation)property.Value).Init(pointData);
                                property.Coroutine = Instance.StartCoroutine(AssignPathAnimation.AssignPathAnimationCoroutine(property, duration, customEventData.time, easing));
                                break;
                            }
                        }
                    }
                }
            }
        }
        private static NoodleCoroutineEventData ProcessCoroutineEvent(CustomEventData customEventData, IReadonlyBeatmapData beatmapData)
        {
            NoodleCoroutineEventData noodleEventData = new NoodleCoroutineEventData();

            string easingString = (string)Trees.at(customEventData.data, EASING);

            noodleEventData.Easing = Functions.easeLinear;
            if (easingString != null)
            {
                noodleEventData.Easing = (Functions)Enum.Parse(typeof(Functions), easingString);
            }

            noodleEventData.Duration = (float?)Trees.at(customEventData.data, DURATION) ?? 0f;

            Track track = GetTrackPreload(customEventData.data, beatmapData);

            if (track == null)
            {
                return(null);
            }

            EventType eventType;

            switch (customEventData.type)
            {
            case ANIMATETRACK:
                eventType = EventType.AnimateTrack;
                break;

            case ASSIGNPATHANIMATION:
                eventType = EventType.AssignPathAnimation;
                break;

            default:
                return(null);
            }

            List <string> excludedStrings = new List <string> {
                TRACK, DURATION, EASING
            };
            IDictionary <string, object>   eventData  = new Dictionary <string, object>(customEventData.data as IDictionary <string, object>); // Shallow copy
            IDictionary <string, Property> properties = null;

            switch (eventType)
            {
            case EventType.AnimateTrack:
                properties = track.Properties;
                break;

            case EventType.AssignPathAnimation:
                properties = track.PathProperties;
                break;
            }

            foreach (KeyValuePair <string, object> valuePair in eventData)
            {
                if (!excludedStrings.Any(n => n == valuePair.Key))
                {
                    if (!properties.TryGetValue(valuePair.Key, out Property property))
                    {
                        NoodleLogger.Log($"Could not find property {valuePair.Key}!", IPA.Logging.Logger.Level.Error);
                        continue;
                    }

                    Dictionary <string, PointDefinition> pointDefinitions = Trees.at(((CustomBeatmapData)beatmapData).customData, "pointDefinitions");
                    TryGetPointData(customEventData.data, valuePair.Key, out PointDefinition pointData, pointDefinitions);

                    NoodleCoroutineEventData.CoroutineInfo coroutineInfo = new NoodleCoroutineEventData.CoroutineInfo()
                    {
                        PointDefinition = pointData,
                        Property        = property,
                    };

                    noodleEventData.CoroutineInfos.Add(coroutineInfo);
                }
            }

            return(noodleEventData);
        }