February 22nd 2018 Patch
Before I begin, no, this is not tonight's nightly build. This is another patch. I figured out multiple things from last night's build. First, I released the wrong build. I was releasing AnyCPU builds of the game instead of x86 builds that actually had the code changes I intended to release. Secondly I learned that console logs can go a very long way for debugging when you read into them.
Using the logs that one of you sent me (username JPlexer on our discord, thank you!! :D) I was able to determine the cause of the "starting internal server" bug.
Basically, it was caused by the game's internal server not finding any backend modules or request handlers - and this includes the handler for the server handshake routines. The server was starting and the game was connecting, but the server didn't know how to respond to the game! So it was just throwing errors that the game wasn't programmed to properly handle - it was just suppressing them. So now we know what's going on with the bug and...what caused it.
But that begs the question, what is causing the server not to find any of its request handlers? Well, that puzzled me...there wasn't any error in the logs I got that suggested anything that would cause that.
...That is, until I looked at the ReflectMan log. For those who don't know, ReflectMan is a tiny C# library integrated into our Peace Engine and in Peacenet's server software. It was also integrated into ShiftOS. It is written by Declan Hoare (a.k.a RogueAI), and is a utility that looks through all the assemblies in your executable's directory (EXEs or DLLs), and grabs information about every single class, structure, interface or enumeration in every assembly it can find - and puts this information in a handy database in memory that you can query using C#'s LINQ library.
This allows me to do things like "Find every single class in the database that is a Window" and it'll give me a list of types that inherit from the Window class.
ReflectMan is also an error-suppressing library in the sense that when it has an error loading an assembly (either it's not a .NET assembly, or some other issue), it skips loading that assembly and logs the error to the console. That way, your app can continue loading up even if it's missing a few things in ReflectMan's database...and if there IS a fatal error, you know what it was by looking in the console.
And BOY, there was a fatal error in JPlexer's log. ReflectMan was hitting a .NET CAS protection issue when loading Peacenet.Backend.dll, where all the server components and request handlers are stored. If you're not familiar with CAS, it is basically Windows SmartScreen for .NET Reflection. Although it is deprecated because it has no real use cases, basically, what it does, is when you try to load an assembly through Reflection that isn't directly referenced by your app, and .NET doesn't trust this assembly, CAS will kick in and prevent you from loading it.
This explains why the game loads up into the menu just fine, but the server doesn't start properly.
Though, there is a workaround that you can use by placing a config entry in your project's "app.config" file (or, in our case, Peacenet.exe.config" that tells .NET to disable CAS protection and load untrusted types anyway. This patch adds that config entry. As soon as we added it, the CAS errors went away, and the server started up properly.
Leave a comment
Log in with itch.io to leave a comment.