Skip to content

Commit dd00950

Browse files
committed
Merge remote-tracking branch 'remotes/origin/develop' into develop
2 parents 82d5bfc + 2dd2faf commit dd00950

72 files changed

Lines changed: 1734 additions & 1271 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BouyomiPlugin/IpcTalker.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using FNF.Utility;
2+
using System;
3+
using System.Runtime.Remoting;
4+
using System.Runtime.Remoting.Contexts;
5+
using System.Runtime.Remoting.Messaging;
6+
7+
namespace BouyomiPlugin
8+
{
9+
class IpcTalker : ITalker
10+
{
11+
public void Dispose()
12+
{
13+
_bouyomiChanClient.Dispose();
14+
}
15+
16+
public void TalkText(string text)
17+
{
18+
_bouyomiChanClient.AddTalkTask2(text);
19+
}
20+
21+
public void TalkText(string text, Int16 voiceSpeed, Int16 voiceTone, Int16 voiceVolume, VoiceType voiceType)
22+
{
23+
try
24+
{
25+
_bouyomiChanClient.AddTalkTask2(
26+
text,
27+
voiceSpeed,
28+
voiceTone,
29+
voiceVolume,
30+
voiceType
31+
);
32+
}
33+
catch (RemotingException ex)
34+
{
35+
throw new TalkException("", ex);
36+
}
37+
}
38+
private readonly BouyomiChanClient _bouyomiChanClient = new FNF.Utility.BouyomiChanClient();
39+
}
40+
}

BouyomiPlugin/TcpTalker.cs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.IO;
3+
using System.Net.Sockets;
4+
using System.Text;
5+
6+
namespace BouyomiPlugin
7+
{
8+
class TcpTalker : ITalker
9+
{
10+
private bool _disposedValue;
11+
12+
const Int16 COMMAND = 0x0001;
13+
const byte CHARCODE_UTF8 = 0;
14+
15+
public string IpAddr { get; set; }
16+
public int Port { get; set; }
17+
18+
public void TalkText(string text)
19+
{
20+
//-1を指定すると棒読みちゃん画面上の設定を使用する
21+
TalkText(text, -1, -1, -1, FNF.Utility.VoiceType.Default);
22+
}
23+
public void TalkText(string text, Int16 voiceSpeed, Int16 voiceTone, Int16 voiceVolume, FNF.Utility.VoiceType voiceTypeIndex)
24+
{
25+
var ipAddr = "127.0.0.1";
26+
var port = 50001;
27+
var messageBytes = Encoding.UTF8.GetBytes(text);
28+
29+
try
30+
{
31+
using (var tc = new TcpClient(ipAddr, port))
32+
using (NetworkStream ns = tc.GetStream())
33+
using (var bw = new BinaryWriter(ns))
34+
{
35+
bw.Write(COMMAND); //コマンド( 0:メッセージ読み上げ)
36+
bw.Write((Int16)voiceSpeed); //速度 (-1:棒読みちゃん画面上の設定)
37+
bw.Write((Int16)voiceTone); //音程 (-1:棒読みちゃん画面上の設定)
38+
bw.Write((Int16)voiceVolume); //音量 (-1:棒読みちゃん画面上の設定)
39+
bw.Write((Int16)voiceTypeIndex); //声質 ( 0:棒読みちゃん画面上の設定、1:女性1、2:女性2、3:男性1、4:男性2、5:中性、6:ロボット、7:機械1、8:機械2、10001~:SAPI5)
40+
bw.Write(CHARCODE_UTF8); //文字列のbyte配列の文字コード(0:UTF-8, 1:Unicode, 2:Shift-JIS)
41+
bw.Write((Int32)messageBytes.Length); //文字列のbyte配列の長さ
42+
bw.Write(messageBytes); //文字列のbyte配列
43+
}
44+
}
45+
catch (Exception ex)
46+
{
47+
throw new TalkException("", ex);
48+
}
49+
}
50+
51+
protected virtual void Dispose(bool disposing)
52+
{
53+
if (!_disposedValue)
54+
{
55+
if (disposing)
56+
{
57+
// TODO: dispose managed state (managed objects)
58+
}
59+
60+
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
61+
// TODO: set large fields to null
62+
_disposedValue = true;
63+
}
64+
}
65+
66+
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
67+
// ~TcpTalker()
68+
// {
69+
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
70+
// Dispose(disposing: false);
71+
// }
72+
73+
public void Dispose()
74+
{
75+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
76+
Dispose(disposing: true);
77+
GC.SuppressFinalize(this);
78+
}
79+
public TcpTalker(string ipAddr, int port)
80+
{
81+
IpAddr = ipAddr;
82+
Port = port;
83+
}
84+
}
85+
}

