tModLoader TCR - TerrariaChatRelay

Panini

Terrarian
TerrariaChatRelay

core-logo-browser.png

discord-logo-browser.png
slack-logo-browser.png


Self-serving Terraria Chat Relay with extensible chat service support
Send messages from Terraria to your favorite Chat Services!

Available for tModLoader and TShock.

Currently supports:
Discord, Slack

Attention tModLoader users!
This is a server-side only mod! It will only work from a server console using tModLoaderServer.exe.

Hi Everyone! :dryadsmile:

While this isn't my first contribution to the community, this is my first mod!
It will allow you to send chat from Terraria to multiple Chat Services (such as Discord) and vice versa.

✅What's Done:
  • Terraria <-> Discord Chat <-> Slack Chat!
    • Send chat from Terraria to Discord to Slack and vice versa!
  • Extensible Eventing Framework!
    • Helps other developers easily add on to the code so they can help out!
  • Self-serving relay!
    • No additional installations required. All you need is the mod installed!
  • Robust Command System!
    • Run commands straight from any channel to Terraria!
  • Server-side only design!
    • No need to waste other people's resources, only the servers!
✏ To-do:
  • Nothing at the moment!
⭕Discord: Join Narnia's mod Discord, Narnia's Workshop!
⬇ Download:
✉ GitHub SourceCode:


Changelogs:

Screenshots:
unknown.png
 

Attachments

  • icon.png
    icon.png
    7 KB · Views: 1,515
Last edited:
Coincidentally I recently started looking for a mod like this one, but all of them have either been deprecated for years or are incompatible with TML. It's great to see that you're filling this big hole in the modding community!
 
I'm so close yet so far. I havw transmission going back and forth from Discord to Terraria, but only in debug mode...?

I'll be looking more into it this weekend. Cross your fingers!
 
I've updated the GIF, GitHub to-do's, and original post to-do's with what I have left.
Discord <-> Terraria chat works!... Only on Windows.

For some reason, I can't get it to work on my Linux machine. I'm wondering whether it's my firewall or my own Linux server? Maybe it's just some weird Linux only bug? Once I get that fixed, it'll be ready for release.

Stay tuned everyone :dryadsmile:
 
Last edited:
Resolved the connectivity issues! It works on Linux and Windows from Discord <-> Terraria. I'm going to get everything finalized, polished, and hopefully have a release ready soon. Maybe a week or two depending on my schedule (been a very busy month!)

Stay tuned!

unknown.png


Repost Edit: I've updated the original post with a link to the Mod's Discord! Instead of continuously posting updates here, I will save them for the Discord announcements channel. I'll post the link here for convenience

⭕ Mod Discord: https://discord.gg/nJ5vPeA
 
Thank you Nuova ^_^ I've updated the mod to deploy a hotfix.
For those relaying to only one channel, or have encrypted connections, this will fix the mod and get it to working order.

Thank you, Khaki, for your incredible patience and testing!
 
so how i do to configure this mod in my server?

Please go through the directory in the top of the image, and look for the highlighted file name.

(this is on Windows 10, directory and folders may vary between operating systems or different folders)
upload_2019-7-3_17-44-6.png
 
You are godsent, thank you. Leafos Gaming is honored.

Request: Can we get modified Chat Strings, so we can "Format" our chat outputs on discord, some of us have already predefined looks on how the chat should appear on discord. When you get the chance (which will require a new .json config or the same one.)

I would like to format my chat output like this for example:

:white_small_square: **%playername%** >> *%text%*

ERRORLOGS:
Code:
[03:02:10] [1/WARN] [Terraria]: Error on message Terraria.MessageBuffer
[03:02:10] [3/WARN] [tML]: Silently Caught Exception:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.TcpClient'.
   at System.Net.Sockets.TcpClient.GetStream()
   at Terraria.Net.Sockets.TcpSocket.SendCallback(IAsyncResult result)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.ContextAwareResult.CompleteCallback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.ContextAwareResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

