@@ -32,6 +32,7 @@ import net.silkmc.silk.core.annotations.ExperimentalSilkApi
32
32
import net.silkmc.silk.core.event.Events
33
33
import net.silkmc.silk.core.event.Server
34
34
import net.silkmc.silk.core.logging.logError
35
+ import net.silkmc.silk.core.task.mcSyncLaunch
35
36
import net.silkmc.silk.core.task.silkCoroutineScope
36
37
import org.jetbrains.kotlinx.multik.api.linalg.dot
37
38
import org.jetbrains.kotlinx.multik.api.mk
@@ -204,6 +205,11 @@ class MinecraftComposeGui(
204
205
val updateData = MapItemSavedData .MapPatch (startX, startY, width, height, packetColors)
205
206
return ClientboundMapItemDataPacket (mapId, 0 , false , null , updateData)
206
207
}
208
+
209
+ fun createClearPacket (): ClientboundMapItemDataPacket {
210
+ val updateData = MapItemSavedData .MapPatch (0 , 0 , 128 , 128 , ByteArray (128 * 128 ))
211
+ return ClientboundMapItemDataPacket (mapId, 0 , false , null , updateData)
212
+ }
207
213
}
208
214
209
215
private val coroutineContext = Executors .newSingleThreadExecutor().asCoroutineDispatcher()
@@ -292,14 +298,13 @@ class MinecraftComposeGui(
292
298
293
299
scene.render(canvas, System .nanoTime())
294
300
295
- val networkHandler = player.connection
301
+ val connection = player.connection
296
302
297
303
coroutineScope {
298
304
for (xFrame in 0 until blockWidth) {
299
305
for (yFrame in 0 until blockHeight) {
300
306
launch(Dispatchers .Default ) {
301
307
val guiChunk = getGuiChunk(xFrame, yFrame)
302
- val mapId = guiChunk.mapId
303
308
304
309
for (x in 0 until 128 ) {
305
310
for (y in 0 until 128 ) {
@@ -308,29 +313,31 @@ class MinecraftComposeGui(
308
313
}
309
314
}
310
315
311
- // send the map data
312
- val updatePacket = guiChunk.createPacket()
313
- if (updatePacket != null ) {
314
- networkHandler.send(updatePacket)
315
- }
316
-
317
316
if (! placedItemFrames) {
318
317
val framePos = position.below(yFrame).relative(placementDirection, xFrame)
319
318
320
319
// spawn the fake item frame
321
320
val itemFrame = GlowItemFrame (player.level, framePos, guiDirection)
322
321
itemFrame.isInvisible = true
323
- networkHandler .send(itemFrame.addEntityPacket)
322
+ connection .send(itemFrame.addEntityPacket)
324
323
withContext(limitedDispatcher) {
325
324
itemFrameEntityIds + = itemFrame.id
326
325
}
327
326
328
327
// put the map in the item frame
329
328
val composeStack = Items .FILLED_MAP .defaultInstance.apply {
330
- orCreateTag.putInt(" map" , mapId)
329
+ orCreateTag.putInt(" map" , guiChunk. mapId)
331
330
}
332
331
itemFrame.setItem(composeStack, false )
333
- networkHandler.send(ClientboundSetEntityDataPacket (itemFrame.id, itemFrame.entityData, true ))
332
+ connection.send(ClientboundSetEntityDataPacket (itemFrame.id, itemFrame.entityData, true ))
333
+
334
+ connection.send(guiChunk.createClearPacket())
335
+ }
336
+
337
+ // send the map data
338
+ val updatePacket = guiChunk.createPacket()
339
+ if (updatePacket != null ) {
340
+ connection.send(updatePacket)
334
341
}
335
342
}
336
343
}
@@ -410,11 +417,25 @@ class MinecraftComposeGui(
410
417
silkCoroutineScope.launch {
411
418
withContext(guiContext) {
412
419
player.connection.send(ClientboundRemoveEntitiesPacket (* itemFrameEntityIds.toIntArray()))
413
- MapIdGenerator .makeOldIdAvailable(guiChunks.map { it.mapId })
414
420
415
- frameDispatcher.cancel()
416
- scene.close()
421
+ try {
422
+ frameDispatcher.cancel()
423
+ scene.close()
424
+ } finally {
425
+ coroutineScope {
426
+ guiChunks.forEach {
427
+ mcSyncLaunch {
428
+ if (! player.hasDisconnected()) {
429
+ player.connection.send(it.createClearPacket())
430
+ }
431
+ }
432
+ }
433
+ }
434
+
435
+ MapIdGenerator .makeOldIdsAvailable(guiChunks.map { it.mapId })
436
+ }
417
437
}
438
+
418
439
guiContext.cancel()
419
440
guiContext.close()
420
441
}
0 commit comments