
*NEW* VM computers
This project adds working computers as virtual machines in Minecraft, this is a fan made port of original VM computers by Delta2Force
(DEPRECATED) *NEW* VM computers 1.4.15-1.20.1-fabric-vbox-7+-fix
Список изменений
Changelog
[1.4.16-1.20.1-fabric] - 2026-05-09
Security & Critical Bug Fixes
-
Fixed UUID mismatch in multiplayer screen texture cleanup (
ClientMod.java)S2C_STOP_SCREENandS2C_SCREENwere usingmcc.player.getUuid()forremove()instead ofpcOwner.- This caused screen textures from other players to never be destroyed, leading to a severe memory leak (
NativeImage,NativeImageBackedTexture,Identifier). - Also fixed a double-close bug where
vmScreenTextureNI.close()was called instead ofvmScreenTextureNIBT.close()inS2C_SCREEN.
-
Fixed component loss when placing last PC case from stack (
ItemPCCase.java,ItemPCCaseSidepanel.java)decrement(1)was called before reading NBT data. Whencount == 1, the stack becameEMPTYandgetNbt()returnednull, causing permanent loss of all PC components (motherboard, CPU, RAM, HDD, ISO).- Now NBT is saved to a local variable before decrementing.
-
Fixed server crash on missing inventory item (
MainMod.java)removeStck()threwRuntimeExceptionwhen an item was not found, crashing the entire server.- Replaced with logging via
LOGGER.error()and graceful return. - Also hardened against desync between
contains()check andremoveStck()execution.
-
Fixed ClassCastException exploit in C2S_ORDER (
MainMod.java)- No validation that
readItemStack().getItem()is actually anOrderableItem. A malicious client could send any item, causing a server crash. - Added
instanceof OrderableItemcheck with logging of invalid packets. - Same fix applied to
S2C_SYNC_ORDERhandler inClientMod.java.
- No validation that
-
Fixed IllegalArgumentException in C2S_ADD_CPU / C2S_ADD_RAM (
MainMod.java)- When
dividedByormbvalues did not match expected constants,lookingForremainednull, causingnew ItemStack(null)→ server crash. - Added
lookingFor != nullguard before creatingItemStack.
- When
-
Fixed HDD removal ignoring NBT (
MainMod.java)removeStck()matched only byItemtype, not NBT. If a player had multiple HDDs with different VHD files, the wrong disk could be removed.- Enhanced
removeStck()to prefer exact NBT match before falling back to type-only match.
-
Fixed VM always created with only 1 CPU (
GuiPCEditing.java)Math.min(1, ...)in the "create new VM" branch always returned1, regardless of host CPU count or player settings. The "modify existing" branch already used correctMath.max(1, ...).- Fixed to
Math.max(1, ...)— VM now gets the correct number of CPUs.
-
Fixed ConcurrentModificationException in ServerMixin (
ServerMixin.java)MainMod.orders.remove()was called duringfor-eachiteration overHashMap.values(), guaranteeing a crash every time an order completed.- Implemented deferred removal: collect keys to remove in a list, then delete after the loop.
-
Fixed NPE when sending packets to disconnected players (
ServerMixin.java)playerManager.getPlayer()could returnnullif a player logged out. Calling.getWorld()orServerPlayNetworking.send(null, ...)caused NPE.- Added null checks before all
getPlayer()usages.
-
Fixed deadlock in insertISO (
GuiPCEditing.java)wait()withoutwhileloop and without timeout — ifnotify()was called beforewait(), the thread hung forever.- Replaced with
while (condition) { lock.wait(5000); }pattern using a sharedClientMod.VM_TURNING_ON_LOCK. - Also fixed the case where a new
GuiPCEditinginstance had a different monitor object than the onenotify()was called on.
-
Fixed busy-wait burning 100% CPU in turnOffPC (
GuiPCEditing.java)while(ClientMod.vmTurningOn) {}was an infinite spin-loop.- Replaced with
Thread.sleep(50)inside the loop. Also addedvolatiletovmTurningOnso the thread actually sees state changes.
-
Fixed Timer thread leak in GuiFocus (
GuiFocus.java)- A new
Timerwas created every timeGuiFocusopened, butcancel()was only called onNullPointerException(singleplayer). In multiplayer, timers leaked indefinitely. - Timer is now stored as a field and cancelled in
removed().
- A new
-
Fixed NPE-based control flow in singleplayer (
GuiFocus.java)getCurrentServerEntry().addressthrows NPE in singleplayer. The code usedcatch(NullPointerException)as control flow.- Replaced with explicit
== nullcheck.
-
Fixed resource leak in VBoxManage (
VBoxManage.java)BufferedReaderandInputStreamwere not closed infinally, leaking file descriptors on exceptions.- Wrapped in
try-with-resources.
-
Fixed FileWriter not closed on exception (
ClientMod.java)increaseVHDNum()opened aFileWriterwithouttry-with-resourcesorfinally. On any exception, the file handle leaked.- Wrapped in
try-with-resources.
-
Fixed Unpooled.buffer() leaks across all packet handlers
new PacketByteBuf(Unpooled.buffer())was used inClientMod.java,GuiPCEditing.java,ServerMixin.java, andPlayerManagerMixin.javainstead ofPacketByteBufs.create().- Replaced all instances with the proper Fabric API method.
-
Fixed regex bug in hard drive selection (
GuiCreateHarddrive.java)split(" | ")treated" | "as a regex (space OR space), effectively equivalent tosplit(" ").- Any VHD filename containing a space was broken. Replaced with
indexOf(" | ")+substring()for literal matching.
-
Fixed iron ingot overpayment loss (
EntityDeliveryChest.java)- When a player overpaid,
is.increment()was called on an already-emptyItemStack(afterdecrement()), causing the excess ingots to be permanently lost. - Fixed by saving the count before
decrement(), then creating a newItemStackfor the refund and usingplayer.getInventory().offerOrDrop().
- When a player overpaid,
-
Fixed matrix stack imbalance on exception (
HeldItemMixin.java)matrices.push()in HEAD andmatrices.pop()in TAIL were not atomic. An exception between them left the stack unbalanced.- Wrapped rendering in
try-finallyto guaranteematrices.pop().
-
Fixed NBT key inconsistency (
EntityPC.java,ItemPCCase.java,ItemPCCaseSidepanel.java)- Constructor used different NBT keys (
x64,MoboInstalled,GPUInstalled,RAMSlot0,VHDName,ISOName) thanreadCustomDataFromNbt/writeCustomDataToNbt(X64,MotherboardInstalled,GpuInstalled,GbRamSlot0,HardDriveFileName,IsoFileName). - This worked only because the two paths never crossed, but was a refactoring minefield.
- Unified all keys to match
writeCustomDataToNbtformat. Added backward compatibility in constructor to read both old and new keys.
- Constructor used different NBT keys (
New Features
-
Transition to VBoxManage CLI (VBox CLI)
- Replaced the deprecated VirtualBox JWS (Java Web Services) API with a new
VBoxManage.javawrapper that calls theVBoxManagecommand-line tool directly. - The JWS API was removed in VirtualBox 7.0+, making the old mod completely incompatible with modern VirtualBox installations.
- All VM operations are now performed via CLI:
createVm,modifyVm,startVm,powerOffVmstorageAttach,addStorageController,removeStorageControllermountMedium,unmountMediumputScancodes,putMouseEventtakeScreenshotgetVmState,vmExists,discardSavedState
- Added
executeSilent()for optional operations that may fail on newer VBox versions (e.g.,--accelerate2dvideoin VBox 7.x). - Added connection test (
testConnection()) and version detection (getVersion()).
- Replaced the deprecated VirtualBox JWS (Java Web Services) API with a new
-
Support for VirtualBox 7.x and newer
- VBox 7.0+ removed
vboxwebsrv(the SOAP web service). The mod now works with any VirtualBox version that providesVBoxManage. - Added parsing of
showvminfo --machinereadableoutput for medium attachment state, compatible with VBox 7.x output format. --accelerate2dvideois now handled silently (ignored if unsupported) instead of crashing.
- VBox 7.0+ removed
Performance Improvements
-
Added
volatileto all cross-thread shared state (ClientMod.java)vmTurnedOn,vmTurningOn,vmTurningOff,vmUpdateThread,vmTextureBytes,vmTextureBytesSize.- Prevents infinite busy-waits and race conditions between the render thread and VM update thread.
-
Added
synchronizedto texture byte transfers (VMRunnable.java+ClientMod.java)vmTextureBytes/vmTextureBytesSizewere updated in one thread and read in another without any synchronization, risking torn reads.- Added
VM_TEXTURE_LOCKwith propersynchronizedblocks on both write (VM thread) and read (render thread) sides.
-
Added
synchronizedto tablet texture streaming (TabletOS.java)byteArrayInputStreamwas written by the tablet renderer thread and read by the main render thread without synchronization.- Added
TEXTURE_SYNClock with local copy pattern.
-
Throttled
isMediumEjected()polling (GuiPCEditing.java)- Previously called
VBoxManage showvminfoevery frame (~60 times/second), spawning a new OS process each time. - Now checks every 2 seconds, reducing CPU and disk load by ~99%.
- Previously called
-
Throttled tablet renderer (
GameloopMixin.java)- Tablet renderer
while(true)loop had noThread.sleep(), pinning a CPU core at 100%. - Added
Thread.sleep(33)for ~30 FPS cap. - Also replaced silent
ConcurrentModificationExceptionswallowing with proper logging.
- Tablet renderer
-
Reduced S2C_SYNC_ORDER network spam (
ServerMixin.java)- Order sync packet was sent 20 times/second per order regardless of whether status changed.
- Now tracks
lastSyncedStatusand only sends the packet when the status actually changes.
Architecture & Code Quality
-
Proper use of
PacketByteBufs.create()throughout- Eliminates manual buffer lifecycle management and potential leaks.
-
Added SLF4J/Log4j logging (
MainMod.java)- Replaced
RuntimeExceptionserver crashes withLOGGER.error()for inventory desync events.
- Replaced
-
Backward compatibility for old NBT saves
- Old PC cases placed in the world before this update will still load correctly thanks to dual-key reading in
EntityPCconstructor.
- Old PC cases placed in the world before this update will still load correctly thanks to dual-key reading in
