mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-04-11 11:50:07 +03:00
202 lines
7.5 KiB
C#
202 lines
7.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Threading;
|
|
using Syroot.Worms.Mgame.GameServer.Core;
|
|
using Syroot.Worms.Mgame.GameServer.Packets;
|
|
using Syroot.Worms.Mgame.GameServer.Packets.OnlineWorms;
|
|
|
|
namespace Syroot.Worms.Mgame.GameServer
|
|
{
|
|
/// <summary>
|
|
/// Represents a connection with an Online Worms client which replies to received packets appropriately.
|
|
/// </summary>
|
|
internal class Client : AppConnection
|
|
{
|
|
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
|
|
|
private readonly Server _server;
|
|
|
|
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Client"/> class accepted by the given <paramref name="server"/>
|
|
/// through the provided <see cref="tcpClient"/>.
|
|
/// </summary>
|
|
/// <param name="tcpClient">The <see cref="TcpClient"/> representing the connection to the client.</param>
|
|
/// <param name="server">The <see cref="Server"/> instance with which this client communicates.</param>
|
|
internal Client(TcpClient tcpClient, Server server)
|
|
: base(tcpClient)
|
|
{
|
|
_server = server;
|
|
}
|
|
|
|
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
|
|
|
public void HandleConnect(ConnectQuery packet)
|
|
{
|
|
SendPacket(new ConnectReply
|
|
{
|
|
Unknown = _server.Config.Name,
|
|
Unknown2 = _server.Config.Region,
|
|
Version = _server.Config.Version
|
|
});
|
|
}
|
|
|
|
public void HandleLogin(LoginQuery packet)
|
|
{
|
|
// Send login result.
|
|
// 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
|
|
{
|
|
Result = LoginResult.Success,
|
|
PlayerInfos = playerInfos
|
|
});
|
|
|
|
// Send info text.
|
|
SendPacket(new ServerInfoReply
|
|
{
|
|
Text = "Welcome to the Online Worms Server."
|
|
});
|
|
|
|
// Send channels. The port is abused to identify the channel later on.
|
|
SendPacket(new ChannelInfosReply
|
|
{
|
|
Channels = new[]
|
|
{
|
|
new ChannelInfo
|
|
{
|
|
Name = "Test Channel",
|
|
EndPoint = new IPEndPoint(_server.Config.IPAddress, 1),
|
|
Type = ChannelType.Normal,
|
|
Color = Color.LightGreen,
|
|
Load = ChannelLoad.Highest
|
|
},
|
|
new ChannelInfo
|
|
{
|
|
Name = "Real Channel",
|
|
EndPoint = new IPEndPoint(_server.Config.IPAddress, 2),
|
|
Type = ChannelType.Normal
|
|
},
|
|
new ChannelInfo
|
|
{
|
|
Name = "Boredom Time",
|
|
EndPoint = new IPEndPoint(_server.Config.IPAddress, 3),
|
|
Type = ChannelType.Normal,
|
|
Load = ChannelLoad.Medium
|
|
},
|
|
new ChannelInfo
|
|
{
|
|
Name = "Nothing Goes",
|
|
EndPoint = new IPEndPoint(_server.Config.IPAddress, 4),
|
|
Type = ChannelType.Roping,
|
|
Color = Color.Orange,
|
|
Coins = 2,
|
|
Load = ChannelLoad.Closed
|
|
},
|
|
new ChannelInfo
|
|
{
|
|
Name = "Doper's Heaven",
|
|
EndPoint = new IPEndPoint(_server.Config.IPAddress, 5),
|
|
Type = ChannelType.Roping,
|
|
Color = Color.Orange,
|
|
Coins = 1,
|
|
Load = ChannelLoad.Full
|
|
},
|
|
new ChannelInfo
|
|
{
|
|
Name = "Unhelpful Channel",
|
|
EndPoint = new IPEndPoint(_server.Config.IPAddress, 6),
|
|
Type = ChannelType.Special
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void HandleChannelEnter(ChannelEnterQuery packet)
|
|
{
|
|
// Simply allow joining a channel running on the same server port.
|
|
SendPacket(new ChannelEnterReply
|
|
{
|
|
EndPoint = _server.Config.EndPoint
|
|
});
|
|
}
|
|
|
|
public void HandleChannelConnect(ChannelConnectQuery packet)
|
|
{
|
|
SendPacket(new ChannelConnectReply
|
|
{
|
|
Result = ChannelConnectResult.Success,
|
|
Player = new ChannelConnectPlayerInfo
|
|
{
|
|
ID = packet.Players[0].ID,
|
|
Name = "Your Name",
|
|
Experience = 1337,
|
|
Gold = 1000000,
|
|
Rank = 19,
|
|
GuildMarkIndex = 1,
|
|
GuildName = "Your Guild"
|
|
}
|
|
});
|
|
}
|
|
|
|
public void HandleChannelTop20(ChannelTop20Query packet)
|
|
{
|
|
// Send some simulated player rank infos.
|
|
ChannelTop20Reply reply = new ChannelTop20Reply
|
|
{
|
|
UnknownA = "Test",
|
|
Top20 = new List<ChannelTop20Player>(20)
|
|
};
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
reply.Top20.Add(new ChannelTop20Player
|
|
{
|
|
Name = $"GoodPlayer{(char)('A' + i)}",
|
|
Rank = (ushort)((i + 6) / 3),
|
|
Experience = (ulong)(20 - i) * 957
|
|
});
|
|
}
|
|
SendPacket(reply);
|
|
|
|
// This is the last channel info packet, tell the client to go to the channel screen.
|
|
SendPacket(new ChannelEnterFinishReply());
|
|
}
|
|
|
|
public void HandleStartSingleGameQuery(StartSingleGameQuery packet)
|
|
{
|
|
SendPacket(new StartSingleGameReply
|
|
{
|
|
Success = packet.RoundType == GameStartRoundType.First
|
|
});
|
|
}
|
|
|
|
#if DEBUG
|
|
public void HandleRaw(RawPacket packet) { }
|
|
#endif
|
|
|
|
// ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------
|
|
|
|
protected override void OnPrePacketHandle(Packet packet)
|
|
{
|
|
_server.Log.Write(LogCategory.Client,
|
|
$"{TcpClient.Client.RemoteEndPoint} >> {packet}{Environment.NewLine}{ObjectDumper.Dump(packet)}");
|
|
}
|
|
|
|
protected override void OnPrePacketSend(Packet packet)
|
|
{
|
|
_server.Log.Write(LogCategory.Server,
|
|
$"{TcpClient.Client.RemoteEndPoint} << {packet}{Environment.NewLine}{ObjectDumper.Dump(packet)}");
|
|
if (_server.Config.SendDelay > 0)
|
|
Thread.Sleep(_server.Config.SendDelay);
|
|
}
|
|
}
|
|
} |