mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-01-13 07:18:00 +03:00
Implement WWPA packets, update OW ones to Span parsing, rename encodings.
This commit is contained in:
parent
899c031840
commit
587ac06330
@ -42,7 +42,7 @@ namespace Syroot.Worms.Mgame.GameServer
|
||||
});
|
||||
|
||||
// Send channels. The port is abused to identify the channel later on.
|
||||
SendPacket(new ChannelInfosReply
|
||||
SendPacket(new ChannelListReply
|
||||
{
|
||||
Channels = new[]
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua;
|
||||
using System.Collections.Generic;
|
||||
using Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer
|
||||
{
|
||||
@ -6,9 +7,21 @@ namespace Syroot.Worms.Mgame.GameServer
|
||||
{
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
public void HandleWWPAConnect(ConnectQuery packet)
|
||||
public void HandleWwpaConnect(ConnectQuery packet)
|
||||
{
|
||||
|
||||
SendPacket(new ConnectReply { ServerVersion = _server.Config.Version });
|
||||
}
|
||||
|
||||
public void HandleWwpaLogin(LoginQuery packet)
|
||||
{
|
||||
SendPacket(new LoginReply { Result = LoginResult.Success });
|
||||
}
|
||||
|
||||
public void HandleWwpaLoginAcknowledge(ChannelListQuery packet)
|
||||
{
|
||||
SendPacket(new ChannelListReply { Channels = new List<ChannelInfo>() });
|
||||
}
|
||||
|
||||
public void HandleWwpaDisconnectQuery(DisconnectQuery packet) { }
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,15 @@ namespace Syroot.Worms.Mgame.GameServer
|
||||
};
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
public void HandleRawPacket(RawPacket packet) { }
|
||||
#endif
|
||||
|
||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||
|
||||
private string FormatPacket(Packet packet, string direction)
|
||||
=> $"{TcpClient.Client.RemoteEndPoint} {direction} {packet.GetType().Name}{ObjectDumper.Dump(packet)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Core.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents extension methods for <see cref="SpanReader"/> instances.
|
||||
/// </summary>
|
||||
internal static class SpanReaderExtensions
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Reads the remaining bytes that are available.
|
||||
/// </summary>
|
||||
/// <param name="self">The extended instance.</param>
|
||||
/// <returns>The remaining bytes in the reader.</returns>
|
||||
internal static byte[] ReadToEnd(this ref SpanReader self) => self.ReadBytes(self.Length - self.Position);
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace Syroot.Worms.Mgame.GameServer.Core.IO
|
||||
/// </summary>
|
||||
/// <param name="self">The extended instance.</param>
|
||||
/// <param name="color">The <see cref="Color"/> to write.</param>
|
||||
internal static void WriteColor(this SpanWriter self, Color color)
|
||||
internal static void WriteColor(this ref SpanWriter self, Color color)
|
||||
{
|
||||
self.WriteByte(color.R);
|
||||
self.WriteByte(color.G);
|
||||
|
@ -104,7 +104,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
SendOWServerPacket(attribute.ID, packet);
|
||||
break;
|
||||
case PacketFormat.Wwpa:
|
||||
SaveWwpaPacket(attribute.ID, packet);
|
||||
SendWwpaPacket(attribute.ID, packet, false);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Cannot send unknown packet format.");
|
||||
@ -145,7 +145,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
int dataSize = _tcpStream.ReadUInt16();
|
||||
int id = _tcpStream.Read1Byte();
|
||||
// Read data.
|
||||
SpanReader reader = new SpanReader(_tcpStream.ReadBytes(dataSize), encoding: Encodings.Win949);
|
||||
SpanReader reader = new SpanReader(_tcpStream.ReadBytes(dataSize), encoding: Encodings.Korean);
|
||||
// Read tail.
|
||||
ushort endTag = _tcpStream.ReadUInt16();
|
||||
if (endTag != _owTagEndChannel)
|
||||
@ -153,7 +153,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
|
||||
// Instantiate, deserialize, and return packet.
|
||||
Packet packet = PacketFactory.Create(PacketFormat.OWChannel, id);
|
||||
packet.LoadData(reader);
|
||||
packet.Load(ref reader);
|
||||
return packet;
|
||||
}
|
||||
|
||||
@ -162,11 +162,11 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
// Read head.
|
||||
int dataSize = _tcpStream.ReadUInt16();
|
||||
// Read data.
|
||||
SpanReader reader = new SpanReader(_tcpStream.ReadBytes(dataSize), encoding: Encodings.Win949);
|
||||
SpanReader reader = new SpanReader(_tcpStream.ReadBytes(dataSize), encoding: Encodings.Korean);
|
||||
|
||||
// Instantiate, deserialize, and return packet.
|
||||
Packet packet = PacketFactory.Create(PacketFormat.OWServer, tag);
|
||||
packet.LoadData(reader);
|
||||
packet.Load(ref reader);
|
||||
return packet;
|
||||
}
|
||||
|
||||
@ -174,9 +174,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
{
|
||||
// Read head.
|
||||
if (!_tcpStream.ReadBoolean())
|
||||
throw new IOException("Unexpected WWPA packet head2.");
|
||||
throw new IOException("Unexpected WWPA packet bHead2.");
|
||||
if (_tcpStream.ReadBoolean())
|
||||
throw new IOException("Unexpected WWPA packet head3.");
|
||||
throw new IOException("Unexpected WWPA packet bHead3.");
|
||||
if (!_tcpStream.ReadBoolean())
|
||||
throw new IOException("Unexpected WWPA packet bIsCompressed.");
|
||||
int decompressedSize = _tcpStream.ReadUInt16();
|
||||
@ -191,18 +191,19 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
throw new IOException("Invalid WWPA packet end tag.");
|
||||
|
||||
// Instantiate, deserialize, and return packet.
|
||||
SpanReader reader = new SpanReader(PacketCompression.Decompress(compressedData), encoding: Encodings.Win949);
|
||||
SpanReader reader = new SpanReader(PacketCompression.Decompress(compressedData), encoding: Encodings.Korean);
|
||||
int id = reader.ReadInt32();
|
||||
Packet packet = PacketFactory.Create(PacketFormat.Wwpa, id);
|
||||
packet.LoadData(reader.Slice());
|
||||
SpanReader dataReader = reader.Slice();
|
||||
packet.Load(ref dataReader);
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void SendOWChannelPacket(int id, Packet packet)
|
||||
{
|
||||
// Retrieve data. Must have at least 1 byte.
|
||||
SpanWriter writer = new SpanWriter(new byte[_maxDataSize], encoding: Encodings.Win949);
|
||||
packet.SaveData(writer);
|
||||
SpanWriter writer = new SpanWriter(new byte[_maxDataSize], encoding: Encodings.Korean);
|
||||
packet.Save(ref writer);
|
||||
writer.Position = Math.Max(1, writer.Position);
|
||||
|
||||
// Send head.
|
||||
@ -221,8 +222,8 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
private void SendOWServerPacket(int id, Packet packet)
|
||||
{
|
||||
// Retrieve data.
|
||||
SpanWriter writer = new SpanWriter(new byte[_maxDataSize], encoding: Encodings.Win949);
|
||||
packet.SaveData(writer);
|
||||
SpanWriter writer = new SpanWriter(new byte[_maxDataSize], encoding: Encodings.Korean);
|
||||
packet.Save(ref writer);
|
||||
|
||||
// Send head.
|
||||
_tcpStream.WriteUInt16((ushort)id);
|
||||
@ -232,27 +233,36 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
_tcpStream.Write(writer.Span);
|
||||
}
|
||||
|
||||
private void SaveWwpaPacket(int id, Packet packet)
|
||||
private void SendWwpaPacket(int id, Packet packet, bool compress)
|
||||
{
|
||||
// Retrieve (decompressed) data size.
|
||||
SpanWriter writer = new SpanWriter(new byte[_maxDataSize], encoding: Encodings.Win949);
|
||||
packet.SaveData(writer);
|
||||
ReadOnlySpan<byte> compressedData = PacketCompression.Compress(writer.Span);
|
||||
// Retrieve (decompressed) data.
|
||||
SpanWriter writer = new SpanWriter(new byte[_maxDataSize], encoding: Encodings.Korean);
|
||||
writer.WriteInt32(id);
|
||||
packet.Save(ref writer);
|
||||
|
||||
// Send head.
|
||||
// Send head and data.
|
||||
_tcpStream.WriteUInt16(_wwpaTagStart);
|
||||
_tcpStream.WriteBoolean(true);
|
||||
_tcpStream.WriteBoolean(false);
|
||||
_tcpStream.WriteBoolean(true); // isCompressed
|
||||
_tcpStream.WriteUInt16((ushort)writer.Span.Length);
|
||||
_tcpStream.WriteUInt32((uint)compressedData.Length);
|
||||
_tcpStream.WriteInt32(1); // Apparently only needs to be same as in tail.
|
||||
|
||||
// Send data.
|
||||
_tcpStream.Write(compressedData);
|
||||
_tcpStream.WriteBoolean(true); // bHead2 (unknown)
|
||||
_tcpStream.WriteBoolean(false); // bHead3 (unknown)
|
||||
_tcpStream.WriteBoolean(compress);
|
||||
if (compress)
|
||||
{
|
||||
ReadOnlySpan<byte> compressedData = PacketCompression.Compress(writer.Span);
|
||||
_tcpStream.WriteUInt16((ushort)writer.Position); // decompressed size
|
||||
_tcpStream.WriteUInt32((uint)compressedData.Length); // compressed size
|
||||
_tcpStream.WriteInt32(1); // index
|
||||
_tcpStream.Write(compressedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tcpStream.WriteUInt16(0); // unused
|
||||
_tcpStream.WriteUInt32((ushort)writer.Position); // raw size
|
||||
_tcpStream.WriteInt32(1); // index
|
||||
_tcpStream.Write(writer.Span.Slice(0, writer.Position));
|
||||
}
|
||||
|
||||
// Send tail.
|
||||
_tcpStream.WriteInt32(1); // Apparently only needs to be same as in head.
|
||||
_tcpStream.WriteInt32(1); // index (must equal other)
|
||||
_tcpStream.WriteUInt16(_wwpaTagEnd);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader)
|
||||
internal override void Load(ref SpanReader reader)
|
||||
{
|
||||
Players = new List<ChannelConnectPlayerCredentials>
|
||||
{
|
||||
@ -51,7 +51,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
UnknownB = reader.ReadByte();
|
||||
}
|
||||
|
||||
internal override void SaveData(SpanWriter writer) => throw new NotImplementedException();
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal class ChannelConnectPlayerCredentials
|
||||
|
@ -17,9 +17,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
if (Result == ChannelConnectResult.Success)
|
||||
{
|
||||
|
@ -12,8 +12,8 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer) { }
|
||||
internal override void Save(ref SpanWriter writer) { }
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,12 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader)
|
||||
internal override void Load(ref SpanReader reader)
|
||||
{
|
||||
PlayerID = reader.ReadString();
|
||||
ChannelEndPoint = new IPEndPoint(IPAddress.Parse(reader.ReadString()), reader.ReadUInt16());
|
||||
}
|
||||
|
||||
internal override void SaveData(SpanWriter writer) => throw new NotImplementedException();
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteString(EndPoint.Address.ToString());
|
||||
writer.WriteString2(EndPoint.Address.ToString());
|
||||
writer.WriteUInt16((ushort)EndPoint.Port);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
/// Represents an additional server response to a <see cref="LoginQuery"/>, providing available server channels.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.OWServer, 0x80C9)]
|
||||
internal class ChannelInfosReply : Packet
|
||||
internal class ChannelListReply : Packet
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
@ -19,9 +19,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteUInt16((ushort)Channels.Count);
|
||||
foreach (ChannelInfo channel in Channels)
|
||||
@ -31,7 +31,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
writer.WriteColor(channel.Color);
|
||||
writer.WriteUInt16(1); // ?
|
||||
|
||||
writer.WriteString(channel.Name);
|
||||
writer.WriteString2(channel.Name);
|
||||
writer.WriteByte(0); // ?
|
||||
|
||||
writer.WriteBytes(channel.EndPoint.Address.GetAddressBytes());
|
@ -18,11 +18,11 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader)
|
||||
internal override void Load(ref SpanReader reader)
|
||||
{
|
||||
Count = reader.ReadUInt16();
|
||||
}
|
||||
|
||||
internal override void SaveData(SpanWriter writer) => throw new NotImplementedException();
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteStringFix(UnknownA, 30);
|
||||
foreach (ChannelTop20Player top20Player in Top20)
|
||||
|
@ -11,8 +11,8 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) { }
|
||||
internal override void Load(ref SpanReader reader) { }
|
||||
|
||||
internal override void SaveData(SpanWriter writer) => throw new NotImplementedException();
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,13 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteString(Unknown);
|
||||
writer.WriteString2(Unknown);
|
||||
writer.WriteByte(0);
|
||||
writer.WriteString(Unknown2);
|
||||
writer.WriteString2(Unknown2);
|
||||
writer.WriteUInt16(Version);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader)
|
||||
internal override void Load(ref SpanReader reader)
|
||||
{
|
||||
Unknown1 = reader.ReadUInt16();
|
||||
Logins = new LoginCredentials[reader.ReadUInt16()];
|
||||
@ -35,7 +35,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
ClientIP = IPAddress.Parse(reader.ReadString());
|
||||
}
|
||||
|
||||
internal override void SaveData(SpanWriter writer) => throw new NotImplementedException();
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal class LoginCredentials
|
||||
|
@ -23,9 +23,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
bool loginSuccessful = Result == LoginResult.Success;
|
||||
writer.WriteBoolean(loginSuccessful);
|
||||
@ -35,7 +35,7 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
writer.WriteUInt16((ushort)PlayerInfos.Length);
|
||||
foreach (LoginPlayerInfo playerInfo in PlayerInfos)
|
||||
{
|
||||
writer.WriteString(playerInfo.ID);
|
||||
writer.WriteString2(playerInfo.ID);
|
||||
writer.WriteUInt16(playerInfo.Rank);
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteString(Text.Replace(Environment.NewLine, "\n"));
|
||||
writer.WriteString2(Text.Replace(Environment.NewLine, "\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader)
|
||||
internal override void Load(ref SpanReader reader)
|
||||
{
|
||||
RoundType = reader.ReadEnumSafe<GameStartRoundType>();
|
||||
UnknownB = reader.ReadByte();
|
||||
UnknownC = reader.ReadByte();
|
||||
}
|
||||
|
||||
internal override void SaveData(SpanWriter writer) => throw new NotImplementedException();
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal enum GameStartRoundType : byte
|
||||
|
@ -15,9 +15,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) => throw new NotImplementedException();
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteBoolean2(Success);
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal abstract void LoadData(SpanReader reader);
|
||||
internal abstract void Load(ref SpanReader reader);
|
||||
|
||||
internal abstract void SaveData(SpanWriter writer);
|
||||
internal abstract void Save(ref SpanWriter writer);
|
||||
}
|
||||
}
|
||||
|
@ -27,15 +27,9 @@ namespace Syroot.Worms.Mgame.GameServer.Packets
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader)
|
||||
{
|
||||
Data = reader.ReadBytes(reader.Length);
|
||||
}
|
||||
internal override void Load(ref SpanReader reader) => Data = reader.ReadBytes(reader.Length);
|
||||
|
||||
internal override void SaveData(SpanWriter writer)
|
||||
{
|
||||
writer.WriteBytes(Data);
|
||||
}
|
||||
internal override void Save(ref SpanWriter writer) => writer.WriteBytes(Data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -0,0 +1,17 @@
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the client request for a <see cref="ChannelListReply"/>.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.Wwpa, 0x801E)]
|
||||
internal class ChannelListQuery : Packet
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void Load(ref SpanReader reader) { }
|
||||
|
||||
internal override void Save(ref SpanWriter writer) { }
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the server reply to a <see cref="ChannelListQuery"/>.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.Wwpa, 0x801F)]
|
||||
internal class ChannelListReply : Packet
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
public IList<ChannelInfo> Channels { get; set; }
|
||||
|
||||
public byte Unknown { get; set; }
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteUInt16((ushort)Channels.Count);
|
||||
writer.WriteByte(Unknown);
|
||||
writer.Align(4);
|
||||
foreach (ChannelInfo channel in Channels)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ChannelInfo
|
||||
{
|
||||
}
|
||||
}
|
@ -10,8 +10,8 @@ namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void LoadData(SpanReader reader) { }
|
||||
internal override void Load(ref SpanReader reader) { }
|
||||
|
||||
internal override void SaveData(SpanWriter writer) { }
|
||||
internal override void Save(ref SpanWriter writer) { }
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the server response to a <see cref="ConnectQuery"/>.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.Wwpa, 0x8002)]
|
||||
internal class ConnectReply : Packet
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an error message displayed to prevent the connection attempt. This property must be
|
||||
/// <see langword="null"/> to allow further communication.
|
||||
/// </summary>
|
||||
internal string ErrorMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server version reported to the client, and checked by it to allow further communication.
|
||||
/// </summary>
|
||||
internal ushort ServerVersion { get; set; }
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
bool connectionFailed = ErrorMessage != null;
|
||||
writer.WriteBoolean4(connectionFailed);
|
||||
if (connectionFailed)
|
||||
writer.WriteString2(ErrorMessage);
|
||||
else
|
||||
writer.WriteUInt16(ServerVersion);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the client packet probably sent when it notifies about disconnecting.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.Wwpa, 0x801B)]
|
||||
internal class DisconnectQuery : Packet
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void Load(ref SpanReader reader) { }
|
||||
|
||||
internal override void Save(ref SpanWriter writer) { }
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the client request for a <see cref="LoginReply"/>.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.Wwpa, 0x8019)]
|
||||
internal class LoginQuery : Packet
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the names and passwords of the players to login.
|
||||
/// </summary>
|
||||
public IList<LoginCredentials> Logins { get; set; }
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void Load(ref SpanReader reader)
|
||||
{
|
||||
Logins = new List<LoginCredentials> { ReadCredentials(ref reader) };
|
||||
if (reader.ReadBoolean())
|
||||
Logins.Add(ReadCredentials(ref reader));
|
||||
}
|
||||
|
||||
internal override void Save(ref SpanWriter writer) => throw new NotImplementedException();
|
||||
|
||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||
|
||||
private static LoginCredentials ReadCredentials(ref SpanReader reader) => new LoginCredentials
|
||||
{
|
||||
UserName = reader.ReadString2(),
|
||||
Password = reader.ReadString2()
|
||||
};
|
||||
}
|
||||
|
||||
internal class LoginCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the player to login.
|
||||
/// </summary>
|
||||
internal string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password with which the player profile is authenticated.
|
||||
/// </summary>
|
||||
internal string Password { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Syroot.BinaryData.Memory;
|
||||
|
||||
namespace Syroot.Worms.Mgame.GameServer.Packets.WorldPartyAqua
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the server response to a <see cref="LoginQuery"/>.
|
||||
/// </summary>
|
||||
[Packet(PacketFormat.Wwpa, 0x801A)]
|
||||
internal class LoginReply : Packet
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
public LoginResult Result { get; set; }
|
||||
|
||||
public byte UnknownA { get; set; }
|
||||
|
||||
public ushort UnknownB { get; set; }
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
internal override void Load(ref SpanReader reader) => throw new NotImplementedException();
|
||||
|
||||
internal override void Save(ref SpanWriter writer)
|
||||
{
|
||||
writer.WriteEnumSafe(Result);
|
||||
if (Result == LoginResult.Success)
|
||||
{
|
||||
writer.WriteByte(UnknownA);
|
||||
writer.WriteUInt16(UnknownB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum LoginResult : byte
|
||||
{
|
||||
Success = 0,
|
||||
SaveInfoOnly = 12,
|
||||
NicknameDoesNotExist = 14,
|
||||
LoginFailed = 15,
|
||||
FailedToFindUser = 99
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
"Port": 17022,
|
||||
"Name": "Mgame Worms Private Server",
|
||||
"Region": "Global",
|
||||
"Version": 114,
|
||||
"Version": 34, // 114 for OW, 34 for WWPA
|
||||
|
||||
// Debugging settings (optional)
|
||||
"SendDelay": 0 // milliseconds to sleep before sending packets (simulate network load)
|
||||
|
@ -9,14 +9,14 @@ namespace Syroot.Worms.Mgame
|
||||
{
|
||||
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
||||
|
||||
public static readonly Encoding Win949;
|
||||
public static readonly Encoding Korean;
|
||||
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
static Encodings()
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
Win949 = Encoding.GetEncoding(949);
|
||||
Korean = Encoding.GetEncoding("ks_c_5601-1987"); // codepage 949
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace Syroot.Worms.Mgame
|
||||
MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(mapName, 1266,
|
||||
MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable);
|
||||
using (BinaryStream stream = new BinaryStream(mappedFile.CreateViewStream(),
|
||||
encoding: Encodings.Win949, stringCoding: StringCoding.ZeroTerminated))
|
||||
encoding: Encodings.Korean, stringCoding: StringCoding.ZeroTerminated))
|
||||
{
|
||||
stream.WriteString(Publisher, 16);
|
||||
stream.WriteString(Unknown, 20);
|
||||
|
@ -63,7 +63,7 @@ namespace Syroot.Worms.Mgame
|
||||
{
|
||||
Elements.Add(new LpdElement
|
||||
{
|
||||
FileName = stream.ReadString(StringCoding.Int32CharCount, Encodings.Win949),
|
||||
FileName = stream.ReadString(StringCoding.Int32CharCount, Encodings.Korean),
|
||||
Rectangle = new Rectangle(stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32()),
|
||||
Properties = stream.ReadInt32(),
|
||||
Version = stream.ReadInt32()
|
||||
|
@ -40,7 +40,7 @@ namespace Syroot.Worms.Mgame
|
||||
using (MemoryStream inStream = new MemoryStream(new byte[_bufferSize]))
|
||||
{
|
||||
// Write input into a buffer. Required to loop over the input password end.
|
||||
inStream.WriteString(data, StringCoding.ZeroTerminated, Encodings.Win949);
|
||||
inStream.WriteString(data, StringCoding.ZeroTerminated, Encodings.Korean);
|
||||
inStream.Position = 0;
|
||||
using (MemoryStream outStream = new MemoryStream(new byte[_bufferSize]))
|
||||
{
|
||||
@ -57,7 +57,7 @@ namespace Syroot.Worms.Mgame
|
||||
}
|
||||
// Return the encrypted password as a zero-terminated ASCII string.
|
||||
outStream.Position = 0;
|
||||
return outStream.ReadString(StringCoding.ZeroTerminated, Encodings.Win949);
|
||||
return outStream.ReadString(StringCoding.ZeroTerminated, Encodings.Korean);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace Syroot.Worms.Mgame
|
||||
using (MemoryStream inStream = new MemoryStream(new byte[_bufferSize]))
|
||||
{
|
||||
// Write input into a buffer. Required to loop over the input password end.
|
||||
inStream.WriteString(data, StringCoding.Raw, Encodings.Win949);
|
||||
inStream.WriteString(data, StringCoding.Raw, Encodings.Korean);
|
||||
inStream.Position = 0;
|
||||
using (MemoryStream outStream = new MemoryStream(new byte[_bufferSize]))
|
||||
{
|
||||
@ -93,7 +93,7 @@ namespace Syroot.Worms.Mgame
|
||||
}
|
||||
// Return the decrypted password as a zero-terminated ASCII string.
|
||||
outStream.Position = 0;
|
||||
return outStream.ReadString(StringCoding.ZeroTerminated, Encodings.Win949);
|
||||
return outStream.ReadString(StringCoding.ZeroTerminated, Encodings.Korean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user