Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements into webservice layout for the huge bots #172

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0d3331c
Add auto publish version on new tag versions
sefirosweb Jan 23, 2023
b80a41e
Remove readonly for movements
sefirosweb Jan 23, 2023
9e775b1
Added default port
sefirosweb Jan 23, 2023
3fb87fd
Linted
sefirosweb Jan 23, 2023
f10490f
Test build
sefirosweb Jan 23, 2023
c82e2e8
Test build
sefirosweb Jan 23, 2023
35c1e5f
Test build
sefirosweb Jan 23, 2023
5744c5d
Change main branch to publish to master
sefirosweb Jan 23, 2023
27ac6e2
Fix clear layout when bot is reloaded
sefirosweb Jan 23, 2023
7317d87
Merge branch 'master' of github.com:sefirosweb/mineflayer-statemachine
sefirosweb Jan 23, 2023
bff9bb8
Add watch in development
sefirosweb Jan 23, 2023
c1bc2dd
Fix name of state
sefirosweb Jan 23, 2023
4fc64ff
Added example with typescript with nested state
sefirosweb Jan 23, 2023
dbcd753
Add info wich state id is this current nestedState
sefirosweb Jan 24, 2023
d71b313
Added method to naviagate nested states via canvas
sefirosweb Jan 24, 2023
b8a2c75
Fixed navigation
sefirosweb Jan 24, 2023
76e26bb
Linted code
sefirosweb Jan 24, 2023
918c87e
Added file tsconfig eslit
sefirosweb Jan 24, 2023
d0eb6b4
Merge branch 'fix_avoid_duplicated_on_reload' into change_nested_layo…
sefirosweb Jan 25, 2023
4316ecd
Merge branch 'auto_publish_npm_version' into change_nested_layout_bar
sefirosweb Jan 25, 2023
945727c
Merge branch 'remove_readonly_movements' into change_nested_layout_bar
sefirosweb Jan 25, 2023
63c2b8a
Restore file delete from error
sefirosweb Jan 25, 2023
1e62fab
Merge branch 'add_click_to_change_nested_state' into change_nested_la…
sefirosweb Jan 25, 2023
8ce29db
Adding example to use tree
sefirosweb Jan 26, 2023
80da963
Changes buttons style
sefirosweb Jan 26, 2023
f33758a
Add tree return data for new layout
sefirosweb Jan 26, 2023
eff1389
Added tree
sefirosweb Jan 27, 2023
6cae910
Removed unused files
sefirosweb Jan 27, 2023
47d2f59
Removed unused css
sefirosweb Jan 27, 2023
e37c4c4
Refact style
sefirosweb Jan 27, 2023
6227fc1
Optimized doble click on button
sefirosweb Jan 27, 2023
5f92a55
Added and fixed bar to move divs
sefirosweb Jan 27, 2023
dcc18a9
Fixed bugs to know in wich layer are all states
sefirosweb Jan 28, 2023
f450a0a
Remove unused code
sefirosweb Jan 28, 2023
640d759
Add buttons to close and open all nested behaviors
sefirosweb Jan 28, 2023
c8fa48b
Add checkbot to auto open state if is actived
sefirosweb Jan 28, 2023
44d0fec
Fixed layout dashboard
sefirosweb Jan 28, 2023
051b3a4
Merge pull request #1 from PrismarineJS/master
kaduvert Oct 2, 2023
fd1230d
Merge branch 'master' of github.com:sefirosweb/mineflayer-statemachine
sefirosweb Nov 5, 2023
e67b941
Merge branch 'master' into change_nested_layout_bar
sefirosweb Nov 5, 2023
dc0f4e9
Merge pull request #3 from sefirosweb/change_nested_layout_bar
kaduvert Dec 15, 2023
7a14845
fix inconsistent variable naming (styling)
kaduvert Dec 15, 2023
d79f14b
remove superfluous whitespace (styling)
kaduvert Dec 15, 2023
823b104
Merge pull request #1 from kaduvert/change_nested_layout_bar
sefirosweb Mar 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/lookatplayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
*/
const mineflayer = require('mineflayer')

