Skip to content

Commit 9225327

Browse files
committed
Initial commit
0 parents  commit 9225327

17 files changed

+3400
-0
lines changed

.babelrc

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"ignore": ["node_modules/**/*"],
3+
"presets": [
4+
["@babel/preset-typescript"],
5+
["@babel/preset-env",
6+
{
7+
"targets": {
8+
"esmodules": true
9+
}
10+
}]
11+
],
12+
"plugins": [
13+
"@babel/plugin-proposal-class-properties",
14+
"babel-plugin-add-module-exports",
15+
"@babel/plugin-transform-classes"
16+
]
17+
}

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
.env
4+
server

.prettierrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"trailingComma": "es5",
3+
"tabWidth": 2,
4+
"semi": false,
5+
"singleQuote": true,
6+
"printWidth": 120,
7+
"proseWrap": "always"
8+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021-present, Kyle Mercer
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

deps/.gitkeep

Whitespace-only changes.

deps/java-express-0.0.10.jar

82.9 KB
Binary file not shown.

docs/assets/hotreload.gif

2.9 MB
Loading

docs/assets/lodash.gif

10.5 MB
Loading

package.json

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"author": "Kyle Mercer",
3+
"name": "grakkit-boilerplate",
4+
"description": "Boilerplate impl. using Babel, Webpack, and TypeScript",
5+
"license": "MIT",
6+
"version": "1.0.1",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/MercerK/grakkit-boilerplate"
10+
},
11+
"keywords": [
12+
"grakkit",
13+
"minecraft"
14+
],
15+
"dependencies": {
16+
"@grakkit/stdlib-paper": "^1.0.12",
17+
"grakkit-boilerplate-util": "^0.0.18",
18+
"grakkit-sound-browser": "^0.0.5",
19+
"lodash": "^4.17.21"
20+
},
21+
"devDependencies": {
22+
"@babel/cli": "^7.14.3",
23+
"@babel/core": "^7.14.3",
24+
"@babel/plugin-proposal-class-properties": "^7.13.0",
25+
"@babel/preset-env": "^7.14.2",
26+
"@babel/preset-typescript": "^7.13.0",
27+
"@types/lodash": "^4.14.178",
28+
"@types/node": "^16.4.6",
29+
"babel-loader": "^8.2.2",
30+
"babel-plugin-add-module-exports": "^1.0.4",
31+
"babel-plugin-transform-class-properties": "^6.24.1",
32+
"concurrently": "^7.0.0",
33+
"got": "^11.8.2",
34+
"ts-node": "^10.0.0",
35+
"typescript": "^4.5.5",
36+
"webpack": "^5.37.0",
37+
"webpack-cli": "^4.7.0"
38+
},
39+
"peerDependencies": {
40+
"@grakkit/server": "^1.4.2"
41+
},
42+
"scripts": {
43+
"start:server": "cd server & java -Xms2G -Xmx2G -jar server.jar -nogui",
44+
"start:js": "ts-node --project tsconfig-node.json ./scripts/start",
45+
"start": "concurrently \"npm run start:server\" \"npm run start:js\"",
46+
"build": "webpack --env production"
47+
}
48+
}

