Skip to content

Commit

Permalink
Add text chat
Browse files Browse the repository at this point in the history
  • Loading branch information
Lacyway committed Jun 5, 2024
1 parent e1e1cfa commit cb26102
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 37 deletions.
134 changes: 134 additions & 0 deletions Fika.Core/Coop/Custom/FikaChat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using Comfort.Common;
using EFT.UI;
using Fika.Core.Coop.Matchmaker;
using Fika.Core.Networking;
using Fika.Core.Networking.Packets.Communication;
using HarmonyLib;
using LiteNetLib.Utils;
using System;
using UnityEngine;

namespace Fika.Core.Coop.Custom
{
internal class FikaChat : MonoBehaviour
{
private Rect windowRect;
private string nickname;
private string chatText;
private string textField;
private bool show;
private bool isServer;
private NetDataWriter writer;
private UISoundsWrapper soundsWrapper;

protected void Awake()
{
windowRect = new(20, Screen.height - 260, 600, 250);
nickname = MatchmakerAcceptPatches.PMCName;
chatText = string.Empty;
textField = string.Empty;
show = false;
isServer = MatchmakerAcceptPatches.IsServer;
writer = new();
GUISounds guiSounds = Singleton<GUISounds>.Instance;
soundsWrapper = Traverse.Create(guiSounds).Field<UISoundsWrapper>("uisoundsWrapper_0").Value;
}

protected void Update()
{
if (Input.GetKeyDown(KeyCode.Backspace))
{
ToggleVisibility();
}
}

protected void OnGUI()
{
if (!show)
{
return;
}

GUI.skin.label.alignment = TextAnchor.LowerLeft;
GUI.skin.window.alignment = TextAnchor.UpperLeft;
GUI.Window(0, windowRect, DrawWindow, "Fika Chat");

if (Event.current.isKey)
{
if (Event.current.keyCode is KeyCode.Return or KeyCode.KeypadEnter && show)
{
SendMessage();
GUI.UnfocusWindow();
GUI.FocusControl(null);
}
}
}

private void ToggleVisibility()
{
show = !show;
}

private void SendMessage()
{
if (!show)
{
return;
}

if (!string.IsNullOrEmpty(textField))
{
string message = textField;
textField = string.Empty;

TextMessagePacket packet = new(nickname, message);
writer.Reset();

if (isServer)
{
Singleton<FikaServer>.Instance.SendDataToAll(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableUnordered);
}
else
{
Singleton<FikaClient>.Instance.SendData(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableUnordered);
}
AudioClip outgoingClip = soundsWrapper.GetSocialNetworkClip(ESocialNetworkSoundType.OutgoingMessage);
Singleton<GUISounds>.Instance.PlaySound(outgoingClip);
AddMessage(nickname + ": " + message);
}
}

public void ReceiveMessage(string nickname, string message)
{
AudioClip incomingClip = soundsWrapper.GetSocialNetworkClip(ESocialNetworkSoundType.IncomingMessage);
Singleton<GUISounds>.Instance.PlaySound(incomingClip);
AddMessage(nickname + ": " + message);
}

private void AddMessage(string message)
{
chatText = string.Concat(chatText, message, "\n");
if (chatText.Length > 1000)
{
chatText = chatText.Substring(500);
}
}

private void DrawWindow(int windowId)
{
Rect rect = new(5, 15, 580, 200);
GUI.Label(rect, chatText);
rect.y += rect.height;
Rect textRect = new(rect.x, rect.y, rect.width - 55, 25);
textField = GUI.TextField(textRect, textField);
rect.x += 535;
Rect buttonRect = new(rect.x, rect.y, 50, 25);
if (GUI.Button(buttonRect, "SEND"))
{
SendMessage();
GUI.UnfocusWindow();
GUI.FocusControl(null);
}
}
}
}
61 changes: 41 additions & 20 deletions Fika.Core/Networking/FikaClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
using EFT.UI;
using EFT.Weather;
using Fika.Core.Coop.Components;
using Fika.Core.Coop.Custom;
using Fika.Core.Coop.GameMode;
using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
using Fika.Core.Modding;
using Fika.Core.Modding.Events;
using Fika.Core.Networking.Packets.Communication;
using Fika.Core.Networking.Packets.GameWorld;
using Fika.Core.Networking.Packets.Player;
using HarmonyLib;
Expand Down Expand Up @@ -51,7 +53,7 @@ public NetManager NetClient
/*public string IP { get; private set; }
public int Port { get; private set; }*/
public bool SpawnPointsReceived { get; private set; } = false;
private readonly ManualLogSource clientLogger = BepInEx.Logging.Logger.CreateLogSource("Fika.Client");
private readonly ManualLogSource logger = BepInEx.Logging.Logger.CreateLogSource("Fika.Client");
public bool Started
{
get
Expand All @@ -63,6 +65,7 @@ public bool Started
return _netClient.IsRunning;
}
}
private FikaChat fikaChat;

