Reimplemented chat range & radio messages. Each client now has their own chatMsgQueue, so all chat messages don't have to be sent to all clients.
This commit is contained in:
@@ -45,9 +45,14 @@ namespace Barotrauma.Items.Components
|
|||||||
list.Add(this);
|
list.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CanTransmit()
|
||||||
|
{
|
||||||
|
return HasRequiredContainedItems(true);
|
||||||
|
}
|
||||||
|
|
||||||
public void Transmit(string signal)
|
public void Transmit(string signal)
|
||||||
{
|
{
|
||||||
if (!HasRequiredContainedItems(true)) return;
|
if (!CanTransmit()) return;
|
||||||
|
|
||||||
var receivers = GetReceiversInRange();
|
var receivers = GetReceiversInRange();
|
||||||
foreach (WifiComponent w in receivers)
|
foreach (WifiComponent w in receivers)
|
||||||
@@ -60,14 +65,22 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private List<WifiComponent> GetReceiversInRange()
|
private List<WifiComponent> GetReceiversInRange()
|
||||||
{
|
{
|
||||||
return list.FindAll(w =>
|
return list.FindAll(w => w != this && w.CanReceive(this));
|
||||||
w != this && w.channel == channel &&
|
}
|
||||||
Vector2.Distance(item.WorldPosition, w.item.WorldPosition) <= Range);
|
|
||||||
|
public bool CanReceive(WifiComponent sender)
|
||||||
|
{
|
||||||
|
if (!HasRequiredContainedItems(false)) return false;
|
||||||
|
|
||||||
|
if (sender == null || sender.channel != channel) return false;
|
||||||
|
|
||||||
|
return Vector2.Distance(item.WorldPosition, sender.item.WorldPosition) <= sender.Range;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power=0.0f)
|
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power=0.0f)
|
||||||
{
|
{
|
||||||
if (!HasRequiredContainedItems(false)) return;
|
var senderComponent = sender.GetComponent<WifiComponent>();
|
||||||
|
if (senderComponent != null && !CanReceive(senderComponent)) return;
|
||||||
|
|
||||||
if (LinkToChat)
|
if (LinkToChat)
|
||||||
{
|
{
|
||||||
@@ -76,7 +89,10 @@ namespace Barotrauma.Items.Components
|
|||||||
item.ParentInventory.Owner == Character.Controlled &&
|
item.ParentInventory.Owner == Character.Controlled &&
|
||||||
GameMain.NetworkMember != null)
|
GameMain.NetworkMember != null)
|
||||||
{
|
{
|
||||||
signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, range);
|
if (senderComponent != null)
|
||||||
|
{
|
||||||
|
signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, senderComponent.range);
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio);
|
GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,10 +40,11 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static UInt32 LastID = 0;
|
public static UInt32 LastID = 0;
|
||||||
public UInt32 netStateID = 0;
|
|
||||||
public UInt32 NetStateID
|
public UInt32 NetStateID
|
||||||
{
|
{
|
||||||
get { return netStateID; }
|
get;
|
||||||
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChatMessage(string senderName, string text, ChatMessageType type, Character sender)
|
private ChatMessage(string senderName, string text, ChatMessageType type, Character sender)
|
||||||
@@ -56,12 +57,6 @@ namespace Barotrauma.Networking
|
|||||||
SenderName = senderName;
|
SenderName = senderName;
|
||||||
|
|
||||||
TextWithSender = string.IsNullOrWhiteSpace(senderName) ? text : senderName + ": " + text;
|
TextWithSender = string.IsNullOrWhiteSpace(senderName) ? text : senderName + ": " + text;
|
||||||
|
|
||||||
if (GameMain.Server != null)
|
|
||||||
{
|
|
||||||
LastID++;
|
|
||||||
netStateID = LastID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender)
|
public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender)
|
||||||
@@ -140,7 +135,8 @@ namespace Barotrauma.Networking
|
|||||||
if (c.lastSentChatMsgID < ID)
|
if (c.lastSentChatMsgID < ID)
|
||||||
{
|
{
|
||||||
//this chat message is new to the server
|
//this chat message is new to the server
|
||||||
GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name);
|
GameMain.Server.SendChatMessage(txt, null, c);
|
||||||
|
//GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name);
|
||||||
c.lastSentChatMsgID = ID;
|
c.lastSentChatMsgID = ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public UInt32 lastRecvEntitySpawnID = 0;
|
public UInt32 lastRecvEntitySpawnID = 0;
|
||||||
|
|
||||||
public List<string> ChatMessages = new List<string>();
|
public List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
||||||
public float ChatSpamSpeed;
|
public float ChatSpamSpeed;
|
||||||
public float ChatSpamTimer;
|
public float ChatSpamTimer;
|
||||||
public int ChatSpamCount;
|
public int ChatSpamCount;
|
||||||
|
|||||||
@@ -847,18 +847,18 @@ namespace Barotrauma.Networking
|
|||||||
client.SendMessage(outmsg, NetDeliveryMethod.Unreliable);
|
client.SendMessage(outmsg, NetDeliveryMethod.Unreliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendChatMessage(string message, ChatMessageType? type = null)
|
public void SendChatMessage(string message)
|
||||||
{
|
{
|
||||||
if (client.ServerConnection == null) return;
|
if (client.ServerConnection == null) return;
|
||||||
|
|
||||||
type = ChatMessageType.Default;
|
|
||||||
|
|
||||||
ChatMessage chatMessage = ChatMessage.Create(
|
ChatMessage chatMessage = ChatMessage.Create(
|
||||||
gameStarted && myCharacter != null ? myCharacter.Name : name,
|
gameStarted && myCharacter != null ? myCharacter.Name : name,
|
||||||
message, (ChatMessageType)type, gameStarted ? myCharacter : null);
|
message,
|
||||||
|
ChatMessageType.Default,
|
||||||
|
gameStarted ? myCharacter : null);
|
||||||
|
|
||||||
lastQueueChatMsgID++;
|
lastQueueChatMsgID++;
|
||||||
chatMessage.netStateID = lastQueueChatMsgID;
|
chatMessage.NetStateID = lastQueueChatMsgID;
|
||||||
|
|
||||||
chatMsgQueue.Add(chatMessage);
|
chatMsgQueue.Add(chatMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,7 +542,7 @@ namespace Barotrauma.Networking
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
foreach (Character c in Character.CharacterList)
|
/*foreach (Character c in Character.CharacterList)
|
||||||
{
|
{
|
||||||
if (c.IsDead) continue;
|
if (c.IsDead) continue;
|
||||||
|
|
||||||
@@ -554,7 +554,7 @@ namespace Barotrauma.Networking
|
|||||||
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
|
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
sparseUpdateTimer = DateTime.Now + sparseUpdateInterval;
|
sparseUpdateTimer = DateTime.Now + sparseUpdateInterval;
|
||||||
}
|
}
|
||||||
@@ -658,17 +658,11 @@ namespace Barotrauma.Networking
|
|||||||
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
|
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
|
||||||
outmsg.Write(c.lastSentEntityEventID);
|
outmsg.Write(c.lastSentEntityEventID);
|
||||||
|
|
||||||
foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children)
|
c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID);
|
||||||
|
foreach (ChatMessage cMsg in c.chatMsgQueue)
|
||||||
{
|
{
|
||||||
if (gc is GUITextBlock && gc.UserData is ChatMessage)
|
cMsg.ServerWrite(outmsg, c);
|
||||||
{
|
}
|
||||||
ChatMessage cMsg = (ChatMessage)gc.UserData;
|
|
||||||
if (cMsg.NetStateID > c.lastRecvChatMsgID)
|
|
||||||
{
|
|
||||||
cMsg.ServerWrite(outmsg, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Item.Spawner.NetStateID > c.lastRecvEntitySpawnID)
|
if (Item.Spawner.NetStateID > c.lastRecvEntitySpawnID)
|
||||||
{
|
{
|
||||||
@@ -681,7 +675,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (character is AICharacter)
|
if (character is AICharacter)
|
||||||
{
|
{
|
||||||
//TODO: don't send if the ai character is far from the client
|
//TODO: don't send if the ai character is far from the client
|
||||||
//(some sort of distance-based culling might be a good idea for player-controlled characters as well)
|
//(some sort of distance-based culling might be a good idea for player-controlled characters as well)
|
||||||
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
|
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
|
||||||
character.ServerWrite(outmsg, c);
|
character.ServerWrite(outmsg, c);
|
||||||
@@ -766,20 +760,12 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
|
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
|
||||||
|
|
||||||
foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children)
|
c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID);
|
||||||
|
foreach (ChatMessage cMsg in c.chatMsgQueue)
|
||||||
{
|
{
|
||||||
if (gc is GUITextBlock)
|
cMsg.ServerWrite(outmsg, c);
|
||||||
{
|
}
|
||||||
if (gc.UserData is ChatMessage)
|
|
||||||
{
|
|
||||||
ChatMessage cMsg = (ChatMessage)gc.UserData;
|
|
||||||
if (cMsg.NetStateID > c.lastRecvChatMsgID)
|
|
||||||
{
|
|
||||||
cMsg.ServerWrite(outmsg,c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
||||||
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
|
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
|
||||||
}
|
}
|
||||||
@@ -1214,16 +1200,139 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendChatMessage(string message, ChatMessageType? type = null)
|
/// <summary>
|
||||||
|
/// Add the message to the chatbox and pass it to all clients who can receive it
|
||||||
|
/// </summary>
|
||||||
|
public void SendChatMessage(string message, ChatMessageType? type = null, Client senderClient = null)
|
||||||
{
|
{
|
||||||
type = ChatMessageType.Default;
|
Character senderCharacter = null;
|
||||||
|
string senderName = "";
|
||||||
|
|
||||||
|
if (type==null)
|
||||||
|
{
|
||||||
|
string tempStr;
|
||||||
|
string command = ChatMessage.GetChatMessageCommand(message, out tempStr);
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case "r":
|
||||||
|
case "radio":
|
||||||
|
type = ChatMessageType.Radio;
|
||||||
|
break;
|
||||||
|
case "d":
|
||||||
|
case "dead":
|
||||||
|
type = ChatMessageType.Dead;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = ChatMessageType.Default;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChatMessage chatMessage = ChatMessage.Create(
|
if (gameStarted)
|
||||||
gameStarted && myCharacter != null ? myCharacter.Name : name,
|
{
|
||||||
message, (ChatMessageType)type, gameStarted ? myCharacter : null);
|
//msg sent by the server
|
||||||
|
if (senderClient == null)
|
||||||
|
{
|
||||||
|
senderCharacter = myCharacter;
|
||||||
|
senderName = myCharacter == null ? name : myCharacter.Name;
|
||||||
|
}
|
||||||
|
//msg sent by a client
|
||||||
|
else
|
||||||
|
{
|
||||||
|
senderCharacter = senderClient.Character;
|
||||||
|
senderName = senderCharacter == null ? senderClient.name : senderCharacter.Name;
|
||||||
|
|
||||||
|
//sender doesn't have an alive character -> only ChatMessageType.Dead allowed
|
||||||
|
if (senderCharacter == null || senderCharacter.IsDead)
|
||||||
|
{
|
||||||
|
type = ChatMessageType.Dead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//game not started -> clients can only send normal chatmessages
|
||||||
|
if (senderClient != null)
|
||||||
|
{
|
||||||
|
type = ChatMessageType.Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddChatMessage(chatMessage);
|
//check if the client is allowed to send the message
|
||||||
|
WifiComponent senderRadio = null;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ChatMessageType.Radio:
|
||||||
|
if (senderCharacter == null) return;
|
||||||
|
|
||||||
|
//return if senderCharacter doesn't have a working radio
|
||||||
|
var radio = senderCharacter.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
|
||||||
|
if (radio == null) return;
|
||||||
|
|
||||||
|
senderRadio = radio.GetComponent<WifiComponent>();
|
||||||
|
if (!senderRadio.CanTransmit()) return;
|
||||||
|
break;
|
||||||
|
case ChatMessageType.Dead:
|
||||||
|
//character still alive -> not allowed
|
||||||
|
if (senderClient != null && senderCharacter != null && !senderCharacter.IsDead)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check which clients can receive the message and apply distance effects
|
||||||
|
foreach (Client client in ConnectedClients)
|
||||||
|
{
|
||||||
|
string modifiedMessage = message;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ChatMessageType.Default:
|
||||||
|
if (senderCharacter != null &&
|
||||||
|
client.Character != null && !client.Character.IsDead)
|
||||||
|
{
|
||||||
|
modifiedMessage = ChatMessage.ApplyDistanceEffect(client.Character, senderCharacter, message, ChatMessage.SpeakRange);
|
||||||
|
|
||||||
|
//too far to hear the msg -> don't send
|
||||||
|
if (string.IsNullOrWhiteSpace(modifiedMessage)) continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ChatMessageType.Radio:
|
||||||
|
if (client.Character != null && !client.Character.IsDead)
|
||||||
|
{
|
||||||
|
var radio = client.Character.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
|
||||||
|
//client doesn't have a radio -> don't send
|
||||||
|
if (radio == null) return;
|
||||||
|
|
||||||
|
var radioComponent = radio.GetComponent<WifiComponent>();
|
||||||
|
if (!radioComponent.CanReceive(senderRadio)) return;
|
||||||
|
|
||||||
|
modifiedMessage = ChatMessage.ApplyDistanceEffect(radio, senderRadio.Item, message, senderRadio.Range);
|
||||||
|
|
||||||
|
//too far to hear the msg -> don't send
|
||||||
|
if (string.IsNullOrWhiteSpace(modifiedMessage)) continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ChatMessageType.Dead:
|
||||||
|
if (client.Character != null && !client.Character.IsDead) return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var chatMsg = ChatMessage.Create(
|
||||||
|
senderName,
|
||||||
|
modifiedMessage,
|
||||||
|
(ChatMessageType)type,
|
||||||
|
senderCharacter);
|
||||||
|
|
||||||
|
chatMsg.NetStateID = client.chatMsgQueue.Count > 0 ?
|
||||||
|
client.chatMsgQueue.Last().NetStateID + 1 :
|
||||||
|
client.lastRecvChatMsgID+1;
|
||||||
|
|
||||||
|
client.chatMsgQueue.Add(chatMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddChatMessage(message, (ChatMessageType)type, senderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||||
|
|||||||
@@ -195,7 +195,14 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(message)) return false;
|
if (string.IsNullOrWhiteSpace(message)) return false;
|
||||||
|
|
||||||
SendChatMessage(message);
|
if (this == GameMain.Server)
|
||||||
|
{
|
||||||
|
GameMain.Server.SendChatMessage(message, null, null);
|
||||||
|
}
|
||||||
|
else if (this == GameMain.Client)
|
||||||
|
{
|
||||||
|
GameMain.Client.SendChatMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
if (textBox == chatMsgBox) textBox.Deselect();
|
if (textBox == chatMsgBox) textBox.Deselect();
|
||||||
|
|
||||||
@@ -209,33 +216,12 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void AddChatMessage(ChatMessage message)
|
public void AddChatMessage(ChatMessage message)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (message.Type == ChatMessageType.Radio &&
|
|
||||||
Character.Controlled != null &&
|
|
||||||
message.Sender != null && message.Sender != myCharacter)
|
|
||||||
{
|
|
||||||
var radio = message.Sender.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
|
|
||||||
if (radio == null) return;
|
|
||||||
|
|
||||||
message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Radio]);
|
|
||||||
|
|
||||||
var radioComponent = radio.GetComponent<WifiComponent>();
|
|
||||||
radioComponent.Transmit(message.TextWithSender);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameServer.Log(message.TextWithSender, message.Color);
|
GameServer.Log(message.TextWithSender, message.Color);
|
||||||
|
|
||||||
string displayedText = message.Text;
|
string displayedText = message.Text;
|
||||||
|
|
||||||
if (message.Sender != null)
|
if (message.Sender != null)
|
||||||
{
|
{
|
||||||
if (message.Type == ChatMessageType.Default && Character.Controlled != null)
|
|
||||||
{
|
|
||||||
displayedText = message.ApplyDistanceEffect(Character.Controlled);
|
|
||||||
if (string.IsNullOrWhiteSpace(displayedText)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Default]);
|
message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Default]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,8 +265,6 @@ namespace Barotrauma.Networking
|
|||||||
GUI.PlayUISound(soundType);
|
GUI.PlayUISound(soundType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendChatMessage(string message, ChatMessageType? type = null) { }
|
|
||||||
|
|
||||||
public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { }
|
public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { }
|
||||||
|
|
||||||
public virtual void AddToGUIUpdateList()
|
public virtual void AddToGUIUpdateList()
|
||||||
|
|||||||
Reference in New Issue
Block a user