102 Commits

Author SHA1 Message Date
6b5b8bb54f add deprecation notice
All checks were successful
Publish / docker (push) Successful in 1m59s
2023-11-05 23:17:44 +00:00
403c34befd Merge branch 'main' of https://git.fascinated.cc/Fascinated/beatsaber-overlay
All checks were successful
Publish / docker (push) Successful in 2m31s
2023-10-31 11:44:53 +00:00
0185a9ed3e silly mee 2023-10-31 11:44:50 +00:00
47a255e48a fix proxy 2023-10-31 11:44:27 +00:00
Lee
69f763cdb0 Merge pull request 'chore(deps): update docker/setup-buildx-action action to v3' (#10) from renovate/docker-setup-buildx-action-3.x into main
All checks were successful
Publish / docker (push) Successful in 1m38s
Reviewed-on: #10
2023-10-15 23:21:40 +00:00
Lee
cd6f550035 Merge pull request 'chore(deps): update docker/login-action action to v3' (#9) from renovate/docker-login-action-3.x into main
Some checks are pending
Publish / docker (push) Waiting to run
Reviewed-on: #9
2023-10-15 23:21:33 +00:00
ab7d5f909c chore(deps): update docker/setup-buildx-action action to v3 2023-10-15 04:01:19 +00:00
918da6f88b hahaball
All checks were successful
Publish / docker (push) Successful in 1m53s
2023-10-15 04:30:41 +01:00
1ea19aff4b my dick is wet
All checks were successful
Publish / docker (push) Successful in 1m59s
2023-10-15 04:27:37 +01:00
a34de0aa93 huehoiqw
All checks were successful
Publish / docker (push) Successful in 1m53s
2023-10-15 04:23:19 +01:00
a9b7d65c20 7.777
All checks were successful
Publish / docker (push) Successful in 3m44s
2023-10-15 04:16:35 +01:00
6ef4eac93c 7.77
Some checks failed
Publish / docker (push) Failing after 1m46s
2023-10-15 04:12:26 +01:00
acc107baff 77
Some checks failed
Publish / docker (push) Failing after 1m57s
2023-10-15 04:07:36 +01:00
a504051d7f 7
Some checks failed
Publish / docker (push) Failing after 1m36s
2023-10-15 04:04:00 +01:00
e3861c1a47 chore(deps): update docker/login-action action to v3 2023-10-15 03:01:40 +00:00
e7206883d9 fix building
Some checks failed
Publish / docker (push) Failing after 1m53s
2023-10-15 04:01:23 +01:00
324f4ef0e2 fix depends
Some checks failed
Publish / docker (push) Failing after 32s
2023-10-15 03:59:34 +01:00
393ecf0c3f fix caching
Some checks failed
Publish / docker (push) Failing after 1m46s
2023-10-15 03:45:42 +01:00
3a69316f64 fix nextui depends
Some checks failed
Publish / docker (push) Failing after 55s
2023-10-15 03:44:06 +01:00
Lee
61b1b4194e Merge pull request 'fix(deps): update dependency @nextui-org/react to v1.0.0-beta.9-dbg2' (#4) from renovate/nextui-org-react-1.x-lockfile into main
All checks were successful
Publish / docker (push) Successful in 2m32s
Reviewed-on: #4
2023-10-15 02:31:29 +00:00
Lee
6e777c5be5 Merge pull request 'chore(deps): update actions/checkout action to v4' (#6) from renovate/actions-checkout-4.x into main
Some checks are pending
Publish / docker (push) Waiting to run
Reviewed-on: #6
2023-10-15 02:21:46 +00:00
Lee
595f7fdfe2 Merge pull request 'chore(deps): update docker/build-push-action action to v5' (#7) from renovate/docker-build-push-action-5.x into main
Some checks failed
Publish / docker (push) Has been cancelled
Reviewed-on: #7
2023-10-15 02:21:38 +00:00
Lee
0f57963155 Merge pull request 'chore(deps): update dependency @types/node to v20.8.6' (#3) from renovate/node-20.x-lockfile into main
Some checks failed
Publish / docker (push) Has been cancelled
Reviewed-on: #3
2023-10-15 02:21:13 +00:00
5467f31dd7 chore(deps): update docker/build-push-action action to v5 2023-10-15 02:10:19 +00:00
8127e43bf1 chore(deps): update actions/checkout action to v4 2023-10-15 02:10:17 +00:00
d7ff4fd9f5 fix(deps): update dependency @nextui-org/react to v1.0.0-beta.9-dbg2 2023-10-15 01:52:48 +00:00
0bed47986b chore(deps): update dependency @types/node to v20.8.6 2023-10-15 01:52:38 +00:00
Lee
d7773702bb Merge pull request 'Configure Renovate' (#2) from renovate/configure into main
All checks were successful
Publish / docker (push) Successful in 2m36s
Reviewed-on: #2
2023-10-15 01:51:21 +00:00
ad8d211ce8 chore(deps): add renovate.json 2023-10-15 01:45:56 +00:00
Lee
418ef17b73 update branch name in action
All checks were successful
Publish / docker (push) Successful in 2m58s
2023-10-11 23:02:02 +00:00
Lee
90f39bb409 Merge pull request 'feat: nodejs 20' (#1) from development into main
Some checks failed
Publish / docker (push) Has been cancelled
Reviewed-on: #1
2023-10-11 22:59:33 +00:00
37e60a8425 add dev branch to action
All checks were successful
Publish / docker (push) Successful in 2m44s
2023-10-11 23:40:09 +01:00
a55027ef68 update action tasks 2023-10-11 23:37:41 +01:00
4b3a991b91 update to nodejs 20 2023-10-11 23:35:39 +01:00
52d44d79c1 bump depends and fix building
All checks were successful
Publish / docker (push) Successful in 2m27s
2023-10-11 23:30:39 +01:00
3a49341a6a pls work
Some checks failed
Publish / docker (push) Failing after 1m28s
2023-10-11 23:19:12 +01:00
d3ae2761cd test
Some checks failed
Publish / docker (push) Has been cancelled
2023-10-11 23:13:38 +01:00
01be27b415 test
Some checks failed
Publish / docker (push) Has been cancelled
2023-10-11 23:13:10 +01:00
0e6e472ded test
Some checks failed
Publish / docker (push) Failing after 4s
2023-10-11 23:12:29 +01:00
7139163ba2 test
Some checks failed
Publish / docker (push) Failing after 20s
2023-10-11 23:11:48 +01:00
462535254d maybe fix
Some checks failed
Publish / docker (push) Failing after 9s
2023-10-10 15:39:30 +01:00
5871e9b662 update action
Some checks failed
Publish / docker (push) Failing after 33s
2023-10-10 15:30:53 +01:00
83d5193257 pls work
Some checks failed
Publish / docker (push) Failing after 19s
2023-10-09 22:52:50 +01:00
44e9687867 update depends
Some checks failed
Publish / docker (ubuntu-20.04, 2.38.4) (push) Failing after 26s
2023-10-09 22:50:47 +01:00
bced89d1ec fix action
Some checks failed
Publish / docker (ubuntu-20.04, 2.38.4) (push) Failing after 5s
2023-10-08 16:42:08 +01:00
884d3df8ec fix build action
Some checks failed
Publish / docker (ubuntu-20.04, 2.38.4) (push) Failing after 1s
2023-09-25 02:11:32 +01:00
d001590405 bump depends
Some checks are pending
Publish / docker (ubuntu-latest, 2.38.4) (push) Waiting to run
2023-09-25 02:08:38 +01:00
529f6d38b3 remove spacer
All checks were successful
Publish / docker (ubuntu-latest, 2.38.4) (push) Successful in 2m37s
2023-04-18 11:47:28 +01:00
75d6429379 fix SEO
All checks were successful
Publish / docker (ubuntu-latest, 2.38.4) (push) Successful in 2m36s
2023-04-18 11:46:45 +01:00
4dce461cd9 bump depends
All checks were successful
Publish / docker (ubuntu-latest, 2.38.4) (push) Successful in 3m36s
2023-04-14 20:14:51 +01:00
2cd1efbd1d update git msg
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-04-10 15:29:13 +01:00
9d2cf79372 update depends
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-04-09 17:06:20 +01:00
ea843e475c Update 'README.md'
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-03-28 04:02:31 +01:00
3b6b8389ae Delete '.drone.yml'
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-03-28 04:01:55 +01:00
07616aad0e fixes
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-03-27 22:49:22 +01:00
f809d61171 fixes
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 22:48:58 +01:00
57a97c6caf fixes
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 22:28:42 +01:00
33d5dfab3f fixes
Some checks are pending
docker (git.fascinated.cc/fascinated/gitea-runner:latest, 2.38.4)
2023-03-27 22:27:45 +01:00
885bf5c4b3 Merge branch 'main' of https://git.fascinated.cc/Fascinated/beatsaber-overlay
Some checks failed
docker (git.fascinated.cc/fascinated/gitea-runner:ubuntu-latest, 2.38.4)
2023-03-27 22:18:00 +01:00
1ad54694a9 fixes 2023-03-27 22:17:49 +01:00
b7b5823d99 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (git.fascinated.cc/fascinated/gitea-runner:ubuntu-latest, 2.38.4)
2023-03-27 22:16:02 +01:00
d2f63c6dc5 Merge branch 'main' of https://git.fascinated.cc/Fascinated/beatsaber-overlay
Some checks failed
docker (git.fascinated.cc/fascinated/gitea-runner:ubuntu-latest, 2.38.4)
2023-03-27 22:03:41 +01:00
c6db350393 update image location 2023-03-27 22:03:26 +01:00
b9bd7f8e85 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (git.fascinated.cc/fascinated/gitea-runner:ubuntu-latest, 2.38.4)
2023-03-27 22:00:45 +01:00
35e2ccd402 Update '.gitea/workflows/publish.yaml'
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-03-27 21:17:10 +01:00
23cd272c3c Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 21:13:13 +01:00
d84122da3a Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 21:11:43 +01:00
190c19f238 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 21:09:48 +01:00
34c17ea167 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 21:05:26 +01:00
3b0f7e3ef2 Update '.gitea/workflows/publish.yaml'
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:59:11 +01:00
42192e7885 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:57:36 +01:00
8f86710cb6 Update '.gitea/workflows/publish.yaml'
Some checks are pending
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:56:46 +01:00
f013d49c7a Update '.gitea/workflows/publish.yaml'
All checks were successful
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:45:14 +01:00
8737f88145 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:43:26 +01:00
3e4c1ff437 Update '.gitea/workflows/publish.yaml'
Some checks are pending
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:38:28 +01:00
40c65e4d88 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:36:38 +01:00
6eb3ead4c9 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:34:52 +01:00
7013bb4e09 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:33:41 +01:00
9f8f6001b8 Update '.gitea/workflows/publish.yaml'
Some checks are pending
docker (ubuntu-latest, 2.38.4)
2023-03-27 20:25:22 +01:00
af7f5a6de2 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4, 1.20)
2023-03-27 20:23:30 +01:00
7aa8724ba1 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker (ubuntu-latest, 2.38.4, 1.19)
docker (arm-ubuntu-latest, 2.38.4, 1.19)
docker (arm-ubuntu-latest, 2.38.4, 1.20)
docker (ubuntu-latest, 2.38.4, 1.20)
2023-03-27 20:23:06 +01:00
7443e38033 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 20:22:02 +01:00
b3a2a943e7 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 20:18:25 +01:00
cfdf052e25 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 19:35:37 +01:00
fa9b44aebd Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 19:24:44 +01:00
cea026adb6 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 19:22:04 +01:00
a18a77d198 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 19:19:05 +01:00
caa10915a8 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 19:14:19 +01:00
42ff5305f5 Update '.gitea/workflows/publish.yaml' 2023-03-27 19:11:50 +01:00
e12a6513cb Update '.gitea/workflows/publish.yaml' 2023-03-27 19:10:49 +01:00
a2357c6469 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
2023-03-27 19:10:34 +01:00
03f8ef04de Update '.gitea/workflows/publish.yaml' 2023-03-27 19:08:11 +01:00
a0e7901feb Update '.gitea/workflows/publish.yaml'
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-27 19:05:53 +01:00
78cb587464 Update '.gitea/workflows/publish.yaml'
Some checks failed
docker
continuous-integration/drone/push Build is failing
2023-03-27 18:54:56 +01:00
61afc15409 Add '.gitea/workflows/publish.yaml'
Some checks failed
continuous-integration/drone/push Build is failing
docker
2023-03-27 18:36:44 +01:00
67525b4cc7 Update '.drone.yml'
Some checks are pending
continuous-integration/drone/push Build is running
2023-03-27 18:29:04 +01:00
4d373228f2 Update 'README.md' 2023-03-27 17:58:55 +01:00
7f4a1ea56c update overlay img
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-27 16:23:48 +01:00
334c788318 Update 'README.md'
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-27 16:13:42 +01:00
faa314960f fix error when showing pp
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-27 16:08:57 +01:00
6f0fdb3778 added alt and fixed wrong logos showing
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-27 15:58:20 +01:00
0ae09dc3e8 remove gitea actions
Some checks are pending
continuous-integration/drone/push Build is running
2023-03-27 15:53:51 +01:00
28 changed files with 6410 additions and 15607 deletions

View File

@ -1,15 +0,0 @@
name: Gitea Actions Demo
run-name: ${{ github.actor }} is testing out Gitea Actions
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-20.04
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "This job is now running on a ${{ runner.os }} server hosted by Gitea!"
- run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "The workflow is now ready to test your code on the runner."
- run: echo "This job's status is ${{ job.status }}."

View File

@ -1,71 +0,0 @@
kind: pipeline
type: docker
name: default
steps:
- name: restore-cache
image: drillster/drone-volume-cache
volumes:
- name: cache
path: /cache
settings:
restore: true
mount:
- ./node_modules
- name: install depends
image: node:18
commands:
- npm install
- name: rebuild-cache
image: drillster/drone-volume-cache
volumes:
- name: cache
path: /cache
settings:
rebuild: true
mount:
- ./node_modules
# Other branches
- name: test
image: node:18
when:
branch:
exclude:
- main
commands:
- npm run lint
# Main branches
- name: docker
image: plugins/docker
when:
branch:
- main
settings:
username:
from_secret: dockerhub_username
password:
from_secret: dockerhub_password
repo: fascinated/beatsaber-overlay
tags: latest
volumes:
- name: cache
host:
path: /tmp/cache
# deploy:
# image: alpine:latest
# stage: deploy
# tags:
# script:
# - chmod og= $ID_RSA
# - apk update && apk add openssh-client
# - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "cd /home/overlay && docker compose pull && docker compose up -d && docker image prune -f"
# environment:
# name: production
# url: https://bs-overlay.fascinated.cc
# only:
# - main

View File

@ -1,12 +1,12 @@
REACT_APP_HTTP_PROXY=https://proxy.fascinated.cc
REACT_APP_HTTP_PROXY=<https://proxy.fascinated.cc>
REACT_APP_SITE_NAME=BeatSaber Overlay
REACT_APP_SITE_TITLE=BeatSaber Overlay - Simple and easy to use BeatSaber overlay
REACT_APP_SITE_DESCRIPTION=ScoreSaber and BeatLeader overlay for Twitch streamers - Elevate your Beat Saber streams with our professional, customizable overlay that displays your real-time scores, rankings, and leaderboard information for your viewers.
REACT_APP_SITE_COLOR=0EBFE9
REACT_APP_SITE_URL=http://localhost:3000
REACT_APP_SITE_URL=<http://localhost:3000>
REDIS_PORT=6379
REDIS_HOST=localhost
REDIS_PASSWORD=set me
REDIS_DATABASE=0
REDIS_DATABASE=0

View File

@ -1,3 +1,4 @@
{
"parser": "@babel/eslint-parser",
"extends": "next/core-web-vitals"
}

View File

@ -1,15 +1,58 @@
name: Gitea Actions Demo
run-name: ${{ github.actor }} is testing out Gitea Actions
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-20.04
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "This job is now running on a ${{ runner.os }} server hosted by Gitea!"
- run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "The workflow is now ready to test your code on the runner."
- run: echo "This job's status is ${{ job.status }}."
name: Publish
on:
push:
branches:
- "main"
- "development"
jobs:
docker:
runs-on: ubuntu-22.04
container: fascinated/docker-images:node-latest
steps:
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v7
- name: checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Repo
uses: docker/login-action@v3
with:
username: ${{ secrets.REPO_USERNAME }}
password: ${{ secrets.REPO_TOKEN }}
- name: Restore Docker Build Cache
uses: actions/cache@v3
id: build-cache
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx
- name: Build and Push (Latest)
uses: docker/build-push-action@v5
if: steps.branch-name.outputs.current_branch == 'main'
with:
push: true
context: .
tags: fascinated/beatsaber-overlay:latest
- name: Build and Push (Other Branches)
uses: docker/build-push-action@v5
if: steps.branch-name.outputs.current_branch != 'main'
with:
push: true
context: .
tags: fascinated/beatsaber-overlay:${{ steps.branch-name.outputs.current_branch }}
- name: Save Docker Build Cache
id: build-cache
uses: actions/cache/save@v3
with:
path: /tmp/.buildx-caches
key: ${{ runner.os }}-buildx

6
.gitignore vendored
View File

@ -4,6 +4,7 @@
/node_modules
/.pnp
.pnp.js
package-lock.json
# testing
/coverage
@ -37,4 +38,7 @@ yarn-error.log*
.vercel
# IntelliJ
.idea
.idea
# Ignore Yarn
yarn.lock

View File

@ -1,62 +1,39 @@
# Install dependencies only when needed
FROM node:19 AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
#RUN apk add libc6-compat
FROM fascinated/docker-images:node-pnpm-latest AS base
# Install depends
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json* pnpm-lock.yaml* ./
RUN pnpm install --production --frozen-lockfile --quiet
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
# Copy cached files
#COPY node_modules ./
#RUN npm i
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Rebuild the source code only when needed
FROM node:19 AS builder
# Build from source
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
RUN pnpm build
# Build the project
RUN yarn build
# Production image, copy all the files and run next
FROM node:19-alpine AS runner
# Run the app
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/next.config.js ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./.next/static
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./.next/static
RUN npm i -g @beam-australia/react-env
RUN chown -R nextjs:nodejs /app
USER nextjs
EXPOSE 3000
ENV HOSTNAME "0.0.0.0"
ENV PORT 3000
CMD npx react-env --env APP_ENV && yarn start
CMD npx react-env --env APP_ENV && pnpm start

View File

@ -1,10 +1,8 @@
# BeatSaber Overlay with real-time data from HttpSiraStatus
[![Build Status](https://drone.fascinated.cc/api/badges/Fascinated/beatsaber-overlay/status.svg)](https://drone.fascinated.cc/Fascinated/beatsaber-overlay)
The project is on my [Gitea](https://git.fascinated.cc/Fascinated/beatsaber-overlay) now, but the repo will be kept in sync here. <br />
The project is on my [Gitea](https://git.fascinated.cc/Fascinated/beatsaber-overlay) now, but the repo will be kept in sync on GitHub. <br />
The public url to view/use: <https://bs-overlay.fascinated.cc> <br />
Need help? Feel free to message me at: Fascinated#7668
Need help? Feel free to message me on Discord: Fascinated#7668 or Matrix: @fascinated:matrix.fascinated.cc
## Usage
@ -15,13 +13,6 @@ Go to the [Wiki](https://git.fascinated.cc/Fascinated/beatsaber-overlay/wiki/Usa
![Overlay](./assets/overlay.png)
![Builder Menu](./assets/builder.png)
## Todo
- Add toggle for showing pp
- Change the song time to a circular style in the song art
- Add overall stream stats (avg acc, misses, highest combo)
- Add option to scale the ui using css scale
## Getting started with developent
- Clone the repo

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

@ -1,6 +1,6 @@
services:
beatsaber-overlay:
image: fascinated/beatsaber-overlay:latest
image: git.fascinated.cc/fascinated/beatsaber-overlay:latest
restart: always
env_file:
- .env.production

11398
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +1,44 @@
{
"name": "beatsaber-overlay",
"private": true,
"scripts": {
"dev": "react-env -- next",
"build": "next build",
"start": "APP_ENV=production node server.js",
"lint": "next lint",
"update-depends": "npm-check -u"
},
"dependencies": {
"@beam-australia/react-env": "^3.1.1",
"@emotion/cache": "^11.10.5",
"@emotion/server": "^11.10.0",
"@nextui-org/react": "^1.0.0-beta.12",
"axios": "^1.3.4",
"core-js-pure": "^3.29.1",
"critters": "^0.0.16",
"ioredis": "^5.3.1",
"next": "^13.2.4",
"next-seo": "^5.15.0",
"next-themes": "^0.2.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-country-flag": "^3.0.2",
"react-dom": "^18.2.0",
"react-toastify": "^9.1.2",
"sharp": "^0.32.0",
"websocket": "^1.0.34",
"zustand": "^4.3.6"
},
"devDependencies": {
"@types/node": "^18.15.10",
"@types/react": "^18.0.29",
"@types/websocket": "^1.0.5",
"eslint": "^8.36.0",
"eslint-config-next": "^13.2.4",
"typescript": "^5.0.2"
}
"name": "beatsaber-overlay",
"private": true,
"scripts": {
"dev": "react-env -- next",
"build": "next build",
"start": "APP_ENV=production node server.js",
"lint": "next lint",
"update-depends": "npm-check -u"
},
"dependencies": {
"@babel/eslint-parser": "^7.22.15",
"@beam-australia/react-env": "^3.1.1",
"@emotion/cache": "^11.11.0",
"@emotion/server": "^11.11.0",
"@nextui-org/react": "1.0.0-beta.10",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"@typescript-eslint/parser": "^6.7.5",
"axios": "^1.5.1",
"core-js-pure": "^3.33.0",
"critters": "^0.0.20",
"ioredis": "^5.3.2",
"next": "^13.5.4",
"next-seo": "^6.1.0",
"next-themes": "^0.2.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-country-flag": "^3.1.0",
"react-dom": "^18.2.0",
"react-toastify": "^9.1.3",
"sharp": "^0.32.6",
"websocket": "^1.0.34",
"zustand": "^4.4.3"
},
"devDependencies": {
"@types/node": "^20.8.4",
"@types/react": "^18.2.28",
"@types/websocket": "^1.0.7",
"eslint": "^8.51.0",
"eslint-config-next": "^13.5.4",
"npm-check": "^6.0.1",
"typescript": "^5.2.2"
}
}

5817
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

6
renovate.json Normal file
View File

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>Fascinated/renovate-config"
]
}

View File

@ -2,19 +2,19 @@ import { Navbar, Text } from "@nextui-org/react";
import Settings from "./Settings";
const NavBar = (props) => {
return (
<Navbar isBordered variant={"sticky"}>
<Navbar.Brand>
<Text b color="inherit">
BeatSaber Overlay
</Text>
</Navbar.Brand>
return (
<Navbar isBordered variant={"sticky"}>
<Navbar.Brand>
<Text b color="inherit">
BeatSaber Overlay
</Text>
</Navbar.Brand>
<Navbar.Content>
<Settings {...props}></Settings>
</Navbar.Content>
</Navbar>
);
<Navbar.Content>
<Settings {...props}></Settings>
</Navbar.Content>
</Navbar>
);
};
export default NavBar;

View File

@ -61,13 +61,15 @@ export default function ScoreStats() {
width={30}
height={30}
src="https://cdn.fascinated.cc/Hc1eD7QY.png"
unoptimized
alt="BeatLeader logo"
></Image>
<p
style={{
marginLeft: "5px",
}}
>
{scoreSaberPP.toFixed(0)}pp
{scoreSaberPP.pp.toFixed(0)}pp
</p>
</div>
) : null}
@ -82,6 +84,8 @@ export default function ScoreStats() {
width={30}
height={30}
src="https://cdn.fascinated.cc/Wo9JRAfD.png"
unoptimized
alt="BeatLeader logo"
></Image>
<div>
{Object.entries(beatLeaderPP).map((value, i) => {

View File

@ -1,8 +1,8 @@
import {
Avatar as NextAvatar,
changeTheme,
Dropdown,
Avatar as NextAvatar,
Text,
changeTheme,
useTheme,
} from "@nextui-org/react";
@ -27,6 +27,7 @@ const Avatar = (props) => {
as="button"
color="primary"
src={avatarUrl}
alt="Account avatar"
/>
</Dropdown.Trigger>
<Dropdown.Menu aria-label="Static Actions">

View File

@ -5,17 +5,17 @@ import { BeatSaverMapData } from "../types/BeatSaverMapData";
import { getValue, setValue, valueExists } from "../utils/redisUtils";
const BEATSAVER_MAP_API =
env(VARS.HTTP_PROXY) + "/https://api.beatsaver.com/maps/hash/%s";
env(VARS.HTTP_PROXY) + "/https://api.beatsaver.com/maps/hash/%s";
const KEY = "BS_MAP_DATA_";
function getLatestMapArt(data: BeatSaverMapData) {
return data.versions[data.versions.length - 1].coverURL;
return data.versions[data.versions.length - 1].coverURL;
}
type MapData = {
bsr: string;
mapArt: string | undefined;
bsr: string;
mapArt: string | undefined;
};
/**
@ -25,34 +25,30 @@ type MapData = {
* @returns The map data
*/
export async function getMapData(hash: string): Promise<MapData | undefined> {
const mapHash = hash.replace("custom_level_", "").toLowerCase();
const mapHash = hash.replace("custom_level_", "").toLowerCase();
const key = `${KEY}${mapHash}`;
const exists = await valueExists(key);
if (exists) {
const data = await getValue(key);
return JSON.parse(data);
}
const key = `${KEY}${mapHash}`;
const exists = await valueExists(key);
if (exists) {
const data = await getValue(key);
return JSON.parse(data);
}
const before = Date.now();
const response = await axios.get(BEATSAVER_MAP_API.replace("%s", mapHash), {
headers: {
"X-Requested-With": "BeatSaber Overlay",
},
});
if (response.status === 404) {
return undefined;
}
const jsonResponse = response.data;
const json = {
bsr: jsonResponse.id,
mapArt: getLatestMapArt(jsonResponse),
};
await setValue(key, JSON.stringify(json), 86400 * 7); // Expire in a week
console.log(
`[Cache]: Cached BS Map Data for hash ${mapHash} in ${
Date.now() - before
}ms`
);
return json;
const before = Date.now();
const response = await axios.get(BEATSAVER_MAP_API.replace("%s", mapHash));
if (response.status === 404) {
return undefined;
}
const jsonResponse = response.data;
const json = {
bsr: jsonResponse.id,
mapArt: getLatestMapArt(jsonResponse),
};
await setValue(key, JSON.stringify(json), 86400 * 7); // Expire in a week
console.log(
`[Cache]: Cached BS Map Data for hash ${mapHash} in ${
Date.now() - before
}ms`
);
return json;
}

View File

@ -2,13 +2,8 @@ import axios from "axios";
import LeaderboardType from "../../consts/LeaderboardType";
export async function getPlayerData(leaderboardType, playerId) {
const data = await axios.get(
LeaderboardType[leaderboardType].ApiUrl.PlayerData.replace("%s", playerId),
{
headers: {
"x-requested-with": "BeatSaber Overlay",
},
}
);
return data;
const data = await axios.get(
LeaderboardType[leaderboardType].ApiUrl.PlayerData.replace("%s", playerId)
);
return data;
}

View File

@ -6,57 +6,56 @@ import { VARS } from "../consts/EnvVars";
import "../styles/globals.css";
const lightTheme = createTheme({
type: "light",
theme: {
colors: {},
},
type: "light",
theme: {
colors: {},
},
});
const darkTheme = createTheme({
type: "dark",
theme: {
colors: {},
},
type: "dark",
theme: {
colors: {},
},
});
function MyApp({ Component, pageProps }) {
return (
<>
<DefaultSeo
titleTemplate={`${env(VARS.SITE_NAME)} - %s`}
title={env(VARS.SITE_TITLE)}
description={env(VARS.SITE_DESCRIPTION)}
openGraph={{
url: env(VARS.SITE_URL),
title: env(VARS.SITE_NAME),
description: env(VARS.SITE_DESCRIPTION),
siteName: env(VARS.SITE_NAME),
images: [
{
url: "https://git.fascinated.cc/Fascinated/beatsaber-overlay/media/branch/main/assets/overlay.png",
alt: "Site Example",
},
],
}}
twitter={{
cardType: "summary_large_image",
// site: "@BeatSaber Overlay",
}}
/>
<NextThemesProvider
storageKey="theme"
attribute="class"
value={{
dark: darkTheme,
light: lightTheme,
}}
>
<NextUIProvider>
<Component {...pageProps} />
</NextUIProvider>
</NextThemesProvider>
</>
);
return (
<>
<DefaultSeo
titleTemplate={`${env(VARS.SITE_NAME)} - %s`}
title={env(VARS.SITE_TITLE)}
description={env(VARS.SITE_DESCRIPTION)}
openGraph={{
url: env(VARS.SITE_URL),
title: env(VARS.SITE_NAME),
description: env(VARS.SITE_DESCRIPTION),
siteName: env(VARS.SITE_NAME),
images: [
{
url: "https://git.fascinated.cc/Fascinated/beatsaber-overlay/media/branch/main/assets/overlay.png",
alt: "Site Example",
},
],
}}
twitter={{
cardType: "summary_large_image",
}}
/>
<NextThemesProvider
storageKey="theme"
attribute="class"
value={{
dark: darkTheme,
light: lightTheme,
}}
>
<NextUIProvider>
<Component {...pageProps} />
</NextUIProvider>
</NextThemesProvider>
</>
);
}
export default MyApp;

View File

@ -11,97 +11,92 @@ const KEY = "BL_MAP_DATA_";
* @returns
*/
export default async function handler(req, res) {
if (!req.query.hash || !req.query.difficulty || !req.query.characteristic) {
return res.status(404).json({
status: 404,
message: "Invalid request",
});
}
const mapHash = req.query.hash.replace("custom_level_", "").toLowerCase();
const difficulty = req.query.difficulty.replace(" ", "");
const characteristic = req.query.characteristic;
if (!req.query.hash || !req.query.difficulty || !req.query.characteristic) {
return res.status(404).json({
status: 404,
message: "Invalid request",
});
}
const mapHash = req.query.hash.replace("custom_level_", "").toLowerCase();
const difficulty = req.query.difficulty.replace(" ", "");
const characteristic = req.query.characteristic;
const key = `${KEY}${difficulty}-${characteristic}-${mapHash}`;
const exists = await valueExists(key);
if (exists) {
const data = await getValue(key);
const json = JSON.parse(data);
res.setHeader("Cache-Status", "hit");
const key = `${KEY}${difficulty}-${characteristic}-${mapHash}`;
const exists = await valueExists(key);
if (exists) {
const data = await getValue(key);
const json = JSON.parse(data);
res.setHeader("Cache-Status", "hit");
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: json.stars,
modifiers: json.modifiers,
passRating: json.passRating,
accRating: json.accRating,
techRating: json.techRating,
});
}
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: json.stars,
modifiers: json.modifiers,
passRating: json.passRating,
accRating: json.accRating,
techRating: json.techRating,
});
}
const before = Date.now();
const reesponse = await axios.get(
WebsiteTypes.BeatLeader.ApiUrl.MapData.replace("%h", mapHash),
{
headers: {
"X-Requested-With": "BeatSaber Overlay",
},
}
);
if (reesponse.status === 404) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
const json = reesponse.data;
let starCount = undefined;
let modifiers = undefined;
let passRating = undefined;
let accRating = undefined;
let techRating = undefined;
const before = Date.now();
const reesponse = await axios.get(
WebsiteTypes.BeatLeader.ApiUrl.MapData.replace("%h", mapHash)
);
if (reesponse.status === 404) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
const json = reesponse.data;
let starCount = undefined;
let modifiers = undefined;
let passRating = undefined;
let accRating = undefined;
let techRating = undefined;
for (const diff of json.difficulties) {
if (
diff.difficultyName === difficulty &&
diff.modeName === characteristic
) {
starCount = diff.stars;
modifiers = diff.modifierValues;
passRating = diff.passRating;
accRating = diff.accRating;
techRating = diff.techRating;
}
}
if (starCount === undefined) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
await setValue(
key,
JSON.stringify({
stars: starCount,
modifiers: modifiers,
passRating: passRating,
accRating: accRating,
techRating: techRating,
})
);
console.log(
`[Cache]: Cached BL Star Count for hash ${mapHash} in ${
Date.now() - before
}ms`
);
res.setHeader("Cache-Status", "miss");
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: starCount,
modifiers: modifiers,
passRating: passRating,
accRating: accRating,
techRating: techRating,
});
for (const diff of json.difficulties) {
if (
diff.difficultyName === difficulty &&
diff.modeName === characteristic
) {
starCount = diff.stars;
modifiers = diff.modifierValues;
passRating = diff.passRating;
accRating = diff.accRating;
techRating = diff.techRating;
}
}
if (starCount === undefined) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
await setValue(
key,
JSON.stringify({
stars: starCount,
modifiers: modifiers,
passRating: passRating,
accRating: accRating,
techRating: techRating,
})
);
console.log(
`[Cache]: Cached BL Star Count for hash ${mapHash} in ${
Date.now() - before
}ms`
);
res.setHeader("Cache-Status", "miss");
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: starCount,
modifiers: modifiers,
passRating: passRating,
accRating: accRating,
techRating: techRating,
});
}

View File

@ -12,65 +12,60 @@ const KEY = "SS_MAP_STAR_";
* @returns
*/
export default async function handler(req, res) {
if (!req.query.hash) {
return res.status(404).json({
status: 404,
message: "Invalid request",
});
}
const mapHash = req.query.hash.replace("custom_level_", "").toLowerCase();
const difficulty = req.query.difficulty.replace(" ", "");
const characteristic = req.query.characteristic;
if (!req.query.hash) {
return res.status(404).json({
status: 404,
message: "Invalid request",
});
}
const mapHash = req.query.hash.replace("custom_level_", "").toLowerCase();
const difficulty = req.query.difficulty.replace(" ", "");
const characteristic = req.query.characteristic;
const key = `${KEY}${difficulty}-${characteristic}-${mapHash}`;
const exists = await valueExists(key);
if (exists) {
const data = await getValue(key);
res.setHeader("Cache-Status", "hit");
const key = `${KEY}${difficulty}-${characteristic}-${mapHash}`;
const exists = await valueExists(key);
if (exists) {
const data = await getValue(key);
res.setHeader("Cache-Status", "hit");
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: Number.parseFloat(data),
});
}
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: Number.parseFloat(data),
});
}
const before = Date.now();
const response = await axios.get(
WebsiteTypes.ScoreSaber.ApiUrl.MapData.replace("%h", mapHash).replace(
"%d",
diffToScoreSaberDiff(difficulty)
),
{
headers: {
"X-Requested-With": "BeatSaber Overlay",
},
}
);
if (response.status === 404) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
const json = response.data;
let starCount = json.stars;
if (starCount === undefined) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
await setValue(key, starCount);
console.log(
`[Cache]: Cached SS Star Count for hash ${mapHash} in ${
Date.now() - before
}ms`
);
res.setHeader("Cache-Status", "miss");
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: starCount,
});
const before = Date.now();
const response = await axios.get(
WebsiteTypes.ScoreSaber.ApiUrl.MapData.replace("%h", mapHash).replace(
"%d",
diffToScoreSaberDiff(difficulty)
)
);
if (response.status === 404) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
const json = response.data;
let starCount = json.stars;
if (starCount === undefined) {
return res.status(404).json({
status: 404,
message: "Unknown Map Hash",
});
}
await setValue(key, starCount);
console.log(
`[Cache]: Cached SS Star Count for hash ${mapHash} in ${
Date.now() - before
}ms`
);
res.setHeader("Cache-Status", "miss");
return res.status(200).json({
status: "OK",
difficulty: difficulty,
stars: starCount,
});
}