public void Init()
{
Expand All @@ -89,6 +92,7 @@ public void Init()
packetProcessor.SubscribeNetSerializable<AssignNetIdPacket>(OnAssignNetIdPacketReceived);
packetProcessor.SubscribeNetSerializable<SyncNetIdPacket>(OnSyncNetIdPacketReceived);
packetProcessor.SubscribeNetSerializable<OperationCallbackPacket>(OnOperationCallbackPacketReceived);
packetProcessor.SubscribeNetSerializable<TextMessagePacket>(OnTextMessagePacketReceived);

_netClient = new NetManager(this)
{
Expand Down Expand Up @@ -124,10 +128,21 @@ public void Init()
FikaEventDispatcher.DispatchEvent(new FikaClientCreatedEvent(this));
}

private void OnTextMessagePacketReceived(TextMessagePacket packet)
{
logger.LogInfo($"Received message from: {packet.Nickname}, Message: {packet.Message}");

if (fikaChat != null)
{
fikaChat.ReceiveMessage(packet.Nickname, packet.Message);
}
}

public void SetupGameVariables(CoopPlayer coopPlayer)
{
coopHandler = CoopHandler.CoopHandlerParent.GetComponent<CoopHandler>();
MyPlayer = coopPlayer;
fikaChat = gameObject.AddComponent<FikaChat>();
}

private void OnOperationCallbackPacketReceived(OperationCallbackPacket packet)
Expand Down Expand Up @@ -277,7 +292,7 @@ private void OnWeatherPacketReceived(WeatherPacket packet)
}
else
{
clientLogger.LogWarning("WeatherPacket2Received: WeatherControll was null!");
logger.LogWarning("WeatherPacket2Received: WeatherControll was null!");
}
}
}
Expand Down Expand Up @@ -324,7 +339,7 @@ private void OnExfiltrationPacketReceived(ExfiltrationPacket packet)
}
else
{
clientLogger.LogWarning($"ExfiltrationPacketPacketReceived::ExfiltrationPoints: Could not find exfil point with name '{exfilPoint.Key}'");
logger.LogWarning($"ExfiltrationPacketPacketReceived::ExfiltrationPoints: Could not find exfil point with name '{exfilPoint.Key}'");
}
}

Expand Down Expand Up @@ -352,7 +367,7 @@ private void OnExfiltrationPacketReceived(ExfiltrationPacket packet)
}
else
{
clientLogger.LogWarning($"ExfiltrationPacketPacketReceived::ScavExfiltrationPoints: Could not find exfil point with name '{scavExfilPoint.Key}'");
logger.LogWarning($"ExfiltrationPacketPacketReceived::ScavExfiltrationPoints: Could not find exfil point with name '{scavExfilPoint.Key}'");
}
}

Expand All @@ -364,7 +379,7 @@ private void OnExfiltrationPacketReceived(ExfiltrationPacket packet)
}
else
{
clientLogger.LogWarning($"ExfiltrationPacketPacketReceived: ExfiltrationController was null");
logger.LogWarning($"ExfiltrationPacketPacketReceived: ExfiltrationController was null");
}
}
}
Expand Down Expand Up @@ -416,7 +431,7 @@ private void OnGenericPacketReceived(GenericPacket packet)
}
else
{
clientLogger.LogWarning("GenericPacketReceived: Could not find locomotive!");
logger.LogWarning("GenericPacketReceived: Could not find locomotive!");
}
}
break;
Expand Down Expand Up @@ -461,16 +476,16 @@ private void OnGenericPacketReceived(GenericPacket packet)
{
botToDispose.Dispose();
AssetPoolObject.ReturnToPool(botToDispose.gameObject, true);
clientLogger.LogInfo("Disposing bot: " + packet.BotNetId);
logger.LogInfo("Disposing bot: " + packet.BotNetId);
}
else
{
clientLogger.LogWarning("Unable to dispose of bot: " + packet.BotNetId);
logger.LogWarning("Unable to dispose of bot: " + packet.BotNetId);
}
}
else
{
clientLogger.LogWarning("Unable to dispose of bot: " + packet.BotNetId + ", unable to find GameObject");
logger.LogWarning("Unable to dispose of bot: " + packet.BotNetId + ", unable to find GameObject");
}
}
break;
Expand All @@ -489,13 +504,13 @@ private void OnGenericPacketReceived(GenericPacket packet)
if (!botToEnable.gameObject.activeSelf)
{
#if DEBUG
clientLogger.LogWarning("Enabling " + packet.BotNetId);
logger.LogWarning("Enabling " + packet.BotNetId);
#endif
botToEnable.gameObject.SetActive(true);
}
else
{
clientLogger.LogWarning($"Received packet to enable {botToEnable.ProfileId}, netId {packet.BotNetId} but the bot was already enabled!");
logger.LogWarning($"Received packet to enable {botToEnable.ProfileId}, netId {packet.BotNetId} but the bot was already enabled!");
}
}
}
Expand All @@ -507,13 +522,13 @@ private void OnGenericPacketReceived(GenericPacket packet)
if (botToEnable.gameObject.activeSelf)
{
#if DEBUG
clientLogger.LogWarning("Disabling " + packet.BotNetId);
logger.LogWarning("Disabling " + packet.BotNetId);
#endif
botToEnable.gameObject.SetActive(false);
}
else
{
clientLogger.LogWarning($"Received packet to disable {botToEnable.ProfileId}, netId {packet.BotNetId} but the bot was already disabled!");
logger.LogWarning($"Received packet to disable {botToEnable.ProfileId}, netId {packet.BotNetId} but the bot was already disabled!");
}
}
}
Expand All @@ -537,7 +552,7 @@ private void OnAirdropLootPacketReceived(AirdropLootPacket packet)
}
else
{
clientLogger.LogError("OnAirdropLootPacketReceived: Received loot package but manager is not instantiated!");
logger.LogError("OnAirdropLootPacketReceived: Received loot package but manager is not instantiated!");
}
}

