Skip to content

Commit

Permalink
phase 2: add typings with script & a few manual fixes, fix a few bugs
Browse files Browse the repository at this point in the history
(cherry picked from commit 1acb152)

with a lot of manual fixes
  • Loading branch information
zardoy committed Jan 17, 2024
1 parent f721622 commit 90caa81
Show file tree
Hide file tree
Showing 55 changed files with 798 additions and 285 deletions.
5 changes: 3 additions & 2 deletions src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// make process.platform also accept browser
declare namespace NodeJS {
interface Process {
platform: string;
//@ts-ignore
platform: string
browser?: boolean
}

}
interface NodeRequire {
// webpack bundling
context: (path: string, deep: boolean, filter: RegExp) => { keys: () => string[]; (id: string): any };
context: (path: string, deep: boolean, filter: RegExp) => { keys: () => string[]; (id: string): any }
}
74 changes: 45 additions & 29 deletions src/index.js → src/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import { createServer } from 'minecraft-protocol'

import { testedVersions, latestSupportedVersion, oldestSupportedVersion } from './lib/version'
import Command from './lib/command'
import * as plugins from './lib/modules'
import { EventEmitter } from 'events'
import { Server as ProtocolServer } from 'minecraft-protocol'

if (typeof process !== 'undefined' && !process.browser && process.platform !== 'browser' && parseInt(process.versions.node.split('.')[0]) < 18) {
console.error('[\x1b[31mCRITICAL\x1b[0m] Node.JS 18 or newer is required')
console.error('[\x1b[31mCRITICAL\x1b[0m] You can download the new version from https://nodejs.org/')
console.error(`[\x1b[31mCRITICAL\x1b[0m] Your current Node.JS version is: ${process.versions.node}`)
process.exit(1)
}

const { createServer } = require('minecraft-protocol')

const EventEmitter = require('events').EventEmitter
const { testedVersions, latestSupportedVersion, oldestSupportedVersion } = require('./lib/version')
const Command = require('./lib/command')
const plugins = require('./lib/plugins')
require('emit-then').register()
if (process.env.NODE_ENV === 'dev') {
require('longjohn')
}

module.exports = {
createMCServer,
Behavior: require('./lib/behavior'),
Command: require('./lib/command'),
generations: require('./lib/generations'),
experience: require('./lib/experience'),
UserError: require('./lib/user_error'),
portal_detector: require('./lib/portal_detector'),
testedVersions
}

