mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28: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
|
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
|
## [4.3.22] - 23.04.2023
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="3.203.0" />
|
<PackageReference Include="Discord.Net" Version="3.204.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -5,8 +5,8 @@ public enum ShopEntryType
|
|||||||
{
|
{
|
||||||
Role,
|
Role,
|
||||||
|
|
||||||
List
|
List,
|
||||||
//Infinite_List,
|
Command
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ShopEntry : DbEntity, IIndexed
|
public class ShopEntry : DbEntity, IIndexed
|
||||||
@@ -25,6 +25,9 @@ public class ShopEntry : DbEntity, IIndexed
|
|||||||
//list
|
//list
|
||||||
public HashSet<ShopEntryItem> Items { get; set; } = new();
|
public HashSet<ShopEntryItem> Items { get; set; } = new();
|
||||||
public ulong? RoleRequirement { get; set; }
|
public ulong? RoleRequirement { get; set; }
|
||||||
|
|
||||||
|
// command
|
||||||
|
public string Command { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ShopEntryItem : DbEntity
|
public class ShopEntryItem : DbEntity
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<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" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ using Nadeko.Bot.Db.Models;
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using LinqToDB.EntityFrameworkCore;
|
using LinqToDB.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NadekoBot.Db.Models;
|
using NadekoBot.Db.Models;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Administration.Services;
|
namespace NadekoBot.Modules.Administration.Services;
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<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" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
using Nadeko.Bot.Db.Models;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Gambling.Services;
|
namespace NadekoBot.Modules.Gambling.Services;
|
||||||
|
|
||||||
public interface IShopService
|
public interface IShopService
|
||||||
@@ -40,4 +42,5 @@ public interface IShopService
|
|||||||
Task<bool> MoveEntryAsync(ulong guildId, int fromIndex, int toIndex);
|
Task<bool> MoveEntryAsync(ulong guildId, int fromIndex, int toIndex);
|
||||||
|
|
||||||
Task<bool> SetItemRoleRequirementAsync(ulong guildId, int index, ulong? roleId);
|
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.Common;
|
||||||
using NadekoBot.Modules.Gambling.Services;
|
using NadekoBot.Modules.Gambling.Services;
|
||||||
using Nadeko.Bot.Db.Models;
|
using Nadeko.Bot.Db.Models;
|
||||||
|
using NadekoBot.Modules.Administration;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Gambling;
|
namespace NadekoBot.Modules.Gambling;
|
||||||
|
|
||||||
@@ -22,6 +23,12 @@ public partial class Gambling
|
|||||||
Role
|
Role
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Command
|
||||||
|
{
|
||||||
|
Command,
|
||||||
|
Cmd
|
||||||
|
}
|
||||||
|
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly ICurrencyService _cs;
|
private readonly ICurrencyService _cs;
|
||||||
|
|
||||||
@@ -156,7 +163,7 @@ public partial class Gambling
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.Type == ShopEntryType.List)
|
else if (entry.Type == ShopEntryType.List)
|
||||||
{
|
{
|
||||||
if (entry.Items.Count == 0)
|
if (entry.Items.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -213,11 +220,79 @@ public partial class Gambling
|
|||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
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)
|
private static long GetProfitAmount(int price)
|
||||||
=> (int)Math.Ceiling(0.90 * 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]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
@@ -471,6 +546,14 @@ public partial class Gambling
|
|||||||
.AddField(GetText(strs.type), GetText(strs.random_unique_item), true);
|
.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)
|
//else if (entry.Type == ShopEntryType.Infinite_List)
|
||||||
// return embed.AddField(GetText(strs.name), GetText(strs.shop_role(Format.Bold(entry.RoleName)), true))
|
// return embed.AddField(GetText(strs.name), GetText(strs.shop_role(Format.Bold(entry.RoleName)), true))
|
||||||
// .AddField(GetText(strs.price), entry.Price.ToString(), 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")));
|
+ GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name ?? "MISSING_ROLE")));
|
||||||
if (entry.Type == ShopEntryType.List)
|
if (entry.Type == ShopEntryType.List)
|
||||||
return prepend + GetText(strs.unique_items_left(entry.Items.Count)) + "\n" + entry.Name;
|
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;
|
return prepend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NadekoBot.Db;
|
using NadekoBot.Db;
|
||||||
|
|
||||||
using Nadeko.Bot.Db.Models;
|
using Nadeko.Bot.Db.Models;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Gambling.Services;
|
namespace NadekoBot.Modules.Gambling.Services;
|
||||||
@@ -14,7 +13,9 @@ public class ShopService : IShopService, INService
|
|||||||
=> _db = db;
|
=> _db = db;
|
||||||
|
|
||||||
private IndexedCollection<ShopEntry> GetEntriesInternal(DbContext uow, ulong guildId)
|
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();
|
.ShopEntries.ToIndexed();
|
||||||
|
|
||||||
public async Task<bool> ChangeEntryPriceAsync(ulong guildId, int index, int newPrice)
|
public async Task<bool> ChangeEntryPriceAsync(ulong guildId, int index, int newPrice)
|
||||||
@@ -109,4 +110,24 @@ public class ShopService : IShopService, INService
|
|||||||
await uow.SaveChangesAsync();
|
await uow.SaveChangesAsync();
|
||||||
return true;
|
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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net.Core" Version="3.203.0" />
|
<PackageReference Include="Discord.Net.Core" Version="3.204.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
using Nadeko.Bot.Db.Models;
|
||||||
using NadekoBot.Db.Models;
|
using NadekoBot.Db.Models;
|
||||||
|
|
||||||
namespace NadekoBot.Services.Database.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"
|
- "2"
|
||||||
shopadd:
|
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:
|
args:
|
||||||
- "role 1000 Rich"
|
- "role 1000 Rich"
|
||||||
|
- "cmd 1000 .setrole %user% Rich"
|
||||||
shopremove:
|
shopremove:
|
||||||
desc: "Removes an item from the shop by its ID."
|
desc: "Removes an item from the shop by its ID."
|
||||||
args:
|
args:
|
||||||
|
@@ -710,6 +710,7 @@
|
|||||||
"shop_item_add": "Shop item added",
|
"shop_item_add": "Shop item added",
|
||||||
"shop_none": "No shop items found on this page.",
|
"shop_none": "No shop items found on this page.",
|
||||||
"shop_role": "You will get {0} role.",
|
"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",
|
"type": "Type",
|
||||||
"gvc_disabled": "Game Voice Channel feature has been disabled on this server.",
|
"gvc_disabled": "Game Voice Channel feature has been disabled on this server.",
|
||||||
"gvc_enabled": "{0} is a Game Voice Channel now.",
|
"gvc_enabled": "{0} is a Game Voice Channel now.",
|
||||||
|
Reference in New Issue
Block a user