View File

@ -190,7 +190,6 @@ export default class Home extends Component {
<Grid xs={12} lg={9}>
<Card>
<Card.Body>
<Spacer y={1.2} />
<Text>
How to use{" "}
<span>
@ -360,9 +359,9 @@ export default class Home extends Component {
}}
>
<Link href="https://git.fascinated.cc/Fascinated/beatsaber-overlay">
<a>
If you like this project and want to support it. Come
check out the project on Gitea!
<a href="https://git.fascinated.cc/Fascinated/beatsaber-overlay">
If you like this project and want to help me make it
better, come check out the project on Gitea!
</a>
</Link>
</Text>

View File

@ -12,71 +12,86 @@ import { usePlayerDataStore } from "../store/playerDataStore";
import styles from "../styles/overlay.module.css";
export default function Overlay(props) {
const query = JSON.parse(props.query);
const [setOverlaySettings, mounted, setMounted] = useSettingsStore(
(state) => [state.setOverlaySettings, state.mounted, state.setMounted]
);
const updatePlayerData = usePlayerDataStore(
(state) => state.updatePlayerData
);
const query = JSON.parse(props.query);
const [setOverlaySettings, mounted, setMounted] = useSettingsStore(
(state) => [state.setOverlaySettings, state.mounted, state.setMounted]
);
const updatePlayerData = usePlayerDataStore(
(state) => state.updatePlayerData
);
useEffect(() => {
if (!mounted && props.isValidSteamId) {
setMounted(true);
useEffect(() => {
if (!mounted && props.isValidSteamId) {
setMounted(true);
async function setup() {
await setOverlaySettings(query);
const showSongInfo = useSettingsStore.getState().showSongInfo;
const showScoreInfo = useSettingsStore.getState().showScoreInfo;
if (showSongInfo || (showScoreInfo && typeof window !== "undefined")) {
await connectClient();
}
const showPlayerStats = useSettingsStore.getState().showPlayerStats;
if (showPlayerStats) {
await updatePlayerData();
}
}
setup();
}
}, [
query,
props.isValidSteamId,
setOverlaySettings,
mounted,
setMounted,
updatePlayerData,
]);
async function setup() {
await setOverlaySettings(query);
const showSongInfo = useSettingsStore.getState().showSongInfo;
const showScoreInfo = useSettingsStore.getState().showScoreInfo;
if (showSongInfo || (showScoreInfo && typeof window !== "undefined")) {
await connectClient();
}
const showPlayerStats = useSettingsStore.getState().showPlayerStats;
if (showPlayerStats) {
await updatePlayerData();
}
}
setup();
}
}, [
query,
props.isValidSteamId,
setOverlaySettings,
mounted,
setMounted,
updatePlayerData,
]);
if (!props.isValidSteamId) {
return (
<div className={styles.invalidPlayer}>
<h1>Invalid Steam ID</h1>
<h3>Please check the id field in the url</h3>
</div>
);
}
if (!props.isValidSteamId) {
return (
<div className={styles.invalidPlayer}>
<h1>Invalid Steam ID</h1>
<h3>Please check the id field in the url</h3>
</div>
);
}
return (
<div className={styles.main}>
<NextSeo title="Overlay" />
<PlayerStats />
<SongInfo />
<ScoreStats />
<CutStats />
</div>
);
return (
<div className={styles.main}>
<NextSeo title="Overlay" />
<PlayerStats />
<SongInfo />
<ScoreStats />
<CutStats />
<p
style={{
fontSize: 50,
position: "absolute",
top: 0,
right: 0,
paddingRight: "10px",
}}
>
This overlay is deprecated use:{" "}
<a href="https://ssr.fascinated.cc/overlay/builder">
https://ssr.fascinated.cc/overlay/builder
</a>
</p>
</div>
);
}
export async function getServerSideProps(context) {
const steamId = context.query.id;
const steamIdResponse = await axios.get(
`${process.env.REACT_APP_SITE_URL}/api/validateid?steamid=${steamId}`
);
const steamId = context.query.id;
const steamIdResponse = await axios.get(
`${process.env.REACT_APP_SITE_URL}/api/validateid?steamid=${steamId}`
);
return {
props: {
isValidSteamId: steamIdResponse.data.message === "Valid",
query: JSON.stringify(context.query),
},
};
return {
props: {
isValidSteamId: steamIdResponse.data.message === "Valid",
query: JSON.stringify(context.query),
},
};
}

