Content Migration from websites repo

This commit is contained in:
Neshura 2022-12-03 21:02:24 +01:00
parent f6eb9794a9
commit f58a45df06
No known key found for this signature in database
GPG key ID: ACDF5B6EBECF6B0A
24 changed files with 7575 additions and 1 deletions

10
.eslintrc.json Normal file
View file

@ -0,0 +1,10 @@
{
"extends": "next/core-web-vitals",
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
}

18
.gitignore vendored Executable file
View file

@ -0,0 +1,18 @@
# do not track installed modules
/node_modules
# do not track built files
/.next
*.tsbuildinfo
next-env.d.ts
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# production
/build
/confs

50
Dockerfile Normal file
View file

@ -0,0 +1,50 @@
## INIT STEP
# Install dependencies only when needed
FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Copy the files needed to install deps
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
## BUILD STEP
# Rebuild the source code only when needed
FROM node:16-alpine AS builder
WORKDIR /app
# Copy node_modules installed by the deps step
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN yarn build
## RUN STEP
FROM node:16-alpine AS runner
LABEL author="neshura@proton.me"
WORKDIR /usr/src/ap
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
# expose port 3000
ENV PORT 3000
EXPOSE 3000
CMD [ "yarn", "start" ]

View file

@ -1 +0,0 @@
# minecraft

11
components/footer.tsx Normal file
View file

@ -0,0 +1,11 @@
import styles from '/styles/Home.module.css'
const Footer = () => {
return (
<footer className={styles.footer}>
Built using Next.js
</footer>
);
}
export default Footer;

31
components/layout.tsx Normal file
View file

@ -0,0 +1,31 @@
import Footer from './footer'
import Navbar from './navbar'
import styles from '/styles/Home.module.css'
import UseSWR from 'swr'
const fetcher = (url:string) => fetch(url).then((res) => res.json())
function Layout({ children }: {children: React.ReactNode} ):JSX.Element {
const { data, error } = UseSWR('/api/navbar', fetcher)
let layout: JSX.Element = <></>
if (error) layout = <><div>Failed to load data</div></>
if (!data) {
layout = <></>
}
if(data) {
layout =
<>
<Navbar links={data.links} />
<main className={styles.main}>
{children}
</main>
<Footer />
</>
}
return layout
}
export default Layout;

25
components/navbar.tsx Normal file
View file

@ -0,0 +1,25 @@
import styles from '../styles/Home.module.css'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { LinkList, CustomLink } from '../interfaces/LinkTypes';
function Navbar(props: LinkList) {
const router = useRouter();
const navLinks = props.links
return (
<div className={styles.header}>
<Link key="home" href="https://www.neshura-server.net">
<a className={styles.home}>Home</a>
</Link>
<nav className={styles.navbar}>
{navLinks.map((item: CustomLink) => (
<Link key={item.name} href={item.href}>
<a className={router.pathname == item.href ? styles.navelem_active : styles.navelem}>{item.name}</a>
</Link>
))}
</nav>
</div>
);
}
export default Navbar;

7
interfaces/LinkTypes.ts Normal file
View file

@ -0,0 +1,7 @@
export interface LinkList {
links: CustomLink[]
}
export interface CustomLink {
name: string,
href: string
}

32
interfaces/ServerType.ts Normal file
View file

@ -0,0 +1,32 @@
export interface ServerData {
server: ServerObject
}
export interface ServerObject {
mods: Mod[],
url: string,
port: number,
status: Status
}
export interface Mod {
name: string,
href: string,
version: string
}
export interface Status {
data: Details,
online: string
error: any
}
export interface Details {
players: Players,
}
export interface Players {
online: number,
max: number,
sample: string[]
}

8
next.config.js Executable file
View file

@ -0,0 +1,8 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: 'standalone',
};
module.exports = nextConfig;

5110
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

28
package.json Normal file
View file

@ -0,0 +1,28 @@
{
"name": "minecraft",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@types/next": "^9.0.0",
"dgram": "^1.0.1",
"fs": "^0.0.1-security",
"minecraft-server-util": "^5.2.10",
"next": "^12.2.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"swr": "^1.3.0"
},
"devDependencies": {
"@types/node": "^18.0.1",
"@types/react": "^18.0.14",
"eslint": "8.19.0",
"eslint-config-next": "12.2.0",
"typescript": "^4.7.4"
}
}

81
pages/1_18_2.tsx Normal file
View file

