Skip to content

Commit 274eba6

Browse files
authored
Merge pull request #17 from lexonegit/fix-chars-too-small
Fix chars too small
2 parents a23b981 + f71b516 commit 274eba6

File tree

10 files changed

+95
-91
lines changed

10 files changed

+95
-91
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [1.2.2] - 2023-03-27
8+
9+
### Added
10+
- Added JoinChannel and LeaveChannel methods
11+
12+
### Changed
13+
- Fixed decoded chars array being too small issue
14+
- Switched to using StringBuilder when decoding IRC messages
15+
- Upgraded ExampleProject to Unity 2021.3.21f1 (LTS)
16+
17+
718
## [1.2.1] - 2023-01-24
819

920
### Added

Unity-Twitch-Chat/Assets/ExampleProject/Scenes/ExampleScene.unity

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ MonoBehaviour:
773773
showThreadDebug: 1
774774
useRandomColorForUndefined: 1
775775
readInterval: 50
776-
readBufferSize: 1024
776+
readBufferSize: 256
777777
writeInterval: 50
778778
--- !u!4 &1312367230
779779
Transform:

Unity-Twitch-Chat/Assets/Package/Runtime/IRC.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ public partial class IRC : MonoBehaviour
4848

4949
[Tooltip("The number of milliseconds between each time the read thread checks for new messages.")]
5050
[SerializeField] public int readInterval = 50;
51-
[Tooltip("The capacity of the read buffer. Smaller values consume less memory but require more cycles to retrieve data.")]
52-
[SerializeField] public int readBufferSize = 1024;
51+
[Tooltip("The capacity of the read buffer. Smaller values consume less memory but require more cycles to retrieve data (CPU usage)")]
52+
[SerializeField] public ReadBufferSize readBufferSize = ReadBufferSize._256;
5353

5454
[Header("Chat write settings (write thread)")]
5555

5656
[Tooltip("The number of milliseconds between each time the write thread checks its queues.")]
5757
public int writeInterval = 50;
5858

