Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

A working Minecraft 1.8.9 server implemented entirely in Outlook VBA. Real client with a real protocol and no server software. The process listening on port 25565 is OUTLOOK.EXE.

You start it by emailing yourself the word START. You stop it by emailing yourself STOP. While it's running, the server status lands in a mail folder as a post that updates in place, and every connect, join and disconnect arrives as its own unread item.

This is the second one. The first was Excel, and this is the same protocol code with the display layer rewritten, because the interesting part of Outlook isn't that it can open a socket, it's that the control surface is your inbox.

Why

There have been a fair amount of Minecraft clones inside Office apps. Nobody had made one speak the actual protocol so a real client can connect and because an email client is the last thing in the you'd expect to be listening on a port.

If someone got here first, I'd like to see it.

What it does

Server list ping with MOTD, player count and a favicon. Offline-mode login, no encryption. Flat world, 5x5 chunks of bedrock, dirt and grass. Creative mode, so you can fly and place things. Keep-alives, so the session survives longer than 20 seconds. Live player position and packet counts written into a mail item, including a top-down ASCII map of where you're standing (which is useless in realtime really because it just refreshes every time you move and puts you back at the top of the email).

Start and stop by email, which is the whole point.

What it doesn't do

Almost everything else. No block updates on the server side, no entities, no mobs, no real physics, no chat commands, no second player. Blocks you place exist only in your client.

It's a server in the sense that a client connects to it and receives a world. Set your expectations accordingly.

Requirements

Windows, with classic Outlook. New Outlook has no VBA at all, so if Alt+F11 does nothing, that's why. If classic isn't installed (C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.exe) you'll need to install it separately, since new Microsoft 365 installs no longer ship it by default.

Minecraft Java 1.8.9, protocol 47.

Setup

Download OutlookMCServer.bas. Alt+F11 for the VB Editor, then File > Import File. Outlook has one VBA project for the whole profile rather than one per document, so there's no workbook to create.

File > Options > Trust Center > Trust Center Settings > Macro Settings, enable macros, restart Outlook. There's no yellow bar to click like in Excel.

Ctrl+G for the Immediate window, type Setup, Enter. That creates the Minecraft Server folder under your Inbox.

Then paste this into ThisOutlookSession, which is separate from the module and sits under Microsoft Outlook Objects in the tree:

Private WithEvents mCtrl As Outlook.Items

Private Sub Application_Startup()
    Set mCtrl = Application.Session.GetDefaultFolder(6).Items
End Sub

Private Sub Application_Quit()
    RequestStop
End Sub

Private Sub mCtrl_ItemAdd(ByVal Item As Object)
    On Error Resume Next
    Dim s As String
    s = UCase$(Trim$(Item.Subject))
    If s = "START" Then
        Item.Delete
        RequestStart
    ElseIf s = "STOP" Then
        Item.Delete
        RequestStop
    End If
End Sub

Restart Outlook, because Application_Startup only fires on launch. Then email yourself with the subject START and an empty body. The message deletes itself and the server comes up.

Optional: put a 64x64 PNG called favicon.png in the same folder as the .bas and it'll show in the server list. Must be exactly 64x64 or the client drops it.

If you'd rather not use email, add StartServer and StopServer to the Quick Access Toolbar via File > Options > Quick Access Toolbar with Macros selected in the dropdown.

How it works

The Declare PtrSafe block at the top binds to ws2_32.dll, Windows' sockets library. Every program on Windows that touches the network goes through it, Java included.

Everything above that is written from nothing, because no VBA library for any of this exists.

VarInts. The protocol's variable width integer format. Needs an unsigned right shift, which VBA doesn't have, so URShift7 fakes it.

Packet framing. Length, then packet ID, then payload. TCP is a stream and not a sequence of messages, so packets arrive split across reads or several at once.

Endianness. The protocol is big-endian, x86 is little-endian, so every multi-byte number gets reversed. Doubles and floats go through CopyMemory because there's no other way to see their bytes in VBA.

Chunks. The reason this targets 1.8.9 and not a current version. In 1.8, a chunk section is a flat array of (id << 4) | meta shorts, then block light, then sky light. 12,544 bytes for one section plus biome data, and you can send it uncompressed. Modern versions use palette-encoded, bit packed longs and expect zlib. VBA has no zlib. That's a whole different project.

The timer, which is the part that differs from the Excel version. Excel could get away with a blocking loop and DoEvents, because you only ever needed to look at one sheet. Outlook can't. A blocking loop freezes the whole client, and calling a never-returning routine from a mail event handler is not something Outlook supports. So the server runs on a Windows SetTimer callback instead: every 20ms it does one pass of accept, read, flush and keep-alive, then returns. Outlook stays fully usable while it's serving, and starting it from an email handler becomes legitimate rather than something that works until it doesn't.

Outbound bytes are queued rather than pushed. The join sequence is 314KB and a non-blocking socket won't take that in one go, so it drains a bit per tick. The status readout shows the queue emptying.

Things that went wrong, for the benefit of anyone attempting this

VBA is case-insensitive, so a constant called CTRLFOLDER and a function called CtrlFolder are the same name. Ambiguous name detected and it took a minute.

Module-level variables have to be declared at the top of the module, above every procedure. Put one at the bottom and nothing compiles.

WSAGetLastError has to be captured immediately. Calling it after a log write or a disconnect reads a code that intervening API calls have already overwritten, so every socket error I logged was potentially the wrong one.

Saving an Outlook item pumps the message loop, which means a timer tick can fire inside another timer tick and corrupt the buffers. There's a re-entrancy guard for this. It would otherwise be an intermittent crash.

An unhandled error inside an AddressOf callback kills the host process, so the timer callback traps everything.

Exchange runs mail rules server-side, so a rule that files your START email into a folder means ItemAdd never fires. Watch the Inbox directly and let the handler delete the message instead.

Running it from a Mac

Windows in a VM. Two things will get you.

macOS blocks apps from reaching the local network until you grant permission, and reports the refusal as NoRouteToHost. Every test from Terminal works, because Terminal already has the grant. Relay through Terminal instead:

socat TCP-LISTEN:25565,fork,reuseaddr TCP::25565

Then connect to localhost:25565.

And bridged networking over WiFi is unreliable, because a bridged guest presents a second MAC through one wireless association and access points often won't reflect frames back to the same client. Symptom is socat reporting "Host is down" and arp showing incomplete, while the VM itself can ping the gateway perfectly well. Restarting the VM fixes it.

Licence

MIT. Do what you like with it.

About

No description, website, or topics provided.

Resources

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages