Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to change OBS voting overlay bar progression color #3416

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions ConfigApp/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,17 @@
<TextBlock x:Name="twitch_user_overlay_mode_label" Text="Voting Overlay Mode" Grid.Row="0" Grid.Column="2"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<ComboBox x:Name="twitch_user_overlay_mode" Width="120" Height="25" Grid.Row="0" Grid.Column="4"
HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBlock x:Name="twitch_user_random_voteable_enable_label" Text="Enable &quot;Random Effect&quot; voteable option" Grid.Row="1" Grid.Column="2"
HorizontalAlignment="Left" VerticalAlignment="Center" SelectionChanged="twitch_user_overlay_mode_changed" />
<TextBlock x:Name="twitch_user_overlay_bar_color_label" Text="Voting Overlay Bar Progression" Grid.Row="1" Grid.Column="2"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<CheckBox x:Name="twitch_user_random_voteable_enable" Width="60" Height="20" Grid.Row="1" Grid.Column="4"
<xctk:ColorPicker Name="twitch_user_overlay_bar_color" Width="60" Height="25" Grid.Row="1" Grid.Column="4"
HorizontalAlignment="Left" VerticalAlignment="Center"
SelectedColor="#238BEB" ShowStandardColors="False" UsingAlphaChannel="False" Margin="0,8,0,7" IsEnabled="False" />
<Button x:Name="twitch_user_overlay_bar_color_reset_button" Content="Reset" Width="60" Height="25" Grid.Row="1" Grid.Column="4"
HorizontalAlignment="Left" VerticalAlignment="Center" Margin="70,8,0,7" IsEnabled="False" Click="twitch_user_overlay_bar_color_reset_Click"/>
<TextBlock x:Name="twitch_user_random_voteable_enable_label" Text="Enable &quot;Random Effect&quot; voteable option" Grid.Row="2" Grid.Column="2"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<CheckBox x:Name="twitch_user_random_voteable_enable" Width="60" Height="20" Grid.Row="2" Grid.Column="4"
HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center" />
<TextBlock x:Name="twitch_permitted_usernames_label" Text="Permitted Twitch usernames (separated by , )"
Grid.Row="3" Grid.Column="2"
Expand Down
29 changes: 29 additions & 0 deletions ConfigApp/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ private void ParseTwitchFile()
twitch_user_channel_oauth.Password = m_TwitchFile.ReadValue("TwitchChannelOAuth");
twitch_user_effects_secs_before_chat_voting.Text = m_TwitchFile.ReadValue("TwitchVotingSecsBeforeVoting", "0");
twitch_user_overlay_mode.SelectedIndex = m_TwitchFile.ReadValueInt("TwitchVotingOverlayMode", 0);
if (m_ConfigFile.HasKey("OverlayVotingBarColor"))
{
twitch_user_overlay_bar_color.SelectedColor = (Color)ColorConverter.ConvertFromString(m_TwitchFile.ReadValue("TwitchVotingOverlayBarColor"));
}
twitch_user_chance_system_enable.IsChecked = m_TwitchFile.ReadValueBool("TwitchVotingChanceSystem", false);
twitch_user_chance_system_retain_chance_enable.IsChecked = m_TwitchFile.ReadValueBool("TwitchVotingChanceSystemRetainChance", true);
twitch_user_random_voteable_enable.IsChecked = m_TwitchFile.ReadValueBool("TwitchRandomEffectVoteableEnable", true);
Expand All @@ -223,6 +227,7 @@ private void WriteTwitchFile()
m_TwitchFile.WriteValue("TwitchChannelOAuth", twitch_user_channel_oauth.Password);
m_TwitchFile.WriteValue("TwitchVotingSecsBeforeVoting", twitch_user_effects_secs_before_chat_voting.Text);
m_TwitchFile.WriteValue("TwitchVotingOverlayMode", twitch_user_overlay_mode.SelectedIndex);
m_TwitchFile.WriteValue("TwitchVotingOverlayBarColor", twitch_user_overlay_bar_color.SelectedColor.ToString());
m_TwitchFile.WriteValue("TwitchVotingChanceSystem", twitch_user_chance_system_enable.IsChecked.Value);
m_TwitchFile.WriteValue("TwitchVotingChanceSystemRetainChance", twitch_user_chance_system_retain_chance_enable.IsChecked.Value);
m_TwitchFile.WriteValue("TwitchRandomEffectVoteableEnable", twitch_user_random_voteable_enable.IsChecked.Value);
Expand Down Expand Up @@ -399,6 +404,8 @@ void TwitchTabHandleAgreed()
twitch_user_effects_secs_before_chat_voting.IsEnabled = agreed;
twitch_user_overlay_mode_label.IsEnabled = agreed;
twitch_user_overlay_mode.IsEnabled = agreed;
twitch_user_overlay_bar_color.IsEnabled = agreed && twitch_user_overlay_mode.SelectedIndex == 2;
twitch_user_overlay_bar_color_reset_button.IsEnabled = agreed && twitch_user_overlay_mode.SelectedIndex == 2;
twitch_user_chance_system_enable_label.IsEnabled = agreed;
twitch_user_chance_system_enable.IsEnabled = agreed;
twitch_user_chance_system_retain_chance_enable_label.IsEnabled = agreed;
Expand Down Expand Up @@ -471,6 +478,28 @@ private void twitch_user_agreed_Click(object sender, RoutedEventArgs e)
TwitchTabHandleAgreed();
}