function createMCServer (options) {
options = options || {}
function createMCServer (options = {}) {
const mcServer = new MCServer()
mcServer.connect(options)
return mcServer
Expand All @@ -43,6 +33,7 @@ class MCServer extends EventEmitter {
}

connect (options) {
const server = this as unknown as Server
const registry = require('prismarine-registry')(options.version)
if (!registry?.version) throw new Error(`Server version '${registry?.version}' is not supported, no data for version`)

Expand All @@ -53,21 +44,46 @@ class MCServer extends EventEmitter {
throw new Error(`Server version '${registry?.version}' is not supported. Oldest supported version is '${oldestSupportedVersion}'.`)
}

this.commands = new Command({})
this._server = createServer(options)
server.commands = new Command({})
server._server = createServer(options)

const promises = []
const promises: Promise<any>[] = []
for (const plugin of plugins.builtinPlugins) {
promises.push(plugin.server?.(this, options))
promises.push(plugin.server?.(server, options))
}
Promise.all(promises).then(() => {
this.emit('pluginsReady')
this.pluginsReady = true
server.emit('pluginsReady')
server.pluginsReady = true
})

if (options.logging === true) this.createLog()
this._server.on('error', error => this.emit('error', error))
this._server.on('listening', () => this.emit('listening', this._server.socketServer.address().port))
this.emit('asap')
if (options.logging === true) server.createLog()
server._server.on('error', error => {
server.emit('error', error);
})
server._server.on('listening', () => {
server.emit('listening', server._server.socketServer.address().port);
})
server.emit('asap')
}
}

declare global {
interface Server {
commands: Command
pluginsReady: boolean
_server: ProtocolServer
supportFeature: (feature: string) => boolean
}
}

export {
createMCServer,
testedVersions
}

export * as Behavior from './lib/behavior';
export * as Command from './lib/command';
export * as generations from './lib/generations';
export * as experience from './lib/experience';
export * as UserError from './lib/user_error';
export * as portal_detector from './lib/portal_detector';
6 changes: 3 additions & 3 deletions src/lib/behavior.js → src/lib/behavior.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = (obj) => {
return async (eventName, data, func, cancelFunc) => {
export default (obj) => {
return async (eventName: string, data?: any, func?: Function, cancelFunc?: Function) => {
let hiddenCancelled = false
let cancelled = false
let cancelCount = 0
Expand All @@ -15,7 +15,7 @@ module.exports = (obj) => {

let resp

func = func || (() => {})
func = func || (() => { })

await obj.emitThen(eventName + '_cancel', data, cancel).catch((err) => setTimeout(() => { throw err }, 0))
await obj.emitThen(eventName, data, cancelled, cancelCount).catch((err) => setTimeout(() => { throw err }, 0))
Expand Down
6 changes: 4 additions & 2 deletions src/lib/command.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const UserError = require('./user_error')
//@ts-check
import UserError from './user_error'

class Command {
constructor (params, parent, hash) {
Expand Down Expand Up @@ -83,9 +84,10 @@ class Command {
}

tab (command, i) {
//@ts-ignore
if (this.find(command)[0].params.tab) return this.find(command)[0].params.tab[i]
return 'player'
}
}

module.exports = Command
export default Command
4 changes: 2 additions & 2 deletions src/lib/convertInventorySlotId.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module.exports = { fromNBT, toNBT }

const replace = {
100: 8, 101: 7, 102: 6, 103: 5, '-106': 45
}
Expand Down Expand Up @@ -28,3 +26,5 @@ function toNBT (slotId) {
}
return invertReplace[returnSlotId] || slot
}

export { fromNBT, toNBT }
4 changes: 2 additions & 2 deletions src/lib/experience.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module.exports = { distanceToXpLevel, getXpLevel, getXpRequired, getBaseXpFromLevel }

function distanceToXpLevel (xp, toLevel) {
const level = getXpLevel(xp)
if (!toLevel) toLevel = level + 1
Expand Down Expand Up @@ -46,3 +44,5 @@ function getBaseXpFromLevel (level) {
return 4.5 * level * level - 162.5 * level + 2220
}
}

export { distanceToXpLevel, getXpLevel, getXpRequired, getBaseXpFromLevel }
4 changes: 3 additions & 1 deletion src/lib/modules/animations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports.player = function (player) {
export const player = function (player: Player) {
player._client.on('arm_animation', () =>
player.behavior('punch', {}, () => {
player._writeOthersNearby('animation', {
Expand All @@ -22,3 +22,5 @@ module.exports.player = function (player) {
}
})
}
declare global {
}
14 changes: 11 additions & 3 deletions src/lib/modules/behavior.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
const Behavior = require('flying-squid').Behavior
import Behavior from '../behavior'

module.exports.server = function (serv) {
export const server = function (serv: Server) {
serv.behavior = Behavior(serv)
}

module.exports.entity = function (entity) {
export const entity = function (entity) {
entity.behavior = Behavior(entity)
}
declare global {
interface Server {
behavior: ReturnType<typeof Behavior>
}
interface Entity {
behavior: ReturnType<typeof Behavior>
}
}
22 changes: 16 additions & 6 deletions src/lib/modules/blockUpdates.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const { performance } = require('perf_hooks')
import { performance } from 'perf_hooks'

let multiBlockChangeHasTrustEdges
class ChunkUpdates {
constructor () {
chunks: Map<string, { chunkX, chunkZ, updates }>
constructor() {
this.chunks = new Map()
}

Expand All @@ -14,7 +15,7 @@ class ChunkUpdates {
if (!this.chunks.has(key)) {
this.chunks.set(key, { chunkX, chunkZ, chunkY, updates: new Set() })
}
this.chunks.get(key).updates.add(pos)
this.chunks.get(key)!.updates.add(pos)
}

updateCount () {
Expand All @@ -26,10 +27,10 @@ class ChunkUpdates {
}

async getMultiBlockPackets (world) {
const packets = []
const packets = [] as any[]

for (const { chunkX, chunkZ, chunkY, updates } of this.chunks.values()) {
const records = []
const records = [] as any[]
for (const p of updates.values()) {
const state = await world.getBlockStateId(p)

Expand Down Expand Up @@ -62,7 +63,7 @@ class ChunkUpdates {
}
}

module.exports.server = (serv, { version }) => {
export const server = (serv: Server, { version }: Options) => {
const registry = require('prismarine-registry')(version)

multiBlockChangeHasTrustEdges = registry.supportFeature('multiBlockChangeHasTrustEdges')
Expand Down Expand Up @@ -187,3 +188,12 @@ module.exports.server = (serv, { version }) => {
}
})
}
declare global {
interface Server {
"MAX_UPDATES_PER_TICK": number
"updateBlock": (world: any, pos: any, fromTick: any, tick: any, forceNotify?: boolean, data?: null) => void
"notifyNeighborsOfStateChange": (world: any, pos: any, fromTick: any, tick: any, forceNotify?: boolean, data?: null) => void
"notifyNeighborsOfStateChangeDirectional": (world: any, pos: any, dir: any, fromTick: any, tick: any, forceNotify?: boolean, data?: null) => void
"onBlockUpdate": (name: any, handler: any) => void
}
}
23 changes: 16 additions & 7 deletions src/lib/modules/blocks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { skipMcPrefix } = require('../utils')
import { skipMcPrefix } from '../utils'

const Vec3 = require('vec3').Vec3
import { Vec3 } from 'vec3'

module.exports.player = function (player, serv, { version }) {
export const player = function (player: Player, serv: Server) {
player.changeBlock = async (position, blockType, blockData) => {
serv.players
.filter(p => p.world === player.world && player !== p)
.forEach(p => p.sendBlock(position, blockType, blockData))
.forEach(p => p.sendBlock(position, blockType/* , blockData */)) // todo

await player.world.setBlockType(position, blockType)
await player.world.setBlockData(position, blockData)
Expand Down Expand Up @@ -51,9 +51,9 @@ module.exports.player = function (player, serv, { version }) {
player.setBlockAction = (position, actionId, actionParam) => serv.setBlockAction(player.world, position, actionId, actionParam)
}

module.exports.server = function (serv, { version }) {
const registry = require('prismarine-registry')(version)
const blocks = registry.blocks
export const server = function (serv: Server, { version }: Options) {
const mcData = require('minecraft-data')(version)
const blocks = mcData.blocks

serv.commands.add({
base: 'setblock',
Expand Down Expand Up @@ -97,3 +97,12 @@ module.exports.server = function (serv, { version }) {
}
})
}
declare global {
interface Player {
"changeBlock": (position: any, blockType: any, blockData: any) => Promise<void>
"sendBlock": (position: any, blockStateId: any) => any
"setBlock": (position: any, stateId: any) => any
"sendBlockAction": (position: any, actionId: any, actionParam: any, blockType: any) => Promise<void>
"setBlockAction": (position: any, actionId: any, actionParam: any) => any
}
}
7 changes: 6 additions & 1 deletion src/lib/modules/channels.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const PLAY = require('minecraft-protocol').states.PLAY

module.exports.player = (player) => {
export const player = (player) => {
player.sendBrand = async (brand = 'flying-squid') => {
if (player._client.state !== PLAY) throw new Error(`The state of the player must be PLAY (actual state: ${player._client.state})`)
player._client.writeChannel((
Expand All @@ -18,3 +18,8 @@ module.exports.player = (player) => {
player.sendBrand()
})
}
declare global {
interface Player {
"sendBrand": (brand?: string) => Promise<void>
}
}
28 changes: 24 additions & 4 deletions src/lib/modules/chat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports.server = function (serv) {
serv.broadcast = (message, { whitelist = serv.players, blacklist = [], system = false } = {}) => {
export const server = function (serv: Server) {
serv.broadcast = (message, { whitelist = serv.players, blacklist = [], system = false }: any = {}) => {
if (whitelist.type === 'player') whitelist = [whitelist]

if (typeof message === 'string') message = serv.parseClassic(message)
Expand Down Expand Up @@ -45,7 +45,15 @@ module.exports.server = function (serv) {

serv.parseClassic = (message) => {
if (typeof message === 'object') return message
const messageList = []
const messageList: {
text,
color,
bold,
italic,
underlined,
strikethrough,
obfuscated
}[] = []
let text = ''
let nextChanged = false
let color = 'white'
Expand Down Expand Up @@ -119,7 +127,7 @@ module.exports.server = function (serv) {
}
}

module.exports.player = function (player, serv) {
export const player = function (player: Player, serv: Server) {
player._client.on('chat', ({ message } = {}) => {
if (message[0] === '/') {
player.behavior('command', { command: message.slice(1) }, ({ command }) => player.handleCommand(command))
Expand Down Expand Up @@ -159,3 +167,15 @@ module.exports.player = function (player, serv) {
player._client.write('chat', { message: JSON.stringify(message), position: 2, sender: '0' })
}
}
declare global {
interface Server {
"broadcast": (message: any, { whitelist, blacklist, system }?: { whitelist?: any; blacklist?: any[] | undefined; system?: boolean | undefined }) => void
"color": { black: string; dark_blue: string; dark_green: string; dark_cyan: string; dark_red: string; purple: string; dark_purple: string; gold: string; gray: string; grey: string; dark_gray: string; dark_grey: string; blue: string; green: string; aqua: string; cyan: string; red: string; pink: string; light_purple: string; yellow: string; white: string; random: string; obfuscated: string; bold: string; strikethrough: string; underlined: string; underline: string; italic: string; italics: string; reset: string }
"parseClassic": (message: any) => any
}
interface Player {
"chat": (message: any) => void
"emptyChat": (count?: number) => void
"system": (message: any) => void
}
}
7 changes: 5 additions & 2 deletions src/lib/modules/chest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Vec3 = require('vec3').Vec3
import MinecraftData from 'minecraft-data'
import { Vec3 } from 'vec3'

module.exports.server = function (serv, { version }) {
export const server = (serv: Server, { version }: Options) => {
serv.once('asap', () => {
// Importing necessary libraries
const registry = require('prismarine-registry')(version)
Expand Down Expand Up @@ -106,3 +107,5 @@ module.exports.server = function (serv, { version }) {
}
})
}
declare global {
}
Loading

0 comments on commit 90caa81

Please sign in to comment.