-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Realm #18
base: develop
Are you sure you want to change the base?
Realm #18
Conversation
…rd for logging onto expansion character with d2dv
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not implementing games or ladder yet
That's fine.
It turns out MCP does send a protocol byte, except it's 0x01, so I stuck it on a different socket; I chose port 6113 because it's what pvpgn uses
That's fine.
Do you want the name "Olympus" as a setting?
Yes.
Sending a statstring for EID_USERUPDATE causes a rather esoteric rendering bug in Diablo II
We could make not sending it only a D2DV/D2XP thing if it's expected for other products
It's expected that only users on the same product as the initiator will receive other users' EID_USERUPDATE messages, I believe. Spht may know more specifically on that. I'd be fine with D2DV/D2XP having special behavior if it's warranted, but only for statstring, as flag updates still need to occur for when a user gains channel operator after /designate or becomes channel speaker, etc.
Take a look at SID_ENTERCHAT lines 73-90, see comment
Seems fine. Behavior is unchanged for now which I'm happy with. The comment seems like future work/todo.
The SID_LOGONREALMEX response has to send an IP address, I did a quick lookup but it's not exactly ideal...lmk if you're already getting this somewhere or you want a different solution (see NetworkUtilities.cs)
I've commented already but the URL that it tries needs to be made configurable and it needs a discriminator for the type of IP address it uses to learn its public IP address.
I'm using a bunch of static but essentially random values for the MCP chunks (only actually relying on the cookie), not sure what you want to do here
Not sure either. Seems like future work/todo. Static is fine at this stage where not everything is implemented.
I had to essentially duplicate several classes: Message, Frame, one of the exceptions, the ServerSocket, etc.; any or all of these could be much more DRY with a refactor, lmk what you think (feels icky)
I've left comments throughout those files. Please address them. DRY would be better, it is icky right now.
There are a handful of places I want to decompose into functions, add helpers, etc. - planning to hit that in my next pass of refactors if that's cool
I disagree with the premise of the ByteHelpers. I really want to look over each reason why you're adding one. The .NET standard library and C# language provide a lot already.
I left a couple pieces of commented out code as reminders for places I need to treat when I add games and ladder
Seems fine.
There are like 4-5 areas where I found the bnetdocs documentation could be improved, I can submit these later and trim out my comments
You asked to be made an editor on BNETDocs. I've already discussed this with you over Discord. I am not the sole decision maker on that. @nmbook and @Davnit also need to weigh their opinion as they are BNETDocs Staff, together all three of us make up a quorum. We've had editors make changes on the site without consultation and those changes ended up needing to be reversed, and I've made unilateral decisions in the past without asking others that ended up going bad for me. Fundamentally, I believe we'd rather moderate by having new changes made by the existing editors we have now. I'm open to opinions.
{ | ||
var partial = new byte[][] | ||
{ | ||
"Olympus".ToBytes(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be made into a configurable. Perhaps you want to use this?
var realmName = Settings.GetString(new string[] { "realm", "name" });
{ | ||
public static string GetPublicAddress() | ||
{ | ||
WebRequest request = WebRequest.Create("https://api.ipify.org"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded url should be made into a configurable option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Around this line, there should also be a discriminator for IPv4, as the endpoint/url that a user may enter (or even override with their own DNS or hosts file) could contain an Dual-Stack (IPv4+IPv6 / A+AAAA) record.
Since Battle.net protocols only support IPv4, Atlas should make sure it only takes the IPv4 address, if both IPv4 and IPv6 are available from DNS, and it should error or give an empty/null/none result if there is only an IPv6 address with no IPv4 address from DNS or if DNS resolution fails.
|
||
namespace Atlasd.Helpers | ||
{ | ||
public static class BytesHelper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class seems fundamentally not necessary, as C# and .NET 3.1 already provide for many of the bit and byte helpers with BitConverter
to start.
The methods below, GetBytes, AsString, ToBytes, that extend UInt32[], IPAddress, byte[], and strings, already exist elsewhere via the .NET namespaces.
Further, AsString() and ToBytes() assumes a UTF8 encoding and does not contain a parameter to set the encoding, not all of Battle.net supported UTF8 and there are components of the protocol that in fact used Latin1 (ISO-8859-1) encoding, despite Atlas's incorrect emulation only using UTF8. Any improvement to the general helpfulness of converting strings to byte arrays and byte arrays to strings, should include an encoding parameter at minimum, though again this entire class seems not necessary.
@@ -85,6 +85,7 @@ public static void WriteLine(LogLevel level, LogType type, string buffer) | |||
if (level > CurrentLogLevel) return; | |||
|
|||
Console.Out.WriteLine($"[{DateTime.Now}] [{LogLevelToString(level)}] [{LogTypeToString(type).Replace("_", "] [")}] {buffer}"); | |||
Console.Out.Flush(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the performance of always calling Flush() when Debug log-level is set on a busy server.
SetLocalEndPoint(localEndPoint); | ||
} | ||
|
||
public void Dispose() /* part of IDisposable */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be refactored. It was copied from the original ServerSocket which is also wrong.
https://learn.microsoft.com/en-us/dotnet/api/system.idisposable?view=netcore-3.1
tl;dr - It needs to only Dispose during special conditions relating to the garbage collector, which this does not even consider.
@@ -75,15 +77,84 @@ public override bool Invoke(MessageContext context) | |||
* (STRING) Battle.net unique name (* as of D2 1.14d, this is empty) | |||
*/ | |||
|
|||
Buffer = new byte[8]; // MCP Cookie + MCP Status only; Atlas does not have realm/MCP servers implemented yet. | |||
if (((byte[])context.Arguments["realmTitle"]).AsString() == "Olympus") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it configurable
@@ -5,6 +5,7 @@ | |||
using System.IO; | |||
using System.Linq; | |||
using System.Text; | |||
using Atlasd.Helpers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphabetize the using list
Settings.State.RootElement.TryGetProperty("battlenet", out var battlenetJson); | ||
battlenetJson.TryGetProperty("realm_listener", out var listenerJson); | ||
listenerJson.TryGetProperty("interface", out var interfaceJson); | ||
listenerJson.TryGetProperty("port", out var portJson); | ||
|
||
var listenerAddressStr = interfaceJson.GetString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be refactored using the settings getter.
string listenerAddressStr = Settings.Get(new string[] { "battlenet", "realm_listener", "interface", "port" }, default: string.Empty);
@@ -102,14 +107,17 @@ public static void Initialize() | |||
ActiveChannels = new ConcurrentDictionary<string, Channel>(StringComparer.OrdinalIgnoreCase); | |||
ActiveClans = new ConcurrentDictionary<byte[], Clan>(); | |||
ActiveClientStates = new ConcurrentDictionary<Socket, ClientState>(); | |||
RealmClientStates = new ConcurrentDictionary<UInt32, ClientState>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphabetize this
public static List<GameAd> ActiveGameAds; | ||
public static ConcurrentDictionary<string, GameState> ActiveGameStates; | ||
public static Realm Realm; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphabetize this by property name
No description provided.