59-
59+
6060
// If the game is paused for a significant amount of time and then unpaused,
6161
// there could be a lot of data to handle, which could cause lag spikes.
6262
// To prevent this, we limit the amount of data handled per frame.
@@ -301,7 +301,7 @@ public void SendChatMessage(string message)
301301
/// Join a new channel
302302
/// </summary>
303303
/// <param name="channel">The channel to join</param>
304-
public void JoinChannel(string channel)
304+
public void JoinChannel(string channel)
305305
{
306306
if (channel != "")
307307
connection.SendCommand("JOIN #" + channel.ToLower(), true);
@@ -311,7 +311,7 @@ public void JoinChannel(string channel)
311311
/// Leaves a channel
312312
/// </summary>
313313
/// <param name="channel">The channel to leave</param>
314-
public void LeaveChannel(string channel)
314+
public void LeaveChannel(string channel)
315315
{
316316
if (channel != "")
317317
connection.SendCommand("PART #" + channel.ToLower(), true);

Unity-Twitch-Chat/Assets/Package/Runtime/TwitchConnection.ReadThread.cs

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,73 +3,71 @@
33
using System.Text;
44
using System.Threading;
55
using System.Net.Sockets;
6-
7-
using Random = System.Random;
6+
using System.IO;
87

98
namespace Lexone.UnityTwitchChat
109
{
1110
internal partial class TwitchConnection
1211
{
13-
private string currentRawLine;
14-
private byte[] inputBuffer;
15-
private char[] chars;
16-
private Decoder decoder = Encoding.UTF8.GetDecoder();
17-
1812
// Used to generate session based random colors for undefined users
19-
private int sessionRandom = DateTime.Now.Second;
13+
private int sessionRandom = DateTime.Now.Second;
2014

2115
private void ReadThreadLoop()
2216
{
2317
if (showThreadDebug)
2418
Debug.Log($"{Tags.thread} Read thread started");
2519

26-
Socket socket = tcpClient.Client;
27-
currentRawLine = string.Empty;
28-
inputBuffer = new byte[readBufferSize];
29-
chars = new char[readBufferSize];
30-
31-
while (ThreadsRunning)
20+
using (NetworkStream stream = tcpClient.GetStream())
3221
{
33-
if (!CheckConnection(socket))
34-
{
35-
// Sometimes, right after a new TcpClient is created, the socket says
36-
// it has been shutdown. This catches that case and attempts reconnecting.
37-
alertQueue.Enqueue(IRCReply.CONNECTION_INTERRUPTED);
38-
break;
39-
}
22+
byte[] readBuffer = new byte[readBufferSize];
23+
StringBuilder currentLine = new StringBuilder();
24+
Decoder decoder = Encoding.UTF8.GetDecoder();
4025

41-
while (socket.Available > 0)
42-
{
43-
// Receive data from the socket
44-
int bytesReceived = socket.Receive(inputBuffer);
26+
// Temporary solution(?):
27+
// Certain multi-byte UTF-8 characters can result in overflowing (special characters)
28+
// So we add a little extra space to the chars array just to be safe
29+
char[] chars = new char[readBufferSize + Mathf.Clamp(readBufferSize / 4, 1, 32)];
4530

46-
// Decode data into text
47-
int charCount = decoder.GetChars(inputBuffer, 0, bytesReceived, chars, 0);
31+
while (ThreadsRunning)
32+
{
33+
// Check if the connection is still alive
34+
if (!CheckConnection(tcpClient.Client))
35+
{
36+
alertQueue.Enqueue(IRCReply.CONNECTION_INTERRUPTED);
37+
return;
38+
}
4839

49-
for (int i = 0; i < charCount; ++i)
40+
while (stream.DataAvailable)
5041
{
51-
// If the character is a linebreak, we have a complete line
52-
if (chars[i] == '\n' || chars[i] == '\r')
42+
// Read the bytes from the stream
43+
int bytesReceived = stream.Read(readBuffer, 0, readBufferSize);
44+
45+
// Decode the bytes to chars
46+
int charsDecoded = decoder.GetChars(readBuffer, 0, bytesReceived, chars, 0);
47+
48+
for (int i = 0; i < charsDecoded; ++i)
5349
{
54-
// Process the line if it's not empty
55-
if (currentRawLine.Length > 0)
50+
// Character is a linebreak -> We have a complete line
51+
if (chars[i] == '\n' || chars[i] == '\r')
5652
{
57-
HandleRawLine(currentRawLine);
58-
currentRawLine = string.Empty;
53+
// If the line is not empty, handle it
54+
if (currentLine.Length > 0)
55+
{
56+
HandleRawLine(currentLine.ToString());
57+
currentLine.Clear();
58+
}
59+
}
60+
else
61+
{
62+
// Append the character to the current line
63+
currentLine.Append(chars[i]);
5964
}
60-
continue;
61-
}
62-
63-
// Otherwise, append the character to the current line
64-
else
65-
{
66-
currentRawLine += chars[i];
6765
}
6866
}
69-
}
7067

71-
// Sleep to prevent high CPU usage
72-
Thread.Sleep(readInterval);
68+
// Sleep to prevent high CPU usage
69+
Thread.Sleep(readInterval);
70+
}
7371
}
7472

7573
if (showThreadDebug)
@@ -87,6 +85,7 @@ private bool CheckConnection(Socket socket)
8785
return true;
8886
}
8987

88+
9089
private void HandleRawLine(string raw)
9190
{
9291
if (showIRCDebug)
@@ -147,10 +146,10 @@ private void HandlePRIVMSG(string ircString, string tagString)
147146
var channel = ParseHelper.ParseChannel(ircString);
148147
var message = ParseHelper.ParseMessage(ircString);
149148
var tags = ParseHelper.ParseTags(tagString);
150-
149+
151150
// Not all users have set their Twitch name color, so we need to check for that
152151
if (tags.colorHex.Length <= 0)
153-
tags.colorHex = useRandomColorForUndefined
152+
tags.colorHex = useRandomColorForUndefined
154153
? ChatColors.GetRandomNameColor(sessionRandom, login)
155154
: "#FFFFFF";
156155

Unity-Twitch-Chat/Assets/Package/Runtime/TwitchConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public TwitchConnection(IRC irc)
2323
this.nick = irc.username;
2424
this.channel = irc.channel;
2525

26-
this.readBufferSize = irc.readBufferSize;
26+
this.readBufferSize = (int)irc.readBufferSize; // Parse enum value
2727
this.readInterval = irc.readInterval;
2828
this.writeInterval = irc.writeInterval;
2929

Unity-Twitch-Chat/Assets/Package/Runtime/Utils.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ public enum IRCReply
2424
NO_CONNECTION = 499,
2525
}
2626

27+
28+
public enum ReadBufferSize
29+
{
30+
_32 = 32,
31+
_64 = 64,
32+
_128 = 128,
33+
_256 = 256,
34+
_512 = 512,
35+
_1024 = 1024,
36+
_2048 = 2048,
37+
_4096 = 4096,
38+
}
39+
2740
public static class Tags
2841
{
2942
public static string read = "<color=#00ff00><b>[IRC READ]</b></color>";

Unity-Twitch-Chat/Packages/manifest.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"dependencies": {
3-
"com.unity.collab-proxy": "1.17.7",
3+
"com.unity.collab-proxy": "2.0.1",
44
"com.unity.feature.2d": "1.0.0",
5-
"com.unity.ide.rider": "3.0.16",
6-
"com.unity.ide.visualstudio": "2.0.16",
5+
"com.unity.ide.rider": "3.0.18",
6+
"com.unity.ide.visualstudio": "2.0.17",
77
"com.unity.ide.vscode": "1.2.5",
88
"com.unity.test-framework": "1.1.31",
99
"com.unity.textmeshpro": "3.0.6",
1010
"com.unity.timeline": "1.6.4",
1111
"com.unity.ugui": "1.0.0",
12-
"com.unity.visualscripting": "1.7.8",
12+
"com.unity.visualscripting": "1.8.0",
1313
"com.unity.modules.ai": "1.0.0",
1414
"com.unity.modules.androidjni": "1.0.0",
1515
"com.unity.modules.animation": "1.0.0",

Unity-Twitch-Chat/Packages/packages-lock.json

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@
3939
"url": "https://packages.unity.com"
4040
},
4141
"com.unity.2d.psdimporter": {
42-
"version": "6.0.6",
42+
"version": "6.0.7",
4343
"depth": 1,
4444
"source": "registry",
4545
"dependencies": {
46-
"com.unity.2d.animation": "7.0.8",
47-
"com.unity.2d.common": "6.0.5",
46+
"com.unity.2d.animation": "7.0.9",
47+
"com.unity.2d.common": "6.0.6",
4848
"com.unity.2d.sprite": "1.0.0"
4949
},
5050
"url": "https://packages.unity.com"
@@ -74,7 +74,7 @@
7474
"dependencies": {}
7575
},
7676
"com.unity.2d.tilemap.extras": {
77-
"version": "2.2.3",
77+
"version": "2.2.4",
7878
"depth": 1,
7979
"source": "registry",
8080
"dependencies": {
@@ -95,12 +95,10 @@
9595
"url": "https://packages.unity.com"
9696
},
9797
"com.unity.collab-proxy": {
98-
"version": "1.17.7",
98+
"version": "2.0.1",
9999
"depth": 0,
100100
"source": "registry",
101-
"dependencies": {
102-
"com.unity.services.core": "1.0.1"
103-
},
101+
"dependencies": {},
104102
"url": "https://packages.unity.com"
105103
},
106104
"com.unity.ext.nunit": {
@@ -117,15 +115,15 @@
117115
"dependencies": {
118116
"com.unity.2d.animation": "7.0.9",
119117
"com.unity.2d.pixel-perfect": "5.0.3",
120-
"com.unity.2d.psdimporter": "6.0.6",
118+
"com.unity.2d.psdimporter": "6.0.7",
121119
"com.unity.2d.sprite": "1.0.0",
122120
"com.unity.2d.spriteshape": "7.0.6",
123121
"com.unity.2d.tilemap": "1.0.0",
124-
"com.unity.2d.tilemap.extras": "2.2.3"
122+
"com.unity.2d.tilemap.extras": "2.2.4"
125123
}
126124
},
127125
"com.unity.ide.rider": {
128-
"version": "3.0.16",
126+
"version": "3.0.18",
129127
"depth": 0,
130128
"source": "registry",
131129
"dependencies": {
@@ -134,7 +132,7 @@
134132
"url": "https://packages.unity.com"
135133
},
136134
"com.unity.ide.visualstudio": {
137-
"version": "2.0.16",
135+
"version": "2.0.17",
138136
"depth": 0,
139137
"source": "registry",
140138
"dependencies": {
@@ -156,24 +154,6 @@
156154
"dependencies": {},
157155
"url": "https://packages.unity.com"
158156
},
159-
"com.unity.nuget.newtonsoft-json": {
160-
"version": "3.0.2",
161-
"depth": 2,
162-
"source": "registry",
163-
"dependencies": {},
164-
"url": "https://packages.unity.com"
165-
},
166-
"com.unity.services.core": {
167-
"version": "1.6.0",
168-
"depth": 1,
169-
"source": "registry",
170-
"dependencies": {
171-
"com.unity.modules.unitywebrequest": "1.0.0",
172-
"com.unity.nuget.newtonsoft-json": "3.0.2",
173-
"com.unity.modules.androidjni": "1.0.0"
174-
},
175-
"url": "https://packages.unity.com"
176-
},
177157
"com.unity.test-framework": {
178158
"version": "1.1.31",
179159
"depth": 0,
@@ -216,7 +196,7 @@
216196
}
217197
},
218198
"com.unity.visualscripting": {
219-
"version": "1.7.8",
199+
"version": "1.8.0",
220200
"depth": 0,
221201
"source": "registry",
222202
"dependencies": {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
m_EditorVersion: 2021.3.16f1
2-
m_EditorVersionWithRevision: 2021.3.16f1 (4016570cf34f)
1+
m_EditorVersion: 2021.3.21f1
2+
m_EditorVersionWithRevision: 2021.3.21f1 (1b156197d683)

Unity-Twitch-Chat/ProjectSettings/QualitySettings.asset

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,13 @@ QualitySettings:
224224
excludedTargetPlatforms: []
225225
m_PerPlatformDefaultQuality:
226226
Android: 2
227-
Lumin: 5
228227
GameCoreScarlett: 5
229228
GameCoreXboxOne: 5
229+
Lumin: 5
230230
Nintendo Switch: 5
231231
PS4: 5
232232
PS5: 5
233+
Server: 0
233234
Stadia: 5
234235
Standalone: 5
235236
WebGL: 3

0 commit comments

Comments
 (0)