private void twitch_user_overlay_mode_changed(object sender, SelectionChangedEventArgs e)
{
if (!twitch_user_overlay_bar_color.IsEnabled && twitch_user_overlay_mode.SelectedIndex == 2 && twitch_user_agreed.IsChecked.GetValueOrDefault())
{
twitch_user_overlay_bar_color.IsEnabled = true;
twitch_user_overlay_bar_color_reset_button.IsEnabled = true;
}
else
{
twitch_user_overlay_bar_color.IsEnabled = false;
twitch_user_overlay_bar_color_reset_button.IsEnabled = false;
}
}

private void twitch_user_overlay_bar_color_reset_Click(object sender, RoutedEventArgs e)
{
if (twitch_user_overlay_bar_color.IsEnabled && twitch_user_overlay_mode.SelectedIndex == 2)
{
twitch_user_overlay_bar_color.SelectedColor = (Color)ColorConverter.ConvertFromString("#238BEB");
}
}

private void effect_user_config_Click(object sender, RoutedEventArgs e)
{
TreeMenuItem curTreeMenuItem = (TreeMenuItem)((TreeViewItem)((Grid)((Border)((ContentPresenter)((StackPanel)((Button)sender).Parent).TemplatedParent).Parent).Parent).TemplatedParent).DataContext;
Expand Down
10 changes: 10 additions & 0 deletions TwitchChatVotingProxy/Config/Config.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using Serilog;
using Shared;
using System.IO;
using System.Windows.Media;

namespace TwitchChatVotingProxy.Config
{
class Config : IConfig
{
public static readonly string KEY_OVERLAY_SERVER_PORT = "OverlayServerPort";
public static readonly string KEY_OVERLAY_VOTING_BAR_COLOR = "TwitchVotingOverlayBarColor";
public static readonly string KEY_TWITCH_CHANNEL_NAME = "TwitchChannelName";
public static readonly string KEY_TWITCH_CHANNEL_OAUTH = "TwitchChannelOAuth";
public static readonly string KEY_TWITCH_CHANNEL_USER_NAME = "TwitchUserName";
Expand All @@ -17,6 +19,7 @@ class Config : IConfig

public EOverlayMode? OverlayMode { get; set; }
public int? OverlayServerPort { get; set; }
public Color? OverlayVotingBarColor { get; set; }
public bool RetainInitalVotes { get; set; }
public EVotingMode? VotingMode { get; set; }
public string TwitchChannelName { get; set; }
Expand All @@ -40,6 +43,11 @@ public Config(string file)

OverlayServerPort = optionsFile.ReadValueInt(KEY_OVERLAY_SERVER_PORT, -1);
if (OverlayServerPort == -1) OverlayServerPort = null;
if (optionsFile.HasKey("OverlayVotingBarColor"))
{
OverlayVotingBarColor = (Color)ColorConverter.ConvertFromString(optionsFile.ReadValue(KEY_OVERLAY_VOTING_BAR_COLOR));
}
else { OverlayVotingBarColor = null; }
RetainInitalVotes = optionsFile.ReadValueBool(KEY_TWITCH_RETAIN_INITIAL_VOTES, false);
TwitchChannelName = optionsFile.ReadValue(KEY_TWITCH_CHANNEL_NAME);
TwitchOAuth = optionsFile.ReadValue(KEY_TWITCH_CHANNEL_OAUTH);
Expand All @@ -63,6 +71,8 @@ public Config(string file)
{
PermittedTwitchUsernames = new string[0];
}

logger.Information("succesfully read twitch voting config");
}
}
}
Expand Down
49 changes: 46 additions & 3 deletions TwitchChatVotingProxy/OverlayServer/OverlayMessage.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
namespace TwitchChatVotingProxy.OverlayServer
using System.Windows.Media;

