Skip to content

Commit 713cd36

Browse files
committed
Implement utils module and WIP readme
1 parent 7299ae6 commit 713cd36

File tree

5 files changed

+210
-274
lines changed

5 files changed

+210
-274
lines changed

README.md

+23-257
Original file line numberDiff line numberDiff line change
@@ -3,260 +3,26 @@ scriptserver
33

44
[![](http://i.imgur.com/zhptNme.png)](https://github.com/garrettjoecox/scriptserver)
55

6-
[![Gitter chat](https://img.shields.io/gitter/room/ScriptServer/Lobby.svg)](https://gitter.im/ScriptServer/Lobby) ![Total Downloads](https://img.shields.io/npm/dt/scriptserver.svg)
7-
8-
## What's ScriptServer?
9-
A configurable Minecraft server wrapper written in Node.js.
10-
Using a combination of RCON and the output of the server console it allows you to do some pretty cool things.
11-
Though, this is the engine of ScriptServer, and is honestly pretty bare.
12-
The modules are where the magic happens (check 'Published Modules' down below).
13-
14-
The ScriptServer engine does 3 things:
15-
- Starts the Minecraft server as a child process, using the specified jar & arguments
16-
- Provides an interface to send commands, use their results, and make use of other things that are displayed in the server console.
17-
- Initializes a simple module loader for ScriptServer modules.
18-
19-
## What version of Minecraft does it work with?
20-
21-
Because it relies on the RCON interface and the format of the output log, it should work with pretty much any version of Minecraft dating back to 2012. It should continue to work for all future releases and snapshots as long as the logging format doesn't drastically change, and they don't drop RCON support. (Both unlikely)
22-
23-
## Getting Started
24-
25-
#### Prerequisites
26-
- [NodeJS](https://nodejs.org/en/) (^8.0.0 recommended)
27-
- Somewhat of a familiarity with NodeJS is recommended.
28-
29-
#### Setup
30-
While inside the root of your Minecraft server directory, run `npm install scriptserver`. Then create a javascript file to run the server, I usually go with `server.js`. Paste in the following:
31-
32-
```javascript
33-
const ScriptServer = require('scriptserver');
34-
35-
const server = new ScriptServer({
36-
core: {
37-
jar: 'minecraft_server.jar',
38-
args: ['-Xmx2G'],
39-
rcon: {
40-
port: '25575',
41-
password: 'password'
42-
}
43-
}
44-
});
45-
46-
server.start();
47-
```
48-
49-
When initializing your ScriptServer instance all it takes is an optional config object, which is automatically set to `server.config`, and accessible by third party modules. Read each module's README to check for configuration options.
50-
51-
The options in the `core` config are used by the ScriptServer engine to determine the startup jar, arguments, and RCON configuration.
52-
53-
**RCON IS NOT ENABLED BY DEFAULT**, you will need to add the following to your `server.properties` to enable it:
54-
```
55-
enable-rcon=true
56-
rcon.port=25575
57-
rcon.password=password
58-
```
59-
60-
You start your server with `server.start()`
61-
62-
Finally, you can run the server with node using
63-
```bash
64-
node server.js
65-
```
66-
67-
And that's it!
68-
69-
Seriously. Like I said the engine is pretty bare, especially to users, but in the section 'Creating Modules' I'll explain how developers can utilize the simplicity of this engine.
70-
71-
For people looking to quickly try this out, I recommend giving [scriptserver-essentials](https://github.com/garrettjoecox/scriptserver-essentials) a try, it provides basic commands like `tpa`, `home`, and `spawn`, as well as a starter kit.
72-
73-
## Using Modules
74-
75-
To put 3rd party modules to use, you must first of course `npm install` them, then in your `server.js` initialize them one at a time with `server.use()`
76-
77-
```javascript
78-
const ScriptServer = require('scriptserver');
79-
80-
// Configuration
81-
82-
const server = new ScriptServer({
83-
core: {
84-
jar: 'minecraft_server.jar',
85-
args: ['-Xmx2G']
86-
},
87-
command: {
88-
prefix: '~'
89-
},
90-
essentials: {
91-
starterKit: {
92-
enabled: false
93-
}
94-
}
95-
});
96-
97-
// Loading modules
98-
99-
server.use(require('scriptserver-command'))
100-
// or
101-
const ssEssentials = require('scriptserver-essentials');
102-
server.use(ssEssentials);
103-
104-
// Start server
105-
106-
server.start();
107-
```
108-
109-
As for the functionality of the actual module please refer to it's own `README.md` for use.
110-
111-
## Creating Modules
112-
113-
As a developer you have a few tools to work with. Below I will explain and use them in examples.
114-
115-
### 1) server.on(event, callback)
116-
117-
The server's console output is our main way of getting data from the server to our javascript wrapper.
118-
Every time a log is output the engine emits the `console` event. This sounds useless as first but combining that with RegExp you'd be surprised at how much you can do.
119-
120-
Because ScriptServer extends the EventsEmitter, 3rd party module creators can utilize the emitter themselves. For instance the `scriptserver-event` module emits the events `chat`, `login`, `logout`, etc. right along side the main `console` event.
121-
122-
#### Simple ~head command example
123-
```javascript
124-
server.on('console', line => {
125-
// Regex matches when a user types ~head in chat
126-
const result = line.match(/]: <([\w]+)> ~head (.*)/);
127-
if (result) {
128-
// Player that sent command
129-
console.log(result[1])
130-
// head user is requesting
131-
console.log(result[2]);
132-
// Give the user the player head!
133-
server.send(`give ${result[1]} minecraft:skull 1 3 {SkullOwner:"${result[2]}"}`)
134-
}
135-
});
136-
```
137-
138-
### 2) server.send(command)
139-
140-
The send method allows you to send commands to the Minecraft server.
141-
See [here](http://minecraft.gamepedia.com/Commands) for a list of available commands. When mixed with ES2015's template strings and Promises, server.send can be a powerful tool.
142-
143-
#### Using server.send
144-
```javascript
145-
const player = 'ProxySaw';
146-
// Just like commands you'd type in the server console.
147-
server.send(`give ${player} minecraft:diamond 1`);
148-
server.send(`playsound entity.item.pickup master ${player} ~ ~ ~ 10 1 1`);
149-
server.send(`say ${player} got a diamond!`);
150-
```
151-
152-
`server.send` also allows you to use the result of the command through it's returned promise. Similar to the console output, when combined with RegExp this can be extremely useful.
153-
154-
#### Using server.send promises to get player location
155-
156-
Sending the following command to the server console:
157-
```
158-
execute ProxySaw ~ ~ ~ /testforblock ~ ~ ~ minecraft:air 10
159-
```
160-
Will result in the following line being output:
161-
```
162-
[10:32:37] [Server thread/INFO]: The block at 20,74,-161 had the data value of 0 (expected: 10).
163-
```
164-
165-
Using the RegExp: `/at\s([-\d]+),([-\d]+),([-\d]+)/` I can pull the coordinates out of that log and use them within my javascript function.
166-
167-
```javascript
168-
var player = 'ProxySaw';
169-
170-
server.send(`execute ${player} ~ ~ ~ /testforblock ~ ~ ~ minecraft:air 10`)
171-
.then(result => {
172-
const coords = result.match(/at\s([-\d]+),([-\d]+),([-\d]+)/);
173-
console.log('X:', coords[0]);
174-
console.log('Y:', coords[1]);
175-
console.log('Z:', coords[2]);
176-
});
177-
```
178-
179-
### 3) server.sendConsole(command)
180-
181-
sendConsole is a helper method for special use-cases that want/need to bypass the RCON interface, and instead write directly to the server console. The drawback of this, is that there is no direct response to anything sent directly to the console. About 99% of the time you'll likely want to use `server.send` instead.
182-
183-
### Module Structure
184-
So now that you know how to utilize those tools, it's time to build a module. Whenever a user `.use`'s your module, it simply invokes it with the context of their server, therefor encapsulate all server-side logic in a module.exports function.
185-
186-
The following was taken from the [scriptserver-command module](https://github.com/garrettjoecox/scriptserver-command). It allows for custom commands to be created using server.command() Read inline comments for breakdown.
187-
```javascript
188-
// The function that is called on server.use(require('scriptserver-command'))
189-
module.exports = function() {
190-
// Invoked with the context of the user's server
191-
const server = this;
192-
// Local storage for commands
193-
const commands = {};
194-
195-
// Uses another scriptserver module
196-
server.use(require('scriptserver-event'));
197-
198-
// Interface for users to add commands
199-
server.command = function(cmd, callback) {
200-
commands[cmd] = commands[cmd] || [];
201-
commands[cmd].push(callback);
202-
}
203-
204-
// Hooks into chat event to watch for the ~ char, then emits the command event
205-
server.on('chat', event => {
206-
const stripped = event.message.match(/~([\w]+)\s?(.*)/);
207-
if (stripped && commands.hasOwnProperty(stripped[1])) {
208-
server.emit('command', {
209-
player: event.player,
210-
command: stripped[1],
211-
args: stripped[2].split(' '),
212-
timestamp: Date.now()
213-
});
214-
}
215-
});
216-
217-
// Invokes any listeners on the command the player triggered
218-
server.on('command', event => {
219-
if (commands.hasOwnProperty(event.command)) {
220-
commands[event.command].forEach(callback => callback(event));
221-
}
222-
});
223-
}
224-
```
225-
226-
Now for using the scriptserver-command module,
227-
```javascript
228-
const ScriptServer = require('scriptserver');
229-
const server = new ScriptServer({
230-
core: {
231-
jar: 'minecraft_server.jar',
232-
args: ['-Xmx2G']
233-
},
234-
});
235-
236-
server.use(require('scriptserver-command'));
237-
238-
server.command('head', event => {
239-
var skull = event.args[0] || event.player
240-
server.send(`give ${event.player} minecraft:skull 1 3 {SkullOwner:"${skull}"}`);
241-
});
242-
243-
server.start();
244-
```
245-
246-
And muahlah! In game sending the command `~head` will give yourself your player head or passing in a name `~head Notch` will give you their player head!
247-
248-
If you run into any issues or questions, read through other published modules(below) or submit an issue and I'll try to help you out!
249-
250-
## Published Modules
251-
- [scriptserver-essentials](https://github.com/garrettjoecox/scriptserver-essentials)
252-
Some essential server commands like home, tpa, and head.
253-
- [scriptserver-command](https://github.com/garrettjoecox/scriptserver-command)
254-
Provides interface for adding custom server commands.
255-
- [scriptserver-event](https://github.com/garrettjoecox/scriptserver-event)
256-
Interface for hooking onto events like chat, login, and logout.
257-
- [scriptserver-util](https://github.com/garrettjoecox/scriptserver-util)
258-
Multiple helper commands for module developers.
259-
- [scriptserver-json](https://github.com/garrettjoecox/scriptserver-json)
260-
Provides ability to read/write from JSON files.
261-
- [scriptserver-update](https://github.com/garrettjoecox/scriptserver-update)
262-
Lets you restart the server in game, and auto update to snapshot/release channels.
6+
## What's this?
7+
Sciptserver is a minecraft server wrapper, allowing you to write simple plugins using the RCON connection and STDIN/OUT from the java console. This is currently a WIP port to deno, milage may vary.
8+
9+
## Todo:
10+
- [x] Basic functionality
11+
- [x] Split up java server from rcon connection
12+
- [x] Plugin interface pattern
13+
- [x] Events module
14+
- [x] Command module
15+
- [ ] Utils module
16+
- [ ] isOp
17+
- [ ] isOp
18+
- [ ] getOnline
19+
- [x] tellRaw
20+
- [x] getEntityData
21+
- [x] getDimension
22+
- [x] getLocation
23+
- [x] teleport
24+
- [ ] JSON module
25+
- [ ] Essentials module
26+
- [ ] More user friendly config (deep defaults)
27+
- [ ] README documentation
28+
- [ ] Paper/Spigot flavors

command.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ export interface CommandConfig {
1818
commands: {
1919
[cmd: string]: CommandCallback[];
2020
};
21-
commandFunc?: (cmd: string, callback: CommandCallback) => void;
2221
}
2322

2423
declare module "./config.ts" {
@@ -31,6 +30,10 @@ declare module "./java_server.ts" {
3130
export interface JavaServerEvents {
3231
command: CommandCallback;
3332
}
33+
34+
export interface JavaServer {
35+
command: (cmd: string, callback: CommandCallback) => void;
36+
}
3437
}
3538

3639
const DEFAULT_CONFIG: CommandConfig = {
@@ -41,7 +44,7 @@ const DEFAULT_CONFIG: CommandConfig = {
4144

4245
export function useCommand(javaServer: JavaServer) {
4346
if (javaServer.config?.command?.initialized) {
44-
return javaServer.config.command.commandFunc!;
47+
return;
4548
}
4649

4750
useEvents(javaServer);
@@ -78,15 +81,10 @@ export function useCommand(javaServer: JavaServer) {
7881
}
7982
});
8083

81-
javaServer.config.command.commandFunc = (
82-
cmd: string,
83-
callback: CommandCallback
84-
) => {
84+
javaServer.command = (cmd: string, callback: CommandCallback) => {
8585
cmd = cmd.toLowerCase();
8686
javaServer.config.command.commands[cmd] =
8787
javaServer.config.command.commands[cmd] || [];
8888
javaServer.config.command.commands[cmd].push(callback);
8989
};
90-
91-
return javaServer.config.command.commandFunc;
9290
}

java_server.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { EventEmitter } from "https://deno.land/[email protected]/node/events.ts";
22
import { iter } from "https://deno.land/[email protected]/io/util.ts";
33
import { Config } from "./config.ts";
4+
import { Buffer } from "https://deno.land/[email protected]/node/buffer.ts";
45

56
export interface JavaServerConfig {
67
jar: string;
@@ -71,6 +72,12 @@ export class JavaServer extends EventEmitter {
7172
this.stderrIter();
7273
}
7374

75+
public send(message: string) {
76+
if (!this.process || !this.process.stdin) return;
77+
78+
this.process.stdin.write(Buffer.from(message + "\n"));
79+
}
80+
7481
private async stdoutIter() {
7582
try {
7683
if (this.process?.stdout && this.config.javaServer.pipeStdout) {

0 commit comments

Comments
 (0)