Compare commits
No commits in common. "main" and "1.0" have entirely different histories.
10 changed files with 38 additions and 730 deletions
|
|
@ -12,12 +12,11 @@
|
|||
"THAIlux",
|
||||
"Reijn7000",
|
||||
"McPikkie",
|
||||
"Brabo-Gamer",
|
||||
"SquadKiller101",
|
||||
"HeteKip",
|
||||
"Pettie1972",
|
||||
"Reijn7001",
|
||||
"Ghost_0223",
|
||||
"Bossoemang"
|
||||
"Reijn7000"
|
||||
|
||||
],
|
||||
"alts": [
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ if ($fileContent -match "\`$apiKey\s*=\s*\'([^\']+)\'") {
|
|||
$apiKey = $matches[1]
|
||||
}
|
||||
else {
|
||||
write-output "API Key not found"
|
||||
Write-Output "API Key not found"
|
||||
}
|
||||
|
||||
$headers = @{
|
||||
|
|
@ -36,19 +36,11 @@ $headers = @{
|
|||
$fileContent = Get-Content -Path "$scriptroot/../discord/config.php" -Raw
|
||||
|
||||
# Use regex to match the apiKey value
|
||||
if ($fileContent -match "\`$webhookurl\s*=\s*'([^']+)'") {
|
||||
if ($fileContent -match "\`$webhookurl\s*=\s*\'([^\']+)\'") {
|
||||
$webhookurl = $matches[1]
|
||||
}
|
||||
else {
|
||||
write-output "No web url found"
|
||||
}
|
||||
|
||||
# Use regex to match the losers webhook url
|
||||
if ($fileContent -match "\`$webhookurl_losers\s*=\s*'([^']+)'") {
|
||||
$webhookurl_losers = $matches[1]
|
||||
}
|
||||
else {
|
||||
write-output "No losers web url found"
|
||||
Write-Output "No web url found"
|
||||
}
|
||||
|
||||
function send-discord {
|
||||
|
|
@ -64,22 +56,6 @@ function send-discord {
|
|||
Invoke-RestMethod -Uri $webhookurl -Method Post -Body ($payload | ConvertTo-Json) -ContentType 'Application/Json'
|
||||
}
|
||||
|
||||
function send-discord-losers {
|
||||
param (
|
||||
$content
|
||||
)
|
||||
$payload = [PSCustomObject]@{
|
||||
content = $content
|
||||
}
|
||||
if ($payload.content -eq "") {
|
||||
$payload = [PSCustomObject]@{
|
||||
content = "Nothing to report"
|
||||
}
|
||||
}
|
||||
Invoke-RestMethod -Uri $webhookurl_losers -Method Post -Body ($payload | ConvertTo-Json) -ContentType 'Application/Json'
|
||||
|
||||
}
|
||||
|
||||
$map_map = @{
|
||||
"Baltic_Main" = "Erangel"
|
||||
"Chimera_Main" = "Paramo"
|
||||
|
|
@ -99,142 +75,11 @@ try {
|
|||
$player_matches = get-content "$scriptroot/../data/player_matches.json" | convertfrom-json -Depth 100
|
||||
}
|
||||
catch {
|
||||
write-output 'Unable to read file exitin'
|
||||
Write-Output 'Unable to read file exitin'
|
||||
}
|
||||
write-output $player_matches
|
||||
write-output $new_win_matches
|
||||
$new_win_matches = $player_matches[-2].new_win_matches
|
||||
|
||||
# Gebruik nu de lijst van nieuwe verloren matches uit het JSON-bestand
|
||||
$new_loss_matches = $player_matches[-1].new_loss_matches
|
||||
|
||||
# Post verloren matches naar #losers kanaal
|
||||
# foreach ($lossid in $new_loss_matches) {
|
||||
# $lossmatch = $player_matches.player_matches | Where-Object { $_.id -eq $lossid }
|
||||
# if ($null -eq $lossmatch) { continue }
|
||||
# if ($lossmatch[0].gameMode -eq 'tdm') { continue }
|
||||
|
||||
# # Fetch detailed match stats and telemetry for the loss
|
||||
# $loss_match_stats = $null
|
||||
# $loss_telemetry = $null
|
||||
# try {
|
||||
# $loss_match_stats = Invoke-RestMethod -Uri "https://api.pubg.com/shards/steam/matches/$lossid" -Method GET -Headers $headers
|
||||
# $loss_telemetry = (invoke-webrequest @($lossmatch.telemetry_url)[0]).content | convertfrom-json | where-object { ($_._T -eq 'LOGPLAYERTAKEDAMAGE') -or ($_._T -eq 'LOGPLAYERKILLV2') }
|
||||
# } catch {
|
||||
# $errorMessage = $_.Exception.Message
|
||||
# Write-Warning ("Failed to fetch API/telemetry data for loss match {0}: {1}" -f $lossid, $errorMessage)
|
||||
# }
|
||||
|
||||
# $loss_stats_table = @()
|
||||
# $loss_victims = @() # For team damage
|
||||
|
||||
# # Iterate through players found in the locally stored match data for this loss
|
||||
# foreach ($player_stat in $lossmatch[0].stats) {
|
||||
# $player_name = $player_stat.name
|
||||
# # Find the corresponding detailed stats from the API response
|
||||
# $detailed_player_stats = $null
|
||||
# if ($null -ne $loss_match_stats) {
|
||||
# $detailed_player_stats = $loss_match_stats.included | Where-Object {$_.type -eq 'participant'} | ForEach-Object {$_.attributes.stats} | Where-Object { $_.name -eq $player_name }
|
||||
# }
|
||||
|
||||
# if ($null -eq $detailed_player_stats) {
|
||||
# Write-Warning "Could not find detailed stats for player $player_name in loss match $lossid. Using basic stats."
|
||||
# # Fallback to basic stats if detailed stats are missing
|
||||
# $loss_stats_table += [PSCustomObject]@{
|
||||
# Name = $player_name
|
||||
# 'Human dmg' = "N/A"
|
||||
# 'Human Kills' = "N/A"
|
||||
# 'Dmg' = "$([math]::Round($player_stat.damageDealt))" # Use basic stat
|
||||
# 'Kills' = "$($player_stat.kills)" # Use basic stat
|
||||
# 'alive' = "$([math]::Round(($player_stat.timeSurvived / 60)))" # Use basic stat
|
||||
# }
|
||||
# continue # Skip telemetry processing if detailed stats failed
|
||||
# }
|
||||
|
||||
# # Calculate stats (similar to win stats calculation)
|
||||
# $human_dmg = "N/A"
|
||||
# $human_kills = "N/A"
|
||||
# if ($null -ne $loss_telemetry) {
|
||||
# try {
|
||||
# $human_dmg = [math]::Round(($loss_telemetry | Where-Object { $_._T -eq 'LOGPLAYERTAKEDAMAGE' -and $_.attacker.name -eq $player_name -and $_.victim.accountId -notlike "ai.*" -and $_.victim.teamId -ne $_.attacker.teamId } | Measure-Object -Property damage -Sum).Sum)
|
||||
# $human_kills = ($loss_telemetry | Where-Object { $_._T -eq 'LOGPLAYERKILLV2' -and $_.killer.name -eq $player_name -and $_.victim.accountId -notlike "ai.*" }).count
|
||||
# } catch {
|
||||
# $errorMessage = $_.Exception.Message
|
||||
# Write-Warning ("Error processing telemetry stats for {0} in loss {1}: {2}" -f $player_name, $lossid, $errorMessage)
|
||||
# }
|
||||
# }
|
||||
|
||||
# $loss_stats_table += [PSCustomObject]@{
|
||||
# Name = $player_name
|
||||
# 'Human dmg' = "$human_dmg"
|
||||
# 'Human Kills' = "$human_kills"
|
||||
# 'Dmg' = "$([math]::Round($detailed_player_stats.damageDealt))"
|
||||
# 'Kills' = "$($detailed_player_stats.kills)"
|
||||
# 'alive' = "$([math]::Round(($detailed_player_stats.timeSurvived / 60)))"
|
||||
# }
|
||||
|
||||
# # Calculate team damage
|
||||
# if ($null -ne $loss_telemetry) {
|
||||
# try {
|
||||
# $teamdmg = $loss_telemetry | Where-Object {
|
||||
# $_._T -eq 'LOGPLAYERTAKEDAMAGE' -and
|
||||
# $_.victim.teamId -eq $_.attacker.teamId -and
|
||||
# $_.victim.accountId -notlike "ai.*" -and
|
||||
# $_.victim.name -ne $_.attacker.name -and
|
||||
# $_.attacker.name -eq $player_name
|
||||
# }
|
||||
# if ($teamdmg.count -ge 1) {
|
||||
# foreach ($victim_name in ($teamdmg.victim.name | Select-Object -Unique)) {
|
||||
# $loss_victims += [PSCustomObject]@{
|
||||
# attacker = $player_name
|
||||
# victim = $victim_name
|
||||
# Damage = "$([math]::Round((($teamdmg | Where-Object { $_.victim.name -eq $victim_name }).damage | Measure-Object -Sum).Sum))"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# } catch {
|
||||
# $errorMessage = $_.Exception.Message
|
||||
# Write-Warning ("Error processing team damage for {0} in loss {1}: {2}" -f $player_name, $lossid, $errorMessage)
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
# # Format the stats table
|
||||
# $content_lossstats = ""
|
||||
# if ($loss_stats_table.Count -gt 0) {
|
||||
# $content_lossstats = '```' + ($loss_stats_table | Format-Table -AutoSize | Out-String) + '```'
|
||||
# }
|
||||
|
||||
# # Format team damage table
|
||||
# $content_loss_victims = ""
|
||||
# if ($loss_victims.Count -gt 0) {
|
||||
# $content_loss_victims = ":skull::skull: Team Damage :skull::skull:`n" + '```' + ($loss_victims | Format-Table -AutoSize | Out-String) + '```'
|
||||
# }
|
||||
|
||||
# # Original message construction variables
|
||||
# $losers = $lossmatch[0].stats.name -join ', ' # Join names for display
|
||||
# $map = $map_map[$lossmatch[0].mapName]
|
||||
# $place = ($lossmatch[0].stats | Select-Object -First 1).winPlace # Get placement from the first player stat
|
||||
# $first_player_name = ($lossmatch[0].stats | Select-Object -First 1).name
|
||||
# $replay_url = $lossmatch[0].telemetry_url -replace 'https://telemetry-cdn.pubg.com/bluehole-pubg', 'https://chickendinner.gg'
|
||||
# $replay_url = $replay_url -replace '-telemetry.json', ''
|
||||
# $replay_url = $replay_url + "?follow=$first_player_name" # Follow the first player
|
||||
# $match_settings = @"
|
||||
# ``````
|
||||
# match mode $($lossmatch[0].gameMode)
|
||||
# match type $($lossmatch[0].matchType)
|
||||
# map $($map_map[$lossmatch[0].mapName])
|
||||
# id $($lossmatch[0].id)
|
||||
# ``````
|
||||
# "@
|
||||
# send-discord-losers -content "We hebben een LOSERT! Geen Kip voor jou! :skull::skull:"
|
||||
# send-discord-losers -content ":partying_face::partying_face::partying_face: Helaas, $($losers) :partying_face::partying_face::partying_face:"
|
||||
# send-discord-losers -content $match_settings
|
||||
# send-discord-losers -content $content_lossstats
|
||||
# send-discord-losers -content $content_loss_victims
|
||||
# send-discord-losers -content "[2D replay](<$replay_url>)"
|
||||
# send-discord-losers -content "Meer match details [DTCH_STATS](<https://dtch.online/matchinfo.php?matchid=$($lossmatch[0].id)>)"
|
||||
# }
|
||||
Write-Output $player_matches
|
||||
Write-Output $new_win_matches
|
||||
$new_win_matches = $player_matches[-1].new_win_matches
|
||||
|
||||
|
||||
foreach ($winid in $new_win_matches) {
|
||||
|
|
@ -245,20 +90,13 @@ foreach ($winid in $new_win_matches) {
|
|||
$winmatches = $player_matches.player_matches | Where-Object { $_.id -eq $winid }
|
||||
$telemetry = (invoke-webrequest @($winmatches.telemetry_url)[0]).content | convertfrom-json | where-object { ($_._T -eq 'LOGPLAYERTAKEDAMAGE') -or ($_._T -eq 'LOGPLAYERKILLV2') }
|
||||
$winners = @(($winmatches | where-object { $_.stats.winPlace -eq 1 }).stats.name)
|
||||
# $2D_replay_url = @($winmatches.telemetry_url)[0] -replace 'https://telemetry-cdn.pubg.com/bluehole-pubg', 'https://chickendinner.gg'
|
||||
# $2D_replay_url = $2D_replay_url -replace '-telemetry.json', ''
|
||||
# $2D_replay_url = $2D_replay_url + "?follow=$($winners[0])"
|
||||
$2D_replay_url = 'https://chickendinner.gg/' + $winid
|
||||
$2D_replay_url = @($winmatches.telemetry_url)[0] -replace 'https://telemetry-cdn.pubg.com/bluehole-pubg', 'https://chickendinner.gg'
|
||||
$2D_replay_url = $2D_replay_url -replace '-telemetry.json', ''
|
||||
$2D_replay_url = $2D_replay_url + "?follow=$($winners[0])"
|
||||
|
||||
$match_stats = Invoke-RestMethod -Uri "https://api.pubg.com/shards/steam/matches/$winid" -Method GET -Headers $headers
|
||||
if ($winmatches[0].gameMode -eq 'tdm' ) {
|
||||
continue
|
||||
}
|
||||
if (
|
||||
($winmatches[0].matchtype -eq 'event' -and $winmatches[0].gameMode -ne 'ibr') -or
|
||||
($winmatches[0].gameMode -eq 'tdm')
|
||||
) {
|
||||
Write-Output 'Skipping because of event or tdm'
|
||||
continue
|
||||
} #skip tdm matches
|
||||
if ($winmatches[0].matchType -eq 'custom') {
|
||||
$players_to_report = $match_stats.included.attributes.stats | where-object { $_.playerId -notlike "ai.*" }
|
||||
|
|
@ -266,15 +104,11 @@ foreach ($winid in $new_win_matches) {
|
|||
else {
|
||||
$players_to_report = $match_stats.included.attributes.stats | where-object { $_.winplace -eq 1 }
|
||||
}
|
||||
$2D_replay_url = 'https://chickendinner.gg/' + $winid + "/" + $players_to_report[0].name
|
||||
|
||||
if ($new_win_matches.count -le 10) {
|
||||
#fail safe
|
||||
$winnerswithurl = @()
|
||||
foreach ($winner in $winners) {
|
||||
$winnerswithurl += "[$winner](<https://dtch.online/latestmatches.php?selected_player=$($winner)>)"
|
||||
}
|
||||
send-discord -content ":chicken: :chicken: **WINNER WINNER CHICKEN DINNER!!** :chicken: :chicken:"
|
||||
send-discord -content ":partying_face::partying_face::partying_face: Gefeliciteerd $($winnerswithurl -join ', ') :partying_face::partying_face::partying_face:"
|
||||
send-discord -content ":partying_face::partying_face::partying_face: Gefeliciteerd $($winners -join ', ') :partying_face::partying_face::partying_face:"
|
||||
$match_settings = @"
|
||||
``````
|
||||
match mode $($winmatches[0].gameMode)
|
||||
|
|
@ -356,9 +190,6 @@ foreach ($item in $player_matches) {
|
|||
if ($item.PSObject.Properties.Name -contains "new_win_matches") {
|
||||
$item.new_win_matches = $null
|
||||
}
|
||||
if ($item.PSObject.Properties.Name -contains "new_loss_matches") {
|
||||
$item.new_loss_matches = $null
|
||||
}
|
||||
}
|
||||
|
||||
# Convert back to JSON (optional)
|
||||
|
|
@ -368,5 +199,4 @@ $newJson = $player_matches | ConvertTo-Json -Depth 100
|
|||
$newJson | out-file "$scriptroot/../data/player_matches.json"
|
||||
|
||||
remove-lock
|
||||
Stop-Transcript
|
||||
|
||||
Stop-Transcript
|
||||
|
|
@ -4,11 +4,9 @@ import discord
|
|||
import random
|
||||
import asyncio
|
||||
import re
|
||||
from textwrap import dedent
|
||||
from discord.ext import commands
|
||||
from openai import OpenAI
|
||||
|
||||
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
||||
|
||||
def get_token():
|
||||
with open("config.php", "r") as file:
|
||||
content = file.read()
|
||||
|
|
@ -31,13 +29,10 @@ intents.presences = True # Nodig als de bot presences moet zien
|
|||
intents.members = True # Nodig om leden in een voice channel te zien
|
||||
|
||||
bot = commands.Bot(command_prefix="!", intents=intents)
|
||||
client = OpenAI(api_key=OPENAI_API_KEY)
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print(f'Bot is ingelogd als {bot.user}')
|
||||
channel = bot.get_channel(759006368832159745)
|
||||
if channel:
|
||||
await channel.send("Ben er weer!")
|
||||
|
||||
@bot.command()
|
||||
async def test(ctx):
|
||||
|
|
@ -130,19 +125,19 @@ async def teamify(ctx, *args):
|
|||
await ctx.send(f"Kanaal {channel.name} is opgeruimd omdat het leeg was!")
|
||||
|
||||
@bot.command()
|
||||
async def whoisbest(ctx, category="Casual", matchesback=18, top=3):
|
||||
async def whoisbest(ctx, category="Casual", matchesback=18):
|
||||
|
||||
|
||||
if category.lower() == "help":
|
||||
help_message = (
|
||||
"**Gebruik van het commando `whoisbest`:**\n"
|
||||
"`!whoisbest [category] [matchesback] [top]`\n\n"
|
||||
"`!whoisbest [category] [matchesback]`\n\n"
|
||||
"**Parameters:**\n"
|
||||
"`category` - De categorie van de stats, bijv. 'Casual' of 'Ranked'. Niet hoofdlettergevoelig.\n"
|
||||
"`matchesback` - Het minimum aantal matches dat een speler gespeeld moet hebben om mee te tellen (standaard 18).\n\n"
|
||||
"**Voorbeeld:**\n"
|
||||
"`!whoisbest Casual 18`\n"
|
||||
"Laat de top 3 spelers zien op basis van winratio en gemiddelde damage in de Casual categorie met minimaal 18 matches.\n"
|
||||
"Laat de top 3 spelers zien op basis van winratio en gemiddelde damage in de Casual categorie met minimaal 18 matches.\n\n"
|
||||
"Typ `!whoisbest help` om deze uitleg opnieuw te zien."
|
||||
)
|
||||
await ctx.send(help_message)
|
||||
|
|
@ -178,10 +173,10 @@ async def whoisbest(ctx, category="Casual", matchesback=18, top=3):
|
|||
return
|
||||
|
||||
# Sorteer spelers op winratio (aflopend)
|
||||
top_winratio = sorted(players, key=lambda x: x.get("winratio", 0), reverse=True)[:top]
|
||||
top_winratio = sorted(players, key=lambda x: x.get("winratio", 0), reverse=True)[:3]
|
||||
|
||||
# Sorteer spelers op gemiddelde damage (aflopend)
|
||||
top_ahd = sorted(players, key=lambda x: x.get("ahd", 0), reverse=True)[:top]
|
||||
top_ahd = sorted(players, key=lambda x: x.get("ahd", 0), reverse=True)[:3]
|
||||
|
||||
# Bouw het bericht op
|
||||
message = f"**\U0001F3C6 Top 3 Winratio ({actual_category})**\n"
|
||||
|
|
@ -191,55 +186,11 @@ async def whoisbest(ctx, category="Casual", matchesback=18, top=3):
|
|||
message += f"\n**\U0001F480 Top 3 AHD ({actual_category})**\n"
|
||||
for i, player in enumerate(top_ahd, start=1):
|
||||
message += f"{i}. **{player['playername']}** - {player['ahd']:.2f}\n"
|
||||
##AI
|
||||
|
||||
system_prompt = dedent(f"""
|
||||
Je bent een Discord announcer-bot op de PUBG-server van DTCH.
|
||||
Stijl: brutaal/competitief, licht denigrerend maar leesbaar.
|
||||
AHD = Average Human Damage
|
||||
Regels:
|
||||
- Gebruik uitsluitend de meegeleverde stats-tekst.
|
||||
- Output ALLEEN Discord-markdown (geen JSON, geen codeblokken).
|
||||
- Structuur:
|
||||
1) Titel met category en korte snedige ondertitel.
|
||||
2) **🏆 Top {top} Winratio** en **💀 Top {top} AHD** (exact die koppen).
|
||||
3) Per regel: 🥇/🥈/🥉 + **naam** + waarde (winratio met %).
|
||||
4) De rest van de regels doe je zonder medaille gewoon een cijfer
|
||||
5) Sluit af met 1 of 2 regels analyse van de stats, gebruik humor.
|
||||
- Opgegeven parameters:
|
||||
Categorie: {category}
|
||||
Minimaal aantal matches: {matchesback}
|
||||
Top: {top}
|
||||
- verdere info
|
||||
1) Als de aantal matches laag is (onder de 15) dan zijn cijfers niet echt meer representatief. Meld dat dan ook.
|
||||
- Max ~1800 tekens.
|
||||
""").strip()
|
||||
user_prompt = dedent(f"""
|
||||
Verpak onderstaande stats-tekst in één strakke Discord-post volgens de regels.
|
||||
Wijzig geen waardes, haal alles uit de tekst tussen START/EINDE.
|
||||
await ctx.send(message)
|
||||
|
||||
[STATS-TEKST START]
|
||||
{message}
|
||||
[STATS-TEKST EINDE]
|
||||
""").strip()
|
||||
response = client.chat.completions.create(
|
||||
model="gpt-5-nano",
|
||||
#temperature=0.6,
|
||||
#presence_penalty=0.2,
|
||||
messages=[
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt},
|
||||
],
|
||||
)
|
||||
|
||||
antwoord = response.choices[0].message.content
|
||||
await ctx.send(f"{ctx.author.mention} {antwoord[:1900]}")
|
||||
except Exception as e:
|
||||
await ctx.send(f"{ctx.author.mention} Er ging iets mis: {e}")
|
||||
|
||||
|
||||
##AIEND
|
||||
|
||||
await ctx.send(f"Fout bij het laden van de statistieken: {str(e)}")
|
||||
|
||||
@bot.event
|
||||
async def on_voice_state_update(member, before, after):
|
||||
|
|
@ -264,15 +215,7 @@ async def on_voice_state_update(member, before, after):
|
|||
async def on_member_join(member):
|
||||
logging_channel = discord.utils.get(member.guild.text_channels, name="raadhuisplein")
|
||||
if logging_channel:
|
||||
welcome_message = (
|
||||
f"🎉 Welcome {member.mention} to **{member.guild.name}**!\n\n"
|
||||
"👋 We're glad to have you here.\n"
|
||||
"👉 Want to jump right in? Type `!iamgamer` in the chat and you'll get the **Tourists** role.\n"
|
||||
"With that role you can join the fun and games with everyone else. 🎮\n"
|
||||
"Use !dtch_help for more info\n\n"
|
||||
"Enjoy your stay and have a great time! 🚀"
|
||||
)
|
||||
await logging_channel.send(welcome_message)
|
||||
await logging_channel.send(f"🎉 Welkom {member.mention} op de server! We hopen dat je een leuke tijd hebt!")
|
||||
|
||||
@bot.event
|
||||
async def on_member_remove(member):
|
||||
|
|
@ -308,203 +251,5 @@ async def moveall(ctx):
|
|||
await ctx.send(f"{moved_members} speler(s) zijn verplaatst naar het teamify kanaal.")
|
||||
else:
|
||||
await ctx.send("Er waren geen spelers om te verplaatsen.")
|
||||
@bot.command()
|
||||
async def iamgamer(ctx):
|
||||
role = discord.utils.get(ctx.guild.roles, name="Tourists")
|
||||
if role is None:
|
||||
await ctx.send("De rol **Tourists** bestaat niet!")
|
||||
return
|
||||
|
||||
try:
|
||||
await ctx.author.add_roles(role)
|
||||
await ctx.send(f"✅ {ctx.author.mention}, je bent nu een **Tourist**! Veel plezier! 🎮")
|
||||
except Exception as e:
|
||||
await ctx.send(f"Er is iets misgegaan bij het toekennen van de rol: {e}")
|
||||
@bot.command(name="dtch_help", aliases=["commands"])
|
||||
async def dtch_help_command(ctx):
|
||||
embed = discord.Embed(
|
||||
title="📖 DTCH Bot Command Help",
|
||||
description="Here’s a list of all available commands and how to use them:",
|
||||
color=discord.Color.blue()
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="👉 !teamify",
|
||||
value=(
|
||||
"`!teamify` - Split players into random teams of max 4.\n"
|
||||
"`!teamify <number_of_teams>` - Split players into a given number of teams.\n"
|
||||
"`!teamify <number_of_teams> move` - Split & move players into temporary voice channels.\n"
|
||||
"`!teamify move` - Auto split & move players.\n"
|
||||
"🔹 Works only in the **#teamify** channel."
|
||||
),
|
||||
inline=False
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="👉 !moveall",
|
||||
value="`!moveall` - Moves all players from other voice channels into the **teamify** channel.",
|
||||
inline=False
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="👉 !whoisbest",
|
||||
value=(
|
||||
"`!whoisbest [category] [matchesback]`\n"
|
||||
"Shows the top 3 players based on win ratio and average damage.\n"
|
||||
"`category` = e.g. Casual, Ranked\n"
|
||||
"`matchesback` = minimum matches required (default: 18)\n"
|
||||
"Example: `!whoisbest Casual 18`"
|
||||
),
|
||||
inline=False
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="👉 !iamgamer",
|
||||
value="`!iamgamer` - Gives you the **Tourists** role 🎮 so you can join games and unlock more fun.",
|
||||
inline=False
|
||||
)
|
||||
|
||||
embed.set_footer(text="✨ For advanced options, use: !teamify help or !whoisbest help")
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@bot.command()
|
||||
@commands.cooldown(1, 15, commands.BucketType.user)
|
||||
async def ask(ctx, *, vraag: str):
|
||||
## CLAN MEMBERS
|
||||
file_path = os.path.join("..", "config", "clanmembers.json")
|
||||
# Inlezen als string
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
clanmembers_str = f.read()
|
||||
|
||||
#LIFETIME STATS
|
||||
|
||||
file_path_lifetimestats = os.path.join("..", "data", "player_lifetime_data.json")
|
||||
with open(file_path_lifetimestats, "r", encoding="utf-8") as file:
|
||||
data_lifetimestats = json.load(file)
|
||||
squad_str = json.dumps(data_lifetimestats.get("squad", {}), indent=2)
|
||||
|
||||
#Last stats
|
||||
file_path_laststats = os.path.join("..", "data", "player_last_stats.json")
|
||||
with open(file_path_laststats, "r", encoding="utf-8") as file:
|
||||
data_laststat = json.load(file)
|
||||
casual_str = json.dumps(data_laststat.get("Casual", []), indent=2)
|
||||
ranked_str = json.dumps(data_laststat.get("Ranked", []), indent=2)
|
||||
custom_str = json.dumps(data_laststat.get("custom", []), indent=2)
|
||||
# Online members
|
||||
voice_members = [
|
||||
member.display_name
|
||||
for vc in ctx.guild.voice_channels
|
||||
for member in vc.members
|
||||
]
|
||||
|
||||
voice_str = ", ".join(voice_members) if voice_members else "Niemand zit in een voice kanaal"
|
||||
|
||||
"""Stuur een vraag naar OpenAI"""
|
||||
try:
|
||||
async with ctx.typing():
|
||||
response = client.chat.completions.create(
|
||||
model="gpt-5-nano",
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": (
|
||||
"Je bent een licht denigrerende chatbot in Discord, actief op de PUBG server van clan DTCH. "
|
||||
f"De vraag is gesteld door {ctx.author.display_name}. "
|
||||
|
||||
# Context
|
||||
f"Clanleden: {clanmembers_str}. "
|
||||
f"Momenteel in voice: {voice_str}. "
|
||||
f"Lifetime stats (squad): {squad_str}. "
|
||||
f"Casual (spelen we toch wel het vaakst met elkaar, belangrijke stat dus) stats: {casual_str}. "
|
||||
f"Ranked stats: {ranked_str}. "
|
||||
f"Custom stats (clan games meestal tegen elkaar): {custom_str}. "
|
||||
|
||||
# Richtlijnen voor antwoord
|
||||
"Houd je antwoorden kort en bondig, met maximaal 1600 tekens. "
|
||||
"Kill Death Human (KD_H) en winrato zijn de belangrijkste stats omdat bots heel makkelijk te killen zijn vinden de Human Kill death het belangrijkste"
|
||||
"Gebruik Discord markdown (``` of **vetgedrukt**) wanneer je stats of tabellen toont. "
|
||||
"Wees een beetje sarcastisch, maar wel begrijpelijk. "
|
||||
"Stel geen vragen want je hebt geen context bij de volgende prompt."
|
||||
|
||||
)
|
||||
},
|
||||
{"role": "user", "content": vraag},
|
||||
],
|
||||
)
|
||||
|
||||
antwoord = response.choices[0].message.content
|
||||
await ctx.send(f"{ctx.author.mention} {antwoord[:1900]}")
|
||||
except Exception as e:
|
||||
await ctx.send(f"{ctx.author.mention} Er ging iets mis: {e}")
|
||||
|
||||
@ask.error
|
||||
async def ask_error(ctx, error):
|
||||
if isinstance(error, commands.CommandOnCooldown):
|
||||
retry_after = int(error.retry_after + 0.999)
|
||||
await ctx.reply(f"Rustig {ctx.author.display_name}, probeer het over {retry_after}s nog eens.")
|
||||
else:
|
||||
raise error
|
||||
|
||||
@bot.command()
|
||||
async def loterij(ctx, *members: discord.Member):
|
||||
"""
|
||||
Gebruik:
|
||||
!loterij @naam1 @naam2 @naam3
|
||||
"""
|
||||
# Alleen in #teamify? -> uncomment als je dat ook wilt
|
||||
# if ctx.channel.name != "teamify":
|
||||
# await ctx.send("Dit commando kan alleen worden gebruikt in het #teamify kanaal.")
|
||||
# return
|
||||
|
||||
if not members or len(members) < 2:
|
||||
await ctx.send("Gebruik: `!loterij @naam1 @naam2 ...` (minimaal 2 mensen, anders is het wel héél zielig).")
|
||||
return
|
||||
|
||||
# Uniek maken (als iemand 2x getagd wordt telt 'ie maar 1x mee)
|
||||
unique_members = []
|
||||
seen_ids = set()
|
||||
for m in members:
|
||||
if m.id not in seen_ids:
|
||||
unique_members.append(m)
|
||||
seen_ids.add(m.id)
|
||||
|
||||
# Tekst “tussen A, B en C” netjes bouwen
|
||||
mentions = [m.mention for m in unique_members]
|
||||
if len(mentions) == 2:
|
||||
between_text = f"{mentions[0]} en {mentions[1]}"
|
||||
else:
|
||||
between_text = f"{', '.join(mentions[:-1])} en {mentions[-1]}"
|
||||
|
||||
winnaar = random.choice(unique_members)
|
||||
|
||||
await ctx.send(f"En de loterij gaat tussen {between_text}.")
|
||||
|
||||
# Countdown
|
||||
await asyncio.sleep(1)
|
||||
await ctx.send("in 3")
|
||||
await asyncio.sleep(1)
|
||||
await ctx.send("2")
|
||||
await asyncio.sleep(1)
|
||||
await ctx.send("1")
|
||||
await asyncio.sleep(1)
|
||||
|
||||
await ctx.send("trom gerofel 🥁")
|
||||
await asyncio.sleep(1)
|
||||
|
||||
await ctx.send(f"De winnaar is {winnaar.mention} 🎆🎇")
|
||||
|
||||
@loterij.error
|
||||
async def loterij_error(ctx, error):
|
||||
if isinstance(error, commands.BadArgument):
|
||||
await ctx.send(
|
||||
"Ik snap er niks van 🤨\n"
|
||||
"Gebruik het zo:\n"
|
||||
"`!loterij @naam1 @naam2 @naam3`\n"
|
||||
"Zorg dat je **echte Discord-mentions** gebruikt."
|
||||
)
|
||||
else:
|
||||
raise error
|
||||
|
||||
|
||||
|
||||
bot.run(token)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ if ($host == 'dev.dtch.online') {
|
|||
<a href="last_stats.php">Last quarter %</a>
|
||||
<a href="latestmatches.php">Last Matches</a>
|
||||
<a href="topstats.php">Top20</a>
|
||||
<a href="user_stats.php">User Stats</a>
|
||||
<a href="videos.php">Videos</a>
|
||||
<a href="user_stats.php">User Stats</a>
|
||||
</div>
|
||||
<a href="javascript:void(0);" class="icon" onclick="myFunction()">
|
||||
<i class="fa fa-bars"></i>
|
||||
|
|
|
|||
|
|
@ -240,87 +240,3 @@ td, th {
|
|||
background-color: #0f0f0f;
|
||||
color: #e69109;
|
||||
}
|
||||
|
||||
/* Videos page styles */
|
||||
.videos-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.video-item {
|
||||
flex: 1 1 300px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.video-item video {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
width: auto;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Share and theatre button styles */
|
||||
.video-controls {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Theatre mode styles */
|
||||
.video-item.theatre-mode {
|
||||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.video-item.theatre-mode video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.video-title {
|
||||
text-align: center;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.video-item.theatre-mode {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.video-item.theatre-mode video {
|
||||
max-width: 90%;
|
||||
max-height: 80vh;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.video-item.theatre-mode .video-title {
|
||||
color: #fff;
|
||||
order: -1; /* Display title above the video */
|
||||
}
|
||||
|
||||
.video-item.theatre-mode .video-controls {
|
||||
position: relative;
|
||||
bottom: auto;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,6 @@ table {
|
|||
td, th {
|
||||
padding: 8px;
|
||||
}
|
||||
/* Theatre mode mobile styles */
|
||||
.video-item.theatre-mode {
|
||||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.video-item.theatre-mode video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.topnav {
|
||||
overflow: hidden;
|
||||
|
|
@ -91,50 +81,4 @@ table {
|
|||
section h2 {
|
||||
margin-top: 10px;
|
||||
|
||||
}
|
||||
/* Videos page responsive adjustments */
|
||||
.videos-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.video-item {
|
||||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.video-item video {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
/* Share and theatre button mobile styles */
|
||||
.video-controls {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.video-title {
|
||||
text-align: center;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.video-item.theatre-mode {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.video-item.theatre-mode video {
|
||||
max-width: 100%;
|
||||
max-height: 70vh;
|
||||
}
|
||||
|
||||
.video-item.theatre-mode .video-controls {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
|
@ -157,15 +157,15 @@ $lastMatches = array_slice($allMatches, 0, 8);
|
|||
if (substr($playerStats['playerId'], 0, 2) !== 'ai') {
|
||||
// Create links for each stat
|
||||
echo "<tr>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['name']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'> Human </a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['kills']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['HumanDmg']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['timeSurvived']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['winPlace']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['revives']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['DBNOs']) . "</a></td>";
|
||||
echo "<td><a href='https://www.pubg-meta.com/player-stats/steam/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['assists']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['name']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'> Human </a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['kills']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['HumanDmg']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['timeSurvived']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['winPlace']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['revives']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['DBNOs']) . "</a></td>";
|
||||
echo "<td><a href='https://pubg.op.gg/user/" . urlencode($playerStats['name']) . "' target='_blank'>" . htmlspecialchars($playerStats['assists']) . "</a></td>";
|
||||
echo "</tr>";
|
||||
} else {
|
||||
// Display without link
|
||||
|
|
|
|||
|
|
@ -48,13 +48,7 @@ foreach ($player in $player_data) {
|
|||
$stats.included = $sortedStats
|
||||
$stats | ConvertTo-Json -Depth 100 | Out-File "$scriptroot/../data/matches/$match.json"
|
||||
}
|
||||
if (
|
||||
($stats.data.attributes.matchtype -eq 'event' -and $stats.data.attributes.gameMode -ne 'ibr') -or
|
||||
($stats.data.attributes.gameMode -eq 'tdm')
|
||||
) {
|
||||
Write-Output 'Skipping because of event or tdm'
|
||||
continue
|
||||
}
|
||||
|
||||
$playermatches += [PSCustomObject]@{
|
||||
stats = $stats.included.ATTRIBUTES.stats | where-object { $_.name -eq $player.attributes.name }
|
||||
matchType = $stats.data.attributes.matchtype
|
||||
|
|
@ -93,15 +87,6 @@ if (test-path "$scriptroot/../data/player_matches.json") {
|
|||
new_win_matches = $new_win_matches
|
||||
}
|
||||
|
||||
# Nieuwe verloren matches bepalen
|
||||
$new_loss_ids = ($player_matches.player_matches | Where-Object { $_.stats.winplace -ne 1 }).id
|
||||
$old_loss_ids = ($old_player_data.player_matches | Where-Object { $_.stats.winplace -ne 1 }).id
|
||||
$new_loss_matches = ((Compare-Object -ReferenceObject $old_loss_ids -DifferenceObject $new_loss_ids) | Where-Object { $_.SideIndicator -eq '=>' }).InputObject | Select-Object -Unique
|
||||
$new_loss_matches = $old_player_data.new_loss_matches + $new_loss_matches | Select-Object -Unique
|
||||
$player_matches += [PSCustomObject]@{
|
||||
new_loss_matches = $new_loss_matches
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$currentDateTime = Get-Date
|
||||
|
|
|
|||
|
|
@ -161,14 +161,6 @@ $groupedGuids_clan_matches_gt_3 = $guids | Group-Object | Where-Object { $_.Coun
|
|||
$last_month = (get-date).AddMonths($monthsback)
|
||||
foreach ($file in $matchfiles) {
|
||||
$json = get-content $file | ConvertFrom-Json
|
||||
|
||||
if (
|
||||
($stats.data.attributes.matchtype -eq 'event' -and $stats.data.attributes.gameMode -ne 'ibr') -or
|
||||
($stats.data.attributes.gameMode -eq 'tdm')
|
||||
) {
|
||||
Write-Output 'Skipping because of event or tdm'
|
||||
continue
|
||||
}
|
||||
if ($json.created -gt $last_month) {
|
||||
$killstats += $json
|
||||
if ($groupedGuids_clan_matches_gt_1.Name -contains $json.matchid) {
|
||||
|
|
|
|||
102
videos.php
102
videos.php
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
$ogDescription = "Bekijk alle video's";
|
||||
|
||||
// Scan the media/videos directory for mp4 files
|
||||
$videosDir = __DIR__ . '/media/videos';
|
||||
$allFiles = scandir($videosDir);
|
||||
$videoFiles = array_filter($allFiles, function($file) use ($videosDir) {
|
||||
return is_file($videosDir . '/' . $file) && strtolower(pathinfo($file, PATHINFO_EXTENSION)) === 'mp4';
|
||||
});
|
||||
|
||||
// Build array with creation time and sort by creation date descending
|
||||
$videoData = [];
|
||||
foreach ($videoFiles as $file) {
|
||||
$path = $videosDir . '/' . $file;
|
||||
$videoData[] = [
|
||||
'filename' => $file,
|
||||
'ctime' => filectime($path)
|
||||
];
|
||||
}
|
||||
usort($videoData, function($a, $b) {
|
||||
return $b['ctime'] - $a['ctime'];
|
||||
});
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<?php include './includes/head.php'; ?>
|
||||
|
||||
<body>
|
||||
<?php include './includes/navigation.php'; ?>
|
||||
<?php include './includes/header.php'; ?>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Videos</h2>
|
||||
|
||||
<?php if (!empty($videoData)): ?>
|
||||
<div class="videos-container">
|
||||
<?php foreach ($videoData as $video): ?>
|
||||
<div class="video-item">
|
||||
<video controls>
|
||||
<source src="media/videos/<?php echo htmlspecialchars($video['filename']); ?>" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<p class="video-title"><?php echo pathinfo($video['filename'], PATHINFO_FILENAME); ?></p>
|
||||
<div class="video-controls">
|
||||
<button class="btn share-btn">Delen</button>
|
||||
<button class="btn theatre-btn">Theatermodus</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<p>No videos found.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<?php include './includes/footer.php'; ?>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('.share-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var videoItem = btn.closest('.video-item');
|
||||
var src = videoItem.querySelector('video source').src;
|
||||
if (navigator.share) {
|
||||
navigator.share({ title: videoItem.querySelector('p').innerText, url: src })
|
||||
.catch(function(error) { console.error('Error sharing', error); });
|
||||
} else if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(src).then(function() {
|
||||
alert('Videolink gekopieerd naar klembord');
|
||||
}, function(err) {
|
||||
alert('Kon link niet kopiëren: ' + err);
|
||||
});
|
||||
} else {
|
||||
prompt('Kopieer deze link:', src);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.theatre-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var clickedVideoItem = btn.closest('.video-item');
|
||||
|
||||
// Remove theatre mode from all other videos
|
||||
document.querySelectorAll('.video-item.theatre-mode').forEach(function(item) {
|
||||
if (item !== clickedVideoItem) {
|
||||
item.classList.remove('theatre-mode');
|
||||
item.querySelector('.theatre-btn').innerText = 'Theatermodus';
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle theatre mode for the clicked video
|
||||
var isActive = clickedVideoItem.classList.toggle('theatre-mode');
|
||||
btn.innerText = isActive ? 'Sluit theatermodus' : 'Theatermodus';
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue