Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Created January 2, 2019 14:41
Show Gist options
  • Save nathan130200/eb1120e0d3c771d7c65aba249d140458 to your computer and use it in GitHub Desktop.
Save nathan130200/eb1120e0d3c771d7c65aba249d140458 to your computer and use it in GitHub Desktop.
BN Loot & XP Services.
// LootService.cs
using DSharpPlus;
using DSharpPlus.CommandsNext;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.Exceptions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Barberians.Core.Services
{
public class LootService
{
ExperienceService _experience;
ConcurrentDictionary<ulong, long> _channels;
Random _random;
DiscordClient _discord;
public LootService(DiscordClient discord, ExperienceService experience)
{
_experience = experience;
_random = new Random(Environment.TickCount);
_channels = new ConcurrentDictionary<ulong, long>();
_discord = discord;
_discord.GetCommandsNext().CommandExecuted += this.LootService_CommandExecuted;
}
async Task LootService_CommandExecuted(CommandExecutionEventArgs e)
{
var ctx = e.Context;
if (ctx.Guild == null)
return;
if (ctx.Guild.Id != ExperienceService.BNGD)
return;
if (!GotChance())
return;
var chn = ctx.Channel;
var quantity = _random.Next(10, 100);
_channels.AddOrUpdate(chn.Id, quantity, (key, old) => old + quantity);
}
public async Task<(bool success, long quantity)> TryLootAsync(DiscordMember member, DiscordChannel channel)
{
if (!_channels.ContainsKey(channel.Id))
return (false, 0);
if(_channels.TryRemove(channel.Id, out var quantity))
await _experience.UpdateMemberAsync(member, quantity);
return (true, quantity);
}
bool GotChance()
{
var x = _random.Next(int.MinValue, int.MaxValue);
var y = _random.Next(int.MinValue, int.MaxValue);
if (x == y)
return false;
else if (x > y)
return true;
else if (x < y)
return false;
return false;
}
}
}
// ExperienceService.cs
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using Humanizer;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace Barberians.Core.Services
{
public class ExperienceService
{
public const ulong BNGD = 327051205224431616;
private DiscordClient _discord;
private ConcurrentDictionary<ulong, DateTimeOffset> _cooldown;
private ConcurrentDictionary<ulong, long> _cache;
private Timer _timer;
public ExperienceService(DiscordClient discord)
{
_discord = discord;
_timer = new Timer(30.Seconds().TotalMilliseconds);
_timer.Elapsed += this.Elapsed;
_cooldown = new ConcurrentDictionary<ulong, DateTimeOffset>();
_cache = new ConcurrentDictionary<ulong, long>();
_discord.MessageCreated += this.Discord_MessageCreated;
}
async void Elapsed(object sender, ElapsedEventArgs e)
{
// update cache on DB.
}
async Task Discord_MessageCreated(MessageCreateEventArgs e)
{
if (e.Guild == null)
return;
if (e.Guild.Id != BNGD)
return;
if(_cooldown.TryGetValue(e.Author.Id, out var dto) && DateTimeOffset.Now.Add(1.Minutes()) > dto)
{
dto = DateTimeOffset.Now;
_cooldown.AddOrUpdate(e.Author.Id, dto, (key, old) => dto);
_cache.AddOrUpdate(e.Author.Id, 100, (key, old) => old + 100);
}
else
{
_cooldown.AddOrUpdate(e.Author.Id, DateTimeOffset.Now, (key, old) => old);
}
}
public async Task<long> GetExperienceAsync(ulong id)
{
return this._cache.GetValueOrDefault(id, 100);
}
public async Task UpdateMemberAsync(DiscordMember member, long quantity)
{
_cache.AddOrUpdate(member.Id, quantity, (key, old) => old + quantity);
}
}
}
// ProfileModule.cs
using Barberians.Core.Services;
using DSharpPlus.CommandsNext;
using DSharpPlus.CommandsNext.Attributes;
using DSharpPlus.CommandsNext.Exceptions;
using DSharpPlus.Entities;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Humanizer;
namespace Barberians.Core.Modules
{
[ModuleLifespan(ModuleLifespan.Transient)]
public class ProfileModule : BaseCommandModule
{
readonly ExperienceService _experience;
readonly LootService _loot;
public ProfileModule(ExperienceService es, LootService ls)
{
_experience = es;
_loot = ls;
}
[Command, Description("Exibe a quantia de xp do usuário fornecido.")]
public async Task XpAsync(CommandContext ctx, [RemainingText] DiscordMember membro = null)
{
await ctx.TriggerTypingAsync();
if (membro == null)
membro = ctx.Member; ;
var xp = await _experience.GetExperienceAsync(membro.Id);
var self = ctx.Member == membro;
await ctx.RespondAsync($"{ctx.User.Mention} :cyclone: {(!self ? $"O membro `{membro.Username}#{membro.Mention}`" : "Você")} tem **{xp}** XP.");
}
[Command, Description("Faz loot nesse canal em busca de XP perdidos")]
public async Task LootAsync(CommandContext ctx)
{
var (result, quantity) = await _loot.TryLootAsync(ctx.Member, ctx.Channel);
if (!result)
{
await ctx.RespondAsync($"{ctx.User.Mention} :sob: Esse canal está vazio.");
return;
}
await ctx.RespondAsync($"{ctx.User.Mention} :runner: Você caminhou... E encontrou :moneybag: **{quantity}** XP");
return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment