prismarine-chat 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +16 -0
- package/MessageBuilder.js +17 -4
- package/README.md +2 -2
- package/index.d.ts +17 -9
- package/index.js +336 -319
- package/package.json +5 -4
- package/test/basic.test.js +17 -4
- package/test/messagebuilder.test.js +7 -5
package/HISTORY.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
## History
|
|
2
2
|
|
|
3
|
+
### 1.5.0
|
|
4
|
+
|
|
5
|
+
* allow ChatMessage constructor to accept strings with legacy color codes (§) be converted to new json
|
|
6
|
+
|
|
7
|
+
### 1.4.1
|
|
8
|
+
* Remake ChatMessage#clone (@u9g)
|
|
9
|
+
|
|
10
|
+
### 1.4.0
|
|
11
|
+
* Add a example (@u9g)
|
|
12
|
+
* Add hex color code support (@U5B)
|
|
13
|
+
* use rest arg to allow many withs or extras (@u9g)
|
|
14
|
+
* Add missing json attribute to typescript defintions (@Paulomart & @u9g)
|
|
15
|
+
|
|
16
|
+
### 1.3.3
|
|
17
|
+
* fix typings
|
|
18
|
+
|
|
3
19
|
### 1.3.2
|
|
4
20
|
* Properly export loader function and export ChatMessage & MessageBuilder as types
|
|
5
21
|
|
package/MessageBuilder.js
CHANGED
|
@@ -144,16 +144,29 @@ function loader (version) {
|
|
|
144
144
|
/**
|
|
145
145
|
* appended to the end of this message object with the existing formatting.
|
|
146
146
|
* formatting can be overrode in child messagebuilder
|
|
147
|
-
* @param {MessageBuilder|string}
|
|
147
|
+
* @param {Array<MessageBuilder | string>} ...args
|
|
148
148
|
* @returns
|
|
149
149
|
*/
|
|
150
|
-
addExtra (
|
|
150
|
+
addExtra (...args) {
|
|
151
|
+
for (const v of args) {
|
|
152
|
+
const value = typeof v === 'string' ? v : v.toJSON()
|
|
153
|
+
this.extra.push(value)
|
|
154
|
+
}
|
|
155
|
+
return this
|
|
156
|
+
}
|
|
157
|
+
|
|
151
158
|
/**
|
|
152
159
|
* requires .translate to be set for this to be used
|
|
153
|
-
* @param {MessageBuilder|string}
|
|
160
|
+
* @param {Array<MessageBuilder | string>} ...args
|
|
154
161
|
* @returns
|
|
155
162
|
*/
|
|
156
|
-
addWith (
|
|
163
|
+
addWith (...args) {
|
|
164
|
+
for (const v of args) {
|
|
165
|
+
const value = typeof v === 'string' ? v : v.toJSON()
|
|
166
|
+
this.with.push(value)
|
|
167
|
+
}
|
|
168
|
+
return this
|
|
169
|
+
}
|
|
157
170
|
|
|
158
171
|
resetFormatting () {
|
|
159
172
|
this.setBold(false)
|
package/README.md
CHANGED
|
@@ -90,8 +90,8 @@ Returns a prismarine-chat representation of the message recieved from the 'chat'
|
|
|
90
90
|
#### setScore (name: string, objective: string) : this
|
|
91
91
|
#### setClickEvent (action: string, value: object) : this
|
|
92
92
|
#### setHoverEvent (action: string, data: object, type?: 'contents'|'value') : this
|
|
93
|
-
#### addExtra (val: MessageBuilder | string) : this
|
|
94
|
-
#### addWith (val: MessageBuilder | string) : this
|
|
93
|
+
#### addExtra (...val: MessageBuilder | string) : this
|
|
94
|
+
#### addWith (...val: MessageBuilder | string) : this
|
|
95
95
|
#### resetFormatting () : void
|
|
96
96
|
sets every one of the formatting options to false and sets text to `reset` type
|
|
97
97
|
|
package/index.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
declare const loader: (mcVersion: string) => typeof ChatMessage
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export default loader
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
export type MessageBuilder = MessageBuilder
|
|
7
|
-
|
|
8
|
-
declare class ChatMessage {
|
|
5
|
+
export declare class ChatMessage {
|
|
9
6
|
// for export
|
|
10
7
|
static MessageBuilder: typeof MessageBuilder
|
|
11
8
|
|
|
@@ -17,6 +14,8 @@ declare class ChatMessage {
|
|
|
17
14
|
displayWarning?: boolean
|
|
18
15
|
)
|
|
19
16
|
|
|
17
|
+
public readonly json: any
|
|
18
|
+
|
|
20
19
|
/**
|
|
21
20
|
* Append one or more ChatMessages
|
|
22
21
|
*/
|
|
@@ -26,6 +25,13 @@ declare class ChatMessage {
|
|
|
26
25
|
* Returns a clone of the ChatMessage
|
|
27
26
|
*/
|
|
28
27
|
clone(): ChatMessage
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Optional info with no guarantee for form or shape.
|
|
31
|
+
*/
|
|
32
|
+
extra?: Array<ChatMessage>
|
|
33
|
+
|
|
34
|
+
translate?: string
|
|
29
35
|
|
|
30
36
|
/**
|
|
31
37
|
* Flattens the message into plain-text, without style.
|
|
@@ -66,7 +72,7 @@ declare class ChatMessage {
|
|
|
66
72
|
|
|
67
73
|
type Language = { [key: string]: string }
|
|
68
74
|
|
|
69
|
-
declare class MessageBuilder {
|
|
75
|
+
export declare class MessageBuilder {
|
|
70
76
|
with: string[]
|
|
71
77
|
extra: string[]
|
|
72
78
|
bold?: boolean
|
|
@@ -167,19 +173,21 @@ declare class MessageBuilder {
|
|
|
167
173
|
* appended to the end of this message object with the existing formatting.
|
|
168
174
|
* formatting can be overridden in child messagebuilder
|
|
169
175
|
*/
|
|
170
|
-
addExtra(
|
|
176
|
+
addExtra(...args: Array<MessageBuilder | string>): this
|
|
171
177
|
|
|
172
178
|
/**
|
|
173
179
|
* requires .translate to be set for this to be used
|
|
174
180
|
*/
|
|
175
|
-
addWith(
|
|
181
|
+
addWith(...args: Array<MessageBuilder | string>): this
|
|
176
182
|
|
|
177
183
|
resetFormatting(): void
|
|
178
184
|
|
|
179
185
|
toJSON(): object
|
|
180
186
|
|
|
181
187
|
toString(): string
|
|
182
|
-
|
|
188
|
+
/**
|
|
189
|
+
* fromString('&aHello').toJSON() => { text: 'Hello', color: 'aqua' }
|
|
190
|
+
*/
|
|
183
191
|
static fromString(
|
|
184
192
|
str: string,
|
|
185
193
|
args?: { colorSeparator?: string }
|
package/index.js
CHANGED
|
@@ -5,361 +5,378 @@ module.exports = loader
|
|
|
5
5
|
|
|
6
6
|
function loader (mcVersion) {
|
|
7
7
|
const mcData = require('minecraft-data')(mcVersion)
|
|
8
|
-
defaultLang = mcData.language
|
|
8
|
+
const defaultLang = mcData.language
|
|
9
9
|
const { MessageBuilder } = require('./MessageBuilder')(mcVersion)
|
|
10
|
-
ChatMessage.MessageBuilder = MessageBuilder
|
|
11
|
-
return ChatMessage
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let defaultLang
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* ChatMessage Constructor
|
|
18
|
-
* @param {String|Object|Number} message content of ChatMessage
|
|
19
|
-
*/
|
|
20
|
-
class ChatMessage {
|
|
21
|
-
constructor (message, displayWarning = false) {
|
|
22
|
-
if (typeof message === 'string' || typeof message === 'number') {
|
|
23
|
-
this.json = { text: message }
|
|
24
|
-
} else if (typeof message === 'object' && !Array.isArray(message)) {
|
|
25
|
-
this.json = message
|
|
26
|
-
} else if (typeof message === 'object') {
|
|
27
|
-
this.json = { extra: message }
|
|
28
|
-
} else {
|
|
29
|
-
throw new Error('Expected String or Object for Message argument')
|
|
30
|
-
}
|
|
31
|
-
this.parse(displayWarning)
|
|
32
|
-
}
|
|
33
10
|
|
|
34
11
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @return {void}
|
|
12
|
+
* ChatMessage Constructor
|
|
13
|
+
* @param {String|Object|Number} message content of ChatMessage
|
|
38
14
|
*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.text = json.text
|
|
47
|
-
} else if (typeof json.translate === 'string') {
|
|
48
|
-
this.translate = json.translate
|
|
49
|
-
if (typeof json.with === 'object') {
|
|
50
|
-
if (!Array.isArray(json.with)) {
|
|
51
|
-
throw new Error('Expected with property to be an Array in ChatMessage')
|
|
15
|
+
class ChatMessage {
|
|
16
|
+
constructor (message, displayWarning = false) {
|
|
17
|
+
if (typeof message === 'string') {
|
|
18
|
+
if (message === '') {
|
|
19
|
+
this.json = { text: '' }
|
|
20
|
+
} else {
|
|
21
|
+
this.json = MessageBuilder.fromString(message, { colorSeparator: '§' })
|
|
52
22
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new Error('Expected
|
|
23
|
+
} else if (typeof message === 'number') {
|
|
24
|
+
this.json = { text: message }
|
|
25
|
+
} else if (typeof message === 'object' && Array.isArray(message)) {
|
|
26
|
+
this.json = { extra: message }
|
|
27
|
+
} else if (typeof message === 'object') {
|
|
28
|
+
this.json = message
|
|
29
|
+
} else {
|
|
30
|
+
throw new Error('Expected String or Object for Message argument')
|
|
61
31
|
}
|
|
62
|
-
this.
|
|
32
|
+
this.parse(displayWarning)
|
|
63
33
|
}
|
|
64
|
-
// Text modifiers
|
|
65
|
-
this.bold = json.bold
|
|
66
|
-
this.italic = json.italic
|
|
67
|
-
this.underlined = json.underlined
|
|
68
|
-
this.strikethrough = json.strikethrough
|
|
69
|
-
this.obfuscated = json.obfuscated
|
|
70
34
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
'
|
|
83
|
-
|
|
84
|
-
'
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
]
|
|
35
|
+
/**
|
|
36
|
+
* Parses the this.json property to decorate the properties of the ChatMessage.
|
|
37
|
+
* Called by the Constructor
|
|
38
|
+
* @return {void}
|
|
39
|
+
*/
|
|
40
|
+
parse (displayWarning = false) {
|
|
41
|
+
const json = this.json
|
|
42
|
+
// Message scope for callback functions
|
|
43
|
+
// There is EITHER, a text property or a translate property
|
|
44
|
+
// If there is no translate property, there is no with property
|
|
45
|
+
// HOWEVER! If there is a translate property, there may not be a with property
|
|
46
|
+
if (typeof json.text === 'string' || typeof json.text === 'number') {
|
|
47
|
+
this.text = json.text
|
|
48
|
+
} else if (typeof json.translate === 'string') {
|
|
49
|
+
this.translate = json.translate
|
|
50
|
+
if (typeof json.with === 'object') {
|
|
51
|
+
if (!Array.isArray(json.with)) {
|
|
52
|
+
throw new Error('Expected with property to be an Array in ChatMessage')
|
|
53
|
+
}
|
|
54
|
+
this.with = json.with.map(entry => new ChatMessage(entry))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Parse extra property
|
|
58
|
+
// Extras are appended to the initial text
|
|
59
|
+
if (typeof json.extra === 'object') {
|
|
60
|
+
if (!Array.isArray(json.extra)) {
|
|
61
|
+
throw new Error('Expected extra property to be an Array in ChatMessage')
|
|
62
|
+
}
|
|
63
|
+
this.extra = json.extra.map(entry => new ChatMessage(entry))
|
|
64
|
+
}
|
|
65
|
+
// Text modifiers
|
|
66
|
+
this.bold = json.bold
|
|
67
|
+
this.italic = json.italic
|
|
68
|
+
this.underlined = json.underlined
|
|
69
|
+
this.strikethrough = json.strikethrough
|
|
70
|
+
this.obfuscated = json.obfuscated
|
|
108
71
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
72
|
+
// Supported constants @ 2014-04-21
|
|
73
|
+
const supportedColors = [
|
|
74
|
+
'black',
|
|
75
|
+
'dark_blue',
|
|
76
|
+
'dark_green',
|
|
77
|
+
'dark_aqua',
|
|
78
|
+
'dark_red',
|
|
79
|
+
'dark_purple',
|
|
80
|
+
'gold',
|
|
81
|
+
'gray',
|
|
82
|
+
'dark_gray',
|
|
83
|
+
'blue',
|
|
84
|
+
'green',
|
|
85
|
+
'aqua',
|
|
86
|
+
'red',
|
|
87
|
+
'light_purple',
|
|
88
|
+
'yellow',
|
|
89
|
+
'white',
|
|
90
|
+
'obfuscated',
|
|
91
|
+
'bold',
|
|
92
|
+
'strikethrough',
|
|
93
|
+
'underlined',
|
|
94
|
+
'italic',
|
|
95
|
+
'reset'
|
|
96
|
+
]
|
|
97
|
+
const supportedClick = [
|
|
98
|
+
'open_url',
|
|
99
|
+
'open_file',
|
|
100
|
+
'run_command',
|
|
101
|
+
'suggest_command'
|
|
102
|
+
]
|
|
103
|
+
const supportedHover = [
|
|
104
|
+
'show_text',
|
|
105
|
+
'show_achievement',
|
|
106
|
+
'show_item',
|
|
107
|
+
'show_entity'
|
|
108
|
+
]
|
|
141
109
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
110
|
+
// Parse color
|
|
111
|
+
this.color = json.color
|
|
112
|
+
switch (this.color) {
|
|
113
|
+
case 'obfuscated':
|
|
114
|
+
this.obfuscated = true
|
|
115
|
+
this.color = null
|
|
116
|
+
break
|
|
117
|
+
case 'bold':
|
|
118
|
+
this.bold = true
|
|
119
|
+
this.color = null
|
|
120
|
+
break
|
|
121
|
+
case 'strikethrough':
|
|
122
|
+
this.strikethrough = true
|
|
123
|
+
this.color = null
|
|
124
|
+
break
|
|
125
|
+
case 'underlined':
|
|
126
|
+
this.underlined = true
|
|
127
|
+
this.color = null
|
|
128
|
+
break
|
|
129
|
+
case 'italic':
|
|
130
|
+
this.italic = true
|
|
131
|
+
this.color = null
|
|
132
|
+
break
|
|
133
|
+
case 'reset':
|
|
134
|
+
this.reset = true
|
|
135
|
+
this.color = null
|
|
136
|
+
break
|
|
137
|
+
}
|
|
138
|
+
// Make sure color is valid
|
|
139
|
+
if (Array.prototype.indexOf && this.color &&
|
|
140
|
+
supportedColors.indexOf(this.color) === -1 &&
|
|
141
|
+
!this.color.match(/#[a-fA-F\d]{6}/) && displayWarning) {
|
|
142
|
+
console.warn('ChatMessage parsed with unsupported color', this.color)
|
|
149
143
|
}
|
|
150
|
-
}
|
|
151
144
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
// Parse click event
|
|
146
|
+
if (typeof json.clickEvent === 'object') {
|
|
147
|
+
this.clickEvent = json.clickEvent
|
|
148
|
+
if (typeof this.clickEvent.action !== 'string') {
|
|
149
|
+
throw new Error('ClickEvent action missing in ChatMessage')
|
|
150
|
+
} else if (Array.prototype.indexOf && supportedClick.indexOf(this.clickEvent.action) === -1 && displayWarning) {
|
|
151
|
+
console.warn('ChatMessage parsed with unsupported clickEvent', this.clickEvent.action)
|
|
152
|
+
}
|
|
159
153
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
154
|
+
|
|
155
|
+
// Parse hover event
|
|
156
|
+
if (typeof json.hoverEvent === 'object') {
|
|
157
|
+
this.hoverEvent = json.hoverEvent
|
|
158
|
+
if (typeof this.hoverEvent.action !== 'string') {
|
|
159
|
+
throw new Error('HoverEvent action missing in ChatMessage')
|
|
160
|
+
} else if (Array.prototype.indexOf && supportedHover.indexOf(this.hoverEvent.action) === -1 && displayWarning) {
|
|
161
|
+
console.warn('ChatMessage parsed with unsupported hoverEvent', this.hoverEvent.action)
|
|
162
|
+
}
|
|
163
|
+
// Special case
|
|
164
|
+
if (this.hoverEvent.action === 'show_item') {
|
|
165
|
+
let content
|
|
166
|
+
if (this.hoverEvent.value instanceof Array) {
|
|
167
|
+
if (this.hoverEvent.value[0] instanceof Object) {
|
|
168
|
+
content = this.hoverEvent.value[0].text
|
|
169
|
+
} else {
|
|
170
|
+
content = this.hoverEvent.value[0]
|
|
171
|
+
}
|
|
172
172
|
} else {
|
|
173
|
-
|
|
173
|
+
if (this.hoverEvent.value instanceof Object) {
|
|
174
|
+
content = this.hoverEvent.value.text
|
|
175
|
+
} else {
|
|
176
|
+
content = this.hoverEvent.value
|
|
177
|
+
}
|
|
174
178
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
} catch (err) {
|
|
179
|
+
try {
|
|
180
|
+
this.hoverEvent.value = mojangson.parse(content)
|
|
181
|
+
} catch (err) {
|
|
179
182
|
|
|
183
|
+
}
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
186
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Append one or more ChatMessages
|
|
187
|
-
* @param {...object|string} messages ChatMessage
|
|
188
|
-
* @return {void}
|
|
189
|
-
*/
|
|
190
|
-
append (...messages) {
|
|
191
|
-
if (this.extra === undefined) this.extra = []
|
|
192
|
-
messages.forEach((message) => {
|
|
193
|
-
if (typeof message === 'object' && !Array.isArray(message)) {
|
|
194
|
-
this.extra.push(message)
|
|
195
|
-
} else if (typeof message === 'string') {
|
|
196
|
-
this.extra.push(new ChatMessage(message))
|
|
197
|
-
}
|
|
198
|
-
})
|
|
199
|
-
}
|
|
200
187
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Append one or more ChatMessages
|
|
190
|
+
* @param {...object|string} messages ChatMessage
|
|
191
|
+
* @return {void}
|
|
192
|
+
*/
|
|
193
|
+
append (...messages) {
|
|
194
|
+
if (this.extra === undefined) this.extra = []
|
|
195
|
+
messages.forEach((message) => {
|
|
196
|
+
if (typeof message === 'object' && !Array.isArray(message)) {
|
|
197
|
+
this.extra.push(message)
|
|
198
|
+
} else if (typeof message === 'string') {
|
|
199
|
+
this.extra.push(new ChatMessage(message))
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
}
|
|
213
203
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (this.text) count++
|
|
222
|
-
else if (this.with) count += this.with.length
|
|
204
|
+
/**
|
|
205
|
+
* Returns a clone of the ChatMessage
|
|
206
|
+
* @return {ChatMessage}
|
|
207
|
+
*/
|
|
208
|
+
clone () {
|
|
209
|
+
return new ChatMessage(JSON.parse(JSON.stringify(this.json)))
|
|
210
|
+
}
|
|
223
211
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Returns the count of text extras and child ChatMessages
|
|
214
|
+
* Does not count recursively in to the children
|
|
215
|
+
* @return {Number}
|
|
216
|
+
*/
|
|
217
|
+
length () {
|
|
218
|
+
let count = 0
|
|
219
|
+
if (this.text) count++
|
|
220
|
+
else if (this.with) count += this.with.length
|
|
227
221
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
* @param {Number} idx Index of the part
|
|
231
|
-
* @return {String}
|
|
232
|
-
*/
|
|
233
|
-
getText (idx, lang = defaultLang) {
|
|
234
|
-
// If the index is not defined is is invalid, return toString
|
|
235
|
-
if (typeof idx !== 'number') return this.toString(lang)
|
|
236
|
-
// If we are not a translating message, return the text
|
|
237
|
-
if (this.text && idx === 0) return this.text.replace(/§[0-9a-flnmokr]/g, '')
|
|
238
|
-
// Else return the with child if it's in range
|
|
239
|
-
else if (this.with.length > idx) return this.with[idx].toString(lang)
|
|
240
|
-
// Else return the extra if it's in range
|
|
241
|
-
if (this.extra && this.extra.length + (this.text ? 1 : this.with.length) > idx) {
|
|
242
|
-
return this.extra[idx - (this.text ? 1 : this.with.length)].toString(lang)
|
|
222
|
+
if (this.extra) count += this.extra.length
|
|
223
|
+
return count
|
|
243
224
|
}
|
|
244
|
-
// Not sure how you want to default this
|
|
245
|
-
// Undefined, an error ?
|
|
246
|
-
return ''
|
|
247
|
-
}
|
|
248
225
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
else
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Returns a text part from the message
|
|
228
|
+
* @param {Number} idx Index of the part
|
|
229
|
+
* @return {String}
|
|
230
|
+
*/
|
|
231
|
+
getText (idx, lang = defaultLang) {
|
|
232
|
+
// If the index is not defined is is invalid, return toString
|
|
233
|
+
if (typeof idx !== 'number') return this.toString(lang)
|
|
234
|
+
// If we are not a translating message, return the text
|
|
235
|
+
if (this.text && idx === 0) return this.text.replace(/§[0-9a-flnmokr]/g, '')
|
|
236
|
+
// Else return the with child if it's in range
|
|
237
|
+
else if (this.with.length > idx) return this.with[idx].toString(lang)
|
|
238
|
+
// Else return the extra if it's in range
|
|
239
|
+
if (this.extra && this.extra.length + (this.text ? 1 : this.with.length) > idx) {
|
|
240
|
+
return this.extra[idx - (this.text ? 1 : this.with.length)].toString(lang)
|
|
241
|
+
}
|
|
242
|
+
// Not sure how you want to default this
|
|
243
|
+
// Undefined, an error ?
|
|
244
|
+
return ''
|
|
266
245
|
}
|
|
267
|
-
return message.replace(/§[0-9a-flnmokr]/g, '')
|
|
268
|
-
}
|
|
269
246
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Flattens the message in to plain-text
|
|
249
|
+
* @return {String}
|
|
250
|
+
*/
|
|
251
|
+
toString (lang = defaultLang) {
|
|
252
|
+
let message = ''
|
|
253
|
+
if (typeof this.text === 'string' || typeof this.text === 'number') message += this.text
|
|
254
|
+
else if (this.with) {
|
|
255
|
+
const args = this.with.map(entry => entry.toString(lang))
|
|
256
|
+
const format = lang[this.translate]
|
|
257
|
+
if (!format) message += args.join('')
|
|
258
|
+
else message += vsprintf(format, args)
|
|
259
|
+
} else if (this.translate) {
|
|
260
|
+
message += lang[this.translate]
|
|
261
|
+
}
|
|
262
|
+
if (this.extra) {
|
|
263
|
+
message += this.extra.map((entry) => entry.toString(lang)).join('')
|
|
264
|
+
}
|
|
265
|
+
return message.replace(/§[0-9a-flnmokr]/g, '')
|
|
266
|
+
}
|
|
273
267
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
color: {
|
|
277
|
-
black: '§0',
|
|
278
|
-
dark_blue: '§1',
|
|
279
|
-
dark_green: '§2',
|
|
280
|
-
dark_aqua: '§3',
|
|
281
|
-
dark_red: '§4',
|
|
282
|
-
dark_purple: '§5',
|
|
283
|
-
gold: '§6',
|
|
284
|
-
gray: '§7',
|
|
285
|
-
dark_gray: '§8',
|
|
286
|
-
blue: '§9',
|
|
287
|
-
green: '§a',
|
|
288
|
-
aqua: '§b',
|
|
289
|
-
red: '§c',
|
|
290
|
-
light_purple: '§d',
|
|
291
|
-
yellow: '§e',
|
|
292
|
-
white: '§f'
|
|
293
|
-
},
|
|
294
|
-
bold: '§l',
|
|
295
|
-
italic: '§o',
|
|
296
|
-
underlined: '§n',
|
|
297
|
-
strikethrough: '§m',
|
|
298
|
-
obfuscated: '§k'
|
|
268
|
+
valueOf () {
|
|
269
|
+
return this.toString()
|
|
299
270
|
}
|
|
300
271
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
272
|
+
toMotd (lang = defaultLang, parent = {}) {
|
|
273
|
+
const codes = {
|
|
274
|
+
color: {
|
|
275
|
+
black: '§0',
|
|
276
|
+
dark_blue: '§1',
|
|
277
|
+
dark_green: '§2',
|
|
278
|
+
dark_aqua: '§3',
|
|
279
|
+
dark_red: '§4',
|
|
280
|
+
dark_purple: '§5',
|
|
281
|
+
gold: '§6',
|
|
282
|
+
gray: '§7',
|
|
283
|
+
dark_gray: '§8',
|
|
284
|
+
blue: '§9',
|
|
285
|
+
green: '§a',
|
|
286
|
+
aqua: '§b',
|
|
287
|
+
red: '§c',
|
|
288
|
+
light_purple: '§d',
|
|
289
|
+
yellow: '§e',
|
|
290
|
+
white: '§f'
|
|
291
|
+
},
|
|
292
|
+
bold: '§l',
|
|
293
|
+
italic: '§o',
|
|
294
|
+
underlined: '§n',
|
|
295
|
+
strikethrough: '§m',
|
|
296
|
+
obfuscated: '§k'
|
|
297
|
+
}
|
|
307
298
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
message += this.extra.map(entry => entry.toMotd(lang, this)).join('')
|
|
319
|
-
}
|
|
320
|
-
return message
|
|
321
|
-
}
|
|
299
|
+
let message = Object.keys(codes).map((code) => {
|
|
300
|
+
this[code] = this[code] || parent[code]
|
|
301
|
+
if (!this[code] || this[code] === 'false') return null
|
|
302
|
+
if (code === 'color') {
|
|
303
|
+
// return hex codes in this format
|
|
304
|
+
if (this.color.startsWith('#')) return `§${this.color}`
|
|
305
|
+
return codes.color[this.color]
|
|
306
|
+
}
|
|
307
|
+
return codes[code]
|
|
308
|
+
}).join('')
|
|
322
309
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
'§b': '\u001b[96m',
|
|
337
|
-
'§c': '\u001b[91m',
|
|
338
|
-
'§d': '\u001b[95m',
|
|
339
|
-
'§e': '\u001b[93m',
|
|
340
|
-
'§f': '\u001b[97m',
|
|
341
|
-
'§l': '\u001b[1m',
|
|
342
|
-
'§o': '\u001b[3m',
|
|
343
|
-
'§n': '\u001b[4m',
|
|
344
|
-
'§m': '\u001b[9m',
|
|
345
|
-
'§k': '\u001b[6m',
|
|
346
|
-
'§r': '\u001b[0m'
|
|
310
|
+
if (typeof this.text === 'string' || typeof this.text === 'number') message += `${this.text}§r`
|
|
311
|
+
else if (this.with) {
|
|
312
|
+
const args = this.with.map(entry => entry.toMotd(lang))
|
|
313
|
+
const format = lang[this.translate]
|
|
314
|
+
if (!format) message += args.join('')
|
|
315
|
+
else message += vsprintf(format, args)
|
|
316
|
+
} else if (this.translate) {
|
|
317
|
+
message += lang[this.translate]
|
|
318
|
+
}
|
|
319
|
+
if (this.extra) {
|
|
320
|
+
message += this.extra.map(entry => entry.toMotd(lang, this)).join('')
|
|
321
|
+
}
|
|
322
|
+
return message
|
|
347
323
|
}
|
|
348
324
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
325
|
+
toAnsi (lang = defaultLang) {
|
|
326
|
+
const codes = {
|
|
327
|
+
'§0': '\u001b[30m',
|
|
328
|
+
'§1': '\u001b[34m',
|
|
329
|
+
'§2': '\u001b[32m',
|
|
330
|
+
'§3': '\u001b[36m',
|
|
331
|
+
'§4': '\u001b[31m',
|
|
332
|
+
'§5': '\u001b[35m',
|
|
333
|
+
'§6': '\u001b[33m',
|
|
334
|
+
'§7': '\u001b[37m',
|
|
335
|
+
'§8': '\u001b[90m',
|
|
336
|
+
'§9': '\u001b[94m',
|
|
337
|
+
'§a': '\u001b[92m',
|
|
338
|
+
'§b': '\u001b[96m',
|
|
339
|
+
'§c': '\u001b[91m',
|
|
340
|
+
'§d': '\u001b[95m',
|
|
341
|
+
'§e': '\u001b[93m',
|
|
342
|
+
'§f': '\u001b[97m',
|
|
343
|
+
'§l': '\u001b[1m',
|
|
344
|
+
'§o': '\u001b[3m',
|
|
345
|
+
'§n': '\u001b[4m',
|
|
346
|
+
'§m': '\u001b[9m',
|
|
347
|
+
'§k': '\u001b[6m',
|
|
348
|
+
'§r': '\u001b[0m'
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
let message = this.toMotd(lang)
|
|
352
|
+
for (const k in codes) {
|
|
353
|
+
message = message.replace(new RegExp(k, 'g'), codes[k])
|
|
354
|
+
}
|
|
355
|
+
const hexRegex = /§#?([a-fA-F\d]{2})([a-fA-F\d]{2})([a-fA-F\d]{2})/
|
|
356
|
+
while (message.search(hexRegex) !== -1) {
|
|
357
|
+
// Stolen from https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
|
|
358
|
+
const hexCodes = hexRegex.exec(message)
|
|
359
|
+
// Iterate over each hexColorCode match (§#69420, §#ABCDEF, §#A1B2C3)
|
|
360
|
+
const red = parseInt(hexCodes[1], 16)
|
|
361
|
+
const green = parseInt(hexCodes[2], 16)
|
|
362
|
+
const blue = parseInt(hexCodes[3], 16)
|
|
363
|
+
// ANSI from https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#rgb-colors
|
|
364
|
+
message = message.replace(hexRegex, `\u001b[38;2;${red};${green};${blue}m`)
|
|
365
|
+
}
|
|
366
|
+
return message + '\u001b[0m'
|
|
352
367
|
}
|
|
353
|
-
return message + '\u001b[0m'
|
|
354
|
-
}
|
|
355
368
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
369
|
+
static fromNotch (msg) {
|
|
370
|
+
let toRet
|
|
371
|
+
try {
|
|
372
|
+
toRet = new ChatMessage(JSON.parse(msg))
|
|
373
|
+
} catch (e) {
|
|
374
|
+
toRet = new ChatMessage(msg)
|
|
375
|
+
}
|
|
376
|
+
return toRet
|
|
362
377
|
}
|
|
363
|
-
return toRet
|
|
364
378
|
}
|
|
379
|
+
|
|
380
|
+
ChatMessage.MessageBuilder = MessageBuilder
|
|
381
|
+
return ChatMessage
|
|
365
382
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prismarine-chat",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Wrapper for a minecraft chat message",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "mocha --reporter spec --exit",
|
|
8
8
|
"pretest": "npm run lint",
|
|
9
9
|
"lint": "standard",
|
|
10
10
|
"fix": "standard --fix"
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/PrismarineJS/prismarine-chat#readme",
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"
|
|
27
|
+
"expect": "^27.3.1",
|
|
28
|
+
"mocha": "^9.1.3",
|
|
28
29
|
"prismarine-chat": "file:.",
|
|
29
30
|
"standard": "^16.0.1"
|
|
30
31
|
},
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
"minecraft-data": "^2.62.1",
|
|
33
34
|
"mojangson": "^2.0.1",
|
|
34
35
|
"prismarine-item": "^1.10.0",
|
|
35
|
-
"prismarine-nbt": "^
|
|
36
|
+
"prismarine-nbt": "^2.0.0",
|
|
36
37
|
"sprintf-js": "^1.1.2"
|
|
37
38
|
}
|
|
38
39
|
}
|
package/test/basic.test.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
/* eslint-env
|
|
1
|
+
/* eslint-env mocha */
|
|
2
|
+
|
|
2
3
|
const ChatMessage = require('prismarine-chat')('1.16')
|
|
3
|
-
|
|
4
|
+
const expect = require('expect')
|
|
5
|
+
|
|
6
|
+
it('Parsing a chat message', () => {
|
|
4
7
|
const msg = new ChatMessage({ text: 'Example chat message' })
|
|
5
8
|
expect(msg.toString()).toBe('Example chat message')
|
|
6
9
|
})
|
|
7
|
-
|
|
10
|
+
it('Parsing message that uses language file & numbers', () => {
|
|
8
11
|
const msg = new ChatMessage({ italic: true, color: 'gray', translate: 'chat.type.admin', with: [{ insertion: 'ripwhitescrolls', clickEvent: { action: 'suggest_command', value: '/tell ripwhitescrolls ' }, hoverEvent: { action: 'show_entity', contents: { type: 'minecraft:player', id: '9d9e9257-b812-4332-8426-5e9a0d707392', name: { text: 'ripwhitescrolls' } } }, text: 'ripwhitescrolls' }, { translate: 'commands.clear.success.multiple', with: [256, 2] }] })
|
|
9
12
|
// test as a string
|
|
10
13
|
expect(msg.toString()).toBe('[ripwhitescrolls: Removed 256 items from 2 players]')
|
|
@@ -17,7 +20,17 @@ test('Parsing message that uses language file & numbers', () => {
|
|
|
17
20
|
expect(msg.with[1].with[0].text).toBe(256)
|
|
18
21
|
expect(msg.with[1].with[1].text).toBe(2)
|
|
19
22
|
})
|
|
20
|
-
|
|
23
|
+
it('Parsing a chat message which is an array', () => {
|
|
21
24
|
const msg = new ChatMessage([{ text: 'Example chat ' }, { text: 'message' }])
|
|
22
25
|
expect(msg.toString()).toBe('Example chat message')
|
|
23
26
|
})
|
|
27
|
+
it('Chat Message with a single hex color', () => {
|
|
28
|
+
const msg = new ChatMessage({ text: 'uwu', color: '#FF0000' })
|
|
29
|
+
expect(msg.toMotd()).toBe('§#FF0000uwu§r')
|
|
30
|
+
expect(msg.toAnsi()).toBe('\u001B[38;2;255;0;0muwu\u001B[0m\u001B[0m')
|
|
31
|
+
})
|
|
32
|
+
it('Chat Message with multiple hex colors', () => {
|
|
33
|
+
const msg = new ChatMessage(['', { text: 'uwu ', color: '#FF0000' }, { text: 'owo ', color: '#0000FF' }, { text: 'uwu', color: '#FF0000' }])
|
|
34
|
+
expect(msg.toMotd()).toBe('§r§#FF0000uwu §r§#0000FFowo §r§#FF0000uwu§r')
|
|
35
|
+
expect(msg.toAnsi()).toBe('\u001B[0m\u001B[38;2;255;0;0muwu \u001B[0m\u001B[38;2;0;0;255mowo \u001B[0m\u001B[38;2;255;0;0muwu\u001B[0m\u001B[0m')
|
|
36
|
+
})
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
/* eslint-env
|
|
1
|
+
/* eslint-env mocha */
|
|
2
|
+
|
|
3
|
+
const expect = require('expect')
|
|
2
4
|
|
|
3
5
|
describe('MessageBuilder', () => {
|
|
4
6
|
describe('1.16.5', () => {
|
|
@@ -18,7 +20,7 @@ describe('MessageBuilder', () => {
|
|
|
18
20
|
['Insertion', "Hi I'm inserted!"]
|
|
19
21
|
]
|
|
20
22
|
for (const [prop, val] of properties) {
|
|
21
|
-
|
|
23
|
+
it(`builder#set${prop}`, () => { // ex: builder#setBold
|
|
22
24
|
const msg = new MessageBuilder()[`set${prop}`](val) // ex: .setBold(true)
|
|
23
25
|
const json = msg.toJSON() // ex: { bold: true}
|
|
24
26
|
const propName = prop.toLowerCase() // ex: 'bold'
|
|
@@ -28,13 +30,13 @@ describe('MessageBuilder', () => {
|
|
|
28
30
|
})
|
|
29
31
|
|
|
30
32
|
describe('with/extra', () => {
|
|
31
|
-
|
|
33
|
+
it('no translate w/ .with', () => {
|
|
32
34
|
const msg = new MessageBuilder()
|
|
33
35
|
.addWith('Hello,')
|
|
34
36
|
.addWith('World.')
|
|
35
37
|
expect(msg.toJSON()).toStrictEqual({})
|
|
36
38
|
})
|
|
37
|
-
|
|
39
|
+
it('translate w/ .with', () => {
|
|
38
40
|
const msg = new MessageBuilder()
|
|
39
41
|
.setTranslate('chat.type.text')
|
|
40
42
|
.addWith(new MessageBuilder().setText('U9G'))
|
|
@@ -46,7 +48,7 @@ describe('MessageBuilder', () => {
|
|
|
46
48
|
expect(text).toStrictEqual('<U9G> Hello world')
|
|
47
49
|
})
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
it('w/ .addExtra add split hello & world', () => {
|
|
50
52
|
const msg = new MessageBuilder()
|
|
51
53
|
.addExtra(new MessageBuilder().setText('Hello'))
|
|
52
54
|
.addExtra(new MessageBuilder().setText(' ').setColor('reset'))
|