View File

@ -4,52 +4,48 @@ import Utils from "../utils/utils";
import { useSettingsStore } from "./overlaySettingsStore";
interface PlayerDataState {
isLoading: boolean;
id: string;
pp: number;
avatar: string;
globalPos: number;
countryRank: number;
country: string;
updatePlayerData: () => void;
isLoading: boolean;
id: string;
pp: number;
avatar: string;
globalPos: number;
countryRank: number;
country: string;
updatePlayerData: () => void;
}
export const usePlayerDataStore = create<PlayerDataState>()((set) => ({
isLoading: true,
id: "",
pp: 0,
avatar: "",
globalPos: 0,
countryRank: 0,
country: "",
isLoading: true,
id: "",
pp: 0,
avatar: "",
globalPos: 0,
countryRank: 0,
country: "",
updatePlayerData: async () => {
const leaderboardType = useSettingsStore.getState().leaderboardType;
const playerId = useSettingsStore.getState().id;
updatePlayerData: async () => {
const leaderboardType = useSettingsStore.getState().leaderboardType;
const playerId = useSettingsStore.getState().id;
const apiUrl = Utils.getWebsiteApi(
leaderboardType
).ApiUrl.PlayerData.replace("%s", playerId);
const response = await axios.get(apiUrl, {
headers: {
"x-requested-with": "BeatSaber Overlay",
},
});
if (response.status !== 200) {
return;
}
const data = response.data;
const apiUrl = Utils.getWebsiteApi(
leaderboardType
).ApiUrl.PlayerData.replace("%s", playerId);
const response = await axios.get(apiUrl);
if (response.status !== 200) {
return;
}
const data = response.data;
console.log("Updated player data");
console.log("Updated player data");
set(() => ({
id: playerId,
isLoading: false,
pp: data.pp,
avatar: data.avatar || data.profilePicture,
globalPos: data.rank,
countryRank: data.countryRank,
country: data.country,
}));
},
set(() => ({
id: playerId,
isLoading: false,
pp: data.pp,
avatar: data.avatar || data.profilePicture,
globalPos: data.rank,
countryRank: data.countryRank,
country: data.country,
}));
},
}));

