Simple Server-Controlled Chat
There are times when you even want your in-game chat to be controlled by the server, for example to either restrict the use of bad words, prevent spamming, or both.
PlayerChatController
On the player, attach a PlayerChatController which deals with input from the player and sends it to the server. We are using DF-GUI* for our GUI, hence the reference to dfTextbox, but the principles are the same regardless of which GUI-system you use;
* DF-GUI is no longer maintained, so please don't take this as a recommendation to use that GUI solution.
public class PlayerChatController : Bolt.EntityEventListener<IPlayerState> {
dfTextbox chatInputTextbox;
void Start () {
chatInputTextbox = PlayerUI.instance.chatInputTextbox; // PlayerUI is a local, non-networked, singleton
}
void Update () {
// The chat input box is triggered when the player presses "T"
if ( Input.GetKey(KeyCode.T) && !chatInputTextbox.IsVisible ) {
chatInputTextbox.MaxLength = 140; // Bolt allows strings of max 140 chars length
chatInputTextbox.Text = "";
chatInputTextbox.IsVisible = true;
chatInputTextbox.Focus();
}
// Things that can only happen if the chat input textbox is visible
if ( chatInputTextbox.IsVisible ) {
// Send message when player presses Enter/Return
if ( Input.GetKeyDown(KeyCode.Return) ) {
chatInputTextbox.IsVisible = false;
chatInputTextbox.Trim(); // Removes spaces at the beginning and end; we don't want strings filled with spaces to bother us
// Send the chat message to the server only for "quality check"
if ( chatInputTextbox.Text.Length > 0 ) {
using ( var evnt = SendChatMsgToServer.Create(Bolt.GlobalTargets.OnlyServer) ) {
evnt.Sender = entity;
evnt.Message = chatInputTextbox.Text;
}
}
}
// Abort (i.e. if pressing the ESC key)
if ( Input.GetKeyDown(KeyCode.Escape) ) {
chatInputTextbox.IsVisible = false;
}
}
}
}
UI_ChatOutputController
This controller is attached to the player's user interface and takes care of displaying the chat messages, scrolling them, removing the oldest ones etc. It also handles the chat-events;
public class UI_ChatOutputController : Bolt.GlobalEventListener {
public override void OnEvent ( SendChatMsgToServer evnt ) {
bool okToSend = true;
// This is the place where you do all the checks to see if it's OK to forward the message to all the clients.
// Then, if it's OK...
if ( okToSend ) {
// Send the message to everyone, including the server
using ( var clientEvnt = SendChatMsgToClients(Bolt.GlobalTargets.Everyone) ) {
clientEvnt.Message = evnt.Message;
}
}
}
public override void OnEvent ( SendChatMsgToClients evnt ) {
// This is where you receive the chat message from the server, adds it to your chat messages list/array and refreshes your GUI.
}
}
Two events for the same task?
You might notice that there are two events doing basically the same thing here; just sending a chat message around. You are free to use only one event, where the clients sends the event only to the server (as in the code above) and then the same event to send to all the clients (or to everyone, including the server, as in the code above.)
It's all up to you.