BouyomiPlugin/main.cs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
using System.Collections.Generic;
1515
using System.ComponentModel.Composition;
1616
using System.Diagnostics;
17-
using System.Runtime.Remoting.Contexts;
18-
using System.Runtime.Remoting.Messaging;
1917
using TwicasSitePlugin;
2018
using TwitchSitePlugin;
2119
using WhowatchSitePlugin;
@@ -40,7 +38,7 @@ public static string ToTextWithImageAlt(this IEnumerable<IMessagePart> parts)
4038
{
4139
s += image.Alt;
4240
}
43-
else if(part is IMessageRemoteSvg remoteSvg)
41+
else if (part is IMessageRemoteSvg remoteSvg)
4442
{
4543
s += remoteSvg.Alt;
4644
}
@@ -96,10 +94,28 @@ public static string ToTextWithImageAlt(this IEnumerable<IMessagePart> parts, in
9694
return s;
9795
}
9896
}
97+
interface ITalker : IDisposable
98+
{
99+
void TalkText(string text);
100+
101+
void TalkText(string text, Int16 voiceSpeed, Int16 voiceTone, Int16 voiceVolume, FNF.Utility.VoiceType voiceType);
102+
}
103+
104+
[Serializable]
105+
public class TalkException : Exception
106+
{
107+
public TalkException() { }
108+
public TalkException(string message) : base(message) { }
109+
public TalkException(string message, Exception inner) : base(message, inner) { }
110+
protected TalkException(
111+
System.Runtime.Serialization.SerializationInfo info,
112+
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
113+
}
99114
[Export(typeof(IPlugin))]
100115
public class BouyomiPlugin : IPlugin, IDisposable
101116
{
102-
private readonly FNF.Utility.BouyomiChanClient _bouyomiChanClient;
117+
//private readonly FNF.Utility.BouyomiChanClient _bouyomiChanClient;
118+
private readonly ITalker _talker;
103119
private Options _options;
104120
Process _bouyomiChanProcess;
105121
public string Name => "棒読みちゃん連携";
@@ -745,7 +761,7 @@ public void OnMessageReceived(ISiteMessage message, IMessageMetadata messageMeta
745761
}
746762
TalkText(dataToRead);
747763
}
748-
catch (System.Runtime.Remoting.RemotingException)
764+
catch (TalkException)
749765
{
750766
//多分棒読みちゃんが起動していない。
751767
if (_bouyomiChanProcess == null && System.IO.File.Exists(_options.BouyomiChanPath))
@@ -770,21 +786,17 @@ public void OnMessageReceived(ISiteMessage message, IMessageMetadata messageMeta
770786
}
771787
}
772788

773-
private int TalkText(string text)
789+
private void TalkText(string text)
774790
{
775791
if (_options.IsVoiceTypeSpecfied)
776792
{
777-
return _bouyomiChanClient.AddTalkTask2(
778-
text,
779-
_options.VoiceSpeed,
780-
_options.VoiceTone,
781-
_options.VoiceVolume,
782-
(FNF.Utility.VoiceType)Enum.ToObject(typeof(FNF.Utility.VoiceType), _options.VoiceTypeIndex)
783-
);
793+
_talker.TalkText(text, (Int16)_options.VoiceSpeed,
794+
(Int16)_options.VoiceTone,
795+
(Int16)_options.VoiceVolume, (FNF.Utility.VoiceType)Enum.ToObject(typeof(FNF.Utility.VoiceType), _options.VoiceTypeIndex));
784796
}
785797
else
786798
{
787-
return _bouyomiChanClient.AddTalkTask2(text);
799+
_talker.TalkText(text);
788800
}
789801
}
790802

@@ -813,7 +825,7 @@ public void ShowSettingView()
813825
}
814826
public BouyomiPlugin()
815827
{
816-
_bouyomiChanClient = new FNF.Utility.BouyomiChanClient();
828+
_talker = new IpcTalker();
817829
_options = new Options();
818830
}
819831

