Skip to content

Commit

Permalink
Refactor: Code Optimization (#4)
Browse files Browse the repository at this point in the history
* Fix data export (RiiConnect24#33) (RiiConnect24#35)

This just defers the download to the next event cycle, allowing React
enough time to properly update the href.

* Fix typo in readme

* Only print registered date if user registered after RiiTag 2.0 came out

* Add correct favicons

* Fix path to apple touch icon png

* Add theme color

* Expand on homepage

* Replace tag error with image

* Add game counter to homepage

* Add GameTDB titles to parse

* Add 3DS-RPC to supported platforms list

* Find similar games

* Add custom background for embed

* Remove unknown Mii showing up on tag

* Add Wii Menu Dark theme

* Add Switch support

* Add switchtdb.json

* Add switchtdb.xml

* Fix cover reducing size

* Fix ids issue

* Reduce xml filesize

* Make grabbing cover be async

* Add search bar to leaderboard

* Fix cover grabbing

* Fix Flat Dark font setting

* Fix pagination when searching games

* Engine rewrite

* Neo Renderer Update

Co-authored-by: Matthew <[email protected]>

* Replace makeBanner with renderTag (Neo renderer)

* feature: Events

* fix: env

* refactor: Rewrites

* package: Fixes

* package: Fixes

* refactor: Eslint fixes

* refactor: Linting issue fixes

* refactor: Lint fixes

* refactor: Began rewritting entire to fit JS standard

* refactor: More code to JS Standard

* refactor: Final JS standard rewrites

* fix: Fixed module constructors

* renderer: Code optimization and documentation

* fix: Fixed renderer crashes and cover order

* .env emptying

* feature: Starting point for playtime tracking

* .env fix

---------
  • Loading branch information
matthe815 authored Jul 12, 2023
1 parent ef86487 commit f5c82ed
Show file tree
Hide file tree
Showing 17 changed files with 189 additions and 186 deletions.
2 changes: 2 additions & 0 deletions prisma/migrations/20230701142354_events copy/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `playlog` ADD COLUMN `playtime` int NULL;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ model playlog {
playlog_id Int @id @default(autoincrement()) @db.UnsignedInt
user_id Int
game_pk Int @db.UnsignedInt
play_time Int?
played_on DateTime @default(now())
game game @relation(fields: [game_pk], references: [game_pk], onUpdate: NoAction, map: "FK_playlog_game")
user user @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction, map: "FK_playlog_user")
Expand Down
3 changes: 2 additions & 1 deletion src/lib/riitag/neo/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import logger from '@/lib/logger'
import Font from './std/Font'
import Canvas from 'canvas'

export function drawText (ctx: Canvas.CanvasRenderingContext2D, font: Font, text: string, x: number, y: number, align?: Canvas.CanvasTextAlign) {
export function drawText (ctx: Canvas.CanvasRenderingContext2D, font: Font, text: string, x: number, y: number, align?: Canvas.CanvasTextAlign): void {
ctx.font = `${font.style} ${font.size}px ${font.name}`
logger.info(`Font info: ${ctx.font}`)

ctx.fillStyle = font.color
ctx.textAlign = align || 'start'
ctx.fillText(text, font.size + x, font.size + y)
Expand Down
22 changes: 13 additions & 9 deletions src/lib/riitag/neo/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import path from 'node:path'
import fs from 'node:fs'
import { existsSync, readdirSync, readFileSync } from 'node:fs'
import Canvas from 'canvas'
import { CACHE, DATA } from '@/lib/constants/filePaths'
import { exists, saveFile } from '@/lib/utils/fileUtils'
import { saveFile } from '@/lib/utils/fileUtils'
import ModuleBase from './ModuleBase'
import logger from '@/lib/logger'
import { user } from '@prisma/client'

async function loadFonts () {
const fontJsons = await fs.promises.readdir(DATA.FONTS)
const fontJsons = readdirSync(DATA.FONTS)

await Promise.all(
fontJsons.map(async (fontJson) => {
const font = JSON.parse(
await fs.promises.readFile(path.resolve(DATA.FONTS, fontJson), 'utf8')
readFileSync(path.resolve(DATA.FONTS, fontJson), 'utf8')
)

font.styles.map(async (fontStyle) => {
Expand All @@ -26,18 +27,17 @@ async function loadFonts () {
)
}

export async function renderTag (user) {
export async function renderTag (user: user): Promise<void> {
await loadFonts()
const overlayPath = path.resolve(DATA.OVERLAYS, `neo.${user.overlay}.json`)

if (!(await exists(overlayPath))) throw new Error(`Overlay ${overlayPath} does not exist`)
const overlay = JSON.parse(fs.readFileSync(overlayPath, 'utf-8'))
if (!(existsSync(overlayPath))) throw new Error(`Overlay ${overlayPath} does not exist`)
const overlay = JSON.parse(readFileSync(overlayPath, 'utf-8'))

const canvas = new Canvas.Canvas(overlay.width, overlay.height)
const context = canvas.getContext('2d')

let finished = 0

// Load all renderable elements for the overlay
const elements: ModuleBase[] = await Promise.all(overlay.draw_order.map(async (element) => {
const ModuleName = await import(`@/lib/riitag/neo/std/${element}`)
// eslint-disable-next-line new-cap
Expand All @@ -47,11 +47,15 @@ export async function renderTag (user) {
return module
}))

let finished = 0

// Write the renderable elements to the canvas
for (const element of elements) {
await element.render(context, user)
finished++
logger.info(`Finished: ${finished}/${overlay.draw_order.length}`)
}

await saveFile(path.resolve(CACHE.TAGS, `${user.username}.png`), canvas.createPNGStream())
await saveFile(path.resolve(CACHE.TAGS, `${user.username}.max.png`), canvas.createPNGStream())
}
42 changes: 21 additions & 21 deletions src/lib/riitag/neo/std/Avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Canvas from 'canvas'
import path from 'node:path'
import { CACHE, PUBLIC } from '@/lib/constants/filePaths'
import { saveFile } from '@/lib/utils/fileUtils'
import { user } from '@prisma/client'

export default class Avatar extends ModuleBase {
enabled: boolean
Expand All @@ -16,49 +17,48 @@ export default class Avatar extends ModuleBase {
constructor (overlay) {
super()

if (!overlay.avatar) { this.enabled = false; logger.info('Avatar disabled'); return }
if (!overlay.avatar) {
this.enabled = false
return
}

this.enabled = true
logger.info('Avatar enabled')

this.x = overlay.avatar.x
this.y = overlay.avatar.y
this.size = overlay.avatar.size

if (overlay.avatar.background) {
logger.info('Avatar background enabled')
this.background = new ImageBackground(overlay.avatar.background.img, overlay.avatar.background.x, overlay.avatar.background.y, overlay.avatar.background.width, overlay.avatar.background.height)
} else {
logger.info('Avatar background disabled')
}
}

async getAvatar (username: string, image: string): Promise<Canvas.Image> {
const filepath = path.resolve(CACHE.AVATAR, `${username}.png`)

const response = await fetch(image)

if (!response.ok) {
logger.error(`Failed to fetch avatar for ${username}: ${response.statusText}`)
// this.events.emit("rendered");
return
}

await saveFile(filepath, response.body)

return Canvas.loadImage(filepath)
}

async render (ctx: Canvas.CanvasRenderingContext2D, user) {
async render (ctx: Canvas.CanvasRenderingContext2D, user: user): Promise<void> {
logger.info(`Rendering avatar for ${user.username}`)
if (user.show_avatar && this.enabled) {
const avatar = await this.getAvatar(user.username, user.image)
if (this.background) {
const background = await Canvas.loadImage(path.resolve(PUBLIC.OVERLAY_IMAGE, this.background.img))
logger.info('Background loaded')
ctx.drawImage(background, this.background.x, this.background.y, this.background.width, this.background.height)
ctx.drawImage(avatar, this.x, this.y, this.size, this.size)
logger.info('Avatar finished rendering')
} else {
logger.info('No background')
ctx.drawImage(avatar, this.x, this.y, this.size, this.size)
}

if (!(user.show_avatar && this.enabled)) return

if (this.background) {
const background = await Canvas.loadImage(path.resolve(PUBLIC.OVERLAY_IMAGE, this.background.img))
logger.info('Background loaded')
ctx.drawImage(background, this.background.x, this.background.y, this.background.width, this.background.height)
logger.info('Avatar finished rendering')
}

const avatar = await this.getAvatar(user.username, user.image)
ctx.drawImage(avatar, this.x, this.y, this.size, this.size)
}
}
8 changes: 4 additions & 4 deletions src/lib/riitag/neo/std/Background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import ModuleBase from '../ModuleBase'
import logger from '@/lib/logger'

export default class Background extends ModuleBase {
render (ctx: Canvas.CanvasRenderingContext2D, user) {
async render (ctx: Canvas.CanvasRenderingContext2D, user): Promise<void> {
const bgPath = path.resolve(PUBLIC.BACKGROUND, user.background)

if (!fs.existsSync(bgPath)) {
logger.error(`Background image does not exist: ${bgPath}`)
return
}

Canvas.loadImage(bgPath).then((image) => {
ctx.drawImage(image, 0, 0)
})
const bg = await Canvas.loadImage(bgPath)
ctx.drawImage(bg, 0, 0)
}
}
5 changes: 3 additions & 2 deletions src/lib/riitag/neo/std/CoinCount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Font from './Font'
import ModuleBase from '../ModuleBase'
import Canvas, { CanvasTextAlign } from 'canvas'
import { drawText } from '../Utils'
import { user } from '@prisma/client'

export default class CoinCount extends ModuleBase {
font: Font
Expand All @@ -28,9 +29,9 @@ export default class CoinCount extends ModuleBase {
this.max = overlay.coin_count.max
}

render (ctx: Canvas.CanvasRenderingContext2D, user) {
render (ctx: Canvas.CanvasRenderingContext2D, user: user): void {
if (user.font !== 'default' && this.font.force === false) { this.font.name = user.font }

drawText(ctx, this.font, user.coins > this.max ? this.max : user.coins, this.x, this.y, this.align)
drawText(ctx, this.font, user.coins > this.max ? String(this.max) : String(user.coins), this.x, this.y, this.align)
}
}
9 changes: 5 additions & 4 deletions src/lib/riitag/neo/std/CoinIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'node:path'
import Canvas from 'canvas'
import fs from 'node:fs'
import logger from '@/lib/logger'
import { user } from '@prisma/client'

export default class CoinIcon extends ModuleBase {
defaultImg: string
Expand All @@ -18,16 +19,16 @@ export default class CoinIcon extends ModuleBase {
this.y = overlay.coin_icon.y
}

render (ctx: Canvas.CanvasRenderingContext2D, user) {
async render (ctx: Canvas.CanvasRenderingContext2D, user: user): Promise<void> {
const coinImage = user.coin === 'default' ? this.defaultImg : user.coin
const coinPath = path.resolve(PUBLIC.COIN, `${coinImage}.png`)

if (!fs.existsSync(coinPath)) {
logger.error(`Coin image does not exist: ${coinPath}`)
return
}

Canvas.loadImage(coinPath).then((image) => {
ctx.drawImage(image, this.x, this.y)
})
const coin = await Canvas.loadImage(coinPath)
ctx.drawImage(coin, this.x, this.y)
}
}
Loading

0 comments on commit f5c82ed

Please sign in to comment.