Keeps the repo root clean - only README.md visible on landing page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
180 lines
8.2 KiB
C#
180 lines
8.2 KiB
C#
#r "C:\Users\QDave\Desktop\libary\Discord.Net.Commands.3.10.0\lib\net6.0\Discord.Net.Commands.dll"
|
|
#r "C:\Users\QDave\Desktop\libary\Discord.Net.Core.3.10.0\lib\net6.0\Discord.Net.Core.dll"
|
|
#r "C:\Users\QDave\Desktop\libary\Discord.Net.Interactions.3.10.0\lib\net6.0\Discord.Net.Interactions.dll"
|
|
#r "C:\Users\QDave\Desktop\libary\Discord.Net.Rest.3.10.0\lib\net6.0\Discord.Net.Rest.dll"
|
|
#r "C:\Users\QDave\Desktop\libary\Discord.Net.Webhook.3.10.0\lib\net6.0\Discord.Net.Webhook.dll"
|
|
#r "C:\Users\QDave\Desktop\libary\Discord.Net.WebSocket.3.10.0\lib\net6.0\Discord.Net.WebSocket.dll"
|
|
#r "C:\Users\QDave\Desktop\libary\Newtonsoft.Json.13.0.2\lib\net6.0\Newtonsoft.Json.dll"
|
|
|
|
using Discord;
|
|
using Discord.WebSocket;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Xabbo.Core.GameData;
|
|
|
|
ulong desiredServerId = 1106247469882409040;
|
|
ulong desiredChannelId = 1106247469882409043;
|
|
|
|
(int Average, List<(int price, int daysAgo, int volume)> Prices) GetRealAverage(FurniInfo finditem)
|
|
{
|
|
var mpInfo = GetMarketplaceInfo(finditem).TradeInfo;
|
|
int total = 0;
|
|
List<(int, int, int)> prices = new List<(int, int, int)>();
|
|
foreach (var info in mpInfo)
|
|
{
|
|
total += info.AverageSalePrice;
|
|
prices.Add((info.AverageSalePrice, info.DayOffset, info.TradeVolume));
|
|
}
|
|
int average = mpInfo.Count != 0 ? total / mpInfo.Count : -1;
|
|
return (average, prices);
|
|
}
|
|
|
|
var config = new DiscordSocketConfig
|
|
{
|
|
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent
|
|
};
|
|
|
|
var client = new DiscordSocketClient(config);
|
|
|
|
client.Log += (logMessage) =>
|
|
{
|
|
Log($"[{DateTime.Now}] {logMessage.Message}");
|
|
return Task.CompletedTask;
|
|
};
|
|
|
|
client.LoginAsync(TokenType.Bot, "DISCORD_BOT_TOKEN_HERE");
|
|
|
|
client.Ready += () =>
|
|
{
|
|
Log($"[{DateTime.Now}] Bot is now online!");
|
|
return Task.CompletedTask;
|
|
};
|
|
|
|
client.MessageReceived += async (message) =>
|
|
{
|
|
// Check if the message was sent in the desired channel
|
|
if (message.Channel.Id != desiredChannelId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (message.Content.StartsWith("!pc"))
|
|
{
|
|
var furniname = message.Content.Substring(4);
|
|
var furnidata = FurniData.FindItem(furniname);
|
|
if (furnidata == null)
|
|
{
|
|
string noneFoundReply = $"Sadly I could not find the item you are looking for :(";
|
|
var embedBuilder = new EmbedBuilder()
|
|
.WithTitle(noneFoundReply)
|
|
.WithColor(Color.Red)
|
|
.WithFooter("Made by Khale • Last updated:")
|
|
.WithTimestamp(DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")));
|
|
await message.Channel.SendMessageAsync(embed: embedBuilder.Build());
|
|
}
|
|
else
|
|
{
|
|
(int average, var prices) = GetRealAverage(furnidata);
|
|
if (prices.Count == 0)
|
|
{
|
|
string noneFoundReply = $"Sadly {furnidata.Name} has had no sales in the last 30 days :(";
|
|
var embedBuilder = new EmbedBuilder()
|
|
.WithTitle($"Here are {furnidata.Name}'s most recent statistics:")
|
|
.WithColor(Color.Red)
|
|
.WithThumbnailUrl($"https://images.habbo.com/dcr/hof_furni/{furnidata.Revision}/{furnidata.Identifier.Replace('*', '_')}_icon.png")
|
|
.WithFooter("Made by Khale • Last updated:")
|
|
.WithTimestamp(DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")))
|
|
.WithDescription(noneFoundReply);
|
|
var info = FurniData[furnidata.Identifier];
|
|
var mpOffer = SearchMarketplace(info.Name, 0, 99999, MarketplaceSortOrder.LowestPrice)
|
|
.OfKind(furnidata.Identifier)
|
|
.FirstOrDefault();
|
|
Log(info.Name);
|
|
if (mpOffer != null)
|
|
{
|
|
string currentPriceReply = $"{mpOffer.Price}c";
|
|
embedBuilder.AddField("Price", currentPriceReply, true);
|
|
string offerAmountReply = $"{mpOffer.Offers}";
|
|
embedBuilder.AddField("Offers", offerAmountReply, true);
|
|
string isLTD = mpOffer.Data.IsLimitedRare ? "Yes" : "No";
|
|
embedBuilder.AddField("LTD", isLTD, true);
|
|
string line1 = $"{info.Line.Replace('_', ' ')}";
|
|
embedBuilder.AddField("Line", line1, true);
|
|
string sales1 = $"{info.Type},{info.Category},{info.CategoryName}";
|
|
embedBuilder.AddField("Type", sales1, true);
|
|
string sales2 = $"{info.XDimension}x{info.YDimension}";
|
|
embedBuilder.AddField("Size", sales2, true);
|
|
}
|
|
|
|
await message.Channel.SendMessageAsync(embed: embedBuilder.Build());
|
|
}
|
|
else
|
|
{
|
|
string greetingReply = $"Here are {furnidata.Name}'s most recent statistics:";
|
|
var embedBuilder = new EmbedBuilder()
|
|
.WithTitle(greetingReply)
|
|
.WithColor(new Color(0,136,255));
|
|
foreach (var priceDate in prices.TakeLast(9).Reverse())
|
|
{
|
|
int daysAgo = Math.Abs(priceDate.daysAgo);
|
|
DateTime saleDate = DateTime.UtcNow.AddDays(-daysAgo);
|
|
int timestamp = (int)(saleDate - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
|
|
string daysAgoDiscord = $"<t:{timestamp}:R>";
|
|
string priceReply = $"{priceDate.volume} {(priceDate.volume == 1 ? "time " : "times ")} for {priceDate.price}c";
|
|
var thumbnailUrl = $"https://images.habbo.com/dcr/hof_furni/{furnidata.Revision}/{furnidata.Identifier.Replace('*', '_')}_icon.png";
|
|
embedBuilder.AddField($"Sold {daysAgoDiscord}", priceReply, true)
|
|
.WithThumbnailUrl(thumbnailUrl)
|
|
.WithFooter("Made by Khale • Last updated:")
|
|
.WithTimestamp(DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")));
|
|
}
|
|
|
|
string averageReply = $"The average over the last 30 days is: {average}c";
|
|
embedBuilder.AddField("Average over last 30 days", averageReply);
|
|
|
|
var info = FurniData[furnidata.Identifier];
|
|
var mpOffer = SearchMarketplace(info.Name, 0, 99999, MarketplaceSortOrder.LowestPrice)
|
|
.OfKind(furnidata.Identifier)
|
|
.FirstOrDefault();
|
|
Log(info.Name);
|
|
if (mpOffer != null)
|
|
{
|
|
string currentPriceReply = $"{mpOffer.Price}c";
|
|
embedBuilder.AddField("Price", currentPriceReply, true);
|
|
string offerAmountReply = $"{mpOffer.Offers}";
|
|
embedBuilder.AddField("Offers", offerAmountReply, true);
|
|
string isLTD = mpOffer.Data.IsLimitedRare ? "Yes" : "No";
|
|
embedBuilder.AddField("LTD", isLTD, true);
|
|
string line1 = $"{info.Line.Replace('_', ' ')}";
|
|
embedBuilder.AddField("Line", line1, true);
|
|
string sales1 = $"{info.Type},{info.Category},{info.CategoryName}";
|
|
embedBuilder.AddField("Type", sales1, true);
|
|
string sales2 = $"{info.XDimension}x{info.YDimension}";
|
|
embedBuilder.AddField("Size", sales2, true);
|
|
|
|
// Check if the price was boosted
|
|
if (mpOffer.Price > (1.1 * average))
|
|
{
|
|
double percentage = ((double)(mpOffer.Price - average) / average) * 100;
|
|
string priceBoostedReply = $"The price of {furnidata.Name} is above the avg by **over {percentage:F0}%**!";
|
|
|
|
|
|
embedBuilder.AddField(":exclamation:Price boosted", priceBoostedReply);
|
|
}
|
|
}
|
|
|
|
await message.Channel.SendMessageAsync(embed: embedBuilder.Build());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Ct.Register(async () => {
|
|
await client.StopAsync();
|
|
await client.LogoutAsync();
|
|
client.Dispose();
|
|
});
|
|
|
|
await client.StartAsync();
|
|
await Task.Delay(-1); |