namespace TwitchChatVotingProxy.OverlayServer
{
enum eMessageType : int
{
NONE = -1,
SET_VOTES,
SET_COLOR
}

/// <summary>
/// Universal container for voting overlay message data
/// </summary>
class OverlayBaseMessage
{
/// <summary>
/// The type of the message request. This is read by the overlay to properly parse the correct request message.
/// </summary>
public string type { get; set; }
/// <summary>
/// The json data (serialized) of the actual request
/// </summary>
public string messageData { get; set; }
}

/// <summary>
/// Message which is being sent
/// Message containing voting data
/// </summary>
class OverlayMessage
class OverlayVotingMessage
{
public bool retainInitialVotes { get; set; }
/// <summary>
Expand All @@ -23,4 +47,23 @@ class OverlayMessage
/// </summary>
public OverlayVoteOption[] voteOptions { get; set; }
}

/// <summary>
/// Message to tell the voting overlay to update the style color for the bar progression
/// </summary>
class OverlayColorMessage
{
/// <summary>
/// Red value of the style color
/// </summary>
public int colorR;
/// <summary>
/// Green value of the style color
/// </summary>
public int colorG;
/// <summary>
/// Blue value of the style color
/// </summary>
public int colorB;
}
}
41 changes: 31 additions & 10 deletions TwitchChatVotingProxy/OverlayServer/OverlayServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
using Serilog;
using System;
using System.Collections.Generic;
using System.Windows.Media;

// TODO: fix voting mode
namespace TwitchChatVotingProxy.OverlayServer
{
class OverlayServer : IOverlayServer
{
private OverlayServerConfig config;
private List<Fleck.IWebSocketConnection> connections = new List<Fleck.IWebSocketConnection>();
private List<IWebSocketConnection> connections = new List<IWebSocketConnection>();
private ILogger logger = Log.Logger.ForContext<OverlayServer>();

public OverlayServer(OverlayServerConfig config)
Expand All @@ -19,16 +20,32 @@ public OverlayServer(OverlayServerConfig config)

try
{
var WSS = new Fleck.WebSocketServer($"ws://0.0.0.0:{config.Port}");
var WSS = new WebSocketServer($"ws://0.0.0.0:{config.Port}");
// Set the websocket listeners
WSS.Start(connection =>
{
connection.OnOpen += () => OnWsConnectionOpen(connection);
connection.OnClose += () => OnWSConnectionClose(connection);
});

//Set voting bar color
SendSetBarColorMessage();
} catch (Exception e)
{
logger.Fatal(e, "failed so start websocket server");
logger.Fatal(e, "failed to start websocket server");
}
}

public void SendSetBarColorMessage()
{
if (config.OverlayVotingBarColor.HasValue)
{
var clrMsg = new OverlayColorMessage();
clrMsg.colorR = ((Color)config.OverlayVotingBarColor).R;
clrMsg.colorG = ((Color)config.OverlayVotingBarColor).G;
clrMsg.colorB = ((Color)config.OverlayVotingBarColor).B;

Broadcast(eMessageType.SET_COLOR, JsonConvert.SerializeObject(clrMsg));
}
}

Expand All @@ -52,14 +69,20 @@ public void UpdateVoting(List<IVoteOption> voteOptions)
/// <summary>
/// Broadcasts a message to all socket clients
/// </summary>
/// <param name="messageType">Type of message which should be broadcast</param>
/// <param name="message">Message which should be broadcast</param>
private void Broadcast(string message)
private void Broadcast(eMessageType messageType, string message)
{
OverlayBaseMessage baseMsg = new OverlayBaseMessage();
baseMsg.type = Enum.GetName(typeof(eMessageType), messageType);
baseMsg.messageData = message;
string msg = JsonConvert.SerializeObject(baseMsg);

connections.ForEach(connection =>
{
// If the connection is not available for some reason, we just close it
if (!connection.IsAvailable) connection.Close();
else connection.Send(message);
else connection.Send(msg);
});
}
/// <summary>
Expand Down Expand Up @@ -99,7 +122,7 @@ private void OnWsConnectionOpen(IWebSocketConnection connection)
/// <param name="voteOptions">Vote options that should be sent</param>
private void Request(string request, List<IVoteOption> voteOptions)
{
var msg = new OverlayMessage();
var msg = new OverlayVotingMessage();
msg.request = request;
msg.voteOptions = voteOptions.ConvertAll(_ => new OverlayVoteOption(_)).ToArray();
msg.retainInitialVotes = config.RetainInitialVotes;
Expand All @@ -116,9 +139,7 @@ private void Request(string request, List<IVoteOption> voteOptions)
msg.totalVotes = 0;
voteOptions.ForEach(_ => msg.totalVotes += _.Votes);
// Send the message to all clients
Broadcast(JsonConvert.SerializeObject(msg));
Broadcast(eMessageType.SET_VOTES, JsonConvert.SerializeObject(msg));
}
}
}


}
10 changes: 4 additions & 6 deletions TwitchChatVotingProxy/OverlayServer/OverlayServerConfig.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;

