Well, being that we don't have the server code, it wouldn't matter if it were a mess. To emulate it, you'd have to start from scratch, basically seeing what the client sends and trying to figure out what needs to be sent in response. It's still a monumental amount of work.
To amplify what Codewalker said, I need to point out that no amount of C++ classes and working on that thing at work that does that other thing really helps you understand how MMOs work in general and how City of Heroes works in particular. This should be a mantra. Once you have that repeating in a loop in the back of your mind, gnaw on this for a while: the CoH client isn't a "dumb" client: Paragon Chat itself demonstrates this. It would be an oversimplification but an illustrative one to say that the CoH client is 25% client and 75% server, while the game servers were 75% server and 25% metaserver.
If that doesn't make sense, imagine City of Heroes was composed of three components. One part was the human interface that took input from the users and displayed output in various ways. One part was the "laws of physics" that controlled how the game world worked. And one part was the "script" that was like the hand of God putting pieces on the board and telling them what to do. The game server had the last two pieces. The game client has the first two pieces. They share the second piece so that the game client and the game server both have some idea of what is going on in the world, and try to keep them in sync.
The game client knows that there's a wall over there, so you can't run through it. The game server knows there's a wall over there, so it knows you won't run through it. The game client knows what the player is trying to do, and predicts what is likely to happen next throughout the world. The game server knows what is going to happen next throughout the world and predicts what the player is likely to do next. They try to stay in sync, and when they fall out of sync you get rubberbanding.
This critical overlap part of the software governs a lot of rules about how the world works, and makes it extremely tricky to replace either one with something else. Both the game client and the game server have a "mental model" of how the world works, and any attempt to replace the game servers with something else the client will work with (or hypothetically to replace the game client with something else that would work with the servers) must be able to exactly replicate that mental model, warts and all, or the whole thing won't work right.
90% of all the issues with Codewalker developing Paragon Chat are likely explicitly attempting to make Paragon Chat "understand" this "mental model" that is built into the client and anything that talks to the client must obey. This is what I would refer to on the official forums as a "non-trivial problem."
So you do not need to replicate the strangeness in the literal code of the game servers if you are writing them from scratch. But you must somehow replicate the weirdness they implemented, at least in all of the parts of the game that exist within the "mental model" part of the code. Like, for example, how to get the client to believe an entity should "con red." It apparently isn't about setting the "display name in red" flag. It is about convincing the client's mental model of the world that that entity is something that should show up with a red name so the client does that automatically because it thinks it should.
There's an analogy from the world of biology. At one time, people thought that the neurons of the brain activated by either triggering a signal or not triggering a signal. We now know that is not how neurons work. They work by constantly sending signals and it is the *rate* of firing that determines whether they will trigger a neighboring neuron to fire. It isn't off/on, it is bang-bang or bang-bang-bang-bang.
My understanding is that some of CoH was static: you set this or you unset that. But some of it was dynamic: you have to send this every second to make this happen, or constantly set that to prevent this from happening. And sometimes which way it works depends on the mood of the original programmer when they wrote the code. You can't just look at what the client sends and try to figure out what the correct response is because the communications between client and server are way more dynamic than that.