House rules also machine translated and added loadrules universal lib

pull/68/head
v4ltages 3 months ago
parent a9f33e9ec0
commit 5771581013
No known key found for this signature in database
GPG Key ID: DC7BC38E0DC642B
  1. 4
      src/app/[locale]/kodukord/page.tsx
  2. 17
      src/app/[locale]/reeglid/[slug]/page.tsx
  3. 29
      src/data/rules/en/kodukord.md
  4. 0
      src/data/rules/et/kodukord.md
  5. 165
      src/lib/loadRules.ts
  6. 75
      src/lib/rules.ts

@ -3,6 +3,7 @@ import ReactMarkdown, { Components } from "react-markdown";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import SectionDivider from "@/components/SectionDivider";
import { getTranslations, setRequestLocale } from "next-intl/server";
import { loadRulesBun } from "@/lib/loadRules";
export default async function Page({
params,
@ -12,8 +13,7 @@ export default async function Page({
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations({ locale });
const file = Bun.file("src/data/kodukord.md");
const content = await file.text();
const content = await loadRulesBun("kodukord", locale as "et" | "en");
return (
<div>

@ -3,6 +3,7 @@ import ReactMarkdown, { Components } from "react-markdown";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import SectionDivider from "@/components/SectionDivider";
import { getTranslations, setRequestLocale } from "next-intl/server";
import { loadRulesBun } from "@/lib/loadRules";
// Map of valid slugs to their translation keys
const rulesMap = {
@ -28,20 +29,10 @@ async function getRuleContent(slug: string, locale: string) {
const ruleConfig = rulesMap[slug as RuleSlug];
try {
// Try to load the file for the current locale first
let filePath = `src/data/rules/${locale}/${slug}.md`;
let file = Bun.file(filePath);
// Check if file exists, if not fallback to Estonian
if (!(await file.exists()) && locale !== "et") {
console.warn(
`Rules file not found for ${slug} in ${locale}, falling back to Estonian`,
const content = await loadRulesBun(
slug as "cs2" | "lol",
locale as "et" | "en",
);
filePath = `src/data/rules/et/${slug}.md`;
file = Bun.file(filePath);
}
const content = await file.text();
return {
content,
titleKey: ruleConfig.titleKey,

@ -0,0 +1,29 @@
Event participation house rules apply to everyone, both visitors and competitors. In case of violation of house rules, TipiLAN reserves the right to remove the participant from the event and, if necessary, notify the police. In the case of an underage participant, we will notify their parents or guardians in case of serious house rule violations.
# Participant Reminders
1. Upon arrival, exchange your ticket for a wristband.
2. Participants must be at least 16 years old. Ticket controllers may ask you for identification.
3. The event will be photographed and filmed, and event content will be covered in various media channels.
4. If you have TipiLAN-provided accommodation, notify us when exchanging your ticket for a wristband.
5. If you bring your own computer, you will be guided on where to set it up when receiving your wristband.
# Event House Rules
1. Participants are obligated to behave politely and with dignity and respect other event participants.
2. TipiLAN does not tolerate:
2.1. Hate speech based on national, racial, gender, sexual or religious affiliation, disabilities, appearance or age; harassment, threatening, offensive or aggressive behavior, incitement or support thereof
2.2. This applies both on the event premises (IRL) and in online environments related to the event.
3. Participants are obligated to treat the event building, inventory and furnishings with care. It is forbidden to break, stain or move items that do not belong to the participant.
3.1. If a participant has organizer-provided accommodation, then in the accommodation area the participant is obligated to be quiet and allow companions to rest.
3.2. Persons who are not provided accommodation there may not be invited to the accommodation area.
4. TipiLAN is not responsible for participants' personal property.
4.1. The organizer-provided accommodation area is lockable and unauthorized persons are not allowed there, but regardless of this, it is worth keeping an eye on your valuables.
4.2. If there is suspicion that theft has occurred, this must be immediately reported to the organizer.
4.3. When finding lost items, please give them to the organizer or take them to *lost & found* (Merchandise table).
5. Smoking and using vapes is prohibited on the event premises. There are designated smoking areas outside for this purpose.
6. Illegal substances or drugs, sharp objects, firearms, explosives or incendiary materials and other items that may harm participants or others may not be brought to the event.
7. Underage participants are prohibited from consuming alcohol or using nicotine-containing products.
7.1. When purchasing alcohol from the bar, participants are obligated to show identification upon request by bar staff.
8. Participants are obligated to behave responsibly regarding alcohol.
9. Any form of gambling for money or other benefits is prohibited.

@ -0,0 +1,165 @@
import fs from "fs";
import path from "path";
export type Locale = "et" | "en";
export type RuleType = "cs2" | "lol" | "kodukord";
/**
* Loads any rule content for a specific type and locale
* @param ruleType - The type of rules to load (cs2, lol, kodukord)
* @param locale - The locale to load rules for (et, en)
* @returns Promise<string> The markdown content of the rules file
*/
export async function loadRules(
ruleType: RuleType,
locale: Locale,
): Promise<string> {
// Try to load the file for the current locale first
let filePath = path.join(
process.cwd(),
"src",
"data",
"rules",
locale,
`${ruleType}.md`,
);
try {
// Check if file exists for current locale
if (fs.existsSync(filePath)) {
const file = await import("fs").then(() =>
fs.readFileSync(filePath, "utf8")
);
return file;
}
// Fallback to Estonian if English version doesn't exist
if (locale !== "et") {
console.warn(
`Rules file not found for ${ruleType} in ${locale}, falling back to Estonian`,
);
const fallbackPath = path.join(
process.cwd(),
"src",
"data",
"rules",
"et",
`${ruleType}.md`,
);
if (fs.existsSync(fallbackPath)) {
const fallbackFile = fs.readFileSync(fallbackPath, "utf8");
return fallbackFile;
}
}
throw new Error(`Rules file not found for ${ruleType}`);
} catch (error) {
console.error(
`Error loading rules for ${ruleType} in locale ${locale}:`,
error,
);
throw new Error(
`Failed to load rules for ${ruleType}: ${error instanceof Error ? error.message : 'Unknown error'}`,
);
}
}
/**
* Loads rules using Bun.file (for Bun runtime environments)
* @param ruleType - The type of rules to load
* @param locale - The locale to load rules for
* @returns Promise<string> The markdown content
*/
export async function loadRulesBun(
ruleType: RuleType,
locale: Locale,
): Promise<string> {
// Try to load the file for the current locale first
let filePath = `src/data/rules/${locale}/${ruleType}.md`;
let file = Bun.file(filePath);
// Check if file exists, if not fallback to Estonian
if (!(await file.exists()) && locale !== "et") {
console.warn(
`Rules file not found for ${ruleType} in ${locale}, falling back to Estonian`,
);
filePath = `src/data/rules/et/${ruleType}.md`;
file = Bun.file(filePath);
}
try {
const content = await file.text();
return content;
} catch (error) {
console.error(
`Error loading rules for ${ruleType} in locale ${locale}:`,
error,
);
throw new Error(
`Failed to load rules for ${ruleType}: ${error instanceof Error ? error.message : 'Unknown error'}`,
);
}
}
/**
* Gets all available rule types for a given locale
* @param locale - The locale to check for available rules
* @returns Promise<RuleType[]> Array of available rule types
*/
export async function getAvailableRules(locale: Locale): Promise<RuleType[]> {
const rulesDir = path.join(process.cwd(), "src", "data", "rules", locale);
try {
const files = fs.readdirSync(rulesDir);
const ruleTypes = files
.filter((file) => file.endsWith(".md"))
.map((file) => file.replace(".md", "") as RuleType);
return ruleTypes;
} catch (error) {
console.warn(`Could not read rules directory for locale ${locale}:`, error);
return [];
}
}
/**
* Checks if a specific rule file exists for a given locale
* @param ruleType - The type of rules to check
* @param locale - The locale to check
* @returns boolean indicating if the file exists
*/
export function ruleExists(ruleType: RuleType, locale: Locale): boolean {
const filePath = path.join(
process.cwd(),
"src",
"data",
"rules",
locale,
`${ruleType}.md`,
);
return fs.existsSync(filePath);
}
/**
* Gets the best available locale for a rule type
* Prefers the requested locale, falls back to Estonian
* @param ruleType - The type of rules to check
* @param preferredLocale - The preferred locale
* @returns Locale The best available locale for the rule type
*/
export function getBestAvailableLocale(
ruleType: RuleType,
preferredLocale: Locale,
): Locale {
if (ruleExists(ruleType, preferredLocale)) {
return preferredLocale;
}
if (ruleExists(ruleType, "et")) {
return "et";
}
// If neither exists, return preferred (will throw error when trying to load)
return preferredLocale;
}

@ -1,35 +1,58 @@
import fs from 'fs';
import path from 'path';
import fs from "fs";
import path from "path";
export type Locale = 'et' | 'en';
export type RuleType = 'cs2' | 'lol';
export type Locale = "et" | "en";
export type RuleType = "cs2" | "lol" | "kodukord";
/**
* Loads rules content for a specific game and locale
* @param ruleType - The type of rules to load (cs2, lol)
* @param ruleType - The type of rules to load (cs2, lol, kodukord)
* @param locale - The locale to load rules for (et, en)
* @returns The markdown content of the rules file
*/
export async function getRules(ruleType: RuleType, locale: Locale): Promise<string> {
const filePath = path.join(process.cwd(), 'src', 'data', 'rules', locale, `${ruleType}.md`);
export async function getRules(
ruleType: RuleType,
locale: Locale,
): Promise<string> {
const filePath = path.join(
process.cwd(),
"src",
"data",
"rules",
locale,
`${ruleType}.md`,
);
try {
const content = fs.readFileSync(filePath, 'utf8');
const content = fs.readFileSync(filePath, "utf8");
return content;
} catch (error) {
// Fallback to Estonian if English version doesn't exist
if (locale === 'en') {
console.warn(`Rules file not found for ${ruleType} in ${locale}, falling back to Estonian`);
const fallbackPath = path.join(process.cwd(), 'src', 'data', 'rules', 'et', `${ruleType}.md`);
if (locale === "en") {
console.warn(
`Rules file not found for ${ruleType} in ${locale}, falling back to Estonian`,
);
const fallbackPath = path.join(
process.cwd(),
"src",
"data",
"rules",
"et",
`${ruleType}.md`,
);
try {
const fallbackContent = fs.readFileSync(fallbackPath, 'utf8');
const fallbackContent = fs.readFileSync(fallbackPath, "utf8");
return fallbackContent;
} catch (fallbackError) {
throw new Error(`Rules file not found for ${ruleType} in either ${locale} or et locale`);
throw new Error(
`Rules file not found for ${ruleType} in either ${locale} or et locale`,
);
}
}
throw new Error(`Rules file not found for ${ruleType} in ${locale} locale: ${error}`);
throw new Error(
`Rules file not found for ${ruleType} in ${locale} locale: ${error}`,
);
}
}
@ -39,13 +62,13 @@ export async function getRules(ruleType: RuleType, locale: Locale): Promise<stri
* @returns Array of available rule types
*/
export async function getAvailableRules(locale: Locale): Promise<RuleType[]> {
const rulesDir = path.join(process.cwd(), 'src', 'data', 'rules', locale);
const rulesDir = path.join(process.cwd(), "src", "data", "rules", locale);
try {
const files = fs.readdirSync(rulesDir);
const ruleTypes = files
.filter(file => file.endsWith('.md'))
.map(file => file.replace('.md', '') as RuleType);
.filter((file) => file.endsWith(".md"))
.map((file) => file.replace(".md", "") as RuleType);
return ruleTypes;
} catch (error) {
@ -61,7 +84,14 @@ export async function getAvailableRules(locale: Locale): Promise<RuleType[]> {
* @returns Boolean indicating if the file exists
*/
export function ruleExists(ruleType: RuleType, locale: Locale): boolean {
const filePath = path.join(process.cwd(), 'src', 'data', 'rules', locale, `${ruleType}.md`);
const filePath = path.join(
process.cwd(),
"src",
"data",
"rules",
locale,
`${ruleType}.md`,
);
return fs.existsSync(filePath);
}
@ -72,13 +102,16 @@ export function ruleExists(ruleType: RuleType, locale: Locale): boolean {
* @param preferredLocale - The preferred locale
* @returns The best available locale for the rule type
*/
export function getBestAvailableLocale(ruleType: RuleType, preferredLocale: Locale): Locale {
export function getBestAvailableLocale(
ruleType: RuleType,
preferredLocale: Locale,
): Locale {
if (ruleExists(ruleType, preferredLocale)) {
return preferredLocale;
}
if (ruleExists(ruleType, 'et')) {
return 'et';
if (ruleExists(ruleType, "et")) {
return "et";
}
// If neither exists, return preferred (will throw error when trying to load)

Loading…
Cancel
Save