Implement ChannelInfosReply.

This commit is contained in:
Ray Koopa 2019-01-03 21:48:31 +01:00
parent 90110979c0
commit ee17e5886e
5 changed files with 181 additions and 28 deletions

View File

@ -1,4 +1,6 @@
using System.Net.Sockets;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using Syroot.Worms.OnlineWorms.Server.Net;
namespace Syroot.Worms.OnlineWorms.Server
@ -28,9 +30,9 @@ namespace Syroot.Worms.OnlineWorms.Server
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
public void HandleConnect(ConnectQueryPacket inPacket)
public void HandleConnect(ConnectQuery packet)
{
SendPacket(new ConnectReplyPacket
SendPacket(new ConnectReply
{
Unknown = _server.Name,
Unknown2 = _server.RegionName,
@ -38,37 +40,82 @@ namespace Syroot.Worms.OnlineWorms.Server
});
}
public void HandleLogin(LoginQueryPacket inPacket)
public void HandleLogin(LoginQuery packet)
{
LoginPlayerInfo[] playerInfos = new LoginPlayerInfo[inPacket.Logins.Length];
for (int i = 0; i < inPacket.Logins.Length; i++)
{
LoginCredentials credentials = inPacket.Logins[i];
playerInfos[i] = new LoginPlayerInfo
{
ID = credentials.ID,
Rank = 19
};
}
// Send login result.
SendPacket(new LoginReplyPacket
// Create player infos from the given credentials. This would be the place to check for actual accounts.
LoginPlayerInfo[] playerInfos = new LoginPlayerInfo[packet.Logins.Length];
for (int i = 0; i < packet.Logins.Length; i++)
{
LoginCredentials credentials = packet.Logins[i];
playerInfos[i] = new LoginPlayerInfo { ID = credentials.ID, Rank = 19 };
}
SendPacket(new LoginReply
{
Unknown1 = 1,
LoginResult = LoginResult.Success,
PlayerInfos = playerInfos
});
// Send info text.
SendPacket(new ServerInfoReplyPacket { Text = @"Welcome to the Online Worms Server.
Encoding tests are following:
Direct Sound Error로
.
%s님을 \t하시겠습니까?
01234567890" });
SendPacket(new ServerInfoReply
{
Text = "Welcome to the Online Worms Server."
});
// Send channels.
SendPacket(new ChannelInfosReply
{
Channels = new[]
{
new ChannelInfo
{
Name = "Test Channel",
EndPoint = new IPEndPoint(IPAddress.Loopback, _server.Port),
Type = ChannelType.Normal,
Color = Color.LightGreen,
UserLoad = 5
},
new ChannelInfo
{
Name = "Real Channel",
EndPoint = new IPEndPoint(IPAddress.Loopback, _server.Port),
Type = ChannelType.Normal,
Color = Color.Yellow,
UserLoad = 1
},
new ChannelInfo
{
Name = "Nothing Goes",
EndPoint = new IPEndPoint(IPAddress.Loopback, _server.Port),
Type = ChannelType.Roping,
Color = Color.Orange,
Coins = 2,
UserLoad = 6
},
new ChannelInfo
{
Name = "Boredom Time",
EndPoint = new IPEndPoint(IPAddress.Loopback, _server.Port),
Type = ChannelType.Roping,
Color = Color.HotPink,
Coins = 1,
UserLoad = 3
},
new ChannelInfo
{
Name = "Unhelpful Channel",
EndPoint = new IPEndPoint(IPAddress.Loopback, _server.Port),
Type = ChannelType.Special,
Color = Color.White,
UserLoad = 1
}
}
});
}
#if DEBUG
public void HandleRaw(RawQueryPacket inPacket) { }
public void HandleRaw(RawQuery packet) { }
#endif
// ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------

View File

@ -43,7 +43,7 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
#if DEBUG
return _packetTypes.TryGetValue(id, out Type type)
? (Packet)Activator.CreateInstance(type, true)
: new RawQueryPacket(id);
: new RawQuery(id);
#else
return (Packet)Activator.CreateInstance(_packetTypes[id], true);
#endif
@ -57,7 +57,7 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
internal static ushort GetID(Packet packet)
{
#if DEBUG
if (packet is RawQueryPacket rawPacket)
if (packet is RawQuery rawPacket)
return rawPacket.ID;
else
#endif

View File

@ -1,4 +1,5 @@
using System.IO;
using System.Drawing;
using System.IO;
using System.Text;
using Syroot.BinaryData;
@ -99,11 +100,27 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
return _baseStream.ReadString(StringCoding.Int16CharCount, _win949Encoding);
}
/// <summary>
/// Reads the remaining bytes in the buffer.
/// </summary>
/// <returns>The remaining bytes.</returns>
internal byte[] ReadToEnd()
{
return _baseStream.ReadBytes((int)(Length - Position));
}
/// <summary>
/// Writes the given <paramref name="color"/> as an RGB0 integer value.
/// </summary>
/// <param name="color">The <see cref="Color"/> to write.</param>
internal void WriteColor(Color color)
{
_baseStream.WriteByte(color.R);
_baseStream.WriteByte(color.G);
_baseStream.WriteByte(color.B);
_baseStream.WriteByte(0);
}
/// <summary>
/// Writes a 2-byte length-prefixed, Windows-949 encoded string.
/// </summary>

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using Syroot.BinaryData;
namespace Syroot.Worms.OnlineWorms.Server.Net
{
/// <summary>
/// Represents an additional server response to a <see cref="LoginQuery"/>, providing available server channels.
/// </summary>
[Packet(0x80C9)]
internal class ChannelInfosReply : Packet
{
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
public IList<ChannelInfo> Channels { get; set; }
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
internal override void Deserialize(PacketStream stream) => throw new NotImplementedException();
internal override void Serialize(PacketStream stream)
{
stream.WriteUInt16((ushort)Channels.Count);
foreach (ChannelInfo channel in Channels)
{
stream.WriteEnum(channel.Type);
stream.WriteByte(channel.Coins);
stream.WriteColor(channel.Color);
stream.WriteUInt16(1); // ?
stream.WriteString(channel.Name);
stream.WriteByte(0); // ?
stream.WriteBytes(channel.EndPoint.Address.GetAddressBytes());
stream.WriteUInt16((ushort)channel.EndPoint.Port);
stream.WriteByte(channel.UserLoad);
}
}
}
internal class ChannelInfo
{
/// <summary>
/// Gets or sets the name of the channel. Should not exceed 32 characters.
/// </summary>
internal string Name { get; set; }
/// <summary>
/// Gets or sets the <see cref="IPEndPoint"/> under which the server hosting this channel can be reached.
/// </summary>
internal IPEndPoint EndPoint { get; set; }
/// <summary>
/// Gets or sets the type of the channel determining where it will be shown in the server screen.
/// </summary>
internal ChannelType Type { get; set; }
/// <summary>
/// Gets or sets an indicator of coins with unclear meaning. 0 is no indicator, 1 is few coins, 2 is many.
/// </summary>
internal byte Coins { get; set; }
/// <summary>
/// Gets or sets the text color of the channel.
/// </summary>
internal Color Color { get; set; }
/// <summary>
/// Gets or sets an indicator of the number of players in this channel. 0 hides the channel, and 6 represents a
/// full channel.
/// </summary>
internal byte UserLoad { get; set; }
}
internal enum ChannelType : byte
{
Normal = 0,
Roping = 1,
Special = 2
}
}

View File

@ -21,6 +21,11 @@ namespace Syroot.Worms.OnlineWorms.Server
internal string RegionName => "Global";
internal ushort Version => 114;
/// <summary>
/// Gets the port under which the server listens for new connections.
/// </summary>
internal int Port { get; private set; }
internal Log Log { get; } = new Log();
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
@ -32,9 +37,10 @@ namespace Syroot.Worms.OnlineWorms.Server
/// <param name="port">The port on which to listen for new client connections.</param>
internal void Listen(int port)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
Port = port;
TcpListener tcpListener = new TcpListener(IPAddress.Any, Port);
tcpListener.Start();
Log.Write(LogCategory.Server, $"Listening on port {port}...");
Log.Write(LogCategory.Server, $"Listening on port {Port}...");
while (true)
{