View File

@ -154,6 +154,8 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
}
const { bsr, mapArt } = mapDataresponse.data.data;
console.log(scoreSaberLeaderboardData);
set({
isLoading: false,
hasError: hasError,

View File

@ -5,134 +5,130 @@ import { getScoreSaberPP } from "../curve/ScoreSaberCurve";
import { useSongDataStore } from "../store/songDataStore";
export default class Utils {
/**
* Returns the information for the given website type.
*
* @param {string} website
* @returns The website type's information.
*/
static getWebsiteApi(website) {
return LeaderboardType[website];
}
/**
* Returns the information for the given website type.
*
* @param {string} website
* @returns The website type's information.
*/
static getWebsiteApi(website) {
return LeaderboardType[website];
}
static openInNewTab(url) {
window.open(url, "_blank");
}
static openInNewTab(url) {
window.open(url, "_blank");
}
static async isLeaderboardValid(url, steamId) {
const response = await axios.get(url.replace("%s", steamId), {
headers: {
"X-Requested-With": "BeatSaber Overlay",
},
});
if (response.status === 429) {
return true; // Just assume it's true is we are rate limited
}
const json = response.data;
return !!json.pp;
}
static async isLeaderboardValid(url, steamId) {
const response = await axios.get(url.replace("%s", steamId));
if (response.status === 429) {
return true; // Just assume it's true is we are rate limited
}
const json = response.data;
return !!json.pp;
}
static calculatePP(stars, acc, type) {
if (stars <= 0) {
return undefined;
}
if (type === "BeatLeader") {
const leaderboardData =
useSongDataStore.getState().mapLeaderboardData.beatLeader;
static calculatePP(stars, acc, type) {
if (stars <= 0) {
return undefined;
}
if (type === "BeatLeader") {
const leaderboardData =
useSongDataStore.getState().mapLeaderboardData.beatLeader;
return getBeatLeaderPP(
acc,
leaderboardData.accRating,
leaderboardData.passRating,
leaderboardData.techRating
);
}
if (type === "ScoreSaber") {
return getScoreSaberPP(acc, stars);
}
return undefined;
}
return getBeatLeaderPP(
acc,
leaderboardData.accRating,
leaderboardData.passRating,
leaderboardData.techRating
);
}
if (type === "ScoreSaber") {
return getScoreSaberPP(acc, stars);
}
return undefined;
}
static calculateModifierBonus() {
const songMods = useSongDataStore.getState().songModifiers;
const modifierMulipliers =
useSongDataStore.getState().mapLeaderboardData.beatLeader.modifiers;
let bonus = 1;
static calculateModifierBonus() {
const songMods = useSongDataStore.getState().songModifiers;
const modifierMulipliers =
useSongDataStore.getState().mapLeaderboardData.beatLeader.modifiers;
let bonus = 1;
// No Fail
if (
songMods.noFail == true &&
modifierMulipliers.nf < 0 &&
useSongDataStore.getState().failed
) {
bonus -= modifierMulipliers.nf;
}
// No Fail
if (
songMods.noFail == true &&
modifierMulipliers.nf < 0 &&
useSongDataStore.getState().failed
) {
bonus -= modifierMulipliers.nf;
}
// Speed Modifiers
if (songMods.songSpeed != "Normal") {
if (songMods.songSpeed == "SuperSlow" && modifierMulipliers.ss > 0) {
bonus -= modifierMulipliers.ss;
}
if (songMods.songSpeed == "Faster" && modifierMulipliers.fs > 0) {
bonus += modifierMulipliers.fs;
}
if (songMods.songSpeed == "SuperFast" && modifierMulipliers.sf > 0) {
bonus += modifierMulipliers.sf;
}
}
// Speed Modifiers
if (songMods.songSpeed != "Normal") {
if (songMods.songSpeed == "SuperSlow" && modifierMulipliers.ss > 0) {
bonus -= modifierMulipliers.ss;
}
if (songMods.songSpeed == "Faster" && modifierMulipliers.fs > 0) {
bonus += modifierMulipliers.fs;
}
if (songMods.songSpeed == "SuperFast" && modifierMulipliers.sf > 0) {
bonus += modifierMulipliers.sf;
}
}
// Disappearing Arrows
if (songMods.disappearingArrows == true && modifierMulipliers.da > 0) {
bonus += modifierMulipliers.da;
}
// Disappearing Arrows
if (songMods.disappearingArrows == true && modifierMulipliers.da > 0) {
bonus += modifierMulipliers.da;
}
// Ghost Notes
if (songMods.ghostNotes == true && modifierMulipliers.gn > 0) {
toAdd += modifierMulipliers.gn;
}
// Ghost Notes
if (songMods.ghostNotes == true && modifierMulipliers.gn > 0) {
toAdd += modifierMulipliers.gn;
}
// No Arrows
if (songMods.noArrows == true && modifierMulipliers.na < 0) {
bonus -= modifierMulipliers.na;
}
// No Arrows
if (songMods.noArrows == true && modifierMulipliers.na < 0) {
bonus -= modifierMulipliers.na;
}
// No Bombs
if (songMods.noBombs == true && modifierMulipliers.nb < 0) {
bonus -= modifierMulipliers.nb;
}
// No Bombs
if (songMods.noBombs == true && modifierMulipliers.nb < 0) {
bonus -= modifierMulipliers.nb;
}
// No Obstacles
if (songMods.obstacles == false && modifierMulipliers.no < 0) {
bonus -= modifierMulipliers.no;
}
// No Obstacles
if (songMods.obstacles == false && modifierMulipliers.no < 0) {
bonus -= modifierMulipliers.no;
}
return bonus;
}
return bonus;
}
static base64ToArrayBuffer(base64) {
return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
}
static base64ToArrayBuffer(base64) {
return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
}
static stringToBoolean = (stringValue) => {
switch (stringValue?.toLowerCase()?.trim()) {
case "true":
case "yes":
case "1":
return true;
static stringToBoolean = (stringValue) => {
switch (stringValue?.toLowerCase()?.trim()) {
case "true":
case "yes":
case "1":
return true;
case "false":
case "no":
case "0":
case null:
case undefined:
return false;
case "false":
case "no":
case "0":
case null:
case undefined:
return false;
default:
return JSON.parse(stringValue);
}
};
default:
return JSON.parse(stringValue);
}
};
static capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
static capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
}

3549
yarn.lock

File diff suppressed because it is too large Load Diff