[03:03:40] [17/WARN] [tML]: Silently Caught Exception:
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
   at System.String.Substring(Int32 startIndex, Int32 length)
   at TerrariaChatRelay.Clients.DiscordChatClient.ExecuteCommand(DiscordMessageData chatmsg) in TerrariaChatRelay\Clients\DiscordChatClient.cs:line 302
   at TerrariaChatRelay.Clients.DiscordChatClient.Socket_OnDataReceived(Object sender, MessageEventArgs e) in TerrariaChatRelay\Clients\DiscordChatClient.cs:line 198
   at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
   at WebSocketSharp.Ext.Emit[TEventArgs](EventHandler`1 eventHandler, Object sender, TEventArgs e)
   at WebSocketSharp.WebSocket.messagec(MessageEventArgs e)
   at WebSocketSharp.WebSocket.message()
   at WebSocketSharp.WebSocket.<>c__DisplayClass17.<startReceiving>b__15(WebSocketFrame frame)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClass16.<ReadFrameAsync>b__15(WebSocketFrame frame3)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClass10.<readPayloadDataAsync>b__f(Byte[] bytes)
   at WebSocketSharp.Ext.<>c__DisplayClass9.<ReadBytesAsync>b__8(IAsyncResult ar)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
   at System.Net.Security.SslStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
   at WebSocketSharp.Ext.ReadBytesAsync(Stream stream, Int32 length, Action`1 completed, Action`1 error)
   at WebSocketSharp.WebSocketFrame.readPayloadDataAsync(Stream stream, WebSocketFrame frame, Action`1 completed, Action`1 error)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClass16.<ReadFrameAsync>b__14(WebSocketFrame frame2)
   at WebSocketSharp.WebSocketFrame.readMaskingKeyAsync(Stream stream, WebSocketFrame frame, Action`1 completed, Action`1 error)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClass16.<ReadFrameAsync>b__13(WebSocketFrame frame1)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClass7.<readExtendedPayloadLengthAsync>b__6(Byte[] bytes)
   at WebSocketSharp.Ext.<>c__DisplayClass9.<ReadBytesAsync>b__8(IAsyncResult ar)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
   at System.Net.Security.SslStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
   at WebSocketSharp.Ext.ReadBytesAsync(Stream stream, Int32 length, Action`1 completed, Action`1 error)
   at WebSocketSharp.WebSocketFrame.readExtendedPayloadLengthAsync(Stream stream, WebSocketFrame frame, Action`1 completed, Action`1 error)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClass16.<ReadFrameAsync>b__12(WebSocketFrame frame)
   at WebSocketSharp.WebSocketFrame.<>c__DisplayClassa.<readHeaderAsync>b__9(Byte[] bytes)
   at WebSocketSharp.Ext.<>c__DisplayClass9.<ReadBytesAsync>b__8(IAsyncResult ar)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Security._SslStream.ProcessFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.ReadFrameCallback(AsyncProtocolRequest asyncRequest)
   at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result)
   at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes)
   at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.ContextAwareResult.CompleteCallback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.ContextAwareResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
 
Last edited:
TCR 0.9 will be released, if not already, at the time of writing this. This is a fairly big update for developers, and important update for server owners, and a smaller for consumers.

tl;dr
-New chat formats in config file
-Server start and stop messages
-Notifies you when there is a new version
-Config files moved
-TCR will no longer break the server with the Websocket.Closed error message

Attention server owners!
This update will creates brand new configuration files in a folder in Mod Configs.
As a result, your TCR will stop working when you update.
All you need to do is copy the values from your old Mod Config into the new TerrariaChatRelay-Discord.json configuration file.


--------------------------------------------------------------------------------------------------------

So here's TCR 0.9 with a slew of new features! Running commands from Discord is coming later sadly. I have submitted some code that has been inserted into an unreleased version of tModLoader. Once the new version of tModLoader is out, command support will be put into TCR and for you guys to use.

I'm also considering adding Terraria to Terraria server support. If you are interested in this feature, please join the official Panini Mod Discord and let me know in the TerrariaChatRelay channel.

TCR 0.9 Patch Notes:

Bugfixes:

-Add retry code to re-connect DCR if it disconnects
-Re-adjust how hooks fire so other mods hooks can fire
-Prevent DCR from crashing server when the socket is closed

New Server Features:
-Add server start and server stop messages
-Move config files into a new TerrariaChatRelay folder
-Make console logging prettier and more identifiable
-New version checker that notifies you when a new version is available
-Add comments in DCR config to help users understand how to use it
-Add configurations to change formatting of messages

Dev stuff:
-Decouple all DCR classes from TCR
-Add DCR only configuration options to independent config file
-Re-order DCR configuration properties to keep it easy to read and clean
-Add base class for future Reflection based decoupling
-Reorder some properties into a Global class
-Reorder some files into a new Core folder
-Add comments

Thanks everyone!
 
Last edited:
TCR 0.9.1 Patch Notes:

Bugfixes:

-Fix version checker always saying there is an update for TCR :dryadtongue:
 
Hey there,
Just wondering if you expect any issues with this mod and the launch of 1.4 - or you think it would mostly work once a recompile is published?

Cheers,
p
 
Back
Top Bottom