WIP Compiler Errors: Adding DbService and PlayerRegistration components

This commit is contained in:
Joseph Ferano 2022-01-15 22:33:55 +07:00
parent e40fc42482
commit 7b2f6ba861
19 changed files with 285 additions and 111 deletions

39
DbService/DbService.fs Normal file
View File

@ -0,0 +1,39 @@
module DegenzGame.DbService
open DegenzGame.Shared
open DegenzGame.Shared
open MongoDB.Bson
open MongoDB.Driver
type PlayerEntry = {
Id : BsonObjectId
Player : Player
}
let mongo = MongoClient("mongodb://localhost:27017")
let db = mongo.GetDatabase("degenz-game")
let players = db.GetCollection<PlayerEntry>("players")
let tryFindPlayer (id : uint64) : Async<Player option> =
async {
let filter = Builders<PlayerEntry>.Filter.Eq((fun p -> p.Player.DiscordId), id)
let! player = players.FindAsync<PlayerEntry>(filter) |> Async.AwaitTask
return match player.ToEnumerable() |> Seq.toList with
| [] -> None
| entry::_ -> Some entry.Player
}
let insertNewPlayer (player : Player) =
async {
do! { Id = BsonObjectId(ObjectId.GenerateNewId()) ; Player = player }
|> players.InsertOneAsync
|> Async.AwaitTask
}
let removePlayer (memberId : uint64) =
async {
// TODO: Check the result of this delete operation
return! players.DeleteOneAsync (fun p -> p.Player.DiscordId = memberId)
|> Async.AwaitTask
|> Async.Ignore
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="DbService.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.fsproj" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>

View File

@ -0,0 +1,7 @@
FSharp.Core
DSharpPlus
// DSharpPlus.CommandsNext
// DSharpPlus.Interactivity
DSharpPlus.SlashCommands
MongoDB.Driver

View File

@ -9,6 +9,10 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Shared", "Shared\Shared.fsp
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Store", "Store\Store.fsproj", "{CD88B0A6-DE42-4087-9B33-48FF84201633}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "PlayerRegistration", "PlayerRegistration\PlayerRegistration.fsproj", "{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "DbService", "DbService\DbService.fsproj", "{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -30,5 +34,13 @@ Global
{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
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Release|Any CPU.Build.0 = Release|Any CPU
{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -6,7 +6,8 @@ open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.EventArgs
open DSharpPlus.SlashCommands
open DegenzGame.Types
open DegenzGame.Shared
open DegenzGame.DbService
open DegenzGame.Functions
open MongoDB.Driver
@ -16,60 +17,6 @@ open MongoDB.Driver
// 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 {

View File

@ -3,9 +3,7 @@ module DegenzGame.Functions
open System
open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.SlashCommands
open DegenzGame.Types
open MongoDB.Bson
open DegenzGame.Shared
let hackDescription = ""
@ -16,29 +14,6 @@ Active Hacks: {player.Attacks |> Array.toList}
Active Defenses: {player.Defenses |> Array.toList}
Bank: {player.Bank}"
let newPlayer nickname (membr : uint64) =
let h1 = [| Weapon.Virus ; Weapon.Ransom |]
let h2 = [| Weapon.DDos ; Weapon.Worm |]
let h3 = [| Weapon.Crack ; Weapon.Injection |]
let d1 = [| Shield.Firewall ; Shield.PortScan |]
let d2 = [| Shield.Encryption ; Shield.Cypher |]
let d3 = [| Shield.Hardening ; Shield.Sanitation |]
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
let getRandom (actions : 'a array) = actions.[rand.Next(0,2)]
let weapons = [| getRandom h1 ; getRandom h2 ; getRandom h3 |]
let shields = [| getRandom d1 ; getRandom d2 ; getRandom d3 |]
{ Id = BsonObjectId(ObjectId.GenerateNewId())
DiscordId = membr
Name = nickname
Weapons = weapons
Shields = shields
Attacks = [||]
Defenses = [||]
Bank = 0f }
let constructButtons (actionType : string) (playerInfo : string) (weapons : 'a array) =
weapons
|> Seq.map (fun hack ->
@ -47,17 +22,6 @@ let constructButtons (actionType : string) (playerInfo : string) (weapons : 'a a
$"{actionType}-{hack}-{playerInfo}",
$"{hack}"))
let createSimpleResponseAsync msg (ctx : InteractionContext) =
async {
let builder = DiscordInteractionResponseBuilder()
builder.Content <- msg
builder.AsEphemeral true |> ignore
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
}
let notYetAHackerMsg = createSimpleResponseAsync "You are not currently a hacker, first use the /redpill command to become one"
let removeExpiredActions timespan (timestamp : 'a -> DateTime) actions =
actions
|> Array.filter (fun act ->

View File

@ -17,8 +17,10 @@
<Compile Include="Functions.fs" />
<Compile Include="Commands.fs" />
<Compile Include="Program.fs" />
<Content Include="paket.references" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DbService\DbService.fsproj" />
<ProjectReference Include="..\Shared\Shared.fsproj" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />

View File

@ -1,27 +1,16 @@
module DegenzGame.Program
open System
open System.Threading.Tasks
open System.Threading.Tasks
open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.EventArgs
open DSharpPlus.SlashCommands
open Emzi0767.Utilities
open DegenzGame.Types
open DegenzGame
open DegenzGame.Commands
open MongoDB.Driver
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
type HackerGame() =
inherit ApplicationCommandModule ()
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
[<SlashCommand("bluepill", "Take the bluepill and become lame")>]
member _.RemoveHackerRole (ctx : InteractionContext) = Commands.removeHackerRole ctx
[<SlashCommand("hack", "Send a hack attack to another player")>]
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
Commands.attack ctx target

View File

@ -4,4 +4,4 @@ DSharpPlus
// DSharpPlus.Interactivity
DSharpPlus.SlashCommands
MongoDB.Driver
// MongoDB.Driver

View 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

View 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 ["PlayerRegistration/PlayerRegistration.fsproj", "PlayerRegistration/"]
RUN dotnet restore "PlayerRegistration/PlayerRegistration.fsproj"
COPY . .
WORKDIR "/src/PlayerRegistration"
RUN dotnet build "PlayerRegistration.fsproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "PlayerRegistration.fsproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "PlayerRegistration.dll"]

View File

@ -0,0 +1,21 @@
<?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" />
<Content Include="paket.references" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DbService\DbService.fsproj" />
<ProjectReference Include="..\Shared\Shared.fsproj" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>

View File

@ -0,0 +1,115 @@
open System.Threading.Tasks
open DegenzGame.DbService
open DSharpPlus
open DSharpPlus.SlashCommands
open DegenzGame.Shared
module Commands =
let newPlayer nickname (membr : uint64) =
let h1 = [| Weapon.Virus ; Weapon.Ransom |]
let h2 = [| Weapon.DDos ; Weapon.Worm |]
let h3 = [| Weapon.Crack ; Weapon.Injection |]
let d1 = [| Shield.Firewall ; Shield.PortScan |]
let d2 = [| Shield.Encryption ; Shield.Cypher |]
let d3 = [| Shield.Hardening ; Shield.Sanitation |]
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
let getRandom (actions : 'a array) = actions.[rand.Next(0,2)]
let weapons = [| getRandom h1 ; getRandom h2 ; getRandom h3 |]
let shields = [| getRandom d1 ; getRandom d2 ; getRandom d3 |]
{ DiscordId = membr
Name = nickname
Weapons = weapons
Shields = shields
Attacks = [||]
Defenses = [||]
Bank = 0f }
let addHackerRole (ctx : InteractionContext) =
async {
let! player = tryFindPlayer ctx.Member.Id
let! newPlayer =
match player with
| Some _ -> async.Return false
| None ->
async {
do! newPlayer ctx.Member.Username ctx.Member.Id
|> insertNewPlayer
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
do! removePlayer ctx.Member.Id
do! ctx.CreateResponseAsync("You are now lame", true)
|> Async.AwaitTask
} |> Async.StartAsTask
:> Task
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
type PlayerRegistration() =
inherit ApplicationCommandModule ()
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
[<SlashCommand("bluepill", "Take the bluepill and become lame")>]
member _.RemoveHackerRole (ctx : InteractionContext) = Commands.removeHackerRole ctx
let config = DiscordConfiguration()
config.Token <- "OTIyNDIyMDIyMTI1MDEwOTU1.YcBOcw.JxfW1CSIwEO7j6RbRFCnPZ-HoTk"
config.TokenType <- TokenType.Bot
config.Intents <- DiscordIntents.All
//config.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace
let client = new DiscordClient(config)
//client.add_ComponentInteractionCreated(AsyncEventHandler(handleButtonEvent))
let slash = client.UseSlashCommands()
// My server
slash.RegisterCommands<PlayerRegistration>(922419263275425832uL);
// Degenz
//slash.RegisterCommands<HackerGame>(922414052708327494uL);
client.ConnectAsync ()
|> Async.AwaitTask
|> Async.RunSynchronously
Task.Delay(-1)
|> Async.AwaitTask
|> Async.RunSynchronously
client.DisconnectAsync ()
|> Async.AwaitTask
|> Async.RunSynchronously

View File

@ -0,0 +1,7 @@
FSharp.Core
DSharpPlus
// DSharpPlus.CommandsNext
// DSharpPlus.Interactivity
DSharpPlus.SlashCommands
// MongoDB.Driver

View File

@ -6,6 +6,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Types.fs" />
<Content Include="paket.references" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>

View File

@ -1,7 +1,9 @@
module DegenzGame.Types
module DegenzGame.Shared
open System
open MongoDB.Bson
open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.SlashCommands
type ActionClass =
| Network
@ -54,7 +56,6 @@ type Defense = {
[<CLIMutable>]
type Player = {
Id : BsonObjectId
DiscordId : uint64
Name : string
Weapons : Weapon array
@ -64,4 +65,13 @@ type Player = {
Bank : single
}
let createSimpleResponseAsync msg (ctx : InteractionContext) =
async {
let builder = DiscordInteractionResponseBuilder()
builder.Content <- msg
builder.AsEphemeral true |> ignore
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
}
let notYetAHackerMsg = createSimpleResponseAsync "You are not currently a hacker, first use the /redpill command to become one"

View File

@ -1,2 +1,3 @@
FSharp.Core
MongoDB.Driver
DSharpPlus
DSharpPlus.SlashCommands

View File

@ -11,8 +11,10 @@
<ItemGroup>
<Content Include=".dockerignore" />
<Content Include="Dockerfile" />
<Content Include="paket.references" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DbService\DbService.fsproj" />
<ProjectReference Include="..\Shared\Shared.fsproj" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />

View File

@ -4,4 +4,4 @@ DSharpPlus
// DSharpPlus.Interactivity
DSharpPlus.SlashCommands
MongoDB.Driver
// MongoDB.Driver