@@ -827,7 +839,7 @@ protected virtual void Dispose(bool disposing)
827839
if (disposing)
828840
{
829841
}
830-
_bouyomiChanClient.Dispose();
842+
_talker.Dispose();
831843
if (_bouyomiChanProcess != null)
832844
{
833845
_bouyomiChanProcess.Close();

Common/Common.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<PackageReference Include="SharpVectors" Version="1.7.6" />
4747
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.114.3" PrivateAssets="none" />
4848
<PackageReference Include="WebSocket4Net" Version="0.15.2" />
49+
<PackageReference Include="WpfAnimatedGif" Version="2.0.2" />
4950
</ItemGroup>
5051
<ItemGroup>
5152
<ProjectReference Include="..\ISitePlugin\SitePlugin.csproj" />

Common/Converter.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ public static InlineUIContainer RemoteImage2UiContainer(IMessageImage remoteIcon
5252
Height = remoteIcon.Height ?? bi.Height,
5353
Source = imageSource,
5454
};
55+
//これを入れるとアニメーションGIFが動く
56+
WpfAnimatedGif.ImageBehavior.SetAnimatedSource(image, imageSource);
57+
5558
if (!string.IsNullOrEmpty(remoteIcon.Alt))
5659
{
5760
image.ToolTip = remoteIcon.Alt;

Common/Websocket.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public Task ReceiveAsync(string url)
2929
var tcs = new TaskCompletionSource<object>();
3030
_tcs = tcs;
3131
var cookies = new List<KeyValuePair<string, string>>();
32-
var ws = new WebSocket(url, SubProtocol, cookies, null, UserAgent, Origin)
32+
var ws = new WebSocket(url, SubProtocol, cookies, null, UserAgent, Origin, WebSocketVersion.None, null, System.Security.Authentication.SslProtocols.Tls12)
3333
{
3434
EnableAutoSendPing = EnableAutoSendPing,
3535
AutoSendPingInterval = AutoSendPingInterval,

LineLiveSitePlugin/MessageProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public Task ReceiveAsync(string url)
4545

4646
private void _ws_Closed(object sender, EventArgs e)
4747
{
48-
_tcs.SetResult(null);
48+
_tcs.TrySetResult(null);
4949
}
5050

5151
private void _ws_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)

MultiCommentViewer/IPluginManager.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,22 @@ public class PluginManager : IPluginManager
3030
private IEnumerable<IPlugin> _plugins;
3131
public void LoadPlugins(IPluginHost host)
3232
{
33-
var dir = _options.PluginDir;
34-
var pluginDirs = Directory.GetDirectories(dir);
33+
var plugins = new List<IPlugin>();
34+
_plugins = plugins;
35+
var pluginDir = _options.PluginDir;
36+
if (!System.IO.Directory.Exists(pluginDir))
37+
{
38+
return;
39+
}
40+
41+
42+
var pluginDirs = Directory.GetDirectories(pluginDir);
3543
var list = new List<DirectoryCatalog>();
3644
var def = new ImportDefinition(d => d.ContractName == typeof(IPlugin).FullName, "", ImportCardinality.ExactlyOne, false, false);
37-
var plugins = new List<IPlugin>();
38-
foreach (var pluginDir in pluginDirs)
45+
46+
foreach (var eachPluginDir in pluginDirs)
3947
{
40-
var files = Directory.GetFiles(pluginDir).Where(s => s.EndsWith("Plugin.dll"));//ファイル名がPlugin.dllで終わるアセンブリだけ探す
48+
var files = Directory.GetFiles(eachPluginDir).Where(s => s.EndsWith("Plugin.dll"));//ファイル名がPlugin.dllで終わるアセンブリだけ探す
4149
foreach (var file in files)
4250
{
4351
var filename = Path.GetFileName(file);
@@ -54,9 +62,8 @@ public void LoadPlugins(IPluginHost host)
5462
Debug.WriteLine(ex.Message);
5563
}
5664
}
57-
list.Add(new DirectoryCatalog(pluginDir));
65+
list.Add(new DirectoryCatalog(eachPluginDir));
5866
}
59-
_plugins = plugins;
6067
foreach (var plugin in _plugins)
6168
{
6269
plugin.Host = host;

MultiCommentViewer/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
[assembly: InternalsVisibleTo("MultiCommentViewerTests")]
55

6-
[assembly: AssemblyVersion("0.6.21")]
6+
[assembly: AssemblyVersion("0.6.32")]

MultiCommentViewer/ViewModels/CommentViewModel/McvYouTubeLiveCommentViewModel.cs

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,21 +138,76 @@ public McvYouTubeLiveCommentViewModel(YouTubeLiveSitePlugin.IYouTubeLiveSupercha
138138
Id = comment.Id;
139139
PostTime = comment.PostedAt.ToString("HH:mm:ss");
140140
}
141+
public McvYouTubeLiveCommentViewModel(YouTubeLiveSitePlugin.IYouTubeLivePaidSticker sticker, IMessageMetadata metadata, IMessageMethods methods, IConnectionStatus connectionStatus, IOptions options)
142+
: this(metadata, methods, connectionStatus, options)
143+
{
144+
_message = sticker;
145+
146+
_nameItems = sticker.NameItems;
147+
148+
var list = new List<IMessagePart>();
149+
list.Add(MessagePartFactory.CreateMessageText(sticker.PurchaseAmount + Environment.NewLine));
150+
list.Add(new Common.MessageImage
151+
{
152+
Url = sticker.StickerUrl,
153+
Alt = sticker.StickerTooltip,
154+
Width = sticker.StickerWidth,
155+
Height = sticker.StickerHeight,
156+
});
157+
MessageItems = list;
158+
159+
Thumbnail = sticker.UserIcon;
160+
Id = sticker.Id;
161+
PostTime = sticker.PostedAt.ToString("HH:mm:ss");
162+
}
163+
public McvYouTubeLiveCommentViewModel(YouTubeLiveSitePlugin.IYouTubeLiveSponsorshipsGiftPurchaseAnnouncement sticker, IMessageMetadata metadata, IMessageMethods methods, IConnectionStatus connectionStatus, IOptions options)
164+
: this(metadata, methods, connectionStatus, options)
165+
{
166+
_message = sticker;
167+
168+
_nameItems = sticker.NameItems;
169+
170+
var list = new List<IMessagePart>();
171+
list.AddRange(sticker.MessageItems);
172+
MessageItems = list;
173+
174+
Thumbnail = sticker.UserIcon;
175+
Id = sticker.Id;
176+
PostTime = sticker.PostedAt.ToString("HH:mm:ss");
177+
}
141178
public McvYouTubeLiveCommentViewModel(YouTubeLiveSitePlugin.IYouTubeLiveMembership comment, IMessageMetadata metadata, IMessageMethods methods, IConnectionStatus connectionStatus, IOptions options)
142179
: this(metadata, methods, connectionStatus, options)
143180
{
144181
_message = comment;
145182

146183
_nameItems = comment.NameItems;
147-
var messageItems = new List<IMessagePart>();
148-
messageItems.AddRange(comment.HeaderPrimaryTextItems);
149-
messageItems.AddRange(comment.HeaderSubTextItems);
150-
messageItems.AddRange(comment.CommentItems);
151-
MessageItems = messageItems;
152-
Thumbnail = comment.UserIcon;
153-
Id = comment.Id.ToString();
154-
PostTime = comment.PostedAt.ToString("HH:mm:ss");
155-
Info = "メンバー登録";
184+
185+
if (comment.HeaderPrimaryTextItems == null || comment.CommentItems.Count() == 0)
186+
{
187+
//メンバーシップ登録
188+
var messageItems = new List<IMessagePart>();
189+
messageItems.AddRange(comment.HeaderSubTextItems);
190+
MessageItems = messageItems;
191+
Thumbnail = comment.UserIcon;
192+
Id = comment.Id.ToString();
193+
PostTime = comment.PostedAt.ToString("HH:mm:ss");
194+
Info = "メンバーシップ登録";
195+
}
196+
else
197+
{
198+
//メンバーシップメッセージ
199+
var messageItems = new List<IMessagePart>();
200+
messageItems.AddRange(comment.HeaderPrimaryTextItems);
201+
messageItems.Add(MessagePartFactory.CreateMessageText(Environment.NewLine));
202+
messageItems.AddRange(comment.HeaderSubTextItems);
203+
messageItems.Add(MessagePartFactory.CreateMessageText(Environment.NewLine));
204+
messageItems.AddRange(comment.CommentItems);
205+
MessageItems = messageItems;
206+
Thumbnail = comment.UserIcon;
207+
Id = comment.Id.ToString();
208+
PostTime = comment.PostedAt.ToString("HH:mm:ss");
209+
Info = "メンバーシップメッセージ";
210+
}
156211
}
157212
public McvYouTubeLiveCommentViewModel(YouTubeLiveSitePlugin.IYouTubeLiveConnected connected, IMessageMetadata metadata, IMessageMethods methods, IConnectionStatus connectionStatus, IOptions options)
158213
: this(metadata, methods, connectionStatus, options)

0 commit comments

Comments
 (0)