mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 09:18:27 -04:00
Added .shopadd cmd
This commit is contained in:
@@ -2,6 +2,14 @@
|
||||
|
||||
Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
|
||||
|
||||
## [5.0.0]
|
||||
|
||||
### Added
|
||||
|
||||
- `.shopadd command` You can now sell commands in the shop. The command will execute as if you were the one running it when someone buys it
|
||||
- type `.h .shopadd` for more info
|
||||
-
|
||||
|
||||
## [4.3.22] - 23.04.2023
|
||||
|
||||
### Added
|
||||
|
@@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.203.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.204.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -5,8 +5,8 @@ public enum ShopEntryType
|
||||
{
|
||||
Role,
|
||||
|
||||
List
|
||||
//Infinite_List,
|
||||
List,
|
||||
Command
|
||||
}
|
||||
|
||||
public class ShopEntry : DbEntity, IIndexed
|
||||
@@ -25,6 +25,9 @@ public class ShopEntry : DbEntity, IIndexed
|
||||
//list
|
||||
public HashSet<ShopEntryItem> Items { get; set; } = new();
|
||||
public ulong? RoleRequirement { get; set; }
|
||||
|
||||
// command
|
||||
public string Command { get; set; }
|
||||
}
|
||||
|
||||
public class ShopEntryItem : DbEntity
|
||||
|
@@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.203.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.204.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -4,6 +4,7 @@ using Nadeko.Bot.Db.Models;
|
||||
using System.Collections.Immutable;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
@@ -14,7 +14,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.203.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.204.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#nullable disable
|
||||
using Nadeko.Bot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Services;
|
||||
|
||||
public interface IShopService
|
||||
@@ -40,4 +42,5 @@ public interface IShopService
|
||||
Task<bool> MoveEntryAsync(ulong guildId, int fromIndex, int toIndex);
|
||||
|
||||
Task<bool> SetItemRoleRequirementAsync(ulong guildId, int index, ulong? roleId);
|
||||
Task<ShopEntry> AddShopCommandAsync(ulong guildId, ulong userId, int price, string command);
|
||||
}
|
@@ -4,6 +4,7 @@ using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Gambling.Common;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
using Nadeko.Bot.Db.Models;
|
||||
using NadekoBot.Modules.Administration;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling;
|
||||
|
||||
@@ -22,6 +23,12 @@ public partial class Gambling
|
||||
Role
|
||||
}
|
||||
|
||||
public enum Command
|
||||
{
|
||||
Command,
|
||||
Cmd
|
||||
}
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly ICurrencyService _cs;
|
||||
|
||||
@@ -156,7 +163,7 @@ public partial class Gambling
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.Type == ShopEntryType.List)
|
||||
else if (entry.Type == ShopEntryType.List)
|
||||
{
|
||||
if (entry.Items.Count == 0)
|
||||
{
|
||||
@@ -213,11 +220,79 @@ public partial class Gambling
|
||||
else
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||
}
|
||||
else if (entry.Type == ShopEntryType.Command)
|
||||
{
|
||||
var guild = ctx.Guild as SocketGuild;
|
||||
var channel = ctx.Channel as ISocketMessageChannel;
|
||||
var msg = ctx.Message as SocketUserMessage;
|
||||
var user = await ctx.Guild.GetUserAsync(entry.AuthorId);
|
||||
|
||||
if (guild is null || channel is null || msg is null || user is null)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.shop_command_invalid_context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await _cs.RemoveAsync(ctx.User.Id, entry.Price, new("shop", "buy", entry.Type.ToString())))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cmd = entry.Command.Replace("%you%", ctx.User.Id.ToString());
|
||||
var eb = _eb.Create()
|
||||
.WithPendingColor()
|
||||
.WithTitle("Executing shop command")
|
||||
.WithDescription(cmd);
|
||||
|
||||
var msgTask = ctx.Channel.EmbedAsync(eb);
|
||||
|
||||
await _cs.AddAsync(entry.AuthorId,
|
||||
GetProfitAmount(entry.Price),
|
||||
new("shop", "sell", entry.Name));
|
||||
|
||||
await _cmdHandler.TryRunCommand(guild,
|
||||
channel,
|
||||
new DoAsUserMessage(
|
||||
msg,
|
||||
user,
|
||||
cmd
|
||||
));
|
||||
|
||||
try
|
||||
{
|
||||
var pendingMsg = await msgTask;
|
||||
await pendingMsg.EditAsync(SmartEmbedText.FromEmbed(eb
|
||||
.WithOkColor()
|
||||
.WithTitle("Shop command executed")
|
||||
.Build()));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static long GetProfitAmount(int price)
|
||||
=> (int)Math.Ceiling(0.90 * price);
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
[BotPerm(GuildPerm.ManageRoles)]
|
||||
public async Task ShopAdd(Command _, int price, [Leftover] string command)
|
||||
{
|
||||
if (price < 1)
|
||||
return;
|
||||
|
||||
|
||||
var entry = await _service.AddShopCommandAsync(ctx.Guild.Id, ctx.User.Id, price, command);
|
||||
|
||||
await ctx.Channel.EmbedAsync(EntryToEmbed(entry).WithTitle(GetText(strs.shop_item_add)));
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
@@ -471,6 +546,14 @@ public partial class Gambling
|
||||
.AddField(GetText(strs.type), GetText(strs.random_unique_item), true);
|
||||
}
|
||||
|
||||
else if (entry.Type == ShopEntryType.Command)
|
||||
{
|
||||
return embed
|
||||
.AddField(GetText(strs.name), Format.Code(entry.Command), true)
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
||||
}
|
||||
|
||||
//else if (entry.Type == ShopEntryType.Infinite_List)
|
||||
// return embed.AddField(GetText(strs.name), GetText(strs.shop_role(Format.Bold(entry.RoleName)), true))
|
||||
// .AddField(GetText(strs.price), entry.Price.ToString(), true)
|
||||
@@ -490,6 +573,9 @@ public partial class Gambling
|
||||
+ GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name ?? "MISSING_ROLE")));
|
||||
if (entry.Type == ShopEntryType.List)
|
||||
return prepend + GetText(strs.unique_items_left(entry.Items.Count)) + "\n" + entry.Name;
|
||||
|
||||
if (entry.Type == ShopEntryType.Command)
|
||||
return prepend + Format.Code(entry.Command);
|
||||
return prepend;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Db;
|
||||
|
||||
using Nadeko.Bot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Services;
|
||||
@@ -14,7 +13,9 @@ public class ShopService : IShopService, INService
|
||||
=> _db = db;
|
||||
|
||||
private IndexedCollection<ShopEntry> GetEntriesInternal(DbContext uow, ulong guildId)
|
||||
=> uow.GuildConfigsForId(guildId, set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
|
||||
=> uow.GuildConfigsForId(guildId,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries.ToIndexed();
|
||||
|
||||
public async Task<bool> ChangeEntryPriceAsync(ulong guildId, int index, int newPrice)
|
||||
@@ -109,4 +110,24 @@ public class ShopService : IShopService, INService
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<ShopEntry> AddShopCommandAsync(ulong guildId, ulong userId, int price, string command)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
var entry = new ShopEntry()
|
||||
{
|
||||
AuthorId = userId,
|
||||
Command = command,
|
||||
Type = ShopEntryType.Command,
|
||||
Price = price,
|
||||
};
|
||||
entries.Add(entry);
|
||||
uow.GuildConfigsForId(guildId, set => set).ShopEntries = entries;
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
return entry;
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net.Core" Version="3.203.0" />
|
||||
<PackageReference Include="Discord.Net.Core" Version="3.204.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#nullable disable
|
||||
using Nadeko.Bot.Db.Models;
|
||||
using NadekoBot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Services.Database.Models;
|
||||
|
3788
src/NadekoBot/Migrations/Mysql/20240423140608_shopcommands.Designer.cs
generated
Normal file
3788
src/NadekoBot/Migrations/Mysql/20240423140608_shopcommands.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
1362
src/NadekoBot/Migrations/Mysql/20240423140608_shopcommands.cs
Normal file
1362
src/NadekoBot/Migrations/Mysql/20240423140608_shopcommands.cs
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3785
src/NadekoBot/Migrations/Postgresql/20240423140552_shopcommands.Designer.cs
generated
Normal file
3785
src/NadekoBot/Migrations/Postgresql/20240423140552_shopcommands.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Db.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class shopcommands : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "command",
|
||||
table: "shopentry",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "command",
|
||||
table: "shopentry");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
2917
src/NadekoBot/Migrations/Sqlite/20240423113453_shopcommands.Designer.cs
generated
Normal file
2917
src/NadekoBot/Migrations/Sqlite/20240423113453_shopcommands.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Db.Migrations.Sqlite
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class shopcommands : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Command",
|
||||
table: "ShopEntry",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Command",
|
||||
table: "ShopEntry");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1751,9 +1751,14 @@ shop:
|
||||
- ""
|
||||
- "2"
|
||||
shopadd:
|
||||
desc: "Adds an item to the shop by specifying type price and name. Available types are role and list. 90% of currency from each purchase will be received by the user who added the item to the shop."
|
||||
desc: |-
|
||||
- Available types are role, list and command.
|
||||
- If the item is a role, specify a role id or a role name.
|
||||
- If the item is a command, specify the full command, replacing the user with %user% (for a mention) or %user.id% for user id.
|
||||
90% of currency from each purchase will be received by the user who added the item to the shop.
|
||||
args:
|
||||
- "role 1000 Rich"
|
||||
- "cmd 1000 .setrole %user% Rich"
|
||||
shopremove:
|
||||
desc: "Removes an item from the shop by its ID."
|
||||
args:
|
||||
|
@@ -710,6 +710,7 @@
|
||||
"shop_item_add": "Shop item added",
|
||||
"shop_none": "No shop items found on this page.",
|
||||
"shop_role": "You will get {0} role.",
|
||||
"shop_command_invalid_context": "Unable to retrieve user, channel or server in order to execute the command.",
|
||||
"type": "Type",
|
||||
"gvc_disabled": "Game Voice Channel feature has been disabled on this server.",
|
||||
"gvc_enabled": "{0} is a Game Voice Channel now.",
|
||||
|
Reference in New Issue
Block a user