Expand All @@ -564,7 +579,7 @@ private void OnAirdropPacketReceived(AirdropPacket packet)
}
else
{
clientLogger.LogError("OnAirdropPacketReceived: Received package but manager is not instantiated!");
logger.LogError("OnAirdropPacketReceived: Received package but manager is not instantiated!");
}
}

Expand All @@ -581,15 +596,15 @@ private void OnAllCharacterRequestPacketReceived(AllCharacterRequestPacket packe
{
if (!packet.IsRequest)
{
clientLogger.LogInfo($"Received CharacterRequest! ProfileID: {packet.PlayerInfo.Profile.ProfileId}, Nickname: {packet.PlayerInfo.Profile.Nickname}");
logger.LogInfo($"Received CharacterRequest! ProfileID: {packet.PlayerInfo.Profile.ProfileId}, Nickname: {packet.PlayerInfo.Profile.Nickname}");
if (packet.ProfileId != MyPlayer.ProfileId)
{
coopHandler.QueueProfile(packet.PlayerInfo.Profile, packet.Position, packet.NetId, packet.IsAlive, packet.IsAI);
}
}
else if (packet.IsRequest)
{
clientLogger.LogInfo($"Received CharacterRequest from server, send my Profile.");
logger.LogInfo($"Received CharacterRequest from server, send my Profile.");
AllCharacterRequestPacket requestPacket = new(MyPlayer.ProfileId)
{
IsRequest = false,
Expand Down Expand Up @@ -689,6 +704,12 @@ protected void Update()
protected void OnDestroy()
{
_netClient?.Stop();

if (fikaChat != null)
{
Destroy(fikaChat);
}

FikaEventDispatcher.DispatchEvent(new FikaClientDestroyedEvent(this));
}

Expand All @@ -706,7 +727,7 @@ public void OnPeerConnected(NetPeer peer)

public void OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode)
{
clientLogger.LogInfo("[CLIENT] We received error " + socketErrorCode);
logger.LogInfo("[CLIENT] We received error " + socketErrorCode);
}

public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod)
Expand All @@ -718,7 +739,7 @@ public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketRead
{
if (messageType == UnconnectedMessageType.BasicMessage && _netClient.ConnectedPeersCount == 0 && reader.GetInt() == 1)
{
clientLogger.LogInfo("[CLIENT] Received discovery response. Connecting to: " + remoteEndPoint);
logger.LogInfo("[CLIENT] Received discovery response. Connecting to: " + remoteEndPoint);
_netClient.Connect(remoteEndPoint, "fika.core");
}
}
Expand All @@ -737,7 +758,7 @@ public void OnConnectionRequest(ConnectionRequest request)

public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
{
clientLogger.LogInfo("[CLIENT] We disconnected because " + disconnectInfo.Reason);
logger.LogInfo("[CLIENT] We disconnected because " + disconnectInfo.Reason);
if (disconnectInfo.Reason is DisconnectReason.Timeout)
{
NotificationManagerClass.DisplayWarningNotification("Lost connection to host!");
Expand Down
Loading

0 comments on commit cb26102

Please sign in to comment.