@ -0,0 +1,81 @@
import Head from 'next/head'
import styles from '/styles/Server.module.css'
import Link from 'next/link'
import { Mod, ServerData, Details } from '../interfaces/ServerType';
import * as mcutil from 'minecraft-server-util'
function Server_1_18_2(props: ServerData) {
const mods = props.server.mods
const address = props.server.url + ":" + String(props.server.port)
const info = props.server.status
return (
<>
<Head>
<title>1.18.2 Server</title>
<meta name="description" content="Minecraft Server running Version 1.18.2" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" media="screen" href="https://fontlibrary.org//face/minecraftia" type="text/css" />
</Head>
<h1 className={styles.title}>1.18.2 Server</h1>
<p className={styles.description}>{address}</p>
<div className={styles.card}>
<h2>Mod & Version info</h2>
{mods.map((item: Mod) => (
<Link key={item.name} href={item.href}>
<a className={styles.link}>{item.name} Version: {item.version}</a>
</Link>
))}
</div>
<div className={styles.card}>
<h2>Status: <a className={props.server.status.online == "Online" ? styles.online : styles.offline}>{props.server.status.online}</a></h2>
<>
{
() => {
if (info.error != null) {
return
}
else {
let data = info.data
return (
<>
<p>Players: {data.players.online}/{data.players.max}</p>
<p>Players currently online:
{data.players.sample !== null
? data.players.sample.map((player: any, index: any) => <span key={index}>{(index ? ', ' : ' ') + player.name}</span>)
: <span> -</span>}</p>
</>
)
}
}
}
</>
</div>
</>
)
}
export const getServerSideProps: any = async () => {
const res = await fetch('https://minecraft.neshura-server.net/api/servers')
const data = await res.json()
const options = {
timeout: 1000 * 5, //timeout in multiples of 1000ms
enableSRV: true
}
if (data) {
const sdata = await mcutil.status(data.v1182.url, data.v1182.port, options)
.then((result) => result)
.catch((error) => error)
if (sdata.players != null) {
const serverData = { "data": sdata, "online": "Online" }
const server = { "mods": data.v1182.mods, "status": serverData, "url": data.v1182.url, "port": data.v1182.port }
return { props: { server } }
}
else {
const serverData = { "error": JSON.stringify(sdata), "online": "Offline" }
const server = { "mods": data.v1182.mods, "status": serverData, "url": data.v1182.url, "port": data.v1182.port }
return { props: { server } }
}
}
}
export default Server_1_18_2;

14
pages/_app.tsx Executable file
View file

