# This package is used for making a server on [thingmaker's version of MineKhan](https://thingmaker.us.eu.org)

# First things
First, install the package. Type this in your shell.
```
npm install minekhan-server
```
Then, add something like this to you code:
```js
const express = require('express');
const app = express();
const router = express.Router();
const cors = require('cors');
app.use(cors({
  origin: function(origin, callback){
    return callback(null, true);
  },
  credentials: true
}))
let serverPort = app.listen(3000, function(){
  console.log("App server is running on port 3000");
});
```
Now, choose the name and description of you server. Add this to your code and customize it:
```js
const mkServer = MineKhanServer("name", "description", {
	server: serverPort, //What server to use?
	url: "https://server", //The URL of the server
	wsurl:"wss://server", //Websocket URL of the server
  thumbnail: "image URL", //(Optional) The thumbnail of the server
  saveActivity:true, //(Optional) Should it add any activity to the log?
  operators: ["username"], //(Optional) Who can edit blocks and use commands other people can't
	loadDistance: 4 //(Optional) How many chunks to load around players? Default is 4.
})
```
If you want to know what the server property is for, click [here](#why-does-it-need-server).

# Creating a room
If you want your server to have a world loaded when someone joins, you should create a room.
Room means a world.  
This is how you create a room. You can customize it.
```js
var room = mkServer.createRoom("room name", {
  code: "your save code",
  spawn: [x,y,z], //(Optional) Where will the players spawn when they go to this room?
  canEdit:false, //(Optional) Can the players change anything in the room?
  autosave:false, //(Optional) Should changes in this room be saved?
  cheats:false, //(Optional) Is cheats enabled for this room? Cheats is always enabled for creative mode.
  savePlayersInv:false, //(Optional) Should player data be saved when there are players in this room (this also saves position)?
	resourcePacks:[], //(Optional) What resource packs should be used in this room? Items should be urls to resource packs.
  settings:{ //This and everything inside are optional.
    tntExplode:true,
    killCmdOff:false,
    dayNightCycle: false,
    blocksFall: true,
    attack: true,
    fireSpreads: true,
		weatherCycle: false,
		mobSpawning: false
  }
})
```
If you want the players to go to another room when in a specific place, for example: when players go in a portal, add this to your code and customize it:
```js
room.addPortal("room name", coordinates)
```
If you want a function to be done when a player goes to a specific place, add this to your code and customize it:
```js
room.addPortal(function(player){
  //do something
}, coordinates)
```
Coordinates should be like this: x,y,z,x,y,z
You could also add text to the room. To add text, add this to your code and customize it.
```js
room.addText(x,y,z,"text",color,background,size)
```
Color should be an array with three numbers from 0 to 1.  
Background should be an array with four numbers from 0 to 1.

To make a place not editable, add this to your code and customize it.
```js
room.addUneditable(coordinates)
```
Coordinates should be like this: x,y,z,x,y,z

# What to do when players join
When players join this server, nothing happens, so you should send them to a room when they join.
This code will do that:
```js
mkServer.on("join", function({player}){
  player.goToRoom("room name")
})
```
Replace room name with the name of the room you want the player to go to when they join.

# Adding server commands
Server commands are commands run on the server. These commands can only be used on your server.
To add a server command, add this to your code and change some things.
```js
mkServer.addServerCmd({
	name: "command_name",
	args: ["argument1","argument2" /*...*/],//(Optional) The argument names of the command
	lastArgRaw:true,//(Optional) Is the last argument raw?
	argValues:{argument1:["a-possible-value-for-argument1"] /*...*/}, //What types are for each argument?
	info: "a description",//(Optional)
	func: (args,pos,player) => {
		doSomething()
	},
	in:"all"//(Optional, defaults to all) where is this command used? Array of room names or "all"
},
{
	//Another command
	//...
} /*...*/ )
```
split is an array of the argument values.
pos is the position of the player.

# Custom terrain generation
To generate custom terrain, set `customChunkGenerate` and `customChunkPopulate` to a function on the world (`room.world`). The arguments for the function is a chunk. When it is set, it will not do normal terrain generation unless the function returns `true`.
Example:
```js
room.world.customChunkGenerate = function(chunk){
	for(let x=0;x<16;x++)for(let z=0;z<16;z++){
		chunk.setBlock(x,0,z,mkServer.blockIds.stone)
	}
}
```

# Functions and other things
Here is a list of functions and other things:
```js
mkServer.getLog()
mkServer.getInfo()
mkServer.createRoom(name, options)
mkServer.getRoom(name)
mkServer.deleteRoom(name)
mkServer.save()//Saves all rooms with autosave
room.addPortal(name, x,y,z, x,y,z)
room.addUneditable(x,y,z, x,y,z)
room.world//The world instance for the room
player.send(object)//Send a packet to client
player.close()//Kicks a client
```
# Why does it need server?
The server is used to create a websocket server that the client can connect to.<br>
It also adds these paths to the server: /info  /validateServer<br>
This means you can't use those urls so you have to ignore them when you recieve it.

# Example
Click [here](https://replit.com/@MineKhan/mkServer?v=1) to see an example