22
22
* SOFTWARE.
23
23
*/
24
24
25
- import { world , system } from '@minecraft/server'
25
+ import { world , system , ScriptEventSource } from '@minecraft/server'
26
26
27
27
namespace IPC {
28
28
let ID = 0
@@ -45,10 +45,10 @@ namespace IPC {
45
45
export namespace FRAGMENTATION {
46
46
/**
47
47
* @description Used when fragmenting data strings
48
- * @default 1024
48
+ * @default 2048
49
49
* @warning Modify only if you know what you're doing, incorrect values can cause issues
50
50
*/
51
- export let MAX_STR_LENGTH : number = 1024
51
+ export let MAX_CMD_LENGTH : number = 2048
52
52
}
53
53
}
54
54
@@ -262,7 +262,7 @@ namespace IPC {
262
262
const buffer = new Map < number , { size : number ; payloads : Payload [ ] } > ( )
263
263
return system . afterEvents . scriptEventReceive . subscribe (
264
264
event => {
265
- if ( event . id === `ipc:${ event_id } ` ) {
265
+ if ( event . id === `ipc:${ event_id } ` && event . sourceType === ScriptEventSource . Server ) {
266
266
const p : Payload . Packed = JSON . parse ( decodeURI ( event . message ) )
267
267
if ( p [ 0 ] === channel ) {
268
268
const payload : Payload = Payload . fromPacked ( p )
@@ -288,21 +288,50 @@ namespace IPC {
288
288
}
289
289
290
290
function emit ( event_id : string , channel : string , args : any [ ] ) {
291
- const data_fragments : string [ ] =
292
- JSON . stringify ( args ) . match ( new RegExp ( `.{1,${ CONFIG . FRAGMENTATION . MAX_STR_LENGTH } }` , 'g' ) ) ?? [ ]
293
- const payload_strings = data_fragments
294
- . map ( ( data , index ) => {
295
- return data_fragments . length > 1
296
- ? index === data_fragments . length - 1
297
- ? { channel : channel , id : ID , data : data , index : index , final : true }
298
- : { channel : channel , id : ID , data : data , index : index }
299
- : { channel : channel , id : ID , data : data }
291
+ const CMD = ( payload : Payload ) => `scriptevent ipc:${ event_id } ${ encodeURI ( Payload . toString ( payload ) ) } `
292
+ const cmd = CMD ( { channel : channel , id : ID , data : '' } )
293
+ const args_str = JSON . stringify ( args )
294
+ const chars = Array . from ( args_str )
295
+ const enc_chars = ( function ( chars : string [ ] ) {
296
+ let r : string [ ] = [ ]
297
+ let acc : string = ''
298
+ chars . forEach ( c => {
299
+ if ( c === '\\' && acc . length === 0 ) {
300
+ acc += c
301
+ } else {
302
+ r . push ( encodeURI ( acc + c ) )
303
+ acc = ''
304
+ }
300
305
} )
301
- . map ( payload => Payload . toString ( payload ) )
306
+ return r
307
+ } ) ( Array . from ( JSON . stringify ( args_str ) ) )
308
+
309
+ const payloads : Payload [ ] = [ ]
310
+ let str = ''
311
+ let enc_str_len = 0
312
+ for ( let i = 0 ; i < chars . length ; i ++ ) {
313
+ const enc_char = enc_chars [ i + 1 ]
314
+ const cmd_len = enc_str_len + enc_char . length + cmd . length + `,${ payloads . length } ,1` . length
315
+ if ( cmd_len < CONFIG . FRAGMENTATION . MAX_CMD_LENGTH ) {
316
+ str += chars [ i ]
317
+ enc_str_len += enc_char . length
318
+ } else {
319
+ payloads . push ( { channel : channel , id : ID , data : str , index : payloads . length } )
320
+ str = chars [ i ]
321
+ enc_str_len = enc_char . length
322
+ }
323
+ }
324
+
325
+ if ( payloads . length === 0 ) {
326
+ payloads . push ( { channel : channel , id : ID , data : str } )
327
+ } else {
328
+ payloads . push ( { channel : channel , id : ID , data : str , index : payloads . length , final : true } )
329
+ }
330
+
302
331
system . runJob (
303
332
( function * ( ) {
304
- for ( const string of payload_strings ) {
305
- world . getDimension ( 'overworld' ) . runCommand ( `scriptevent ipc: ${ event_id } ${ encodeURI ( string ) } ` )
333
+ for ( const payload of payloads ) {
334
+ world . getDimension ( 'overworld' ) . runCommand ( CMD ( payload ) )
306
335
yield
307
336
}
308
337
} ) ( )
0 commit comments