Restructuring project for new bots
This commit is contained in:
parent
5ccb4b730f
commit
e40fc42482
287
Commands.fs
287
Commands.fs
@ -1,287 +0,0 @@
|
|||||||
module Joebot.Commands
|
|
||||||
|
|
||||||
open System
|
|
||||||
open System.Threading.Tasks
|
|
||||||
open DSharpPlus
|
|
||||||
open DSharpPlus.Entities
|
|
||||||
open DSharpPlus.EventArgs
|
|
||||||
open DSharpPlus.SlashCommands
|
|
||||||
open Joebot.Types
|
|
||||||
open Joebot.Functions
|
|
||||||
|
|
||||||
let mutable players : Player list = []
|
|
||||||
|
|
||||||
[<Literal>]
|
|
||||||
let battleChannel = 930363007781978142uL
|
|
||||||
|
|
||||||
let addHackerRole (ctx : InteractionContext) =
|
|
||||||
async {
|
|
||||||
for role in ctx.Guild.Roles do
|
|
||||||
if role.Value.Name = "Hacker" then
|
|
||||||
do! ctx.Member.GrantRoleAsync(role.Value)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
let player = players |> List.tryFind (fun p -> int64 p.DiscordId = int64 ctx.Member.Id)
|
|
||||||
players <-
|
|
||||||
match player with
|
|
||||||
| Some _ -> players
|
|
||||||
| None -> (newPlayer ctx.Member.Username ctx.Member.Id)::players
|
|
||||||
|
|
||||||
if Option.isSome player then
|
|
||||||
do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
else
|
|
||||||
do! ctx.CreateResponseAsync("You are now an elite haxxor", true)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
|
|
||||||
let removeHackerRole (ctx : InteractionContext) =
|
|
||||||
async {
|
|
||||||
for role in ctx.Member.Roles do
|
|
||||||
if role.Name = "Hacker" then
|
|
||||||
do! ctx.Member.RevokeRoleAsync(role)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
players <- players |> List.filter (fun p -> p.DiscordId <> ctx.User.Id)
|
|
||||||
do! ctx.CreateResponseAsync("You are now lame", true)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
|
|
||||||
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
|
||||||
// TODO: We need to check if the player has any active embed hacks going, if not they can cheat
|
|
||||||
let attacker = players |> List.tryFind (fun p -> p.DiscordId = ctx.Member.Id)
|
|
||||||
let defender = players |> List.tryFind (fun p -> p.DiscordId = target.Id)
|
|
||||||
match attacker , defender with
|
|
||||||
| Some attacker , Some defender ->
|
|
||||||
let updatedAttacks = removeExpiredActions (TimeSpan.FromMinutes(5)) (fun (atk : Attack) -> atk.Timestamp) attacker.Attacks
|
|
||||||
players <-
|
|
||||||
players
|
|
||||||
|> List.map (fun p -> if p.DiscordId = attacker.DiscordId then { p with Attacks = updatedAttacks } else p)
|
|
||||||
if updatedAttacks.Length < 2 then
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.AddEmbed (constructEmbed "Pick the hack you wish to use.") |> ignore
|
|
||||||
|
|
||||||
let defenderInfo = $"{defender.DiscordId}-{target.Username}"
|
|
||||||
constructButtons "Attack" defenderInfo attacker.Weapons
|
|
||||||
|> Seq.cast<DiscordComponent>
|
|
||||||
|> builder.AddComponents
|
|
||||||
|> ignore
|
|
||||||
|
|
||||||
builder.AsEphemeral true |> ignore
|
|
||||||
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
else
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
let timestamp = updatedAttacks |> List.rev |> List.head |> fun a -> a.Timestamp // This should be the next expiring timestamp
|
|
||||||
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - timestamp)
|
|
||||||
builder.Content <- $"No more hacks available, please wait {timeRemaining.Minutes} minutes and {timeRemaining.Seconds} seconds to attempt another hack"
|
|
||||||
|
|
||||||
builder.AsEphemeral true |> ignore
|
|
||||||
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
| None , _ -> notYetAHackerMsg ctx
|
|
||||||
| _ , None -> createSimpleResponseAsync "Your target is not connected to the network, they must join first by using the /redpill command" ctx
|
|
||||||
|
|
||||||
let defend (ctx : InteractionContext) =
|
|
||||||
players
|
|
||||||
|> List.tryFind (fun p -> p.DiscordId = ctx.Member.Id)
|
|
||||||
|> function
|
|
||||||
| Some player ->
|
|
||||||
async {
|
|
||||||
let updatedDefenses = removeExpiredActions (TimeSpan.FromMinutes(60)) (fun (pro : Defense) -> pro.Timestamp) player.Defenses
|
|
||||||
players <-
|
|
||||||
players
|
|
||||||
|> List.map (fun p -> if p.DiscordId = player.DiscordId then { p with Defenses = updatedDefenses } else p)
|
|
||||||
if updatedDefenses.Length < 2 then
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.AddEmbed (constructEmbed "Pick a defense to mount for a duration of time") |> ignore
|
|
||||||
|
|
||||||
constructButtons "Defend" (string player.DiscordId) player.Shields
|
|
||||||
|> Seq.cast<DiscordComponent>
|
|
||||||
|> builder.AddComponents
|
|
||||||
|> ignore
|
|
||||||
|
|
||||||
builder.AsEphemeral true |> ignore
|
|
||||||
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
else
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
let timestamp = updatedDefenses |> List.rev |> List.head |> fun a -> a.Timestamp // This should be the next expiring timestamp
|
|
||||||
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - timestamp)
|
|
||||||
builder.Content <- $"Cannot add new defense, please wait {timeRemaining.Minutes} minutes and {timeRemaining.Seconds} seconds to add another defense"
|
|
||||||
|
|
||||||
builder.AsEphemeral true |> ignore
|
|
||||||
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
| None -> notYetAHackerMsg ctx
|
|
||||||
|
|
||||||
let status (ctx : InteractionContext) =
|
|
||||||
async {
|
|
||||||
return!
|
|
||||||
match players |> List.tryFind (fun p -> p.DiscordId = ctx.Member.Id) with
|
|
||||||
| Some player ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- Functions.statusFormat player
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
}
|
|
||||||
| None -> notYetAHackerMsg ctx |> Async.AwaitTask
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
|
|
||||||
let leaderboard (ctx : InteractionContext) =
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
let content =
|
|
||||||
players
|
|
||||||
|> List.sortByDescending (fun p -> p.Bank)
|
|
||||||
|> List.mapi (fun i p -> $"{i + 1}. {p.Bank} {p.Name}")
|
|
||||||
|> String.concat "\n"
|
|
||||||
builder.Content <- if not <| String.IsNullOrEmpty content then content else "There are no active hackers"
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
|
|
||||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
|
||||||
let updatePlayer amount attack p = {
|
|
||||||
p with Attacks = attack::p.Attacks
|
|
||||||
Bank = MathF.Max(p.Bank + amount, 0f)
|
|
||||||
}
|
|
||||||
async {
|
|
||||||
let split = event.Id.Split("-")
|
|
||||||
let resultHack = Weapon.TryParse(split.[1])
|
|
||||||
let ( resultId , targetId ) = UInt64.TryParse split.[2]
|
|
||||||
return!
|
|
||||||
match resultHack , resultId with
|
|
||||||
| Some weapon , true ->
|
|
||||||
let hackType = weapon
|
|
||||||
players
|
|
||||||
|> List.find (fun p -> p.DiscordId = targetId)
|
|
||||||
|> fun p -> p.Defenses
|
|
||||||
|> List.map (fun dfn -> dfn.DefenseType)
|
|
||||||
|> List.map (calculateDamage hackType)
|
|
||||||
|> List.contains Weak
|
|
||||||
|> function
|
|
||||||
| false ->
|
|
||||||
async {
|
|
||||||
let prize = 0.1726f
|
|
||||||
let attack = { HackType = hackType ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
|
||||||
players <-
|
|
||||||
players
|
|
||||||
|> List.map (fun p -> if p.DiscordId = event.User.Id then updatePlayer prize attack p else p)
|
|
||||||
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Successfully hacked {split.[3]} using {hackType}! You just won {prize} genz!"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
let builder = DiscordMessageBuilder()
|
|
||||||
builder.WithContent($"{event.User.Username} successfully hacked <@{targetId}>!") |> ignore
|
|
||||||
let channel = (event.Guild.GetChannel(battleChannel))
|
|
||||||
do! channel.SendMessageAsync(builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|> Async.Ignore
|
|
||||||
}
|
|
||||||
| true ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
let loss = -0.0623f
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Hack failed! {split.[3]} was able to mount a successful defense! You lost {loss} genz!"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
let attack = { HackType = hackType ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
|
||||||
players <-
|
|
||||||
players
|
|
||||||
|> List.map (fun p -> if p.DiscordId = event.User.Id then updatePlayer loss attack p else p)
|
|
||||||
|
|
||||||
let builder = DiscordMessageBuilder()
|
|
||||||
builder.WithContent($"{event.User.Username} failed to hack <@{targetId}>!") |> ignore
|
|
||||||
let channel = (event.Guild.GetChannel(battleChannel))
|
|
||||||
do! channel.SendMessageAsync(builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|> Async.Ignore
|
|
||||||
}
|
|
||||||
| _ ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- "Error parsing Button Id"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
|
||||||
async {
|
|
||||||
let split = event.Id.Split("-")
|
|
||||||
return!
|
|
||||||
match Shield.TryParse(split.[1]) with
|
|
||||||
| Some shield ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Mounted a {shield} defense for 1 hour"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
let defense = { DefenseType = shield ; Timestamp = DateTime.UtcNow }
|
|
||||||
players <-
|
|
||||||
players
|
|
||||||
|> List.map (fun p -> { p with Defenses = defense::p.Defenses })
|
|
||||||
|
|
||||||
let builder = DiscordMessageBuilder()
|
|
||||||
builder.WithContent($"{event.User.Username} has protected their system!") |> ignore
|
|
||||||
let channel = (event.Guild.GetChannel(battleChannel))
|
|
||||||
do! channel.SendMessageAsync(builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|> Async.Ignore
|
|
||||||
}
|
|
||||||
| _ ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- "Error parsing Button Id"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let handleButtonEvent (client : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
|
||||||
async {
|
|
||||||
return! match event.Id with
|
|
||||||
| id when id.StartsWith("Attack") -> handleAttack event
|
|
||||||
| id when id.StartsWith("Defend") -> handleDefense event
|
|
||||||
| _ ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Incorrect Action identifier {event.Id}"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
}
|
|
||||||
} |> Async.StartAsTask
|
|
||||||
:> Task
|
|
34
Degenz.sln
Normal file
34
Degenz.sln
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.30114.105
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "HackerBattle", "HackerBattle\HackerBattle.fsproj", "{2A437756-3D5D-467D-9497-DF9789DB99CC}"
|
||||||
|
EndProject
|
||||||
|
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Shared", "Shared\Shared.fsproj", "{5F34C24E-BA4E-4E57-9141-812775687360}"
|
||||||
|
EndProject
|
||||||
|
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Store", "Store\Store.fsproj", "{CD88B0A6-DE42-4087-9B33-48FF84201633}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{2A437756-3D5D-467D-9497-DF9789DB99CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2A437756-3D5D-467D-9497-DF9789DB99CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2A437756-3D5D-467D-9497-DF9789DB99CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2A437756-3D5D-467D-9497-DF9789DB99CC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5F34C24E-BA4E-4E57-9141-812775687360}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5F34C24E-BA4E-4E57-9141-812775687360}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5F34C24E-BA4E-4E57-9141-812775687360}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5F34C24E-BA4E-4E57-9141-812775687360}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{CD88B0A6-DE42-4087-9B33-48FF84201633}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{CD88B0A6-DE42-4087-9B33-48FF84201633}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{CD88B0A6-DE42-4087-9B33-48FF84201633}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{CD88B0A6-DE42-4087-9B33-48FF84201633}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
25
HackerBattle/.dockerignore
Normal file
25
HackerBattle/.dockerignore
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/.idea
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/azds.yaml
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
290
HackerBattle/Commands.fs
Normal file
290
HackerBattle/Commands.fs
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
module DegenzGame.Commands
|
||||||
|
|
||||||
|
open System
|
||||||
|
open System.Threading.Tasks
|
||||||
|
open DSharpPlus
|
||||||
|
open DSharpPlus.Entities
|
||||||
|
open DSharpPlus.EventArgs
|
||||||
|
open DSharpPlus.SlashCommands
|
||||||
|
open DegenzGame.Types
|
||||||
|
open DegenzGame.Functions
|
||||||
|
open MongoDB.Driver
|
||||||
|
|
||||||
|
[<Literal>]
|
||||||
|
// Degenz Server
|
||||||
|
//let battleChannel = 930363007781978142uL
|
||||||
|
// My server
|
||||||
|
let battleChannel = 927449884204867664uL
|
||||||
|
|
||||||
|
let mongo = MongoClient("mongodb://localhost:27017")
|
||||||
|
let db = mongo.GetDatabase("degenz-game")
|
||||||
|
let players = db.GetCollection<Player>("players")
|
||||||
|
|
||||||
|
let tryFindPlayer (id : uint64) : Async<Player option> =
|
||||||
|
async {
|
||||||
|
let filter = Builders<Player>.Filter.Eq((fun p -> p.DiscordId), id)
|
||||||
|
let! player = players.FindAsync<Player>(filter) |> Async.AwaitTask
|
||||||
|
return match player.ToEnumerable() |> Seq.toList with
|
||||||
|
| [] -> None
|
||||||
|
| p::_ -> Some p
|
||||||
|
}
|
||||||
|
|
||||||
|
let addHackerRole (ctx : InteractionContext) =
|
||||||
|
async {
|
||||||
|
let! player = tryFindPlayer ctx.Member.Id
|
||||||
|
let! newPlayer =
|
||||||
|
match player with
|
||||||
|
| Some _ -> async.Return false
|
||||||
|
| None ->
|
||||||
|
async {
|
||||||
|
let p = (newPlayer ctx.Member.Username ctx.Member.Id)
|
||||||
|
do! players.InsertOneAsync p |> Async.AwaitTask
|
||||||
|
|
||||||
|
for role in ctx.Guild.Roles do
|
||||||
|
if role.Value.Name = "Hacker" then
|
||||||
|
do! ctx.Member.GrantRoleAsync(role.Value)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if newPlayer then
|
||||||
|
do! ctx.CreateResponseAsync("You are now an elite haxxor", true)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
else
|
||||||
|
do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
|
let removeHackerRole (ctx : InteractionContext) =
|
||||||
|
async {
|
||||||
|
for role in ctx.Member.Roles do
|
||||||
|
if role.Name = "Hacker" then
|
||||||
|
do! ctx.Member.RevokeRoleAsync(role)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
// TODO: Check the result of this delete operation
|
||||||
|
let! _ = players.DeleteOneAsync (fun p -> p.DiscordId = ctx.Member.Id) |> Async.AwaitTask
|
||||||
|
do! ctx.CreateResponseAsync("You are now lame", true)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
|
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||||
|
async {
|
||||||
|
// TODO: We need to check if the player has any active embed hacks going, if not they can cheat
|
||||||
|
let! attacker = tryFindPlayer ctx.Member.Id
|
||||||
|
let! defender = tryFindPlayer target.Id
|
||||||
|
match attacker , defender with
|
||||||
|
| Some attacker , Some defender ->
|
||||||
|
let updatedAttacks = removeExpiredActions (TimeSpan.FromMinutes(5)) (fun (atk : Attack) -> atk.Timestamp) attacker.Attacks
|
||||||
|
let filter = Builders<Player>.Filter.Eq((fun p -> p.DiscordId), attacker.DiscordId)
|
||||||
|
let update = Builders<Player>.Update.Set((fun p -> p.Attacks), updatedAttacks)
|
||||||
|
let! _ = players.UpdateOneAsync(filter, update) |> Async.AwaitTask
|
||||||
|
if updatedAttacks.Length < 2 then
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.AddEmbed (constructEmbed "Pick the hack you wish to use.") |> ignore
|
||||||
|
|
||||||
|
let defenderInfo = $"{defender.DiscordId}-{target.Username}"
|
||||||
|
constructButtons "Attack" defenderInfo attacker.Weapons
|
||||||
|
|> Seq.cast<DiscordComponent>
|
||||||
|
|> builder.AddComponents
|
||||||
|
|> ignore
|
||||||
|
|
||||||
|
builder.AsEphemeral true |> ignore
|
||||||
|
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
else
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
let timestamp = updatedAttacks |> Array.rev |> Array.head |> fun a -> a.Timestamp // This should be the next expiring timestamp
|
||||||
|
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - timestamp)
|
||||||
|
builder.Content <- $"No more hacks available, please wait {timeRemaining.Minutes} minutes and {timeRemaining.Seconds} seconds to attempt another hack"
|
||||||
|
|
||||||
|
builder.AsEphemeral true |> ignore
|
||||||
|
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
| None , _ -> do! notYetAHackerMsg ctx
|
||||||
|
| _ , None -> do! createSimpleResponseAsync "Your target is not connected to the network, they must join first by using the /redpill command" ctx
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
|
let defend (ctx : InteractionContext) =
|
||||||
|
async {
|
||||||
|
let! player = tryFindPlayer ctx.Member.Id
|
||||||
|
match player with
|
||||||
|
| Some player ->
|
||||||
|
let updatedDefenses = removeExpiredActions (TimeSpan.FromMinutes(60)) (fun (pro : Defense) -> pro.Timestamp) player.Defenses
|
||||||
|
let filter = Builders<Player>.Filter.Eq((fun p -> p.DiscordId), player.DiscordId)
|
||||||
|
let update = Builders<Player>.Update.Set((fun p -> p.Defenses), updatedDefenses)
|
||||||
|
let! _ = players.UpdateOneAsync(filter, update) |> Async.AwaitTask
|
||||||
|
if updatedDefenses.Length < 2 then
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.AddEmbed (constructEmbed "Pick a defense to mount for a duration of time") |> ignore
|
||||||
|
|
||||||
|
constructButtons "Defend" (string player.DiscordId) player.Shields
|
||||||
|
|> Seq.cast<DiscordComponent>
|
||||||
|
|> builder.AddComponents
|
||||||
|
|> ignore
|
||||||
|
|
||||||
|
builder.AsEphemeral true |> ignore
|
||||||
|
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
else
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
let timestamp = updatedDefenses |> Array.rev |> Array.head |> fun a -> a.Timestamp // This should be the next expiring timestamp
|
||||||
|
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - timestamp)
|
||||||
|
builder.Content <- $"Cannot add new defense, please wait {timeRemaining.Minutes} minutes and {timeRemaining.Seconds} seconds to add another defense"
|
||||||
|
|
||||||
|
builder.AsEphemeral true |> ignore
|
||||||
|
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
| None -> do! notYetAHackerMsg ctx
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
|
let status (ctx : InteractionContext) =
|
||||||
|
async {
|
||||||
|
let! player = tryFindPlayer ctx.Member.Id
|
||||||
|
match player with
|
||||||
|
| Some p ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- Functions.statusFormat p
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
| None -> do! notYetAHackerMsg ctx
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
|
let leaderboard (ctx : InteractionContext) =
|
||||||
|
async {
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
|
||||||
|
let! leaders = players.Find(fun _ -> true).SortBy(fun p -> p.Bank).Limit(10).ToListAsync() |> Async.AwaitTask
|
||||||
|
let content =
|
||||||
|
leaders.ToArray()
|
||||||
|
|> Array.mapi (fun i p -> $"{i + 1}. {p.Bank} {p.Name}")
|
||||||
|
|> String.concat "\n"
|
||||||
|
builder.Content <- if not <| String.IsNullOrEmpty content then content else "There are no active hackers"
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
|
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
let updatePlayer amount attack p =
|
||||||
|
{ p with Attacks = Array.append [| attack |] p.Attacks ; Bank = MathF.Max(p.Bank + amount, 0f) }
|
||||||
|
async {
|
||||||
|
let split = event.Id.Split("-")
|
||||||
|
let ( resultHack , weapon ) = Weapon.TryParse(split.[1])
|
||||||
|
let ( resultId , targetId ) = UInt64.TryParse split.[2]
|
||||||
|
let! resultPlayer = tryFindPlayer event.User.Id
|
||||||
|
let! resultTarget = tryFindPlayer targetId
|
||||||
|
match resultPlayer , resultTarget , resultHack , resultId with
|
||||||
|
| Some player , Some target , true , true ->
|
||||||
|
let wasSuccessfulHack =
|
||||||
|
target.Defenses
|
||||||
|
|> Seq.toArray
|
||||||
|
|> Array.map (fun dfn -> int dfn.DefenseType)
|
||||||
|
|> Array.map (calculateDamage weapon)
|
||||||
|
|> Array.contains Weak
|
||||||
|
match wasSuccessfulHack with
|
||||||
|
| false ->
|
||||||
|
let prize = 0.1726f
|
||||||
|
let attack = { HackType = enum<Weapon>(weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||||
|
let filter = Builders<Player>.Filter.Eq((fun p -> p.DiscordId), player.DiscordId)
|
||||||
|
let! _ = players.ReplaceOneAsync(filter, updatePlayer prize attack player) |> Async.AwaitTask
|
||||||
|
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- $"Successfully hacked {split.[3]} using {weapon}! You just won {prize} genz!"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
let builder = DiscordMessageBuilder()
|
||||||
|
builder.WithContent($"{event.User.Username} successfully hacked <@{targetId}>!") |> ignore
|
||||||
|
let channel = (event.Guild.GetChannel(battleChannel))
|
||||||
|
do! channel.SendMessageAsync(builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|> Async.Ignore
|
||||||
|
| true ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
let loss = -0.0623f
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- $"Hack failed! {split.[3]} was able to mount a successful defense! You lost {loss} genz!"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
let attack = { HackType = enum<Weapon>(weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||||
|
let filter = Builders<Player>.Filter.Eq((fun p -> p.DiscordId), player.DiscordId)
|
||||||
|
let! _ = players.ReplaceOneAsync(filter, updatePlayer loss attack player) |> Async.AwaitTask
|
||||||
|
|
||||||
|
let builder = DiscordMessageBuilder()
|
||||||
|
builder.WithContent($"{event.User.Username} failed to hack <@{targetId}>!") |> ignore
|
||||||
|
let channel = (event.Guild.GetChannel(battleChannel))
|
||||||
|
do! channel.SendMessageAsync(builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|> Async.Ignore
|
||||||
|
| _ ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- "Error occurred processing attack"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
}
|
||||||
|
|
||||||
|
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
async {
|
||||||
|
let split = event.Id.Split("-")
|
||||||
|
let ( shieldResult , shield ) = Shield.TryParse(split.[1])
|
||||||
|
let! playerResult = tryFindPlayer event.User.Id
|
||||||
|
match playerResult , shieldResult with
|
||||||
|
| Some player , true ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- $"Mounted a {shield} defense for 1 hour"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
|
let defense = { DefenseType = shield ; Timestamp = DateTime.UtcNow }
|
||||||
|
let filter = Builders<Player>.Filter.Eq((fun p -> p.DiscordId), player.DiscordId)
|
||||||
|
let update = Builders<Player>.Update.Set((fun p -> p.Defenses), Array.append [| defense |] player.Defenses )
|
||||||
|
let! _ = players.UpdateOneAsync(filter, update) |> Async.AwaitTask
|
||||||
|
|
||||||
|
let builder = DiscordMessageBuilder()
|
||||||
|
builder.WithContent($"{event.User.Username} has protected their system!") |> ignore
|
||||||
|
let channel = event.Guild.Channels.Values |> Seq.find (fun c -> c.Name = "battle-1")
|
||||||
|
do! channel.SendMessageAsync(builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|> Async.Ignore
|
||||||
|
| _ ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- "Error parsing Button Id"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
}
|
||||||
|
|
||||||
|
let handleButtonEvent (client : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
async {
|
||||||
|
return! match event.Id with
|
||||||
|
| id when id.StartsWith("Attack") -> handleAttack event
|
||||||
|
| id when id.StartsWith("Defend") -> handleDefense event
|
||||||
|
| _ ->
|
||||||
|
async {
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- $"Incorrect Action identifier {event.Id}"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
}
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
18
HackerBattle/Dockerfile
Normal file
18
HackerBattle/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||||
|
WORKDIR /src
|
||||||
|
COPY ["HackerBattle/HackerBattle.fsproj", "HackerBattle/"]
|
||||||
|
RUN dotnet restore "HackerBattle/HackerBattle.fsproj"
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/HackerBattle"
|
||||||
|
RUN dotnet build "HackerBattle.fsproj" -c Release -o /app/build
|
||||||
|
|
||||||
|
FROM build AS publish
|
||||||
|
RUN dotnet publish "HackerBattle.fsproj" -c Release -o /app/publish
|
||||||
|
|
||||||
|
FROM base AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
ENTRYPOINT ["dotnet", "HackerBattle.dll"]
|
@ -1,52 +1,52 @@
|
|||||||
module Joebot.Functions
|
module DegenzGame.Functions
|
||||||
|
|
||||||
open System
|
open System
|
||||||
open System.Threading.Tasks
|
|
||||||
open DSharpPlus
|
open DSharpPlus
|
||||||
open DSharpPlus.Entities
|
open DSharpPlus.Entities
|
||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Joebot.Types
|
open DegenzGame.Types
|
||||||
|
open MongoDB.Bson
|
||||||
|
|
||||||
let hackDescription = ""
|
let hackDescription = ""
|
||||||
|
|
||||||
let statusFormat player =
|
let statusFormat player =
|
||||||
$"Hack Inventory: {player.Weapons}
|
$"Hack Inventory: {player.Weapons}
|
||||||
Shield Inventory: {player.Shields}
|
Shield Inventory: {player.Shields}
|
||||||
Active Hacks: {player.Attacks}
|
Active Hacks: {player.Attacks |> Array.toList}
|
||||||
Active Defenses: {player.Defenses}
|
Active Defenses: {player.Defenses |> Array.toList}
|
||||||
Bank: {player.Bank}"
|
Bank: {player.Bank}"
|
||||||
|
|
||||||
|
|
||||||
let newPlayer nickname (membr : uint64) =
|
let newPlayer nickname (membr : uint64) =
|
||||||
let h1 = [| Virus ; Ransom |]
|
let h1 = [| Weapon.Virus ; Weapon.Ransom |]
|
||||||
let h2 = [| DDos ; Worm |]
|
let h2 = [| Weapon.DDos ; Weapon.Worm |]
|
||||||
let h3 = [| Crack ; Injection |]
|
let h3 = [| Weapon.Crack ; Weapon.Injection |]
|
||||||
let d1 = [| Firewall ; PortScan |]
|
let d1 = [| Shield.Firewall ; Shield.PortScan |]
|
||||||
let d2 = [| Encryption ; Cypher |]
|
let d2 = [| Shield.Encryption ; Shield.Cypher |]
|
||||||
let d3 = [| Hardening ; Sanitation |]
|
let d3 = [| Shield.Hardening ; Shield.Sanitation |]
|
||||||
|
|
||||||
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
||||||
let getRandom (actions : 'a array) = actions.[rand.Next(0,2)]
|
let getRandom (actions : 'a array) = actions.[rand.Next(0,2)]
|
||||||
|
|
||||||
let weapons = [ getRandom h1 ; getRandom h2 ; getRandom h3 ]
|
let weapons = [| getRandom h1 ; getRandom h2 ; getRandom h3 |]
|
||||||
let shields = [ getRandom d1 ; getRandom d2 ; getRandom d3 ]
|
let shields = [| getRandom d1 ; getRandom d2 ; getRandom d3 |]
|
||||||
|
|
||||||
{ DiscordId = membr
|
{ Id = BsonObjectId(ObjectId.GenerateNewId())
|
||||||
|
DiscordId = membr
|
||||||
Name = nickname
|
Name = nickname
|
||||||
Weapons = weapons
|
Weapons = weapons
|
||||||
Shields = shields
|
Shields = shields
|
||||||
Attacks = []
|
Attacks = [||]
|
||||||
Defenses = []
|
Defenses = [||]
|
||||||
Bank = 0f }
|
Bank = 0f }
|
||||||
|
|
||||||
let constructButtons (actionType : string) (playerInfo : string) (weapons : 'a list) =
|
let constructButtons (actionType : string) (playerInfo : string) (weapons : 'a array) =
|
||||||
weapons
|
weapons
|
||||||
|> Seq.map (fun hack ->
|
|> Seq.map (fun hack ->
|
||||||
DiscordButtonComponent(
|
DiscordButtonComponent(
|
||||||
ButtonStyle.Primary,
|
ButtonStyle.Primary,
|
||||||
$"{actionType}-{hack}-{playerInfo}",
|
$"{actionType}-{hack}-{playerInfo}",
|
||||||
$"{hack}"))
|
$"{hack}"))
|
||||||
|
|
||||||
let createSimpleResponseAsync msg (ctx : InteractionContext) =
|
let createSimpleResponseAsync msg (ctx : InteractionContext) =
|
||||||
async {
|
async {
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
@ -54,14 +54,13 @@ let createSimpleResponseAsync msg (ctx : InteractionContext) =
|
|||||||
builder.AsEphemeral true |> ignore
|
builder.AsEphemeral true |> ignore
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
} |> Async.StartAsTask
|
}
|
||||||
:> Task
|
|
||||||
|
|
||||||
let notYetAHackerMsg = createSimpleResponseAsync "You are not currently a hacker, first use the /redpill command to become one"
|
let notYetAHackerMsg = createSimpleResponseAsync "You are not currently a hacker, first use the /redpill command to become one"
|
||||||
|
|
||||||
let removeExpiredActions timespan (timestamp : 'a -> DateTime) actions =
|
let removeExpiredActions timespan (timestamp : 'a -> DateTime) actions =
|
||||||
actions
|
actions
|
||||||
|> List.filter (fun act ->
|
|> Array.filter (fun act ->
|
||||||
if DateTime.UtcNow - (timestamp act) < timespan
|
if DateTime.UtcNow - (timestamp act) < timespan
|
||||||
then true
|
then true
|
||||||
else false)
|
else false)
|
||||||
@ -71,16 +70,16 @@ let constructEmbed message =
|
|||||||
builder.Color <- Optional(DiscordColor.PhthaloGreen)
|
builder.Color <- Optional(DiscordColor.PhthaloGreen)
|
||||||
builder.Description <- message
|
builder.Description <- message
|
||||||
let author = DiscordEmbedBuilder.EmbedAuthor()
|
let author = DiscordEmbedBuilder.EmbedAuthor()
|
||||||
author.Name <- "Joebot Pro"
|
author.Name <- "Degenz Hacker Game"
|
||||||
author.Url <- "https://twitter.com/degenzgame"
|
author.Url <- "https://twitter.com/degenzgame"
|
||||||
author.IconUrl <- "https://pbs.twimg.com/profile_images/1473192843359309825/cqjm0VQ4_400x400.jpg"
|
author.IconUrl <- "https://pbs.twimg.com/profile_images/1473192843359309825/cqjm0VQ4_400x400.jpg"
|
||||||
builder.Author <- author
|
builder.Author <- author
|
||||||
builder.Build()
|
builder.Build()
|
||||||
|
|
||||||
let calculateDamage (hack : IClass) (protection : IClass) =
|
let calculateDamage (hack : int) (shield : int) =
|
||||||
let hackClass = hack.GetClass()
|
let hackClass = getClass hack
|
||||||
let protectionClass = protection.GetClass()
|
let protectionClass = getClass shield
|
||||||
match hackClass , protectionClass with
|
match hackClass , protectionClass with
|
||||||
| h , p when h = p -> Weak
|
| h , p when h = p -> Weak
|
||||||
| _ -> Strong
|
| _ -> Strong
|
||||||
|
|
@ -3,21 +3,23 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RootNamespace>discord_bot</RootNamespace>
|
<RootNamespace>hacker-game</RootNamespace>
|
||||||
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="challenge.jpg">
|
<Content Include=".dockerignore" />
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<Content Include="Dockerfile" />
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ReferencePathWithRefAssemblies Update="\home\joe\.nuget\packages\dsharpplus.slashcommands\4.2.0-nightly-01054\lib\netstandard2.0\DSharpPlus.SlashCommands.dll" />
|
<ReferencePathWithRefAssemblies Update="\home\joe\.nuget\packages\dsharpplus.slashcommands\4.2.0-nightly-01054\lib\netstandard2.0\DSharpPlus.SlashCommands.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Types.fs" />
|
|
||||||
<Compile Include="Functions.fs" />
|
<Compile Include="Functions.fs" />
|
||||||
<Compile Include="Commands.fs" />
|
<Compile Include="Commands.fs" />
|
||||||
<Compile Include="Program.fs" />
|
<Compile Include="Program.fs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project=".paket\Paket.Restore.targets" />
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Shared\Shared.fsproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\.paket\Paket.Restore.targets" />
|
||||||
</Project>
|
</Project>
|
@ -1,4 +1,4 @@
|
|||||||
module Joebot.Program
|
module DegenzGame.Program
|
||||||
|
|
||||||
open System
|
open System
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
@ -7,30 +7,31 @@ open DSharpPlus.Entities
|
|||||||
open DSharpPlus.EventArgs
|
open DSharpPlus.EventArgs
|
||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Emzi0767.Utilities
|
open Emzi0767.Utilities
|
||||||
open Joebot.Types
|
open DegenzGame.Types
|
||||||
open Joebot.Commands
|
open DegenzGame.Commands
|
||||||
|
open MongoDB.Driver
|
||||||
|
|
||||||
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
|
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
|
||||||
|
|
||||||
type JoeBot() =
|
type HackerGame() =
|
||||||
inherit ApplicationCommandModule ()
|
inherit ApplicationCommandModule ()
|
||||||
|
|
||||||
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
|
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
|
||||||
member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
|
member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
|
||||||
|
|
||||||
[<SlashCommand("bluepill", "Take the bluepill and become lame")>]
|
[<SlashCommand("bluepill", "Take the bluepill and become lame")>]
|
||||||
member _.RemoveHackerRole (ctx : InteractionContext) = Commands.removeHackerRole ctx
|
member _.RemoveHackerRole (ctx : InteractionContext) = Commands.removeHackerRole ctx
|
||||||
|
|
||||||
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
||||||
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
||||||
Commands.attack ctx target
|
Commands.attack ctx target
|
||||||
|
|
||||||
[<SlashCommand("defend", "Create a passive defense that will last a certain amount of time")>]
|
[<SlashCommand("defend", "Create a passive defense that will last a certain amount of time")>]
|
||||||
member this.DefendCommand (ctx : InteractionContext) = Commands.defend ctx
|
member this.DefendCommand (ctx : InteractionContext) = Commands.defend ctx
|
||||||
|
|
||||||
[<SlashCommand("status", "Get your current status like bank account, and active hacks and defenses")>]
|
[<SlashCommand("status", "Get your current status like bank account, and active hacks and defenses")>]
|
||||||
member this.Status (ctx : InteractionContext) = Commands.status ctx
|
member this.Status (ctx : InteractionContext) = Commands.status ctx
|
||||||
|
|
||||||
[<SlashCommand("leaderboard", "View the current list of players ranked by highest earnings")>]
|
[<SlashCommand("leaderboard", "View the current list of players ranked by highest earnings")>]
|
||||||
member this.Leaderboard (ctx : InteractionContext) = Commands.leaderboard ctx
|
member this.Leaderboard (ctx : InteractionContext) = Commands.leaderboard ctx
|
||||||
|
|
||||||
@ -46,7 +47,10 @@ client.add_ComponentInteractionCreated(AsyncEventHandler(handleButtonEvent))
|
|||||||
|
|
||||||
let slash = client.UseSlashCommands()
|
let slash = client.UseSlashCommands()
|
||||||
|
|
||||||
slash.RegisterCommands<JoeBot>(922414052708327494uL);
|
// My server
|
||||||
|
slash.RegisterCommands<HackerGame>(922419263275425832uL);
|
||||||
|
// Degenz
|
||||||
|
//slash.RegisterCommands<HackerGame>(922414052708327494uL);
|
||||||
|
|
||||||
client.ConnectAsync ()
|
client.ConnectAsync ()
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
@ -3,4 +3,5 @@ DSharpPlus
|
|||||||
// DSharpPlus.CommandsNext
|
// DSharpPlus.CommandsNext
|
||||||
// DSharpPlus.Interactivity
|
// DSharpPlus.Interactivity
|
||||||
DSharpPlus.SlashCommands
|
DSharpPlus.SlashCommands
|
||||||
LiteDB.FSharp
|
|
||||||
|
MongoDB.Driver
|
11
Shared/Shared.fsproj
Normal file
11
Shared/Shared.fsproj
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Types.fs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\.paket\Paket.Restore.targets" />
|
||||||
|
</Project>
|
67
Shared/Types.fs
Normal file
67
Shared/Types.fs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
module DegenzGame.Types
|
||||||
|
|
||||||
|
open System
|
||||||
|
open MongoDB.Bson
|
||||||
|
|
||||||
|
type ActionClass =
|
||||||
|
| Network
|
||||||
|
| Exploit
|
||||||
|
| Penetration
|
||||||
|
|
||||||
|
type Weapon =
|
||||||
|
| Virus = 0
|
||||||
|
| Ransom = 1
|
||||||
|
| Worm = 2
|
||||||
|
| DDos = 3
|
||||||
|
| Crack = 4
|
||||||
|
| Injection = 5
|
||||||
|
|
||||||
|
type Shield =
|
||||||
|
| Firewall = 0
|
||||||
|
| PortScan = 1
|
||||||
|
| Encryption = 2
|
||||||
|
| Hardening = 4
|
||||||
|
| Sanitation = 5
|
||||||
|
| Cypher = 3
|
||||||
|
|
||||||
|
let getClass = function
|
||||||
|
| 0 | 1 -> Network
|
||||||
|
| 2 | 3 -> Exploit
|
||||||
|
| 4 | _ -> Penetration
|
||||||
|
|
||||||
|
type HackResult =
|
||||||
|
| Strong
|
||||||
|
| Weak
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type DiscordPlayer = {
|
||||||
|
Id : uint64
|
||||||
|
Name : string
|
||||||
|
}
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type Attack = {
|
||||||
|
HackType : Weapon
|
||||||
|
Target : DiscordPlayer
|
||||||
|
Timestamp : DateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type Defense = {
|
||||||
|
DefenseType : Shield
|
||||||
|
Timestamp : DateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type Player = {
|
||||||
|
Id : BsonObjectId
|
||||||
|
DiscordId : uint64
|
||||||
|
Name : string
|
||||||
|
Weapons : Weapon array
|
||||||
|
Shields : Shield array
|
||||||
|
Attacks : Attack array
|
||||||
|
Defenses : Defense array
|
||||||
|
Bank : single
|
||||||
|
}
|
||||||
|
|
||||||
|
|
2
Shared/paket.references
Normal file
2
Shared/paket.references
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FSharp.Core
|
||||||
|
MongoDB.Driver
|
25
Store/.dockerignore
Normal file
25
Store/.dockerignore
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/.idea
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/azds.yaml
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
18
Store/Dockerfile
Normal file
18
Store/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||||
|
WORKDIR /src
|
||||||
|
COPY ["Store/Store.fsproj", "Store/"]
|
||||||
|
RUN dotnet restore "Store/Store.fsproj"
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/Store"
|
||||||
|
RUN dotnet build "Store.fsproj" -c Release -o /app/build
|
||||||
|
|
||||||
|
FROM build AS publish
|
||||||
|
RUN dotnet publish "Store.fsproj" -c Release -o /app/publish
|
||||||
|
|
||||||
|
FROM base AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
ENTRYPOINT ["dotnet", "Store.dll"]
|
4
Store/Program.fs
Normal file
4
Store/Program.fs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
// For more information see https://aka.ms/fsharp-console-apps
|
||||||
|
printfn "Hello from F#"
|
19
Store/Store.fsproj
Normal file
19
Store/Store.fsproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Program.fs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include=".dockerignore" />
|
||||||
|
<Content Include="Dockerfile" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Shared\Shared.fsproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\.paket\Paket.Restore.targets" />
|
||||||
|
</Project>
|
7
Store/paket.references
Normal file
7
Store/paket.references
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
FSharp.Core
|
||||||
|
DSharpPlus
|
||||||
|
// DSharpPlus.CommandsNext
|
||||||
|
// DSharpPlus.Interactivity
|
||||||
|
DSharpPlus.SlashCommands
|
||||||
|
|
||||||
|
MongoDB.Driver
|
88
Types.fs
88
Types.fs
@ -1,88 +0,0 @@
|
|||||||
module Joebot.Types
|
|
||||||
|
|
||||||
open System
|
|
||||||
|
|
||||||
type ActionClass =
|
|
||||||
| Network
|
|
||||||
| Exploit
|
|
||||||
| Penetration
|
|
||||||
|
|
||||||
type IClass = abstract GetClass : unit -> ActionClass
|
|
||||||
|
|
||||||
type Weapon =
|
|
||||||
| Virus
|
|
||||||
| Ransom
|
|
||||||
| Worm
|
|
||||||
| DDos
|
|
||||||
| Crack
|
|
||||||
| Injection
|
|
||||||
interface IClass with
|
|
||||||
member this.GetClass () =
|
|
||||||
match this with
|
|
||||||
| Virus | Ransom -> Exploit
|
|
||||||
| DDos | Worm -> Network
|
|
||||||
| Crack | Injection -> Penetration
|
|
||||||
static member TryParse weapon =
|
|
||||||
match weapon with
|
|
||||||
| "Virus" -> Some Virus
|
|
||||||
| "Ransom" -> Some Ransom
|
|
||||||
| "Worm" -> Some Worm
|
|
||||||
| "DDos" -> Some DDos
|
|
||||||
| "Crack" -> Some Crack
|
|
||||||
| "Injection" -> Some Injection
|
|
||||||
| _ -> None
|
|
||||||
|
|
||||||
type Shield =
|
|
||||||
| Firewall
|
|
||||||
| PortScan
|
|
||||||
| Encryption
|
|
||||||
| Cypher
|
|
||||||
| Hardening
|
|
||||||
| Sanitation
|
|
||||||
interface IClass with
|
|
||||||
member this.GetClass () =
|
|
||||||
match this with
|
|
||||||
| Firewall | PortScan -> Network
|
|
||||||
| Encryption | Cypher -> Exploit
|
|
||||||
| Hardening | Sanitation -> Penetration
|
|
||||||
static member TryParse shield =
|
|
||||||
match shield with
|
|
||||||
| "Firewall" -> Some Firewall
|
|
||||||
| "PortScan" -> Some PortScan
|
|
||||||
| "Encryption" -> Some Encryption
|
|
||||||
| "Cypher" -> Some Cypher
|
|
||||||
| "Hardening" -> Some Hardening
|
|
||||||
| "Sanitation" -> Some Sanitation
|
|
||||||
| _ -> None
|
|
||||||
|
|
||||||
type HackResult =
|
|
||||||
| Strong
|
|
||||||
| Weak
|
|
||||||
|
|
||||||
type DiscordPlayer = {
|
|
||||||
Id : uint64
|
|
||||||
Name : string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Attack = {
|
|
||||||
HackType : Weapon
|
|
||||||
Target : DiscordPlayer
|
|
||||||
Timestamp : DateTime
|
|
||||||
}
|
|
||||||
|
|
||||||
type Defense = {
|
|
||||||
DefenseType : Shield
|
|
||||||
Timestamp : DateTime
|
|
||||||
}
|
|
||||||
|
|
||||||
type Player = {
|
|
||||||
DiscordId : uint64
|
|
||||||
Name : string
|
|
||||||
Weapons : Weapon list
|
|
||||||
Shields : Shield list
|
|
||||||
Attacks : Attack list
|
|
||||||
Defenses : Defense list
|
|
||||||
Bank : single
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
BIN
challenge.jpg
BIN
challenge.jpg
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
@ -10,4 +10,4 @@ source https://nuget.emzi0767.com/api/v3/index.json
|
|||||||
nuget DSharpPlus >= 4.2.0-nightly-01054
|
nuget DSharpPlus >= 4.2.0-nightly-01054
|
||||||
nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01054
|
nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01054
|
||||||
|
|
||||||
nuget LiteDB.FSharp 2.16.0
|
nuget MongoDB.Driver
|
||||||
|
74
paket.lock
74
paket.lock
@ -1,35 +1,16 @@
|
|||||||
STORAGE: NONE
|
STORAGE: NONE
|
||||||
RESTRICTION: || (== net6.0) (== netstandard2.0) (== netstandard2.1)
|
RESTRICTION: || (== net6.0) (== netstandard2.0) (== netstandard2.1)
|
||||||
NUGET
|
NUGET
|
||||||
remote: https://nuget.emzi0767.com/api/v3/index.json
|
|
||||||
DSharpPlus (4.2.0-nightly-01054)
|
|
||||||
Emzi0767.Common (>= 2.6.2)
|
|
||||||
Microsoft.Extensions.Logging.Abstractions (>= 5.0)
|
|
||||||
Newtonsoft.Json (>= 13.0.1)
|
|
||||||
System.Memory (>= 4.5.4)
|
|
||||||
System.Net.Http (>= 4.3.4)
|
|
||||||
System.Net.WebSockets (>= 4.3)
|
|
||||||
System.Net.WebSockets.Client (>= 4.3.2)
|
|
||||||
System.Runtime.InteropServices.RuntimeInformation (>= 4.3)
|
|
||||||
System.Threading.Channels (>= 5.0)
|
|
||||||
DSharpPlus.SlashCommands (4.2.0-nightly-01054)
|
|
||||||
DSharpPlus (>= 4.2.0-nightly-01054)
|
|
||||||
Microsoft.Extensions.DependencyInjection (>= 5.0.1)
|
|
||||||
remote: https://api.nuget.org/v3/index.json
|
remote: https://api.nuget.org/v3/index.json
|
||||||
|
DnsClient (1.5)
|
||||||
|
Microsoft.Win32.Registry (>= 5.0)
|
||||||
|
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net471)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net471)) (&& (== netstandard2.1) (< netstandard2.0))
|
||||||
Emzi0767.Common (2.6.2)
|
Emzi0767.Common (2.6.2)
|
||||||
System.Collections.Immutable (>= 5.0)
|
System.Collections.Immutable (>= 5.0)
|
||||||
System.Memory (>= 4.5.4)
|
System.Memory (>= 4.5.4)
|
||||||
System.Runtime.CompilerServices.Unsafe (>= 5.0)
|
System.Runtime.CompilerServices.Unsafe (>= 5.0)
|
||||||
System.ValueTuple (>= 4.5)
|
System.ValueTuple (>= 4.5)
|
||||||
FSharp.Core (6.0.1)
|
FSharp.Core (6.0.1)
|
||||||
LiteDB (4.1.4)
|
|
||||||
System.Reflection (>= 4.3)
|
|
||||||
System.Reflection.TypeExtensions (>= 4.3)
|
|
||||||
LiteDB.FSharp (2.16)
|
|
||||||
FSharp.Core (>= 4.7.2)
|
|
||||||
LiteDB (>= 4.1.4 < 5.0)
|
|
||||||
Newtonsoft.Json (>= 13.0.1)
|
|
||||||
TypeShape (>= 9.0)
|
|
||||||
Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
|
Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
|
||||||
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
|
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
|
||||||
Microsoft.Extensions.DependencyInjection (6.0)
|
Microsoft.Extensions.DependencyInjection (6.0)
|
||||||
@ -49,6 +30,24 @@ NUGET
|
|||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
System.Runtime (>= 4.3)
|
System.Runtime (>= 4.3)
|
||||||
|
Microsoft.Win32.Registry (5.0)
|
||||||
|
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= monoandroid) (< netstandard1.3)) (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (== netstandard2.0) (== netstandard2.1)
|
||||||
|
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (>= uap10.1)) (== netstandard2.0) (== netstandard2.1)
|
||||||
|
System.Security.AccessControl (>= 5.0)
|
||||||
|
System.Security.Principal.Windows (>= 5.0)
|
||||||
|
MongoDB.Bson (2.14.1)
|
||||||
|
System.Runtime.CompilerServices.Unsafe (>= 5.0)
|
||||||
|
MongoDB.Driver (2.14.1)
|
||||||
|
MongoDB.Bson (>= 2.14.1)
|
||||||
|
MongoDB.Driver.Core (>= 2.14.1)
|
||||||
|
MongoDB.Libmongocrypt (>= 1.3)
|
||||||
|
MongoDB.Driver.Core (2.14.1)
|
||||||
|
DnsClient (>= 1.4)
|
||||||
|
MongoDB.Bson (>= 2.14.1)
|
||||||
|
MongoDB.Libmongocrypt (>= 1.3)
|
||||||
|
SharpCompress (>= 0.30.1)
|
||||||
|
System.Buffers (>= 4.5.1)
|
||||||
|
MongoDB.Libmongocrypt (1.3)
|
||||||
Newtonsoft.Json (13.0.1)
|
Newtonsoft.Json (13.0.1)
|
||||||
runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
||||||
runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
||||||
@ -93,7 +92,10 @@ NUGET
|
|||||||
runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
||||||
runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
||||||
runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
|
||||||
System.Buffers (4.5.1) - restriction: || (&& (== net6.0) (>= net461)) (== netstandard2.0) (== netstandard2.1)
|
SharpCompress (0.30.1)
|
||||||
|
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
|
||||||
|
System.Text.Encoding.CodePages (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1)
|
||||||
|
System.Buffers (4.5.1)
|
||||||
System.Collections (4.3)
|
System.Collections (4.3)
|
||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
@ -294,9 +296,6 @@ NUGET
|
|||||||
System.IO (>= 4.3)
|
System.IO (>= 4.3)
|
||||||
System.Reflection.Primitives (>= 4.3)
|
System.Reflection.Primitives (>= 4.3)
|
||||||
System.Runtime (>= 4.3)
|
System.Runtime (>= 4.3)
|
||||||
System.Reflection.Emit.ILGeneration (4.7) - restriction: || (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< portable-net45+wp8)) (&& (== net6.0) (>= uap10.1)) (== netstandard2.0) (&& (== netstandard2.1) (< netstandard2.0)) (&& (== netstandard2.1) (< portable-net45+wp8)) (&& (== netstandard2.1) (>= uap10.1))
|
|
||||||
System.Reflection.Emit.LightWeight (4.7) - restriction: || (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1)
|
|
||||||
System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< portable-net45+wp8)) (&& (== net6.0) (>= uap10.1)) (== netstandard2.0) (&& (== netstandard2.1) (< netstandard2.0)) (&& (== netstandard2.1) (< portable-net45+wp8)) (&& (== netstandard2.1) (>= uap10.1))
|
|
||||||
System.Reflection.Extensions (4.3)
|
System.Reflection.Extensions (4.3)
|
||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
@ -306,7 +305,6 @@ NUGET
|
|||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
System.Runtime (>= 4.3)
|
System.Runtime (>= 4.3)
|
||||||
System.Reflection.TypeExtensions (4.7)
|
|
||||||
System.Resources.ResourceManager (4.3)
|
System.Resources.ResourceManager (4.3)
|
||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
@ -345,6 +343,8 @@ NUGET
|
|||||||
System.Resources.ResourceManager (>= 4.3)
|
System.Resources.ResourceManager (>= 4.3)
|
||||||
System.Runtime (>= 4.3)
|
System.Runtime (>= 4.3)
|
||||||
System.Runtime.Extensions (>= 4.3)
|
System.Runtime.Extensions (>= 4.3)
|
||||||
|
System.Security.AccessControl (6.0)
|
||||||
|
System.Security.Principal.Windows (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (== netstandard2.0) (== netstandard2.1)
|
||||||
System.Security.Claims (4.3)
|
System.Security.Claims (4.3)
|
||||||
System.Collections (>= 4.3)
|
System.Collections (>= 4.3)
|
||||||
System.Globalization (>= 4.3)
|
System.Globalization (>= 4.3)
|
||||||
@ -440,6 +440,9 @@ NUGET
|
|||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
System.Runtime (>= 4.3)
|
System.Runtime (>= 4.3)
|
||||||
|
System.Text.Encoding.CodePages (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1)
|
||||||
|
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1)
|
||||||
|
System.Runtime.CompilerServices.Unsafe (>= 6.0)
|
||||||
System.Text.Encoding.Extensions (4.3)
|
System.Text.Encoding.Extensions (4.3)
|
||||||
Microsoft.NETCore.Platforms (>= 1.1)
|
Microsoft.NETCore.Platforms (>= 1.1)
|
||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
@ -464,6 +467,17 @@ NUGET
|
|||||||
Microsoft.NETCore.Targets (>= 1.1)
|
Microsoft.NETCore.Targets (>= 1.1)
|
||||||
System.Runtime (>= 4.3)
|
System.Runtime (>= 4.3)
|
||||||
System.ValueTuple (4.5)
|
System.ValueTuple (4.5)
|
||||||
TypeShape (10.0)
|
remote: https://nuget.emzi0767.com/api/v3/index.json
|
||||||
FSharp.Core (>= 4.5.4)
|
DSharpPlus (4.2.0-nightly-01059)
|
||||||
System.Reflection.Emit.LightWeight (>= 4.7) - restriction: || (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1)
|
Emzi0767.Common (>= 2.6.2)
|
||||||
|
Microsoft.Extensions.Logging.Abstractions (>= 5.0)
|
||||||
|
Newtonsoft.Json (>= 13.0.1)
|
||||||
|
System.Memory (>= 4.5.4)
|
||||||
|
System.Net.Http (>= 4.3.4)
|
||||||
|
System.Net.WebSockets (>= 4.3)
|
||||||
|
System.Net.WebSockets.Client (>= 4.3.2)
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation (>= 4.3)
|
||||||
|
System.Threading.Channels (>= 5.0)
|
||||||
|
DSharpPlus.SlashCommands (4.2.0-nightly-01059)
|
||||||
|
DSharpPlus (>= 4.2.0-nightly-01059)
|
||||||
|
Microsoft.Extensions.DependencyInjection (>= 5.0.1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user