예제 #1
0
 public BaseCircle(BaseCircle baseInstance)
 {
     //Copy from baseInstance
     Location = baseInstance.Location;
     Radius = baseInstance.Radius;
     StartTime = baseInstance.StartTime;
     Type = baseInstance.Type;
     Effect = baseInstance.Effect;
 }
예제 #2
0
        private void Parse(string bm)
        {
            Info.Filename = bm;
            Info.BeatmapHash = MD5FromFile(bm);
            using (StreamReader sR = new StreamReader(bm))
            {
                string currentSection = "";

                while (sR.Peek() != -1)
                {
                    string line = sR.ReadLine();

                    //Check for blank lines
                    if ((line == "") || (line.Length < 2))
                        continue;

                    //Check for section tag
                    if (line.Substring(0, 1) == "[")
                    {
                        currentSection = line;
                        continue;
                    }

                    //Check for commented-out line
                    if (line.Substring(0, 2) == "//")
                        continue;

                    //Check for version string
                    if (line.Length > 17)
                    {
                        if (line.Substring(0, 17) == "osu file format v")
                        {
                            Info.Format = Convert.ToInt32(line.Substring(17).Replace(Environment.NewLine, "").Replace(" ", ""));
                        }
                    }

                    //Do work for [General], [Metadata], [Difficulty] and [Editor] sections
                    if ((currentSection == "[General]") || (currentSection == "[Metadata]") || (currentSection == "[Difficulty]") || (currentSection == "[Editor]"))
                    {
                        string[] reSplit = line.Split(':');
                        string cProperty = reSplit[0];

                        //Check for blank value
                        string cValue = line.Length == reSplit[0].Length ? "" : reSplit[1].Trim();

                        //Import properties into Info
                        switch (cProperty)
                        {
                            case "EditorBookmarks":
                            {
                                string[] marks = cValue.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (string m in marks.Where(m => m != ""))
                                {
                                    Info.EditorBookmarks.Add(Convert.ToInt32(m));
                                }
                            }
                                break;
                            case "Bookmarks":
                            {
                                string[] marks = cValue.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (string m in marks.Where(m => m != ""))
                                {
                                    Info.Bookmarks.Add(Convert.ToInt32(m));
                                }
                            }
                                break;
                            case "Tags":
                                string[] tags = cValue.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (string t in tags)
                                    Info.Tags.Add(t);
                                break;
                            case "Mode":
                                Info.Mode = (GameMode)Convert.ToInt32(cValue);
                                break;
                            case "OverlayPosition":
                                Info.OverlayPosition = (OverlayOptions)Convert.ToInt32(cValue);
                                break;
                            case "AlwaysShowPlayfield":
                                Info.AlwaysShowPlayfield = Convert.ToBoolean(Convert.ToInt32(cValue));
                                break;
                            default:
                                FieldInfo fi = Info.GetType().GetField(cProperty);
                                PropertyInfo pi = Info.GetType().GetProperty(cProperty);
                                if (fi != null)
                                {
                                    if ((fi.FieldType == typeof(double?)) || (fi.FieldType == typeof(double)))
                                        fi.SetValue(Info, Convert.ToDouble(cValue));
                                    else if ((fi.FieldType == typeof(int?)) || (fi.FieldType == typeof(int)))
                                        fi.SetValue(Info, Convert.ToInt32(cValue));
                                    else if (fi.FieldType == typeof(string))
                                        fi.SetValue(Info, cValue);
                                    break;
                                }
                                if ((pi.PropertyType == typeof(double?)) || (pi.PropertyType == typeof(double)))
                                    pi.SetValue(Info, Convert.ToDouble(cValue), null);
                                else if ((pi.PropertyType == typeof(int?)) || (pi.PropertyType == typeof(int)))
                                    pi.SetValue(Info, Convert.ToInt32(cValue), null);
                                else if (pi.PropertyType == typeof(string))
                                    pi.SetValue(Info, cValue, null);
                                break;
                        }
                        continue;
                    }

                    //The following are version-dependent, the version is stored as a numeric value inside Info.Format
                    //Do work for [Events] section
                    if (currentSection == "[Events]")
                    {
                        switch (Info.Format)
                        {
                            case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13:
                                string[] reSplit = line.Split(',');
                                if (reSplit[0] == "0")
                                {
                                    BackgroundInfo tempEvent = new BackgroundInfo();
                                    tempEvent.StartTime = Convert.ToInt32(reSplit[1]);
                                    tempEvent.Filename = reSplit[2].Replace("\"", "");
                                    Info.Events.Add(tempEvent);
                                }
                                else if ((reSplit[0] == "1") || (reSplit[0].ToLower() == "video"))
                                {
                                    VideoInfo tempEvent = new VideoInfo();
                                    tempEvent.StartTime = Convert.ToInt32(reSplit[1]);
                                    tempEvent.Filename = reSplit[2];
                                    Info.Events.Add(tempEvent);
                                }
                                else if (reSplit[0] == "2")
                                {
                                    BreakInfo tempEvent = new BreakInfo();
                                    tempEvent.StartTime = Convert.ToInt32(reSplit[1]);
                                    tempEvent.EndTime = Convert.ToInt32(reSplit[2]);
                                    Info.Events.Add(tempEvent);
                                }
                                else if (reSplit[0] == "3")
                                {
                                    ColourInfo tempEvent = new ColourInfo();
                                    tempEvent.StartTime = Convert.ToInt32(reSplit[1]);
                                    tempEvent.R = Convert.ToInt32(reSplit[2]);
                                    tempEvent.G = Convert.ToInt32(reSplit[3]);
                                    tempEvent.B = Convert.ToInt32(reSplit[4]);
                                    Info.Events.Add(tempEvent);
                                }
                                break;
                        }

                    }

                    //Do work for [TimingPoints] section
                    if (currentSection == "[TimingPoints]")
                    {
                        TimingPointInfo tempTimingPoint = new TimingPointInfo();

                        double[] values = { 0, 0, 4, 0, 0, 100, 0, 0, 0 };
                        string[] reSplit = line.Split(',');
                        for (int i = 0; i < reSplit.Length; i++)
                        {
                            values[i] += Convert.ToDouble(reSplit[i]);
                        }
                        tempTimingPoint.Time = Convert.ToDouble(values[0]);
                        tempTimingPoint.BpmDelay = Convert.ToDouble(values[1]);
                        tempTimingPoint.TimeSignature = Convert.ToInt32(values[2]);
                        tempTimingPoint.SampleSet = Convert.ToInt32(values[3]);
                        tempTimingPoint.CustomSampleSet = Convert.ToInt32(values[4]);
                        tempTimingPoint.VolumePercentage = Convert.ToInt32(values[5]);
                        tempTimingPoint.InheritsBPM = !Convert.ToBoolean(Convert.ToInt32(values[6]));
                        tempTimingPoint.VisualOptions = (TimingPointOptions)Convert.ToInt32(values[7]);
                        Info.TimingPoints.Add(tempTimingPoint);
                    }

                    //Do work for [Colours] section
                    if (currentSection == "[Colours]")
                    {
                        switch (Info.Format)
                        {
                            case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13:
                                if (line.Substring(0, line.IndexOf(':', 1)).Trim() == "SliderBorder")
                                {
                                    string value = line.Substring(line.IndexOf(':', 1) + 1).Trim();
                                    string[] reSplit = value.Split(',');
                                    Info.SliderBorder = new ColourInfo();
                                    Info.SliderBorder.R = Convert.ToInt32(reSplit[0]);
                                    Info.SliderBorder.G = Convert.ToInt32(reSplit[1]);
                                    Info.SliderBorder.B = Convert.ToInt32(reSplit[2]);
                                }
                                else if (line.Substring(0, 5) == "Combo")
                                {
                                    string value = line.Substring(line.IndexOf(':', 1) + 1).Trim();
                                    string[] reSplit = value.Split(',');
                                    ComboInfo tempCombo = new ComboInfo();
                                    tempCombo.ComboNumber = Convert.ToInt32(line.Substring(5, 1));
                                    tempCombo.Colour.R = Convert.ToInt32(reSplit[0]);
                                    tempCombo.Colour.G = Convert.ToInt32(reSplit[1]);
                                    tempCombo.Colour.B = Convert.ToInt32(reSplit[2]);
                                    Info.ComboColours.Add(tempCombo);
                                }
                                break;
                        }
                    }

                    //Do work for [HitObjects] section
                    if (currentSection == "[HitObjects]")
                    {
                        string[] reSplit = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        BaseCircle newObject = new BaseCircle
                        {
                            Radius = 40 - 4 * (Info.CircleSize - 2),
                            Location = new PointInfo(Convert.ToInt32(reSplit[0]), Convert.ToInt32(reSplit[1])),
                            StartTime = Convert.ToInt32(reSplit[2]),
                            Type = (HitObjectType)Convert.ToInt32(reSplit[3]),
                            Effect = (EffectType)Convert.ToInt32(reSplit[4])
                        };
                        if ((newObject.Type & HitObjectType.Slider) > 0)
                        {
                            newObject = new SliderInfo(newObject);
                            ((SliderInfo)newObject).Velocity = Info.SliderMultiplier;
                            switch (reSplit[5].Substring(0, 1))
                            {
                                case "B":
                                    ((SliderInfo)newObject).Type = SliderType.Bezier;
                                    break;
                                case "C":
                                    ((SliderInfo)newObject).Type = SliderType.CSpline;
                                    break;
                                case "L":
                                    ((SliderInfo)newObject).Type = SliderType.Linear;
                                    break;
                                case "P":
                                    ((SliderInfo)newObject).Type = SliderType.PSpline;
                                    break;
                            }
                            string[] pts = reSplit[5].Split(new[] { "|" }, StringSplitOptions.None);

                            //Always add the location as a point
                            ((SliderInfo)newObject).Points.Add(newObject.Location);

                            //Always exclude index 1, this will contain the type
                            for (int i = 1; i <= pts.Length - 1; i++)
                            {
                                PointInfo p = new PointInfo(Convert.ToDouble(pts[i].Substring(0, pts[i].IndexOf(":", StringComparison.InvariantCulture))),
                                                            Convert.ToDouble(pts[i].Substring(pts[i].IndexOf(":", StringComparison.InvariantCulture) + 1)));
                                ((SliderInfo)newObject).Points.Add(p);
                            }
                            ((SliderInfo)newObject).RepeatCount = Convert.ToInt32(reSplit[6]);
                            double tempDbl;
                            if (double.TryParse(reSplit[7], out tempDbl))
                            {
                                ((SliderInfo)newObject).MaxPoints = tempDbl;
                            }
                        }
                        if ((newObject.Type & HitObjectType.Spinner) > 0)
                        {
                            newObject = new SpinnerInfo(newObject);
                            ((SpinnerInfo)newObject).EndTime = Convert.ToInt32(reSplit[5]);
                        }
                        Info.HitObjects.Add(newObject);
                    }
                }
            }
            foreach (FieldInfo fi in Info.GetType().GetFields())
            {
                FieldInfo ff = GetType().GetField(fi.Name);
                ff.SetValue(this, fi.GetValue(Info));
            }
            foreach (PropertyInfo pi in Info.GetType().GetProperties())
            {
                PropertyInfo ff = GetType().GetProperty(pi.Name);
                ff.SetValue(this, pi.GetValue(Info, null), null);
            }
        }