Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma semicolon 1
- #include <sourcemod>
- #include <sdktools>
- #include <discord>
- #include <socket>
- #include <morecolors>
- #include <basecomm>
- #undef REQUIRE_PLUGIN
- #include <chat-processor>
- #pragma newdecls required
- // Socket Handles
- Handle gH_Socket = INVALID_HANDLE;
- // Clients
- ArrayList gAL_Clients;
- // Discord Bot
- DiscordBot gDB_Bot = view_as<DiscordBot>(INVALID_HANDLE);
- // ConVars
- ConVar gCV_DiscordChatChannel;
- ConVar gCV_DiscordEnable;
- ConVar gCV_SocketEnable;
- ConVar gCV_SocketPort;
- ConVar gCV_ServerMessageTag;
- ConVar gCV_DiscordMessageTag;
- char gS_BotToken[128];
- char gS_ServerTag[128];
- char gS_DiscordTag[128];
- bool gB_ChatProcessor;
- bool gB_ListeningToDiscord = false;
- public Plugin myinfo =
- {
- name = "Discord Chat Relay - Server",
- author = "PaxPlay, Credits to Ryan \"FLOOR_MASTER\" Mannion, shavit and Deathknife",
- description = "Chat relay between a sourcemod server and Discord.",
- version = "1.0.0",
- url = ""
- };
- public void OnPluginStart()
- {
- gCV_DiscordChatChannel = CreateConVar("sm_discord_text_channel_id", "", "The Discord text channel id.");
- gCV_DiscordEnable = CreateConVar("sm_discord_relay_enable", "1", "Enable the chat relay with Discord.", 0, true, 0.0, true, 1.0);
- gCV_SocketEnable = CreateConVar("sm_discord_socket_enable", "0", "Enable the cross server chat relay.", 0, true, 0.0, true, 1.0);
- gCV_SocketPort = CreateConVar("sm_discord_socket_port", "13370", "Port for the cross server chat relay socket.");
- gCV_ServerMessageTag = CreateConVar("sm_discord_chat_prefix_server", "{grey}[{green}SERVER{grey}]", "Chat Tag for messages from the server.");
- gCV_DiscordMessageTag = CreateConVar("sm_discord_chat_prefix_discord", "{grey}[{blue}DISCORD{grey}]", "Chat Tag for messages from discord.");
- gCV_ServerMessageTag.AddChangeHook(OnConVarChanged);
- gCV_DiscordMessageTag.AddChangeHook(OnConVarChanged);
- AutoExecConfig(true, "discord-chat-relay-server", "sourcemod");
- gB_ChatProcessor = LibraryExists("chat-processor");
- AddCommandListener(Hook_ChatMessage, "say");
- AddCommandListener(Hook_ChatMessage, "say_team");
- }
- public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
- {
- UpdateCvars();
- }
- void UpdateCvars()
- {
- char buffer[MAX_BUFFER_LENGTH];
- gCV_ServerMessageTag.GetString(buffer, sizeof(buffer));
- FormatEx(gS_ServerTag, sizeof(gS_ServerTag), "%s", buffer); // Update Gameserver Chat Tag
- gCV_DiscordMessageTag.GetString(buffer, sizeof(buffer));
- FormatEx(gS_DiscordTag, sizeof(gS_DiscordTag), "%s", buffer); // Update Discord Chat Tag
- }
- bool LoadConfig()
- {
- char[] sPath = new char[PLATFORM_MAX_PATH];
- BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "configs/dcr.cfg");
- if (!FileExists(sPath))
- {
- File hFile = OpenFile(sPath, "w");
- WriteFileLine(hFile, "\"discord-chat-relay\"");
- WriteFileLine(hFile, "{");
- WriteFileLine(hFile, "\t\"bot-token\"\t\"<insert-bot-token>\"");
- WriteFileLine(hFile, "}");
- CloseHandle(hFile);
- LogError("[DCR] \"%s\" not found, creating!", sPath);
- return false;
- }
- KeyValues kv = new KeyValues("discord-chat-relay");
- if(!kv.ImportFromFile(sPath))
- {
- delete kv;
- LogError("[DCR] Couldnt import KeyValues from \"%s\"!", sPath);
- return false;
- }
- kv.GetString("bot-token", gS_BotToken, sizeof(gS_BotToken));
- LogMessage("Loaded the BotToken.");
- delete kv;
- return true;
- }
- public void OnAllPluginsLoaded()
- {
- if(gDB_Bot != view_as<DiscordBot>(INVALID_HANDLE))
- return;
- if (LoadConfig())
- gDB_Bot = new DiscordBot(gS_BotToken);
- else
- LogError("Couldnt load the dcr config.");
- }
- public void OnConfigsExecuted()
- {
- UpdateCvars();
- if (gCV_DiscordEnable.BoolValue && gDB_Bot != view_as<DiscordBot>(INVALID_HANDLE))
- {
- if(!gB_ListeningToDiscord)
- gDB_Bot.GetGuilds(GuildList, INVALID_FUNCTION);
- }
- if(gCV_SocketEnable.BoolValue && gH_Socket == INVALID_HANDLE)
- {
- char ip[24];
- int port = gCV_SocketPort.IntValue;
- GetServerIP(ip, sizeof(ip));
- gH_Socket = SocketCreate(SOCKET_TCP, OnSocketError);
- SocketBind(gH_Socket, ip, port);
- SocketListen(gH_Socket, OnSocketIncoming);
- gAL_Clients = CreateArray();
- LogMessage("%s chat-processor. DCR %s be able to send messages.", gB_ChatProcessor ? "Found" : "Couldn\'t find", gB_ChatProcessor ? "will" : "won\'t");
- LogMessage("[DCR] Started Server Chat Relay server on port %d", port);
- }
- }
- public void GuildList(DiscordBot bot, char[] id, char[] name, char[] icon, bool owner, int permissions, any data)
- {
- gDB_Bot.GetGuildChannels(id, ChannelList, INVALID_FUNCTION);
- }
- public void ChannelList(DiscordBot bot, char[] guild, DiscordChannel Channel, any data)
- {
- if(Channel.IsText) {
- char id[32];
- Channel.GetID(id, sizeof(id));
- char sChannelID[64];
- gCV_DiscordChatChannel.GetString(sChannelID, sizeof(sChannelID));
- if(StrEqual(id, sChannelID) && !gB_ListeningToDiscord)
- {
- gDB_Bot.StopListening();
- char name[32];
- Channel.GetName(name, sizeof(name));
- gDB_Bot.StartListeningToChannel(Channel, OnMessage);
- LogMessage("[DCR] Started listening to channel %s (%s)", name, id);
- gB_ListeningToDiscord = true;
- }
- }
- }
- public void OnMessage(DiscordBot Bot, DiscordChannel Channel, DiscordMessage message)
- {
- if (message.GetAuthor().IsBot())
- return;
- char sMessage[2048];
- message.GetContent(sMessage, sizeof(sMessage));
- char sAuthor[128];
- message.GetAuthor().GetUsername(sAuthor, sizeof(sAuthor));
- Format(sMessage, sizeof(sMessage), "%s %s: %s", gS_DiscordTag, sAuthor, sMessage);
- CPrintToChatAll("%s", sMessage);
- Broadcast(INVALID_HANDLE, sMessage, sizeof(sMessage));
- }
- public Action Hook_ChatMessage(int client, const char[] command, int argc)
- {
- if(BaseComm_IsClientGagged(client))
- {
- return Plugin_Continue;
- }
- char full_message[MAX_BUFFER_LENGTH];
- GetCmdArgString(full_message, sizeof(full_message));
- if(full_message[0] == '!' || full_message[1] == '!') // remove chat commands
- {
- return Plugin_Continue;
- }
- char sMessage[MAX_BUFFER_LENGTH];
- Format(sMessage, sizeof(sMessage), "%s %N: %s", gS_ServerTag, client, full_message);
- ReplaceString(sMessage, sizeof(sMessage), "\"", "", false);
- //Broadcast() is questionnable...
- Broadcast(INVALID_HANDLE, sMessage, sizeof(sMessage));
- SendToDiscord(sMessage ,sizeof(sMessage));
- return Plugin_Continue;
- }
- public void OnMessageSent(DiscordBot bot, char[] channel, DiscordMessage message, any data)
- {
- char sMessage[2048];
- message.GetContent(sMessage, sizeof(sMessage));
- LogMessage("[SM] Message sent to discord: \"%s\".", sMessage);
- }
- void GetServerIP(char[] ip, int length)
- {
- int hostip = FindConVar("hostip").IntValue;
- Format(ip, length, "%d.%d.%d.%d",
- (hostip >> 24 & 0xFF),
- (hostip >> 16 & 0xFF),
- (hostip >> 8 & 0xFF),
- (hostip & 0xFF)
- );
- }
- bool Broadcast(Handle socket, const char[] message, int maxlength)
- {
- if(!gCV_SocketEnable.BoolValue)
- return false;
- if(gAL_Clients == INVALID_HANDLE)
- {
- LogError("In Broadcast, gAL_Clients was invalid. This should never happen!");
- return false;
- }
- int size = gAL_Clients.Length;
- Handle dest_socket = INVALID_HANDLE;
- for (int i = 0; i < size; i++)
- {
- dest_socket = gAL_Clients.Get(i);
- if (dest_socket != socket) // Prevent sending back to the same server.
- {
- SocketSend(dest_socket, message, maxlength);
- }
- }
- if (socket != INVALID_HANDLE) // Prevent printing to the server chat, if message is by the server.
- {
- PrintToChatAll(" %s", message);
- }
- return true;
- }
- void CloseSocket()
- {
- if(gH_Socket != INVALID_HANDLE)
- {
- CloseHandle(gH_Socket);
- gH_Socket = INVALID_HANDLE;
- LogMessage("Closed local Server Chat Relay socket");
- }
- if(gAL_Clients != INVALID_HANDLE)
- {
- CloseHandle(gAL_Clients);
- }
- }
- void RemoveClient(Handle client)
- {
- if (gAL_Clients == INVALID_HANDLE)
- {
- LogError("Attempted to remove client while g_clients was invalid. This should never happen!");
- return;
- }
- int size = gAL_Clients.Length;
- for (int i = 0; i < size; i++)
- {
- if(gAL_Clients.Get(i) == client)
- {
- gAL_Clients.Erase(i);
- return;
- }
- }
- LogError("Could not find client in RemoveClient. This should never happen!");
- }
- public int OnSocketIncoming(Handle socket, Handle newSocket, char[] remoteIP, int remotePort, any arg)
- {
- if (gAL_Clients == INVALID_HANDLE) {
- LogError("In OnSocketIncoming, gAL_Clients was invalid. This should never happen!");
- }
- else {
- PushArrayCell(gAL_Clients, newSocket);
- }
- SocketSetReceiveCallback(newSocket, OnChildSocketReceive);
- SocketSetDisconnectCallback(newSocket, OnChildSocketDisconnected);
- SocketSetErrorCallback(newSocket, OnChildSocketError);
- }
- public int OnSocketDisconnected(Handle socket, any arg)
- {
- CloseSocket();
- }
- public int OnSocketError(Handle socket, const int errorType, const int errorNum, any arg)
- {
- LogError("Socket error %d (errno %d)", errorType, errorNum);
- CloseSocket();
- }
- public int OnChildSocketReceive(Handle socket, char[] receiveData, const int dataSize, any arg)
- {
- Broadcast(socket, receiveData, dataSize);
- SendToDiscord(receiveData, dataSize);
- }
- public int OnChildSocketDisconnected(Handle socket, any arg) {
- RemoveClient(socket);
- CloseHandle(socket);
- }
- public int OnChildSocketError(Handle socket, const int errorType, const int errorNum, any arg)
- {
- LogError("Child socket error %d (errno %d)", errorType, errorNum);
- RemoveClient(socket);
- CloseHandle(socket);
- }
- void SendToDiscord(const char[] message, int maxlength)
- {
- char[] sMessage = new char[maxlength];
- FormatEx(sMessage, maxlength, "%s", message);
- CRemoveTags(sMessage, maxlength);
- char sChannelID[64];
- gCV_DiscordChatChannel.GetString(sChannelID, sizeof(sChannelID));
- gDB_Bot.SendMessageToChannelID(sChannelID, sMessage, OnMessageSent);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement