Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Networking/ChatMessage.cs
2 using Microsoft.Xna.Framework;
3 using System;
4 
5 namespace Barotrauma.Networking
6 {
7  partial class ChatMessage
8  {
9  public virtual void ClientWrite(in SegmentTableWriter<ClientNetSegment> segmentTableWriter, IWriteMessage msg)
10  {
11  segmentTableWriter.StartNewSegment(ClientNetSegment.ChatMessage);
13  msg.WriteRangedInteger((int)Type, 0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
14  msg.WriteRangedInteger((int)ChatMode, 0, Enum.GetValues(typeof(ChatMode)).Length - 1);
15  msg.WriteString(Text);
16  }
17 
18  public static void ClientRead(IReadMessage msg)
19  {
20  UInt16 id = msg.ReadUInt16();
21  ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
23  string txt = "";
24  string styleSetting = string.Empty;
25 
26  if (type != ChatMessageType.Order)
27  {
28  changeType = (PlayerConnectionChangeType)msg.ReadByte();
29  }
30  txt = msg.ReadString();
31 
32  string senderName = msg.ReadString();
33  Entity sender = null;
34  Character senderCharacter = null;
35  Client senderClient = null;
36  bool hasSenderClient = msg.ReadBoolean();
37  if (hasSenderClient)
38  {
39  string userId = msg.ReadString();
40  senderClient = GameMain.Client.ConnectedClients.Find(c
41  => c.SessionOrAccountIdMatches(userId));
42  if (senderClient != null) { senderName = senderClient.Name; }
43  }
44  bool hasSender = msg.ReadBoolean();
45  if (hasSender)
46  {
47  sender = Entity.FindEntityByID(msg.ReadUInt16());
48  senderCharacter = sender as Character;
49  if (sender is Character or Item)
50  {
51  senderName = OrderChatMessage.NameFromEntityOrNull(sender);
52  }
53  }
54 
55  Color? textColor = null;
56  if (msg.ReadBoolean())
57  {
58  textColor = msg.ReadColorR8G8B8A8();
59  }
60 
61  msg.ReadPadBits();
62 
63  switch (type)
64  {
65  case ChatMessageType.Default:
66  break;
67  case ChatMessageType.Order:
68  var orderMessageInfo = OrderChatMessage.ReadOrder(msg);
69  if (orderMessageInfo.OrderIdentifier == Identifier.Empty)
70  {
71  DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
72  if (NetIdUtils.IdMoreRecent(id, LastID)) { LastID = id; }
73  return;
74  }
75  var orderPrefab = orderMessageInfo.OrderPrefab ?? OrderPrefab.Prefabs[orderMessageInfo.OrderIdentifier];
76  Identifier orderOption = orderMessageInfo.OrderOption;
77  orderOption = orderOption.IfEmpty(
78  orderMessageInfo.OrderOptionIndex.HasValue && orderMessageInfo.OrderOptionIndex >= 0 && orderMessageInfo.OrderOptionIndex < orderPrefab.Options.Length
79  ? orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value]
80  : Identifier.Empty);
81  string targetRoom;
82 
83  if (orderMessageInfo.TargetEntity is Hull targetHull)
84  {
85  targetRoom = targetHull.DisplayName.Value;
86  }
87  else
88  {
89  targetRoom = senderCharacter?.CurrentHull?.DisplayName?.Value;
90  }
91 
92  if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
93  {
94  Order order = null;
95  switch (orderMessageInfo.TargetType)
96  {
97  case Order.OrderTargetType.Entity:
98  order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity, orderPrefab.GetTargetItemComponent(orderMessageInfo.TargetEntity as Item), orderGiver: senderCharacter);
99  break;
100  case Order.OrderTargetType.Position:
101  order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetPosition, orderGiver: senderCharacter);
102  break;
103  case Order.OrderTargetType.WallSection:
104  order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity as Structure, orderMessageInfo.WallSectionIndex, orderGiver: senderCharacter);
105  break;
106  }
107 
108  if (order != null)
109  {
110  order = order.WithManualPriority(orderMessageInfo.Priority);
111  if (order.TargetAllCharacters)
112  {
113  var fadeOutTime = !orderPrefab.IsIgnoreOrder ? (float?)orderPrefab.FadeOutTime : null;
114  GameMain.GameSession?.CrewManager?.AddOrder(order, fadeOutTime);
115  }
116  else
117  {
118  orderMessageInfo.TargetCharacter?.SetOrder(order, orderMessageInfo.IsNewOrder);
119  }
120  }
121  }
122 
123  if (NetIdUtils.IdMoreRecent(id, LastID))
124  {
125  Order order = null;
126  if (orderMessageInfo.TargetPosition != null)
127  {
128  order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetPosition, orderGiver: senderCharacter)
129  .WithManualPriority(orderMessageInfo.Priority);
130  }
131  else if (orderMessageInfo.WallSectionIndex != null)
132  {
133  order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity as Structure, orderMessageInfo.WallSectionIndex, orderGiver: senderCharacter)
134  .WithManualPriority(orderMessageInfo.Priority);
135  }
136  else
137  {
138  order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity, orderPrefab.GetTargetItemComponent(orderMessageInfo.TargetEntity as Item), orderGiver: senderCharacter)
139  .WithManualPriority(orderMessageInfo.Priority);
140  }
142  new OrderChatMessage(order, txt, orderMessageInfo.TargetCharacter, senderCharacter));
143  LastID = id;
144  }
145  return;
146  case ChatMessageType.ServerMessageBox:
147  txt = TextManager.GetServerMessage(txt).Value;
148  break;
149  case ChatMessageType.ServerMessageBoxInGame:
150  styleSetting = msg.ReadString();
151  txt = TextManager.GetServerMessage(txt).Value;
152  break;
153  }
154 
155  if (NetIdUtils.IdMoreRecent(id, LastID))
156  {
157  switch (type)
158  {
159  case ChatMessageType.MessageBox:
160  case ChatMessageType.ServerMessageBox:
161  //only show the message box if the text differs from the text in the currently visible box
162  if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt)
163  {
164  GUIMessageBox messageBox = new GUIMessageBox("", txt);
165  if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
166  }
167  break;
168  case ChatMessageType.ServerMessageBoxInGame:
169  {
170  GUIMessageBox messageBox = new GUIMessageBox("", txt, Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
171  if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
172  }
173  break;
174  case ChatMessageType.Console:
175  DebugConsole.NewMessage(txt, textColor == null ? MessageColor[(int)ChatMessageType.Console] : textColor.Value);
176  break;
177  case ChatMessageType.ServerLog:
178  if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType))
179  {
180  return;
181  }
182  GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
183  break;
184  default:
185  GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, sender, changeType, textColor: textColor);
186  if (type == ChatMessageType.Radio && CanUseRadio(senderCharacter, out WifiComponent radio))
187  {
188  Signal s = new Signal(txt, sender: senderCharacter, source: radio.Item);
189  radio.TransmitSignal(s, sentFromChat: true);
190  }
191  break;
192  }
193  LastID = id;
194  }
195  }
196  }
197 }
static Entity FindEntityByID(ushort ID)
Find an entity based on the ID
Definition: Entity.cs:204
static GUIComponent VisibleBox
static GameSession?? GameSession
Definition: GameMain.cs:88
static GameScreen GameScreen
Definition: GameMain.cs:52
static GameClient Client
Definition: GameMain.cs:188
static bool CanUseRadio(Character sender, bool ignoreJamming=false)
virtual void ClientWrite(in SegmentTableWriter< ClientNetSegment > segmentTableWriter, IWriteMessage msg)
override IReadOnlyList< Client > ConnectedClients
Definition: GameClient.cs:133
override void AddChatMessage(ChatMessage message)
Definition: GameClient.cs:2741
static string NameFromEntityOrNull(Entity entity)
bool IsIgnoreOrder
Definition: Order.cs:558
Order WithManualPriority(int newPriority)
Definition: Order.cs:709
bool TargetAllCharacters
Definition: Order.cs:551
static readonly PrefabCollection< OrderPrefab > Prefabs
Definition: Order.cs:41
Microsoft.Xna.Framework.Color ReadColorR8G8B8A8()
int ReadRangedInteger(int min, int max)
void WriteRangedInteger(int val, int min, int max)