diff --git a/TrueCraft.API/Server/ChatMessageEventArgs.cs b/TrueCraft.API/Server/ChatMessageEventArgs.cs
new file mode 100644
index 0000000..a9d5418
--- /dev/null
+++ b/TrueCraft.API/Server/ChatMessageEventArgs.cs
@@ -0,0 +1,22 @@
+using System;
+using TrueCraft.API.Networking;
+
+namespace TrueCraft.API.Server
+{
+ public class ChatMessageEventArgs : EventArgs
+ {
+ public ChatMessageEventArgs(IRemoteClient client, string message)
+ {
+ Client = client;
+ Message = message;
+ PreventDefault = false;
+ }
+
+ public IRemoteClient Client { get; set; }
+ public string Message { get; set; }
+ ///
+ /// If set to true, the server won't send the default message back to the client.
+ ///
+ public bool PreventDefault { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.API/Server/IMultiplayerServer.cs b/TrueCraft.API/Server/IMultiplayerServer.cs
index 4edd038..65af6f3 100644
--- a/TrueCraft.API/Server/IMultiplayerServer.cs
+++ b/TrueCraft.API/Server/IMultiplayerServer.cs
@@ -15,6 +15,8 @@ namespace TrueCraft.API.Server
public interface IMultiplayerServer
{
+ event EventHandler ChatMessageReceived;
+
IPacketReader PacketReader { get; }
IList Clients { get; }
IList Worlds { get; }
@@ -26,5 +28,6 @@ namespace TrueCraft.API.Server
void AddLogProvider(ILogProvider provider);
void Log(LogCategory category, string text, params object[] parameters);
IEntityManager GetEntityManagerForWorld(IWorld world);
+ void SendMessage(string message, params object[] parameters);
}
}
\ No newline at end of file
diff --git a/TrueCraft.API/TrueCraft.API.csproj b/TrueCraft.API/TrueCraft.API.csproj
index 94f0f35..ac3a34f 100644
--- a/TrueCraft.API/TrueCraft.API.csproj
+++ b/TrueCraft.API/TrueCraft.API.csproj
@@ -72,6 +72,7 @@
+
diff --git a/TrueCraft/Handlers/LoginHandlers.cs b/TrueCraft/Handlers/LoginHandlers.cs
index e663e19..096ffee 100644
--- a/TrueCraft/Handlers/LoginHandlers.cs
+++ b/TrueCraft/Handlers/LoginHandlers.cs
@@ -30,19 +30,19 @@ namespace TrueCraft.Handlers
client.QueuePacket(new DisconnectPacket("Server has no worlds configured."));
else
{
- server.Log(LogCategory.Notice, "{0} joined the server.", client.Username); // TODO: Mention the same thing in chat
client.LoggedIn = true;
client.Entity = new PlayerEntity(client.Username);
client.World = server.Worlds[0];
server.GetEntityManagerForWorld(client.World).SpawnEntity(client.Entity);
client.QueuePacket(new LoginResponsePacket(0, 0, Dimension.Overworld));
- client.ChunkRadius = 2;
+ client.ChunkRadius = 3;
client.UpdateChunks();
client.QueuePacket(new WindowItemsPacket(0, client.Inventory.GetSlots()));
client.QueuePacket(new SpawnPositionPacket(0, 16, 0));
client.QueuePacket(new SetPlayerPositionPacket(0, 16, 17, 0, 0, 0, true));
server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(10), client.SendKeepAlive);
server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(1), client.ExpandChunkRadius);
+ server.SendMessage(ChatColor.Yellow + "{0} joined the server.", client.Username);
}
}
}
diff --git a/TrueCraft/Handlers/PacketHandlers.cs b/TrueCraft/Handlers/PacketHandlers.cs
index 497ed7e..b608104 100644
--- a/TrueCraft/Handlers/PacketHandlers.cs
+++ b/TrueCraft/Handlers/PacketHandlers.cs
@@ -3,6 +3,7 @@ using TrueCraft.API;
using TrueCraft.API.Server;
using TrueCraft.Core.Networking.Packets;
using TrueCraft.API.Networking;
+using TrueCraft.API.Logging;
namespace TrueCraft.Handlers
{
@@ -27,15 +28,16 @@ namespace TrueCraft.Handlers
// TODO
}
- internal static void HandleChatMessage(IPacket _packet, IRemoteClient _client, IMultiplayerServer server)
+ internal static void HandleChatMessage(IPacket _packet, IRemoteClient _client, IMultiplayerServer _server)
{
// TODO: Abstract this to support things like commands
// TODO: Sanitize messages
var packet = (ChatMessagePacket)_packet;
- foreach (var client in server.Clients)
- {
- client.SendMessage(ChatColor.Yellow + string.Format("<{0}> {1}", _client.Username, packet.Message));
- }
+ var server = (MultiplayerServer)_server;
+ var args = new ChatMessageEventArgs(_client, packet.Message);
+ server.OnChatMessageReceived(args);
+ if (!args.PreventDefault)
+ server.SendMessage("<{0}> {1}", _client.Username, packet.Message);
}
}
}
\ No newline at end of file
diff --git a/TrueCraft/MultiplayerServer.cs b/TrueCraft/MultiplayerServer.cs
index 7b399c0..b16bbee 100644
--- a/TrueCraft/MultiplayerServer.cs
+++ b/TrueCraft/MultiplayerServer.cs
@@ -9,11 +9,14 @@ using System.Collections.Generic;
using TrueCraft.API.World;
using TrueCraft.API.Logging;
using TrueCraft.Core.Networking.Packets;
+using TrueCraft.API;
namespace TrueCraft
{
public class MultiplayerServer : IMultiplayerServer
{
+ public event EventHandler ChatMessageReceived;
+
public IPacketReader PacketReader { get; private set; }
public IList Clients { get; private set; }
public IList Worlds { get; private set; }
@@ -104,6 +107,22 @@ namespace TrueCraft
return null;
}
+ public void SendMessage(string message, params object[] parameters)
+ {
+ var compiled = string.Format(message, parameters);
+ foreach (var client in Clients)
+ {
+ client.SendMessage(compiled);
+ Log(LogCategory.Notice, compiled);
+ }
+ }
+
+ protected internal void OnChatMessageReceived(ChatMessageEventArgs e)
+ {
+ if (ChatMessageReceived != null)
+ ChatMessageReceived(this, e);
+ }
+
private void DisconnectClient(IRemoteClient _client)
{
var client = (RemoteClient)_client;
@@ -130,7 +149,7 @@ namespace TrueCraft
for (int i = 0; i < Clients.Count; i++)
{
var client = Clients[i] as RemoteClient;
- if (client.PacketQueue.Count != 0)
+ while (client.PacketQueue.Count != 0)
{
IPacket packet;
while (!client.PacketQueue.TryDequeue(out packet)) { }
@@ -139,6 +158,7 @@ namespace TrueCraft
{
DisconnectClient(client);
i--;
+ break;
}
}
if (client.DataAvailable)