namespace TwitchChatVotingProxy.OverlayServer
{
Expand All @@ -14,12 +10,14 @@ class OverlayServerConfig
public bool RetainInitialVotes { get; set; }
public EVotingMode VotingMode { get; set; }
public int Port { get; set; }
public Color? OverlayVotingBarColor { get; set; }

public OverlayServerConfig(EVotingMode votingMode, bool retainInitialVotes, int? port)
public OverlayServerConfig(EVotingMode votingMode, bool retainInitialVotes, int? port, Color? overlayVotingBarColor)
{
RetainInitialVotes = retainInitialVotes;
VotingMode = votingMode;
Port = port == null ? 9091 : (int)port;
OverlayVotingBarColor = overlayVotingBarColor;
}
}
}
13 changes: 10 additions & 3 deletions TwitchChatVotingProxy/TwitchChatVotingProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ private static void Main(string[] args)
if (config.OverlayMode == EOverlayMode.OVERLAY_OBS)
{
// Create overlay server config
OverlayServerConfig overlayServerConfig = new OverlayServerConfig(votingMode, config.RetainInitalVotes, config.OverlayServerPort);
OverlayServerConfig overlayServerConfig = new OverlayServerConfig(votingMode, config.RetainInitalVotes, config.OverlayServerPort, config.OverlayVotingBarColor);

// Create component
overlayServer = new OverlayServer.OverlayServer(overlayServerConfig);

logger.Information("succesfully setup OBS voting overlay");
}

// Create components
Expand All @@ -80,9 +82,14 @@ private static void Main(string[] args)
// Start the chaos mod controller
new ChaosModController(chaosPipe, overlayServer, votingReceiver, config);

while (chaosPipe.IsConnected())
if (chaosPipe.IsConnected())
{
Thread.Sleep(100);
logger.Information("successfully set up twitch chat voting proxy");

while (chaosPipe.IsConnected())
{
Thread.Sleep(100);
}
}
}
finally
Expand Down
1 change: 1 addition & 0 deletions TwitchChatVotingProxy/TwitchChatVotingProxy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\packages\Serilog.2.10.0\lib\net46\Serilog.dll</HintPath>
</Reference>
Expand Down
4 changes: 2 additions & 2 deletions twitchVotingOverlay/src/barOverlay.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IChaosOverlayClient } from './chaosOverlayClient/iClient';
import { IChaosOverlayClientMessage } from './chaosOverlayClient/iMessage';
import { IChaosOverlayVotingClientMessage } from './chaosOverlayClient/iMessage';

const ANIMATION_DELAY_DELTA = 100;
const ANIMATION_LENGTH = 600;
Expand Down Expand Up @@ -115,7 +115,7 @@ export class BarOverlay {
private onEndVote(): void {
this.bars.forEach(bar => (bar.isDisabled = true));
}
private onUpdateVote(message: IChaosOverlayClientMessage): void {
private onUpdateVote(message: IChaosOverlayVotingClientMessage): void {
const { retainInitialVotes, voteOptions, votingMode } = message;
let { totalVotes } = message;

Expand Down
Loading