A lot of work on flower shop
This commit is contained in:
		
							
								
								
									
										128
									
								
								src/NadekoBot/DataStructures/IndexedCollection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/NadekoBot/DataStructures/IndexedCollection.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | |||||||
|  | using NadekoBot.Services.Database.Models; | ||||||
|  | using System.Collections; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  |  | ||||||
|  | namespace NadekoBot.DataStructures | ||||||
|  | { | ||||||
|  |     public class IndexedCollection<T> : IList<T> where T : IIndexed | ||||||
|  |     { | ||||||
|  |         public List<T> Source { get; } | ||||||
|  |         private readonly object _locker = new object(); | ||||||
|  |  | ||||||
|  |         public IndexedCollection(IEnumerable<T> source) | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 Source = source.OrderBy(x => x.Index).ToList(); | ||||||
|  |                 for (var i = 0; i < Source.Count; i++) | ||||||
|  |                 { | ||||||
|  |                     if (Source[i].Index != i) | ||||||
|  |                         Source[i].Index = i; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static implicit operator List<T>(IndexedCollection<T> x) => | ||||||
|  |             x.Source; | ||||||
|  |  | ||||||
|  |         public IEnumerator<T> GetEnumerator() => | ||||||
|  |             Source.GetEnumerator(); | ||||||
|  |  | ||||||
|  |         IEnumerator IEnumerable.GetEnumerator() => | ||||||
|  |             Source.GetEnumerator(); | ||||||
|  |  | ||||||
|  |         public void Add(T item) | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 item.Index = Source.Count; | ||||||
|  |                 Source.Add(item); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public virtual void Clear() | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 Source.Clear(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool Contains(T item) | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 return Source.Contains(item); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void CopyTo(T[] array, int arrayIndex) | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 Source.CopyTo(array, arrayIndex); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public virtual bool Remove(T item) | ||||||
|  |         { | ||||||
|  |             bool removed; | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 if (removed = Source.Remove(item)) | ||||||
|  |                 { | ||||||
|  |                     for (int i = 0; i < Source.Count; i++) | ||||||
|  |                     { | ||||||
|  |                         // hm, no idea how ef works, so I don't want to set if it's not changed,  | ||||||
|  |                         // maybe it will try to update db?  | ||||||
|  |                         // But most likely it just compares old to new values, meh. | ||||||
|  |                         if (Source[i].Index != i) | ||||||
|  |                             Source[i].Index = i; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return removed; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public int Count => Source.Count; | ||||||
|  |         public bool IsReadOnly => false; | ||||||
|  |         public int IndexOf(T item) => item.Index; | ||||||
|  |  | ||||||
|  |         public virtual void Insert(int index, T item) | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 Source.Insert(index, item); | ||||||
|  |                 for (int i = index; i < Source.Count; i++) | ||||||
|  |                 { | ||||||
|  |                     Source[i].Index = i; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public virtual void RemoveAt(int index) | ||||||
|  |         { | ||||||
|  |             lock (_locker) | ||||||
|  |             { | ||||||
|  |                 Source.RemoveAt(index); | ||||||
|  |                 for (int i = index; i < Source.Count; i++) | ||||||
|  |                 { | ||||||
|  |                     Source[i].Index = i; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public virtual T this[int index] { | ||||||
|  |             get { return Source[index]; } | ||||||
|  |             set { | ||||||
|  |                 lock (_locker) | ||||||
|  |                 { | ||||||
|  |                     value.Index = index; | ||||||
|  |                     Source[index] = value; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -6,132 +6,67 @@ using NadekoBot.Services.Database.Models; | |||||||
|  |  | ||||||
| namespace NadekoBot.DataStructures | namespace NadekoBot.DataStructures | ||||||
| { | { | ||||||
|     public class PermissionsCollection<T> : IList<T> where T : IIndexed |     public class PermissionsCollection<T> : IndexedCollection<T> where T : IIndexed | ||||||
|     { |     { | ||||||
|         public List<T> Source { get; } |         private readonly object _localLocker = new object(); | ||||||
|         private readonly object _locker = new object(); |         public PermissionsCollection(IEnumerable<T> source) : base(source) | ||||||
|  |  | ||||||
|         public PermissionsCollection(IEnumerable<T> source) |  | ||||||
|         { |         { | ||||||
|             lock (_locker) |  | ||||||
|             { |  | ||||||
|                 Source = source.OrderBy(x => x.Index).ToList(); |  | ||||||
|                 for (var i = 0; i < Source.Count; i++) |  | ||||||
|                 { |  | ||||||
|                     if(Source[i].Index != i) |  | ||||||
|                         Source[i].Index = i; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static implicit operator List<T>(PermissionsCollection<T> x) =>  |         public static implicit operator List<T>(PermissionsCollection<T> x) =>  | ||||||
|             x.Source; |             x.Source; | ||||||
|  |  | ||||||
|         public IEnumerator<T> GetEnumerator() => |         public override void Clear() | ||||||
|             Source.GetEnumerator(); |  | ||||||
|  |  | ||||||
|         IEnumerator IEnumerable.GetEnumerator() => |  | ||||||
|             Source.GetEnumerator(); |  | ||||||
|  |  | ||||||
|         public void Add(T item) |  | ||||||
|         { |         { | ||||||
|             lock (_locker) |             lock (_localLocker) | ||||||
|             { |  | ||||||
|                 item.Index = Source.Count; |  | ||||||
|                 Source.Add(item); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public void Clear() |  | ||||||
|         { |  | ||||||
|             lock (_locker) |  | ||||||
|             { |             { | ||||||
|                 var first = Source[0]; |                 var first = Source[0]; | ||||||
|                 Source.Clear(); |                 base.Clear(); | ||||||
|                 Source[0] = first; |                 Source[0] = first; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public bool Contains(T item) |         public override bool Remove(T item) | ||||||
|         { |  | ||||||
|             lock (_locker) |  | ||||||
|             { |  | ||||||
|                 return Source.Contains(item); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public void CopyTo(T[] array, int arrayIndex) |  | ||||||
|         { |  | ||||||
|             lock (_locker) |  | ||||||
|             { |  | ||||||
|                 Source.CopyTo(array, arrayIndex); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public bool Remove(T item) |  | ||||||
|         { |         { | ||||||
|             bool removed; |             bool removed; | ||||||
|             lock (_locker) |             lock (_localLocker) | ||||||
|             { |             { | ||||||
|                 if(Source.IndexOf(item) == 0) |                 if(Source.IndexOf(item) == 0) | ||||||
|                     throw new ArgumentException("You can't remove first permsission (allow all)"); |                     throw new ArgumentException("You can't remove first permsission (allow all)"); | ||||||
|                 if (removed = Source.Remove(item)) |                 removed = base.Remove(item); | ||||||
|                 { |  | ||||||
|                     for (int i = 0; i < Source.Count; i++) |  | ||||||
|                     { |  | ||||||
|                         // hm, no idea how ef works, so I don't want to set if it's not changed,  |  | ||||||
|                         // maybe it will try to update db?  |  | ||||||
|                         // But most likely it just compares old to new values, meh. |  | ||||||
|                         if (Source[i].Index != i) |  | ||||||
|                             Source[i].Index = i; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             return removed; |             return removed; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public int Count => Source.Count; |         public override void Insert(int index, T item) | ||||||
|         public bool IsReadOnly => false; |  | ||||||
|         public int IndexOf(T item) => item.Index; |  | ||||||
|  |  | ||||||
|         public void Insert(int index, T item) |  | ||||||
|         { |         { | ||||||
|             lock (_locker) |             lock (_localLocker) | ||||||
|             { |             { | ||||||
|                 if(index == 0) // can't insert on first place. Last item is always allow all. |                 if(index == 0) // can't insert on first place. Last item is always allow all. | ||||||
|                     throw new IndexOutOfRangeException(nameof(index)); |                     throw new IndexOutOfRangeException(nameof(index)); | ||||||
|                 Source.Insert(index, item); |                 base.Insert(index, item); | ||||||
|                 for (int i = index; i < Source.Count; i++) |  | ||||||
|                 { |  | ||||||
|                     Source[i].Index = i; |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void RemoveAt(int index) |         public override void RemoveAt(int index) | ||||||
|         { |         { | ||||||
|             lock (_locker) |             lock (_localLocker) | ||||||
|             { |             { | ||||||
|                 if(index == 0) // you can't remove first permission (allow all) |                 if(index == 0) // you can't remove first permission (allow all) | ||||||
|                     throw new IndexOutOfRangeException(nameof(index));  |                     throw new IndexOutOfRangeException(nameof(index)); | ||||||
|  |  | ||||||
|                 Source.RemoveAt(index); |                 base.RemoveAt(index); | ||||||
|                 for (int i = index; i < Source.Count; i++) |  | ||||||
|                 { |  | ||||||
|                     Source[i].Index = i; |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public T this[int index] { |         public override T this[int index] { | ||||||
|             get { return Source[index]; } |             get { return Source[index]; } | ||||||
|             set { |             set { | ||||||
|                 lock (_locker) |                 lock (_localLocker) | ||||||
|                 { |                 { | ||||||
|                     if(index == 0) // can't set first element. It's always allow all |                     if(index == 0) // can't set first element. It's always allow all | ||||||
|                         throw new IndexOutOfRangeException(nameof(index)); |                         throw new IndexOutOfRangeException(nameof(index)); | ||||||
|                     value.Index = index; |                     base[index] = value; | ||||||
|                     Source[index] = value; |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
							
								
								
									
										1518
									
								
								src/NadekoBot/Migrations/20170405161814_flower-shop.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1518
									
								
								src/NadekoBot/Migrations/20170405161814_flower-shop.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										79
									
								
								src/NadekoBot/Migrations/20170405161814_flower-shop.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/NadekoBot/Migrations/20170405161814_flower-shop.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using Microsoft.EntityFrameworkCore.Migrations; | ||||||
|  |  | ||||||
|  | namespace NadekoBot.Migrations | ||||||
|  | { | ||||||
|  |     public partial class flowershop : Migration | ||||||
|  |     { | ||||||
|  |         protected override void Up(MigrationBuilder migrationBuilder) | ||||||
|  |         { | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "ShopEntry", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     Id = table.Column<int>(nullable: false) | ||||||
|  |                         .Annotation("Sqlite:Autoincrement", true), | ||||||
|  |                     AuthorId = table.Column<ulong>(nullable: false), | ||||||
|  |                     DateAdded = table.Column<DateTime>(nullable: true), | ||||||
|  |                     GuildConfigId = table.Column<int>(nullable: true), | ||||||
|  |                     Index = table.Column<int>(nullable: false), | ||||||
|  |                     Name = table.Column<string>(nullable: true), | ||||||
|  |                     Price = table.Column<int>(nullable: false), | ||||||
|  |                     RoleId = table.Column<ulong>(nullable: false), | ||||||
|  |                     RoleName = table.Column<string>(nullable: true), | ||||||
|  |                     Type = table.Column<int>(nullable: false) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_ShopEntry", x => x.Id); | ||||||
|  |                     table.ForeignKey( | ||||||
|  |                         name: "FK_ShopEntry_GuildConfigs_GuildConfigId", | ||||||
|  |                         column: x => x.GuildConfigId, | ||||||
|  |                         principalTable: "GuildConfigs", | ||||||
|  |                         principalColumn: "Id", | ||||||
|  |                         onDelete: ReferentialAction.Restrict); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "ShopEntryItem", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     Id = table.Column<int>(nullable: false) | ||||||
|  |                         .Annotation("Sqlite:Autoincrement", true), | ||||||
|  |                     DateAdded = table.Column<DateTime>(nullable: true), | ||||||
|  |                     ShopEntryId = table.Column<int>(nullable: true), | ||||||
|  |                     Text = table.Column<string>(nullable: true) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_ShopEntryItem", x => x.Id); | ||||||
|  |                     table.ForeignKey( | ||||||
|  |                         name: "FK_ShopEntryItem_ShopEntry_ShopEntryId", | ||||||
|  |                         column: x => x.ShopEntryId, | ||||||
|  |                         principalTable: "ShopEntry", | ||||||
|  |                         principalColumn: "Id", | ||||||
|  |                         onDelete: ReferentialAction.Restrict); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             migrationBuilder.CreateIndex( | ||||||
|  |                 name: "IX_ShopEntry_GuildConfigId", | ||||||
|  |                 table: "ShopEntry", | ||||||
|  |                 column: "GuildConfigId"); | ||||||
|  |  | ||||||
|  |             migrationBuilder.CreateIndex( | ||||||
|  |                 name: "IX_ShopEntryItem_ShopEntryId", | ||||||
|  |                 table: "ShopEntryItem", | ||||||
|  |                 column: "ShopEntryId"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected override void Down(MigrationBuilder migrationBuilder) | ||||||
|  |         { | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "ShopEntryItem"); | ||||||
|  |  | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "ShopEntry"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -971,6 +971,54 @@ namespace NadekoBot.Migrations | |||||||
|                     b.ToTable("SelfAssignableRoles"); |                     b.ToTable("SelfAssignableRoles"); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd(); | ||||||
|  |  | ||||||
|  |                     b.Property<ulong>("AuthorId"); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime?>("DateAdded"); | ||||||
|  |  | ||||||
|  |                     b.Property<int?>("GuildConfigId"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("Index"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("Name"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("Price"); | ||||||
|  |  | ||||||
|  |                     b.Property<ulong>("RoleId"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("RoleName"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("Type"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("GuildConfigId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ShopEntry"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd(); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime?>("DateAdded"); | ||||||
|  |  | ||||||
|  |                     b.Property<int?>("ShopEntryId"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("Text"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("ShopEntryId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ShopEntryItem"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => |             modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => | ||||||
|                 { |                 { | ||||||
|                     b.Property<int>("Id") |                     b.Property<int>("Id") | ||||||
| @@ -1377,6 +1425,20 @@ namespace NadekoBot.Migrations | |||||||
|                         .HasForeignKey("BotConfigId"); |                         .HasForeignKey("BotConfigId"); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") | ||||||
|  |                         .WithMany("ShopEntries") | ||||||
|  |                         .HasForeignKey("GuildConfigId"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("NadekoBot.Services.Database.Models.ShopEntry") | ||||||
|  |                         .WithMany("Items") | ||||||
|  |                         .HasForeignKey("ShopEntryId"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => |             modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => | ||||||
|                 { |                 { | ||||||
|                     b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") |                     b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") | ||||||
|   | |||||||
							
								
								
									
										170
									
								
								src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | |||||||
|  | using Discord; | ||||||
|  | using Discord.Commands; | ||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using NadekoBot.Attributes; | ||||||
|  | using NadekoBot.DataStructures; | ||||||
|  | using NadekoBot.Extensions; | ||||||
|  | using NadekoBot.Services; | ||||||
|  | using NadekoBot.Services.Database; | ||||||
|  | using NadekoBot.Services.Database.Models; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace NadekoBot.Modules.Gambling | ||||||
|  | { | ||||||
|  |     public partial class Gambling | ||||||
|  |     { | ||||||
|  |         [Group] | ||||||
|  |         public class FlowerShop : NadekoSubmodule | ||||||
|  |         { | ||||||
|  |             public enum Role { | ||||||
|  |                 Role | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             [NadekoCommand, Usage, Description, Aliases] | ||||||
|  |             [RequireContext(ContextType.Guild)] | ||||||
|  |             public async Task Shop(int page = 1) | ||||||
|  |             { | ||||||
|  |                 if (page <= 0) | ||||||
|  |                     return; | ||||||
|  |                 page -= 1; | ||||||
|  |                 List<ShopEntry> entries; | ||||||
|  |                 using (var uow = DbHandler.UnitOfWork()) | ||||||
|  |                 { | ||||||
|  |                     entries = new IndexedCollection<ShopEntry>(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)).ShopEntries); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 await Context.Channel.SendPaginatedConfirmAsync(page + 1, (curPage) => | ||||||
|  |                 { | ||||||
|  |                     var theseEntries = entries.Skip((curPage - 1) * 9).Take(9); | ||||||
|  |  | ||||||
|  |                     if (!theseEntries.Any()) | ||||||
|  |                         return new EmbedBuilder().WithErrorColor() | ||||||
|  |                             .WithDescription(GetText("shop_none")); | ||||||
|  |                     var embed = new EmbedBuilder().WithOkColor() | ||||||
|  |                         .WithTitle(GetText("shop", NadekoBot.BotConfig.CurrencySign)); | ||||||
|  |  | ||||||
|  |                     for (int i = 0; i < entries.Count; i++) | ||||||
|  |                     { | ||||||
|  |                         var entry = entries[i]; | ||||||
|  |                         embed.AddField(efb => efb.WithName($"#{i + 1} - {entry.Price}{NadekoBot.BotConfig.CurrencySign}").WithValue(EntryToString(entry)).WithIsInline(true)); | ||||||
|  |                     } | ||||||
|  |                     return embed; | ||||||
|  |                 }, entries.Count / 9, true); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             [NadekoCommand, Usage, Description, Aliases] | ||||||
|  |             [RequireContext(ContextType.Guild)] | ||||||
|  |             public async Task Buy(int entryNumber) | ||||||
|  |             { | ||||||
|  |                 var channel = (ITextChannel)Context.Channel; | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             [NadekoCommand, Usage, Description, Aliases] | ||||||
|  |             [RequireContext(ContextType.Guild)] | ||||||
|  |             [RequireUserPermission(GuildPermission.Administrator)] | ||||||
|  |             public async Task ShopAdd(ShopEntryType type, int price, string name) | ||||||
|  |             { | ||||||
|  |                 var entry = new ShopEntry() | ||||||
|  |                 { | ||||||
|  |                     Name = name, | ||||||
|  |                     Price = price, | ||||||
|  |                     Type = type, | ||||||
|  |                     AuthorId = Context.User.Id, | ||||||
|  |                 }; | ||||||
|  |                 using (var uow = DbHandler.UnitOfWork()) | ||||||
|  |                 { | ||||||
|  |                     var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)).ShopEntries); | ||||||
|  |                     entries.Add(entry); | ||||||
|  |                     uow.GuildConfigs.For(Context.Guild.Id, set => set).ShopEntries = entries; | ||||||
|  |                     uow.Complete(); | ||||||
|  |                 } | ||||||
|  |                 await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() | ||||||
|  |                     .WithTitle(GetText("shop_item_add")) | ||||||
|  |                     .AddField(efb => efb.WithName(GetText("name")).WithValue(name).WithIsInline(true)) | ||||||
|  |                     .AddField(efb => efb.WithName(GetText("price")).WithValue(price.ToString()).WithIsInline(true)) | ||||||
|  |                     .AddField(efb => efb.WithName(GetText("type")).WithValue(type.ToString()).WithIsInline(true))); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             [NadekoCommand, Usage, Description, Aliases] | ||||||
|  |             [RequireContext(ContextType.Guild)] | ||||||
|  |             [RequireUserPermission(GuildPermission.Administrator)] | ||||||
|  |             public async Task ShopAdd(Role _, int price, [Remainder] IRole role) | ||||||
|  |             { | ||||||
|  |                 var entry = new ShopEntry() | ||||||
|  |                 { | ||||||
|  |                     Name = "-", | ||||||
|  |                     Price = price, | ||||||
|  |                     Type = ShopEntryType.Role, | ||||||
|  |                     AuthorId = Context.User.Id, | ||||||
|  |                     RoleId = role.Id, | ||||||
|  |                     RoleName = role.Name | ||||||
|  |                 }; | ||||||
|  |                 using (var uow = DbHandler.UnitOfWork()) | ||||||
|  |                 { | ||||||
|  |                     var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)).ShopEntries); | ||||||
|  |                     entries.Add(entry); | ||||||
|  |                     uow.GuildConfigs.For(Context.Guild.Id, set => set).ShopEntries = entries; | ||||||
|  |                     uow.Complete(); | ||||||
|  |                 } | ||||||
|  |                 await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() | ||||||
|  |                     .WithTitle(GetText("shop_item_add")) | ||||||
|  |                     .AddField(efb => efb.WithName(GetText("name")).WithValue(GetText("shop_role", Format.Bold(entry.RoleName))).WithIsInline(true)) | ||||||
|  |                     .AddField(efb => efb.WithName(GetText("price")).WithValue(price.ToString()).WithIsInline(true)) | ||||||
|  |                     .AddField(efb => efb.WithName(GetText("type")).WithValue("Role").WithIsInline(true))); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             [NadekoCommand, Usage, Description, Aliases] | ||||||
|  |             [RequireContext(ContextType.Guild)] | ||||||
|  |             public async Task ShopRemove(int index) | ||||||
|  |             { | ||||||
|  |                 if (index < 0) | ||||||
|  |                     return; | ||||||
|  |                 ShopEntry removed; | ||||||
|  |                 using (var uow = DbHandler.UnitOfWork()) | ||||||
|  |                 { | ||||||
|  |                     var config = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)); | ||||||
|  |                     var entries = new IndexedCollection<ShopEntry>(config.ShopEntries); | ||||||
|  |                     removed = entries.ElementAtOrDefault(index); | ||||||
|  |                     if (removed != null) | ||||||
|  |                     { | ||||||
|  |                         entries.Remove(removed); | ||||||
|  |  | ||||||
|  |                         config.ShopEntries = entries; | ||||||
|  |                         uow.Complete(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if(removed == null) | ||||||
|  |                     await ReplyErrorLocalized("shop_rem_fail").ConfigureAwait(false); | ||||||
|  |                 else | ||||||
|  |                     await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() | ||||||
|  |                         .WithTitle(GetText("shop_item_add")) | ||||||
|  |                         .AddField(efb => efb.WithName(GetText("name")).WithValue(GetText("shop_role", Format.Bold(removed.RoleName))).WithIsInline(true)) | ||||||
|  |                         .AddField(efb => efb.WithName(GetText("price")).WithValue(removed.Price.ToString()).WithIsInline(true)) | ||||||
|  |                         .AddField(efb => efb.WithName(GetText("type")).WithValue(removed.Type.ToString()).WithIsInline(true))); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             public string EntryToString(ShopEntry entry) | ||||||
|  |             { | ||||||
|  |                 if (entry.Type == ShopEntryType.Role) | ||||||
|  |                 { | ||||||
|  |                     return Format.Bold(entry.Name) + "\n" + GetText("shop_role", Format.Bold(entry.RoleName)); | ||||||
|  |                 } | ||||||
|  |                 else if (entry.Type == ShopEntryType.List) | ||||||
|  |                 { | ||||||
|  |  | ||||||
|  |                 } | ||||||
|  |                 else if (entry.Type == ShopEntryType.Infinite_List) | ||||||
|  |                 { | ||||||
|  |  | ||||||
|  |                 } | ||||||
|  |                 return ""; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										107
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										107
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							| @@ -1716,7 +1716,7 @@ namespace NadekoBot.Resources { | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. |         ///    Looks up a localized string similar to Claim patreon rewards. If you're subscribed to bot owner's patreon you can use this command to claim your rewards - assuming bot owner did setup has their patreon key.. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         public static string claimpatreonrewards_desc { |         public static string claimpatreonrewards_desc { | ||||||
|             get { |             get { | ||||||
| @@ -2103,7 +2103,7 @@ namespace NadekoBot.Resources { | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to `{0}crad 44`. |         ///    Looks up a localized string similar to `{0}crdm 44`. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         public static string crdm_usage { |         public static string crdm_usage { | ||||||
|             get { |             get { | ||||||
| @@ -4173,7 +4173,7 @@ namespace NadekoBot.Resources { | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to `{0}liqu` or `{0}liqu 3`. |         ///    Looks up a localized string similar to Lists all quotes on the server ordered alphabetically. 15 Per page.. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         public static string listquotes_desc { |         public static string listquotes_desc { | ||||||
|             get { |             get { | ||||||
| @@ -4182,7 +4182,7 @@ namespace NadekoBot.Resources { | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to Lists all quotes on the server ordered alphabetically. 15 Per page.. |         ///    Looks up a localized string similar to `{0}liqu` or `{0}liqu 3`. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         public static string listquotes_usage { |         public static string listquotes_usage { | ||||||
|             get { |             get { | ||||||
| @@ -5297,6 +5297,33 @@ namespace NadekoBot.Resources { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to parewrel. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string patreonrewardsreload_cmd { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("patreonrewardsreload_cmd", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Forces the update of the list of patrons who are eligible for the reward.. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string patreonrewardsreload_desc { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("patreonrewardsreload_desc", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to `{0}parewrel`. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string patreonrewardsreload_usage { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("patreonrewardsreload_usage", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to pause p. |         ///    Looks up a localized string similar to pause p. | ||||||
|         /// </summary> |         /// </summary> | ||||||
| @@ -7484,6 +7511,78 @@ namespace NadekoBot.Resources { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to shop. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shop_cmd { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shop_cmd", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Lists this server's administrators' shop. Paginated.. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shop_desc { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shop_desc", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to `{0}shop` or `{0}shop 2`. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shop_usage { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shop_usage", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to shopadd. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shopadd_cmd { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shopadd_cmd", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Adds an item to the shop by specifying type price and name.. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shopadd_desc { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shopadd_desc", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to `{0}shopadd role 1000 Rich`. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shopadd_usage { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shopadd_usage", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to shoprem shoprm. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shopremove_cmd { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shopremove_cmd", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Removes an item from the shop by its color.. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string shopremove_desc { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("shopremove_desc", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to shorten. |         ///    Looks up a localized string similar to shorten. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|   | |||||||
							
								
								
									
										63
									
								
								src/NadekoBot/Resources/ResponseStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										63
									
								
								src/NadekoBot/Resources/ResponseStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							| @@ -2755,6 +2755,15 @@ namespace NadekoBot.Resources { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Name. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string gambling_name { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("gambling_name", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to No more cards in the deck.. |         ///    Looks up a localized string similar to No more cards in the deck.. | ||||||
|         /// </summary> |         /// </summary> | ||||||
| @@ -2854,6 +2863,42 @@ namespace NadekoBot.Resources { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Shop. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string gambling_shop { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("gambling_shop", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Shop item added. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string gambling_shop_item_add { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("gambling_shop_item_add", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to No shop items found on this page.. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string gambling_shop_none { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("gambling_shop_none", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to You will get {0} role.. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string gambling_shop_role { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("gambling_shop_role", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to Bet. |         ///    Looks up a localized string similar to Bet. | ||||||
|         /// </summary> |         /// </summary> | ||||||
| @@ -2972,6 +3017,15 @@ namespace NadekoBot.Resources { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Type. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string gambling_type { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("gambling_type", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to your affinity is already set to that waifu or you're trying to remove your affinity while not having one.. |         ///    Looks up a localized string similar to your affinity is already set to that waifu or you're trying to remove your affinity while not having one.. | ||||||
|         /// </summary> |         /// </summary> | ||||||
| @@ -6115,6 +6169,15 @@ namespace NadekoBot.Resources { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         /// <summary> | ||||||
|  |         ///    Looks up a localized string similar to Next update in {0}. | ||||||
|  |         /// </summary> | ||||||
|  |         public static string utility_clpa_next_update { | ||||||
|  |             get { | ||||||
|  |                 return ResourceManager.GetString("utility_clpa_next_update", resourceCulture); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         ///    Looks up a localized string similar to You've received {0} Thanks for supporting the project!. |         ///    Looks up a localized string similar to You've received {0} Thanks for supporting the project!. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|   | |||||||
| @@ -2406,4 +2406,26 @@ Owner ID: {2}</value> | |||||||
|     <value>Time in {0} is {1} - {2}</value> |     <value>Time in {0} is {1} - {2}</value> | ||||||
|     <comment>Time in London, UK is 15:30 - Time Zone Name</comment> |     <comment>Time in London, UK is 15:30 - Time Zone Name</comment> | ||||||
|   </data> |   </data> | ||||||
|  |   <data name="gambling_name" xml:space="preserve"> | ||||||
|  |     <value>Name</value> | ||||||
|  |   </data> | ||||||
|  |   <data name="gambling_shop" xml:space="preserve"> | ||||||
|  |     <value>Shop</value> | ||||||
|  |   </data> | ||||||
|  |   <data name="gambling_shop_item_add" xml:space="preserve"> | ||||||
|  |     <value>Shop item added</value> | ||||||
|  |   </data> | ||||||
|  |   <data name="gambling_shop_none" xml:space="preserve"> | ||||||
|  |     <value>No shop items found on this page.</value> | ||||||
|  |   </data> | ||||||
|  |   <data name="gambling_shop_role" xml:space="preserve"> | ||||||
|  |     <value>You will get {0} role.</value> | ||||||
|  |   </data> | ||||||
|  |   <data name="gambling_type" xml:space="preserve"> | ||||||
|  |     <value>Type</value> | ||||||
|  |   </data> | ||||||
|  |   <data name="utility_clpa_next_update" xml:space="preserve"> | ||||||
|  |     <value>Next update in {0}</value> | ||||||
|  |     <comment>Next update in 05:30</comment> | ||||||
|  |   </data> | ||||||
| </root> | </root> | ||||||
| @@ -76,6 +76,8 @@ namespace NadekoBot.Services.Database.Models | |||||||
|         public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; } |         public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; } | ||||||
|         public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; } |         public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; } | ||||||
|  |  | ||||||
|  |         public List<ShopEntry> ShopEntries { get; set; } | ||||||
|  |  | ||||||
|         //public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>(); |         //public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								src/NadekoBot/Services/Database/Models/ShopEntry.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/NadekoBot/Services/Database/Models/ShopEntry.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace NadekoBot.Services.Database.Models | ||||||
|  | { | ||||||
|  |     public enum ShopEntryType | ||||||
|  |     { | ||||||
|  |         Role, | ||||||
|  |         List, | ||||||
|  |         Infinite_List, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class ShopEntry : DbEntity, IIndexed | ||||||
|  |     { | ||||||
|  |         public int Index { get; set; } | ||||||
|  |         public int Price { get; set; } | ||||||
|  |         public string Name { get; set; } | ||||||
|  |         public ulong AuthorId { get; set; } | ||||||
|  |  | ||||||
|  |         public ShopEntryType Type { get; set; } | ||||||
|  |         public string RoleName { get; set; } | ||||||
|  |         public ulong RoleId { get; set; } | ||||||
|  |         public List<ShopEntryItem> Items { get; set; } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class ShopEntryItem : DbEntity | ||||||
|  |     { | ||||||
|  |         public string Text { get; set; } | ||||||
|  |  | ||||||
|  |         public override bool Equals(object obj) | ||||||
|  |         { | ||||||
|  |             if (obj == null || GetType() != obj.GetType()) | ||||||
|  |             { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |             return ((ShopEntryItem)obj).Text == Text; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override int GetHashCode() => | ||||||
|  |             Text.GetHashCode(); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user