Compare commits
33 commits
370730cbea
...
c6d78cc370
Author | SHA1 | Date | |
---|---|---|---|
c6d78cc370 | |||
33a8b85580 | |||
ed42ceaca4 | |||
2bce901d63 | |||
8aa4fc340a | |||
ea9c8c5247 | |||
14929b1aed | |||
bcbd0855b8 | |||
22cd98f229 | |||
cda41d87c3 | |||
b14fac2c58 | |||
5c905e3a87 | |||
b1d2daa871 | |||
c7b01c932e | |||
16857ef14d | |||
94f285541b | |||
48f4bf095b | |||
dead9545ba | |||
76f1dbaba5 | |||
5dd50a3f3b | |||
42dfe2d047 | |||
e32105a849 | |||
2d2c76a266 | |||
2377397a2e | |||
0c94c5817f | |||
42883c3a99 | |||
2f9d80f430 | |||
806dcb9ab3 | |||
4ceefe20f9 | |||
cd2abf0315 | |||
3e09cf7f43 | |||
9a278b3dc1 | |||
756f536370 |
42 changed files with 1448 additions and 583 deletions
|
@ -7,7 +7,7 @@
|
||||||
# any secret values.
|
# any secret values.
|
||||||
|
|
||||||
BOT_TOKEN=
|
BOT_TOKEN=
|
||||||
BOT_VER=0.5.1
|
BOT_VER=0.5.0
|
||||||
BOT_AUTHOR=Vylpes
|
BOT_AUTHOR=Vylpes
|
||||||
BOT_OWNERID=147392775707426816
|
BOT_OWNERID=147392775707426816
|
||||||
BOT_CLIENTID=682942374040961060
|
BOT_CLIENTID=682942374040961060
|
||||||
|
@ -19,13 +19,14 @@ ABOUT_REPO=
|
||||||
|
|
||||||
DATA_DIR=
|
DATA_DIR=
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=
|
||||||
DB_PORT=3301
|
DB_PORT=
|
||||||
DB_NAME=carddrop
|
DB_NAME=
|
||||||
DB_AUTH_USER=dev
|
DB_AUTH_USER=
|
||||||
DB_AUTH_PASS=dev
|
DB_AUTH_PASS=
|
||||||
DB_SYNC=true
|
DB_SYNC=
|
||||||
DB_LOGGING=true
|
DB_LOGGING=
|
||||||
|
DB_DATA_LOCATION=~/.docker
|
||||||
|
|
||||||
DB_CARD_FILE=:memory:
|
DB_CARD_FILE=:memory:
|
||||||
|
|
71
.forgejo/workflows/production.yml
Normal file
71
.forgejo/workflows/production.yml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
name: Deploy To Production
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
environment: prod
|
||||||
|
|
||||||
|
runs-on: node
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build
|
||||||
|
- run: npm test
|
||||||
|
|
||||||
|
- name: "Copy files over to location"
|
||||||
|
run: cp -r . ${{ secrets.PROD_REPO_PATH }}
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
environment: prod
|
||||||
|
needs: build
|
||||||
|
runs-on: node
|
||||||
|
steps:
|
||||||
|
- uses: https://github.com/appleboy/ssh-action@v1.0.0
|
||||||
|
env:
|
||||||
|
DB_NAME: ${{ secrets.PROD_DB_NAME }}
|
||||||
|
DB_AUTH_USER: ${{ secrets.PROD_DB_AUTH_USER }}
|
||||||
|
DB_AUTH_PASS: ${{ secrets.PROD_DB_AUTH_PASS }}
|
||||||
|
DB_HOST: ${{ secrets.PROD_DB_HOST }}
|
||||||
|
DB_PORT: ${{ secrets.PROD_DB_PORT }}
|
||||||
|
DB_ROOT_HOST: ${{ secrets.PROD_DB_ROOT_HOST }}
|
||||||
|
DB_SYNC: ${{ secrets.PROD_DB_SYNC }}
|
||||||
|
DB_LOGGING: ${{ secrets.PROD_DB_LOGGING }}
|
||||||
|
DB_DATA_LOCATION: ${{ secrets.PROD_DB_DATA_LOCATION }}
|
||||||
|
SERVER_PATH: ${{ secrets.PROD_SSH_SERVER_PATH }}
|
||||||
|
BOT_TOKEN: ${{ secrets.PROD_BOT_TOKEN }}
|
||||||
|
BOT_VER: ${{ vars.PROD_BOT_VER }}
|
||||||
|
BOT_AUTHOR: ${{ vars.PROD_BOT_AUTHOR }}
|
||||||
|
BOT_OWNERID: ${{ vars.PROD_BOT_OWNERID }}
|
||||||
|
BOT_CLIENTID: ${{ vars.PROD_BOT_CLIENTID }}
|
||||||
|
BOT_ENV: ${{ vars.PROD_BOT_ENV }}
|
||||||
|
BOT_ADMINS: ${{ vars.PROD_BOT_ADMINS }}
|
||||||
|
ABOUT_FUNDING: ${{ vars.PROD_ABOUT_FUNDING }}
|
||||||
|
ABOUT_REPO: ${{ vars.PROD_ABOUT_REPO }}
|
||||||
|
DATA_DIR: ${{ secrets.PROD_DATA_DIR }}
|
||||||
|
GDRIVESYNC_AUTO: ${{ vars.PROD_GDRIVESYNC_AUTO }}
|
||||||
|
EXPRESS_PORT: ${{ secrets.PROD_EXPRESS_PORT }}
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.PROD_SSH_HOST }}
|
||||||
|
username: ${{ secrets.PROD_SSH_USER }}
|
||||||
|
key: ${{ secrets.PROD_SSH_KEY }}
|
||||||
|
port: ${{ secrets.PROD_SSH_PORT }}
|
||||||
|
envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,BOT_ENV,BOT_ADMINS,DATA_DIR,GDRIVESYNC_AUTO,SERVER_PATH,EXPRESS_PORT
|
||||||
|
script: |
|
||||||
|
source .sshrc \
|
||||||
|
&& cd /home/vylpes/apps/card-drop/card-drop_prod \
|
||||||
|
&& docker compose down \
|
||||||
|
&& (pm2 stop card-drop_prod || true) \
|
||||||
|
&& (pm2 delete card-drop_prod || true) \
|
||||||
|
&& docker compose up -d \
|
||||||
|
&& sleep 10 \
|
||||||
|
&& yarn run db:up \
|
||||||
|
&& pm2 start --name card-drop_prod dist/bot.js
|
71
.forgejo/workflows/stage.yml
Normal file
71
.forgejo/workflows/stage.yml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
name: Deploy To Stage
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
environment: stage
|
||||||
|
|
||||||
|
runs-on: node
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build
|
||||||
|
- run: npm test
|
||||||
|
|
||||||
|
- name: "Copy files over to location"
|
||||||
|
run: cp -r . ${{ secrets.STAGE_REPO_PATH }}
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
environment: prod
|
||||||
|
needs: build
|
||||||
|
runs-on: node
|
||||||
|
steps:
|
||||||
|
- uses: https://github.com/appleboy/ssh-action@v1.0.0
|
||||||
|
env:
|
||||||
|
DB_NAME: ${{ secrets.STAGE_DB_NAME }}
|
||||||
|
DB_AUTH_USER: ${{ secrets.STAGE_DB_AUTH_USER }}
|
||||||
|
DB_AUTH_PASS: ${{ secrets.STAGE_DB_AUTH_PASS }}
|
||||||
|
DB_HOST: ${{ secrets.STAGE_DB_HOST }}
|
||||||
|
DB_PORT: ${{ secrets.STAGE_DB_PORT }}
|
||||||
|
DB_ROOT_HOST: ${{ secrets.STAGE_DB_ROOT_HOST }}
|
||||||
|
DB_SYNC: ${{ secrets.STAGE_DB_SYNC }}
|
||||||
|
DB_LOGGING: ${{ secrets.STAGE_DB_LOGGING }}
|
||||||
|
DB_DATA_LOCATION: ${{ secrets.STAGE_DB_DATA_LOCATION }}
|
||||||
|
SERVER_PATH: ${{ secrets.STAGE_SSH_SERVER_PATH }}
|
||||||
|
BOT_TOKEN: ${{ secrets.STAGE_BOT_TOKEN }}
|
||||||
|
BOT_VER: ${{ vars.STAGE_BOT_VER }}
|
||||||
|
BOT_AUTHOR: ${{ vars.STAGE_BOT_AUTHOR }}
|
||||||
|
BOT_OWNERID: ${{ vars.STAGE_BOT_OWNERID }}
|
||||||
|
BOT_CLIENTID: ${{ vars.STAGE_BOT_CLIENTID }}
|
||||||
|
BOT_ENV: ${{ vars.STAGE_BOT_ENV }}
|
||||||
|
BOT_ADMINS: ${{ vars.STAGE_BOT_ADMINS }}
|
||||||
|
ABOUT_FUNDING: ${{ vars.STAGE_ABOUT_FUNDING }}
|
||||||
|
ABOUT_REPO: ${{ vars.STAGE_ABOUT_REPO }}
|
||||||
|
DATA_DIR: ${{ secrets.STAGE_DATA_DIR }}
|
||||||
|
GDRIVESYNC_AUTO: ${{ vars.STAGE_GDRIVESYNC_AUTO }}
|
||||||
|
EXPRESS_PORT: ${{ secrets.STAGE_EXPRESS_PORT }}
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.STAGE_SSH_HOST }}
|
||||||
|
username: ${{ secrets.STAGE_SSH_USER }}
|
||||||
|
key: ${{ secrets.STAGE_SSH_KEY }}
|
||||||
|
port: ${{ secrets.STAGE_SSH_PORT }}
|
||||||
|
envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,BOT_ENV,BOT_ADMINS,DATA_DIR,GDRIVESYNC_AUTO,SERVER_PATH,EXPRESS_PORT
|
||||||
|
script: |
|
||||||
|
source .sshrc \
|
||||||
|
&& cd /home/vylpes/apps/card-drop/card-drop_stage \
|
||||||
|
&& docker compose down \
|
||||||
|
&& (pm2 stop card-drop_stage || true) \
|
||||||
|
&& (pm2 delete card-drop_stage || true) \
|
||||||
|
&& docker compose up -d \
|
||||||
|
&& sleep 10 \
|
||||||
|
&& yarn run db:up \
|
||||||
|
&& pm2 start --name card-drop_stage dist/bot.js
|
24
.forgejo/workflows/test.yml
Normal file
24
.forgejo/workflows/test.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
name: Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- feature/*
|
||||||
|
- hotfix/*
|
||||||
|
- renovate/*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
environment: stage
|
||||||
|
|
||||||
|
runs-on: node
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build
|
||||||
|
- run: npm test
|
34
.prod.env
34
.prod.env
|
@ -1,34 +0,0 @@
|
||||||
# Security Warning! Do not commit this file to any VCS!
|
|
||||||
# This is a local file to speed up development process,
|
|
||||||
# so you don't have to change your environment variables.
|
|
||||||
#
|
|
||||||
# This is not applied to `.env.template`!
|
|
||||||
# Template files must be committed to the VCS, but must not contain
|
|
||||||
# any secret values.
|
|
||||||
|
|
||||||
BOT_TOKEN=
|
|
||||||
BOT_VER=0.5.1
|
|
||||||
BOT_AUTHOR=Vylpes
|
|
||||||
BOT_OWNERID=147392775707426816
|
|
||||||
BOT_CLIENTID=1093810443589529631
|
|
||||||
BOT_ENV=1
|
|
||||||
BOT_ADMINS=147392775707426816,887272961504071690
|
|
||||||
|
|
||||||
ABOUT_FUNDING=
|
|
||||||
ABOUT_REPO=
|
|
||||||
|
|
||||||
DATA_DIR=/home/vylpes/appdata/card-drop/card-drop_prod
|
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
|
||||||
DB_PORT=3321
|
|
||||||
DB_NAME=carddrop
|
|
||||||
DB_AUTH_USER=prod
|
|
||||||
DB_AUTH_PASS=prod
|
|
||||||
DB_SYNC=false
|
|
||||||
DB_LOGGING=false
|
|
||||||
|
|
||||||
DB_CARD_FILE=:memory:
|
|
||||||
|
|
||||||
EXPRESS_PORT=3323
|
|
||||||
|
|
||||||
GDRIVESYNC_AUTO=false
|
|
34
.stage.env
34
.stage.env
|
@ -1,34 +0,0 @@
|
||||||
# Security Warning! Do not commit this file to any VCS!
|
|
||||||
# This is a local file to speed up development process,
|
|
||||||
# so you don't have to change your environment variables.
|
|
||||||
#
|
|
||||||
# This is not applied to `.env.template`!
|
|
||||||
# Template files must be committed to the VCS, but must not contain
|
|
||||||
# any secret values.
|
|
||||||
|
|
||||||
BOT_TOKEN=
|
|
||||||
BOT_VER=0.5.1
|
|
||||||
BOT_AUTHOR=Vylpes
|
|
||||||
BOT_OWNERID=147392775707426816
|
|
||||||
BOT_CLIENTID=1147976642942214235
|
|
||||||
BOT_ENV=2
|
|
||||||
BOT_ADMINS=147392775707426816,887272961504071690
|
|
||||||
|
|
||||||
ABOUT_FUNDING=
|
|
||||||
ABOUT_REPO=
|
|
||||||
|
|
||||||
DATA_DIR=/home/vylpes/appdata/card-drop/card-drop_stage
|
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
|
||||||
DB_PORT=3311
|
|
||||||
DB_NAME=carddrop
|
|
||||||
DB_AUTH_USER=stage
|
|
||||||
DB_AUTH_PASS=stage
|
|
||||||
DB_SYNC=false
|
|
||||||
DB_LOGGING=false
|
|
||||||
|
|
||||||
DB_CARD_FILE=:memory:
|
|
||||||
|
|
||||||
EXPRESS_PORT=3313
|
|
||||||
|
|
||||||
GDRIVESYNC_AUTO=false
|
|
|
@ -28,8 +28,8 @@ steps:
|
||||||
- apk add rsync openssh-client
|
- apk add rsync openssh-client
|
||||||
- eval `ssh-agent -s`
|
- eval `ssh-agent -s`
|
||||||
- echo "$SSH_KEY" | tr -d '\r' | ssh-add -
|
- echo "$SSH_KEY" | tr -d '\r' | ssh-add -
|
||||||
- rsync -e "ssh -o StrictHostKeyChecking=no" -r ./* vylpes@192.168.68.120:/home/vylpes/apps/card-drop/card-drop_stage
|
- rsync -e "ssh -o StrictHostKeyChecking=no" -r ./* vylpes@192.168.1.115:/home/vylpes/apps/card-drop/card-drop_stage
|
||||||
- ssh vylpes@192.168.68.120 BOT_TOKEN='$${stage_bot_token}' 'bash -s' < ./scripts/deploy_stage.sh
|
- ssh vylpes@192.168.1.115 BOT_TOKEN='$${stage_bot_token}' 'bash -s' < ./scripts/deploy_stage.sh
|
||||||
when:
|
when:
|
||||||
event: push
|
event: push
|
||||||
branch: [ develop ]
|
branch: [ develop ]
|
||||||
|
@ -40,8 +40,8 @@ steps:
|
||||||
- apk add rsync openssh-client
|
- apk add rsync openssh-client
|
||||||
- eval `ssh-agent -s`
|
- eval `ssh-agent -s`
|
||||||
- echo "$SSH_KEY" | tr -d '\r' | ssh-add -
|
- echo "$SSH_KEY" | tr -d '\r' | ssh-add -
|
||||||
- rsync -e "ssh -o StrictHostKeyChecking=no" -r ./* vylpes@192.168.68.120:/home/vylpes/apps/card-drop/card-drop_prod
|
- rsync -e "ssh -o StrictHostKeyChecking=no" -r ./* vylpes@192.168.1.115:/home/vylpes/apps/card-drop/card-drop_prod
|
||||||
- ssh vylpes@192.168.68.120 BOT_TOKEN='$${prod_bot_token}' 'bash -s' < ./scripts/deploy_prod.sh
|
- ssh vylpes@192.168.1.115 BOT_TOKEN='$${prod_bot_token}' 'bash -s' < ./scripts/deploy_prod.sh
|
||||||
when:
|
when:
|
||||||
event: push
|
event: push
|
||||||
branch: [ main ]
|
branch: [ main ]
|
7
database/0.6/1713289062969-user/Up/01-table/User.sql
Normal file
7
database/0.6/1713289062969-user/Up/01-table/User.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE `user` (
|
||||||
|
`Id` varchar(255) NOT NULL,
|
||||||
|
`WhenCreated` datetime NOT NULL,
|
||||||
|
`WhenUpdated` datetime NOT NULL,
|
||||||
|
`Currency` int NOT NULL,
|
||||||
|
PRIMARY KEY (`Id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
|
@ -1,31 +0,0 @@
|
||||||
version: "3.9"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prod_database_data:
|
|
||||||
|
|
||||||
services:
|
|
||||||
# discord:
|
|
||||||
# build: .
|
|
||||||
|
|
||||||
database:
|
|
||||||
image: mysql/mysql-server
|
|
||||||
command: --default-authentication-plugin=mysql_native_password
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- MYSQL_DATABASE=carddrop
|
|
||||||
- MYSQL_USER=prod
|
|
||||||
- MYSQL_PASSWORD=prod
|
|
||||||
- MYSQL_ROOT_PASSWORD=root
|
|
||||||
- MYSQL_ROOT_HOST=0.0.0.0
|
|
||||||
ports:
|
|
||||||
- "3321:3306"
|
|
||||||
volumes:
|
|
||||||
- prod_database_data:/var/lib/mysql
|
|
||||||
|
|
||||||
phpmyadmin:
|
|
||||||
image: phpmyadmin
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "3322:80"
|
|
||||||
environment:
|
|
||||||
- PMA_ARBITRARY=1
|
|
|
@ -1,31 +0,0 @@
|
||||||
version: "3.9"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
stage_database_data:
|
|
||||||
|
|
||||||
services:
|
|
||||||
# discord:
|
|
||||||
# build: .
|
|
||||||
|
|
||||||
database:
|
|
||||||
image: mysql/mysql-server
|
|
||||||
command: --default-authentication-plugin=mysql_native_password
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- MYSQL_DATABASE=carddrop
|
|
||||||
- MYSQL_USER=stage
|
|
||||||
- MYSQL_PASSWORD=stage
|
|
||||||
- MYSQL_ROOT_PASSWORD=root
|
|
||||||
- MYSQL_ROOT_HOST=0.0.0.0
|
|
||||||
ports:
|
|
||||||
- "3311:3306"
|
|
||||||
volumes:
|
|
||||||
- stage_database_data:/var/lib/mysql
|
|
||||||
|
|
||||||
phpmyadmin:
|
|
||||||
image: phpmyadmin
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "3312:80"
|
|
||||||
environment:
|
|
||||||
- PMA_ARBITRARY=1
|
|
|
@ -1,31 +1,17 @@
|
||||||
version: "3.9"
|
version: "3.9"
|
||||||
|
|
||||||
volumes:
|
|
||||||
dev_database_data:
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# discord:
|
|
||||||
# build: .
|
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: mysql/mysql-server
|
image: mysql/mysql-server
|
||||||
command: --default-authentication-plugin=mysql_native_password
|
command: --default-authentication-plugin=mysql_native_password
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_DATABASE=carddrop
|
- MYSQL_DATABASE=$DB_NAME
|
||||||
- MYSQL_USER=dev
|
- MYSQL_USER=$DB_AUTH_USER
|
||||||
- MYSQL_PASSWORD=dev
|
- MYSQL_PASSWORD=$DB_AUTH_PASS
|
||||||
- MYSQL_ROOT_PASSWORD=root
|
- MYSQL_ROOT_PASSWORD=$DB_AUTH_PASS
|
||||||
- MYSQL_ROOT_HOST=0.0.0.0
|
- MYSQL_ROOT_HOST=$DB_ROOT_HOST
|
||||||
ports:
|
ports:
|
||||||
- "3301:3306"
|
- "$DB_PORT:3306"
|
||||||
volumes:
|
volumes:
|
||||||
- dev_database_data:/var/lib/mysql
|
- $DB_DATA_LOCATION:/var/lib/mysql
|
||||||
|
|
||||||
phpmyadmin:
|
|
||||||
image: phpmyadmin
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "3302:80"
|
|
||||||
environment:
|
|
||||||
- PMA_ARBITRARY=1
|
|
723
package-lock.json
generated
723
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -38,10 +38,11 @@
|
||||||
"glob": "^10.3.10",
|
"glob": "^10.3.10",
|
||||||
"jest": "^29.0.0",
|
"jest": "^29.0.0",
|
||||||
"jest-mock-extended": "^3.0.0",
|
"jest-mock-extended": "^3.0.0",
|
||||||
"minimatch": "9.0.3",
|
"minimatch": "9.0.4",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"ts-jest": "^29.0.0",
|
"ts-jest": "^29.0.0",
|
||||||
"typeorm": "0.3.20"
|
"typeorm": "0.3.20",
|
||||||
|
"winston": "^3.11.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"undici": "^5.28.3"
|
"undici": "^5.28.3"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Config from "../database/entities/app/Config";
|
||||||
import { glob } from "glob";
|
import { glob } from "glob";
|
||||||
import { SeriesMetadata } from "../contracts/SeriesMetadata";
|
import { SeriesMetadata } from "../contracts/SeriesMetadata";
|
||||||
import { CoreClient } from "../client/client";
|
import { CoreClient } from "../client/client";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export interface CardMetadataResult {
|
export interface CardMetadataResult {
|
||||||
IsSuccess: boolean;
|
IsSuccess: boolean;
|
||||||
|
@ -21,16 +22,22 @@ export interface FindMetadataResult {
|
||||||
|
|
||||||
export default class CardMetadataFunction {
|
export default class CardMetadataFunction {
|
||||||
public static async Execute(overrideSafeMode: boolean = false): Promise<CardMetadataResult> {
|
public static async Execute(overrideSafeMode: boolean = false): Promise<CardMetadataResult> {
|
||||||
if (!overrideSafeMode && await Config.GetValue("safemode") == "true") return {
|
AppLogger.LogInfo("Functions/CardMetadataFunction", "Executing");
|
||||||
|
|
||||||
|
if (!overrideSafeMode && await Config.GetValue("safemode") == "true") {
|
||||||
|
AppLogger.LogWarn("Functions/CardMetadataFunction", "Safe Mode is active, refusing to resync");
|
||||||
|
|
||||||
|
return {
|
||||||
IsSuccess: false,
|
IsSuccess: false,
|
||||||
ErrorMessage: "Safe mode is on and not overridden",
|
ErrorMessage: "Safe mode is on and not overridden",
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const cardResult = await this.FindMetadataJSONs();
|
const cardResult = await this.FindMetadataJSONs();
|
||||||
|
|
||||||
if (cardResult.IsSuccess) {
|
if (cardResult.IsSuccess) {
|
||||||
CoreClient.Cards = cardResult.Result!;
|
CoreClient.Cards = cardResult.Result!;
|
||||||
console.log(`Loaded ${CoreClient.Cards.flatMap(x => x.cards).length} cards to database`);
|
AppLogger.LogInfo("Functions/CardMetadataFunction", `Loaded ${CoreClient.Cards.flatMap(x => x.cards).length} cards to database`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
IsSuccess: true,
|
IsSuccess: true,
|
||||||
|
@ -38,6 +45,7 @@ export default class CardMetadataFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
await Config.SetValue("safemode", "true");
|
await Config.SetValue("safemode", "true");
|
||||||
|
AppLogger.LogError("Functions/CardMetadataFunction", `Safe Mode activated due to error: ${cardResult.Error!.Message}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
IsSuccess: false,
|
IsSuccess: false,
|
||||||
|
@ -52,13 +60,13 @@ export default class CardMetadataFunction {
|
||||||
|
|
||||||
for (const jsonPath of seriesJSONs) {
|
for (const jsonPath of seriesJSONs) {
|
||||||
try {
|
try {
|
||||||
console.log(`Reading file ${jsonPath}`);
|
AppLogger.LogVerbose("Functions/CardMetadataFunction", `Reading file ${jsonPath}`);
|
||||||
const jsonFile = readFileSync(jsonPath);
|
const jsonFile = readFileSync(jsonPath);
|
||||||
const parsedJson: SeriesMetadata[] = JSON.parse(jsonFile.toString());
|
const parsedJson: SeriesMetadata[] = JSON.parse(jsonFile.toString());
|
||||||
|
|
||||||
res.push(...parsedJson);
|
res.push(...parsedJson);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
AppLogger.LogError("Functions/CardMetadataFunction", `Error reading file ${jsonPath}: ${e}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
IsSuccess: false,
|
IsSuccess: false,
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import { ButtonInteraction } from "discord.js";
|
import { AttachmentBuilder, ButtonInteraction } from "discord.js";
|
||||||
import { ButtonEvent } from "../type/buttonEvent";
|
import { ButtonEvent } from "../type/buttonEvent";
|
||||||
import Inventory from "../database/entities/app/Inventory";
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
import { CoreClient } from "../client/client";
|
import { CoreClient } from "../client/client";
|
||||||
import { default as eClaim } from "../database/entities/app/Claim";
|
import { default as eClaim } from "../database/entities/app/Claim";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
export default class Claim extends ButtonEvent {
|
export default class Claim extends ButtonEvent {
|
||||||
public override async execute(interaction: ButtonInteraction) {
|
public override async execute(interaction: ButtonInteraction) {
|
||||||
|
@ -13,17 +17,17 @@ export default class Claim extends ButtonEvent {
|
||||||
const droppedBy = interaction.customId.split(" ")[3];
|
const droppedBy = interaction.customId.split(" ")[3];
|
||||||
const userId = interaction.user.id;
|
const userId = interaction.user.id;
|
||||||
|
|
||||||
await interaction.deferReply();
|
AppLogger.LogSilly("Button/Claim", `Parameters: cardNumber=${cardNumber}, claimId=${claimId}, droppedBy=${droppedBy}, userId=${userId}`);
|
||||||
|
|
||||||
const claimed = await eClaim.FetchOneByClaimId(claimId);
|
const claimed = await eClaim.FetchOneByClaimId(claimId);
|
||||||
|
|
||||||
if (claimed) {
|
if (claimed) {
|
||||||
await interaction.editReply("This card has already been claimed");
|
await interaction.reply("This card has already been claimed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (claimId == CoreClient.ClaimId && userId != droppedBy) {
|
if (claimId == CoreClient.ClaimId && userId != droppedBy) {
|
||||||
await interaction.editReply("The latest dropped card can only be claimed by the user who dropped it");
|
await interaction.reply("The latest dropped card can only be claimed by the user who dropped it");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +46,24 @@ export default class Claim extends ButtonEvent {
|
||||||
|
|
||||||
await claim.Save(eClaim, claim);
|
await claim.Save(eClaim, claim);
|
||||||
|
|
||||||
await interaction.editReply(`Card claimed by ${interaction.user}`);
|
const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber);
|
||||||
|
|
||||||
|
if (!card) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path));
|
||||||
|
const imageFileName = card.card.path.split("/").pop()!;
|
||||||
|
|
||||||
|
const attachment = new AttachmentBuilder(image, { name: imageFileName });
|
||||||
|
|
||||||
|
const embed = CardDropHelperMetadata.GenerateDropEmbed(card, inventory.Quantity, imageFileName, interaction.user.username);
|
||||||
|
const row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id, true);
|
||||||
|
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [ embed ],
|
||||||
|
files: [ attachment ],
|
||||||
|
components: [ row ],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { ButtonInteraction } from "discord.js";
|
import { ButtonInteraction } from "discord.js";
|
||||||
import { ButtonEvent } from "../type/buttonEvent";
|
import { ButtonEvent } from "../type/buttonEvent";
|
||||||
import InventoryHelper from "../helpers/InventoryHelper";
|
import InventoryHelper from "../helpers/InventoryHelper";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Inventory extends ButtonEvent {
|
export default class Inventory extends ButtonEvent {
|
||||||
public override async execute(interaction: ButtonInteraction) {
|
public override async execute(interaction: ButtonInteraction) {
|
||||||
|
@ -9,6 +10,8 @@ export default class Inventory extends ButtonEvent {
|
||||||
const userid = interaction.customId.split(" ")[1];
|
const userid = interaction.customId.split(" ")[1];
|
||||||
const page = interaction.customId.split(" ")[2];
|
const page = interaction.customId.split(" ")[2];
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Button/Inventory", `Parameters: userid=${userid}, page=${page}`);
|
||||||
|
|
||||||
const member = interaction.guild.members.cache.find(x => x.id == userid) || await interaction.guild.members.fetch(userid);
|
const member = interaction.guild.members.cache.find(x => x.id == userid) || await interaction.guild.members.fetch(userid);
|
||||||
|
|
||||||
if (!member) {
|
if (!member) {
|
||||||
|
@ -17,6 +20,8 @@ export default class Inventory extends ButtonEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
AppLogger.LogVerbose("Button/Inventory", `Generating inventory page ${page} for ${member.user.username} with id ${member.user.id}`);
|
||||||
|
|
||||||
const embed = await InventoryHelper.GenerateInventoryPage(member.user.username, member.user.id, Number(page));
|
const embed = await InventoryHelper.GenerateInventoryPage(member.user.username, member.user.id, Number(page));
|
||||||
|
|
||||||
await interaction.update({
|
await interaction.update({
|
||||||
|
@ -24,7 +29,8 @@ export default class Inventory extends ButtonEvent {
|
||||||
components: [ embed.row ],
|
components: [ embed.row ],
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
AppLogger.LogError("Button/Inventory", `Error generating inventory page for ${member.user.username} with id ${member.user.id}: ${e}`);
|
||||||
|
|
||||||
await interaction.reply("No page for user found.");
|
await interaction.reply("No page for user found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Inventory from "../database/entities/app/Inventory";
|
||||||
import Config from "../database/entities/app/Config";
|
import Config from "../database/entities/app/Config";
|
||||||
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Reroll extends ButtonEvent {
|
export default class Reroll extends ButtonEvent {
|
||||||
public override async execute(interaction: ButtonInteraction) {
|
public override async execute(interaction: ButtonInteraction) {
|
||||||
|
@ -16,6 +17,8 @@ export default class Reroll extends ButtonEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await Config.GetValue("safemode") == "true") {
|
if (await Config.GetValue("safemode") == "true") {
|
||||||
|
AppLogger.LogWarn("Button/Reroll", "Safe Mode is active, refusing to send next drop.");
|
||||||
|
|
||||||
await interaction.reply("Safe Mode has been activated, please resync to continue.");
|
await interaction.reply("Safe Mode has been activated, please resync to continue.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +33,8 @@ export default class Reroll extends ButtonEvent {
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
AppLogger.LogVerbose("Button/Reroll", `Sending next drop: ${randomCard.card.id} (${randomCard.card.name})`);
|
||||||
|
|
||||||
const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path));
|
const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path));
|
||||||
const imageFileName = randomCard.card.path.split("/").pop()!;
|
const imageFileName = randomCard.card.path.split("/").pop()!;
|
||||||
|
|
||||||
|
@ -51,9 +56,8 @@ export default class Reroll extends ButtonEvent {
|
||||||
});
|
});
|
||||||
|
|
||||||
CoreClient.ClaimId = claimId;
|
CoreClient.ClaimId = claimId;
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
AppLogger.LogError("Button/Reroll", `Error sending next drop for card ${randomCard.card.id}: ${e}`);
|
||||||
|
|
||||||
await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`);
|
await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`);
|
||||||
}
|
}
|
||||||
|
|
45
src/buttonEvents/Series.ts
Normal file
45
src/buttonEvents/Series.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import { ButtonInteraction } from "discord.js";
|
||||||
|
import { ButtonEvent } from "../type/buttonEvent";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
import SeriesHelper from "../helpers/SeriesHelper";
|
||||||
|
|
||||||
|
export default class Series extends ButtonEvent {
|
||||||
|
public override async execute(interaction: ButtonInteraction) {
|
||||||
|
const subaction = interaction.customId.split(" ")[1];
|
||||||
|
|
||||||
|
switch(subaction) {
|
||||||
|
case "view":
|
||||||
|
await this.ViewSeries(interaction);
|
||||||
|
break;
|
||||||
|
case "list":
|
||||||
|
await this.ListSeries(interaction);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AppLogger.LogWarn("Commands/Series", `Subaction doesn't exist: ${subaction}`);
|
||||||
|
interaction.reply("Subaction doesn't exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ViewSeries(interaction: ButtonInteraction) {
|
||||||
|
const seriesid = interaction.customId.split(" ")[2];
|
||||||
|
const page = interaction.customId.split(" ")[3];
|
||||||
|
|
||||||
|
const embed = SeriesHelper.GenerateSeriesViewPage(Number(seriesid), Number(page));
|
||||||
|
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [ embed!.embed ],
|
||||||
|
components: [ embed!.row ],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ListSeries(interaction: ButtonInteraction) {
|
||||||
|
const page = interaction.customId.split(" ")[2];
|
||||||
|
|
||||||
|
const embed = SeriesHelper.GenerateSeriesListPage(Number(page));
|
||||||
|
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [ embed!.embed ],
|
||||||
|
components: [ embed!.row ],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
211
src/buttonEvents/Trade.ts
Normal file
211
src/buttonEvents/Trade.ts
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder } from "discord.js";
|
||||||
|
import { ButtonEvent } from "../type/buttonEvent";
|
||||||
|
import { CoreClient } from "../client/client";
|
||||||
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
|
export default class Trade extends ButtonEvent {
|
||||||
|
public override async execute(interaction: ButtonInteraction) {
|
||||||
|
const action = interaction.customId.split(" ")[1];
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Button/Trade", `Parameters: action=${action}`);
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "accept":
|
||||||
|
await this.AcceptTrade(interaction);
|
||||||
|
break;
|
||||||
|
case "decline":
|
||||||
|
await this.DeclineTrade(interaction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async AcceptTrade(interaction: ButtonInteraction) {
|
||||||
|
const giveUserId = interaction.customId.split(" ")[2];
|
||||||
|
const receiveUserId = interaction.customId.split(" ")[3];
|
||||||
|
const giveCardNumber = interaction.customId.split(" ")[4];
|
||||||
|
const receiveCardNumber = interaction.customId.split(" ")[5];
|
||||||
|
const expiry = interaction.customId.split(" ")[6];
|
||||||
|
const timeoutId = interaction.customId.split(" ")[7];
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Button/Trade/AcceptTrade", `Parameters: giveUserId=${giveUserId}, receiveUserId=${receiveUserId}, giveCardNumber=${giveCardNumber}, receiveCardNumber=${receiveCardNumber}, expiry=${expiry}, timeoutId=${timeoutId}`);
|
||||||
|
|
||||||
|
const expiryDate = new Date(expiry);
|
||||||
|
|
||||||
|
if (expiryDate < new Date()) {
|
||||||
|
await interaction.reply("Trade has expired");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.user.id !== receiveUserId) {
|
||||||
|
await interaction.reply("You are not the user who the trade is intended for");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === giveCardNumber);
|
||||||
|
|
||||||
|
const receiveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveItem || !receiveItem) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveUser = interaction.client.users.cache.get(giveUserId) || await interaction.client.users.fetch(giveUserId);
|
||||||
|
const receiveUser = interaction.client.users.cache.get(receiveUserId) || await interaction.client.users.fetch(receiveUserId);
|
||||||
|
|
||||||
|
const giveUserInventory1 = await Inventory.FetchOneByCardNumberAndUserId(giveUserId, giveCardNumber);
|
||||||
|
const receiveUserInventory1 = await Inventory.FetchOneByCardNumberAndUserId(receiveUserId, receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveUserInventory1 || !receiveUserInventory1) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (giveUserInventory1.Quantity < 1 || receiveUserInventory1.Quantity < 1) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
giveUserInventory1.SetQuantity(giveUserInventory1.Quantity - 1);
|
||||||
|
receiveUserInventory1.SetQuantity(receiveUserInventory1.Quantity - 1);
|
||||||
|
|
||||||
|
await giveUserInventory1.Save(Inventory, giveUserInventory1);
|
||||||
|
await receiveUserInventory1.Save(Inventory, receiveUserInventory1);
|
||||||
|
|
||||||
|
let giveUserInventory2 = await Inventory.FetchOneByCardNumberAndUserId(receiveUserId, giveCardNumber);
|
||||||
|
let receiveUserInventory2 = await Inventory.FetchOneByCardNumberAndUserId(giveUserId, receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveUserInventory2) {
|
||||||
|
giveUserInventory2 = new Inventory(receiveUserId, giveCardNumber, 1);
|
||||||
|
} else {
|
||||||
|
giveUserInventory2.SetQuantity(giveUserInventory2.Quantity + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!receiveUserInventory2) {
|
||||||
|
receiveUserInventory2 = new Inventory(giveUserId, receiveCardNumber, 1);
|
||||||
|
} else {
|
||||||
|
receiveUserInventory2.SetQuantity(receiveUserInventory2.Quantity + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
await giveUserInventory2.Save(Inventory, giveUserInventory2);
|
||||||
|
await receiveUserInventory2.Save(Inventory, receiveUserInventory2);
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Accepted")
|
||||||
|
.setDescription(`Trade initiated between ${receiveUser.username} and ${giveUser.username}`)
|
||||||
|
.setColor(EmbedColours.Success)
|
||||||
|
.setImage("https://i.imgur.com/9w5f1ls.gif")
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: "I receieve",
|
||||||
|
value: `${receiveItem.id}: ${receiveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "You receieve",
|
||||||
|
value: `${giveItem.id}: ${giveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Complete",
|
||||||
|
value: new Date().toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("trade expired accept")
|
||||||
|
.setLabel("Accept")
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
.setDisabled(true),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("trade expired decline")
|
||||||
|
.setLabel("Decline")
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
.setDisabled(true),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.update({ embeds: [ tradeEmbed ], components: [ row ]});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async DeclineTrade(interaction: ButtonInteraction) {
|
||||||
|
const giveUserId = interaction.customId.split(" ")[2];
|
||||||
|
const receiveUserId = interaction.customId.split(" ")[3];
|
||||||
|
const giveCardNumber = interaction.customId.split(" ")[4];
|
||||||
|
const receiveCardNumber = interaction.customId.split(" ")[5];
|
||||||
|
// No need to get expiry date
|
||||||
|
const timeoutId = interaction.customId.split(" ")[7];
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Button/Trade/DeclineTrade", `Parameters: giveUserId=${giveUserId}, receiveUserId=${receiveUserId}, giveCardNumber=${giveCardNumber}, receiveCardNumber=${receiveCardNumber}, timeoutId=${timeoutId}`);
|
||||||
|
|
||||||
|
if (interaction.user.id != receiveUserId && interaction.user.id !==giveUserId) {
|
||||||
|
await interaction.reply("You are not the user who the trade is intended for");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveUser = interaction.client.users.cache.get(giveUserId) || await interaction.client.users.fetch(giveUserId);
|
||||||
|
const receiveUser = interaction.client.users.cache.get(receiveUserId) || await interaction.client.users.fetch(receiveUserId);
|
||||||
|
|
||||||
|
const giveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === giveCardNumber);
|
||||||
|
|
||||||
|
const receiveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveItem || !receiveItem) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Declined")
|
||||||
|
.setDescription(`Trade initiated between ${receiveUser.username} and ${giveUser.username}`)
|
||||||
|
.setColor(EmbedColours.Error)
|
||||||
|
.setImage("https://i.imgur.com/9w5f1ls.gif")
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: "I Receive",
|
||||||
|
value: `${receiveItem.id}: ${receiveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "You Receive",
|
||||||
|
value: `${giveItem.id}: ${giveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Declined",
|
||||||
|
value: new Date().toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("trade expired accept")
|
||||||
|
.setLabel("Accept")
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
.setDisabled(true),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("trade expired decline")
|
||||||
|
.setLabel("Decline")
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
.setDisabled(true),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.update({ embeds: [ tradeEmbed ], components: [ row ]});
|
||||||
|
}
|
||||||
|
}
|
65
src/client/appLogger.ts
Normal file
65
src/client/appLogger.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import { Logger, createLogger, format, transports } from "winston";
|
||||||
|
|
||||||
|
export default class AppLogger {
|
||||||
|
public static Logger: Logger;
|
||||||
|
|
||||||
|
public static InitialiseLogger(logLevel: string, outputToConsole: boolean) {
|
||||||
|
const customFormat = format.printf(({ level, message, timestamp, label }) => {
|
||||||
|
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const logger = createLogger({
|
||||||
|
level: logLevel,
|
||||||
|
format: format.combine(
|
||||||
|
format.timestamp({
|
||||||
|
format: "YYYY-MM-DD HH:mm:ss"
|
||||||
|
}),
|
||||||
|
format.errors({ stack: true }),
|
||||||
|
format.splat(),
|
||||||
|
customFormat,
|
||||||
|
),
|
||||||
|
defaultMeta: { service: "bot" },
|
||||||
|
transports: [
|
||||||
|
new transports.File({ filename: "error.log", level: "error" }),
|
||||||
|
new transports.File({ filename: "combined.log" }),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (outputToConsole) {
|
||||||
|
logger.add(new transports.Console({
|
||||||
|
format: format.combine(
|
||||||
|
format.colorize(),
|
||||||
|
format.timestamp(),
|
||||||
|
customFormat,
|
||||||
|
)}));
|
||||||
|
}
|
||||||
|
|
||||||
|
AppLogger.Logger = logger;
|
||||||
|
|
||||||
|
AppLogger.LogInfo("AppLogger", `Log Level: ${logLevel}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogError(label: string, message: string) {
|
||||||
|
AppLogger.Logger.error({ label, message });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogWarn(label: string, message: string) {
|
||||||
|
AppLogger.Logger.warn({ label, message });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogInfo(label: string, message: string) {
|
||||||
|
AppLogger.Logger.info({ label, message });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogVerbose(label: string, message: string) {
|
||||||
|
AppLogger.Logger.verbose({ label, message });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogDebug(label: string, message: string) {
|
||||||
|
AppLogger.Logger.debug({ label, message });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogSilly(label: string, message: string) {
|
||||||
|
AppLogger.Logger.silly({ label, message });
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import { Environment } from "../constants/Environment";
|
||||||
import Webhooks from "../webhooks";
|
import Webhooks from "../webhooks";
|
||||||
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
||||||
import { SeriesMetadata } from "../contracts/SeriesMetadata";
|
import { SeriesMetadata } from "../contracts/SeriesMetadata";
|
||||||
|
import AppLogger from "./appLogger";
|
||||||
|
|
||||||
export class CoreClient extends Client {
|
export class CoreClient extends Client {
|
||||||
private static _commandItems: ICommandItem[];
|
private static _commandItems: ICommandItem[];
|
||||||
|
@ -44,6 +45,14 @@ export class CoreClient extends Client {
|
||||||
super({ intents: intents });
|
super({ intents: intents });
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
CoreClient.Environment = Number(process.env.BOT_ENV);
|
||||||
|
|
||||||
|
const loglevel = process.env.BOT_LOGLEVEL ?? "info";
|
||||||
|
|
||||||
|
AppLogger.InitialiseLogger(loglevel, CoreClient.Environment == Environment.Local);
|
||||||
|
|
||||||
|
AppLogger.LogInfo("Client", "Initialising Client");
|
||||||
|
|
||||||
CoreClient._commandItems = [];
|
CoreClient._commandItems = [];
|
||||||
CoreClient._buttonEvents = [];
|
CoreClient._buttonEvents = [];
|
||||||
|
|
||||||
|
@ -51,21 +60,24 @@ export class CoreClient extends Client {
|
||||||
this._util = new Util();
|
this._util = new Util();
|
||||||
this._webhooks = new Webhooks();
|
this._webhooks = new Webhooks();
|
||||||
|
|
||||||
CoreClient.Environment = Number(process.env.BOT_ENV);
|
AppLogger.LogInfo("Client", `Environment: ${CoreClient.Environment}`);
|
||||||
console.log(`Bot Environment: ${CoreClient.Environment}`);
|
|
||||||
|
|
||||||
CoreClient.AllowDrops = true;
|
CoreClient.AllowDrops = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async start() {
|
public async start() {
|
||||||
if (!process.env.BOT_TOKEN) {
|
if (!process.env.BOT_TOKEN) {
|
||||||
console.error("BOT_TOKEN is not defined in .env");
|
AppLogger.LogError("Client", "BOT_TOKEN is not defined in .env");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await AppDataSource.initialize()
|
await AppDataSource.initialize()
|
||||||
.then(() => console.log("App Data Source Initialised"))
|
.then(() => AppLogger.LogInfo("Client", "App Data Source Initialised"))
|
||||||
.catch(err => console.error("Error initialising App Data Source", err));
|
.catch(err => {
|
||||||
|
AppLogger.LogError("Client", "App Data Source Initialisation Failed");
|
||||||
|
AppLogger.LogError("Client", err);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
super.on("interactionCreate", this._events.onInteractionCreate);
|
super.on("interactionCreate", this._events.onInteractionCreate);
|
||||||
super.on("ready", this._events.onReady);
|
super.on("ready", this._events.onReady);
|
||||||
|
@ -90,6 +102,8 @@ export class CoreClient extends Client {
|
||||||
|
|
||||||
if ((environment & CoreClient.Environment) == CoreClient.Environment) {
|
if ((environment & CoreClient.Environment) == CoreClient.Environment) {
|
||||||
CoreClient._commandItems.push(item);
|
CoreClient._commandItems.push(item);
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", `Registered Command: ${name}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +126,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Channel Create Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterChannelDeleteEvent(fn: (channel: DMChannel | NonThreadGuildBasedChannel) => void) {
|
public static RegisterChannelDeleteEvent(fn: (channel: DMChannel | NonThreadGuildBasedChannel) => void) {
|
||||||
|
@ -133,6 +149,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Channel Delete Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterChannelUpdateEvent(fn: (channel: DMChannel | NonThreadGuildBasedChannel) => void) {
|
public static RegisterChannelUpdateEvent(fn: (channel: DMChannel | NonThreadGuildBasedChannel) => void) {
|
||||||
|
@ -154,6 +172,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Channel Update Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterGuildBanAddEvent(fn: (ban: GuildBan) => void) {
|
public static RegisterGuildBanAddEvent(fn: (ban: GuildBan) => void) {
|
||||||
|
@ -175,6 +195,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Guild Ban Add Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterGuildBanRemoveEvent(fn: (channel: GuildBan) => void) {
|
public static RegisterGuildBanRemoveEvent(fn: (channel: GuildBan) => void) {
|
||||||
|
@ -196,6 +218,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Guild Ban Remove Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterGuildCreateEvent(fn: (guild: Guild) => void) {
|
public static RegisterGuildCreateEvent(fn: (guild: Guild) => void) {
|
||||||
|
@ -217,6 +241,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Guild Create Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterGuildMemberAddEvent(fn: (member: GuildMember) => void) {
|
public static RegisterGuildMemberAddEvent(fn: (member: GuildMember) => void) {
|
||||||
|
@ -238,6 +264,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Guild Member Add Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterGuildMemberRemoveEvent(fn: (member: GuildMember | PartialGuildMember) => void) {
|
public static RegisterGuildMemberRemoveEvent(fn: (member: GuildMember | PartialGuildMember) => void) {
|
||||||
|
@ -259,6 +287,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Guild Member Remove Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GuildMemebrUpdate(fn: (oldMember: GuildMember | PartialGuildMember, newMember: GuildMember) => void) {
|
public static GuildMemebrUpdate(fn: (oldMember: GuildMember | PartialGuildMember, newMember: GuildMember) => void) {
|
||||||
|
@ -280,6 +310,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Guild Member Update Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterMessageCreateEvent(fn: (message: Message<boolean>) => void) {
|
public static RegisterMessageCreateEvent(fn: (message: Message<boolean>) => void) {
|
||||||
|
@ -301,6 +333,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Message Create Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterMessageDeleteEvent(fn: (message: Message<boolean> | PartialMessage) => void) {
|
public static RegisterMessageDeleteEvent(fn: (message: Message<boolean> | PartialMessage) => void) {
|
||||||
|
@ -322,6 +356,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [],
|
MessageUpdate: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Message Delete Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterMessageUpdateEvent(fn: (oldMessage: Message<boolean> | PartialMessage, newMessage: Message<boolean> | PartialMessage) => void) {
|
public static RegisterMessageUpdateEvent(fn: (oldMessage: Message<boolean> | PartialMessage, newMessage: Message<boolean> | PartialMessage) => void) {
|
||||||
|
@ -343,6 +379,8 @@ export class CoreClient extends Client {
|
||||||
MessageUpdate: [ fn ],
|
MessageUpdate: [ fn ],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", "Registered Message Update Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterButtonEvent(buttonId: string, event: ButtonEvent, environment: Environment = Environment.All) {
|
public static RegisterButtonEvent(buttonId: string, event: ButtonEvent, environment: Environment = Environment.All) {
|
||||||
|
@ -354,6 +392,8 @@ export class CoreClient extends Client {
|
||||||
|
|
||||||
if ((environment & CoreClient.Environment) == CoreClient.Environment) {
|
if ((environment & CoreClient.Environment) == CoreClient.Environment) {
|
||||||
CoreClient._buttonEvents.push(item);
|
CoreClient._buttonEvents.push(item);
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Client", `Registered Button Event: ${buttonId}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
import { Interaction } from "discord.js";
|
import { Interaction } from "discord.js";
|
||||||
import ChatInputCommand from "./interactionCreate/ChatInputCommand";
|
import ChatInputCommand from "./interactionCreate/ChatInputCommand";
|
||||||
import Button from "./interactionCreate/Button";
|
import Button from "./interactionCreate/Button";
|
||||||
|
import AppLogger from "./appLogger";
|
||||||
|
|
||||||
export class Events {
|
export class Events {
|
||||||
public async onInteractionCreate(interaction: Interaction) {
|
public async onInteractionCreate(interaction: Interaction) {
|
||||||
if (!interaction.guildId) return;
|
if (!interaction.guildId) return;
|
||||||
|
|
||||||
if (interaction.isChatInputCommand()) {
|
if (interaction.isChatInputCommand()) {
|
||||||
|
AppLogger.LogVerbose("Client", `ChatInputCommand: ${interaction.commandName}`);
|
||||||
ChatInputCommand.onChatInput(interaction);
|
ChatInputCommand.onChatInput(interaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interaction.isButton()) {
|
if (interaction.isButton()) {
|
||||||
|
AppLogger.LogVerbose("Client", `Button: ${interaction.customId}`);
|
||||||
Button.onButtonClicked(interaction);
|
Button.onButtonClicked(interaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit when bot is logged in and ready to use
|
// Emit when bot is logged in and ready to use
|
||||||
public onReady() {
|
public onReady() {
|
||||||
console.log("Ready");
|
AppLogger.LogInfo("Client", "Ready");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ButtonInteraction } from "discord.js";
|
import { ButtonInteraction } from "discord.js";
|
||||||
import { CoreClient } from "../client";
|
import { CoreClient } from "../client";
|
||||||
|
import AppLogger from "../appLogger";
|
||||||
|
|
||||||
export default class Button {
|
export default class Button {
|
||||||
public static async onButtonClicked(interaction: ButtonInteraction) {
|
public static async onButtonClicked(interaction: ButtonInteraction) {
|
||||||
|
@ -8,10 +9,21 @@ export default class Button {
|
||||||
const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(" ")[0]);
|
const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(" ")[0]);
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
AppLogger.LogVerbose("Button", `Event not found: ${interaction.customId}`);
|
||||||
|
|
||||||
await interaction.reply("Event not found");
|
await interaction.reply("Event not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
AppLogger.LogDebug("Button", `Executing ${interaction.customId}`);
|
||||||
|
|
||||||
item.Event.execute(interaction);
|
item.Event.execute(interaction);
|
||||||
|
} catch (e) {
|
||||||
|
AppLogger.LogError("Button", `Error occurred while executing event: ${interaction.customId}`);
|
||||||
|
AppLogger.LogError("Button", e as string);
|
||||||
|
|
||||||
|
await interaction.reply("An error occurred while executing the event");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { Interaction } from "discord.js";
|
import { Interaction } from "discord.js";
|
||||||
import { CoreClient } from "../client";
|
import { CoreClient } from "../client";
|
||||||
import ICommandItem from "../../contracts/ICommandItem";
|
import ICommandItem from "../../contracts/ICommandItem";
|
||||||
|
import AppLogger from "../appLogger";
|
||||||
|
|
||||||
export default class ChatInputCommand {
|
export default class ChatInputCommand {
|
||||||
public static async onChatInput(interaction: Interaction) {
|
public static async onChatInput(interaction: Interaction) {
|
||||||
|
@ -13,6 +14,8 @@ export default class ChatInputCommand {
|
||||||
|
|
||||||
if (!itemForServer) {
|
if (!itemForServer) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
AppLogger.LogVerbose("ChatInputCommand", `Command not found: ${interaction.commandName}`);
|
||||||
|
|
||||||
await interaction.reply("Command not found");
|
await interaction.reply("Command not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +25,15 @@ export default class ChatInputCommand {
|
||||||
itemToUse = itemForServer;
|
itemToUse = itemForServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
AppLogger.LogDebug("Command", `Executing ${interaction.commandName}`);
|
||||||
|
|
||||||
itemToUse.Command.execute(interaction);
|
itemToUse.Command.execute(interaction);
|
||||||
|
} catch (e) {
|
||||||
|
AppLogger.LogError("ChatInputCommand", `Error occurred while executing command: ${interaction.commandName}`);
|
||||||
|
AppLogger.LogError("ChatInputCommand", e as string);
|
||||||
|
|
||||||
|
await interaction.reply("An error occurred while executing the command");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { Client, REST, Routes, SlashCommandBuilder } from "discord.js";
|
import { Client, REST, Routes, SlashCommandBuilder } from "discord.js";
|
||||||
import EventExecutors from "../contracts/EventExecutors";
|
import EventExecutors from "../contracts/EventExecutors";
|
||||||
import { CoreClient } from "./client";
|
import { CoreClient } from "./client";
|
||||||
|
import AppLogger from "./appLogger";
|
||||||
|
|
||||||
export class Util {
|
export class Util {
|
||||||
public loadSlashCommands(client: Client) {
|
public loadSlashCommands(client: Client) {
|
||||||
|
@ -29,6 +30,8 @@ export class Util {
|
||||||
|
|
||||||
const rest = new REST({ version: "10" }).setToken(process.env.BOT_TOKEN!);
|
const rest = new REST({ version: "10" }).setToken(process.env.BOT_TOKEN!);
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Util", `REST PUT: ${globalCommandData.flatMap(x => x.name).join(", ")}`);
|
||||||
|
|
||||||
rest.put(
|
rest.put(
|
||||||
Routes.applicationCommands(process.env.BOT_CLIENTID!),
|
Routes.applicationCommands(process.env.BOT_CLIENTID!),
|
||||||
{
|
{
|
||||||
|
@ -49,6 +52,8 @@ export class Util {
|
||||||
|
|
||||||
if (!client.guilds.cache.has(guild)) continue;
|
if (!client.guilds.cache.has(guild)) continue;
|
||||||
|
|
||||||
|
AppLogger.LogVerbose("Util", `REST PUT: ${guild} - ${guildCommandData.flatMap(x => x.name).join(", ")}`);
|
||||||
|
|
||||||
rest.put(
|
rest.put(
|
||||||
Routes.applicationGuildCommands(process.env.BOT_CLIENTID!, guild),
|
Routes.applicationGuildCommands(process.env.BOT_CLIENTID!, guild),
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Inventory from "../database/entities/app/Inventory";
|
||||||
import Config from "../database/entities/app/Config";
|
import Config from "../database/entities/app/Config";
|
||||||
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Drop extends Command {
|
export default class Drop extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -24,6 +25,8 @@ export default class Drop extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await Config.GetValue("safemode") == "true") {
|
if (await Config.GetValue("safemode") == "true") {
|
||||||
|
AppLogger.LogWarn("Commands/Drop", "Safe Mode is active, refusing to send next drop.");
|
||||||
|
|
||||||
await interaction.reply("Safe Mode has been activated, please resync to continue.");
|
await interaction.reply("Safe Mode has been activated, please resync to continue.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +34,8 @@ export default class Drop extends Command {
|
||||||
const randomCard = CardDropHelperMetadata.GetRandomCard();
|
const randomCard = CardDropHelperMetadata.GetRandomCard();
|
||||||
|
|
||||||
if (!randomCard) {
|
if (!randomCard) {
|
||||||
|
AppLogger.LogWarn("Commands/Drop", "Unable to fetch card, please try again. (randomCard is null)");
|
||||||
|
|
||||||
await interaction.reply("Unable to fetch card, please try again.");
|
await interaction.reply("Unable to fetch card, please try again.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +66,7 @@ export default class Drop extends Command {
|
||||||
CoreClient.ClaimId = claimId;
|
CoreClient.ClaimId = claimId;
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
AppLogger.LogError("Commands/Drop", `Error sending next drop for card ${randomCard.card.id}: ${e}`);
|
||||||
|
|
||||||
await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`);
|
await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ExecException, exec } from "child_process";
|
||||||
import { CoreClient } from "../client/client";
|
import { CoreClient } from "../client/client";
|
||||||
import Config from "../database/entities/app/Config";
|
import Config from "../database/entities/app/Config";
|
||||||
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Gdrivesync extends Command {
|
export default class Gdrivesync extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -32,19 +33,28 @@ export default class Gdrivesync extends Command {
|
||||||
|
|
||||||
CoreClient.AllowDrops = false;
|
CoreClient.AllowDrops = false;
|
||||||
|
|
||||||
|
AppLogger.LogInfo("Commands/GDriveSync", "Syncing google drive to the bot");
|
||||||
|
|
||||||
exec(`rclone sync card-drop-gdrive: ${process.env.DATA_DIR}/cards`, async (error: ExecException | null) => {
|
exec(`rclone sync card-drop-gdrive: ${process.env.DATA_DIR}/cards`, async (error: ExecException | null) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
AppLogger.LogError("Commands/GDriveSync", `Error while running sync command: ${error.code}, ${error.message}`);
|
||||||
|
AppLogger.LogWarn("Commands/GDriveSync", "Safe mode activated");
|
||||||
|
|
||||||
await interaction.editReply(`Error while running sync command. Safe Mode has been activated. Code: ${error.code}`);
|
await interaction.editReply(`Error while running sync command. Safe Mode has been activated. Code: ${error.code}`);
|
||||||
await Config.SetValue("safemode", "true");
|
await Config.SetValue("safemode", "true");
|
||||||
} else {
|
} else {
|
||||||
const result = await CardMetadataFunction.Execute(true);
|
const result = await CardMetadataFunction.Execute(true);
|
||||||
|
|
||||||
if (result.IsSuccess) {
|
if (result.IsSuccess) {
|
||||||
|
AppLogger.LogInfo("Commands/GDriveSync", "Synced successfully");
|
||||||
|
|
||||||
await interaction.editReply("Synced successfully.");
|
await interaction.editReply("Synced successfully.");
|
||||||
|
|
||||||
CoreClient.AllowDrops = true;
|
CoreClient.AllowDrops = true;
|
||||||
await Config.SetValue("safemode", "false");
|
await Config.SetValue("safemode", "false");
|
||||||
} else {
|
} else {
|
||||||
|
AppLogger.LogError("Commands/GDriveSync", `Error while running sync command: ${result.ErrorMessage}`);
|
||||||
|
|
||||||
await interaction.editReply(`Sync failed \`\`\`${result.ErrorMessage}\`\`\``);
|
await interaction.editReply(`Sync failed \`\`\`${result.ErrorMessage}\`\`\``);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { CoreClient } from "../client/client";
|
||||||
import Config from "../database/entities/app/Config";
|
import Config from "../database/entities/app/Config";
|
||||||
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
||||||
import Inventory from "../database/entities/app/Inventory";
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Give extends Command {
|
export default class Give extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -46,6 +47,8 @@ export default class Give extends Command {
|
||||||
const cardNumber = interaction.options.get("cardnumber", true);
|
const cardNumber = interaction.options.get("cardnumber", true);
|
||||||
const user = interaction.options.getUser("user", true);
|
const user = interaction.options.getUser("user", true);
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Commands/Give", `Parameters: cardNumber=${cardNumber.value}, user=${user.id}`);
|
||||||
|
|
||||||
const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber.value!.toString());
|
const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber.value!.toString());
|
||||||
|
|
||||||
if (!card) {
|
if (!card) {
|
||||||
|
@ -53,16 +56,16 @@ export default class Give extends Command {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inventory = await Inventory.FetchOneByCardNumberAndUserId(user.id, card.id);
|
let inventory = await Inventory.FetchOneByCardNumberAndUserId(user.id, card.card.id);
|
||||||
|
|
||||||
if (!inventory) {
|
if (!inventory) {
|
||||||
inventory = new Inventory(user.id, card.id, 1);
|
inventory = new Inventory(user.id, card.card.id, 1);
|
||||||
} else {
|
} else {
|
||||||
inventory.SetQuantity(inventory.Quantity + 1);
|
inventory.SetQuantity(inventory.Quantity + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
await inventory.Save(Inventory, inventory);
|
await inventory.Save(Inventory, inventory);
|
||||||
|
|
||||||
await interaction.reply(`${card.name} given to ${interaction.user}, they now have ${inventory.Quantity}`);
|
await interaction.reply(`${card.card.name} given to ${user.username}, they now have ${inventory.Quantity}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { CommandInteraction, SlashCommandBuilder } from "discord.js";
|
import { CommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
import InventoryHelper from "../helpers/InventoryHelper";
|
import InventoryHelper from "../helpers/InventoryHelper";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Inventory extends Command {
|
export default class Inventory extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -23,6 +24,8 @@ export default class Inventory extends Command {
|
||||||
const page = interaction.options.get("page");
|
const page = interaction.options.get("page");
|
||||||
const user = interaction.options.getUser("user") || interaction.user;
|
const user = interaction.options.getUser("user") || interaction.user;
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Commands/Inventory", `Parameters: page=${page?.value}, user=${user.id}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let pageNumber = 0;
|
let pageNumber = 0;
|
||||||
|
|
||||||
|
@ -36,7 +39,9 @@ export default class Inventory extends Command {
|
||||||
embeds: [ embed.embed ],
|
embeds: [ embed.embed ],
|
||||||
components: [ embed.row ],
|
components: [ embed.row ],
|
||||||
});
|
});
|
||||||
} catch {
|
} catch (e) {
|
||||||
|
AppLogger.LogError("Commands/Inventory", e as string);
|
||||||
|
|
||||||
await interaction.reply("No page for user found.");
|
await interaction.reply("No page for user found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { CacheType, CommandInteraction, PermissionsBitField, SlashCommandBuilder
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
import Config from "../database/entities/app/Config";
|
import Config from "../database/entities/app/Config";
|
||||||
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class Resync extends Command {
|
export default class Resync extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -23,10 +24,14 @@ export default class Resync extends Command {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogInfo("Commands/Resync", "Resyncing database");
|
||||||
|
|
||||||
const result = await CardMetadataFunction.Execute(true);
|
const result = await CardMetadataFunction.Execute(true);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
if (await Config.GetValue("safemode") == "true") {
|
if (await Config.GetValue("safemode") == "true") {
|
||||||
|
AppLogger.LogInfo("Commands/Resync", "Resync successful, safe mode disabled");
|
||||||
|
|
||||||
await Config.SetValue("safemode", "false");
|
await Config.SetValue("safemode", "false");
|
||||||
await interaction.reply("Resynced database and disabled safe mode.");
|
await interaction.reply("Resynced database and disabled safe mode.");
|
||||||
|
|
||||||
|
@ -34,6 +39,8 @@ export default class Resync extends Command {
|
||||||
}
|
}
|
||||||
await interaction.reply("Resynced database.");
|
await interaction.reply("Resynced database.");
|
||||||
} else {
|
} else {
|
||||||
|
AppLogger.LogWarn("Commands/Resync", "Resync failed, safe mode activated");
|
||||||
|
|
||||||
await interaction.reply("Resync failed, safe mode has been activated until successful resync.");
|
await interaction.reply("Resync failed, safe mode has been activated until successful resync.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
71
src/commands/series.ts
Normal file
71
src/commands/series.ts
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import { CommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||||
|
import { Command } from "../type/command";
|
||||||
|
import { CoreClient } from "../client/client";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
import SeriesHelper from "../helpers/SeriesHelper";
|
||||||
|
|
||||||
|
export default class Series extends Command {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.CommandBuilder = new SlashCommandBuilder()
|
||||||
|
.setName("series")
|
||||||
|
.setDescription("View details on a series")
|
||||||
|
.addSubcommand(x =>
|
||||||
|
x
|
||||||
|
.setName("view")
|
||||||
|
.setDescription("View a specifiic series by id")
|
||||||
|
.addStringOption(y =>
|
||||||
|
y
|
||||||
|
.setName("id")
|
||||||
|
.setDescription("The series id")
|
||||||
|
.setRequired(true)))
|
||||||
|
.addSubcommand(x =>
|
||||||
|
x
|
||||||
|
.setName("list")
|
||||||
|
.setDescription("List all series")) as SlashCommandBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async execute(interaction: CommandInteraction) {
|
||||||
|
if (!interaction.isChatInputCommand()) return;
|
||||||
|
|
||||||
|
switch (interaction.options.getSubcommand()) {
|
||||||
|
case "view":
|
||||||
|
await this.ViewSeries(interaction);
|
||||||
|
break;
|
||||||
|
case "list":
|
||||||
|
await this.ListSeries(interaction);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AppLogger.LogWarn("Commands/Series", `Subcommand doesn't exist: ${interaction.options.getSubcommand()}`);
|
||||||
|
await interaction.reply("Subcommand doesn't exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ViewSeries(interaction: CommandInteraction) {
|
||||||
|
const id = interaction.options.get("id");
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Commands/Series/View", `Parameters: id=${id?.value}`);
|
||||||
|
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
const series = CoreClient.Cards.find(x => x.id == id.value);
|
||||||
|
|
||||||
|
if (!series) {
|
||||||
|
AppLogger.LogVerbose("Commands/Series/View", "Series not found.");
|
||||||
|
|
||||||
|
await interaction.reply("Series not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = SeriesHelper.GenerateSeriesViewPage(series.id, 0);
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [ embed!.embed ], components: [ embed!.row ]});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ListSeries(interaction: CommandInteraction) {
|
||||||
|
const embed = SeriesHelper.GenerateSeriesListPage(0);
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [ embed!.embed ], components: [ embed!.row ]});
|
||||||
|
}
|
||||||
|
}
|
148
src/commands/trade.ts
Normal file
148
src/commands/trade.ts
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
|
||||||
|
import { Command } from "../type/command";
|
||||||
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
|
import { CoreClient } from "../client/client";
|
||||||
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
|
export default class Trade extends Command {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.CommandBuilder = new SlashCommandBuilder()
|
||||||
|
.setName("trade")
|
||||||
|
.setDescription("Initiate a trade with another user.")
|
||||||
|
.addUserOption(x =>
|
||||||
|
x
|
||||||
|
.setName("user")
|
||||||
|
.setDescription("User to trade with")
|
||||||
|
.setRequired(true))
|
||||||
|
.addStringOption(x =>
|
||||||
|
x
|
||||||
|
.setName("give")
|
||||||
|
.setDescription("Item to give")
|
||||||
|
.setRequired(true))
|
||||||
|
.addStringOption(x =>
|
||||||
|
x
|
||||||
|
.setName("receive")
|
||||||
|
.setDescription("Item to receive")
|
||||||
|
.setRequired(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async execute(interaction: CommandInteraction) {
|
||||||
|
const user = interaction.options.getUser("user")!;
|
||||||
|
const give = interaction.options.get("give")!;
|
||||||
|
const receive = interaction.options.get("receive")!;
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Commands/Trade", `Parameters: user=${user.id}, give=${give.value}, receive=${receive.value}`);
|
||||||
|
|
||||||
|
const giveItemEntity = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, give.value!.toString());
|
||||||
|
const receiveItemEntity = await Inventory.FetchOneByCardNumberAndUserId(user.id, receive.value!.toString());
|
||||||
|
|
||||||
|
if (!giveItemEntity) {
|
||||||
|
await interaction.reply("You do not have the item you are trying to trade.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!receiveItemEntity) {
|
||||||
|
await interaction.reply("The user you are trying to trade with does not have the item you are trying to trade for.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === give.value!.toString());
|
||||||
|
|
||||||
|
const receiveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === receive.value!.toString());
|
||||||
|
|
||||||
|
if (!giveItem || !receiveItem) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const expiry = now.setMinutes(now.getMinutes() + 15);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("⚠️ Trade Offer ⚠️")
|
||||||
|
.setDescription(`Trade initiated between ${interaction.user.username} and ${user.username}`)
|
||||||
|
.setColor(EmbedColours.Grey)
|
||||||
|
.setImage("https://media1.tenor.com/m/KkZwKl2AQ2QAAAAd/trade-offer.gif")
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: "I Receive",
|
||||||
|
value: `${receiveItem.id}: ${receiveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "You Receive",
|
||||||
|
value: `${giveItem.id}: ${giveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Expires",
|
||||||
|
value: new Date(expiry).toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const timeoutId = setTimeout(async () => this.autoDecline(interaction, interaction.user.username, user.username, giveItem.id, receiveItem.id, giveItem.name, receiveItem.name), 1000 * 60 * 15); // 15 minutes
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`trade accept ${interaction.user.id} ${user.id} ${giveItem.id} ${receiveItem.id} ${expiry} ${timeoutId}`)
|
||||||
|
.setLabel("Accept")
|
||||||
|
.setStyle(ButtonStyle.Success),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`trade decline ${interaction.user.id} ${user.id} ${giveItem.id} ${receiveItem.id} ${expiry} ${timeoutId}`)
|
||||||
|
.setLabel("Decline")
|
||||||
|
.setStyle(ButtonStyle.Danger),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.reply({ content: `${user}`, embeds: [ tradeEmbed ], components: [ row ] });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async autoDecline(interaction: CommandInteraction, giveUsername: string, receiveUsername: string, giveCardNumber: string, receiveCardNumber: string, giveCardName: string, receiveCardName: string) {
|
||||||
|
AppLogger.LogSilly("Commands/Trade/AutoDecline", `Auto declining trade between ${giveUsername} and ${receiveUsername}`);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Expired")
|
||||||
|
.setDescription(`Trade initiated between ${receiveUsername} and ${giveUsername}`)
|
||||||
|
.setColor(EmbedColours.Error)
|
||||||
|
.setImage("https://media1.tenor.com/m/KkZwKl2AQ2QAAAAd/trade-offer.gif")
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: "I Receive",
|
||||||
|
value: `${receiveCardNumber}: ${receiveCardName}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "You Receive",
|
||||||
|
value: `${giveCardNumber}: ${giveCardName}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Expired",
|
||||||
|
value: new Date().toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("trade expired accept")
|
||||||
|
.setLabel("Accept")
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
.setDisabled(true),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("trade expired declined")
|
||||||
|
.setLabel("Decline")
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
.setDisabled(true),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [ tradeEmbed ], components: [ row ]});
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import { readFileSync } from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import Inventory from "../database/entities/app/Inventory";
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class View extends Command {
|
export default class View extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -23,6 +24,8 @@ export default class View extends Command {
|
||||||
public override async execute(interaction: CommandInteraction) {
|
public override async execute(interaction: CommandInteraction) {
|
||||||
const cardNumber = interaction.options.get("cardnumber");
|
const cardNumber = interaction.options.get("cardnumber");
|
||||||
|
|
||||||
|
AppLogger.LogSilly("Commands/View", `Parameters: cardNumber=${cardNumber?.value}`);
|
||||||
|
|
||||||
if (!cardNumber || !cardNumber.value) {
|
if (!cardNumber || !cardNumber.value) {
|
||||||
await interaction.reply("Card number is required.");
|
await interaction.reply("Card number is required.");
|
||||||
return;
|
return;
|
||||||
|
@ -46,6 +49,8 @@ export default class View extends Command {
|
||||||
try {
|
try {
|
||||||
image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path));
|
image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path));
|
||||||
} catch {
|
} catch {
|
||||||
|
AppLogger.LogError("Commands/View", `Unable to fetch image for card ${card.id}.`);
|
||||||
|
|
||||||
await interaction.reply(`Unable to fetch image for card ${card.id}.`);
|
await interaction.reply(`Unable to fetch image for card ${card.id}.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +70,7 @@ export default class View extends Command {
|
||||||
files: [ attachment ],
|
files: [ attachment ],
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
AppLogger.LogError("Commands/View", `Error sending view for card ${card.id}: ${e}`);
|
||||||
|
|
||||||
if (e instanceof DiscordAPIError) {
|
if (e instanceof DiscordAPIError) {
|
||||||
await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. Code: ${e.code}.`);
|
await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. Code: ${e.code}.`);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export default class EmbedColours {
|
export default class EmbedColours {
|
||||||
public static readonly Ok = 0x3050ba;
|
public static readonly Ok = 0x3050ba;
|
||||||
|
public static readonly Success = 0x50c878;
|
||||||
public static readonly Error = 0xff0000;
|
public static readonly Error = 0xff0000;
|
||||||
public static readonly Grey = 0xd3d3d3;
|
public static readonly Grey = 0xd3d3d3;
|
||||||
public static readonly BronzeCard = 0xcd7f32;
|
public static readonly BronzeCard = 0xcd7f32;
|
||||||
|
|
19
src/database/entities/app/User.ts
Normal file
19
src/database/entities/app/User.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { Column, Entity } from "typeorm";
|
||||||
|
import AppBaseEntity from "../../../contracts/AppBaseEntity";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export default class User extends AppBaseEntity {
|
||||||
|
constructor(userId: string, currency: number) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.Id = userId;
|
||||||
|
this.Currency = currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
Currency: number;
|
||||||
|
|
||||||
|
public UpdateCurrency(currency: number) {
|
||||||
|
this.Currency = currency;
|
||||||
|
}
|
||||||
|
}
|
15
src/database/migrations/app/0.6/1713289062969-user.ts
Normal file
15
src/database/migrations/app/0.6/1713289062969-user.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
import MigrationHelper from "../../../../helpers/MigrationHelper";
|
||||||
|
|
||||||
|
export class User1713289062969 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
MigrationHelper.Up("1713289062969-user", "0.6", [
|
||||||
|
"01-table/User",
|
||||||
|
], queryRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(): Promise<void> {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
|
||||||
import { CardRarity, CardRarityToColour, CardRarityToString } from "../constants/CardRarity";
|
import { CardRarity, CardRarityToColour, CardRarityToString } from "../constants/CardRarity";
|
||||||
import CardRarityChances from "../constants/CardRarityChances";
|
import CardRarityChances from "../constants/CardRarityChances";
|
||||||
import { CardMetadata, DropResult } from "../contracts/SeriesMetadata";
|
import { DropResult } from "../contracts/SeriesMetadata";
|
||||||
import { CoreClient } from "../client/client";
|
import { CoreClient } from "../client/client";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default class CardDropHelperMetadata {
|
export default class CardDropHelperMetadata {
|
||||||
public static GetRandomCard(): DropResult | undefined {
|
public static GetRandomCard(): DropResult | undefined {
|
||||||
|
@ -23,10 +24,14 @@ export default class CardDropHelperMetadata {
|
||||||
|
|
||||||
const randomCard = this.GetRandomCardByRarity(cardRarity);
|
const randomCard = this.GetRandomCardByRarity(cardRarity);
|
||||||
|
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCard", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`);
|
||||||
|
|
||||||
return randomCard;
|
return randomCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GetRandomCardByRarity(rarity: CardRarity): DropResult | undefined {
|
public static GetRandomCardByRarity(rarity: CardRarity): DropResult | undefined {
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Parameters: rarity=${rarity}`);
|
||||||
|
|
||||||
const allCards = CoreClient.Cards
|
const allCards = CoreClient.Cards
|
||||||
.flatMap(x => x.cards)
|
.flatMap(x => x.cards)
|
||||||
.filter(x => x.type == rarity);
|
.filter(x => x.type == rarity);
|
||||||
|
@ -38,28 +43,53 @@ export default class CardDropHelperMetadata {
|
||||||
.find(x => x.cards.includes(card));
|
.find(x => x.cards.includes(card));
|
||||||
|
|
||||||
if (!series) {
|
if (!series) {
|
||||||
|
AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`);
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Random card: ${card.id} ${card.name}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
series: series,
|
series: series,
|
||||||
card: card,
|
card: card,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GetCardByCardNumber(cardNumber: string): CardMetadata | undefined {
|
public static GetCardByCardNumber(cardNumber: string): DropResult | undefined {
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Parameters: cardNumber=${cardNumber}`);
|
||||||
|
|
||||||
const card = CoreClient.Cards
|
const card = CoreClient.Cards
|
||||||
.flatMap(x => x.cards)
|
.flatMap(x => x.cards)
|
||||||
.find(x => x.id == cardNumber);
|
.find(x => x.id == cardNumber);
|
||||||
|
|
||||||
return card;
|
const series = CoreClient.Cards
|
||||||
|
.find(x => x.cards.find(y => y.id == card?.id));
|
||||||
|
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Card: ${card?.id} ${card?.name}`);
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Series: ${series?.id} ${series?.name}`);
|
||||||
|
|
||||||
|
if (!card || !series) {
|
||||||
|
AppLogger.LogVerbose("CardDropHelperMetadata/GetCardByCardNumber", `Unable to find card metadata: ${cardNumber}`);
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string): EmbedBuilder {
|
return { card, series };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string): EmbedBuilder {
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropEmbed", `Parameters: drop=${drop.card.id}, quantityClaimed=${quantityClaimed}, imageFileName=${imageFileName}`);
|
||||||
|
|
||||||
let description = "";
|
let description = "";
|
||||||
description += `Series: ${drop.series.name}\n`;
|
description += `Series: ${drop.series.name}\n`;
|
||||||
description += `Claimed: ${quantityClaimed}\n`;
|
description += `Claimed: ${quantityClaimed}\n`;
|
||||||
|
|
||||||
|
if (claimedBy != null) {
|
||||||
|
description += `Claimed by: ${claimedBy}\n`;
|
||||||
|
} else {
|
||||||
|
description += "Claimed by: (UNCLAIMED)\n";
|
||||||
|
}
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return new EmbedBuilder()
|
||||||
.setTitle(drop.card.name)
|
.setTitle(drop.card.name)
|
||||||
.setDescription(description)
|
.setDescription(description)
|
||||||
|
@ -68,13 +98,16 @@ export default class CardDropHelperMetadata {
|
||||||
.setImage(`attachment://${imageFileName}`);
|
.setImage(`attachment://${imageFileName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GenerateDropButtons(drop: DropResult, claimId: string, userId: string): ActionRowBuilder<ButtonBuilder> {
|
public static GenerateDropButtons(drop: DropResult, claimId: string, userId: string, disabled: boolean = false): ActionRowBuilder<ButtonBuilder> {
|
||||||
|
AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropButtons", `Parameters: drop=${drop.card.id}, claimId=${claimId}, userId=${userId}`);
|
||||||
|
|
||||||
return new ActionRowBuilder<ButtonBuilder>()
|
return new ActionRowBuilder<ButtonBuilder>()
|
||||||
.addComponents(
|
.addComponents(
|
||||||
new ButtonBuilder()
|
new ButtonBuilder()
|
||||||
.setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`)
|
.setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`)
|
||||||
.setLabel("Claim")
|
.setLabel("Claim")
|
||||||
.setStyle(ButtonStyle.Primary),
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(disabled),
|
||||||
new ButtonBuilder()
|
new ButtonBuilder()
|
||||||
.setCustomId("reroll")
|
.setCustomId("reroll")
|
||||||
.setLabel("Reroll")
|
.setLabel("Reroll")
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { CoreClient } from "../client/client";
|
||||||
import EmbedColours from "../constants/EmbedColours";
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
import { CardRarity, CardRarityToString } from "../constants/CardRarity";
|
import { CardRarity, CardRarityToString } from "../constants/CardRarity";
|
||||||
import cloneDeep from "clone-deep";
|
import cloneDeep from "clone-deep";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
interface InventoryPage {
|
interface InventoryPage {
|
||||||
id: number,
|
id: number,
|
||||||
|
@ -21,6 +22,8 @@ interface InventoryPageCards {
|
||||||
|
|
||||||
export default class InventoryHelper {
|
export default class InventoryHelper {
|
||||||
public static async GenerateInventoryPage(username: string, userid: string, page: number): Promise<{ embed: EmbedBuilder, row: ActionRowBuilder<ButtonBuilder> }> {
|
public static async GenerateInventoryPage(username: string, userid: string, page: number): Promise<{ embed: EmbedBuilder, row: ActionRowBuilder<ButtonBuilder> }> {
|
||||||
|
AppLogger.LogSilly("Helpers/InventoryHelper", `Parameters: username=${username}, userid=${userid}, page=${page}`);
|
||||||
|
|
||||||
const cardsPerPage = 15;
|
const cardsPerPage = 15;
|
||||||
|
|
||||||
const inventory = await Inventory.FetchAllByUserId(userid);
|
const inventory = await Inventory.FetchAllByUserId(userid);
|
||||||
|
@ -73,7 +76,7 @@ export default class InventoryHelper {
|
||||||
const currentPage = pages[page];
|
const currentPage = pages[page];
|
||||||
|
|
||||||
if (!currentPage) {
|
if (!currentPage) {
|
||||||
console.error("Unable to find page");
|
AppLogger.LogError("Helpers/InventoryHelper", "Unable to find page");
|
||||||
return Promise.reject("Unable to find page");
|
return Promise.reject("Unable to find page");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
99
src/helpers/SeriesHelper.ts
Normal file
99
src/helpers/SeriesHelper.ts
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
import cloneDeep from "clone-deep";
|
||||||
|
import { CoreClient } from "../client/client";
|
||||||
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
|
import { CardRarityToString } from "../constants/CardRarity";
|
||||||
|
|
||||||
|
export default class SeriesHelper {
|
||||||
|
public static GenerateSeriesViewPage(seriesId: number, page: number): { embed: EmbedBuilder, row: ActionRowBuilder<ButtonBuilder> } | null {
|
||||||
|
AppLogger.LogSilly("Helpers/SeriesHelper", `Parameters: seriesId=${seriesId}, page=${page}`);
|
||||||
|
|
||||||
|
const itemsPerPage = 15;
|
||||||
|
|
||||||
|
const series = cloneDeep(CoreClient.Cards)
|
||||||
|
.find(x => x.id == seriesId);
|
||||||
|
|
||||||
|
if (!series) {
|
||||||
|
AppLogger.LogVerbose("Helpers/SeriesHelper", `Unable to find series: ${seriesId}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(series.cards.length / itemsPerPage);
|
||||||
|
|
||||||
|
if (page > totalPages) {
|
||||||
|
AppLogger.LogVerbose("Helpers/SeriesHelper", `Trying to find page greater than what exists for this series. Page: ${page} but there are only ${totalPages} pages`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardsOnPage = series.cards.splice(page * itemsPerPage, itemsPerPage);
|
||||||
|
|
||||||
|
const description = cardsOnPage
|
||||||
|
.map(x => `[${x.id}] ${x.name} ${CardRarityToString(x.type).toUpperCase()}`)
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(series.name)
|
||||||
|
.setColor(EmbedColours.Ok)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: `${series.id} · ${series.cards.length} cards · Page ${page + 1} of ${totalPages}` });
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`series view ${seriesId} ${page - 1}`)
|
||||||
|
.setLabel("Previous")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(page == 0),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`series view ${seriesId} ${page + 1}`)
|
||||||
|
.setLabel("Next")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(page + 1 > totalPages));
|
||||||
|
|
||||||
|
return { embed, row };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GenerateSeriesListPage(page: number): { embed: EmbedBuilder, row: ActionRowBuilder<ButtonBuilder> } | null {
|
||||||
|
AppLogger.LogSilly("Helpers/InventoryHelper", `Parameters: page=${page}`);
|
||||||
|
|
||||||
|
const itemsPerPage = 15;
|
||||||
|
|
||||||
|
const series = cloneDeep(CoreClient.Cards)
|
||||||
|
.sort((a, b) => a.id - b.id);
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(series.length / itemsPerPage);
|
||||||
|
|
||||||
|
if (page > totalPages) {
|
||||||
|
AppLogger.LogVerbose("Helpers/SeriesHelper", `Trying to find page greater than what exists for this series. Page: ${page} but there are only ${totalPages} pages`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const seriesOnPage = series.splice(page * itemsPerPage, itemsPerPage);
|
||||||
|
|
||||||
|
const description = seriesOnPage
|
||||||
|
.map(x => `[${x.id}] ${x.name}`)
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle("Series")
|
||||||
|
.setColor(EmbedColours.Ok)
|
||||||
|
.setDescription(description)
|
||||||
|
.setFooter({ text: `${CoreClient.Cards.length} series · Page ${page + 1} of ${totalPages}` });
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`series list ${page - 1}`)
|
||||||
|
.setLabel("Previous")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(page == 0),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`series list ${page + 1}`)
|
||||||
|
.setLabel("Next")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(page + 1 > totalPages));
|
||||||
|
|
||||||
|
return { embed, row };
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
import CardMetadataFunction from "../Functions/CardMetadataFunction";
|
||||||
|
import AppLogger from "../client/appLogger";
|
||||||
|
|
||||||
export default async function ReloadDB(req: Request, res: Response) {
|
export default async function ReloadDB(req: Request, res: Response) {
|
||||||
console.log("Reloading Card DB...");
|
AppLogger.LogInfo("Hooks/ReloadDB", "Reloading Card DB...");
|
||||||
|
|
||||||
await CardMetadataFunction.Execute();
|
await CardMetadataFunction.Execute();
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import Gdrivesync from "./commands/gdrivesync";
|
||||||
import Give from "./commands/give";
|
import Give from "./commands/give";
|
||||||
import Inventory from "./commands/inventory";
|
import Inventory from "./commands/inventory";
|
||||||
import Resync from "./commands/resync";
|
import Resync from "./commands/resync";
|
||||||
|
import Series from "./commands/series";
|
||||||
|
import Trade from "./commands/trade";
|
||||||
import View from "./commands/view";
|
import View from "./commands/view";
|
||||||
|
|
||||||
// Test Command Imports
|
// Test Command Imports
|
||||||
|
@ -18,6 +20,8 @@ import Droprarity from "./commands/stage/droprarity";
|
||||||
import Claim from "./buttonEvents/Claim";
|
import Claim from "./buttonEvents/Claim";
|
||||||
import InventoryButtonEvent from "./buttonEvents/Inventory";
|
import InventoryButtonEvent from "./buttonEvents/Inventory";
|
||||||
import Reroll from "./buttonEvents/Reroll";
|
import Reroll from "./buttonEvents/Reroll";
|
||||||
|
import SeriesEvent from "./buttonEvents/Series";
|
||||||
|
import TradeButtonEvent from "./buttonEvents/Trade";
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
public static RegisterCommands() {
|
public static RegisterCommands() {
|
||||||
|
@ -28,6 +32,8 @@ export default class Registry {
|
||||||
CoreClient.RegisterCommand("give", new Give());
|
CoreClient.RegisterCommand("give", new Give());
|
||||||
CoreClient.RegisterCommand("inventory", new Inventory());
|
CoreClient.RegisterCommand("inventory", new Inventory());
|
||||||
CoreClient.RegisterCommand("resync", new Resync());
|
CoreClient.RegisterCommand("resync", new Resync());
|
||||||
|
CoreClient.RegisterCommand("series", new Series());
|
||||||
|
CoreClient.RegisterCommand("trade", new Trade());
|
||||||
CoreClient.RegisterCommand("view", new View());
|
CoreClient.RegisterCommand("view", new View());
|
||||||
|
|
||||||
// Test Commands
|
// Test Commands
|
||||||
|
@ -41,7 +47,9 @@ export default class Registry {
|
||||||
|
|
||||||
public static RegisterButtonEvents() {
|
public static RegisterButtonEvents() {
|
||||||
CoreClient.RegisterButtonEvent("claim", new Claim());
|
CoreClient.RegisterButtonEvent("claim", new Claim());
|
||||||
CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent);
|
CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent());
|
||||||
CoreClient.RegisterButtonEvent("reroll", new Reroll());
|
CoreClient.RegisterButtonEvent("reroll", new Reroll());
|
||||||
|
CoreClient.RegisterButtonEvent("series", new SeriesEvent());
|
||||||
|
CoreClient.RegisterButtonEvent("trade", new TradeButtonEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import bodyParser from "body-parser";
|
import bodyParser from "body-parser";
|
||||||
import express, { Application } from "express";
|
import express, { Application } from "express";
|
||||||
import ReloadDB from "./hooks/ReloadDB";
|
import ReloadDB from "./hooks/ReloadDB";
|
||||||
|
import AppLogger from "./client/appLogger";
|
||||||
|
|
||||||
export default class Webhooks {
|
export default class Webhooks {
|
||||||
private app: Application;
|
private app: Application;
|
||||||
|
@ -24,7 +25,7 @@ export default class Webhooks {
|
||||||
|
|
||||||
private setupListen() {
|
private setupListen() {
|
||||||
this.app.listen(this.port, () => {
|
this.app.listen(this.port, () => {
|
||||||
console.log(`API listening on port ${this.port}`);
|
AppLogger.LogInfo("Webhooks", `API listening on port ${this.port}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue