public override string ToString() { StringBuilder sb = new StringBuilder(); // TODO - Rewrite this shit. Use dictionary or something. // Yes, I know that string interpolation exists, but I dont like it. sb.AppendFormat( "levelID={0}&version={1}&user_id={2}&credits={3}&cowboyChance={4}&title={5}&time={6}¬e={7}&min_level={8}&song={9}&gravity={10}&max_time={11}&has_pass={12}&live={13}&items={14}&gameMode={15}&data={16}", this.Id, this.Version, this.UserId, String.Empty, this.CowboyChance, this.Title.ToUrlEncodedString(), this.SubmittedDate.GetSecondsSinceUnixTime(), this.Note.ToUrlEncodedString(), this.MinLevel, this.Song, this.Gravity.ToString(StringFormat.DECIMAL_TWO, CultureInfo.InvariantCulture), this.MaxTime, !String.IsNullOrEmpty(this.PassHash), Convert.ToInt32(this.Live), this.Items, this.GameMode.GetEnumDescription(), this.Data); using (MD5Wrapper md5 = new MD5Wrapper()) { String hash = md5.GetHashedString(String.Concat(this.Version.ToString(), this.Id.ToString(), sb.ToString(), Pepper.LEVEL_LOAD)); sb.Append(hash); } return(sb.ToString()); }
/// <summary> /// Processes list of levels and returns its string representation ready to be sent to client. /// </summary> /// <param name="levels">List of LevelRowDTO.</param> /// <returns></returns> public static String GetLevelListString(this IList <LevelRowDTO> levels) { if (!levels.Any()) { return(String.Empty); } StringBuilder sb = new StringBuilder(); for (Int32 i = 0; i < levels.Count; i++) { LevelRowDTO current = levels[i]; // TODO - Rewrite this shit. Use dictionary or something. // Yes, I know that string interpolation exists, but I dont like it. sb.AppendFormat( "levelID{0}={1}&version{0}={2}&title{0}={3}&rating{0}={4}&playCount{0}={5}&minLevel{0}={6}¬e{0}={7}&userName{0}={8}&group{0}={9}&live{0}={10}&pass{0}={11}&type{0}={12}{13}", i, current.LevelId, current.Version, current.Title.ToUrlEncodedString(), current.Rating.ToString(StringFormat.DECIMAL_TWO, CultureInfo.InvariantCulture) ?? String.Empty, current.PlayCount, current.MinRank, current.Note.ToUrlEncodedString(), current.Username.ToUrlEncodedString(), current.Group, Convert.ToInt32(current.IsPublished), current.HasPass ? StatusMessages.ONE : String.Empty, current.GameMode.GetEnumDescription().FirstOrDefault() + String.Empty, (i < levels.Count - 1) ? Separators.AMPERSAND : String.Empty); } using (MD5Wrapper md5 = new MD5Wrapper()) { String hash = md5.GetHashedString(String.Concat(sb.ToString(), Pepper.LEVEL_LIST)); sb.Append(String.Concat("&hash=", hash)); } return(sb.ToString()); }
public void SaveLevel(Int64 userId, String username, LevelDataDTO levelData, String ipAddress) { // TODO - Validation of level data. // TODO - Consider the difference based approach when saving levels. if (levelData == null) { throw new PR2Exception(ErrorMessages.ERR_NO_LEVEL_DATA); } else if (String.IsNullOrEmpty(levelData.Title)) { throw new PR2Exception(ErrorMessages.ERR_NO_LEVEL_TITLE); } else if (levelData.GameMode == GameMode.Unknown) { throw new PR2Exception(ErrorMessages.ERR_INVALID_GAME_MODE); } else if (!String.IsNullOrEmpty(levelData.Items) && !Regex.IsMatch(levelData.Items, ValidationConstraints.LEVEL_ITEMS_PATTERN)) { throw new PR2Exception(ErrorMessages.ERR_INVALID_ITEMS); } using (MD5Wrapper md5 = new MD5Wrapper()) { String hash = md5.GetHashedString( String.Concat(levelData.Title, username?.ToLower() ?? String.Empty, levelData.Data, Pepper.LEVEL_SAVE)); if (String.CompareOrdinal(hash, levelData.Hash) != 0) { throw new PR2Exception(ErrorMessages.ERR_LEVEL_DATA_HASH_MISMATCH); } } DateTime utcDateMinus1min = DateTime.UtcNow.AddMinutes(-1); // To prevent usage of SQL functions. LevelVersion lastSaved = this.dbContext.LevelVersions .Where(v => v.Level != null && v.Level.AuthorId == userId && DateTime.Compare(v.SubmittedDate, utcDateMinus1min) > 0) .OrderByDescending(v => v.SubmittedDate).FirstOrDefault(); if (lastSaved != null) { throw new PR2Exception(String.Format( ErrorMessages.ERR_WAIT_BEFORE_SAVING, Math.Round(TimeSpan.FromMinutes(1).Subtract(DateTime.UtcNow.Subtract(lastSaved.SubmittedDate.ToUniversalTime())).TotalSeconds))); } Level level = this.dbContext.Levels.FirstOrDefault(l => l.AuthorId == userId && l.Title == levelData.Title); if (level == null) { level = new Level { AuthorId = userId, Title = levelData.Title, IsDeleted = false }; this.dbContext.Levels.Add(level); } level.IsPublished = levelData.Live; this.dbContext.LevelVersions.Add(new LevelVersion { Level = level, SubmittedDate = DateTime.UtcNow, SubmittedIP = ipAddress, Note = levelData.Note, GameMode = levelData.GameMode, MinRank = levelData.MinLevel, CowboyChance = levelData.CowboyChance, Gravity = levelData.Gravity, Song = levelData.Song, MaxTime = levelData.MaxTime, Items = levelData.Items, Data = levelData.Data, PassHash = levelData.PassHash }); this.dbContext.SaveChanges(); }