Compare commits
4 Commits
2a04c8180a
...
201829a523
Author | SHA1 | Date | |
---|---|---|---|
201829a523 | |||
560bf04b6c | |||
0ff3b817d8 | |||
e36b32e278 |
22
README.md
22
README.md
@ -143,7 +143,7 @@
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><code>POST</code> <code>/api/teams</code> (Liste aller Teams)</summary>
|
<summary><code>GET</code> <code>/api/team</code> (Liste aller Teams)</summary>
|
||||||
|
|
||||||
##### Request Body
|
##### Request Body
|
||||||
|
|
||||||
@ -165,8 +165,24 @@
|
|||||||
"name": string,
|
"name": string,
|
||||||
// Teamfarbe in HEX
|
// Teamfarbe in HEX
|
||||||
"color": string,
|
"color": string,
|
||||||
// UUIDs aller Teammitglieder
|
// UTC timestamp wann das Team zuletzt gejoined ist
|
||||||
"users": (string | null)[]
|
"lastJoined": number | null,
|
||||||
|
// Gewichtung aller Strikes
|
||||||
|
"strikeWeight": number,
|
||||||
|
// Spieler 1 des Teams
|
||||||
|
"memberOne": {
|
||||||
|
// UUID des Spielers
|
||||||
|
"uuid": string,
|
||||||
|
// Ob der Spieler Tot ist
|
||||||
|
"dead": boolean
|
||||||
|
} | null,
|
||||||
|
// Spieler 2 des Teams
|
||||||
|
"memberTwo": {
|
||||||
|
// UUID des Spielers
|
||||||
|
"uuid": string,
|
||||||
|
// Ob der Spieler Tot ist
|
||||||
|
"dead": boolean
|
||||||
|
} | null
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -16,6 +16,10 @@ export default defineConfig({
|
|||||||
prefetch: true,
|
prefetch: true,
|
||||||
base: '/varo',
|
base: '/varo',
|
||||||
|
|
||||||
|
security: {
|
||||||
|
checkOrigin: false
|
||||||
|
},
|
||||||
|
|
||||||
devToolbar: {
|
devToolbar: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@ export const team = {
|
|||||||
input: z.object({
|
input: z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
color: z.string(),
|
color: z.string(),
|
||||||
lastJoined: z.string().datetime().nullable(),
|
lastJoined: z.string().datetime({ local: true }).nullable(),
|
||||||
memberOne: z.object({
|
memberOne: z.object({
|
||||||
id: z.number().nullish(),
|
id: z.number().nullish(),
|
||||||
username: z.string()
|
username: z.string()
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// states
|
// states
|
||||||
let name = $state<string | null>(team?.name ?? null);
|
let name = $state<string | null>(team?.name ?? null);
|
||||||
let color = $state<string | null>(team?.color ?? null);
|
let color = $state<string | null>(team?.color ?? '#000000');
|
||||||
let lastJoined = $state<string | null>(team?.lastJoined ?? null);
|
let lastJoined = $state<string | null>(team?.lastJoined ?? null);
|
||||||
let memberOne = $state<Team['memberOne']>(team?.memberOne ?? ({ username: null } as unknown as Team['memberOne']));
|
let memberOne = $state<Team['memberOne']>(team?.memberOne ?? ({ username: null } as unknown as Team['memberOne']));
|
||||||
let memberTwo = $state<Team['memberOne']>(team?.memberTwo ?? ({ username: null } as unknown as Team['memberOne']));
|
let memberTwo = $state<Team['memberOne']>(team?.memberTwo ?? ({ username: null } as unknown as Team['memberOne']));
|
||||||
@ -74,15 +74,15 @@
|
|||||||
<h3 class="text-xl font-geist font-bold">{popupTitle}</h3>
|
<h3 class="text-xl font-geist font-bold">{popupTitle}</h3>
|
||||||
<div class="w-full flex flex-col">
|
<div class="w-full flex flex-col">
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<Input type="color" label="Farbe" bind:value={color} />
|
<Input type="color" label="Farbe" bind:value={color} required />
|
||||||
<Input type="text" label="Name" bind:value={name} />
|
<Input type="text" label="Name" bind:value={name} required />
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<UserSearch label="Spieler 1" bind:value={memberOne.username} required mustMatch />
|
<UserSearch label="Spieler 1" bind:value={memberOne.username} required mustMatch />
|
||||||
<UserSearch label="Spieler 2" bind:value={memberTwo.username} required />
|
<UserSearch label="Spieler 2" bind:value={memberTwo.username} required />
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<Input type="date" label="Zuletzt gejoined" bind:value={lastJoined}></Input>
|
<Input type="datetime-local" label="Zuletzt gejoined" bind:value={lastJoined}></Input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id?: string;
|
id?: string;
|
||||||
type?: 'color' | 'date' | 'tel' | 'text' | 'email';
|
type?: 'color' | 'date' | 'datetime-local' | 'tel' | 'text' | 'email';
|
||||||
value?: string | null;
|
value?: string | null;
|
||||||
label?: string;
|
label?: string;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { rulesPopupState, rulesPopupRead } from './RulesPopup.ts';
|
import { rulesPopupState, rulesPopupRead } from './RulesPopup.ts';
|
||||||
import { rulesShort } from '../../../rules.ts';
|
import { rules } from '../../../rules.ts';
|
||||||
|
|
||||||
const modalTimeoutSeconds = 30;
|
const modalTimeoutSeconds = 30;
|
||||||
|
|
||||||
@ -37,19 +37,20 @@
|
|||||||
<p>0. Vorwort</p>
|
<p>0. Vorwort</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-content">
|
<div class="collapse-content">
|
||||||
<p>{rulesShort.header}</p>
|
<p>{rules.header}</p>
|
||||||
<p class="mt-1 text-[.75rem]">{rulesShort.footer}</p>
|
<p class="mt-1 text-[.75rem]">{rules.footer}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600"></span>
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600"></span>
|
||||||
</div>
|
</div>
|
||||||
{#each rulesShort.sections as section, i (section.title)}
|
{#each rules.sections as section, i (section.title)}
|
||||||
<div class="collapse collapse-arrow">
|
<div class="collapse collapse-arrow">
|
||||||
<input type="checkbox" autocomplete="off" />
|
<input type="checkbox" autocomplete="off" />
|
||||||
<div class="collapse-title">
|
<div class="collapse-title">
|
||||||
<p>{i + 1}. {section.title}</p>
|
<p>{i + 1}. {section.title}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-content">
|
<div class="collapse-content">
|
||||||
<p>{section.content}</p>
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html section.content}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600"></span>
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600"></span>
|
||||||
|
@ -26,7 +26,9 @@ import {
|
|||||||
type GetTeamByUserUuidReq,
|
type GetTeamByUserUuidReq,
|
||||||
getTeamByUserUuid,
|
getTeamByUserUuid,
|
||||||
type EditTeamReq,
|
type EditTeamReq,
|
||||||
editTeam
|
editTeam,
|
||||||
|
type GetTeamsFullReq,
|
||||||
|
getTeamsFull
|
||||||
} from './schema/team';
|
} from './schema/team';
|
||||||
import {
|
import {
|
||||||
addTeamDraft,
|
addTeamDraft,
|
||||||
@ -176,6 +178,7 @@ export class Database {
|
|||||||
editTeam = (values: EditTeamReq) => editTeam(this.db, values);
|
editTeam = (values: EditTeamReq) => editTeam(this.db, values);
|
||||||
deleteTeam = (values: DeleteTeamReq) => deleteTeam(this.db, values);
|
deleteTeam = (values: DeleteTeamReq) => deleteTeam(this.db, values);
|
||||||
getTeams = (values: GetTeamsReq) => getTeams(this.db, values);
|
getTeams = (values: GetTeamsReq) => getTeams(this.db, values);
|
||||||
|
getTeamsFull = (values: GetTeamsFullReq) => getTeamsFull(this.db, values);
|
||||||
getTeamById = (values: GetTeamByIdReq) => getTeamById(this.db, values);
|
getTeamById = (values: GetTeamByIdReq) => getTeamById(this.db, values);
|
||||||
getTeamByName = (values: GetTeamByNameReq) => getTeamByName(this.db, values);
|
getTeamByName = (values: GetTeamByNameReq) => getTeamByName(this.db, values);
|
||||||
getTeamByUserUuid = (values: GetTeamByUserUuidReq) => getTeamByUserUuid(this.db, values);
|
getTeamByUserUuid = (values: GetTeamByUserUuidReq) => getTeamByUserUuid(this.db, values);
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import { char, int, mysqlTable, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
import { alias, char, int, mysqlTable, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
||||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||||
import { aliasedTable, and, asc, desc, eq, like } from 'drizzle-orm';
|
import { aliasedTable, and, asc, desc, eq, like, sql } from 'drizzle-orm';
|
||||||
import { teamMember } from './teamMember.ts';
|
import { teamMember } from './teamMember.ts';
|
||||||
import { user } from './user.ts';
|
import { user } from './user.ts';
|
||||||
import { teamDraft } from './teamDraft.ts';
|
import { teamDraft } from './teamDraft.ts';
|
||||||
|
import { death } from '@db/schema/death.ts';
|
||||||
|
import { report } from '@db/schema/report.ts';
|
||||||
|
import { reportStatus } from '@db/schema/reportStatus.ts';
|
||||||
|
import { strikeReason } from '@db/schema/strikeReason.ts';
|
||||||
|
import { strike } from '@db/schema/strike.ts';
|
||||||
|
|
||||||
type Database = MySql2Database<{ team: typeof team }>;
|
type Database = MySql2Database<{ team: typeof team }>;
|
||||||
|
|
||||||
@ -31,6 +36,8 @@ export type GetTeamsReq = {
|
|||||||
limit?: number;
|
limit?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type GetTeamsFullReq = {};
|
||||||
|
|
||||||
export type GetTeamByIdReq = {
|
export type GetTeamByIdReq = {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
@ -127,6 +134,45 @@ export async function getTeams(db: Database, values: GetTeamsReq) {
|
|||||||
.limit(values?.limit ?? 100);
|
.limit(values?.limit ?? 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getTeamsFull(db: Database, _values: GetTeamsFullReq) {
|
||||||
|
const memberOneTeamMember = alias(teamMember, 'member_one_team_member');
|
||||||
|
const memberTwoTeamMember = alias(teamMember, 'member_two_team_member');
|
||||||
|
const memberOneUser = alias(user, 'member_one_user');
|
||||||
|
const memberTwoUser = alias(user, 'member_two_user');
|
||||||
|
const memberOneDeath = alias(death, 'member_one_death');
|
||||||
|
const memberTwoDeath = alias(death, 'member_two_death');
|
||||||
|
|
||||||
|
const strikeWeightSubquery = db
|
||||||
|
.select({
|
||||||
|
teamId: team.id,
|
||||||
|
strikeWeight: sql<number>`cast(sum(${strikeReason.weight}) as int)`.as('strikeWeight')
|
||||||
|
})
|
||||||
|
.from(strike)
|
||||||
|
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
||||||
|
.innerJoin(reportStatus, eq(strike.id, reportStatus.strikeId))
|
||||||
|
.innerJoin(report, eq(reportStatus.reportId, report.id))
|
||||||
|
.innerJoin(team, eq(report.reportedTeamId, team.id))
|
||||||
|
.as('strike_weight_subquery');
|
||||||
|
|
||||||
|
return db
|
||||||
|
.select({
|
||||||
|
team: team,
|
||||||
|
memberOne: memberOneUser,
|
||||||
|
memberTwo: memberTwoUser,
|
||||||
|
memberOneDeath: memberOneDeath,
|
||||||
|
memberTwoDeath: memberTwoDeath,
|
||||||
|
strikeWeight: strikeWeightSubquery.strikeWeight
|
||||||
|
})
|
||||||
|
.from(team)
|
||||||
|
.leftJoin(memberOneTeamMember, eq(team.id, memberOneTeamMember.teamId))
|
||||||
|
.leftJoin(memberTwoTeamMember, eq(team.id, memberTwoTeamMember.teamId))
|
||||||
|
.leftJoin(memberOneUser, eq(memberOneTeamMember.userId, memberOneUser.id))
|
||||||
|
.leftJoin(memberTwoUser, eq(memberTwoTeamMember.userId, memberTwoUser.id))
|
||||||
|
.leftJoin(memberOneDeath, eq(memberOneUser.id, memberOneDeath.deadUserId))
|
||||||
|
.leftJoin(memberTwoDeath, eq(memberTwoUser.id, memberTwoDeath.deadUserId))
|
||||||
|
.leftJoin(strikeWeightSubquery, eq(team.id, strikeWeightSubquery.teamId));
|
||||||
|
}
|
||||||
|
|
||||||
export async function getTeamById(db: Database, values: GetTeamByIdReq) {
|
export async function getTeamById(db: Database, values: GetTeamByIdReq) {
|
||||||
const teams = await db.select().from(team).where(eq(team.id, values.id));
|
const teams = await db.select().from(team).where(eq(team.id, values.id));
|
||||||
|
|
||||||
|
@ -7,18 +7,27 @@ export const GET: APIRoute = async ({ request }) => {
|
|||||||
return new Response(null, { status: 401 });
|
return new Response(null, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const teams = await db.getTeams({});
|
const teams = await db.getTeamsFull({});
|
||||||
|
|
||||||
const response = [];
|
const response = [];
|
||||||
for (const team of teams) {
|
for (const team of teams) {
|
||||||
const users = [];
|
|
||||||
if (team.memberOne.uuid) users.push(team.memberOne.uuid);
|
|
||||||
if (team.memberTwo.uuid) users.push(team.memberTwo.uuid);
|
|
||||||
|
|
||||||
response.push({
|
response.push({
|
||||||
name: team.name,
|
name: team.team.name,
|
||||||
color: team.color,
|
color: team.team.color,
|
||||||
users: users
|
lastJoined: team.team.lastJoined ? new Date(team.team.lastJoined).getTime() : null,
|
||||||
|
strikeWeight: team.strikeWeight ?? 0,
|
||||||
|
memberOne: team.memberOne
|
||||||
|
? {
|
||||||
|
uuid: team.memberOne.uuid,
|
||||||
|
dead: team.memberOneDeath != null
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
memberTwo: team.memberTwo
|
||||||
|
? {
|
||||||
|
uuid: team.memberTwo.uuid,
|
||||||
|
dead: team.memberTwoDeath != null
|
||||||
|
}
|
||||||
|
: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import WebsiteLayout from '@layouts/website/WebsiteLayout.astro';
|
import WebsiteLayout from '@layouts/website/WebsiteLayout.astro';
|
||||||
import { rulesLong } from '../rules';
|
import { rules } from '../rules';
|
||||||
---
|
---
|
||||||
|
|
||||||
<WebsiteLayout title="Regeln">
|
<WebsiteLayout title="Regeln">
|
||||||
@ -12,13 +12,13 @@ import { rulesLong } from '../rules';
|
|||||||
<p>0. Vorwort</p>
|
<p>0. Vorwort</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-content">
|
<div class="collapse-content">
|
||||||
<p>{rulesLong.header}</p>
|
<p>{rules.header}</p>
|
||||||
<p class="mt-1 text-[.75rem]">{rulesLong.footer}</p>
|
<p class="mt-1 text-[.75rem]">{rules.footer}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600"></span>
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600"></span>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
rulesLong.sections.map((section, i) => (
|
rules.sections.map((section, i) => (
|
||||||
<div>
|
<div>
|
||||||
<div class="collapse collapse-arrow">
|
<div class="collapse collapse-arrow">
|
||||||
<input type="checkbox" autocomplete="off" />
|
<input type="checkbox" autocomplete="off" />
|
||||||
@ -27,9 +27,7 @@ import { rulesLong } from '../rules';
|
|||||||
{i + 1}. {section.title}
|
{i + 1}. {section.title}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-content">
|
<div class="collapse-content" set:html={section.content} />
|
||||||
<p>{section.content}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
||||||
</div>
|
</div>
|
||||||
|
265
src/rules.ts
265
src/rules.ts
@ -1,4 +1,4 @@
|
|||||||
export const rulesShort = {
|
export const rules = {
|
||||||
header: `
|
header: `
|
||||||
Das Lesen der Regeln ist für alle Teilnehmer verpflichtend. Die Regeln sollen für einen reibungslosen und
|
Das Lesen der Regeln ist für alle Teilnehmer verpflichtend. Die Regeln sollen für einen reibungslosen und
|
||||||
strukturierte Ablauf des Projekts sorgen, weshalb das Lesen der Regeln ein essenzieller Bestandteil für das Gelingen
|
strukturierte Ablauf des Projekts sorgen, weshalb das Lesen der Regeln ein essenzieller Bestandteil für das Gelingen
|
||||||
@ -8,224 +8,87 @@ export const rulesShort = {
|
|||||||
`,
|
`,
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
title: 'Respektvoller Umgang',
|
title: 'Projektziel',
|
||||||
content: `
|
content: `<p>Varo ist ein <b>PvP-Projekt</b>, bei dem <b>2er-Teams</b> gegeneinander antreten. Das letzte
|
||||||
Oberste Priorität hat der respektvolle und tolerante Umgang der Spieler untereinander. Der Spielspaß, der
|
verbliebene Team gewinnt. Stirbst ein Spieler auf <b>irgendeine</b> Weise, ist er aus dem Projekt ausgeschieden. Sein
|
||||||
offene Umgang miteinander und die Interaktion aller steht im Vordergrund, weshalb Drohungen, Belästigungen
|
Teampartner darf aber weiterhin spielen und kann das Projekt für das Team gewinnen.</p>`
|
||||||
oder sonstige gegenüber anderen Spielern respektlose Aktivitäten strengstens verboten sind und auch hart
|
|
||||||
geahndet werden.`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Einschränkungen von Minecraft-Namen, Skins, Chat-Nachrichten, Links, etc.',
|
title: 'Start',
|
||||||
content: `
|
content: `<p><b>Varo 5 startet am 23. Juni um 19:00 Uhr!</b><br>
|
||||||
Selbstverständlich sind sämtliche Inhalte (Minecraft-Namen, Skins, Chat-Nachrichten, Links, etc.) mit
|
Achtung: Wenn ein Team(also beide Spieler) nicht beim Projektstart um genau 19:00 Uhr dabei ist, darf es erst ab Tag 2
|
||||||
sexistischen, diskriminierenden, rassistischen, pornographischen oder illegalen Inhalten nicht erlaubt.
|
einsteigen – und verliert die 30 Minuten des ersten Tages.</p>`
|
||||||
Außerdem ist es nicht gestattet, den Chat mit Nachrichten jeglicher Art vollzuspammen. Des Weiteren sollte
|
|
||||||
der MC-Name des Spielers, der bei der Anmeldung angegeben wird, bis zum Ende des Projekts nicht geändert
|
|
||||||
werden. Das Nutzen bzw. Anmelden von Zweitaccounts ist nicht gestattet.
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Clientmodifikationen',
|
title: 'Team',
|
||||||
content: `
|
content: `<p>Solange beide Teampartner leben, dürfen diese <b>ausnahmslos nur gleichzeitig</b> auf dem Server
|
||||||
Jegliche Clientmodifications, die deutliche Vorteile gegenüber anderen Spielern erbringen, sind nicht
|
sein. Wenn einer der Spielpartner den Server verlässt – ob absichtlich oder durch einen Verbindungsabbruch – wird der
|
||||||
gestattet.
|
andere Spielpartner automatisch ebenfalls getrennt.</p>`
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Redstone-Bauten und überdimensionierte Villager-Baukomplexe',
|
title: 'Join-Zeiten',
|
||||||
content: `
|
content: `<p>Spieler können dem Server zu Beginn täglich von <b>17:00 bis 21:00 Uhr</b> joinen. Diese Zeiten
|
||||||
Das Erbauen und Betreiben lag-erzeugender Maschinen, Farmen (Zero-Tick-Farmen etc.) oder andere Bauten, die
|
können sich im Projektverlauf ändern, worüber natürlich rechtzeitig informiert wird.</p>`
|
||||||
den Spielfluss stören könnten, ist verboten.
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Verkauf von Items',
|
title: 'Zeiterfassung',
|
||||||
content: `
|
content: `<p>Sobald ein Teammitglied den Server betritt müssen der Spieler und sein Teampartner <b>30 Minuten lang
|
||||||
Das Verkaufen von Items ist allgemein jedem Spieler überall gestattet. Jedoch bietet es sich an und ist
|
am Stück</b> auf dem Server spielen. Spielt das Team an einem Tag nicht, darf es am Folgetag 60 Minuten, also zwei
|
||||||
wünschenswert, die Shops aller Spieler in einem Shoppingdistrict beim Spawn gemeinsam anzusiedeln, um die
|
30-Minuten-Slots spielen. Pro Tag wird dem Team also eine Zeit von 30 Minuten gutgeschrieben. Sollte ein Team <b>mehr als
|
||||||
Interaktion zu fördern. Ein angemessener Abstand der privaten Strukturen vom Shoppingdisrict ist
|
90 Minuten Spielzeit</b> angesammelt haben, wird es automatisch <b>vom Projekt ausgeschlossen</b>.</p>`
|
||||||
einzuhalten.
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Abstecken von Gebieten und Grundstücken',
|
title: 'Strike-Übersicht',
|
||||||
content: `
|
content: `<p>Regelverstöße führen zu Strikes für das gesamte Team, die folgendes zur Folge haben:<br>
|
||||||
Das Abstecken bestimmter Gebiete ist grundsätzlich erlaubt, jedoch sind unangemessen große Grundstücke
|
1. Strike - einmalige Koordinatenveröffentlichung<br>
|
||||||
untersagt. Das maximale Maß ist im Einzelfall zu entscheiden. Die Grenzen bereits abgesteckter Grundstücke
|
2. Strike – vollständiges Löschen der Inventare<br>
|
||||||
sind unveränderlich.
|
3. Strike – Disqualifikation des Teams</p>`
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Verhalten gegenüber anderen Spielern',
|
title: 'Mögliche Regelverstöße',
|
||||||
content: `
|
content: `<p>Das <b>Teamen</b> mit anderen Teams ist verboten. Falls ein Teampartner mit einem anderen Team
|
||||||
Das Töten, und Beklauen von Spielern ist verboten. Ebenso ist es nicht erlaubt, andere Bauten zu zerstören
|
kooperiert, erhalten beide Teams <b>jeweils 2 Strikes</b>.<br>
|
||||||
(Griefing). Ein gewisser Toleranzspielraum besteht, der im Einzelfall zu bewerten ist.
|
Das Nutzen eines <b>Clients</b>, ausgenommen Vanilla Minecraft ohne jegliche Modifikationen, ist verboten. Folglich wird
|
||||||
`
|
das Nutzen von Forge, Badlion, Luna, Optifine, Proxies usw. mit <b>3 Strikes</b> bestraft.<br>
|
||||||
|
Falls ein Team den Server <b>vor Ablauf der 30 Minuten</b> verlässt, ist die verbliebene Zeit verloren und ihr erhaltet
|
||||||
|
<b>einen Strike</b>.<br>
|
||||||
|
Erneuter Hinweis: Verlässt ein Teammitglied den Server, egal wie und warum, wird das andere Teammitglied ebenfalls vom
|
||||||
|
Server getrennt. Darauf folgt dann ein Strike für das Team, da nicht die vollen 30 Minuten am Stück gespielt wurden.
|
||||||
|
</p>`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Rolle der Administratoren',
|
title: 'Reports',
|
||||||
content: `
|
content: `<p>Neben der Kontrolle durch die Admins kann mit <code>/report</code> ein Report erstellt werden, um
|
||||||
Allgemein liegt es in der Hand der Administratoren einzelne Situation zu bewerten, Strafen zu verhängen und
|
Regelverstöße zu melden. Ohne feste <b>Belege</b>, also einer Bildschirmaufnahme, ist ein Report bei Ingameverstößen
|
||||||
Entscheidungen zu treffen. Den Entscheidungen und Anweisungen der Administratoren ist stets Folge zu
|
leider nutzlos.</p>`
|
||||||
leisten. Allgemein gilt immer der Grundsatz, dass ein Eingriff der Administratoren nur dann erfolgt, wenn
|
|
||||||
dies die Spieler auch fordern. Solange beide Parteien zufrieden sind und sich niemand beschwert, passiert
|
|
||||||
natürlich auch nichts.
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Kontakt zum Administratoren-Team',
|
title: 'Grundsätzliches',
|
||||||
content: `
|
content: `<p>Die Admins behalten sich vor für hier nicht aufgelistet Vergehen ebenfalls Strikes zu vergeben.
|
||||||
Jedem Teilnehmer ist es möglich sich an den Support/das Administratoren-Team zu wenden. Zu den
|
Generell gilt ingame aber: Alles ist erlaubt!<br>
|
||||||
Administratoren gehören die Spieler, die auf dem Server mit einem Admin-Tag versehen sind. Zwei von diesen
|
Trotzdem gilt wie bei allen Projekten, dass ein respektvoller Umgang und ein gutes Miteinander eine Grundvoraussetzung
|
||||||
sind außerdem Administrator der WhatsApp-Gruppe. Eine Kontaktaufnahme ist direkt auf dem Server im Chat
|
für das gelingen des Projekts ist.<br>
|
||||||
oder auf dem Teamspeak: „mhsl.eu“ möglich. Außerdem können sie über WhatsApp angeschrieben werden, wenn
|
Jegliche sexistischen, antisemitischen, pornografischen oder diskriminierenden Äußerungen und Handlungen sowie
|
||||||
sich z.B. gerade kein Administrator auf dem Server befindet oder bei anderen Rückfragen. Bei
|
unangemessene Skins oder Ingame-Namen sind verboten. Wer sich daran nicht hält, muss mit dem sofortigen und
|
||||||
Unzufriedenheit, Meldung eines Regelverstoßen, Anregungen oder Fragen steht das Administratoren-Team allen
|
langfristigem Projektausschluss rechnen.</p>`
|
||||||
Spielern jederzeit zu Verfügung.
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Konfliktlösung und mögliche Konsequenzen',
|
title: 'Ingame (Border, Deaktivierte Spielinhalte, usw.)',
|
||||||
content: `
|
content: `<p>Gespielt wird in der <b>aktuellsten Minecraft Java Version</b> mit dem Schwierigkeitsgrad „Normal“.
|
||||||
Konflikte sollen grundlegend zuerst auf einer Ebene zwischen den Spielern geschlichtet werden, bevor ein
|
<br>
|
||||||
Administrator kontaktiert wird. Jeder Regelverstoß zieht unterschiedliche Folgen nach sich, die von
|
Es gibt außerdem eine <b>Worldborder</b>, die sich mit der Zeit – außerhalb der Spielzeiten – langsam verkleinert. Die
|
||||||
Ermahnungen, über Tagesbänne bis zum permanenten Bann führen können. Diese möglichen Konsequenzen sind von
|
Spieler werden im Spiel über alles wichtige informiert, sobald sie sich der Border gefährlich nähern.<br>
|
||||||
allen Teilnehmern zu akzeptieren.
|
Das einzige <b>Netherportal</b> steht am Spawn. Weitere können nicht eröffnet werden. Für das Beste Spielerlebnis sind
|
||||||
`
|
folgende <b>Spielinhalte deaktiviert</b>:
|
||||||
}
|
<ol class="list-disc pl-8 py-3">
|
||||||
],
|
<li>alle Netherite Items</li>
|
||||||
footer: `
|
<li>alle Tränke der Stufe 2, ausgenommen Direktheilung 2</li>
|
||||||
Alle aufgeführten Regeln und die damit in Verbindung stehende Angaben erfolgen ohne Gewähr auf Vollständigkeit,
|
<li>Totems</li>
|
||||||
Richtigkeit und Aktualität. Das Durchsetzen der Regeln liegt im Ermessen der Administratoren, die vorher in
|
<li>Enderkristalle</li>
|
||||||
Absprache mit dem Geschädigten eine der Situation angemessene Maßnahmen getroffen haben.
|
<li>Mace</li>
|
||||||
`
|
<li>OP-Goldapfel</li>
|
||||||
};
|
<li>Villager Handel mit dem Bibliothekar und Panzermacher</li>
|
||||||
|
</ol></p>`
|
||||||
export const rulesLong = {
|
|
||||||
header: `
|
|
||||||
Das Lesen der Regeln ist für alle Teilnehmer verpflichtend. Die Regeln sollen für einen reibungslosen und
|
|
||||||
strukturierte Ablauf des Projekts sorgen, weshalb das Lesen der Regeln ein essenzieller Bestandteil für das Gelingen
|
|
||||||
von CraftAttack 7 ist. Die Regeln sind wörtlich zu verstehen und sind Grundlage für das Projekt. Zur Vereinfachung
|
|
||||||
gehen sie nicht zu weit ins Detail und deuten teils nur umfangreiche Themengebiete an. Entscheidungen werden, wenn
|
|
||||||
von Spielern angeregt, dann durch die Administratoren getroffen, die sich an den Regeln orientieren.
|
|
||||||
`,
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
title: 'Respektvoller Umgang',
|
|
||||||
content: `
|
|
||||||
Oberste Priorität hat der respektvolle und tolerante Umgang der Spieler untereinander. Der Spielspaß, der
|
|
||||||
offene Umgang miteinander und die Interaktion aller steht im Vordergrund, weshalb Drohungen, Belästigungen
|
|
||||||
oder sonstige gegenüber anderen Spielern respektlose Aktivitäten strengstens verboten sind und auch hart
|
|
||||||
geahndet werden.`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Einschränkungen von Minecraft-Namen, Skins, Chat-Nachrichten, Links, etc.',
|
|
||||||
content: `
|
|
||||||
Selbstverständlich sind sämtliche Inhalte (Minecraft-Namen, Skins, Chat-Nachrichten, Links, etc.) mit
|
|
||||||
sexistischen, diskriminierenden, rassistischen, pornographischen oder illegalen Inhalten nicht erlaubt.
|
|
||||||
Außerdem ist es nicht gestattet, den Chat mit Nachrichten jeglicher Art vollzuspammen. Des Weiteren sollte
|
|
||||||
der MC-Name des Spielers, der bei der Anmeldung angegeben wird, bis zum Ende des Projekts nicht geändert
|
|
||||||
werden. Das Nutzen bzw. Anmelden von Zweitaccounts ist nicht gestattet.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Clientmodifikationen',
|
|
||||||
content: `
|
|
||||||
Jegliche Clientmodifications, die deutliche Vorteile gegenüber anderen Spielern erbringen, sind nicht
|
|
||||||
gestattet. Alle Spieler, die kein Minecraft Vanilla spielen, sind verpflichtet ihre Clients oder
|
|
||||||
Modifications dahingehend zu überprüfen, ob durch diese entscheidende Vorteile erlangt werden können.
|
|
||||||
Solche Modifications sind zu entfernen. Das Nutzen von simplen Mini-Maps (Draufsicht) oder Cosmetics ist
|
|
||||||
selbstverständlich erlaubt. Es liegt im Allgemeinen im Interesse der Administratoren, dass Spieler es nicht
|
|
||||||
übertreiben und sich keine Vorteile schaffen, die gegenüber anderen ungerecht sind. Dabei setzen die
|
|
||||||
Administratoren auch auf eine Selbstreflexion jedes einzelnen. Im Zweifel sind Spieler dazu angehalten,
|
|
||||||
einen Administrator zu kontaktieren, der genauer Informationen übermitteln kann.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Redstone-Bauten und überdimensionierte Villager-Baukomplexe',
|
|
||||||
content: `
|
|
||||||
Das Erbauen und Betreiben lag-erzeugender Maschinen, Farmen (Zero-Tick-Farmen etc.) oder andere Bauten, die
|
|
||||||
den Spielfluss stören könnten, ist verboten. Im Zweifelsfall ist eine Anfrage bei den Administratoren
|
|
||||||
erwünscht. Bei beispielsweise Farmen oder allgemeinen Redstone Schaltung sollten diese auch nur dann
|
|
||||||
aktiviert werden, wenn nötig. Außerdem sollten überdimensional große Villager-Baukomplexe nur in Absprache
|
|
||||||
mit Administratoren errichtet und betreiben werden. Selbstverständlich ist das Erbauen von Farmen ein
|
|
||||||
essenzieller Bestandteil des Projekts und stellt auch kein Problem dar, solange die oben genannten
|
|
||||||
Bedingungen eingehalten werden.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Verkauf von Items',
|
|
||||||
content: `
|
|
||||||
Das Verkaufen von Items ist allgemein jedem Spieler überall gestattet. Jedoch bietet es sich an und ist
|
|
||||||
wünschenswert, die Shops aller Spieler in einem Shoppingdistrict gemeinsam anzusiedeln, um die Interaktion
|
|
||||||
zu fördern. Ein Shop muss sich innerhalb des ausgewiesenen Bereiches befinden und muss ebenso über das dort
|
|
||||||
bestehende Wegenetz erreichbar sein. Der Shoppingdistrict ist ausschließlich zum Bauen von Shops vorgesehen.
|
|
||||||
Mehrere Shops zu einem bestimmten Item sind möglich und auch erwünscht. Diebstahl im Shoppingdistrict
|
|
||||||
untersteht denselben Strafen wie allgemeiner Diebstahl. Ein angemessener Abstand der privaten Strukturen
|
|
||||||
vom Shoppingdisrict ist einzuhalten.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Abstecken von Gebieten und Grundstücken',
|
|
||||||
content: `
|
|
||||||
Das Abstecken bestimmter Gebiete ist grundsätzlich erlaubt, jedoch sind unangemessen große Grundstücke
|
|
||||||
untersagt. Das maximale Maß ist im Einzelfall zu entscheiden. Die Grenzen bereits abgesteckter Grundstücke
|
|
||||||
sind unveränderlich. Im Fall von Inaktivität oder andere Beschwerden beziehungsweise Verstöße ist ein
|
|
||||||
Administrator zu kontaktieren.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Verhalten gegenüber anderen Spielern',
|
|
||||||
content: `
|
|
||||||
Wie bereits angedeutet, ist das Ziel ein Umgang untereinander, der für keinen negative Aspekte beinhaltet.
|
|
||||||
So ist es beispielsweise nicht gestattet, andere zu bestehlen oder ohne Erlaubnis Bauwerke anderer zu
|
|
||||||
verändern. Dabei liegt natürlich eine gewisse Toleranzbereitschaft vor und ein Spielraum, der allerdings
|
|
||||||
nicht überschritten werden darf. Dies gilt sowohl für das Bestehlen anderer als auch für Griefing
|
|
||||||
(zerstören von Bauten anderer ohne Erlaubnis etc.). Außerdem ist das Töten anderer ohne nachvollziehbaren
|
|
||||||
Grund verboten. Natürlich ist auch hier eine Bewertung jeder einzelnen Situation notwendig, weshalb eine
|
|
||||||
Verallgemeinerung hier bewusst nicht angeführt wird. Fest steht jedoch, dass klar zwischen einem Töten
|
|
||||||
aus Spaß mit geringen Folgen und einem mehrmaligen - ja sogar permanenten Töten anderer mit schlimmeren
|
|
||||||
Folgen, unterschieden wird.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Rolle der Administratoren',
|
|
||||||
content: `
|
|
||||||
Allgemein liegt es in der Hand der Administratoren einzelne Situation zu bewerten, Strafen zu verhängen und
|
|
||||||
Entscheidungen zu treffen. Ein internes Strikesystem der Administratoren sorgt für eine Gleichberechtigung
|
|
||||||
aller Spieler. Des Weiteren erfolgt eine Absprache unter den Administratoren, um alle Sichtweisen
|
|
||||||
miteinzubringen. Wichtig ist zusätzlich, dass alle Entscheidungen der Administratoren im Sinne des Projekts
|
|
||||||
getroffen werden. Den Entscheidungen und Anweisungen der Administratoren ist stets Folge zu leisten, wenn
|
|
||||||
diese als Administrator fungieren. Im normalen Spielbetrieb sind sie normale Mitspieler ohne
|
|
||||||
spielentscheidende Sonderrechte. So ist es nicht ihre Aufgabe überall nach dem Rechten zu sehen, sondern
|
|
||||||
Ansprechpartner zu sein, um dann nach der Vorlegung eines Problems durch einen Geschädigten die
|
|
||||||
Administratorenrolle einzunehmen und dementsprechend zu handeln. Allgemein gilt immer der Grundsatz, dass
|
|
||||||
ein Eingriff der Administratoren nur dann erfolgt, wenn dies die Spieler auch fordern. Solange beide
|
|
||||||
Parteien zufrieden sind, passiert natürlich auch nichts. Wenn also beispielsweise zwei Spieler ein
|
|
||||||
bewusstes pvp-Duell starten, zieht das logischer Weise keine Konsequenzen nach sich.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Kontakt zum Administratoren-Team',
|
|
||||||
content: `
|
|
||||||
Jedem Teilnehmer ist es möglich sich an den Support/das Administratoren-Team zu wenden. Zu den
|
|
||||||
Administratoren gehören die Spieler, die auf dem Server mit einem Admin-Tag versehen sind. Zwei von diesen
|
|
||||||
sind außerdem Administrator der WhatsApp-Gruppe. Eine Kontaktaufnahme ist direkt auf dem Server im Chat
|
|
||||||
oder auf dem Teamspeak: „mhsl.eu“ möglich. Außerdem können sie über WhatsApp angeschrieben werden, wenn
|
|
||||||
sich z.B. gerade kein Administrator auf dem Server befindet oder bei anderen Rückfragen. Bei
|
|
||||||
Unzufriedenheit, Meldung eines Regelverstoßen, Anregungen oder Fragen steht das Administratoren-Team allen
|
|
||||||
Spielern jederzeit zu Verfügung.
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Konfliktlösung und mögliche Konsequenzen',
|
|
||||||
content: `
|
|
||||||
Konflikte sollen grundlegend zuerst auf einer Ebene zwischen den Spielern geschlichtet werden, bevor ein
|
|
||||||
Administrator kontaktiert wird. Jeder Regelverstoß zieht unterschiedliche Folgen nach sich, die von
|
|
||||||
Ermahnungen, über Tagesbänne bis zum permanenten Bann führen können. Diese möglichen Konsequenzen sind von
|
|
||||||
allen Teilnehmern zu akzeptieren.
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
footer: `
|
footer: `
|
||||||
|
Reference in New Issue
Block a user