109 lines
3.2 KiB
TypeScript
109 lines
3.2 KiB
TypeScript
|
|
import fs from 'node:fs'
|
||
|
|
import path from 'node:path'
|
||
|
|
|
||
|
|
export default defineEventHandler(async () => {
|
||
|
|
const categories: Array<{
|
||
|
|
id: string
|
||
|
|
label: string
|
||
|
|
type: 'static' | 'general' | 'game'
|
||
|
|
rules?: string[]
|
||
|
|
games?: Array<{
|
||
|
|
id: string
|
||
|
|
name: string
|
||
|
|
iconUrl: string
|
||
|
|
bannerUrl: string
|
||
|
|
rules: string[]
|
||
|
|
}>
|
||
|
|
}> = [
|
||
|
|
{
|
||
|
|
id: 'coc',
|
||
|
|
label: 'Code of Conduct violation',
|
||
|
|
type: 'static'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'nsa',
|
||
|
|
label: 'Network Service Agreement violation',
|
||
|
|
type: 'static'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'general',
|
||
|
|
label: 'General Game Rules Violation',
|
||
|
|
type: 'general',
|
||
|
|
rules: []
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'game_specific',
|
||
|
|
label: 'Game-Specific violation',
|
||
|
|
type: 'game',
|
||
|
|
games: []
|
||
|
|
}
|
||
|
|
]
|
||
|
|
|
||
|
|
const parseMarkdownRules = (content: string): string[] => {
|
||
|
|
const rules: string[] = []
|
||
|
|
const regex = /^###\s+\d+\.\s+\*\*(.*?)\*\*/gm
|
||
|
|
let match: RegExpExecArray | null
|
||
|
|
|
||
|
|
while ((match = regex.exec(content)) !== null) {
|
||
|
|
if (match[1]) {
|
||
|
|
rules.push(match[1].trim())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return rules
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const generalRulesPath = path.resolve(process.cwd(), 'public/policy/GENERAL-NETWORK-RULES.md')
|
||
|
|
if (fs.existsSync(generalRulesPath)) {
|
||
|
|
const content = fs.readFileSync(generalRulesPath, 'utf-8')
|
||
|
|
const generalCategory = categories.find(c => c.id === 'general')
|
||
|
|
if (generalCategory) {
|
||
|
|
generalCategory.rules = parseMarkdownRules(content)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (err) {
|
||
|
|
console.error('Error reading GENERAL-NETWORK-RULES.md:', err)
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const gameRulesDir = path.resolve(process.cwd(), 'public/policy/game-rules')
|
||
|
|
if (fs.existsSync(gameRulesDir)) {
|
||
|
|
const entries = fs.readdirSync(gameRulesDir, { withFileTypes: true })
|
||
|
|
const gameCategory = categories.find(c => c.id === 'game_specific')
|
||
|
|
|
||
|
|
for (const entry of entries) {
|
||
|
|
if (entry.isDirectory()) {
|
||
|
|
const gameFolderPath = path.join(gameRulesDir, entry.name)
|
||
|
|
const metadataPath = path.join(gameFolderPath, 'metadata.json')
|
||
|
|
const rulePath = path.join(gameFolderPath, 'rule.md')
|
||
|
|
|
||
|
|
if (fs.existsSync(metadataPath) && fs.existsSync(rulePath)) {
|
||
|
|
try {
|
||
|
|
const metadataRaw = fs.readFileSync(metadataPath, 'utf-8')
|
||
|
|
const metadata = JSON.parse(metadataRaw)
|
||
|
|
const ruleContent = fs.readFileSync(rulePath, 'utf-8')
|
||
|
|
const gameRules = parseMarkdownRules(ruleContent)
|
||
|
|
|
||
|
|
const icon = metadata.icons?.icon ? `/policy/game-rules/${entry.name}/${metadata.icons.icon}` : ''
|
||
|
|
const banner = metadata.icons?.banner ? `/policy/game-rules/${entry.name}/${metadata.icons.banner}` : ''
|
||
|
|
|
||
|
|
gameCategory?.games?.push({
|
||
|
|
id: entry.name,
|
||
|
|
name: metadata.name || entry.name,
|
||
|
|
iconUrl: icon,
|
||
|
|
bannerUrl: banner,
|
||
|
|
rules: gameRules
|
||
|
|
})
|
||
|
|
} catch (jsonErr) {
|
||
|
|
console.error(`Error parsing game rule assets for ${entry.name}:`, jsonErr)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (err) {
|
||
|
|
console.error('Error scanning game-rules folder:', err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return categories
|
||
|
|
})
|