@ -0,0 +1,14 @@
import '/styles/globals.css'
import Layout from '../components/layout'
import { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp

15
pages/api/navbar.tsx Normal file
View file

@ -0,0 +1,15 @@
import fsPromises from 'fs/promises'
import path from 'path'
export default async function Navbar(req: any, res: any) {
try {
const filePath = path.join(process.cwd(), '/confs/navbar.json')
const jsonData = await fsPromises.readFile(filePath)
const data = JSON.parse(jsonData.toString())
res.status(200).json(data)
}
catch (error) {
console.log(error)
res.status(500).json({error: 'Error reading data'})
}
}

15
pages/api/servers.tsx Normal file
View file

@ -0,0 +1,15 @@
import fsPromises from 'fs/promises'
import path from 'path'
export default async function Servers(req: any, res: any) {
try {
const filePath = path.join(process.cwd(), '/confs/servers.json')
const jsonData = await fsPromises.readFile(filePath)
const data = JSON.parse(jsonData.toString())
res.status(200).json(data)
}
catch (error) {
console.log(error)
res.status(500).json({error: 'Error reading data'})
}
}

54
pages/index.tsx Executable file
View file

@ -0,0 +1,54 @@
import Head from 'next/head'
import styles from '/styles/Home.module.css'
export default function Home() {
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" media="screen" href="https://fontlibrary.org//face/minecraftia" type="text/css"/>
</Head>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
Get started by editing{' '}
<code className={styles.code}>pages/index.js</code>
</p>
<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation &rarr;</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn &rarr;</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<a
href="https://github.com/vercel/next.js/tree/canary/examples"
className={styles.card}
>
<h2>Examples &rarr;</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h2>Deploy &rarr;</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
</>
)
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

194
styles/Home.module.css Executable file
View file

@ -0,0 +1,194 @@
.container {
padding: 0 2rem;
}
.main {
background-color: black;
min-height: 100vh;
padding: 1rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}
.header {
background-color: darkgreen;
display: flex;
flex: 1;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
border-bottom: 1px solid var(--def-blue);
}
.home {
background: #727272;
color: rgb(247, 247, 247);
width: auto;
margin: 0.2rem;
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
border: 2px solid rgba(0, 0, 0, 1);
box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.5),
inset -2px -2px 0 rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.navbar {
width: 95%;
display: flex;
flex: 1;
padding: 2rem 0;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
.navelem {
background: #727272;
color: rgb(247, 247, 247);
width: auto;
margin: 0.2rem;
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
border: 2px solid rgba(0, 0, 0, 1);
box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.5),
inset -2px -2px 0 rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
flex-grow: 0.05;
}
.home:hover,
.navelem:hover {
background: rgba(115, 107, 221, 1);
}
.home:focus,
.navelem:focus {
color: rgb(246, 246, 44);
}
.navelem_active {
background: rgba(115, 107, 221, 1);
color: rgb(246, 246, 44);
width: auto;
margin: 0.2rem;
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
border: 2px solid rgba(0, 0, 0, 1);
box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.5),
inset -2px -2px 0 rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
flex-grow: 0.05;
}
.footer {
display: flex;
flex: 1;
padding: 2rem 0;
border-top: 1px solid #eaeaea;
justify-content: center;
align-items: center;
}
.footer a {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
.title a {
color: #0070f3;
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.title {
margin: 0;
line-height: 1.15;
font-size: 4rem;
}
.title,
.description {
text-align: center;
}
.description {
margin: 4rem 0;
line-height: 1.5;
font-size: 1.5rem;
}
.code {
background: #fafafa;
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 800px;
}
.card {
background: #727272;
color: rgb(247, 247, 247);
width: 80%;
margin: 0.2rem;
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
border: 2px solid rgba(0, 0, 0, 1);
box-shadow: inset 3px 3px 0 rgba(255, 255, 255, 0.5),
inset -3px -3px 0 rgba(0, 0, 0, 0.5);
padding: 1.5rem;
text-align: left;
transition: color 0.15s ease, border-color 0.15s ease;
}
.card:hover,
.card:focus,
.card:active {
background: rgba(115, 107, 221, 1);
}
.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
.logo {
height: 1em;
margin-left: 0.5rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}

101
styles/Server.module.css Normal file
View file

@ -0,0 +1,101 @@
@charset "UTF-8";
.container {
padding: 0 2rem;
}
.header {
display: flex;
flex: 1;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
border-bottom: 1px solid var(--def-blue);
}
.title a {
color: #0070f3;
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.title {
margin: 0;
line-height: 1.15;
font-size: 4rem;
}
.title,
.description {
text-align: center;
}
.online {
color: #00fe1f;
}
.offline {
color: #D51210;
}
.description {
background: #727272;
color: rgb(247, 247, 247);
width: 40%;
margin: 0.2rem;
margin-top: 4rem;
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
border: 2px solid rgba(0, 0, 0, 1);
box-shadow: inset 3px 3px 0 rgba(255, 255, 255, 0.5),
inset -3px -3px 0 rgba(0, 0, 0, 0.5);
line-height: 1.5;
font-size: 1.5rem;
padding: 0.5rem;
padding-left: 1.5rem;
text-align: left;
}
.link {
font-weight: normal;
font-style: normal;
}
.link:hover {
color: rgb(246, 246, 44);
}
.card {
background: #727272;
color: rgb(247, 247, 247);
width: 40%;
margin: 0.2rem;
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
border: 2px solid rgba(0, 0, 0, 1);
box-shadow: inset 3px 3px 0 rgba(255, 255, 255, 0.5),
inset -3px -3px 0 rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
align-items: left;
justify-content: left;
padding: 1.5rem;
text-align: left;
transition: color 0.15s ease, border-color 0.15s ease;
}
.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}

27
styles/globals.css Executable file
View file

@ -0,0 +1,27 @@
html,
body {
padding: 0;
margin: 0;
font-family: "MinecraftiaRegular", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
:root {
--black-0f: #0f0f0f;
--black-1e: #1e1e1e;
--black-2d: #2d2d2d;
--def-blue: #00aaff;
--def-orange: #ff5300;
--def-red: #ff0000;
--def-green: #00ff00;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}

26
tsconfig.json Normal file
View file

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable","esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}

1718
yarn.lock Normal file

File diff suppressed because it is too large Load diff