├── .npmrc ├── packages ├── db │ ├── .gitignore │ ├── prisma │ │ ├── extensions.sql │ │ ├── auth_user_trigger_rm.sql │ │ ├── migrations │ │ │ ├── 20221014212935_clan_xp_string_to_number │ │ │ │ └── migration.sql │ │ │ ├── migration_lock.toml │ │ │ ├── 20221013181657_remove_player_alias_relation │ │ │ │ └── migration.sql │ │ │ ├── 20221210182655_make_clan_created_at_optional │ │ │ │ └── migration.sql │ │ │ ├── 20221209172429_bhplayer_alias_createdat_and_public │ │ │ │ └── migration.sql │ │ │ ├── 20221121232634_unarmed_matchtime │ │ │ │ └── migration.sql │ │ │ └── 20221122003649_legends_and_weapons_last_updated │ │ │ │ └── migration.sql │ │ ├── realtime_setup.sql │ │ ├── functions.sql │ │ └── auth_user_trigger_add.sql │ ├── tsconfig.json │ ├── supabase │ │ ├── service.ts │ │ ├── client.ts │ │ └── auth.ts │ └── discord │ │ ├── client.ts │ │ ├── getUserConnections.ts │ │ └── getDiscordProfile.ts ├── web-parser │ ├── index.ts │ ├── tsconfig.json │ ├── weekly-rotation │ │ ├── dev.ts │ │ ├── weeklyRotationMock.ts │ │ └── getWeeklyRotation.ts │ ├── bh-articles │ │ └── dev.ts │ ├── power-rankings │ │ └── dev.ts │ └── package.json ├── common │ ├── hooks │ │ ├── useWindowScroll.ts │ │ ├── useCopyToClipboard.ts │ │ ├── useDebouncedState.ts │ │ ├── useDevice.ts │ │ ├── useLocalStorageState.ts │ │ └── useSortBy.ts │ ├── helpers │ │ ├── classnames.ts │ │ ├── math.ts │ │ ├── formatBalance.ts │ │ ├── validators.ts │ │ ├── cleanString.ts │ │ ├── isValueInEnum.ts │ │ ├── arrayToMap.ts │ │ └── date.ts │ ├── tsconfig.json │ ├── package.json │ └── analytics │ │ ├── gtag.ts │ │ └── GAScripts.tsx ├── server │ ├── helpers │ │ ├── commonOptions.ts │ │ ├── constants.ts │ │ ├── withTimeLog.ts │ │ └── waitForRequestTimeout.ts │ ├── tsconfig.json │ ├── trpc.ts │ ├── router │ │ ├── getWeeklyRotation.ts │ │ ├── getBHArticles.ts │ │ ├── stats │ │ │ ├── getPowerRankings.ts │ │ │ ├── getPlayerAliases.ts │ │ │ └── getClansRankings.ts │ │ └── index.ts │ ├── mutations │ │ ├── updateDBClanData.ts │ │ ├── updateDBPlayerAliases.ts │ │ └── flushOutdatedBPlayerData.ts │ └── package.json ├── bhapi │ ├── tsconfig.json │ ├── helpers │ │ ├── calculateWinrate.ts │ │ ├── getTierFromRating.ts │ │ ├── getPlayerAliases.ts │ │ └── getTeamPlayers.ts │ ├── package.json │ └── mocks │ │ └── clan.ts ├── logger │ ├── tsconfig.json │ ├── package.json │ └── index.ts ├── ui │ ├── tsconfig.json │ ├── theme │ │ ├── theme.js │ │ └── index.ts │ ├── base │ │ ├── AppLink.tsx │ │ ├── Progress.tsx │ │ ├── Kbd.tsx │ │ ├── Card.tsx │ │ ├── Tooltip.tsx │ │ ├── PageLoader.tsx │ │ └── Button.tsx │ └── package.json ├── dl-roster-images │ ├── tsconfig.json │ ├── package.json │ └── downloadImage.ts └── tsconfig │ ├── README.md │ ├── package.json │ ├── nextjs.json │ └── base.json ├── app ├── util │ ├── constants.ts │ └── features.ts ├── public │ ├── ads.txt │ ├── images │ │ ├── BP3.webm │ │ ├── BP4.webm │ │ ├── logo.png │ │ ├── favicon.png │ │ ├── Ada Landing.png │ │ ├── errors │ │ │ ├── 404.png │ │ │ └── 500.png │ │ ├── og │ │ │ └── main-og.jpg │ │ ├── Nix Landing.webp │ │ ├── Bodvar Landing.png │ │ ├── Corehalla_Logo.gif │ │ ├── Landing_Preview.jpg │ │ ├── icons │ │ │ ├── flags │ │ │ │ ├── ALL.png │ │ │ │ ├── AUS.png │ │ │ │ ├── BRZ.png │ │ │ │ ├── EU.png │ │ │ │ ├── JPN.png │ │ │ │ ├── ME.png │ │ │ │ ├── SA.png │ │ │ │ ├── SEA.png │ │ │ │ ├── US-E.png │ │ │ │ └── US-W.png │ │ │ ├── legends │ │ │ │ ├── Ada.png │ │ │ │ ├── Dusk.png │ │ │ │ ├── Fait.png │ │ │ │ ├── Jiro.png │ │ │ │ ├── Kaya.png │ │ │ │ ├── Koji.png │ │ │ │ ├── Kor.png │ │ │ │ ├── Nix.png │ │ │ │ ├── Onyx.png │ │ │ │ ├── Thor.png │ │ │ │ ├── Val.png │ │ │ │ ├── Vivi.png │ │ │ │ ├── Xull.png │ │ │ │ ├── Artemis.png │ │ │ │ ├── Asuri.png │ │ │ │ ├── Azoth.png │ │ │ │ ├── Barraza.png │ │ │ │ ├── Brynn.png │ │ │ │ ├── Bödvar.png │ │ │ │ ├── Caspian.png │ │ │ │ ├── Cassidy.png │ │ │ │ ├── Cross.png │ │ │ │ ├── Diana.png │ │ │ │ ├── Ember.png │ │ │ │ ├── Gnash.png │ │ │ │ ├── Hattori.png │ │ │ │ ├── Imuji.png │ │ │ │ ├── Isaiah.png │ │ │ │ ├── Jaeyun.png │ │ │ │ ├── Jhala.png │ │ │ │ ├── Lin Fei.png │ │ │ │ ├── Lucien.png │ │ │ │ ├── Mirage.png │ │ │ │ ├── Mordex.png │ │ │ │ ├── Orion.png │ │ │ │ ├── Petra.png │ │ │ │ ├── Priya.png │ │ │ │ ├── Ragnir.png │ │ │ │ ├── Rayman.png │ │ │ │ ├── Scarlet.png │ │ │ │ ├── Seven.png │ │ │ │ ├── Sidra.png │ │ │ │ ├── Teros.png │ │ │ │ ├── Thatch.png │ │ │ │ ├── Ulgrim.png │ │ │ │ ├── Vector.png │ │ │ │ ├── Volkov.png │ │ │ │ ├── Yumiko.png │ │ │ │ ├── Zariel.png │ │ │ │ ├── King zuva.png │ │ │ │ ├── Queen Nai.png │ │ │ │ ├── Sentinel.png │ │ │ │ ├── Wu Shang.png │ │ │ │ ├── Lord Vraxx.png │ │ │ │ └── Sir Roland.png │ │ │ ├── ranked │ │ │ │ ├── Tin 0.png │ │ │ │ ├── Tin 1.png │ │ │ │ ├── Tin 2.png │ │ │ │ ├── Tin 3.png │ │ │ │ ├── Tin 4.png │ │ │ │ ├── Tin 5.png │ │ │ │ ├── Bronze 0.png │ │ │ │ ├── Bronze 1.png │ │ │ │ ├── Bronze 2.png │ │ │ │ ├── Bronze 3.png │ │ │ │ ├── Bronze 4.png │ │ │ │ ├── Bronze 5.png │ │ │ │ ├── Diamond.png │ │ │ │ ├── Gold 0.png │ │ │ │ ├── Gold 1.png │ │ │ │ ├── Gold 2.png │ │ │ │ ├── Gold 3.png │ │ │ │ ├── Gold 4.png │ │ │ │ ├── Gold 5.png │ │ │ │ ├── Silver 0.png │ │ │ │ ├── Silver 1.png │ │ │ │ ├── Silver 2.png │ │ │ │ ├── Silver 3.png │ │ │ │ ├── Silver 4.png │ │ │ │ ├── Silver 5.png │ │ │ │ ├── Platinum 0.png │ │ │ │ ├── Platinum 1.png │ │ │ │ ├── Platinum 2.png │ │ │ │ ├── Platinum 3.png │ │ │ │ ├── Platinum 4.png │ │ │ │ ├── Platinum 5.png │ │ │ │ └── Valhallan.webp │ │ │ ├── weapons │ │ │ │ ├── Axe.png │ │ │ │ ├── Bow.png │ │ │ │ ├── Orb.png │ │ │ │ ├── Cannon.png │ │ │ │ ├── Chakram.png │ │ │ │ ├── Katars.png │ │ │ │ ├── Scythe.png │ │ │ │ ├── Spear.png │ │ │ │ ├── Sword.png │ │ │ │ ├── Unarmed.png │ │ │ │ ├── Blasters.png │ │ │ │ ├── Gauntlets.png │ │ │ │ ├── Battle Boots.png │ │ │ │ ├── Greatsword.png │ │ │ │ ├── Rocket Lance.png │ │ │ │ └── Grapple Hammer.png │ │ │ ├── roster │ │ │ │ ├── crossovers │ │ │ │ │ ├── Po.png │ │ │ │ │ ├── Aang.png │ │ │ │ │ ├── Finn.png │ │ │ │ │ ├── Jake.png │ │ │ │ │ ├── Ken.png │ │ │ │ │ ├── Luke.png │ │ │ │ │ ├── Rick.png │ │ │ │ │ ├── Ryu.png │ │ │ │ │ ├── Toph.png │ │ │ │ │ ├── Zuko.png │ │ │ │ │ ├── Akuma.png │ │ │ │ │ ├── Alucard.png │ │ │ │ │ ├── Asuka.png │ │ │ │ │ ├── Barbara.png │ │ │ │ │ ├── Chun Li.png │ │ │ │ │ ├── Daimio.png │ │ │ │ │ ├── Daryl.png │ │ │ │ │ ├── Dhalsim.png │ │ │ │ │ ├── Eivor.png │ │ │ │ │ ├── Garnet.png │ │ │ │ │ ├── Globox.png │ │ │ │ │ ├── Hellboy.png │ │ │ │ │ ├── Maggie.png │ │ │ │ │ ├── Negan.png │ │ │ │ │ ├── Nimue.png │ │ │ │ │ ├── Pearl.png │ │ │ │ │ ├── Raphael.png │ │ │ │ │ ├── Sakura.png │ │ │ │ │ ├── Tigress.png │ │ │ │ │ ├── Amethyst.png │ │ │ │ │ ├── Donatello.png │ │ │ │ │ ├── Four Arms.png │ │ │ │ │ ├── Gruagach.png │ │ │ │ │ ├── Heatblast.png │ │ │ │ │ ├── John Cena.png │ │ │ │ │ ├── Leonardo.png │ │ │ │ │ ├── M. Bison.png │ │ │ │ │ ├── Macho Man.png │ │ │ │ │ ├── Michonne.png │ │ │ │ │ ├── Stevonnie.png │ │ │ │ │ ├── Tai Lung.png │ │ │ │ │ ├── The Rock.png │ │ │ │ │ ├── Becky Lynch.png │ │ │ │ │ ├── Black Knight.png │ │ │ │ │ ├── Diamondhead.png │ │ │ │ │ ├── Enchantress.png │ │ │ │ │ ├── King Knight.png │ │ │ │ │ ├── Lara Croft.png │ │ │ │ │ ├── Michelangelo.png │ │ │ │ │ ├── Roman Reigns.png │ │ │ │ │ ├── Snake Eyes.png │ │ │ │ │ ├── Storm Shadow.png │ │ │ │ │ ├── Xavier Woods.png │ │ │ │ │ ├── Plague Knight.png │ │ │ │ │ ├── Shovel Knight.png │ │ │ │ │ ├── Simon Belmont.png │ │ │ │ │ ├── Specter Knight.png │ │ │ │ │ ├── The Undertaker.png │ │ │ │ │ └── Princess Bubblegum.png │ │ │ │ └── legends │ │ │ │ │ ├── ada.png │ │ │ │ │ ├── asuri.png │ │ │ │ │ ├── azoth.png │ │ │ │ │ ├── brynn.png │ │ │ │ │ ├── cross.png │ │ │ │ │ ├── diana.png │ │ │ │ │ ├── dusk.png │ │ │ │ │ ├── ember.png │ │ │ │ │ ├── ezio.png │ │ │ │ │ ├── fait.png │ │ │ │ │ ├── gnash.png │ │ │ │ │ ├── imuji.png │ │ │ │ │ ├── jhala.png │ │ │ │ │ ├── jiro.png │ │ │ │ │ ├── kaya.png │ │ │ │ │ ├── koji.png │ │ │ │ │ ├── kor.png │ │ │ │ │ ├── loki.png │ │ │ │ │ ├── mako.png │ │ │ │ │ ├── munin.png │ │ │ │ │ ├── nix.png │ │ │ │ │ ├── onyx.png │ │ │ │ │ ├── orion.png │ │ │ │ │ ├── petra.png │ │ │ │ │ ├── priya.png │ │ │ │ │ ├── reno.png │ │ │ │ │ ├── seven.png │ │ │ │ │ ├── sidra.png │ │ │ │ │ ├── teros.png │ │ │ │ │ ├── tezca.png │ │ │ │ │ ├── thea.png │ │ │ │ │ ├── thor.png │ │ │ │ │ ├── val.png │ │ │ │ │ ├── vivi.png │ │ │ │ │ ├── xull.png │ │ │ │ │ ├── arcadia.png │ │ │ │ │ ├── artemis.png │ │ │ │ │ ├── barraza.png │ │ │ │ │ ├── bodvar.png │ │ │ │ │ ├── caspian.png │ │ │ │ │ ├── cassidy.png │ │ │ │ │ ├── hattori.png │ │ │ │ │ ├── isaiah.png │ │ │ │ │ ├── jaeyun.png │ │ │ │ │ ├── lin fei.png │ │ │ │ │ ├── lucien.png │ │ │ │ │ ├── magyar.png │ │ │ │ │ ├── mirage.png │ │ │ │ │ ├── mordex.png │ │ │ │ │ ├── ragnir.png │ │ │ │ │ ├── rayman.png │ │ │ │ │ ├── scarlet.png │ │ │ │ │ ├── thatch.png │ │ │ │ │ ├── ulgrim.png │ │ │ │ │ ├── vector.png │ │ │ │ │ ├── volkov.png │ │ │ │ │ ├── yumiko.png │ │ │ │ │ ├── zariel.png │ │ │ │ │ ├── king zuva.png │ │ │ │ │ ├── lord vraxx.png │ │ │ │ │ ├── queen nai.png │ │ │ │ │ ├── redraptor.png │ │ │ │ │ ├── sentinel.png │ │ │ │ │ ├── sir roland.png │ │ │ │ │ └── wu shang.png │ │ │ └── colors │ │ │ │ ├── 50px-Color_Blue.png │ │ │ │ ├── 50px-Color_Cyan.png │ │ │ │ ├── 50px-Color_Gray.png │ │ │ │ ├── 50px-Color_Pink.png │ │ │ │ ├── 50px-Color_Red.png │ │ │ │ ├── 50px-Color_Black.png │ │ │ │ ├── 50px-Color_Brown.png │ │ │ │ ├── 50px-Color_Classic.png │ │ │ │ ├── 50px-Color_Green.png │ │ │ │ ├── 50px-Color_Orange.png │ │ │ │ ├── 50px-Color_Purple.png │ │ │ │ ├── 50px-Color_Sunset.png │ │ │ │ ├── 50px-Color_White.png │ │ │ │ ├── 50px-Color_Yellow.png │ │ │ │ ├── 37px-Color_Home_Team.png │ │ │ │ ├── 50px-Color_Community.png │ │ │ │ ├── 50px-Color_Haunting.png │ │ │ │ ├── 50px-Color_Heatwave.png │ │ │ │ ├── 50px-Color_Skyforged.png │ │ │ │ ├── 50px-Color_Team_Blue.png │ │ │ │ ├── 50px-Color_Team_Red.png │ │ │ │ ├── 50px-Color_Goldforged.png │ │ │ │ ├── 50px-Color_Lovestruck.png │ │ │ │ ├── 50px-Color_Lucky_Clover.png │ │ │ │ └── 50px-Color_Winter_Holiday.png │ │ ├── Landing Podium 3D.png │ │ ├── backgrounds │ │ │ ├── orion.jpg │ │ │ ├── Wallpaper_Text.jpg │ │ │ ├── Wallpaper_NoText.jpg │ │ │ └── Wallpaper_TextSm.jpg │ │ └── ranked-banners │ │ │ ├── Gold 0.png │ │ │ ├── Gold 1.png │ │ │ ├── Gold 2.png │ │ │ ├── Gold 3.png │ │ │ ├── Gold 4.png │ │ │ ├── Gold 5.png │ │ │ ├── Tin 0.png │ │ │ ├── Tin 1.png │ │ │ ├── Tin 2.png │ │ │ ├── Tin 3.png │ │ │ ├── Tin 4.png │ │ │ ├── Tin 5.png │ │ │ ├── null.png │ │ │ ├── Bronze 0.png │ │ │ ├── Bronze 1.png │ │ │ ├── Bronze 2.png │ │ │ ├── Bronze 3.png │ │ │ ├── Bronze 4.png │ │ │ ├── Bronze 5.png │ │ │ ├── Diamond.png │ │ │ ├── Emerald.png │ │ │ ├── Silver 0.png │ │ │ ├── Silver 1.png │ │ │ ├── Silver 2.png │ │ │ ├── Silver 3.png │ │ │ ├── Silver 4.png │ │ │ ├── Silver 5.png │ │ │ ├── Platinum 0.png │ │ │ ├── Platinum 1.png │ │ │ ├── Platinum 2.png │ │ │ ├── Platinum 3.png │ │ │ ├── Platinum 4.png │ │ │ ├── Platinum 5.png │ │ │ └── Valhallan.png │ ├── icons │ │ ├── icon-192x192.png │ │ ├── icon-256x256.png │ │ ├── icon-384x384.png │ │ └── icon-512x512.png │ ├── robots.txt │ ├── sitemap.xml │ ├── sitemap-0.xml │ └── manifest.json ├── components │ ├── stats │ │ ├── player │ │ │ ├── Player2v2Tab │ │ │ │ └── index.tsx │ │ │ ├── PlayerLegendsTab │ │ │ │ └── index.ts │ │ │ ├── PlayerWeaponsTab │ │ │ │ └── index.ts │ │ │ └── PlayerOverviewTab │ │ │ │ └── index.ts │ │ ├── RatingDisplay.tsx │ │ ├── ProgressCard.tsx │ │ └── GamesDisplay.tsx │ ├── layout │ │ ├── AlertBar.tsx │ │ ├── SectionTitle.tsx │ │ ├── CollapsibleSection.tsx │ │ └── Layout.tsx │ ├── articles │ │ ├── ArticlePreviewGrid.tsx │ │ └── ArticlePreview.tsx │ ├── Image.tsx │ ├── BackToTopButton.tsx │ └── search │ │ ├── SearchboxItem.tsx │ │ └── SearchButton.tsx ├── postcss.config.js ├── next-sitemap.config.js ├── next-env.d.ts ├── pages │ ├── _error.tsx │ ├── 500.tsx │ ├── 404.tsx │ ├── api │ │ ├── stats │ │ │ ├── clan │ │ │ │ └── [clanId].ts │ │ │ └── player │ │ │ │ └── [playerId] │ │ │ │ ├── stats.ts │ │ │ │ ├── ranked.ts │ │ │ │ └── aliases.ts │ │ ├── weekly-rotation.ts │ │ ├── rankings │ │ │ ├── power.ts │ │ │ ├── index.ts │ │ │ ├── clans.ts │ │ │ └── search │ │ │ │ └── player.ts │ │ ├── bh-articles.ts │ │ └── trpc │ │ │ └── [trpc].ts │ └── @me │ │ └── favorites.tsx ├── hooks │ ├── useFeatures.ts │ ├── stats │ │ ├── useClan.ts │ │ ├── usePlayerRanked.ts │ │ ├── usePlayerStats.ts │ │ ├── useClansRankings.ts │ │ ├── usePlayerAliases.ts │ │ ├── usePlayerSearch.ts │ │ ├── usePowerRankings.ts │ │ └── useRankings.ts │ ├── useWeeklyRotation.ts │ └── useBrawlhallaArticles.ts ├── vercel.json ├── styles │ ├── nprogress.css │ └── globals.css ├── tsconfig.json ├── tailwind.config.js └── README.md ├── worker ├── .gitignore ├── reaccord.config.js ├── tsconfig.json ├── .env.example ├── src │ └── appa-bot │ │ └── channel-switcher │ │ └── roomNumbers.ts └── package.json ├── .vscode ├── settings.json └── extensions.json ├── pnpm-workspace.yaml ├── .eslintignore ├── .devcontainer ├── .gitignore ├── zsh │ ├── .zshrc │ └── devcontainer.zsh-theme ├── Dockerfile └── devcontainer.json ├── .prettierrc ├── .env.prod.example ├── .gitignore ├── turbo.json ├── .github └── workflows │ └── codeqa-analysis.yml ├── .eslintrc.yml ├── README.md ├── package.json └── setup.zx.mjs /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers=true -------------------------------------------------------------------------------- /packages/db/.gitignore: -------------------------------------------------------------------------------- 1 | generated/ -------------------------------------------------------------------------------- /packages/web-parser/index.ts: -------------------------------------------------------------------------------- 1 | export {} 2 | -------------------------------------------------------------------------------- /app/util/constants.ts: -------------------------------------------------------------------------------- 1 | export const MAX_SHOWN_ALIASES = 5 2 | -------------------------------------------------------------------------------- /worker/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | 4 | .reaccord -------------------------------------------------------------------------------- /app/public/ads.txt: -------------------------------------------------------------------------------- 1 | google.com, pub-3315371516287731, DIRECT, f08c47fec0942fa0 -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /packages/common/hooks/useWindowScroll.ts: -------------------------------------------------------------------------------- 1 | export { useWindowScroll } from "react-use" 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "app" 3 | - "worker" 4 | - "packages/*" 5 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .next/ 3 | .turbo/ 4 | dist/ 5 | build/ 6 | out/ 7 | generated/ -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "github.copilot" 4 | ] 5 | } -------------------------------------------------------------------------------- /app/components/stats/player/Player2v2Tab/index.tsx: -------------------------------------------------------------------------------- 1 | export { Player2v2Tab } from "./Player2v2Tab" 2 | -------------------------------------------------------------------------------- /app/public/images/BP3.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/BP3.webm -------------------------------------------------------------------------------- /app/public/images/BP4.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/BP4.webm -------------------------------------------------------------------------------- /app/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/logo.png -------------------------------------------------------------------------------- /app/components/stats/player/PlayerLegendsTab/index.ts: -------------------------------------------------------------------------------- 1 | export { PlayerLegendsTab } from "./PlayerLegendsTab" 2 | -------------------------------------------------------------------------------- /app/components/stats/player/PlayerWeaponsTab/index.ts: -------------------------------------------------------------------------------- 1 | export { PlayerWeaponsTab } from "./PlayerWeaponsTab" 2 | -------------------------------------------------------------------------------- /app/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/favicon.png -------------------------------------------------------------------------------- /packages/db/prisma/extensions.sql: -------------------------------------------------------------------------------- 1 | DROP EXTENSION IF EXISTS pg_trgm CASCADE; 2 | 3 | CREATE EXTENSION pg_trgm; -------------------------------------------------------------------------------- /packages/server/helpers/commonOptions.ts: -------------------------------------------------------------------------------- 1 | export type CommonOptions = { 2 | abortSignal: AbortSignal 3 | } 4 | -------------------------------------------------------------------------------- /.devcontainer/.gitignore: -------------------------------------------------------------------------------- 1 | volumes/db/data 2 | volumes/db/init/data.sql 3 | volumes/storage 4 | .env 5 | test.http 6 | -------------------------------------------------------------------------------- /app/components/stats/player/PlayerOverviewTab/index.ts: -------------------------------------------------------------------------------- 1 | export { PlayerOverviewTab } from "./PlayerOverviewTab" 2 | -------------------------------------------------------------------------------- /app/public/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/icons/icon-192x192.png -------------------------------------------------------------------------------- /app/public/icons/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/icons/icon-256x256.png -------------------------------------------------------------------------------- /app/public/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/icons/icon-384x384.png -------------------------------------------------------------------------------- /app/public/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/icons/icon-512x512.png -------------------------------------------------------------------------------- /app/public/images/Ada Landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/Ada Landing.png -------------------------------------------------------------------------------- /app/public/images/errors/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/errors/404.png -------------------------------------------------------------------------------- /app/public/images/errors/500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/errors/500.png -------------------------------------------------------------------------------- /app/public/images/og/main-og.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/og/main-og.jpg -------------------------------------------------------------------------------- /app/public/images/Nix Landing.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/Nix Landing.webp -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "printWidth": 80, 4 | "trailingComma": "all", 5 | "tabWidth": 4 6 | } 7 | -------------------------------------------------------------------------------- /app/public/images/Bodvar Landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/Bodvar Landing.png -------------------------------------------------------------------------------- /app/public/images/Corehalla_Logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/Corehalla_Logo.gif -------------------------------------------------------------------------------- /app/public/images/Landing_Preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/Landing_Preview.jpg -------------------------------------------------------------------------------- /app/public/images/icons/flags/ALL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/ALL.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/AUS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/AUS.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/BRZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/BRZ.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/EU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/EU.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/JPN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/JPN.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/ME.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/ME.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/SA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/SA.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/SEA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/SEA.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/US-E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/US-E.png -------------------------------------------------------------------------------- /app/public/images/icons/flags/US-W.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/flags/US-W.png -------------------------------------------------------------------------------- /app/public/images/Landing Podium 3D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/Landing Podium 3D.png -------------------------------------------------------------------------------- /app/public/images/backgrounds/orion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/backgrounds/orion.jpg -------------------------------------------------------------------------------- /app/public/images/icons/legends/Ada.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Ada.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Dusk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Dusk.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Fait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Fait.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Jiro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Jiro.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Kaya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Kaya.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Koji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Koji.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Kor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Kor.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Nix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Nix.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Onyx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Onyx.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Thor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Thor.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Val.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Val.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Vivi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Vivi.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Xull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Xull.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Tin 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Tin 0.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Tin 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Tin 1.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Tin 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Tin 2.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Tin 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Tin 3.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Tin 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Tin 4.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Tin 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Tin 5.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Axe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Axe.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Bow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Bow.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Orb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Orb.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Artemis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Artemis.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Asuri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Asuri.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Azoth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Azoth.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Barraza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Barraza.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Brynn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Brynn.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Bödvar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Bödvar.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Caspian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Caspian.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Cassidy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Cassidy.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Cross.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Diana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Diana.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Ember.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Ember.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Gnash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Gnash.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Hattori.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Hattori.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Imuji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Imuji.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Isaiah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Isaiah.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Jaeyun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Jaeyun.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Jhala.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Jhala.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Lin Fei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Lin Fei.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Lucien.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Lucien.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Mirage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Mirage.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Mordex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Mordex.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Orion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Orion.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Petra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Petra.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Priya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Priya.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Ragnir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Ragnir.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Rayman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Rayman.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Scarlet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Scarlet.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Seven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Seven.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Sidra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Sidra.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Teros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Teros.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Thatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Thatch.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Ulgrim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Ulgrim.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Vector.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Volkov.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Volkov.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Yumiko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Yumiko.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Zariel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Zariel.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Bronze 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Bronze 0.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Bronze 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Bronze 1.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Bronze 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Bronze 2.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Bronze 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Bronze 3.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Bronze 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Bronze 4.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Bronze 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Bronze 5.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Diamond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Diamond.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Gold 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Gold 0.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Gold 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Gold 1.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Gold 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Gold 2.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Gold 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Gold 3.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Gold 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Gold 4.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Gold 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Gold 5.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Silver 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Silver 0.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Silver 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Silver 1.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Silver 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Silver 2.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Silver 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Silver 3.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Silver 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Silver 4.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Silver 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Silver 5.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Cannon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Cannon.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Chakram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Chakram.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Katars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Katars.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Scythe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Scythe.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Spear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Spear.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Sword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Sword.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Unarmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Unarmed.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Gold 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Gold 0.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Gold 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Gold 1.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Gold 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Gold 2.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Gold 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Gold 3.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Gold 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Gold 4.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Gold 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Gold 5.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Tin 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Tin 0.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Tin 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Tin 1.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Tin 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Tin 2.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Tin 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Tin 3.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Tin 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Tin 4.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Tin 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Tin 5.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/null.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/null.png -------------------------------------------------------------------------------- /packages/common/helpers/classnames.ts: -------------------------------------------------------------------------------- 1 | import classnames from "classnames" 2 | 3 | export const cn: typeof classnames = classnames 4 | -------------------------------------------------------------------------------- /app/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /app/public/images/icons/legends/King zuva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/King zuva.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Queen Nai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Queen Nai.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Sentinel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Sentinel.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Wu Shang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Wu Shang.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Platinum 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Platinum 0.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Platinum 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Platinum 1.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Platinum 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Platinum 2.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Platinum 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Platinum 3.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Platinum 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Platinum 4.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Platinum 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Platinum 5.png -------------------------------------------------------------------------------- /app/public/images/icons/ranked/Valhallan.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/ranked/Valhallan.webp -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Blasters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Blasters.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Gauntlets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Gauntlets.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Bronze 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Bronze 0.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Bronze 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Bronze 1.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Bronze 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Bronze 2.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Bronze 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Bronze 3.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Bronze 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Bronze 4.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Bronze 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Bronze 5.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Diamond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Diamond.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Emerald.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Emerald.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Silver 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Silver 0.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Silver 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Silver 1.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Silver 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Silver 2.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Silver 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Silver 3.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Silver 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Silver 4.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Silver 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Silver 5.png -------------------------------------------------------------------------------- /packages/bhapi/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/logger/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/web-parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/base.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /worker/reaccord.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('reaccord').ReaccordConfig} */ 2 | module.exports = { 3 | entry: "./src/index.ts", 4 | } 5 | -------------------------------------------------------------------------------- /.devcontainer/zsh/.zshrc: -------------------------------------------------------------------------------- 1 | ZSH_THEME="devcontainer" 2 | 3 | plugins=(git) 4 | 5 | source $HOME/.oh-my-zsh/oh-my-zsh.sh 6 | 7 | cd /workspace 8 | -------------------------------------------------------------------------------- /app/public/images/backgrounds/Wallpaper_Text.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/backgrounds/Wallpaper_Text.jpg -------------------------------------------------------------------------------- /app/public/images/icons/legends/Lord Vraxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Lord Vraxx.png -------------------------------------------------------------------------------- /app/public/images/icons/legends/Sir Roland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/legends/Sir Roland.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Po.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Po.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/ada.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/ada.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/asuri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/asuri.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/azoth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/azoth.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/brynn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/brynn.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/cross.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/diana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/diana.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/dusk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/dusk.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/ember.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/ember.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/ezio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/ezio.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/fait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/fait.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/gnash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/gnash.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/imuji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/imuji.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/jhala.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/jhala.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/jiro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/jiro.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/kaya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/kaya.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/koji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/koji.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/kor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/kor.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/loki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/loki.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/mako.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/mako.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/munin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/munin.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/nix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/nix.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/onyx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/onyx.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/orion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/orion.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/petra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/petra.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/priya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/priya.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/reno.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/reno.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/seven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/seven.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/sidra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/sidra.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/teros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/teros.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/tezca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/tezca.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/thea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/thea.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/thor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/thor.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/val.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/val.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/vivi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/vivi.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/xull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/xull.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Battle Boots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Battle Boots.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Greatsword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Greatsword.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Rocket Lance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Rocket Lance.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Platinum 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Platinum 0.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Platinum 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Platinum 1.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Platinum 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Platinum 2.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Platinum 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Platinum 3.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Platinum 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Platinum 4.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Platinum 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Platinum 5.png -------------------------------------------------------------------------------- /app/public/images/ranked-banners/Valhallan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/ranked-banners/Valhallan.png -------------------------------------------------------------------------------- /packages/common/helpers/math.ts: -------------------------------------------------------------------------------- 1 | export const clamp = (value: number, min: number, max: number) => 2 | Math.min(Math.max(value, min), max) 3 | -------------------------------------------------------------------------------- /packages/dl-roster-images/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/base.json", 3 | "include": ["."], 4 | "exclude": ["node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/tsconfig/README.md: -------------------------------------------------------------------------------- 1 | # `tsconfig` 2 | 3 | These are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from. 4 | -------------------------------------------------------------------------------- /app/public/images/backgrounds/Wallpaper_NoText.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/backgrounds/Wallpaper_NoText.jpg -------------------------------------------------------------------------------- /app/public/images/backgrounds/Wallpaper_TextSm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/backgrounds/Wallpaper_TextSm.jpg -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Blue.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Cyan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Cyan.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Gray.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Pink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Pink.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Red.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Aang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Aang.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Finn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Finn.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Jake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Jake.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Ken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Ken.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Luke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Luke.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Rick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Rick.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Ryu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Ryu.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Toph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Toph.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Zuko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Zuko.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/arcadia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/arcadia.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/artemis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/artemis.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/barraza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/barraza.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/bodvar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/bodvar.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/caspian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/caspian.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/cassidy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/cassidy.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/hattori.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/hattori.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/isaiah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/isaiah.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/jaeyun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/jaeyun.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/lin fei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/lin fei.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/lucien.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/lucien.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/magyar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/magyar.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/mirage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/mirage.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/mordex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/mordex.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/ragnir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/ragnir.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/rayman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/rayman.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/scarlet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/scarlet.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/thatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/thatch.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/ulgrim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/ulgrim.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/vector.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/volkov.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/volkov.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/yumiko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/yumiko.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/zariel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/zariel.png -------------------------------------------------------------------------------- /app/public/images/icons/weapons/Grapple Hammer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/weapons/Grapple Hammer.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Black.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Brown.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Classic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Classic.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Green.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Orange.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Purple.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Sunset.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_White.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_White.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Yellow.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Akuma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Akuma.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Alucard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Alucard.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Asuka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Asuka.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Barbara.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Barbara.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Chun Li.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Chun Li.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Daimio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Daimio.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Daryl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Daryl.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Dhalsim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Dhalsim.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Eivor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Eivor.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Garnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Garnet.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Globox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Globox.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Hellboy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Hellboy.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Maggie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Maggie.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Negan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Negan.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Nimue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Nimue.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Pearl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Pearl.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Raphael.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Raphael.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Sakura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Sakura.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Tigress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Tigress.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/king zuva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/king zuva.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/lord vraxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/lord vraxx.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/queen nai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/queen nai.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/redraptor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/redraptor.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/sentinel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/sentinel.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/sir roland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/sir roland.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/legends/wu shang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/legends/wu shang.png -------------------------------------------------------------------------------- /packages/db/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["node_modules", "generated"] 5 | } 6 | -------------------------------------------------------------------------------- /app/public/images/icons/colors/37px-Color_Home_Team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/37px-Color_Home_Team.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Community.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Haunting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Haunting.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Heatwave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Heatwave.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Skyforged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Skyforged.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Team_Blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Team_Blue.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Team_Red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Team_Red.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Amethyst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Amethyst.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Donatello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Donatello.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Four Arms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Four Arms.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Gruagach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Gruagach.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Heatblast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Heatblast.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/John Cena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/John Cena.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Leonardo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Leonardo.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/M. Bison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/M. Bison.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Macho Man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Macho Man.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Michonne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Michonne.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Stevonnie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Stevonnie.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Tai Lung.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Tai Lung.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/The Rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/The Rock.png -------------------------------------------------------------------------------- /packages/common/helpers/formatBalance.ts: -------------------------------------------------------------------------------- 1 | export const formatBalance = (balance: number) => 2 | balance.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") 3 | -------------------------------------------------------------------------------- /packages/db/prisma/auth_user_trigger_rm.sql: -------------------------------------------------------------------------------- 1 | -- AddForeignKey 2 | alter table if exists public."UserProfile" drop constraint if exists "UserProfile_userId_fkey"; -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Goldforged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Goldforged.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Lovestruck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Lovestruck.png -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Lucky_Clover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Lucky_Clover.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Becky Lynch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Becky Lynch.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Black Knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Black Knight.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Diamondhead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Diamondhead.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Enchantress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Enchantress.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/King Knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/King Knight.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Lara Croft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Lara Croft.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Michelangelo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Michelangelo.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Roman Reigns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Roman Reigns.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Snake Eyes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Snake Eyes.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Storm Shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Storm Shadow.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Xavier Woods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Xavier Woods.png -------------------------------------------------------------------------------- /packages/bhapi/helpers/calculateWinrate.ts: -------------------------------------------------------------------------------- 1 | export const calculateWinrate = (wins: number, games: number): number => 2 | (games === 0 ? 0 : wins / games) * 100 3 | -------------------------------------------------------------------------------- /app/public/images/icons/colors/50px-Color_Winter_Holiday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/colors/50px-Color_Winter_Holiday.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Plague Knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Plague Knight.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Shovel Knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Shovel Knight.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Simon Belmont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Simon Belmont.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Specter Knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Specter Knight.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/The Undertaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/The Undertaker.png -------------------------------------------------------------------------------- /app/public/images/icons/roster/crossovers/Princess Bubblegum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djobbo/corehalla/HEAD/app/public/images/icons/roster/crossovers/Princess Bubblegum.png -------------------------------------------------------------------------------- /packages/db/prisma/migrations/20221014212935_clan_xp_string_to_number/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "BHClan" 3 | ALTER COLUMN "xp" TYPE INT 4 | USING "xp"::integer; 5 | -------------------------------------------------------------------------------- /packages/db/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /packages/web-parser/weekly-rotation/dev.ts: -------------------------------------------------------------------------------- 1 | import { getWeeklyRotation } from "./getWeeklyRotation" 2 | import { logInfo } from "logger" 3 | 4 | getWeeklyRotation().then(logInfo) 5 | -------------------------------------------------------------------------------- /app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # * 2 | User-agent: * 3 | Allow: / 4 | 5 | # Host 6 | Host: http://localhost:3000 7 | 8 | # Sitemaps 9 | Sitemap: http://localhost:3000/sitemap.xml 10 | -------------------------------------------------------------------------------- /packages/db/prisma/migrations/20221013181657_remove_player_alias_relation/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropForeignKey 2 | ALTER TABLE "BHPlayerAlias" DROP CONSTRAINT "BHPlayerAlias_playerId_fkey"; 3 | -------------------------------------------------------------------------------- /packages/common/helpers/validators.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | 3 | export const numericLiteralValidator = z 4 | .string() 5 | .regex(/^[0-9]+$/) 6 | .transform((page) => parseInt(page)) 7 | -------------------------------------------------------------------------------- /packages/db/prisma/migrations/20221210182655_make_clan_created_at_optional/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "BHClan" ALTER COLUMN "created" DROP NOT NULL, 3 | ALTER COLUMN "created" SET DEFAULT -1; 4 | -------------------------------------------------------------------------------- /app/public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | http://localhost:3000/sitemap-0.xml 4 | -------------------------------------------------------------------------------- /packages/common/helpers/cleanString.ts: -------------------------------------------------------------------------------- 1 | export const cleanString = (str: string): string => { 2 | try { 3 | return decodeURIComponent(escape(str)) 4 | } catch (e) { 5 | return str 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/web-parser/bh-articles/dev.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | import { parseBHArticlesPage } from "./parseBHArticlesPage" 3 | 4 | parseBHArticlesPage(1, "patch-notes").then((data) => logInfo(data[0])) 5 | -------------------------------------------------------------------------------- /packages/web-parser/power-rankings/dev.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | import { parsePowerRankingsPage } from "./parsePowerRankingsPage" 3 | 4 | parsePowerRankingsPage("2v2", "us-e").then((data) => logInfo(data[0])) 5 | -------------------------------------------------------------------------------- /app/next-sitemap.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next-sitemap').IConfig} */ 2 | module.exports = { 3 | siteUrl: process.env.SITE_URL ?? "https://dev.corehalla.com", 4 | generateRobotsTxt: true, 5 | priority: 1.0, 6 | } 7 | -------------------------------------------------------------------------------- /packages/common/helpers/isValueInEnum.ts: -------------------------------------------------------------------------------- 1 | export const isValueInEnum = 2 | (enumType: EnumType) => 3 | (value: unknown): value is EnumType => 4 | Object.values(enumType).includes(value) 5 | -------------------------------------------------------------------------------- /app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /packages/server/trpc.ts: -------------------------------------------------------------------------------- 1 | import { initTRPC } from "@trpc/server" 2 | 3 | const t = initTRPC.create() 4 | 5 | export const middleware = t.middleware 6 | export const router = t.router 7 | export const publicProcedure = t.procedure 8 | -------------------------------------------------------------------------------- /packages/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsconfig", 3 | "version": "0.0.0", 4 | "private": true, 5 | "main": "base.json", 6 | "files": [ 7 | "base.json", 8 | "nextjs.json" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /app/pages/_error.tsx: -------------------------------------------------------------------------------- 1 | import { ErrorPageContent } from "@components/layout/ErrorPageContent" 2 | import type { NextPage } from "next" 3 | 4 | const ErrorPage: NextPage = () => { 5 | return 6 | } 7 | 8 | export default ErrorPage 9 | -------------------------------------------------------------------------------- /packages/web-parser/weekly-rotation/weeklyRotationMock.ts: -------------------------------------------------------------------------------- 1 | export const weeklyRotationMock = [ 2 | "Mako", 3 | "Jhala", 4 | "Kor", 5 | "Barraza", 6 | "Munin", 7 | "Vector", 8 | "Cassidy", 9 | "Onyx", 10 | "Dusk", 11 | ] 12 | -------------------------------------------------------------------------------- /app/pages/500.tsx: -------------------------------------------------------------------------------- 1 | import { ErrorPageContent } from "@components/layout/ErrorPageContent" 2 | import type { NextPage } from "next" 3 | 4 | const ErrorPage: NextPage = () => { 5 | return 6 | } 7 | 8 | export default ErrorPage 9 | -------------------------------------------------------------------------------- /app/hooks/useFeatures.ts: -------------------------------------------------------------------------------- 1 | import { getFeatureFlags } from "@util/features" 2 | import { useAuth } from "@ctx/auth/AuthProvider" 3 | 4 | export const useFeatureFlags = () => { 5 | const authContext = useAuth() 6 | 7 | return getFeatureFlags({ authContext }) 8 | } 9 | -------------------------------------------------------------------------------- /packages/db/supabase/service.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from "@supabase/supabase-js" 2 | 3 | export const supabaseService = createClient( 4 | process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL ?? "", 5 | process.env.SUPABASE_SERVICE_KEY ?? "", 6 | ) 7 | -------------------------------------------------------------------------------- /packages/db/prisma/migrations/20221209172429_bhplayer_alias_createdat_and_public/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "BHPlayerAlias" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 3 | ADD COLUMN "public" BOOLEAN NOT NULL DEFAULT true; 4 | -------------------------------------------------------------------------------- /app/hooks/stats/useClan.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | 3 | export const useClan = (clanId: string) => { 4 | const { data, ...query } = trpc.getClanStats.useQuery({ clanId }) 5 | 6 | return { 7 | clan: data, 8 | ...query, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "pages/**/*.ts": { 4 | "memory": 1024, 5 | "maxDuration": 4 6 | }, 7 | "pages/**/*.tsx": { 8 | "memory": 1024, 9 | "maxDuration": 4 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /app/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import { ErrorPageContent } from "@components/layout/ErrorPageContent" 2 | import type { NextPage } from "next" 3 | 4 | const ErrorPage: NextPage = () => { 5 | return 6 | } 7 | 8 | export default ErrorPage 9 | -------------------------------------------------------------------------------- /packages/db/prisma/realtime_setup.sql: -------------------------------------------------------------------------------- 1 | -- Setup supabase realtime 2 | 3 | begin; 4 | drop publication if exists supabase_realtime; 5 | 6 | create publication supabase_realtime 7 | for table public."UserProfile", public."UserFavorite", public."UserConnection"; 8 | commit; 9 | -------------------------------------------------------------------------------- /packages/db/supabase/client.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from "@supabase/supabase-js" 2 | export type { Session, User } from "@supabase/supabase-js" 3 | 4 | export const supabase = createClient( 5 | process.env.NEXT_PUBLIC_SUPABASE_URL ?? "", 6 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? "", 7 | ) 8 | -------------------------------------------------------------------------------- /app/hooks/stats/usePlayerRanked.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | 3 | export const usePlayerRanked = (playerId: string) => { 4 | const { data, ...query } = trpc.getPlayerRanked.useQuery({ playerId }) 5 | 6 | return { 7 | playerRanked: data, 8 | ...query, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/hooks/stats/usePlayerStats.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | 3 | export const usePlayerStats = (playerId: string) => { 4 | const { data, ...query } = trpc.getPlayerStats.useQuery({ playerId }) 5 | 6 | return { 7 | playerStats: data, 8 | ...query, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.env.prod.example: -------------------------------------------------------------------------------- 1 | # Corehalla environment variables 2 | 3 | BRAWLHALLA_API_KEY=SUPER_SECRET_API_KEY 4 | 5 | NEXT_PUBLIC_SUPABASE_URL=SUPABASE_URL 6 | NEXT_PUBLIC_SUPABASE_ANON_KEY=SUPABASE_ANON_KEY 7 | SUPABASE_SERVICE_KEY=SUPER_SECRET_SUPABASE_SERVICE_KEY 8 | DATABASE_URL=DATABASE_URL 9 | 10 | NEXT_PUBLIC_API_URL=API_URL 11 | -------------------------------------------------------------------------------- /packages/logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logger", 3 | "version": "0.0.0", 4 | "main": "index.ts", 5 | "devDependencies": { 6 | "@types/node": "^20.11.5", 7 | "tsconfig": "workspace:*", 8 | "typescript": "^5.3.3" 9 | }, 10 | "scripts": { 11 | "ts:check": "tsc --noEmit" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/hooks/stats/useClansRankings.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | 3 | export const useClansRankings = (page: string, name: string) => { 4 | const { data, ...query } = trpc.getClansRankings.useQuery({ 5 | name, 6 | page, 7 | }) 8 | 9 | return { 10 | clans: data ?? [], 11 | ...query, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/server/helpers/constants.ts: -------------------------------------------------------------------------------- 1 | const __DEV = process.env.NODE_ENV === "development" 2 | 3 | export const SEARCH_PLAYERS_ALIASES_PER_PAGE = 50 4 | export const CLANS_RANKINGS_PER_PAGE = __DEV ? 3 : 50 5 | export const GLOBAL_PLAYER_RANKINGS_PER_PAGE = 50 6 | export const GLOBAL_LEGENDS_RANKINGS_PER_PAGE = 50 7 | export const GLOBAL_WEAPONS_RANKINGS_PER_PAGE = 50 8 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y \ 5 | curl \ 6 | zsh 7 | 8 | RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 9 | 10 | RUN npm install -g pnpm 11 | 12 | ENV NODE_ENV development 13 | 14 | RUN git config --global --add safe.directory /workspace 15 | -------------------------------------------------------------------------------- /app/hooks/useWeeklyRotation.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | 3 | export const useWeeklyRotation = () => { 4 | const { data, ...query } = trpc.getWeeklyRotation.useQuery(void 0, { 5 | trpc: { 6 | ssr: false, 7 | }, 8 | }) 9 | 10 | return { 11 | weeklyRotation: data ?? [], 12 | ...query, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/db/discord/client.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | 3 | const DISCORD_API_URL = "https://discord.com/api" 4 | 5 | export const discordApi = { 6 | get: (discordToken: string, url: `/${string}`) => 7 | axios.get(`${DISCORD_API_URL}${url}`, { 8 | headers: { 9 | Authorization: `Bearer ${discordToken}`, 10 | }, 11 | }), 12 | } 13 | -------------------------------------------------------------------------------- /packages/bhapi/helpers/getTierFromRating.ts: -------------------------------------------------------------------------------- 1 | import { rankedTiers } from "../constants" 2 | 3 | export const getTierFromRating = (rating: number) => 4 | (rankedTiers.find((r) => rating >= r[1]) || 5 | rankedTiers[rankedTiers.length - 1])[0] 6 | 7 | export const getMiniTierFromRating = (rating: number) => { 8 | const tier = getTierFromRating(rating) 9 | return tier[0] + (tier.split(" ")[1] ?? "") 10 | } 11 | -------------------------------------------------------------------------------- /packages/ui/theme/theme.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bgVar2: "#1A1B23", 3 | bgVar1: "#1E212C", 4 | bg: "#2B3043", 5 | bgLanding: "#1A1B23AA", 6 | textVar1: "#CCD0D6", 7 | text: "#FFFFFF", 8 | accent: "#3861FB", 9 | accentVar1: "#2095F2", 10 | success: "#24CD7C", 11 | danger: "#ED7853", 12 | warning: "#F3DA57", 13 | accentAlt: "#E568D9", 14 | accentAltVar1: "#FF99E9", 15 | } 16 | -------------------------------------------------------------------------------- /packages/common/hooks/useCopyToClipboard.ts: -------------------------------------------------------------------------------- 1 | export const useCopyToClipboard = () => { 2 | const copyToClipboard = async (text: string) => { 3 | if (!navigator?.clipboard) return false 4 | 5 | try { 6 | await navigator.clipboard.writeText(text) 7 | return true 8 | } catch (error) { 9 | return false 10 | } 11 | } 12 | 13 | return copyToClipboard 14 | } 15 | -------------------------------------------------------------------------------- /packages/server/router/getWeeklyRotation.ts: -------------------------------------------------------------------------------- 1 | import { getWeeklyRotation as getWeeklyRotationFn } from "web-parser/common" 2 | import { logInfo } from "logger" 3 | import { publicProcedure } from "../trpc" 4 | 5 | export const getWeeklyRotation = publicProcedure // 6 | .query(async () => { 7 | logInfo("getWeeklyRotation") 8 | 9 | const rotation = await getWeeklyRotationFn() 10 | 11 | return rotation 12 | }) 13 | -------------------------------------------------------------------------------- /worker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "esModuleInterop": true, 5 | "allowJs": true, 6 | "lib": ["esnext", "dom"], 7 | "moduleResolution": "node", 8 | "jsx": "react-jsx", 9 | "target": "es6", 10 | "skipLibCheck": true, 11 | "sourceMap": false, 12 | "outDir": "dist", 13 | }, 14 | "include": ["src"], 15 | "exclude": ["node_modules"] 16 | } 17 | -------------------------------------------------------------------------------- /app/styles/nprogress.css: -------------------------------------------------------------------------------- 1 | /* Make clicks pass-through */ 2 | #nprogress { 3 | pointer-events: none; 4 | } 5 | 6 | #nprogress .bar { 7 | background: #ffffffaa; 8 | 9 | position: fixed; 10 | z-index: 5000; 11 | top: 0; 12 | left: 0; 13 | 14 | width: 100%; 15 | height: 2px; 16 | } 17 | 18 | .nprogress-custom-parent { 19 | overflow: hidden; 20 | position: relative; 21 | } 22 | 23 | .nprogress-custom-parent #nprogress .bar { 24 | position: absolute; 25 | } -------------------------------------------------------------------------------- /worker/.env.example: -------------------------------------------------------------------------------- 1 | # Discord Manager Bot 2 | DISCORD_MANAGER_BOT_TOKEN=DISCORD_MANAGER_BOT_TOKEN 3 | DISCORD_MANAGER_BOT_DEV_GUILD_ID=DISCORD_MANAGER_BOT_GUILD_ID 4 | DISCORD_MANAGER_BOT_CLIENT_ID=DISCORD_MANAGER_BOT_CLIENT_ID 5 | DISCORD_CHANNEL_SWITCHER_VOICE_LOGS_CHANNEL_ID=DISCORD_CHANNEL_SWITCHER_VOICE_LOGS_CHANNEL_ID 6 | DISCORD_CHANNEL_SWITCHER_GENERATOR_CATEGORY_ID=DISCORD_CHANNEL_SWITCHER_GENERATOR_CATEGORY_ID 7 | DISCORD_CHANNEL_SWITCHER_LOBBYS_CATEGORY_ID=DISCORD_CHANNEL_SWITCHER_LOBBYS_CATEGORY_ID 8 | -------------------------------------------------------------------------------- /packages/db/prisma/migrations/20221121232634_unarmed_matchtime/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `rank` on the `BHPlayerData` table. All the data in the column will be lost. 5 | - Added the required column `matchTimeUnarmed` to the `BHPlayerData` table without a default value. This is not possible if the table is not empty. 6 | 7 | */ 8 | -- AlterTable 9 | ALTER TABLE "BHPlayerData" DROP COLUMN "rank", 10 | ADD COLUMN "matchTimeUnarmed" INTEGER NOT NULL; 11 | -------------------------------------------------------------------------------- /packages/server/helpers/withTimeLog.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | 3 | export const withTimeLog = ( 4 | request: (...args: TArgs) => Promise, 5 | name: string, 6 | ) => { 7 | return async (...args: TArgs) => { 8 | const start = Date.now() 9 | const result = await request(...args) 10 | const end = Date.now() 11 | logInfo(`[TIME_LOG] ${name} | ${end - start}ms`) 12 | return result 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/bhapi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bhapi", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@types/node": "^20.11.5", 6 | "tsconfig": "workspace:*", 7 | "typescript": "^5.3.3" 8 | }, 9 | "scripts": { 10 | "ts:check": "tsc --noEmit" 11 | }, 12 | "dependencies": { 13 | "axios": "1.1.3", 14 | "common": "workspace:*", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "zod": "^3.22.4" 18 | } 19 | } -------------------------------------------------------------------------------- /app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": [ 4 | "next-env.d.ts", 5 | "**/*.ts", 6 | "**/*.tsx" 7 | ], 8 | "exclude": [ 9 | "node_modules" 10 | ], 11 | "compilerOptions": { 12 | "baseUrl": ".", 13 | "paths": { 14 | "@hooks/*": [ 15 | "hooks/*" 16 | ], 17 | "@components/*": [ 18 | "components/*" 19 | ], 20 | "@ctx/*": [ 21 | "providers/*" 22 | ], 23 | "@util/*": [ 24 | "util/*" 25 | ] 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/hooks/stats/usePlayerAliases.ts: -------------------------------------------------------------------------------- 1 | import { cleanString } from "common/helpers/cleanString" 2 | import { trpc } from "@util/trpc" 3 | 4 | export const usePlayerAliases = (playerId: string) => { 5 | const { data, ...query } = trpc.getPlayerAliases.useQuery({ playerId }) 6 | 7 | return { 8 | playerAliases: 9 | data 10 | ?.map((alias) => cleanString(alias)) 11 | .filter( 12 | (alias) => alias.length >= 2 && !alias.endsWith("•2"), 13 | ) ?? [], 14 | ...query, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/db/supabase/auth.ts: -------------------------------------------------------------------------------- 1 | import { supabase } from "./client" 2 | 3 | export const signIn = async () => { 4 | const { error } = await supabase.auth.signIn( 5 | { provider: "discord" }, 6 | { 7 | scopes: "identify email connections guilds", 8 | redirectTo: window.location.href, 9 | }, 10 | ) 11 | 12 | if (error) throw new Error(error.message) 13 | } 14 | 15 | export const signOut = async () => { 16 | const { error } = await supabase.auth.signOut() 17 | 18 | if (error) throw new Error(error.message) 19 | } 20 | -------------------------------------------------------------------------------- /packages/common/helpers/arrayToMap.ts: -------------------------------------------------------------------------------- 1 | export const arrayToMap = ( 2 | arr: (T & { [k in Key]: string | number | symbol })[], 3 | key: Key, 4 | // @ts-expect-error ts doesn't know that T[Key] is a string | number | symbol 5 | ): Record => 6 | // @ts-expect-error ts doesn't know that T[Key] is a string | number | symbol 7 | arr.reduce>( 8 | (obj, item) => ((obj[item[key]] = item), obj), 9 | // @ts-expect-error ts doesn't know that T[Key] is a string | number | symbol 10 | {}, 11 | ) 12 | -------------------------------------------------------------------------------- /app/hooks/stats/usePlayerSearch.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | 3 | export const usePlayerSearch = (search: string) => { 4 | // BMG DB Destroyer 🤦 5 | // const { rankings1v1, isLoading } = useRankings1v1("all", "1", search, { 6 | // enabled: !!search, 7 | // }) 8 | const { data: aliases, isLoading } = trpc.searchPlayerAlias.useQuery( 9 | { alias: search, page: "1" }, 10 | { enabled: !!search }, 11 | ) 12 | 13 | return { 14 | rankings1v1: [], 15 | isLoading, 16 | aliases: aliases ?? [], 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/server/mutations/updateDBClanData.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | import { supabaseService } from "db/supabase/service" 3 | import type { BHClan } from "db/generated/client" 4 | import type { CommonOptions } from "../helpers/commonOptions" 5 | 6 | export const updateDBClanData = async ( 7 | clan: Partial, 8 | options: CommonOptions, 9 | ) => { 10 | logInfo("updateDBClanData", { clanId: clan.id }) 11 | 12 | await supabaseService 13 | .from("BHClan") 14 | .upsert(clan) 15 | .abortSignal(options.abortSignal) 16 | } 17 | -------------------------------------------------------------------------------- /packages/ui/base/AppLink.tsx: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-restricted-imports 2 | import Link from "next/link" 3 | import type { AnchorHTMLAttributes } from "react" 4 | 5 | type AppLinkProps = AnchorHTMLAttributes & { href: string } 6 | 7 | export const AppLink = ({ href, children, ...props }: AppLinkProps) => { 8 | return ( 9 | 15 | {children} 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /app/tailwind.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const colors = require("ui/theme/theme") 3 | 4 | module.exports = { 5 | content: [ 6 | "./pages/**/*.{js,ts,jsx,tsx}", 7 | "./components/**/*.{js,ts,jsx,tsx}", 8 | "../packages/ui/theme/**/*.{js,ts,jsx,tsx}", 9 | "../packages/ui/base/**/*.{js,ts,jsx,tsx}", 10 | ], 11 | theme: { 12 | extend: { 13 | colors, 14 | screens: { 15 | hashover: { raw: "(hover: hover)" }, 16 | }, 17 | }, 18 | }, 19 | plugins: [], 20 | } 21 | -------------------------------------------------------------------------------- /app/components/layout/AlertBar.tsx: -------------------------------------------------------------------------------- 1 | import { InfoIcon } from "ui/icons" 2 | import { alerts } from "@util/alerts" 3 | 4 | const CURRENT_ALERT = process.env.NEXT_PUBLIC_ALERT as 5 | | keyof typeof alerts 6 | | undefined 7 | 8 | export const AlertBar = () => { 9 | if (!CURRENT_ALERT) return null 10 | 11 | const alertContent = alerts[CURRENT_ALERT] 12 | 13 | if (!alertContent) return null 14 | 15 | return ( 16 |
17 | {alertContent} 18 |
19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /packages/common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "common", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@types/node": "^20.11.5", 6 | "@types/react": "^18.2.31", 7 | "tsconfig": "workspace:*", 8 | "typescript": "^5.3.3" 9 | }, 10 | "scripts": { 11 | "ts:check": "tsc --noEmit" 12 | }, 13 | "dependencies": { 14 | "classnames": "^2.5.1", 15 | "dayjs": "^1.11.7", 16 | "next": "13.4.19", 17 | "react": "^18.2.0", 18 | "react-dom": "^18.2.0", 19 | "react-use": "^17.4.0", 20 | "zod": "^3.22.4" 21 | } 22 | } -------------------------------------------------------------------------------- /app/hooks/useBrawlhallaArticles.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | import type { BrawlhallaArticleCategory } from "web-parser/common" 3 | 4 | export const useBrawlhallaArticles = ( 5 | first?: number, 6 | category?: BrawlhallaArticleCategory, 7 | ) => { 8 | const { data, ...query } = trpc.getBHArticles.useQuery( 9 | { 10 | category, 11 | first, 12 | }, 13 | { 14 | trpc: { 15 | ssr: false, 16 | }, 17 | }, 18 | ) 19 | 20 | return { 21 | articles: data ?? [], 22 | ...query, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/bhapi/helpers/getPlayerAliases.ts: -------------------------------------------------------------------------------- 1 | import { cleanString } from "common/helpers/cleanString" 2 | import { getPlayerTeam } from "./getTeamPlayers" 3 | import type { PlayerRanked, PlayerStats } from "../types" 4 | 5 | export const getPlayerAliases = ( 6 | playerStats: PlayerStats, 7 | playerRanked?: PlayerRanked, 8 | ) => [ 9 | ...new Set([ 10 | cleanString(playerStats.name), 11 | ...(playerRanked?.["2v2"].map((team) => 12 | cleanString( 13 | getPlayerTeam(playerRanked.brawlhalla_id, team).playerName, 14 | ), 15 | ) ?? []), 16 | ]), 17 | ] 18 | -------------------------------------------------------------------------------- /packages/ui/base/Progress.tsx: -------------------------------------------------------------------------------- 1 | import { Indicator as ProgressIndicator, Root } from "@radix-ui/react-progress" 2 | 3 | type ProgressProps = { 4 | value: number 5 | className?: string 6 | indicatorClassName?: string 7 | } 8 | 9 | export const Progress = ({ 10 | value, 11 | className, 12 | indicatorClassName, 13 | }: ProgressProps) => { 14 | return ( 15 | 16 | 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /app/pages/api/stats/clan/[clanId].ts: -------------------------------------------------------------------------------- 1 | import { getClan } from "bhapi" 2 | import type { NextApiHandler } from "next" 3 | 4 | const handler: NextApiHandler = async (req, res) => { 5 | try { 6 | const { clanId } = req.query 7 | const data = await getClan(parseInt(clanId as string)) 8 | 9 | res.setHeader( 10 | "Cache-Control", 11 | "public, s-maxage=300, stale-while-revalidate=480", 12 | ) 13 | 14 | res.status(200).json(data) 15 | } catch (error) { 16 | res.status(500).json({ error: "something went wrong" }) 17 | } 18 | } 19 | 20 | export default handler 21 | -------------------------------------------------------------------------------- /packages/db/prisma/migrations/20221122003649_legends_and_weapons_last_updated/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - Added the required column `lastUpdated` to the `BHPlayerLegend` table without a default value. This is not possible if the table is not empty. 5 | - Added the required column `lastUpdated` to the `BHPlayerWeapon` table without a default value. This is not possible if the table is not empty. 6 | 7 | */ 8 | -- AlterTable 9 | ALTER TABLE "BHPlayerLegend" ADD COLUMN "lastUpdated" TIMESTAMP(3) NOT NULL; 10 | 11 | -- AlterTable 12 | ALTER TABLE "BHPlayerWeapon" ADD COLUMN "lastUpdated" TIMESTAMP(3) NOT NULL; 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | .pnpm-store 8 | 9 | # testing 10 | coverage 11 | 12 | # next.js 13 | .next/ 14 | out/ 15 | build 16 | 17 | # misc 18 | .DS_Store 19 | *.pem 20 | 21 | # debug 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | .pnpm-debug.log* 26 | 27 | # local env files 28 | .env 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | .env.dev 34 | .env.prod 35 | 36 | # turbo 37 | .turbo 38 | 39 | # typescript 40 | tsconfig.tsbuildinfo 41 | -------------------------------------------------------------------------------- /app/pages/api/stats/player/[playerId]/stats.ts: -------------------------------------------------------------------------------- 1 | import { getPlayerStats } from "bhapi" 2 | import type { NextApiHandler } from "next" 3 | 4 | const handler: NextApiHandler = async (req, res) => { 5 | res.setHeader( 6 | "Cache-Control", 7 | "public, s-maxage=300, stale-while-revalidate=480", 8 | ) 9 | 10 | try { 11 | const { playerId } = req.query 12 | const data = await getPlayerStats(parseInt(playerId as string)) 13 | res.status(200).json(data) 14 | } catch (error) { 15 | res.status(500).json({ error: "something went wrong" }) 16 | } 17 | } 18 | 19 | export default handler 20 | -------------------------------------------------------------------------------- /packages/db/discord/getUserConnections.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from "discord-api-types/v9" 2 | import { discordApi } from "./client" 3 | import type { APIConnection } from "discord-api-types/v9" 4 | 5 | export const getUserConnections = async ( 6 | discordToken: string, 7 | ): Promise => { 8 | try { 9 | const res = await discordApi.get( 10 | discordToken, 11 | Routes.userConnections(), 12 | ) 13 | 14 | if (res.status !== 200) throw new Error(res.statusText) 15 | 16 | return res.data 17 | } catch (e) { 18 | return null 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/pages/api/weekly-rotation.ts: -------------------------------------------------------------------------------- 1 | import { getWeeklyRotation } from "web-parser/weekly-rotation/getWeeklyRotation" 2 | import type { NextApiHandler } from "next" 3 | 4 | const handler: NextApiHandler = async (req, res) => { 5 | try { 6 | const weeklyRotation = await getWeeklyRotation() 7 | 8 | res.setHeader( 9 | "Cache-Control", 10 | "public, s-maxage=3600, stale-while-revalidate=7200", 11 | ) 12 | 13 | res.status(200).json(weeklyRotation) 14 | } catch (error) { 15 | res.status(500).json({ error: "Failed to fetch weekly rotation" }) 16 | } 17 | } 18 | 19 | export default handler 20 | -------------------------------------------------------------------------------- /app/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | * { 6 | scroll-behavior: smooth; 7 | } 8 | 9 | html, body { 10 | @apply bg-bgVar1 text-text; 11 | font-family: "Montserrat", sans-serif; 12 | } 13 | 14 | ::-webkit-scrollbar { 15 | @apply w-0 hashover:w-2; 16 | } 17 | 18 | ::-webkit-scrollbar-track { 19 | @apply bg-transparent; 20 | } 21 | 22 | ::-webkit-scrollbar-thumb { 23 | @apply bg-bg rounded-full hover:bg-accent; 24 | } 25 | 26 | .p-link { 27 | @apply text-accent hover:underline; 28 | } 29 | 30 | .text-fill-none { 31 | -webkit-text-fill-color: transparent 32 | } 33 | -------------------------------------------------------------------------------- /app/components/articles/ArticlePreviewGrid.tsx: -------------------------------------------------------------------------------- 1 | import { ArticlePreview } from "./ArticlePreview" 2 | import { type BHArticle } from "web-parser/common" 3 | 4 | type ArticlePreviewGridProps = { 5 | articles: BHArticle[] 6 | } 7 | 8 | export const ArticlePreviewGrid = ({ articles }: ArticlePreviewGridProps) => { 9 | if (!articles || articles.length <= 0) return null 10 | 11 | return ( 12 |
13 | {articles.map((article) => ( 14 | 15 | ))} 16 |
17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /packages/common/hooks/useDebouncedState.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | export const useDebouncedState = (defaultValue: T, delay = 500) => { 4 | const [value, setValue] = useState(defaultValue) 5 | const [debouncedValue, setDebouncedValue] = useState(defaultValue) 6 | 7 | useEffect(() => { 8 | const timeout = setTimeout(() => { 9 | setDebouncedValue(value) 10 | }, delay) 11 | 12 | return () => { 13 | clearTimeout(timeout) 14 | } 15 | }, [defaultValue, delay, value]) 16 | 17 | return [debouncedValue, setValue, value, value !== debouncedValue] as const 18 | } 19 | -------------------------------------------------------------------------------- /packages/db/prisma/functions.sql: -------------------------------------------------------------------------------- 1 | create or replace function search_aliases(search text, aliases_offset integer, aliases_per_page integer) 2 | returns setof public."BHPlayerAlias" 3 | language plpgsql 4 | as $$ 5 | begin 6 | return query 7 | select * 8 | from public."BHPlayerAlias" 9 | where "playerId" 10 | in ( 11 | select "playerId" 12 | from public."BHPlayerAlias" 13 | where "alias" ILIKE search||'%' and "public" is TRUE 14 | order by "createdAt" desc 15 | limit aliases_per_page 16 | offset aliases_offset 17 | ) 18 | and "public" is TRUE 19 | order by "createdAt" desc; 20 | end; 21 | $$; 22 | -------------------------------------------------------------------------------- /packages/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ts:check": "tsc --noEmit" 6 | }, 7 | "dependencies": { 8 | "@tanstack/react-query": "^4.22.0", 9 | "@trpc/client": "10.45.0", 10 | "@trpc/next": "10.45.0", 11 | "@trpc/react-query": "10.45.0", 12 | "@trpc/server": "10.45.0", 13 | "bhapi": "workspace:*", 14 | "common": "workspace:*", 15 | "db": "workspace:*", 16 | "logger": "workspace:*", 17 | "web-parser": "workspace:*", 18 | "zod": "^3.22.4" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^20.11.5", 22 | "tsconfig": "workspace:*" 23 | } 24 | } -------------------------------------------------------------------------------- /app/pages/api/stats/player/[playerId]/ranked.ts: -------------------------------------------------------------------------------- 1 | import { getPlayerRanked } from "bhapi" 2 | import type { NextApiHandler } from "next" 3 | 4 | const handler: NextApiHandler = async (req, res) => { 5 | try { 6 | const { playerId } = req.query 7 | const data = await getPlayerRanked(parseInt(playerId as string)) 8 | 9 | res.setHeader( 10 | "Cache-Control", 11 | "public, s-maxage=300, stale-while-revalidate=480", 12 | ) 13 | 14 | res.status(200).json(data) 15 | } catch (error) { 16 | res.status(500).json({ error: "something went wrong" }) 17 | } 18 | } 19 | 20 | export default handler 21 | -------------------------------------------------------------------------------- /app/hooks/stats/usePowerRankings.ts: -------------------------------------------------------------------------------- 1 | // TS2742: https://github.com/microsoft/TypeScript/issues/47663 2 | import {} from "@tanstack/query-core" 3 | import { trpc } from "@util/trpc" 4 | import type { 5 | PowerRankingsBracket, 6 | PowerRankingsRegion, 7 | } from "web-parser/power-rankings/parsePowerRankingsPage" 8 | 9 | export const usePowerRankings = ( 10 | bracket: PowerRankingsBracket, 11 | region: PowerRankingsRegion, 12 | ) => { 13 | const { data: powerRankings, ...query } = trpc.getPowerRankings.useQuery({ 14 | bracket, 15 | region, 16 | }) 17 | 18 | return { 19 | powerRankings, 20 | ...query, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/ui/base/Kbd.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "common/helpers/classnames" 2 | import { css } from "../theme" 3 | import type { ReactNode } from "react" 4 | 5 | type KbdProps = { 6 | children: ReactNode 7 | className?: string 8 | } 9 | 10 | const kbdClassName = css({ 11 | minWidth: "1.25rem", 12 | height: "1.25rem", 13 | })() 14 | 15 | export const Kbd = ({ children, className }: KbdProps) => ( 16 | 25 | ) 26 | -------------------------------------------------------------------------------- /packages/tsconfig/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "target": "es5", 7 | "lib": ["dom", "dom.iterable", "esnext"], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noEmit": true, 13 | "incremental": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "jsx": "preserve" 19 | }, 20 | "include": ["src", "next-env.d.ts"], 21 | "exclude": ["node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /packages/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "composite": false, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "inlineSources": false, 11 | "isolatedModules": true, 12 | "moduleResolution": "node", 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "preserveWatchOutput": true, 16 | "skipLibCheck": true, 17 | "strict": true, 18 | "downlevelIteration": true, 19 | "strictNullChecks": true 20 | }, 21 | "exclude": ["node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /packages/dl-roster-images/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dl-roster-images", 3 | "version": "0.0.0", 4 | "main": "./index.ts", 5 | "types": "./index.ts", 6 | "scripts": { 7 | "dl-roster-dev": "tsnd --respawn ./index.ts", 8 | "dl-roster": "ts-node ./index.ts", 9 | "ts:check": "tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "axios": "1.1.3", 13 | "bhapi": "workspace:*", 14 | "cheerio": "1.0.0-rc.12", 15 | "logger": "workspace:*" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^20.11.5", 19 | "ts-node": "^10.9.1", 20 | "ts-node-dev": "^2.0.0", 21 | "tsconfig": "workspace:*", 22 | "typescript": "^5.3.3" 23 | } 24 | } -------------------------------------------------------------------------------- /packages/logger/index.ts: -------------------------------------------------------------------------------- 1 | const __DEV = process.env.NODE_ENV === "development" 2 | 3 | const isDevOrServer = __DEV || typeof window === "undefined" 4 | 5 | export const logInfo: typeof console.log = (message, ...args) => { 6 | if (!isDevOrServer) return // eslint-disable-next-line no-console 7 | console.log(message, ...args) 8 | } 9 | 10 | export const logWarning: typeof console.warn = (message, ...args) => { 11 | if (!isDevOrServer) return // eslint-disable-next-line no-console 12 | __DEV && console.warn(message, ...args) 13 | } 14 | 15 | export const logError: typeof console.error = (message, ...args) => { 16 | if (!isDevOrServer) return // eslint-disable-next-line no-console 17 | __DEV && console.error(message, ...args) 18 | } 19 | -------------------------------------------------------------------------------- /packages/db/discord/getDiscordProfile.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from "discord-api-types/v9" 2 | import { discordApi } from "./client" 3 | import type { APIUser } from "discord-api-types/v9" 4 | 5 | export const getDiscordProfile = async ( 6 | discordToken: string, 7 | ): Promise | null> => { 8 | try { 9 | const res = await discordApi.get(discordToken, Routes.user()) 10 | 11 | if (res.status !== 200) throw new Error(res.statusText) 12 | 13 | const user = res.data 14 | 15 | return { 16 | username: user.username, 17 | avatar: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}`, 18 | } 19 | } catch (e) { 20 | return null 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "pipeline": { 3 | "build": { 4 | "dependsOn": [ 5 | "^build" 6 | ], 7 | "outputs": [ 8 | "dist/**", 9 | ".next/**" 10 | ], 11 | "cache": false 12 | }, 13 | "lint": { 14 | "outputs": [] 15 | }, 16 | "ts:check": { 17 | "outputs": [] 18 | }, 19 | "ci:deadcode": { 20 | "outputs": [] 21 | }, 22 | "ci:lint": { 23 | "outputs": [] 24 | }, 25 | "dev": { 26 | "cache": false 27 | }, 28 | "dl-roster": { 29 | "outputs": [] 30 | }, 31 | "db:migrate": { 32 | "outputs": [] 33 | }, 34 | "format": { 35 | "outputs": [] 36 | }, 37 | "db:migrate:prod": { 38 | "outputs": [] 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /packages/ui/theme/index.ts: -------------------------------------------------------------------------------- 1 | import { createStitches } from "@stitches/react" 2 | import colors from "./theme" 3 | 4 | export const { 5 | styled, 6 | css, 7 | globalCss, 8 | keyframes, 9 | getCssText, 10 | theme, 11 | createTheme, 12 | config, 13 | } = createStitches({ 14 | theme: { 15 | colors, 16 | }, 17 | }) 18 | 19 | const setColor = 20 | (prop: string) => (color: keyof (typeof theme)["colors"], state?: string) => 21 | css( 22 | state 23 | ? { [state]: { [prop]: theme.colors[color] } } 24 | : { [prop]: theme.colors[color] }, 25 | )() 26 | 27 | export const bg = setColor("backgroundColor") 28 | export const text = setColor("color") 29 | export const border = setColor("borderColor") 30 | -------------------------------------------------------------------------------- /packages/db/prisma/auth_user_trigger_add.sql: -------------------------------------------------------------------------------- 1 | -- addforeignKey 2 | alter table public."UserProfile" add constraint "UserProfile_userId_fkey" foreign key ("id") references auth.users("id") on delete restrict on update cascade; 3 | 4 | -- create User Profile trigger function 5 | create or replace function create_profile_for_new_user() 6 | returns trigger 7 | language plpgsql 8 | security definer set search_path = public 9 | as $$ 10 | begin 11 | insert into public."UserProfile" (id) 12 | values(new.id) on conflict (id) do nothing; 13 | return new; 14 | end; 15 | $$; 16 | 17 | -- create trigger on insert or Update 18 | create or replace trigger create_profile_for_new_user_trigger 19 | after insert or update on auth.users 20 | for each row 21 | execute procedure create_profile_for_new_user(); -------------------------------------------------------------------------------- /packages/server/router/getBHArticles.ts: -------------------------------------------------------------------------------- 1 | import { 2 | brawlhallaArticleCategorySchema, 3 | getBrawlhallaArticles, 4 | } from "web-parser/common" 5 | import { logInfo } from "logger" 6 | import { publicProcedure } from "../trpc" 7 | import { z } from "zod" 8 | 9 | export const getBHArticles = publicProcedure // 10 | .input( 11 | z.object({ 12 | category: brawlhallaArticleCategorySchema.default(""), 13 | first: z.number().min(1).default(1), 14 | }), 15 | ) 16 | .query(async (req) => { 17 | const { category, first } = req.input 18 | logInfo("getBHArticles", { category, first }) 19 | 20 | const articles = await getBrawlhallaArticles({ 21 | category, 22 | first, 23 | }) 24 | 25 | return articles 26 | }) 27 | -------------------------------------------------------------------------------- /app/pages/@me/favorites.tsx: -------------------------------------------------------------------------------- 1 | import { FavoritesGrid } from "@components/favorites/FavoritesGrid" 2 | import { SEO } from "@components/SEO" 3 | import { SectionTitle } from "@components/layout/SectionTitle" 4 | import { useFavorites } from "@ctx/auth/AuthProvider" 5 | import type { NextPage } from "next" 6 | 7 | const Page: NextPage = () => { 8 | const { playerFavorites, clanFavorites } = useFavorites() 9 | 10 | return ( 11 | <> 12 | 13 |