readme.md

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Grakkit Boilerplate
2+
3+
> Useful boilerplate for creating stuff with [Grakkit](https://github.com/grakkit/grakkit)
4+
5+
Grakkit is a Minecraft Server Plugin utilizing the GraalVM JavaScript Engine. This repository is a boilerplate
6+
implementation to quickly spawn up a workspace to get started using Babel, Webpack, and TypeScript.
7+
8+
This boilerplate features a "Hot Reload" method, which speeds up development significantly. Whenever you make changes to
9+
your code during Runtime and hit save, it'll rebuild the solution then reload it on the server. This takes less than a
10+
second.
11+
12+
![Hot Reload](./docs/assets/hotreload.gif)
13+
14+
# Getting Started
15+
16+
1. Click the "Use this template" in the top right.
17+
2. Once you have cloned the repo and have it locally, you'll need to do the following:
18+
19+
- Download your preferred Minecraft Server Plugin implementation
20+
- Grakkit only supports [Paper](https://papermc.io/downloads) or Minestom.
21+
- Place the server plugin jar file in the `./server` folder and rename it to `server.jar`.
22+
- Download the [Grakkit jar](https://github.com/grakkit/grakkit/releases) and place it in the `./server/plugins` folder.
23+
- Run `npm install` or `yarn`.
24+
- Open a terminal and run `npm run start:js` or `yarn start:js`. This will start the webpack.
25+
- Open another terminal and run `npm run start:server` or `yarn start:server`
26+
- When running it for the first time, you'll need to accept the `EULA` in `./server/eula.txt`.
27+
- After updating the `EULA`, you may need to restart the server.
28+
29+
3. Once everything is up and running, you can now start developing in `./src/index.ts`.
30+
31+
# What can you do with this?
32+
33+
- Through Grakkit, you have access to both Java and Paper classes, objects, and types.
34+
- You can access the API of other server plugins, such as LibsDisguises, PlaceholderAPI, and so many more.
35+
- You can import existing JavaScript libraries and use them within your plugin, such as Lodash, Redux, Yaml, Immer, and
36+
so many more.
37+
- Note: NodeJS does not work within GraalVM, so you cannot use libraries expecting NodeJS API.
38+
- Note: Fetch/Websockets/Multithreading can be a challenge.
39+
40+
![Lodash](./docs/assets/lodash.gif)
41+
42+
# How It Works
43+
44+
## Development Mode `npm run start:js`/`yarn start:js`
45+
46+
1. This spawns a webserver within the Minecraft server.
47+
2. When in development mode, it enables a new API route called `/reload`.
48+
3. The solution is built using webpack (which is _fast_) and it will put the compiled files in `server/plugins/grakkit`.
49+
4. Using a custom start up script in `scripts/start/index.ts`, it will build the solution, enable development mode, and
50+
ping the `/reload` endpoint.
51+
- Once the endpoint is hit, well, the server reloads grakkit.
52+
53+
## Production Mode `npm run build`/`yarn build`
54+
55+
1. Using webpack, it'll build the files to `/dist`. Any code relying on `development` will be disabled.
56+
2. This can be a useful step for deployments.
57+
58+
# Startup
59+
60+
1. Run `npm run start:js` or `yarn start:js`
61+
2. Run `npm run start:server` or `yarn start:server`
62+
63+
OR
64+
65+
1. Run `npm run start` or `yarn start`
66+
67+
# Info
68+
69+
## Deps Folder
70+
71+
When developing plugins, you may need to hook into additional dependencies. You can add those jars to the `./deps`
72+
folder. If you need further customization, you can update `scripts/start/index.ts`.

scripts/start/index.ts

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import webpack from 'webpack'
2+
import path from 'path'
3+
import fs from 'fs'
4+
import { clearWebpackConsole, displayWebpackMessages } from 'grakkit-boilerplate-util/dist/scripts'
5+
import got from 'got'
6+
7+
function initializePaths() {
8+
const root = path.join(__dirname, '..', '..')
9+
10+
return {
11+
root,
12+
deps: path.join(root, 'deps'),
13+
grakkit: path.join(root, 'server', 'plugins', 'grakkit'),
14+
config: path.join(root, 'webpack.config.js'),
15+
}
16+
}
17+
18+
const paths = initializePaths()
19+
const createConfig = require(paths.config)
20+
21+
function copyDependencies() {
22+
const files = fs.readdirSync(paths.deps).filter((f) => f.includes('.jar') || f === 'config.yml')
23+
24+
files.forEach((file) => fs.copyFileSync(path.join(paths.deps, file), path.join(paths.grakkit, file)))
25+
}
26+
27+
async function main() {
28+
const config = createConfig({ dev: true })
29+
30+
copyDependencies()
31+
32+
let compiler: webpack.Compiler
33+
try {
34+
compiler = webpack(config)
35+
} catch (err) {
36+
console.log(err)
37+
38+
process.exit(1)
39+
}
40+
41+
clearWebpackConsole()
42+
43+
compiler.hooks.invalid.tap('invalid', () => {
44+
clearWebpackConsole()
45+
46+
console.log('Compiling...')
47+
})
48+
49+
compiler.hooks.done.tap('done', async (stats) => {
50+
clearWebpackConsole()
51+
displayWebpackMessages(stats)
52+
53+
handleReload()
54+
})
55+
56+
return compiler.watch({}, (stats) => {
57+
console.log(stats)
58+
})
59+
}
60+
61+
async function handleReload() {
62+
try {
63+
const req = await got.get('http://localhost:4000/reload', { timeout: 1000 })
64+
console.log('Reload successful')
65+
66+
return
67+
} catch (err) {
68+
console.log('Failed to connect...')
69+
return setTimeout(handleReload, 1000)
70+
}
71+
}
72+
73+
main()

src/demo.ts

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { obePlayer } from '@grakkit/types-paper'
2+
import { event, server, command } from '@grakkit/stdlib-paper'
3+
// You can use the existing npm modules within Minecraft
4+
import debounce from 'lodash/debounce'
5+
// You can import other grakkit plugins into your own as well!
6+
import { SoundBrowser } from 'grakkit-sound-browser'
7+
8+
function initializePlayerJoin() {
9+
event('org.bukkit.event.player.PlayerJoinEvent', (event) => {
10+
const player = event.getPlayer()
11+
12+
sendPlayerMessage(player, 'Hello! Welcome to Grakkit Boilerplate!')
13+
14+
setTimeout(() => {
15+
sendPlayerMessage(player, 'Enjoy your stay!')
16+
sendPlayerMessage(player, 'You can check out the soundBrowser by running `/soundbrowser` in chat.')
17+
}, 5000)
18+
19+
player.getWorld().setTime(600)
20+
})
21+
}
22+
23+
function initializePlayerQuit() {
24+
event('org.bukkit.event.player.PlayerQuitEvent', (event) => {
25+
server.broadcastMessage(`${event.getPlayer().getName()} has left! Please come back soon.`)
26+
})
27+
}
28+
29+
function initializeChunkLoad() {
30+
let count = 0
31+
const debouncedFn = debounce(() => {
32+
server.broadcastMessage(`${count} Chunks have been loaded.`)
33+
count = 0
34+
}, 1000)
35+
36+
event('org.bukkit.event.world.ChunkLoadEvent', (event) => {
37+
count++
38+
debouncedFn()
39+
})
40+
}
41+
42+
export function initializeDemo() {
43+
// Initializes events
44+
initializePlayerJoin()
45+
initializePlayerQuit()
46+
initializeChunkLoad()
47+
48+
// Initializes Command
49+
command({
50+
name: 'help-grakkit',
51+
execute: (sender) => {
52+
sender.sendMessage('For more information on Grakkit, checkout https://github.com/grakkit/grakkit')
53+
},
54+
})
55+
56+
SoundBrowser.initialize()
57+
}
58+
59+
function sendPlayerMessage(player: obePlayer, msg: string) {
60+
// Some typings are not a 100% match, but will allow you to work regardless.
61+
// In this instance, it expects "nmbacBaseComponent", but it will allow a string.
62+
player.sendMessage(msg as any)
63+
}

src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { initializeAutoReload } from 'grakkit-boilerplate-util'
2+
import { initializeDemo } from './demo'
3+
4+
initializeDemo()
5+
initializeAutoReload()

tsconfig-node.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2019",
4+
"lib": ["DOM","es2019"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"esModuleInterop": true,
8+
"allowSyntheticDefaultImports": true,
9+
"strict": true,
10+
"forceConsistentCasingInFileNames": true,
11+
"module": "commonjs",
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"noEmit": true,
16+
"noImplicitAny": false,
17+
"outDir": "temp"
18+
},
19+
"exclude": [
20+
"node_modules"
21+
]
22+
}

tsconfig.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"declaration": true,
5+
"esModuleInterop": true,
6+
"forceConsistentCasingInFileNames": true,
7+
"incremental": true,
8+
"lib": [ "ES2015", "ES2016", "ES2017", "ES2018", "ES2019", "ES2020" ],
9+
"module": "CommonJS",
10+
"moduleResolution": "Node",
11+
"resolveJsonModule": true,
12+
"rootDir": "./",
13+
"skipLibCheck": true,
14+
"target": "es2020",
15+
"watch": true,
16+
},
17+
"include": [
18+
"src/**/*"
19+
],
20+
"exclude": [
21+
"node_modules"
22+
]
23+
}

0 commit comments

Comments
 (0)