if (process.argv.length < 4 || process.argv.length > 6) {
if (process.argv.length < 3 || process.argv.length > 6) {
console.log('Usage : node lookatplayers.js <host> <port> [<name>] [<password>]')
process.exit(1)
}

const bot = mineflayer.createBot({
host: process.argv[2],
port: parseInt(process.argv[3]),
port: process.argv[3] ? parseInt(process.argv[3]) : 25565,
username: process.argv[4] ? process.argv[4] : 'statemachine_bot',
password: process.argv[5]
})
Expand Down
6 changes: 3 additions & 3 deletions examples/webserver.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
const mineflayer = require('mineflayer')

if (process.argv.length < 4 || process.argv.length > 6) {
if (process.argv.length < 3 || process.argv.length > 6) {
console.log('Usage : node webserver.js <host> <port> [<name>] [<password>]')
process.exit(1)
}

const bot = mineflayer.createBot({
host: process.argv[2],
port: parseInt(process.argv[3]),
port: process.argv[3] ? parseInt(process.argv[3]) : 25565,
username: process.argv[4] ? process.argv[4] : 'statemachine_bot',
password: process.argv[5]
})
Expand Down Expand Up @@ -119,7 +119,7 @@ bot.once('spawn', () => {
]

const root = new NestedStateMachine(transitions, printServerStates)
root.name = 'main'
root.stateName = 'main'

bot.on('chat', (username, message) => {
if (message === 'hi') { transitions[1].trigger() }
Expand Down
164 changes: 164 additions & 0 deletions examples/webserver_nested.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import mineflayer, { Bot } from 'mineflayer'
import {
globalSettings,
StateTransition,
BotStateMachine,
StateMachineWebserver,
EntityFilters,
BehaviorIdle,
BehaviorPrintServerStats,
BehaviorFollowEntity,
BehaviorLookAtEntity,
BehaviorGetClosestEntity,
NestedStateMachine,
StateMachineTargets
} from './../src'

import { pathfinder } from 'mineflayer-pathfinder'

if (process.argv.length < 3 || process.argv.length > 6) {
console.log('Usage : node lookatplayers.js <host> <port> [<name>] [<password>]')
process.exit(1)
}

const bot = mineflayer.createBot({
host: process.argv[2],
port: process.argv[3] !== null ? parseInt(process.argv[3]) : 25565,
username: process.argv[4] !== null ? process.argv[4] : 'statemachine_bot',
password: process.argv[5]
})

bot.loadPlugin(pathfinder)

globalSettings.debugMode = true

bot.once('spawn', () => {
const targets = {}

const printServerStates = new BehaviorPrintServerStats(bot)
printServerStates.x = 100
printServerStates.y = 100

const idleState = new BehaviorIdle()
idleState.x = 400
idleState.y = 100

const getClosestPlayer = new BehaviorGetClosestEntity(bot, targets, EntityFilters().PlayersOnly)
getClosestPlayer.x = 700
getClosestPlayer.y = 100

const followingUser = followUser(bot, targets)
followingUser.x = 550
followingUser.y = 210

const transitions = [

new StateTransition({
parent: printServerStates,
child: idleState,
shouldTransition: () => true
}),

new StateTransition({
parent: idleState,
child: getClosestPlayer,
name: 'player says "hi"',
onTransition: () => bot.chat('hello')
}),

new StateTransition({
parent: followingUser,
child: idleState,
name: 'player says "bye"',
onTransition: () => bot.chat('goodbye')
}),

new StateTransition({
parent: getClosestPlayer,
child: followingUser,
shouldTransition: () => true
})
]

const root = new NestedStateMachine(transitions, printServerStates)
root.stateName = 'Main'

bot.on('chat', (username, message) => {
if (message === 'hi') {
transitions.find(t => t.name === 'player says "hi"')?.trigger()
}

if (message === 'bye') {
transitions.find(t => t.name === 'player says "bye"')?.trigger()
}
})

// This function can be in another file
function followUser (bot: Bot, targets: StateMachineTargets): NestedStateMachine {
const lookAtPlayersState = new BehaviorLookAtEntity(bot, targets)
lookAtPlayersState.x = 400
lookAtPlayersState.y = 25

const followPlayer = new BehaviorFollowEntity(bot, targets)
followPlayer.x = 200
followPlayer.y = 200

const lookAtFollowTarget = new BehaviorLookAtEntity(bot, targets)
lookAtFollowTarget.x = 600
lookAtFollowTarget.y = 200

const transitions = [
new StateTransition({
parent: lookAtPlayersState,
child: followPlayer,
name: 'player says "come"'
}),

new StateTransition({
parent: followPlayer,
child: lookAtFollowTarget,
name: 'closeToTarget',
shouldTransition: () => followPlayer.distanceToTarget() < 2
}),

new StateTransition({
parent: lookAtFollowTarget,
child: followPlayer,
name: 'farFromTarget',
shouldTransition: () => lookAtFollowTarget.distanceToTarget() >= 2
}),

new StateTransition({
parent: followPlayer,
child: lookAtPlayersState,
name: 'player says "stay"',
onTransition: () => bot.chat('staying')
}),

new StateTransition({
parent: lookAtFollowTarget,
child: lookAtPlayersState,
name: 'player says "stay"'
})
]

bot.on('chat', (username, message) => {
if (message === 'come') {
transitions.find(t => t.name === 'player says "come"')?.trigger()
}

if (message === 'stay') {
transitions.filter(t => t.name === 'player says "stay"')
.forEach(t => t.trigger())
}
})

const nestedState = new NestedStateMachine(transitions, lookAtPlayersState)
nestedState.stateName = 'Follow the entity'
return nestedState
}

const stateMachine = new BotStateMachine(bot, root)
const webserver = new StateMachineWebserver(bot, stateMachine)
webserver.startServer()
})
2 changes: 1 addition & 1 deletion examples/webserver_static_layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bot.once('spawn', () => {
]

const root = new NestedStateMachine(transitions, printServerStates)
root.name = 'main'
root.stateName = 'main'

bot.on('chat', (username, message) => {
if (message === 'hi') { transitions[1].trigger() }
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"types": "lib/index.d.ts",
"scripts": {
"build": "ts-standard && tsc",
"watch": "tsc -w",
"clean": "rm -rf lib",
"test": "test",
"fix-lint": "ts-standard --fix"
Expand Down Expand Up @@ -58,4 +59,4 @@
"lib"
]
}
}
}
2 changes: 1 addition & 1 deletion src/statemachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export class NestedStateMachine extends EventEmitter implements StateBehavior {
/**
* A list of all states within this state machine layer.
*/
readonly states: StateBehavior[]
readonly states: Array<StateBehavior | NestedStateMachine>

/**
* A list of all transitions within this state machine layer.
Expand Down
59 changes: 57 additions & 2 deletions src/webserver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Bot } from 'mineflayer'
import { BotStateMachine, StateBehavior } from './statemachine'
import { BotStateMachine, NestedStateMachine, StateBehavior } from './statemachine'
import socketLoader, { Socket } from 'socket.io'
import path from 'path'
import express from 'express'
Expand Down Expand Up @@ -93,11 +93,13 @@ export class StateMachineWebserver {
const states = this.getStates()
const transitions = this.getTransitions()
const nestGroups = this.getNestGroups()
const nestGroupsTree: NestedStateMachinePacketTree[] = this.getNestGroupsTree(this.stateMachine.rootStateMachine, true, nestGroups) as NestedStateMachinePacketTree[]

const packet: StateMachineStructurePacket = {
states,
transitions,
nestGroups
nestGroups,
nestGroupsTree
}

socket.emit('connected', packet)
Expand Down Expand Up @@ -175,6 +177,7 @@ export class StateMachineWebserver {
const nest = this.stateMachine.nestedStateMachines[i]
nestGroups.push({
id: i,
stateId: this.stateMachine.states.indexOf(nest),
enter: this.stateMachine.states.indexOf(nest.enter),
exit: nest.exit != null ? this.stateMachine.states.indexOf(nest.exit) : undefined,
indent: nest.depth ?? -1,
Expand All @@ -184,21 +187,73 @@ export class StateMachineWebserver {

return nestGroups
}

private getNestGroupsTree (currentState: NestedStateMachine, firstState: boolean, nestedStateMachine: NestedStateMachinePacket[]): NestedStateMachinePacketTree[] | NestedStateMachinePacketTree {
const statesOnThisBehavior: NestedStateMachinePacketTree[] = []

currentState.states.forEach((state) => {
if (isNestedStateMachine(state)) {
const subStates = this.getNestGroupsTree(state, false, nestedStateMachine)
if (!Array.isArray(subStates)) {
statesOnThisBehavior.push(subStates)
}
}
})

const currentStateId = this.stateMachine.states.indexOf(currentState)

const returnData: NestedStateMachinePacketTree = {
id: nestedStateMachine.find((n) => n.stateId === currentStateId)?.id ?? 0,
stateId: currentStateId,
enter: this.stateMachine.states.indexOf(currentState.enter),
exit: currentState.exit != null ? this.stateMachine.states.indexOf(currentState.exit) : undefined,
name: currentState.stateName,
open: false,
selected: false,
type: statesOnThisBehavior.length > 0 ? 'folder' : 'file',
children: statesOnThisBehavior
}

if (firstState) {
returnData.selected = true
return [returnData]
}

return returnData
}
}

const isNestedStateMachine = (state: NestedStateMachine | StateBehavior): state is NestedStateMachine => {
return state instanceof NestedStateMachine
}

interface StateMachineStructurePacket {
states: StateMachineStatePacket[]
transitions: StateMachineTransitionPacket[]
nestGroups: NestedStateMachinePacket[]
nestGroupsTree: NestedStateMachinePacketTree[]

}

interface NestedStateMachinePacket {
id: number
stateId: number
enter: number
exit?: number
indent: number
name?: string
}
interface NestedStateMachinePacketTree {
id: number
stateId: number
enter: number
exit?: number
name: string
open: boolean
selected: boolean
type: 'folder' | 'file'
children: NestedStateMachinePacketTree[]
}

interface StateMachineStatePacket {
id: number
Expand Down
12 changes: 12 additions & 0 deletions tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"types": ["@types/node"],
"noEmit": true,
"allowJs": true
},
"extends": "./tsconfig.json",
"include": [
"src",
"examples",
]
}
Loading