Favorites

14 | Players 15 | 16 | Clans 17 | 18 | 19 | ) 20 | } 21 | 22 | export default Page 23 | -------------------------------------------------------------------------------- /app/components/Image.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "common/helpers/classnames" 2 | import NextImage from "next/image" 3 | import type { ImageProps as NextImageProps } from "next/image" 4 | 5 | type ImageProps = NextImageProps & { 6 | containerClassName?: string 7 | Container?: "div" | "span" | null 8 | position?: "absolute" | "relative" | "fixed" | string 9 | } 10 | 11 | export const Image = ({ 12 | containerClassName, 13 | Container = "div", 14 | position = "relative", 15 | sizes = "100vw", 16 | ...props 17 | }: ImageProps) => { 18 | if (!Container) { 19 | return 20 | } 21 | 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /app/public/sitemap-0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | http://localhost:30002024-01-19T03:48:22.946Zdaily1 4 | http://localhost:3000/@me/favorites2024-01-19T03:48:22.946Zdaily1 5 | http://localhost:3000/calc2024-01-19T03:48:22.946Zdaily1 6 | -------------------------------------------------------------------------------- /app/pages/api/rankings/power.ts: -------------------------------------------------------------------------------- 1 | import { parsePowerRankingsPage } from "web-parser/power-rankings/parsePowerRankingsPage" 2 | import type { Bracket } from "bhapi/types" 3 | import type { NextApiHandler } from "next" 4 | 5 | const handler: NextApiHandler = async (req, res) => { 6 | try { 7 | const { bracket, region } = req.query 8 | const data = await parsePowerRankingsPage( 9 | bracket as Bracket, 10 | // @ts-expect-error typecheck region 11 | region, 12 | ) 13 | 14 | res.setHeader( 15 | "Cache-Control", 16 | "public, s-maxage=300, stale-while-revalidate=480", 17 | ) 18 | 19 | res.status(200).json(data) 20 | } catch (error) { 21 | res.status(500).json({ error: "something went wrong" }) 22 | } 23 | } 24 | 25 | export default handler 26 | -------------------------------------------------------------------------------- /.devcontainer/zsh/devcontainer.zsh-theme: -------------------------------------------------------------------------------- 1 | local LC_ALL="" LC_CTYPE="en_US.UTF-8" 2 | autoload -U colors && colors 3 | 4 | prompt_git() { 5 | setopt prompt_subst 6 | autoload -Uz vcs_info 7 | 8 | zstyle ':vcs_info:*' enable git 9 | zstyle ':vcs_info:git:*' check-for-changes true 10 | zstyle ':vcs_info:git:*' stagedstr "%{$fg_bold[green]%}!%{$reset_color%}" 11 | zstyle ':vcs_info:git:*' unstagedstr "%{$fg_bold[yellow]%}?%{$reset_color%}" 12 | zstyle ':vcs_info:*' formats " › %b%c%u" 13 | zstyle ':vcs_info:*' actionformats " › %b%c%u %{$fg_bold[red]%}[%a]%{$reset_color%}" 14 | vcs_info 15 | 16 | echo -n ${vcs_info_msg_0_}$reset 17 | } 18 | 19 | build_prompt() { 20 | echo -n "%{$fg[gray]%}corehalla%{$reset_color%}%{$fg[blue]%}%~%{$reset_color%}" 21 | prompt_git 22 | echo 23 | echo "🚀 › " 24 | } 25 | 26 | export PROMPT='$(build_prompt)' 27 | -------------------------------------------------------------------------------- /app/pages/api/rankings/index.ts: -------------------------------------------------------------------------------- 1 | import { getRankings } from "bhapi" 2 | import type { Bracket } from "bhapi/types" 3 | import type { NextApiHandler } from "next" 4 | import type { RankedRegion } from "bhapi/constants" 5 | 6 | const handler: NextApiHandler = async (req, res) => { 7 | res.setHeader( 8 | "Cache-Control", 9 | "public, s-maxage=300, stale-while-revalidate=480", 10 | ) 11 | 12 | try { 13 | const { bracket, region, page, name } = req.query 14 | const data = await getRankings( 15 | bracket as Bracket, 16 | region as RankedRegion, 17 | page as string, 18 | name as string, 19 | ) 20 | res.status(200).json(data) 21 | } catch (error) { 22 | res.status(500).json({ error: "something went wrong" }) 23 | } 24 | } 25 | 26 | export default handler 27 | -------------------------------------------------------------------------------- /app/hooks/stats/useRankings.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from "@util/trpc" 2 | import type { RankedRegion } from "bhapi/constants" 3 | 4 | export const useRankings1v1 = ( 5 | region: RankedRegion, 6 | page: string, 7 | name = "", 8 | options: { enabled?: boolean } = {}, 9 | ) => { 10 | const { data, ...query } = trpc.get1v1Rankings.useQuery( 11 | { 12 | region, 13 | page, 14 | name, 15 | }, 16 | options, 17 | ) 18 | 19 | return { 20 | rankings1v1: data, 21 | ...query, 22 | } 23 | } 24 | 25 | export const useRankings2v2 = (region: RankedRegion, page: string) => { 26 | const { data, ...query } = trpc.get2v2Rankings.useQuery({ 27 | region, 28 | page, 29 | }) 30 | 31 | return { 32 | rankings2v2: data, 33 | ...query, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/util/features.ts: -------------------------------------------------------------------------------- 1 | import type { AuthContext } from "@ctx/auth/AuthProvider" 2 | 3 | export type FeatureFlags = keyof ReturnType 4 | 5 | const __DEV = process.env.NODE_ENV === "development" 6 | 7 | export const getFeatureFlags = ({ 8 | authContext, 9 | }: { 10 | authContext?: AuthContext 11 | }) => { 12 | // const isSSR = typeof window === "undefined" 13 | // const isProductionWebsite = 14 | // process.env.NEXT_PUBLIC_FORCE_PRODUCTION_WEBSITE || 15 | // (!isSSR && window.location.hostname === "corehalla.com") 16 | 17 | return { 18 | // shouldUseVercelImageOptimization: false, 19 | shouldShowDummyFavorites: false && __DEV && !authContext?.isLoggedIn, 20 | shouldShowInfoTooltips: true, // TODO: Add setting to toggle this 21 | shouldShowAds: true, // TODO: premium?? 22 | } as const 23 | } 24 | -------------------------------------------------------------------------------- /packages/web-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-parser", 3 | "version": "0.0.0", 4 | "main": "./index.ts", 5 | "types": "./index.ts", 6 | "scripts": { 7 | "parse-bh-articles:dev": "tsnd --respawn ./bh-articles/dev.ts", 8 | "parse-pr:dev": "tsnd --respawn ./power-rankings/dev.ts", 9 | "parse-weekly-rot:dev": "tsnd --respawn ./weekly-rotation/dev.ts", 10 | "ts:check": "tsc --noEmit" 11 | }, 12 | "dependencies": { 13 | "axios": "1.1.3", 14 | "bhapi": "workspace:*", 15 | "cheerio": "1.0.0-rc.12", 16 | "logger": "workspace:*", 17 | "zod": "^3.22.4" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "^20.11.5", 21 | "ts-node": "^10.9.1", 22 | "ts-node-dev": "^2.0.0", 23 | "tsconfig": "workspace:*", 24 | "typescript": "^5.3.3" 25 | } 26 | } -------------------------------------------------------------------------------- /app/pages/api/stats/player/[playerId]/aliases.ts: -------------------------------------------------------------------------------- 1 | import { supabaseService } from "db/supabase/service" 2 | import type { BHPlayerAlias } from "db/generated/client" 3 | import type { NextApiHandler } from "next" 4 | 5 | const handler: NextApiHandler = async (req, res) => { 6 | res.setHeader( 7 | "Cache-Control", 8 | "public, s-maxage=300, stale-while-revalidate=480", 9 | ) 10 | 11 | const { playerId } = req.query 12 | 13 | try { 14 | const { data, error } = await supabaseService 15 | .from("BHPlayerAlias") 16 | .select("*") 17 | .match({ playerId }) 18 | 19 | if (error) throw error 20 | 21 | res.status(200).json(data.map((alias) => alias.alias)) 22 | } catch (error) { 23 | res.status(500).json({ error: "something went wrong" }) 24 | } 25 | } 26 | 27 | export default handler 28 | -------------------------------------------------------------------------------- /packages/common/hooks/useDevice.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | const getCurrentDevice = () => { 4 | if (typeof window === "undefined") return "" 5 | 6 | const ua = navigator.userAgent 7 | 8 | if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) 9 | return "tablet" 10 | 11 | if ( 12 | /Mobile|iP(hone|od)|Android|BlackBerry|IEMobile|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test( 13 | ua, 14 | ) 15 | ) 16 | return "mobile" 17 | 18 | return navigator.platform.toUpperCase().indexOf("MAC") >= 0 ? "mac" : "pc" 19 | } 20 | 21 | export const useDevice = () => { 22 | const [device, setDevice] = useState< 23 | "" | "tablet" | "mobile" | "mac" | "pc" 24 | >("") 25 | 26 | useEffect(() => { 27 | setDevice(getCurrentDevice()) 28 | }, []) 29 | 30 | return device 31 | } 32 | -------------------------------------------------------------------------------- /app/components/layout/SectionTitle.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "common/helpers/classnames" 2 | import type { ReactNode } from "react" 3 | 4 | type SectionTitleProps = { 5 | className?: string 6 | children: ReactNode 7 | hasBorder?: boolean 8 | customMargin?: boolean 9 | customPadding?: boolean 10 | } 11 | 12 | export const SectionTitle = ({ 13 | children, 14 | className, 15 | hasBorder, 16 | customMargin, 17 | customPadding, 18 | }: SectionTitleProps) => { 19 | return ( 20 |

31 | {children} 32 |

33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /worker/src/appa-bot/channel-switcher/roomNumbers.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | import type { VoiceChannel } from "discord.js" 3 | 4 | const brawlhallaRoomNumbers = new Map() 5 | 6 | const brawlhallaRoomNumberRegex = /^\d{6}$/ 7 | export const isValidBrawlhallaRoomNumber = (content: string) => { 8 | try { 9 | z.string().regex(brawlhallaRoomNumberRegex).parse(content) 10 | return true 11 | } catch (error) { 12 | return false 13 | } 14 | } 15 | 16 | export const saveRoomNumber = async ( 17 | channelId: VoiceChannel, 18 | roomNumber: string, 19 | ) => { 20 | brawlhallaRoomNumbers.set(channelId.id, roomNumber) 21 | } 22 | 23 | export const getRoomNumber = (channelId: VoiceChannel) => { 24 | return brawlhallaRoomNumbers.get(channelId.id) 25 | } 26 | 27 | export const deleteRoomNumber = (channelId: VoiceChannel) => { 28 | brawlhallaRoomNumbers.delete(channelId.id) 29 | } 30 | -------------------------------------------------------------------------------- /app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme_color": "#f69435", 3 | "background_color": "#f69435", 4 | "display": "standalone", 5 | "scope": "/", 6 | "start_url": "/", 7 | "name": "Corehalla", 8 | "short_name": "corehalla", 9 | "description": "Brawlhalla Stats & Rankings", 10 | "icons": [ 11 | { 12 | "src": "/icons/icon-192x192.png", 13 | "sizes": "192x192", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "/icons/icon-256x256.png", 18 | "sizes": "256x256", 19 | "type": "image/png" 20 | }, 21 | { 22 | "src": "/icons/icon-384x384.png", 23 | "sizes": "384x384", 24 | "type": "image/png" 25 | }, 26 | { 27 | "src": "/icons/icon-512x512.png", 28 | "sizes": "512x512", 29 | "type": "image/png" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/dl-roster-images/downloadImage.ts: -------------------------------------------------------------------------------- 1 | import { createWriteStream } from "fs" 2 | import Axios from "axios" 3 | 4 | export const downloadImage = async ( 5 | fileUrl: string, 6 | outputLocationPath: string, 7 | ) => { 8 | const writer = createWriteStream(outputLocationPath) 9 | 10 | return Axios({ 11 | method: "get", 12 | url: fileUrl, 13 | responseType: "stream", 14 | }).then((response) => { 15 | return new Promise((resolve, reject) => { 16 | response.data.pipe(writer) 17 | 18 | let error: Error | null = null 19 | writer.on("error", (err) => { 20 | error = err 21 | writer.close() 22 | reject(err) 23 | }) 24 | 25 | writer.on("close", () => { 26 | if (!error) { 27 | resolve(true) 28 | } 29 | }) 30 | }) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /packages/server/mutations/updateDBPlayerAliases.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | import { supabaseService } from "db/supabase/service" 3 | import type { BHPlayerAlias } from "db/generated/client" 4 | import type { CommonOptions } from "../helpers/commonOptions" 5 | 6 | export const updateDBPlayerAliases = async ( 7 | aliases: BHPlayerAlias[], 8 | options: CommonOptions, 9 | ) => { 10 | const filteredAliases = aliases.filter( 11 | (alias, i) => 12 | aliases.findIndex( 13 | (a) => a.playerId === alias.playerId && a.alias === alias.alias, 14 | ) === i, 15 | ) 16 | 17 | logInfo( 18 | "updateDBPlayerAliases", 19 | filteredAliases.map((alias) => `${alias.playerId} => ${alias.alias}`), 20 | ) 21 | 22 | await supabaseService // 23 | .from("BHPlayerAlias") 24 | .upsert(filteredAliases) 25 | .abortSignal(options.abortSignal) 26 | } 27 | -------------------------------------------------------------------------------- /packages/bhapi/helpers/getTeamPlayers.ts: -------------------------------------------------------------------------------- 1 | import type { PlayerRanked, Ranking2v2 } from "../types" 2 | 3 | export const getTeamPlayers = ( 4 | team: PlayerRanked["2v2"][number] | Ranking2v2, 5 | ) => { 6 | const [player1, player2] = team.teamname.split("+") 7 | return [ 8 | { 9 | name: player1, 10 | id: team.brawlhalla_id_one, 11 | }, 12 | { 13 | name: player2, 14 | id: team.brawlhalla_id_two, 15 | }, 16 | ] 17 | } 18 | 19 | export const getPlayerTeam = ( 20 | playerId: number, 21 | team: PlayerRanked["2v2"][number], 22 | ) => { 23 | const [player1, player2] = getTeamPlayers(team) 24 | 25 | if (team.brawlhalla_id_one === playerId) { 26 | return { 27 | playerName: player1.name, 28 | teammate: player2, 29 | } 30 | } 31 | 32 | return { 33 | playerName: player2.name, 34 | teammate: player1, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/components/stats/RatingDisplay.tsx: -------------------------------------------------------------------------------- 1 | import { GamesDisplay } from "./GamesDisplay" 2 | 3 | type RatingDisplayProps = { 4 | className?: string 5 | games: number 6 | wins: number 7 | rating: number 8 | peak_rating: number 9 | } 10 | 11 | export const RatingDisplay = ({ 12 | className, 13 | games, 14 | wins, 15 | rating, 16 | peak_rating, 17 | }: RatingDisplayProps) => { 18 | return ( 19 | <> 20 | 26 | {rating} 27 | 28 | / {peak_rating} 29 | 30 | 31 | } 32 | description="Peak" 33 | /> 34 | 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /app/pages/api/bh-articles.ts: -------------------------------------------------------------------------------- 1 | import { parseBHArticlesPage } from "web-parser/bh-articles/parseBHArticlesPage" 2 | import type { BHArticleType } from "web-parser/bh-articles/parseBHArticlesPage" 3 | import type { NextApiHandler } from "next" 4 | 5 | const handler: NextApiHandler = async (req, res) => { 6 | const { page = "1", type = "patch-notes", max } = req.query 7 | 8 | try { 9 | const pageNum = parseInt(page as string) 10 | const articles = await parseBHArticlesPage( 11 | pageNum, 12 | type.toString() as BHArticleType, 13 | ) 14 | 15 | res.setHeader( 16 | "Cache-Control", 17 | "public, s-maxage=3600, stale-while-revalidate=7200", 18 | ) 19 | 20 | if (max) { 21 | return res.json(articles.slice(0, parseInt(max.toString()))) 22 | } 23 | res.json(articles) 24 | } catch { 25 | res.status(404).json({ error: "Page not found" }) 26 | } 27 | } 28 | 29 | export default handler 30 | -------------------------------------------------------------------------------- /.github/workflows/codeqa-analysis.yml: -------------------------------------------------------------------------------- 1 | name: Code QA 2 | on: [push] 3 | jobs: 4 | analyze: 5 | name: Analyze 6 | runs-on: ubuntu-latest 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | include: 11 | - name: Lint 12 | action: pnpm ci:lint 13 | - name: Check Types 14 | action: pnpm ts:check 15 | - name: Check Deadcode 16 | action: pnpm ci:deadcode 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: pnpm/action-setup@v2 20 | with: 21 | version: 8.5.0 22 | - uses: actions/setup-node@v2 23 | with: 24 | node-version: 18 25 | cache: "pnpm" 26 | cache-dependency-path: pnpm-lock.yaml 27 | - name: ${{ matrix.name }} 28 | run: | 29 | pnpm ci:install 30 | ${{ matrix.action }} 31 | -------------------------------------------------------------------------------- /packages/server/router/stats/getPowerRankings.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | import { 3 | parsePowerRankingsPage, 4 | powerRankingsBracketValidator, 5 | powerRankingsRegionValidator, 6 | } from "web-parser/power-rankings/parsePowerRankingsPage" 7 | import { publicProcedure } from "../../trpc" 8 | import { withTimeLog } from "../../helpers/withTimeLog" 9 | import { z } from "zod" 10 | 11 | export const getPowerRankings = publicProcedure 12 | .input( 13 | z.object({ 14 | bracket: powerRankingsBracketValidator, 15 | region: powerRankingsRegionValidator, 16 | }), 17 | ) 18 | .query( 19 | withTimeLog(async (req) => { 20 | const { bracket, region } = req.input 21 | logInfo("getPowerRankings", req.input) 22 | 23 | return [] 24 | 25 | // return withTimeLog( 26 | // parsePowerRankingsPage, 27 | // "parsePowerRankingsPage", 28 | // )(bracket ?? "1v1", region ?? "us-e") 29 | }, "getPowerRankings"), 30 | ) 31 | -------------------------------------------------------------------------------- /app/components/stats/ProgressCard.tsx: -------------------------------------------------------------------------------- 1 | import { Card } from "ui/base/Card" 2 | import { Progress } from "ui/base/Progress" 3 | 4 | type ProgressCardProps = { 5 | title?: string 6 | bars: { title: string; value: number; progress: number }[] 7 | } 8 | 9 | export const ProgressCard = ({ title, bars }: ProgressCardProps) => { 10 | return ( 11 | 12 | {bars.map(({ title, value, progress }) => ( 13 |
14 |

15 | {value}{" "} 16 | {title} 17 |

18 | 23 |
24 | ))} 25 |
26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /packages/server/router/index.ts: -------------------------------------------------------------------------------- 1 | import { get1v1Rankings, get2v2Rankings } from "./stats/getRankings" 2 | import { getBHArticles } from "./getBHArticles" 3 | import { getClanStats } from "./stats/getClanStats" 4 | import { getClansRankings } from "./stats/getClansRankings" 5 | import { getGlobalPlayerRankings } from "./stats/getGlobalPlayerRankings" 6 | import { getPlayerAliases } from "./stats/getPlayerAliases" 7 | import { getPlayerRanked } from "./stats/getPlayerRanked" 8 | import { getPlayerStats } from "./stats/getPlayerStats" 9 | import { getPowerRankings } from "./stats/getPowerRankings" 10 | import { getWeeklyRotation } from "./getWeeklyRotation" 11 | import { router } from "../trpc" 12 | import { searchPlayerAlias } from "./stats/searchPlayerAlias" 13 | 14 | export const appRouter = router({ 15 | get1v1Rankings, 16 | get2v2Rankings, 17 | getClansRankings, 18 | getPowerRankings, 19 | getPlayerStats, 20 | getPlayerRanked, 21 | getPlayerAliases, 22 | getClanStats, 23 | searchPlayerAlias, 24 | getWeeklyRotation, 25 | getBHArticles, 26 | getGlobalPlayerRankings, 27 | }) 28 | 29 | export type AppRouter = typeof appRouter 30 | -------------------------------------------------------------------------------- /packages/server/router/stats/getPlayerAliases.ts: -------------------------------------------------------------------------------- 1 | import { logInfo } from "logger" 2 | import { numericLiteralValidator } from "common/helpers/validators" 3 | import { publicProcedure } from "../../trpc" 4 | import { supabaseService } from "db/supabase/service" 5 | import { withTimeLog } from "../../helpers/withTimeLog" 6 | import { z } from "zod" 7 | import type { BHPlayerAlias } from "db/generated/client" 8 | 9 | export const getPlayerAliases = publicProcedure // 10 | .input( 11 | z.object({ 12 | playerId: numericLiteralValidator, 13 | }), 14 | ) 15 | .query( 16 | withTimeLog(async (req) => { 17 | const { playerId } = req.input 18 | logInfo("getPlayerAliases", req.input) 19 | 20 | const { data, error } = await supabaseService 21 | .from("BHPlayerAlias") 22 | .select("*") 23 | .order("createdAt", { ascending: false }) 24 | .match({ playerId, public: true }) 25 | 26 | if (error) throw error 27 | 28 | return data.map((alias) => alias.alias) 29 | }, "getPlayerAliases"), 30 | ) 31 | -------------------------------------------------------------------------------- /packages/ui/base/Card.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "common/helpers/classnames" 2 | import type { ReactNode } from "react" 3 | 4 | type CardProps = { 5 | className?: string 6 | children: ReactNode 7 | title?: ReactNode 8 | titleClassName?: string 9 | contentClassName?: string 10 | } 11 | 12 | export const Card = ({ 13 | className, 14 | children, 15 | title, 16 | titleClassName, 17 | contentClassName, 18 | }: CardProps) => { 19 | return ( 20 |
26 | {title && ( 27 |

33 | {title} 34 |

35 | )} 36 |
37 | {children} 38 |
39 |
40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /app/pages/api/trpc/[trpc].ts: -------------------------------------------------------------------------------- 1 | import * as trpcNext from "@trpc/server/adapters/next" 2 | import { appRouter } from "server/router" 3 | 4 | export default trpcNext.createNextApiHandler({ 5 | router: appRouter, 6 | createContext: () => ({}), 7 | batching: { 8 | enabled: false, 9 | }, 10 | responseMeta({ paths, type, errors }) { 11 | // assuming you have all your public routes with the keyword `public` in them 12 | const allPublic = 13 | paths && paths.every((path) => path.includes("public")) 14 | // checking that no procedures errored 15 | const allOk = errors.length === 0 16 | // checking we're doing a query request 17 | const isQuery = type === "query" 18 | if (allPublic && allOk && isQuery) { 19 | // cache for 1 day + revalidate once every 30 seconds 20 | const CACHE_TIME = 60 * 60 * 24 21 | const REVALIDATE_TIME = 30 22 | 23 | return { 24 | headers: { 25 | "cache-control": `s-maxage=${REVALIDATE_TIME}, stale-while-revalidate=${CACHE_TIME}`, 26 | }, 27 | } 28 | } 29 | return {} 30 | }, 31 | }) 32 | -------------------------------------------------------------------------------- /packages/server/helpers/waitForRequestTimeout.ts: -------------------------------------------------------------------------------- 1 | import { logError, logInfo } from "logger" 2 | 3 | const DEFAULT_REQUEST_TIMEOUT = 1000 * 8 // 8 seconds 4 | 5 | export const waitForRequestTimeout = async ( 6 | request: Promise, 7 | { 8 | abortController = new AbortController(), 9 | timeout = DEFAULT_REQUEST_TIMEOUT, // 10 seconds 10 | }: { abortController?: AbortController; timeout?: number } = {}, 11 | ) => { 12 | const fireAndForgetPromise = request.catch((error) => { 13 | if (error.name === "AbortError") { 14 | logError("Request aborted", error) 15 | return 16 | } 17 | 18 | logError("Request failed", error) 19 | }) 20 | 21 | let timeoutId: NodeJS.Timeout 22 | 23 | const timeoutPromise = new Promise((resolve) => { 24 | timeoutId = setTimeout(() => { 25 | logInfo(`Request timed out after ${timeout}ms`) 26 | clearTimeout(timeoutId) 27 | abortController.abort() 28 | resolve() 29 | }, timeout) 30 | }) 31 | 32 | return Promise.race([fireAndForgetPromise, timeoutPromise]).finally(() => { 33 | clearTimeout(timeoutId) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /app/components/BackToTopButton.tsx: -------------------------------------------------------------------------------- 1 | import { BackToTopIcon } from "ui/icons" 2 | import { Tooltip } from "ui/base/Tooltip" 3 | import { cn } from "common/helpers/classnames" 4 | import { useWindowScroll } from "common/hooks/useWindowScroll" 5 | 6 | export const BackToTopButton = () => { 7 | const { y: scrollY } = useWindowScroll() 8 | 9 | return ( 10 |
15 | 16 | 30 | 31 |
32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /app/pages/api/rankings/clans.ts: -------------------------------------------------------------------------------- 1 | import { CLANS_RANKINGS_PER_PAGE } from "server/helpers/constants" 2 | import { supabaseService } from "db/supabase/service" 3 | import type { BHClan } from "db/generated/client" 4 | import type { NextApiHandler } from "next" 5 | 6 | const handler: NextApiHandler = async (req, res) => { 7 | const { name = "", page = "1" } = req.query 8 | 9 | try { 10 | let query = supabaseService 11 | .from("BHClan") 12 | .select("*") 13 | .order("xp", { ascending: false }) 14 | 15 | if (name) { 16 | query = query.match({ name }) 17 | } 18 | 19 | const pageNum = parseInt(page as string) 20 | 21 | const { data, error } = await query.range( 22 | (pageNum - 1) * CLANS_RANKINGS_PER_PAGE, 23 | pageNum * CLANS_RANKINGS_PER_PAGE - 1, 24 | ) 25 | 26 | if (error) throw error 27 | 28 | res.setHeader( 29 | "Cache-Control", 30 | "public, s-maxage=300, stale-while-revalidate=480", 31 | ) 32 | 33 | res.status(200).json(data ?? []) 34 | } catch (error) { 35 | res.status(500).json({ error: "something went wrong" }) 36 | } 37 | } 38 | 39 | export default handler 40 | -------------------------------------------------------------------------------- /packages/server/mutations/flushOutdatedBPlayerData.ts: -------------------------------------------------------------------------------- 1 | import { supabaseService } from "db/supabase/service" 2 | import type { 3 | BHPlayerData, 4 | BHPlayerLegend, 5 | BHPlayerWeapon, 6 | } from "db/generated/client" 7 | import type { CommonOptions } from "../helpers/commonOptions" 8 | 9 | export const flushOutdatedBPlayerData = async (options: CommonOptions) => { 10 | const currentTimestamp = new Date().getTime() 11 | const twoDaysAgo = currentTimestamp - 2 * 24 * 60 * 60 * 1000 12 | 13 | const flushPlayerData = supabaseService 14 | .from("BHPlayerData") 15 | .delete() 16 | .filter("lastUpdated", "not.gt", twoDaysAgo) 17 | .abortSignal(options.abortSignal) 18 | 19 | const flushLegendData = supabaseService 20 | .from("BHPlayerLegend") 21 | .delete() 22 | .filter("lastUpdated", "not.gt", twoDaysAgo) 23 | .abortSignal(options.abortSignal) 24 | 25 | const flushWeaponData = supabaseService 26 | .from("BHPlayerWeapon") 27 | .delete() 28 | .filter("lastUpdated", "not.gt", twoDaysAgo) 29 | .abortSignal(options.abortSignal) 30 | 31 | await Promise.all([flushPlayerData, flushLegendData, flushWeaponData]) 32 | } 33 | -------------------------------------------------------------------------------- /packages/common/helpers/date.ts: -------------------------------------------------------------------------------- 1 | import { unix } from "dayjs" 2 | 3 | /** 4 | * @error returns different dates in client or ssr mode 5 | * @issue https://github.com/iamkun/dayjs/issues/1690 6 | */ 7 | export const getDateFromUnixTime = (unixTime: number, template?: string) => 8 | unix(unixTime).format(template) 9 | 10 | type HMSTime = { 11 | hours: number 12 | minutes: number 13 | seconds: number 14 | } 15 | 16 | export const getHMSFromSeconds = (seconds: number): HMSTime => { 17 | const minutes = Math.floor(seconds / 60) 18 | const hours = Math.floor(minutes / 60) 19 | 20 | return { 21 | hours, 22 | minutes: minutes % 60, 23 | seconds: seconds % 60, 24 | } 25 | } 26 | 27 | export const getHMSStringFromSeconds = ( 28 | milliseconds: number, 29 | template: ({ hours, minutes, seconds }: HMSTime) => string, 30 | ) => { 31 | const timeData = getHMSFromSeconds(milliseconds) 32 | return template(timeData) 33 | } 34 | 35 | export const formatTime = (seconds: number) => 36 | getHMSStringFromSeconds( 37 | seconds, 38 | ({ hours, minutes, seconds }) => `${hours}h ${minutes}m ${seconds}s`, 39 | ) 40 | 41 | export const formatUnixTime = (unixTime: number) => 42 | getDateFromUnixTime(unixTime, "MMM DD, YYYY") 43 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | root: true 2 | extends: 3 | - eslint:recommended 4 | - next 5 | - plugin:@typescript-eslint/recommended 6 | - plugin:jsx-a11y/strict 7 | parser: "@typescript-eslint/parser" 8 | plugins: 9 | - "@typescript-eslint" 10 | - jsx-a11y 11 | - sort-imports-es6-autofix 12 | - prettier 13 | settings: 14 | next: 15 | rootDir: [app/, packages/*/] 16 | rules: 17 | no-console: 2 18 | no-unused-vars: 0 19 | "@typescript-eslint/no-unused-vars": 2 20 | prettier/prettier: 2 21 | react/function-component-definition: 22 | - 2 23 | - namedComponents: "arrow-function" 24 | unnamedComponents: "arrow-function" 25 | no-var: 2 26 | sort-imports-es6-autofix/sort-imports-es6: 27 | - 2 28 | - ignoreCase: false 29 | ignoreMemberSort: false 30 | memberSyntaxSortOrder: 31 | - none 32 | - all 33 | - multiple 34 | - single 35 | "@typescript-eslint/consistent-type-imports": 36 | - 2 37 | - prefer: "type-imports" 38 | object-shorthand: 39 | - 2 40 | - always 41 | - avoidExplicitReturnArrows: true 42 | no-restricted-imports: 43 | - 2 44 | - paths: 45 | - next/link -------------------------------------------------------------------------------- /worker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "worker", 3 | "version": "0.0.0", 4 | "description": "", 5 | "main": "src/index.ts", 6 | "scripts": { 7 | "dev": "DISCORD_MANAGER_BOT_ENABLED=true CRAWLER_ENABLED=true tsnd --respawn src/index.ts", 8 | "bot:dev": "DISCORD_MANAGER_BOT_ENABLED=true CRAWLER_ENABLED=false tsnd --respawn src/index.ts", 9 | "ts:check": "tsc --noEmit", 10 | "start": "ts-node --transpile-only src/index.ts" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "@types/cors": "^2.8.13", 17 | "@types/express": "^4.17.15", 18 | "@types/node": "^20.11.5", 19 | "@types/react": "^18.2.31", 20 | "typescript": "^5.3.3" 21 | }, 22 | "dependencies": { 23 | "@trpc/client": "10.45.0", 24 | "@trpc/server": "10.45.0", 25 | "bhapi": "workspace:*", 26 | "common": "workspace:*", 27 | "cors": "^2.8.5", 28 | "db": "workspace:*", 29 | "discord.js": "^14.7.1", 30 | "dotenv": "^16.3.1", 31 | "express": "^4.18.2", 32 | "logger": "workspace:*", 33 | "reaccord": "0.0.1-dev.1669742731656.1c2e96f", 34 | "react": "^18.2.0", 35 | "server": "workspace:*", 36 | "ts-node": "^10.9.1", 37 | "ts-node-dev": "^2.0.0", 38 | "web-parser": "workspace:*", 39 | "zod": "^3.22.4" 40 | } 41 | } -------------------------------------------------------------------------------- /packages/common/analytics/gtag.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Google Analytics Identifier 3 | */ 4 | export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_TRACKING_ID 5 | /** 6 | * Google Adsense Identifier 7 | */ 8 | export const ADSENSE_ID = process.env.NEXT_PUBLIC_ADSENSE_ID 9 | 10 | /** 11 | * Google Adsense Publisher Identifier 12 | * ca-pub-[publisher-id] 13 | */ 14 | export const adsenseCaPub = `ca-pub-${ADSENSE_ID}` 15 | 16 | /** 17 | * Google Analytics pageview tracking 18 | * @link https://developers.google.com/analytics/devguides/collection/gtagjs/pages 19 | * @param url page url 20 | */ 21 | export const gaPageview = (url: string) => { 22 | // @ts-expect-error window.gtag is not defined 23 | window.gtag("config", GA_TRACKING_ID, { 24 | page_path: url, 25 | }) 26 | } 27 | 28 | type GAEvent = { 29 | action: string 30 | category: string 31 | label: string 32 | value?: number 33 | } 34 | 35 | /** 36 | * Google Analytics event tracking 37 | * @link https://developers.google.com/analytics/devguides/collection/gtagjs/events 38 | */ 39 | export const gaEvent = ({ action, category, label, value }: GAEvent) => { 40 | // @ts-expect-error window.gtag is not defined 41 | window.gtag("event", action, { 42 | event_category: category, 43 | event_label: label, 44 | value, 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /app/components/layout/CollapsibleSection.tsx: -------------------------------------------------------------------------------- 1 | import { CollapsibleContent } from "./CollapsibleContent" 2 | import { SectionTitle } from "./SectionTitle" 3 | import { cn } from "common/helpers/classnames" 4 | import type { CollapsibleContentProps } from "./CollapsibleContent" 5 | import type { ReactNode } from "react" 6 | 7 | type CollapsibleSectionProps = Omit & { 8 | trigger: ReactNode 9 | } 10 | 11 | export const CollapsibleSection = ({ 12 | className, 13 | triggerClassName, 14 | trigger, 15 | defaultOpen = true, 16 | ...props 17 | }: CollapsibleSectionProps) => { 18 | return ( 19 | ( 26 | 32 | {trigger} 33 | 34 | )} 35 | defaultOpen={defaultOpen} 36 | {...props} 37 | /> 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /packages/web-parser/weekly-rotation/getWeeklyRotation.ts: -------------------------------------------------------------------------------- 1 | import { legends } from "bhapi/legends" 2 | import { load } from "cheerio" 3 | import { parseBHArticlesPage } from "../bh-articles/parseBHArticlesPage" 4 | import axios from "axios" 5 | import type { Legend } from "bhapi/types" 6 | 7 | const PREFIXES = [ 8 | "The free-to-play Legend rotation for this week includes: ", 9 | "The free-to-play Legend rotation for this week features ", 10 | ] 11 | 12 | export const getWeeklyRotation = async () => { 13 | const [article] = await parseBHArticlesPage(1, "weekly-rotation") 14 | 15 | if (!article) return [] 16 | 17 | const { data } = await axios.get(article.href) 18 | 19 | const $ = load(data) 20 | 21 | for (const prefix of PREFIXES) { 22 | const txt = $("i") 23 | .filter((_, el) => $(el).text().startsWith(prefix)) 24 | .first() 25 | .text() 26 | 27 | if (!txt) continue 28 | 29 | const legendsNames = txt 30 | .slice(prefix.length) 31 | .replace(".", "") 32 | .replace(/&|(and)/g, "") 33 | .split(",") 34 | .map((s) => s.trim()) 35 | 36 | return legendsNames 37 | .map((name) => legends.find((l) => l.bio_name === name)) 38 | .filter(Boolean) as Legend[] 39 | } 40 | 41 | return [] 42 | } 43 | -------------------------------------------------------------------------------- /app/components/search/SearchboxItem.tsx: -------------------------------------------------------------------------------- 1 | import { AppLink } from "ui/base/AppLink" 2 | import { useKBar } from "kbar" 3 | import type { ReactNode } from "react" 4 | 5 | type SearchboxItemProps = { 6 | icon?: ReactNode 7 | title: ReactNode 8 | subtitle?: ReactNode 9 | href: string 10 | rightContent?: ReactNode 11 | } 12 | 13 | export const SearchboxItem = ({ 14 | icon, 15 | href, 16 | title, 17 | subtitle, 18 | rightContent, 19 | }: SearchboxItemProps) => { 20 | const { 21 | query: { toggle }, 22 | } = useKBar() 23 | 24 | return ( 25 | toggle()} 28 | className="px-4 py-3 w-full flex items-center justify-between gap-8 border-b cursor-pointer border-bgVar2 hover:bg-bg/75" 29 | > 30 |
31 | {icon} 32 |
33 |

{title}

34 | {subtitle && ( 35 |

36 | {subtitle} 37 |

38 | )} 39 |
40 |
41 | {rightContent} 42 |
43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 |

Corehalla

5 | 6 |

7 | View official rankings, player and clan stats, or find a community, and join the fight! 8 |

9 |

10 |

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

24 | -------------------------------------------------------------------------------- /app/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 |

Corehalla

5 | 6 |

7 | View official rankings, player and clan stats, or find a community, and join the fight! 8 |

9 |

10 |

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

24 | -------------------------------------------------------------------------------- /app/components/layout/Layout.tsx: -------------------------------------------------------------------------------- 1 | import { FirstTimePopup } from "@components/FirstTimePopup" 2 | import { Footer } from "./Footer" 3 | import { Header } from "./Header" 4 | import { LandingBackground } from "./LandingBackground" 5 | import { SideNav } from "./SideNav" 6 | import { bgVar1 } from "ui/theme/theme" 7 | import { styled } from "ui/theme" 8 | import type { ReactNode } from "react" 9 | 10 | export type LayoutProps = { 11 | children: ReactNode 12 | } 13 | 14 | const BackgroundContainer = styled("div", { 15 | "&>svg": { 16 | maskImage: `linear-gradient(0deg, ${bgVar1}00 0%, ${bgVar1} 40%)`, 17 | }, 18 | }) 19 | 20 | export const Layout = ({ children }: LayoutProps) => { 21 | return ( 22 | <> 23 | 24 | 25 | 26 |
27 | 28 |
29 |
30 |
31 | {children} 32 |
33 |
34 |
35 |
36 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /app/pages/api/rankings/search/player.ts: -------------------------------------------------------------------------------- 1 | import { SEARCH_PLAYERS_ALIASES_PER_PAGE } from "server/helpers/constants" 2 | import { supabaseService } from "db/supabase/service" 3 | import type { BHPlayerAlias } from "db/generated/client" 4 | import type { NextApiHandler } from "next" 5 | 6 | const handler: NextApiHandler = async (req, res) => { 7 | res.setHeader( 8 | "Cache-Control", 9 | "public, s-maxage=600, stale-while-revalidate=3600", 10 | ) 11 | 12 | const { search, page = "1" } = req.query 13 | 14 | if (!search) { 15 | return res.status(403).json({ error: "Bad request" }) 16 | } 17 | 18 | try { 19 | let query = supabaseService 20 | .from("BHPlayerAlias") 21 | .select("*") 22 | .order("alias", { ascending: true }) 23 | 24 | if (search) { 25 | query = query.match({ alias: search }) 26 | } 27 | 28 | const pageNum = parseInt(page as string) 29 | 30 | const { data, error } = await query.range( 31 | (pageNum - 1) * SEARCH_PLAYERS_ALIASES_PER_PAGE, 32 | pageNum * SEARCH_PLAYERS_ALIASES_PER_PAGE - 1, 33 | ) 34 | 35 | if (error) throw error 36 | 37 | //TODO: fetch all aliases used by players 38 | 39 | res.status(200).json(data ?? []) 40 | } catch (error) { 41 | res.status(500).json({ error: "something went wrong" }) 42 | } 43 | } 44 | 45 | export default handler 46 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Corehalla", 3 | "workspaceFolder": "/workspace", 4 | "mounts": [ 5 | "source=${localWorkspaceFolder},target=/workspace,type=bind", 6 | "source=${localWorkspaceFolder}/.devcontainer/zsh/.zshrc,target=/root/.zshrc,type=bind", 7 | "source=${localWorkspaceFolder}/.devcontainer/zsh/devcontainer.zsh-theme,target=/root/.oh-my-zsh/custom/themes/devcontainer.zsh-theme,type=bind" 8 | ], 9 | "customizations": { 10 | "vscode": { 11 | "extensions": [ 12 | "dbaeumer.vscode-eslint", 13 | "bradlc.vscode-tailwindcss", 14 | "Prisma.prisma", 15 | "eamodio.gitlens", 16 | "mhutchie.git-graph", 17 | "GitHub.vscode-pull-request-github", 18 | "ms-azuretools.vscode-docker", 19 | "usernamehw.errorlens", 20 | "mrorz.language-gettext", 21 | "rangav.vscode-thunder-client" 22 | ], 23 | "settings": { 24 | "terminal.integrated.defaultProfile.linux": "zsh", 25 | "terminal.integrated.profiles.linux": { 26 | "zsh": { 27 | "path": "/bin/zsh" 28 | } 29 | } 30 | } 31 | } 32 | }, 33 | "dockerComposeFile": "docker-compose.yml", 34 | "service": "app", 35 | "forwardPorts": [ 36 | 3000, 37 | 3001, 38 | 3002 39 | ], 40 | "portsAttributes": { 41 | "3000": { 42 | "label": "Corehalla Web" 43 | }, 44 | "3001": { 45 | "label": "Supabase Studio" 46 | }, 47 | "3002": { 48 | "label": "Corehalla Worker" 49 | } 50 | }, 51 | "postStartCommand": "pnpm ci:install && pnpm setup:env" 52 | } -------------------------------------------------------------------------------- /packages/ui/base/Tooltip.tsx: -------------------------------------------------------------------------------- 1 | import * as RadixTooltip from "@radix-ui/react-tooltip" 2 | import { cn } from "common/helpers/classnames" 3 | import type { ReactNode } from "react" 4 | 5 | type TooltipProps = { 6 | content: ReactNode 7 | children: ReactNode 8 | delay?: number 9 | side?: RadixTooltip.TooltipContentProps["side"] 10 | align?: RadixTooltip.TooltipContentProps["align"] 11 | className?: string 12 | } 13 | 14 | export const Tooltip = ({ 15 | content, 16 | delay = 0, 17 | children, 18 | side = "top", 19 | align = "center", 20 | className, 21 | }: TooltipProps) => { 22 | return ( 23 | 24 | 25 | 26 | {children} 27 | 28 | 29 | 40 | 41 | 42 | 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /packages/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui", 3 | "version": "0.0.0", 4 | "main": "./index.tsx", 5 | "types": "./index.tsx", 6 | "devDependencies": { 7 | "@types/nprogress": "^0.2.3", 8 | "@types/react": "^18.2.31", 9 | "@types/react-dom": "^18.2.18", 10 | "@types/react-table": "^7.7.13", 11 | "autoprefixer": "^10.4.13", 12 | "postcss": "^8.4.33", 13 | "tailwindcss": "^3.4.1", 14 | "tsconfig": "workspace:*", 15 | "typescript": "^5.3.3" 16 | }, 17 | "dependencies": { 18 | "@radix-ui/colors": "^3.0.0", 19 | "@radix-ui/react-collapsible": "^1.0.1", 20 | "@radix-ui/react-dialog": "^1.0.2", 21 | "@radix-ui/react-dropdown-menu": "^2.0.1", 22 | "@radix-ui/react-navigation-menu": "^1.1.1", 23 | "@radix-ui/react-popover": "^1.0.2", 24 | "@radix-ui/react-progress": "^1.0.1", 25 | "@radix-ui/react-tooltip": "^1.0.2", 26 | "@react-icons/all-files": "https://github.com/react-icons/react-icons/releases/download/v5.0.1/react-icons-all-files-5.0.1.tgz", 27 | "@stitches/react": "^1.2.8", 28 | "bhapi": "workspace:*", 29 | "common": "workspace:*", 30 | "db": "workspace:*", 31 | "kbar": "0.1.0-beta.45", 32 | "logger": "workspace:*", 33 | "next": "13.4.19", 34 | "nprogress": "^0.2.0", 35 | "react": "^18.2.0", 36 | "react-dom": "^18.2.0", 37 | "react-phone-input-2": "^2.15.1", 38 | "react-select": "^5.8.0", 39 | "react-table": "^7.8.0" 40 | }, 41 | "scripts": { 42 | "ts:check": "tsc --noEmit" 43 | } 44 | } -------------------------------------------------------------------------------- /packages/bhapi/mocks/clan.ts: -------------------------------------------------------------------------------- 1 | import type { Clan } from "../types" 2 | 3 | export const clanMock: Clan = { 4 | clan_id: 849913, 5 | clan_name: "bad pIayers", 6 | clan_create_date: 1571095544, 7 | clan_xp: "618995", 8 | clan: [ 9 | { 10 | brawlhalla_id: 85291, 11 | name: "pk", 12 | rank: "Leader", 13 | join_date: 1571095544, 14 | xp: 39195, 15 | }, 16 | { 17 | brawlhalla_id: 51859169, 18 | name: "Reedman", 19 | rank: "Member", 20 | join_date: 1612765369, 21 | xp: 7053, 22 | }, 23 | { 24 | brawlhalla_id: 620195, 25 | name: "Alain", 26 | rank: "Recruit", 27 | join_date: 1615521402, 28 | xp: 32131, 29 | }, 30 | { 31 | brawlhalla_id: 257670, 32 | name: "Boomie", 33 | rank: "Officer", 34 | join_date: 1615523565, 35 | xp: 205869, 36 | }, 37 | { 38 | brawlhalla_id: 56387353, 39 | name: "saturn", 40 | rank: "Member", 41 | join_date: 1617530544, 42 | xp: 75077, 43 | }, 44 | { 45 | brawlhalla_id: 9526335, 46 | name: "darkgoul", 47 | rank: "Recruit", 48 | join_date: 1627531043, 49 | xp: 134302, 50 | }, 51 | { 52 | brawlhalla_id: 3666461, 53 | name: "snowy", 54 | rank: "Recruit", 55 | join_date: 1639127801, 56 | xp: 46329, 57 | }, 58 | ], 59 | } 60 | -------------------------------------------------------------------------------- /packages/common/hooks/useLocalStorageState.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | export const useLocalStorageState = ( 4 | key: string, 5 | initialValue: T, 6 | ssrInitialValue?: T, 7 | ) => { 8 | const [storedValue, setStoredValue] = useState( 9 | ssrInitialValue ?? initialValue, 10 | ) 11 | 12 | const setValue = (value: T | ((val: T) => T)) => { 13 | try { 14 | const valueToStore = 15 | value instanceof Function ? value(storedValue) : value 16 | 17 | setStoredValue(valueToStore) 18 | 19 | if (typeof window !== "undefined") { 20 | window.localStorage.setItem(key, JSON.stringify(valueToStore)) 21 | } 22 | } catch (error) { 23 | // Error saving data 24 | } 25 | } 26 | 27 | useEffect(() => { 28 | if (typeof window === "undefined") { 29 | return 30 | } 31 | 32 | try { 33 | const item = window.localStorage.getItem(key) 34 | setStoredValue(item ? JSON.parse(item) : initialValue) 35 | } catch (error) { 36 | // Error retrieving data 37 | } 38 | 39 | const handleStorageChange = (event: StorageEvent) => { 40 | if (event.key === key) { 41 | setStoredValue(JSON.parse(event.newValue ?? "")) 42 | } 43 | } 44 | 45 | window.addEventListener("storage", handleStorageChange) 46 | 47 | return () => { 48 | window.removeEventListener("storage", handleStorageChange) 49 | } 50 | }, [key]) 51 | 52 | return [storedValue, setValue] as const 53 | } 54 | -------------------------------------------------------------------------------- /packages/server/router/stats/getClansRankings.ts: -------------------------------------------------------------------------------- 1 | import { CLANS_RANKINGS_PER_PAGE } from "../../helpers/constants" 2 | import { logInfo } from "logger" 3 | import { numericLiteralValidator } from "common/helpers/validators" 4 | import { publicProcedure } from "../../trpc" 5 | import { supabaseService } from "db/supabase/service" 6 | import { withTimeLog } from "../../helpers/withTimeLog" 7 | import { z } from "zod" 8 | import type { BHClan } from "db/generated/client" 9 | 10 | export const getClansRankings = publicProcedure 11 | .input( 12 | z.object({ 13 | name: z.string(), 14 | page: numericLiteralValidator, 15 | }), 16 | ) 17 | .query( 18 | withTimeLog(async (req) => { 19 | const { name, page } = req.input 20 | logInfo("getClansRankings", req.input) 21 | 22 | let query = supabaseService.from("BHClan").select("*") 23 | 24 | const cleanName = name.trim().replace(/'/g, "\\'") 25 | 26 | if (cleanName.length > 0) { 27 | query = query.ilike("name", `${cleanName}%`) 28 | } else { 29 | query = query.select("*") 30 | } 31 | 32 | const { data, error } = await query 33 | .order("xp", { ascending: false }) 34 | .range( 35 | (page - 1) * CLANS_RANKINGS_PER_PAGE, 36 | page * CLANS_RANKINGS_PER_PAGE - 1, 37 | ) 38 | 39 | if (error) { 40 | throw error 41 | } 42 | 43 | // TODO: type check this with zod 44 | return data 45 | }, "getClansRankings"), 46 | ) 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "corehalla", 3 | "version": "0.0.0", 4 | "private": true, 5 | "repository": "https://github.com/djobbo/corehalla.git", 6 | "author": "Djobbo Maïga ", 7 | "scripts": { 8 | "build": "turbo run build", 9 | "lint": "eslint --fix --ext .js,.jsx,.ts,.tsx .", 10 | "format": "prettier --write \"**/*.{ts,tsx,md}\" && turbo run format", 11 | "ts:check": "turbo run ts:check", 12 | "ci:install": "pnpm install --frozen-lockfile", 13 | "ci:lint": "eslint --ext .js,.jsx,.ts,.tsx .", 14 | "ci:deadcode": "turbo run ci:deadcode", 15 | "dl-roster": "turbo run dl-roster", 16 | "db:migrate": "turbo run db:migrate", 17 | "db:migrate:prod": "turbo run db:migrate:prod --scope=db --include-dependencies --no-deps", 18 | "build:prod": "pnpm db:migrate:prod && turbo run build --scope=app --include-dependencies --no-deps", 19 | "dev": "turbo run dev --parallel", 20 | "setup:env": "zx setup.zx.mjs" 21 | }, 22 | "devDependencies": { 23 | "@typescript-eslint/eslint-plugin": "^6.19.0", 24 | "@typescript-eslint/parser": "^6.19.0", 25 | "eslint": "^8.56.0", 26 | "eslint-config-next": "^14.1.0", 27 | "eslint-plugin-jsx-a11y": "^6.8.0", 28 | "eslint-plugin-prettier": "^5.1.3", 29 | "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", 30 | "prettier": "^3.2.4", 31 | "turbo": "^1.11.3", 32 | "typescript": "^5.3.3", 33 | "zx": "^7.2.3" 34 | }, 35 | "engines": { 36 | "npm": ">=7.0.0", 37 | "node": ">=18.0.0" 38 | }, 39 | "packageManager": "pnpm@8.5.0" 40 | } -------------------------------------------------------------------------------- /packages/ui/base/PageLoader.tsx: -------------------------------------------------------------------------------- 1 | import { theme } from "../theme" 2 | import { useEffect, useState } from "react" 3 | import { useRouter } from "next/router" 4 | import NProgress from "nprogress" 5 | import type { ReactNode } from "react" 6 | 7 | type PageLoaderProps = { 8 | children: ReactNode 9 | } 10 | 11 | NProgress.configure({ showSpinner: false }) 12 | 13 | export const PageLoader = ({ children }: PageLoaderProps) => { 14 | const router = useRouter() 15 | 16 | const [loading, setLoading] = useState(false) 17 | 18 | useEffect(() => { 19 | const handleStart = () => { 20 | NProgress.start() 21 | setLoading(true) 22 | } 23 | const handleComplete = () => { 24 | NProgress.done() 25 | setLoading(false) 26 | } 27 | 28 | router.events.on("routeChangeStart", handleStart) 29 | router.events.on("routeChangeComplete", handleComplete) 30 | router.events.on("routeChangeError", handleComplete) 31 | 32 | return () => { 33 | router.events.off("routeChangeStart", handleStart) 34 | router.events.off("routeChangeComplete", handleComplete) 35 | router.events.off("routeChangeError", handleComplete) 36 | } 37 | }, [router.events]) 38 | 39 | if (!loading) return null 40 | 41 | return ( 42 |
48 | {children} 49 |
50 | ) 51 | } 52 | -------------------------------------------------------------------------------- /app/components/articles/ArticlePreview.tsx: -------------------------------------------------------------------------------- 1 | import { type BHArticle } from "web-parser/common" 2 | import { Image } from "@components/Image" 3 | 4 | type ArticlePreviewProps = { 5 | article: BHArticle 6 | } 7 | 8 | const BASE_BRAWLHALLA_ARTICLE_URL = "https://brawlhalla.com/news/" 9 | 10 | export const ArticlePreview = ({ article }: ArticlePreviewProps) => { 11 | const { title, featuredImage, categories } = article 12 | 13 | const href = `${BASE_BRAWLHALLA_ARTICLE_URL}${article.slug}` 14 | 15 | return ( 16 |
17 | 23 | {title} 30 | 31 |
32 | {categories.map((category) => ( 33 | 37 | {category.name} 38 | 39 | ))} 40 |
41 |

42 | 43 | {title} 44 | 45 |

46 |
47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /app/components/search/SearchButton.tsx: -------------------------------------------------------------------------------- 1 | import { Kbd } from "ui/base/Kbd" 2 | import { SearchIcon } from "ui/icons" 3 | import { cn } from "common/helpers/classnames" 4 | import { useDevice } from "common/hooks/useDevice" 5 | import { useKBar } from "kbar" 6 | 7 | type SearchButtonProps = { 8 | className?: string 9 | bg?: string 10 | customWidth?: boolean 11 | } 12 | 13 | export const SearchButton = ({ 14 | className, 15 | bg, 16 | customWidth, 17 | }: SearchButtonProps) => { 18 | const { query } = useKBar() 19 | const device = useDevice() 20 | 21 | return ( 22 | 41 | ) 42 | } 43 | 44 | type SearchButtonIconProps = { 45 | className?: string 46 | size?: number 47 | } 48 | 49 | export const SearchButtonIcon = ({ 50 | className, 51 | size, 52 | }: SearchButtonIconProps) => { 53 | const { query } = useKBar() 54 | 55 | return ( 56 | 59 | ) 60 | } 61 | -------------------------------------------------------------------------------- /app/components/stats/GamesDisplay.tsx: -------------------------------------------------------------------------------- 1 | import { Progress } from "ui/base/Progress" 2 | import { calculateWinrate } from "bhapi/helpers/calculateWinrate" 3 | import { cn } from "common/helpers/classnames" 4 | import type { ReactNode } from "react" 5 | 6 | type GamesCardProps = { 7 | games: number 8 | wins: number 9 | description?: ReactNode 10 | className?: string 11 | mainContent?: ReactNode 12 | } 13 | 14 | export const GamesDisplay = ({ 15 | games, 16 | wins, 17 | description, 18 | className, 19 | mainContent, 20 | }: GamesCardProps) => { 21 | return ( 22 |
23 |

24 | {mainContent ?? games} 25 | 26 | {description ?? "games"} 27 | 28 |

29 | 34 |
35 | 36 | {wins}W{" "} 37 | 38 | ({calculateWinrate(wins, games).toFixed(2)}%) 39 | 40 | 41 | 42 | {games - wins}L{" "} 43 | 44 | ({calculateWinrate(games - wins, games).toFixed(2)}%) 45 | 46 | 47 |
48 |
49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /setup.zx.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zx 2 | 3 | import { $, cd, chalk, fs, sleep } from "zx" 4 | import { exit } from "node:process" 5 | 6 | const { STUDIO_PORT } = process.env 7 | 8 | //eslint-disable-next-line no-console 9 | const log = (msg) => console.log(`${chalk.green("[dev-env]")} ${msg}`) 10 | 11 | //eslint-disable-next-line no-console 12 | const newLine = () => console.log() 13 | 14 | const { version } = await fs.readJson("./package.json") 15 | log(`Corehalla Version: ${version}`) 16 | 17 | log("Starting dev environment...") 18 | 19 | log(chalk.bold("Installing dependencies")) 20 | try { 21 | await $`pnpm ci:install` 22 | } catch { 23 | log(chalk.red(`Failed to install dependencies`)) 24 | exit(1) 25 | } 26 | log("✔️ Installed dependencies") 27 | newLine() 28 | 29 | log(chalk.italic("Waiting for database to start...")) 30 | try { 31 | const MAX_RETRIES = 10 32 | cd("packages/db") 33 | let retriesLeft = MAX_RETRIES 34 | let dbReady = false 35 | 36 | while (retriesLeft > 0 && !dbReady) { 37 | try { 38 | await $`pnpm db:migrate up` 39 | dbReady = true 40 | } catch { 41 | log( 42 | `Waiting for database to start... (retry ${ 43 | MAX_RETRIES - retriesLeft + 1 44 | }/${MAX_RETRIES})`, 45 | ) 46 | retriesLeft-- 47 | await sleep(5000) 48 | } 49 | } 50 | 51 | if (!dbReady) { 52 | throw new Error("Max retries exceeded, database not ready.") 53 | } 54 | } catch (e) { 55 | log(chalk.red("Failed to start dev environment")) 56 | exit(1) 57 | } 58 | 59 | log("✔️ Migrated database") 60 | log("✔️ Dev environment ready") 61 | log( 62 | `Supabase Studio is running at: ${chalk.blue( 63 | `http://localhost:${STUDIO_PORT}`, 64 | )}`, 65 | ) 66 | -------------------------------------------------------------------------------- /packages/common/analytics/GAScripts.tsx: -------------------------------------------------------------------------------- 1 | import { GA_TRACKING_ID, adsenseCaPub, gaPageview } from "./gtag" 2 | import { useEffect } from "react" 3 | import { useRouter } from "next/router" 4 | import Script from "next/script" 5 | 6 | export const GAScripts = () => { 7 | const router = useRouter() 8 | 9 | useEffect(() => { 10 | const handleRouteChange = (url: string) => { 11 | gaPageview(url) 12 | } 13 | router.events.on("routeChangeComplete", handleRouteChange) 14 | router.events.on("hashChangeComplete", handleRouteChange) 15 | return () => { 16 | router.events.off("routeChangeComplete", handleRouteChange) 17 | router.events.off("hashChangeComplete", handleRouteChange) 18 | } 19 | }, [router.events]) 20 | 21 | return ( 22 | <> 23 | {/* Global Site Tag (gtag.js) - Google Analytics */} 24 |