### 2024-04-12更新

------
####  V1.0.2404.1201
- 新增支持手动运行规则。
- 规则播放时间间隔不再针对全局声效,而只针对当前规则声效。
- 修复规则中播放文件夹可能导致无法执行的BUG。
- 修复规则不勾选礼物和点赞,则无法执行的BUG。
This commit is contained in:
紫林软件 2024-04-13 10:13:30 +08:00
commit 0ec1400de9
72 changed files with 5274 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
obj
bin
.vs

10
CHANGELOG.md Normal file
View File

@ -0,0 +1,10 @@
### 2024-04-12更新
------
#### V1.0.2404.1201
- 新增支持手动运行规则。
- 规则播放时间间隔不再针对全局声效,而只针对当前规则声效。
- 修复规则中播放文件夹可能导致无法执行的BUG。
- 修复规则不勾选礼物和点赞则无法执行的BUG。

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# 紫林直播助手
紫林直播助手可以帮助你在直播过程中自动执行礼物特效、播放特定声音等操作。

155
Source/API/SoundPlay.cs Normal file
View File

@ -0,0 +1,155 @@
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Forms;
namespace LiveTools
{
public class SoundPlay
{
private readonly WaveOut waveOut = null;
/// <summary>
/// 实例化音频播放类
/// </summary>
public SoundPlay()
{
waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
}
/// <summary>
/// 实例化音频播放类
/// </summary>
/// <param name="path"></param>
public SoundPlay(string path)
{
waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
FilePath = path;
}
/// <summary>
/// 音频文件地址
/// </summary>
public string FilePath { get; set; }
public event EventHandler OnPlayEnd;
/// <summary>
/// 播放
/// </summary>
public void Play()
{
Play(FilePath);
}
/// <summary>
/// 播放指定音频
/// </summary>
/// <param name="path"></param>
public void Play(string path)
{
if (!System.IO.File.Exists(path)) { return; }
try
{
//var ms = System.IO.File.OpenRead(path);
var rdr1 = new AudioFileReader(path);
waveOut?.Init(rdr1);
waveOut?.Play();
while(waveOut.PlaybackState== PlaybackState.Playing)
{
System.Windows.Forms.Application.DoEvents();
Thread.Sleep(10);
}
}
catch(Exception ex)
{ }
}
/// <summary>
/// 播放状态
/// </summary>
public PlaybackState PlaybackState
{
get { return waveOut.PlaybackState; }
}
/// <summary>
/// 异步播放指定音频
/// </summary>
/// <param name="path"></param>
public void PlaySync(string path)
{
if (!System.IO.File.Exists(path)) { return; }
Thread th = new Thread(delegate() {
Play(path);
OnPlayEnd?.Invoke(this,new EventArgs());
});
th.Start();
}
/// <summary>
/// 停止播放
/// </summary>
public void Stop()
{
try
{
waveOut?.Stop();
}
catch
{
}
}
/// <summary>
/// 恢复播放
/// </summary>
public void Resume()
{
try
{
waveOut.Resume();
}
catch
{
}
}
/// <summary>
/// 暂停播放
/// </summary>
public void Pause()
{
try
{
waveOut.Pause();
}
catch
{
}
}
/// <summary>
/// 设置/获取音量,范围为0-1
/// </summary>
public float Volume
{
get { return waveOut.Volume; }
set
{
try
{
waveOut.Volume = value;
}
catch(Exception ex)
{
}
}
}
/// <summary>
/// 销毁数据
/// </summary>
~SoundPlay()
{
try
{
waveOut.Dispose();
}
catch
{
}
}
}
}

15
Source/App.xaml Normal file
View File

@ -0,0 +1,15 @@
<Application x:Class="LiveTools.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LiveTools"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
<ResourceDictionary Source="Data/GeometryIcon.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

29
Source/App.xaml.cs Normal file
View File

@ -0,0 +1,29 @@
using System.Configuration;
using System.Data;
using System.Runtime.InteropServices;
using System.Windows;
namespace LiveTools
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private static Mutex mutex = null;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
bool isFirstInstance;
mutex = new Mutex(true,Config.SoftId, out isFirstInstance);
if (!isFirstInstance)
{
//MessageBox.Show("应用程序已经在运行。");
Current.Shutdown();
}
}
}
}

10
Source/AssemblyInfo.cs Normal file
View File

@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

117
Source/Config/API.cs Normal file
View File

@ -0,0 +1,117 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using LiveTools.Data;
using Microsoft.VisualBasic.ApplicationServices;
using ryCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace LiveTools
{
public class API
{
/// <summary>
/// 检查登录
/// </summary>
/// <param name="ErrorMsg"></param>
/// <returns></returns>
public static int CheckedLogin(out string ErrorMsg)
{
try
{
ErrorMsg = "";
Config.UserInfo.NickName = "";
Config.UserInfo.isOut = 1;
HttpResult html = Config.ry_api.Post(Config.Api_Url + "user.aspx", "api=login&userid=" + RyWeb.WebDecode.Escape(Config.UserInfo.UserId) +
"&soft_id=" + RyWeb.WebDecode.Escape(Config.SoftId) + "&pwd=" + RyWeb.WebDecode.Escape(Config.UserInfo.Pwd)
+ "&ver=" + RyWeb.WebDecode.Escape(RySoft.VersionStr) + "&hdid=" + RyWeb.WebDecode.Escape(Config.GetMac()) + "&login=1");
string jsonText = GetJson(html.Html);
if (jsonText != "")
{
Json json = new Json(jsonText);
string result = json.GetJsonValue(Data.ConstVar.json_Result);
if (result == Data.ResultVar.json_Success.ToString())
{
Config.UserInfo.NickName = json.GetJsonValue("nickname");
Config.UserInfo.OutDateStr = json.GetJsonValue("out_date");
Config.UserInfo.OutTime = Config.UserInfo.OutDateStr.ToDateTime().ToInt64();
Config.UserInfo.isOut = json.GetJsonValue("isout").ToInt();
Config.UserInfo.PriceAds = json.GetJsonValue("PriceAds", "月卡59元,季卡99元,年卡199元,永久卡299元");
Config.UserInfo.BuyContact = json.GetJsonValue("BuyContact", "邮箱:1017848709@qq.com");
//ClsPram.ZZ_Op = json.GetJsonValue("zz_op").ToInt();
Config.UserInfo.Media_id = json.GetJsonValue("media_id");
Config.UserInfo.Setting = json.GetJsonValue("setting");
Config.UserInfo.Sys_Setting = json.GetJsonValue("sys_setting");
Config.UserInfo.Parent_Setting = json.GetJsonValue("parent_setting");
Config.UserInfo.Ads_id = json.GetJsonValue("ads_id");
return 1;
}
else if (result == Data.ResultVar.json_UserOutDate.ToString())
{
Config.UserInfo.isOut = 1;
ErrorMsg = "当前账号需要续费才能使用,请续费。";
return -1000;//需要续费
}
else
{
ErrorMsg = json.GetJsonValue(ConstVar.json_ResultText);
//HandyControl.Controls.MessageBox.Show(json.GetJsonValue(ConstVar.json_ResultText), "错误代码:" + result);
return -1;
}
}
else
{
ErrorMsg ="服务器异常,请检查网络连接";
return -100;//服务器异常
}
}
catch { ErrorMsg = "检查登录过程中发生错误。"; return -2; }
}
public static bool IsJson(string result)
{
if (result.Length <= 6)
{
return false;
}
else if (result.Substring(0, 1) == "1")
{
return true;
}
else
{ return false; }
}
public static string GetJson(string result)
{
if (IsJson(result))
{
return result.Substring(6);
}
else
{
return "";
}
}
/// <summary>
/// 获取相对路径
/// </summary>
/// <param name="fullPath"></param>
/// <returns></returns>
public static string GetRelativePath(string fullPath)
{
return fullPath.Replace(Config.GetCurrentFolder,"{app}",true, System.Globalization.CultureInfo.CurrentCulture);
}
/// <summary>
/// 获取相对路径
/// </summary>
/// <param name="fullPath"></param>
/// <returns></returns>
public static string GetTruePath(string fullPath)
{
return fullPath.Replace("{app}", Config.GetCurrentFolder);
}
}
}

182
Source/Config/Config.cs Normal file
View File

@ -0,0 +1,182 @@
using ryCommon;
using ryCommonDb;
using rySafe;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools
{
public class Config
{
public static bool InitCef { get; set; } = false;
public static int isAutoLogin = 0;
public static UserInfo UserInfo { get; set; } = new UserInfo();
public static string Api_Url = "http://reg.itjs.top/API/";
public static string SoftId = "LiveTools";
public static bool MustUpdate = false;
public static string NewVerUrl = "";
public static RyPostGet ry_api = new RyPostGet();
/// <summary>
/// 默认礼物特效
/// </summary>
public static bool GiftTrigger { get; set; } = true;
public static bool PlaySound { get; set; } = true;
/// <summary>
/// 是否允许多个声音同时播放
/// </summary>
public static bool MultiPlaySound { get; set; } = true;
public static int PicSize { get; set; } = 70;
public static int PicCount { get; set; } = 10;
/// <summary>
/// 礼物缓存
/// </summary>
public static Hashtable GiftCache { get; set; } = new Hashtable();
public static UsingLock<object> GiftLock { get; set; } = new UsingLock<object>();
public static void LoadSetting()
{
Json json = new Json(RyFiles.ReadAllText(Config.UserDbFolder + "\\Setting.json"));
GiftTrigger = json.GetJsonValue("GiftTrigger", true);
PlaySound = json.GetJsonValue("PlaySound", true);
MultiPlaySound = json.GetJsonValue("MultiPlaySound", true);
PicSize = json.GetJsonValue("PicSize", 70);
PicCount = json.GetJsonValue("PicCount", 10);
}
/// <summary>
/// 数据库完整路径
/// </summary>
public static string DbFullPath
{
get
{
return UserDbFolder + "\\MyDb.dat";
}
}
public static string GetCurrentFolder
{
get
{
return System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName??"").TrimEnd('\\') ??"";
}
}
/// <summary>
/// 系统数据文件夹
/// </summary>
public static string SysDbFolder
{
get
{
return GetCurrentFolder + "\\SysDb";
}
}
/// <summary>
/// 所有用户数据文件夹
/// </summary>
public static string AllUserDbFolder
{
get
{
return GetCurrentFolder + "\\UserDb";
}
}
/// <summary>
/// 用户数据文件夹
/// </summary>
public static string UserDbFolder
{
get
{
if(UserInfo.UserId.Length>0)
{
return GetCurrentFolder + "\\UserDb\\"+ UserInfo.UserId;
}
return GetCurrentFolder + "\\UserDb";
}
}
/// <summary>
/// 创建数据库
/// </summary>
public static void CreateDb()
{
IDbInterface db = new SQLiteDataProvider();
if (db.ConnDb(DbFullPath) == 1)
{
#region
RyQuickSQL mySQL = new("Rules");
mySQL.AddField("RuleName", "");
mySQL.AddField("SortIndex", 0d);
mySQL.AddField("RuleJson", "");
mySQL.AddField("AddTime", 0L);
mySQL.AddField("EditTime", 0L);
db.CreateDb(mySQL);
#endregion
#region
mySQL.Clear();
mySQL.TableName = "Direct";
mySQL.AddField("Name", "");
mySQL.AddField("Platform", "");
mySQL.AddField("DirectId", "");
mySQL.AddField("DirectJson", "");
mySQL.AddField("AddTime", 0L);
mySQL.AddField("EditTime", 0L);
db.CreateDb(mySQL);
#endregion
//
}
}
/// <summary>
/// 为1表示登录
/// </summary>
/// <returns></returns>
public static int IsLogin()
{
if (UserInfo.UserId.Length == 0)
{
return 0;
}
if (UserInfo.UserId.Length>0 && UserInfo.OutTime>=DateTime.Now.ToInt64())
{
return 1;
}
return -1;
}
public static string GetMac()
{
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
// HostName = computerProperties.HostName;
Console.WriteLine("Interface information for {0}.{1} ",
computerProperties.HostName, computerProperties.DomainName);
if (nics == null || nics.Length < 1)
{
return "";
}
foreach (NetworkInterface adapter in nics)
{
IPInterfaceProperties properties = adapter.GetIPProperties(); // .GetIPInterfaceProperties();
string Description = adapter.Description;//接口的描述
string NetworkInterfaceType = adapter.NetworkInterfaceType.ToString();//获取接口类型
PhysicalAddress address = adapter.GetPhysicalAddress();//返回MAC地址
if (NetworkInterfaceType != "Loopback" && NetworkInterfaceType == "Ethernet")
return adapter.GetPhysicalAddress().ToString();
//byte[] bytes = address.GetAddressBytes();
//for (int i = 0; i < bytes.Length; i++)
//{
// //.ToString("X2") 将byte数组转换成字符串
// Console.Write("{0}", bytes[i].ToString("X2"));
// if (i != bytes.Length - 1)
// {
// Console.Write("-");
// }
//}
}
return "";
}
}
}

439
Source/Config/Json.cs Normal file
View File

@ -0,0 +1,439 @@
using LiveTools;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ryCommon;
using System;
using System.Data;
/// <summary>
/// json 的摘要说明
/// </summary>
public class Json
{
private string jsonText = "";
/// <summary>
///
/// </summary>
public JObject jo;
/// <summary>
///
/// </summary>
public Json()
{
jo = new JObject();
}
/// <summary>
///
/// </summary>
public string Html { get; private set; } = "";
/// <summary>
///
/// </summary>
public Json(JObject jo)
{
this.jo = jo;
}
private void LoadJson(string _jsonText)
{
Html = _jsonText;
if (_jsonText == null) { jo = new JObject(); return; }
if (_jsonText.Length == 0)
{
jo = new JObject(); return;
}
string xx = _jsonText.GetStr("descUrl", "counterApi");
jsonText = _jsonText.Replace("+new Date,", "'',");
jsonText = jsonText.Replace("!true,", "false,");
if (xx.Length > 0) { jsonText = jsonText.Replace(xx, " :'',\r\n "); }
try
{
if (jsonText.Length == 0)
{ jo = new JObject(); }
else
jo = (JObject)JsonConvert.DeserializeObject(jsonText);
}
catch (Exception)
{
jo = new JObject();
}
}
/// <summary>
///
/// </summary>
/// <param name="_jsonText"></param>
public Json(string _jsonText)
{
LoadJson(_jsonText);
}
/// <summary>
/// 获取或设置json文本
/// </summary>
public string Text
{
get { return jo.ToString(); }
set
{
jsonText = value;
if (value.Length == 0)
{
jo = new JObject();
}
else
{
jo = (JObject)JsonConvert.DeserializeObject(value);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetJsonValue(string name)
{
if (jo[name] == null) { return ""; }
else
{ return jo[name].ToString(); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public string GetJsonValue(string name, string defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToString(); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public bool GetJsonValue(string name, bool defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{
string value = jo[name].ToString().ToLower();
return value == "1" || value == "true";
}
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public int GetJsonValue(string name, int defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToInt(defvalue); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public int GetJsonValue(string name, int min, int max, int defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToInt(min, max, defvalue); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public decimal GetJsonValue(string name, decimal min, decimal max, decimal defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToDecimal(min, max, defvalue); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public Int64 GetJsonValue(string name, Int64 defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToInt64(defvalue); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public decimal GetJsonValue(string name, decimal defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToDecimal(defvalue); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public double GetJsonValue(string name, double defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{ return jo[name].ToDouble(defvalue); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public JObject GetJsonValue(string name, JObject defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{
try
{
return (JObject)jo[name];
}
catch { return defvalue; }
}
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public JArray GetJsonValue(string name, JArray defvalue)
{
if (jo[name] == null) { return defvalue; }
else
{
try
{
return (JArray)jo[name];
}
catch { return defvalue; }
}
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public void SetJsonValue(string name, decimal defvalue)
{
if (jo[name] == null) { Add(name, defvalue); }
else
{ jo[name] = defvalue.ToString(); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public void SetJsonValue(string name, int defvalue)
{
if (jo[name] == null) { Add(name, defvalue); }
else
{ jo[name] = defvalue.ToString(); }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public void SetJsonValue(string name, string defvalue)
{
if (jo[name] == null) { Add(name, defvalue); }
else
{ jo[name] = defvalue; }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public void SetJsonValue(string name, bool defvalue)
{
if (jo[name] == null) { Add(name, defvalue); }
else
{ jo[name] = defvalue ? 1 : 0; }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public void SetJsonValue(string name, JObject defvalue)
{
if (jo[name] == null) { Add(name, defvalue); }
else
{ jo[name] = defvalue; }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="defvalue"></param>
/// <returns></returns>
public void SetJsonValue(string name, JArray defvalue)
{
if (jo[name] == null) { Add(name, defvalue); }
else
{ jo[name] = defvalue; }
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public DataTable GetJsonValueByTable(string name)
{
if (jo[name] == null) { return new DataTable(); }
else
{
try
{
return JsonConvert.DeserializeObject(jo[name].ToString(), typeof(DataTable)) as DataTable;
}
catch { return new DataTable(); }
}
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, string value)
{
try
{
jo.Add(Name, value);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, JObject value)
{
try
{
jo.Add(Name, value);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, JArray value)
{
try
{
jo.Add(Name, value);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, int value)
{
try
{
jo.Add(Name, value);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, long value)
{
try
{
jo.Add(Name, value);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, bool value)
{
try
{
jo.Add(Name, value ? 1 : 0);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, decimal value)
{
try
{
jo.Add(Name, value);
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <param name="value"></param>
public void Add(string Name, DataTable value)
{
try
{
jo.Add(Name, Newtonsoft.Json.JsonConvert.SerializeObject(value));
}
catch { }
}
/// <summary>
/// 返回Json
/// </summary>
/// <returns></returns>
public override string ToString()
{
return this.Text;
}
}

121
Source/Config/RyPostGet.cs Normal file
View File

@ -0,0 +1,121 @@
using DotNet4.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools
{
public class RyPostGet
{
/// <summary>
/// 以post方式获取网页源码
/// </summary>
/// <param name="url"></param>
/// <param name="post"></param>
/// <param name="cookie"></param>
/// <returns></returns>
public HttpResult Post(string url, string post, string cookie)
{
try
{
HttpHelper t = new HttpHelper();
HttpItem m = new HttpItem()
{
URL = url,
Postdata = post,
ContentType = "application/x-www-form-urlencoded",
Method = "POST",
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
Expect100Continue = false
};
if (cookie != "")
{
m.Cookie = cookie;
}
HttpResult r = t.GetHtml(m);
return r;
}
catch
{
HttpResult r = new HttpResult();
return r;
}
}
/// <summary>
/// 以post方式获取网页源码
/// </summary>
/// <param name="url"></param>
/// <param name="post"></param>
/// <returns></returns>
public HttpResult Post(string url, string post)
{
return Post(url, post, cookie);
}
/// <summary>
/// 获取网页源码
/// </summary>
/// <param name="url"></param>
/// <param name="cookie"></param>
/// <returns></returns>
public HttpResult Get(string url, string cookie)
{
try
{
HttpHelper t = new HttpHelper();
HttpItem m = new HttpItem()
{
URL = url
};
if (cookie != "")
{
m.Cookie = cookie;
}
m.Allowautoredirect = true;
HttpResult r = t.GetHtml(m);
return r;
}
catch
{
HttpResult r = new HttpResult();
return r;
}
}
/// <summary>
/// 获取网页源码
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public HttpResult Get(string url)
{
return Get(url, cookie);
}
public string Cookie
{
get { return cookie; }
set { cookie = value; }
}
private string cookie = "";
public static string UrlEncode(string str)
{
StringBuilder sb = new StringBuilder();
byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
for (int i = 0; i < byStr.Length; i++)
{
sb.Append(@"%" + Convert.ToString(byStr[i], 16));
}
return (sb.ToString());
}
public static string GetMD5(string str)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(str)))
{
sb.Append(b.ToString("X2"));
}
return sb.ToString().Trim();
}
}
}

34
Source/Config/UserInfo.cs Normal file
View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools
{
public class UserInfo
{
public string NickName { get; set; } = "";
public string UserId { get; set; } = "";
public string Pwd { get; set; } = "";
public string Tokens { get; set; } = "";
public long OutTime { get; set; } = 0;
public int isOut { get; set; } = 0;
public string OutDateStr { get; set; } = "";
/// <summary>
/// 价格广告
/// </summary>
public string PriceAds { get; set; } = "";
/// <summary>
///购买联系方式
/// </summary>
public string BuyContact { get; set; } = "";
public string Setting { get; set; } = "";
public string Sys_Setting { get; set; } = "";
public string Parent_Setting { get; set; } = "";
public string Ads_id { get; set; } = "";
public string Media_id { get; set; } = "";
public long LoginTime { get; set; } = 0;
public string Cookie { get; set; } = "";
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
using System.Windows;
namespace LiveTools
{
public class CustomWindow : Window
{
public CustomWindow()
{
WindowStyle = WindowStyle.None;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
WindowInteropHelper helper = new WindowInteropHelper(this);
SetWindowLong(helper.Handle, GWL_STYLE, GetWindowLong(helper.Handle, GWL_STYLE) & ~WS_SYSMENU);
}
internal const int GWL_STYLE = -16;
internal const int WS_SYSMENU = 0x80000;
[DllImport("user32.dll")]
internal static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
internal static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
}
}

View File

@ -0,0 +1,67 @@
<Border hc:ScrollViewer.IsInertiaEnabled="True"
x:Class="LiveTools.Content.LeftMainContent"
Background="{DynamicResource RegionBrush}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:hc="https://handyorg.github.io/handycontrol"
Margin="16,16,0,16"
CornerRadius="10"
Effect="{StaticResource EffectShadow4}" Loaded="Border_Loaded">
<Border.Resources>
</Border.Resources>
<DockPanel Background="#FFF0F3F8">
<Grid>
<TextBlock Name="LblNickName" Text="未登录" VerticalAlignment="Top" Margin="94,22,10,0" FontWeight="Bold"/>
<TextBlock Name="LblOutDate" Text="未知" VerticalAlignment="Top" Margin="94,42,10,0"/>
<ListView Margin="0,80" Grid.Row="2" Foreground="Black" x:Name="MenuLeft" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Background="#FFF0F3F8">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Resources>
<!--define a SolidColorBrush that you will use on the selected item-->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="#FFCCDFF8" />
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource {x:Static SystemColors.HighlightBrushKey}}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF157BF9" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn />
</GridView>
</ListView.View>
<ListViewItem IsSelected="True" Tag="login" Height="60" MouseLeftButtonUp="ListViewItem_MouseLeftButtonUp">
<StackPanel Orientation="Horizontal">
<Image Source="/Pngs/Icons/home.png" Width="25" Height="25" Margin="10" VerticalAlignment="Center" />
<TextBlock Text="系统首页" VerticalAlignment="Center" Margin="20 10"/>
</StackPanel>
</ListViewItem>
<ListViewItem Tag="direct" Height="60" MouseLeftButtonUp="ListViewItem_MouseLeftButtonUp">
<StackPanel Orientation="Horizontal">
<Image Source="/Pngs/Icons/直播.png" Width="25" Height="25" Margin="10" VerticalAlignment="Center" />
<TextBlock Text="直播平台管理" VerticalAlignment="Center" Margin="20 10"/>
</StackPanel>
</ListViewItem>
<ListViewItem Tag="rules" Height="60" MouseLeftButtonUp="ListViewItem_MouseLeftButtonUp">
<StackPanel Orientation="Horizontal">
<Image Source="/Pngs/Icons/规则引擎.png" Width="25" Height="25" Margin="10" VerticalAlignment="Center" />
<TextBlock Text="规则管理" VerticalAlignment="Center" Margin="20 10"/>
</StackPanel>
</ListViewItem>
<ListViewItem Tag="setting" Height="60" MouseLeftButtonUp="ListViewItem_MouseLeftButtonUp">
<StackPanel Orientation="Horizontal">
<Image Source="/Pngs/Icons/设置.png" Width="25" Height="25" Margin="10" VerticalAlignment="Center" />
<TextBlock Text="设置" VerticalAlignment="Center" Margin="20 10"/>
</StackPanel>
</ListViewItem>
</ListView>
<hc:Gravatar Style="{StaticResource GravatarCircle}" Source="/Pngs/Icons/头像.png" Height="72" VerticalAlignment="Top" HorizontalAlignment="Left" Width="72" Margin="6,4,0,0"/>
</Grid>
</DockPanel>
</Border>

View File

@ -0,0 +1,64 @@
using CommunityToolkit.Mvvm.Messaging.Messages;
using CommunityToolkit.Mvvm.Messaging;
using HandyControl.Controls;
using HandyControl.Tools.Extension;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LiveTools.Data;
namespace LiveTools.Content
{
/// <summary>
/// LeftMainContent.xaml 的交互逻辑
/// </summary>
public partial class LeftMainContent
{
public LeftMainContent()
{
InitializeComponent();
}
private void ButtonAscending_OnClick(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton button && button.Tag is ItemsControl itemsControl)
{
if (button.IsChecked == true)
{
itemsControl.Items.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
}
else
{
itemsControl.Items.SortDescriptions.Clear();
}
}
}
private void Border_Loaded(object sender, RoutedEventArgs e)
{
WeakReferenceMessenger.Default.Send<string>("login");
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken("") { ID = MsgTokenId.Login, From = "LeftMain", Msg = "222" });
}
private void ListViewItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var item= (ListViewItem)sender;
if (item.Tag is string str)
{
WeakReferenceMessenger.Default.Send<string>(str);
}
}
}
}

View File

@ -0,0 +1,17 @@
<Border hc:ScrollViewer.IsInertiaEnabled="True"
x:Class="LiveTools.Content.MainContent"
Background="{DynamicResource RegionBrush}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:hc="https://handyorg.github.io/handycontrol"
Margin="16,16,0,16"
CornerRadius="10"
Effect="{StaticResource EffectShadow4}">
<hc:SimplePanel>
<Border Name="BorderRootEffect" Background="{DynamicResource RegionBrush}" CornerRadius="10" Effect="{StaticResource EffectShadow4}" Margin="16" Visibility="Collapsed"/>
<Border Name="BorderRoot" Style="{StaticResource BorderClip}" Margin="16">
<ContentPresenter Name="PresenterMain" Margin="0,0,0,10" Content="{Binding SubContent}"/>
</Border>
</hc:SimplePanel>
</Border>

View File

@ -0,0 +1,97 @@
using HandyControl.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Reflection;
using System.Diagnostics.Eventing.Reader;
using System.Windows.Forms;
namespace LiveTools.Content
{
/// <summary>
/// MainContent.xaml 的交互逻辑
/// </summary>
public partial class MainContent
{
public MainContent()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register<string>(this, OnReceive);
}
/// <summary>
///
/// </summary>
public object SubContent
{
get;set;
}
private rySafe.UsingLock<object> ui_lock=new rySafe.UsingLock<object>();
private List<System.Windows.Controls.UserControl> list_ui = new List<System.Windows.Controls.UserControl>();
public System.Windows.Controls.UserControl GetUI(Type type)
{
using (ui_lock.Write())
{
var find = list_ui.FindIndex(x => x.GetType() == type);
if (find == -1)
{
var ctl = (System.Windows.Controls.UserControl)Activator.CreateInstance(type);
list_ui.Add(ctl);
return ctl;
}
else
{
return list_ui[find];
}
}
}
private void OnReceive(object recipient, string message)
{
if (SubContent is IDisposable disposable)
{
disposable.Dispose();
}
switch (message)
{
case "login":
if (Config.IsLogin() == 1)
{
SubContent = GetUI(typeof(FrmAccountInfo));
}
else
{
SubContent = GetUI(typeof(FrmLogin));
}
break;
case "home":
SubContent = GetUI(typeof(FrmAccountInfo));
break;
case "rules":
SubContent = GetUI(typeof(FrmRuleView));
break;
case "direct":
SubContent = GetUI(typeof(FrmDirectView));
break;
case "setting":
SubContent = GetUI(typeof(FrmSetting));
break;
}
PresenterMain.Content= SubContent;
}
}
}

View File

@ -0,0 +1,22 @@
<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
BorderThickness="0,1,0,0"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:userControl="clr-namespace:LiveTools.Content"
xmlns:hc="https://handyorg.github.io/handycontrol"
x:Class="LiveTools.Content.MainWinContent" Loaded="Border_Loaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinitionLeft" Width="250" MinWidth="240" MaxWidth="400"/>
<ColumnDefinition x:Name="ColumnDefinitionContent" />
</Grid.ColumnDefinitions>
<Button x:Name="ButtonShiftOut" Click="OnLeftMainContentShiftOut" hc:IconElement.Geometry="{StaticResource LeftGeometry}" Padding="8 8 0 8" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0 26 -16 0" Style="{StaticResource ButtonIconCircular}" />
<userControl:MainContent Grid.Column="1" x:Name="MainContent" />
<userControl:LeftMainContent Grid.Column="0" x:Name="LeftMainContent">
<UIElement.RenderTransform>
<TranslateTransform />
</UIElement.RenderTransform>
</userControl:LeftMainContent>
<GridSplitter x:Name="GridSplitter" Margin="0,26,0,26" Grid.Column="0" HorizontalAlignment="Right" Width="4" Background="Transparent"/>
<Button Grid.Column="0" x:Name="ButtonShiftIn" Click="OnLeftMainContentShiftIn" Visibility="Collapsed" hc:IconElement.Geometry="{StaticResource RightGeometry}" Padding="8 8 0 8" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-12 26 0 0" Style="{StaticResource ButtonIconCircular}" />
</Grid>
</Border>

View File

@ -0,0 +1,110 @@
using HandyControl.Tools.Extension;
using HandyControl.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CommunityToolkit.Mvvm.Messaging;
using LiveTools.Data;
namespace LiveTools.Content
{
/// <summary>
/// MainWinContent.xaml 的交互逻辑
/// </summary>
public partial class MainWinContent
{
private GridLength _columnDefinitionWidth;
public MainWinContent()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register<MsgToken>(this, OnReceive);
}
private void OnLeftMainContentShiftOut(object sender, RoutedEventArgs e)
{
ButtonShiftOut.Collapse();
GridSplitter.IsEnabled = false;
double targetValue = -ColumnDefinitionLeft.MaxWidth;
_columnDefinitionWidth = ColumnDefinitionLeft.Width;
DoubleAnimation animation = AnimationHelper.CreateAnimation(targetValue, milliseconds: 100);
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += OnAnimationCompleted;
LeftMainContent.RenderTransform.BeginAnimation(TranslateTransform.XProperty, animation);
void OnAnimationCompleted(object? _, EventArgs args)
{
animation.Completed -= OnAnimationCompleted;
LeftMainContent.RenderTransform.SetCurrentValue(TranslateTransform.XProperty, targetValue);
Grid.SetColumn(MainContent, 0);
Grid.SetColumnSpan(MainContent, 2);
ColumnDefinitionLeft.MinWidth = 0;
ColumnDefinitionLeft.Width = new GridLength();
ButtonShiftIn.Show();
}
}
private void OnLeftMainContentShiftIn(object sender, RoutedEventArgs e)
{
ButtonShiftIn.Collapse();
GridSplitter.IsEnabled = true;
double targetValue = ColumnDefinitionLeft.Width.Value;
DoubleAnimation animation = AnimationHelper.CreateAnimation(targetValue, milliseconds: 100);
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += OnAnimationCompleted;
LeftMainContent.RenderTransform.BeginAnimation(TranslateTransform.XProperty, animation);
void OnAnimationCompleted(object? _, EventArgs args)
{
animation.Completed -= OnAnimationCompleted;
LeftMainContent.RenderTransform.SetCurrentValue(TranslateTransform.XProperty, targetValue);
Grid.SetColumn(MainContent, 1);
Grid.SetColumnSpan(MainContent, 1);
ColumnDefinitionLeft.MinWidth = 240;
ColumnDefinitionLeft.Width = _columnDefinitionWidth;
ButtonShiftOut.Show();
}
}
private void Border_Loaded(object sender, RoutedEventArgs e)
{
}
private void OnReceive(object recipient, MsgToken message)
{
switch (message.ID)
{
case MsgTokenId.Login:
if(Config.IsLogin()==1)
{
LeftMainContent.IsEnabled = true;
LeftMainContent.LblNickName.Text = Config.UserInfo.NickName;
LeftMainContent.LblOutDate.Text = Config.UserInfo.OutDateStr;
}
else
{
LeftMainContent.IsEnabled = false;
}
break;
}
}
}
}

79
Source/Data/ConstVar.cs Normal file
View File

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools.Data
{
public class ResultVar
{
/// <summary>
/// 数据库错误
/// </summary>
public const int json_DbError = -1000;
/// <summary>
/// API未发现
/// </summary>
public const int json_APIUnFound = -1001;
/// <summary>
/// 未登陆
/// </summary>
public const int json_UnLogin = -1002;
/// <summary>
/// 没有权限
/// </summary>
public const int json_UnAuthorized = -1003;
/// <summary>
/// 账号过期
/// </summary>
public const int json_UserOutDate = -1004;
/// <summary>
/// 结果返回成功
/// </summary>
public const int json_Success = 1;
/// <summary>
/// 错误的用户名
/// </summary>
public const int json_UserUnFound = -1;
/// <summary>
/// 数据没发现
/// </summary>
public const int json_DbUnFound = -1;
/// <summary>
/// 错误的密码
/// </summary>
public const int json_ErrorPwd = -2;
/// <summary>
/// 无效的字符串
/// </summary>
public const int json_InvalidStr = -3;
/// <summary>
/// 用户已被禁用
/// </summary>
public const int json_ForbiddenUser = -4;
/// <summary>
/// 用户已存在
/// </summary>
public const int json_UserExist = -5;
}
public class ConstVar
{
public const string json_Result = "Result";
public const string json_ResultText = "ResultText";
/// <summary>
/// 6位校验码目前只启用首位校验码为1
/// </summary>
public const string json_Start = "100000";
/// <summary>
/// 登陆成功的字符串
/// </summary>
public const string Login_Success = "tianrui";
public ConstVar()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
}

View File

@ -0,0 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Geometry x:Key="Play">
M512 64c247.424 0 448 200.576 448 448S759.424 960 512 960 64 759.424 64 512 264.576 64 512 64z m0 80c-203.24 0-368 164.76-368 368s164.76 368 368 368 368-164.76 368-368-164.76-368-368-368z m-80 197.427a32 32 0 0 1 16 4.288l240.003 138.573c15.305 8.836 20.549 28.407 11.712 43.713a32 32 0 0 1-11.712 11.711L448.001 678.285c-15.306 8.837-34.877 3.594-43.713-11.711A32 32 0 0 1 400 650.573V373.427c0-17.673 14.327-32 32-32z
</Geometry>
</ResourceDictionary>

View File

@ -0,0 +1,36 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging.Messages;
using CommunityToolkit.Mvvm.Messaging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools.Data
{
public partial class LogViewModel : ObservableObject, IRecipient<RequestMessage<string>>
{
[ObservableProperty]
private string title = "控制台界面";
public LogViewModel()
{
//接口必须实现
WeakReferenceMessenger.Default.Register(this);
}
//消息返回
public void Receive(RequestMessage<string> message)
{
Debug.WriteLine("我接受到了消息" + message.Response);
message.Reply(new string("我返回的消息"));
}
}
}

View File

@ -0,0 +1,41 @@
using CommunityToolkit.Mvvm.Messaging.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools.Data
{
public class MessageToken
{
//public static readonly object LoadShowContent = nameof(LoadShowContent);
public static readonly string ClearLeftSelected = nameof(ClearLeftSelected);
public static readonly string MainWindow = nameof(MainWindow);
}
public enum MsgTokenId
{
None = 0,
/// <summary>
/// 触发特效
/// </summary>
Effects=1,
Login =1000,
}
public class MsgToken : ValueChangedMessage<object>
{
public MsgToken(object value) : base(value) { }
public MsgTokenId ID { get; set; } = MsgTokenId.None;
public string From { get; set; } ="";
public string Msg { get; set; } = "";
}
public class LoadShowContent : ValueChangedMessage<object>
{
public LoadShowContent(object value) : base(value) { }
}
public class ClearLeftSelected : ValueChangedMessage<string>
{
public ClearLeftSelected(string value) : base(value) { }
}
}

13
Source/FrmEffects.xaml Normal file
View File

@ -0,0 +1,13 @@
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LiveTools"
xmlns:hc="https://handyorg.github.io/handycontrol" x:Class="LiveTools.FrmEffects"
mc:Ignorable="d"
Title="礼物特效" Height="800" Width="450" Loaded="Window_Loaded" Closing="Window_Closing">
<Canvas x:Name="cvsGround">
<Button Content="测试" Visibility="Hidden" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left" Height="56" VerticalAlignment="Top" Width="100" Click="Button_Click" Canvas.Left="21" Canvas.Top="30"/>
</Canvas>
</Window>

379
Source/FrmEffects.xaml.cs Normal file
View File

@ -0,0 +1,379 @@
using CommunityToolkit.Mvvm.Messaging;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using System.Collections;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class FrmEffects : Window
{
public FrmEffects()
{
InitializeComponent();
cvsGround.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#00ff00"));
this.Background = cvsGround.Background;
}
public DirectInfo DirectInfo { get; set; } = new DirectInfo();
public BitmapImage GetImage(string path)
{
BitmapImage bi = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block.
bi.BeginInit();
bi.UriSource = new Uri(path, UriKind.RelativeOrAbsolute);
bi.EndInit();
return bi;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
List<BitmapImage> imgList = new List<BitmapImage>();
imgList.Add(GetImage("C:\\Users\\李凤鑫\\Desktop\\微信图片_20240329144830.png"));
imgList.Add(GetImage("C:\\Users\\李凤鑫\\Desktop\\微信图片_20240307182811.png"));
imgList.Add(GetImage("C:\\Users\\李凤鑫\\Desktop\\微信图片_20240329144727.png"));
for (int i = 0; i < 10; i++)
{
Random rd2 = new Random(Guid.NewGuid().GetHashCode());
Image simpleImage = new Image();
simpleImage.Width = 50;
//Canvas.SetLeft(simpleImage, i * 300);
// Set the image source.
simpleImage.Source = imgList[rd2.Next(0,imgList.Count)];
cvsGround.Children.Add(simpleImage);
RotateTransform rotateTransform = new RotateTransform(rd2.Next(0,181));
simpleImage.RenderTransform = rotateTransform;
KK(simpleImage);
}
//KK(GroupboxArea);
//KK(GroupboxArea3);
}
void KK(Image grid)
{
var IsLandscape = false;//是否是横屏
Random rd = new Random(Guid.NewGuid().GetHashCode());
var endPos = new Point(this.Width / 2, this.Height / 2);
var mm = rd.Next(0, 4);
var startPos = new Point(0, rd.Next(0, 500));
switch (mm)
{
case 0://左边
startPos = new Point(0, rd.NextDouble() * this.Height);
break;
case 1://上边
startPos = new Point(this.Width * rd.NextDouble(), 0);
break;
case 2://右边
startPos = new Point(this.Width, rd.NextDouble() * this.Height);
break;
case 3://下边
startPos = new Point(rd.NextDouble() * this.Width, this.Height);
break;
}
var story = StartAnim(startPos, endPos);
story.Completed += delegate (object? sender2, EventArgs e2)
{
cvsGround.Children.Remove(grid);
};//完成后要做的事
story.Begin();
//story.RepeatBehavior = RepeatBehavior.Forever;//无限次循环,需要的自己加上
Storyboard StartAnim(Point startPos, Point endPos)
{
var Duration = rd.NextDouble() * 0.4;
// 创建两个DoubleAnimation来描述X和Y方向的移动
DoubleAnimation animX = new DoubleAnimation();
animX.From = startPos.X;//起点
animX.To = endPos.X; // 目标X坐标值
animX.Duration = TimeSpan.FromSeconds(Duration); // 动画持续时间
DoubleAnimation animY = new DoubleAnimation();
animY.From = startPos.Y; // 目标Y坐标值
animY.To = endPos.Y; // 目标Y坐标值
animY.Duration = TimeSpan.FromSeconds(Duration); // 动画持续时间
//
// 使用Storyboard来关联动画和物体
Storyboard.SetTarget(animX, grid);
Storyboard.SetTargetProperty(animX, new PropertyPath(Canvas.LeftProperty));
Storyboard.SetTarget(animY, grid);
Storyboard.SetTargetProperty(animY, new PropertyPath(Canvas.TopProperty));
Storyboard _story = new Storyboard();
_story.Children.Add(animX);
_story.Children.Add(animY);
//第二段动画
// 创建两个DoubleAnimation来描述X和Y方向的移动
//DoubleAnimation animX_end = new DoubleAnimation();
//animX_end.From = endPos.X;//起点
//animX_end.To = startPos.X; // 目标X坐标值
//animX_end.BeginTime = TimeSpan.FromSeconds(Duration);
//animX_end.Duration = TimeSpan.FromSeconds(1.5); // 动画持续时间
//PathGeometry pathGeometry = PathGeometry.CreateFromGeometry(Geometry.Parse("M "+ endPos.X+ ","+ endPos.Y+ " Q "+ (endPos.X+20)+ ","+ (endPos.Y+20)+ " "+ (endPos.X+10)+ ",0"));
// Y轴方向上的动画
//DoubleAnimationUsingPath animationY = new DoubleAnimationUsingPath
//{
// Source = PathAnimationSource.Y,
// BeginTime = TimeSpan.FromSeconds(Duration),
// Duration = TimeSpan.FromSeconds(Duration),
// PathGeometry = pathGeometry
//};
//DoubleAnimation animY_end = new DoubleAnimation();
//animY_end.From = endPos.Y; // 目标Y坐标值
//animY_end.To = this.Height; // 目标Y坐标值
//animY_end.BeginTime = TimeSpan.FromSeconds(Duration);
//animY_end.Duration = TimeSpan.FromSeconds(Duration); // 动画持续时间
//animY_end.AccelerationRatio = 0.6;
var offset = rd.Next(-200, 200);
var offset2 = offset > 0 ? offset + 200 : offset - 200;
var time = rd.NextDouble();
var xx = IsLandscape ? endPos.Y : endPos.X;
var yy = IsLandscape ? endPos.X : endPos.Y;
DoubleAnimationUsingKeyFrames animationX = new DoubleAnimationUsingKeyFrames();
animationX.BeginTime = TimeSpan.FromSeconds(Duration);
animationX.KeyFrames.Add(new LinearDoubleKeyFrame(xx, TimeSpan.FromSeconds(0))); // X from 0
animationX.KeyFrames.Add(new LinearDoubleKeyFrame(xx + offset, TimeSpan.FromSeconds(0.3))); // X to 50 in 1 second
animationX.KeyFrames.Add(new LinearDoubleKeyFrame(xx + offset2, TimeSpan.FromSeconds(time * 2))); // X to 100 in another 1 second
DoubleAnimationUsingKeyFrames animationY = new DoubleAnimationUsingKeyFrames();
animationY.BeginTime = TimeSpan.FromSeconds(Duration);
animationY.KeyFrames.Add(new EasingDoubleKeyFrame(yy, TimeSpan.FromSeconds(0), new QuadraticEase() { EasingMode = EasingMode.EaseOut })); // Y from 0
animationY.KeyFrames.Add(new EasingDoubleKeyFrame(yy - rd.Next(50, 200), TimeSpan.FromSeconds(0.3), new QuadraticEase() { EasingMode = EasingMode.EaseIn })); // Y to -50 in 1 second
animationY.KeyFrames.Add(new EasingDoubleKeyFrame(IsLandscape ? 0 : this.Height, TimeSpan.FromSeconds(time * 2), new BounceEase() { EasingMode = EasingMode.EaseOut })); // Y to 300 in another 1 second
Storyboard.SetTarget(animationX, grid);
Storyboard.SetTargetProperty(animationX, new PropertyPath(Canvas.LeftProperty));
Storyboard.SetTarget(animationY, grid);
Storyboard.SetTargetProperty(animationY, new PropertyPath(Canvas.TopProperty));
_story.Children.Add(animationX);
_story.Children.Add(animationY);
return _story;
}
}
private bool IsProcUse { get; set; } = false;
/// <summary>
/// 正在播放的列表
/// </summary>
Hashtable PlayingList { get; set; } = new Hashtable();
/// <summary>
/// 上一次播放时间
/// </summary>
Hashtable LastPlayTimeList { get; set; } = new Hashtable();
private void OnReceive(object recipient, MsgToken message)
{
if(message.Value is EffectInfo info)
{
if(message.Msg== "Close" && message.From == "Web")
{
IsProcUse = true;
this.Close();
return;
}
if ((info.ID == DirectInfo.Id || info.ID==0) && message.From=="Web")
{
///如果已经过期
if (Config.UserInfo.UserId.Length==0 || Config.UserInfo.OutTime<DateTime.Now.ToInt64() ||Config.UserInfo.isOut==1)
{
return;
}
if(info.ActionList!=null)
{
for (int a = 0; a < info.ActionList.Count; a++)
{
var action_item = (JObject)info.ActionList[a];
var name = action_item.GetJsonValue("Name","");
switch (name)
{
case "Rule_ShowPic":
ShowPic();
void ShowPic()
{
#region
var PicPath = API.GetTruePath(action_item.GetJsonValue("PicPath", ""));
if (System.IO.File.Exists(PicPath))
{
for (int m = 0; m < info.LoopCount; m++)
{
var count = action_item.GetJsonValue("PicCount", 10);
for (int i = 0; i < count; i++)
{
Random rd2 = new Random(Guid.NewGuid().GetHashCode());
this.Dispatcher.Invoke(new Action(() =>
{
Image simpleImage = new Image();
simpleImage.Width = action_item.GetJsonValue("PicSize", 70);
//Canvas.SetLeft(simpleImage, i * 300);
// Set the image source.
simpleImage.Source = GetImage(PicPath);
cvsGround.Children.Add(simpleImage);
RotateTransform rotateTransform = new RotateTransform(rd2.Next(0, 181));
simpleImage.RenderTransform = rotateTransform;
KK(simpleImage);
}));
}
}
if (action_item.GetJsonValue("PlaySound", true))
{
var th = new Thread(StartPlay);
th.Start();
void StartPlay()
{
//var md5 = rySafe.MD5Sha1.GetMD5("AA|" +info.ID+"|"+ DateTime.Now + "|" + Guid.NewGuid());
if (System.IO.File.Exists(Config.SysDbFolder + "\\audio\\砸.mp3"))
{
Thread.Sleep(300);
LiveTools.SoundPlay sound = new LiveTools.SoundPlay
{
Volume = 100 / 100f
};
sound.Play(Config.SysDbFolder + "\\audio\\砸.mp3");
}
}
}
}
#endregion
}
break;
case "Rule_SoundPlay":
MSoundPlay();
void MSoundPlay()
{
if (!action_item.GetJsonValue("MultiPlaySound", false))
{
if (info.RuleID > 0)
{
if (IsPlaying) { return; }
if (PlayingList.Count > 0) { return; }
if (LastPlayTimeList.ContainsKey(info.RuleID))
{
var time= (DateTime)LastPlayTimeList[info.RuleID];
if (time >= DateTime.Now.AddSeconds(-action_item.GetJsonValue("PlaySoundInterval", 10)))
{
return;
}
}
}
}
var th = new Thread(StartPlay);
th.Start();
void StartPlay()
{
IsPlaying = true;
var PlayCustomSound_Path =API.GetTruePath(action_item.GetJsonValue("PlayCustomSound_Path", ""));
var md5 = rySafe.MD5Sha1.GetMD5(PlayCustomSound_Path + "|" + DateTime.Now + "|" + Guid.NewGuid());
if (System.IO.File.Exists(PlayCustomSound_Path))
{
LiveTools.SoundPlay sound = new LiveTools.SoundPlay
{
Volume = action_item.GetJsonValue("Vol", 100) / 100f
};
PlayingList[md5]=sound;
sound.Play(PlayCustomSound_Path);
PlayingList.Remove(md5);
}
else if (System.IO.Directory.Exists(PlayCustomSound_Path))
{
var files = RyFiles.GetFiles(PlayCustomSound_Path, "*.mp3;*.wav;*.flac;*.wma");
if (files.Count > 0)
{
Random rd = new Random(Guid.NewGuid().GetHashCode());
LiveTools.SoundPlay sound = new LiveTools.SoundPlay
{
Volume = action_item.GetJsonValue("Vol", 100) / 100f
};
PlayingList[md5]= sound;
sound.Play(files[rd.Next(0, files.Count)]);
PlayingList.Remove(md5);
}
}
if (LastPlayTimeList.ContainsKey(info.RuleID))
{
LastPlayTimeList[info.RuleID] = DateTime.Now;
}
else
{
LastPlayTimeList[info.RuleID]= DateTime.Now;
}
IsPlaying = false;
}
}
break;
}
}
}
}
}
}
private DateTime LastPlayTime = DateTime.Now;
private bool IsPlaying =false;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Title = DirectInfo.Name + "[" + DirectInfo.Platform + "]特效";
WeakReferenceMessenger.Default.Register<MsgToken>(this, OnReceive);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!IsProcUse)
{
if (HandyControl.Controls.MessageBox.Show("关闭特效窗口,将导致当前直播特效对应Web功能也同步关闭.\r\n是否确定要关闭?", "关闭确认", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
{
e.Cancel = true;
}
else
{
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = DirectInfo.Id;
effectInfo.EffectMode = -1;
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Effects", Msg = "Close" });
}
}
try
{
foreach (var item in PlayingList.Values)
{
if (item is LiveTools.SoundPlay sound)
{
sound.Stop();
}
}
}
catch { }
}
}
/// <summary>
/// 特效信息
/// </summary>
public class EffectInfo
{
public int ID { get; set; } = 0;
public int RuleID { get; set; } = 0;
/// <summary>
/// 事件类型,0表示发生特效,-1表示要关闭当前窗口。
/// </summary>
public int EffectMode { get; set; } = 0;
/// <summary>
/// 循环次数
/// </summary>
public int LoopCount { get; set; } = 1;
/// <summary>
/// 动作列表
/// </summary>
public JArray ActionList { get; set; } =null;
}
}

15
Source/FrmWeb.xaml Normal file
View File

@ -0,0 +1,15 @@
<hc:Window x:Class="LiveTools.FrmWeb"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LiveTools"
xmlns:hc="https://handyorg.github.io/handycontrol"
mc:Ignorable="d"
Style="{StaticResource WindowWin10}"
Background="{DynamicResource RegionBrush}"
Title="直播界面" Height="500" Width="800" Loaded="Window_Loaded" Closing="Window_Closing">
<Grid Name="MainGrid" Margin="0,54,0,0">
<Button x:Name="BtnHidden" Content="隐藏窗口" Width="73" Margin="12,-37,0,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnHidden_Click"/>
</Grid>
</hc:Window>

447
Source/FrmWeb.xaml.cs Normal file
View File

@ -0,0 +1,447 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using CefSharp;
using CefSharp.Wpf;
using CommunityToolkit.Mvvm.Messaging;
using HandyControl.Controls;
using HtmlAgilityPack;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using rySafe;
namespace LiveTools
{
/// <summary>
/// FrmWeb.xaml 的交互逻辑
/// </summary>
public partial class FrmWeb : HandyControl.Controls.Window
{
public FrmWeb()
{
InitializeComponent();
//2 设置定时器时间间隔 TimeSpan.FromSeconds(1) 以秒单位
timer.Interval = TimeSpan.FromMilliseconds(1000);
//3 设置每隔时间要执行的方法 ,绑定方法到定时器上
//tick 是事件名, new System.EventHandler() 参数是方法名
timer.Tick += Timer_Tick;
}
public DirectInfo DirectInfo { get; set; } = new DirectInfo();
Hashtable hash_data = new System.Collections.Hashtable();
bool isRunning = false;
//从图片地址获取图片字节数据
public byte[] GetImageFromResponse(string url, string? cookie = null)
{
try
{
System.Net.WebRequest request = System.Net.WebRequest.Create(url);
if (!string.IsNullOrWhiteSpace(cookie))
{
request.Headers[System.Net.HttpRequestHeader.Cookie] = cookie;
}
System.Net.WebResponse response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
using (MemoryStream ms = new MemoryStream())
{
Byte[] buffer = new Byte[1024];
int current = 0;
do
{
ms.Write(buffer, 0, current);
} while ((current = stream.Read(buffer, 0, buffer.Length)) != 0);
return ms.ToArray();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
//throw new Exception(ex.Message);
return null;
}
}
private async void Timer_Tick(object? sender, EventArgs e)
{
if (isRunning) { return; }
if(chromeBrowser.IsDisposed) { return; }
isRunning = true;
try
{
string source = await chromeBrowser.GetSourceAsync();
var th = new Thread(ScanSource);
th.Start();
void ScanSource()
{
if (source != null)
{
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.LoadHtml(source);
var list = htmlDoc.DocumentNode.SelectNodes("//div[@id='chatroom']//div[@class='webcast-chatroom___items']//div[contains(@class,'webcast-chatroom___item')]");
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
var item = list[i];
//if (item.InnerText.Length == 0) { continue; }
if (item.InnerText.IndexOfEx("关注") > 0 && item.InnerText.IndexOfEx("点点关注") < 0)
{
}
if (item.GetAttributeValue("class", "") == "webcast-chatroom__room-message") { continue; }
var ContentType = "评论";
var isgift = false;//当前是否刷了礼物
var gift_count = 0;
var data_id = item.GetAttributeValue("data-id", "");
if (data_id.Length == 0) { continue; }
if (hash_data.ContainsKey(data_id))
{
continue;
}
HtmlAgilityPack.HtmlDocument htmlItem = new HtmlAgilityPack.HtmlDocument();
htmlItem.LoadHtml(item.OuterHtml);
var imgs = htmlItem.DocumentNode.SelectNodes("//img");
if (imgs != null && imgs.Count > 0)
{
for (int m = 0; m < imgs.Count; m++)
{
if (imgs[m].GetAttributeValue("alt", "").Length > 0)
{
imgs[m].InnerHtml = imgs[m].GetAttributeValue("alt", "");
}
}
}
var content = htmlItem.GetAttr("//*[contains(@class,'webcast-chatroom___content')]", "", "");
var nickname = "";
var iPos = item.InnerText.IndexOf("");
if (iPos > 0)
{
nickname = item.InnerText.Substring(0, iPos);
}
if (nickname.Length == 0)
{
nickname = item.GetAttr("//span[@class='webcast-chatroom___nickname']", "", "");
if (nickname.Length > 0 && content.Length == 0)
{
if (item.InnerText.StartsWith(nickname))
{
ContentType = "加分";
content = item.InnerText.Substring(nickname.Length);
}
}
}
var action = item.GetAttr("//span[3]", "", "");
if (action == "来了") { continue; }
if (action.IndexOfEx("为主播点赞") >= 0)
{
ContentType = "点赞";
}
var gift_url = item.GetAttr("//span[contains(text(),'送出了')]//img", "src", "");
var giftFileName = "";
if (gift_url.Length > 0)
{
ContentType = "礼物";
var md5 = rySafe.MD5Sha1.GetMD5(gift_url.ToLower());
isgift = true;
gift_count = item.GetAttr("//span[contains(text(),'送出了')]//img/following::span", "", "").Replace("×", "").Trim().ToInt();
if (Config.GiftTrigger)
{
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = DirectInfo.Id;
effectInfo.LoopCount = gift_count;
var picPath = "";
Ini ini = new Ini(Config.AllUserDbFolder+"\\Setting.ini");
var filename = ini.ReadIni("gift_md5", md5,"");
if (System.IO.File.Exists(Config.AllUserDbFolder + "\\GiftImages\\Auto\\" + filename + ".png"))
{
picPath = Config.AllUserDbFolder + "\\GiftImages\\Auto\\" + filename + ".png";
}
else
{
try
{
var bytes = GetImageFromResponse(gift_url);
if (bytes != null)
{
var md5_byte = rySafe.MD5Sha1.GetMD5(bytes);
filename = md5_byte;
ini.WriteIni("gift_md5",md5, md5_byte);
RyFiles.CreateDirectory(Config.AllUserDbFolder + "\\GiftImages\\Auto");
using (Config.GiftLock.Write())
{
System.IO.File.WriteAllBytes(Config.AllUserDbFolder + "\\GiftImages\\Auto\\" + md5_byte + ".png", bytes);
}
picPath = Config.AllUserDbFolder + "\\" + md5_byte + ".png";
}
}
catch { continue; }
}
if(picPath.Length>0)
{
JObject jo = new JObject()
{
{ "Name","Rule_ShowPic"},
{ "Mode","ShowPic"},
{ "PlaySound", Config.PlaySound},
{ "PicPath",API.GetRelativePath(picPath) },
{ "PicSize",Config.PicSize },
{ "PicCount", Config.PicCount },
{ "MultiPlaySound", Config.MultiPlaySound },
};
JArray jarr = new JArray();
jarr.Add(jo);
effectInfo.ActionList = jarr;
}
giftFileName = filename + ".png";
//effectInfo.PicPath=
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Web", Msg = "222" });
}
}
IDbInterface db_logs = new SQLiteDataProvider();
db_logs.ConnDb(Config.UserDbFolder + "\\DirectLogs\\" + DirectInfo.Id + ".log.data");
if (nickname.Length > 0)
{
RyQuickSQL mySQL = new("Logs");
mySQL.AddField("DirectId", DirectInfo.DirectId);
mySQL.AddField("NickName", nickname);
mySQL.AddField("data_id", data_id);//送礼物的ID,防止重复记录
mySQL.AddField("ContentType", ContentType);
if (content.Length == 0)
{
if (ContentType != "评论") { content = ContentType; }
}
if (isgift)
{
mySQL.AddField("Content", "送出礼物*"+ gift_count);
}
else
{
mySQL.AddField("Content", content);
}
mySQL.AddField("AddTime", DateTime.Now.ToInt64());
if (db_logs.Update(mySQL, "data_id=@data_id") == 0)
{ db_logs.Insert(mySQL); }
if (giftFileName.Length > 0)
{
RyQuickSQL mySQL2 = new RyQuickSQL("GiftLogs");
mySQL2.AddField("DirectId", DirectInfo.DirectId);
mySQL2.AddField("NickName", nickname);
mySQL2.AddField("GiftFileName", giftFileName);
mySQL2.AddField("data_id", data_id);//送礼物的ID,防止重复记录
mySQL2.AddField("GiftCount", gift_count);//礼物数量
mySQL2.AddField("AddTime", DateTime.Now.ToInt64());
if (db_logs.Update(mySQL2, "data_id=@data_id") == 0)
{ db_logs.Insert(mySQL2); }
}
}
else
{
}
db_logs.Free();
hash_data[data_id] = 1;
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
var ds = db.ReadData("select * from Rules order by SortIndex desc");
if (ds.HaveData())
{
for (int r = 0; r < ds.Tables[0].Rows.Count; r++)
{
var row = ds.GetRow(r);
JObject jo = JObject.Parse(row["RuleJson"].ToString() ?? "");
JArray jarr = jo.GetJsonValue("Content", new JArray());
var ismatch = false;
if (jarr.Count > 0)
{
if (item.InnerText.Length > 0 || content.Length>0)
{
for (int j = 0; j < jarr.Count; j++)
{
if (item.InnerText.IndexOfEx(jarr[j].ToString()) >= 0 || content.IndexOfEx(jarr[j].ToString()) >= 0)
{
ismatch = true;
break;
}
}
}
}
else
{
ismatch = true;
}
if (ismatch)
{
var GiftTrigger=jo.GetJsonValue("GiftTrigger", false);
var DianzanTrigger = jo.GetJsonValue("DianzanTrigger", false);
var match2 = false;
if((GiftTrigger && isgift))
{
var GiftTriggerList = jo.GetJsonValue("GiftTriggerList", "");
if (GiftTriggerList.Length == 0 || ("|" + GiftTriggerList + "|").IndexOfEx("|" + giftFileName + "|") >= 0)
{
match2 = true;
}
}
else if(DianzanTrigger && ContentType == "点赞")
{
match2 = true;
}
else if(!GiftTrigger && !DianzanTrigger)//功能都没开
{
match2 = true;
}
ismatch = match2;
}
if (ismatch)
{
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = DirectInfo.Id;
effectInfo.RuleID = row["id"].ToInt();
effectInfo.LoopCount = gift_count == 0 ? 1 : gift_count;
effectInfo.ActionList = jo.GetJsonValue("ActionList", new JArray());
//HandyControl.Controls.MessageBox.Show(row["RuleName"].ToString());
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Web", Msg = "222" });
break;
}
}
}
ds?.Dispose();
db.Free();
}
}
}
isRunning = false;
}
}
catch
{
isRunning = false;
}
}
// 1 创建定时器
DispatcherTimer timer = new DispatcherTimer();
public ChromiumWebBrowser chromeBrowser;
public void InitCef()
{
if (!Config.InitCef)
{
//参数设置
CefSettings settings = new CefSettings();
//settings.ResourcesDirPath = Config.GetCurrentFolder + "SysDb\\runtimes\\win-x64\\native\\";
settings.CachePath = Config.UserDbFolder + "\\WebCache";
settings.UserDataPath = Config.UserDbFolder + "\\WebUserData";
settings.PersistSessionCookies = true;
settings.IgnoreCertificateErrors = true;
// settings.Locale = "zh-CN";
// settings.CefCommandLineArgs.Add("disable-gpu", "1");//去掉gpu否则chrome显示有问题
Cef.Initialize(settings);
Config.InitCef = true;
}
//创建实例
chromeBrowser = new ChromiumWebBrowser("https://live.douyin.com/"+DirectInfo.DirectId+"?is_aweme_tied=1");
chromeBrowser.Initialized += ChromeBrowser_Initialized;
// 将浏览器放入容器中
MainGrid.Children.Add(chromeBrowser);
}
private void ChromeBrowser_Initialized(object? sender, EventArgs e)
{
timer.Start();
}
/// <summary>
/// 创建数据库
/// </summary>
public void CreateDb()
{
IDbInterface db = new SQLiteDataProvider();
if (db.ConnDb(Config.UserDbFolder + "\\DirectLogs\\"+ DirectInfo.Id+".log.data") == 1)
{
#region
RyQuickSQL mySQL = new("Logs");
mySQL.AddField("DirectId", "");
mySQL.AddField("NickName", "");
mySQL.AddField("data_id", "");//送礼物的ID,防止重复记录
mySQL.AddField("ContentType", "");
mySQL.AddField("Content", "");
mySQL.AddField("AddTime", 0L);
db.CreateDb(mySQL);
#endregion
#region
mySQL.Clear();
mySQL.TableName = "GiftLogs";
mySQL.AddField("DirectId", "");
mySQL.AddField("NickName", "");
mySQL.AddField("GiftFileName", "");
mySQL.AddField("data_id", "");//送礼物的ID,防止重复记录
mySQL.AddField("GiftCount", 0);//礼物数量
mySQL.AddField("AddTime", 0L);
db.CreateDb(mySQL);
#endregion
//
}
db.Free();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Title = DirectInfo.Name + "[" + DirectInfo.Platform + "]网页";
CreateDb();
InitCef();
WeakReferenceMessenger.Default.Register<MsgToken>(this, OnReceive);
//4 开启定时器
}
private bool IsProcUse { get; set; } = false;
private void OnReceive(object recipient, MsgToken message)
{
if (message.Value is EffectInfo)
{
if (message.Msg == "Close" && message.From == "Effects")
{
IsProcUse = true;
this.Close();
return;
}
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!IsProcUse)
{
if (HandyControl.Controls.MessageBox.Show("关闭Web窗口,将导致当前直播特效功能也同步关闭,是否确定要关闭?", "关闭确认", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
{
e.Cancel = true;
}
else
{
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = DirectInfo.Id;
effectInfo.EffectMode = -1;
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Web", Msg = "Close" });
}
}
}
private void BtnHidden_Click(object sender, RoutedEventArgs e)
{
this.Hide();
}
}
}

98
Source/LiveTools.csproj Normal file
View File

@ -0,0 +1,98 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows7.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
<PlatformTarget>x64</PlatformTarget>
<ApplicationIcon>主图.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Remove="Pngs\Icons\home.png" />
<None Remove="Pngs\Icons\主图.ico" />
<None Remove="Pngs\Icons\主图.png" />
<None Remove="Pngs\Icons\头像.png" />
<None Remove="Pngs\Icons\设置.png" />
<None Remove="Pngs\直播.png" />
<None Remove="Pngs\规则引擎.png" />
</ItemGroup>
<ItemGroup>
<Content Include="主图.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Pngs\Icons\home.png" />
<Resource Include="Pngs\Icons\主图.ico" />
<Resource Include="Pngs\Icons\主图.png" />
<Resource Include="Pngs\Icons\头像.png" />
<Resource Include="Pngs\Icons\直播.png" />
<Resource Include="Pngs\Icons\规则引擎.png" />
<Resource Include="Pngs\Icons\设置.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CefSharp.Wpf.NETCore" Version="108.4.130" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="HandyControl" Version="3.5.1" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Data.SQLite" Version="1.0.118" />
</ItemGroup>
<ItemGroup>
<Reference Include="RaX">
<HintPath>bin\Debug\net6.0-windows7.0\RaX.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Content\MainContent.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Content\LeftMainContent.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Update="Tools\Direct\FrmAddDirect.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Direct\FrmDirectView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Login\FrmAccountInfo.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Login\FrmRegUser.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Login\FrmUseSN.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Login\FrmLogin.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Setting\FrmSetting.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="API\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_LastSelectedProfileId>E:\My Codes\我的代码\C#\LiveTools\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
</PropertyGroup>
<ItemGroup>
<ApplicationDefinition Update="App.xaml">
<SubType>Designer</SubType>
</ApplicationDefinition>
</ItemGroup>
<ItemGroup>
<Compile Update="Content\MainWinContent.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Rules\FrmAddRule.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Rules\FrmRuleView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="FrmWeb.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="MainWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Tools\Rules\GiftItem.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Update="Content\MainContent.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Content\LeftMainContent.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Content\MainWinContent.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Data\GeometryIcon.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="RuleItem\Rule_ShowPic.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="RuleItem\Rule_Variable.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="RuleItem\Rule_SoundPlay.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Direct\FrmAddDirect.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Direct\FrmDirectView.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Login\FrmAccountInfo.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Login\FrmRegUser.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Login\FrmUseSN.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Login\FrmLogin.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Rules\FrmAddRule.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Rules\FrmRuleView.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="FrmWeb.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="FrmEffects.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="MainWindow.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Rules\GiftItem.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Tools\Setting\FrmSetting.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
</Project>

25
Source/LiveTools.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34707.107
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiveTools", "LiveTools.csproj", "{56146D74-BDCE-406C-8142-2B285F9837EE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{56146D74-BDCE-406C-8142-2B285F9837EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56146D74-BDCE-406C-8142-2B285F9837EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56146D74-BDCE-406C-8142-2B285F9837EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56146D74-BDCE-406C-8142-2B285F9837EE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {43250F82-D2D9-42F4-B146-ADC52BFA6632}
EndGlobalSection
EndGlobal

18
Source/MainWindow.xaml Normal file
View File

@ -0,0 +1,18 @@
<hc:Window x:Class="LiveTools.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
mc:Ignorable="d"
Title="直播助手"
Icon="/Pngs/Icons/主图.png"
Style="{StaticResource WindowWin10}"
Background="{DynamicResource SecondaryRegionBrush}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
d:DesignHeight="800"
d:DesignWidth="1400"
Width="1100" Loaded="Window_Loaded">
<ContentControl Name="ControlMain"/>
</hc:Window>

151
Source/MainWindow.xaml.cs Normal file
View File

@ -0,0 +1,151 @@
using CefSharp.DevTools.CSS;
using HandyControl.Controls;
using HandyControl.Data;
using HandyControl.Tools;
using LiveTools.Data;
using Microsoft.Win32;
using ryCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace LiveTools
{
/// <summary>
/// MainWindow2.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : HandyControl.Controls.Window
{
public MainWindow()
{
InitializeComponent();
this.Title = "紫林直播助手V"+RySoft.VersionStr;
//2 设置定时器时间间隔 TimeSpan.FromSeconds(1) 以秒单位
timer.Interval = TimeSpan.FromMilliseconds(1000);
//3 设置每隔时间要执行的方法 ,绑定方法到定时器上
//tick 是事件名, new System.EventHandler() 参数是方法名
timer.Tick += Timer_Tick;
Random rd=new Random();
RandMinute=rd.Next(0, 60);
}
/// <summary>
/// 软件启动时间
/// </summary>
private DateTime dt_SoftStart = DateTime.Now;
private int RandMinute = 0;
private void Timer_Tick(object sender, EventArgs e)
{
if(DateTime.Now.Minute== RandMinute && DateTime.Now.Second== dt_SoftStart.Second)
{
var th = new Thread(delegate() { API.CheckedLogin(out _); });
th.Start();
}
}
DispatcherTimer timer = new DispatcherTimer();
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
//DataContext = ViewModelLocator.Instance.Main;
//NonClientAreaContent = new NonClientAreaContent();
ControlMain.Content = new Content.MainWinContent();
}
/// <summary>
/// 检查自动更新
/// </summary>
private void CheckUpdate(bool isSlient)
{
var th = new Thread(delegate () { Start(); });
th.Start();
void Start()
{
RyWeb.QuickWeb web=new RyWeb.QuickWeb();
var http= web.Get("http://reg.itjs.top/update/"+Config.SoftId+".json");
if(http.StatusCode== System.Net.HttpStatusCode.OK)
{
Json json = new Json(http.Html);
var new_ver = json.GetJsonValue("new_ver");
if(RySoft.CompareVer(RySoft.VersionStr, new_ver)==1)//如果存在新版
{
var update_date= json.GetJsonValue("update_date_str");//更新时间
var update_url = json.GetJsonValue("update_url");//更新网址
var mustupdate = json.GetJsonValue("mustupdate");//指定版本以下的必须更新
var is_must_update = false;//是否强制更新
if (RySoft.CompareVer(RySoft.VersionStr, mustupdate) == 1)
{
is_must_update = true;
}
var message = "发现存在新版[V" + new_ver + "],更新时间:" + update_date + "。";
Config.MustUpdate = is_must_update;
Config.NewVerUrl = update_url;
if (is_must_update)
{
message += "当前版本已经过老,必须更新后才能使用!";
}
else
{
message += "是否进行更新?";
}
if (!isSlient)
{
if (HandyControl.Controls.MessageBox.Show(new MessageBoxInfo
{
Message = message + "\r\n\r\n更新日志:\r\n" + json.GetJsonValue("update_desc", "暂无"),
Caption = "发现新版本",
Button = MessageBoxButton.YesNo,
IconBrushKey = ResourceToken.AccentBrush,
IconKey = ResourceToken.AskGeometry,
}) == MessageBoxResult.Yes)
{
RyFiles.OpenUrl(update_url);
}
}
else
{
Growl.Info(new GrowlInfo
{
Message = "[V" + new_ver + "]新版已推出,更新时间:" + update_date + "。\r\n更新日志:\r\n" + json.GetJsonValue("update_desc", "暂无"),
CancelStr = "取消",
ActionBeforeClose = isConfirmed =>
{
//Growl.Info(isConfirmed.ToString());
return true;
}
});
}
}
}
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
timer.Start();
try
{
RegistryKey LMach = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser,RegistryView.Registry64);
RegistryKey softwareRun = LMach.CreateSubKey("Software\\RySoft\\"+Config.SoftId, true);
if (softwareRun != null)
{
softwareRun.SetValue("InstallDir", Config.GetCurrentFolder);
}
softwareRun.Close();
LMach.Close();
}
catch
{
}
CheckUpdate(false);
}
}
}

BIN
Source/Pngs/Icons/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0-windows7.0\publish\win-x64\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net6.0-windows7.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<History>True|2024-04-07T01:56:14.4083209Z||;True|2024-04-07T09:55:02.4321529+08:00||;True|2024-04-07T09:53:01.2699593+08:00||;True|2024-04-03T16:21:10.4387835+08:00||;False|2024-04-03T16:20:46.9533320+08:00||;True|2024-04-03T15:59:23.0498758+08:00||;False|2024-04-03T15:58:18.3023795+08:00||;True|2024-04-03T15:36:09.2401460+08:00||;True|2024-04-03T15:30:28.9444930+08:00||;True|2024-04-03T15:28:51.4700365+08:00||;False|2024-04-03T15:27:37.5056077+08:00||;False|2024-04-03T15:25:43.1339604+08:00||;False|2024-04-03T15:24:26.0771751+08:00||;False|2024-04-03T15:24:03.8303830+08:00||;False|2024-04-03T15:23:36.3533402+08:00||;True|2024-04-03T15:07:57.5158510+08:00||;True|2024-04-03T11:27:02.2909106+08:00||;True|2024-04-02T22:54:31.5223940+08:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

26
Source/Properties/Settings.Designer.cs generated Normal file
View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace LiveTools.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
</SettingsFile>

19
Source/RuleItem/IRule.cs Normal file
View File

@ -0,0 +1,19 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools.RuleItem
{
interface IRule
{
int ID { get; set; }
string RuleID { get; }
void LoadSetting(JObject jo);
JObject SettingJson();
void Run(EffectInfo info, JObject jo);
bool CheckVerification();
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiveTools.RuleItem
{
public class RuleMsg
{
public int ID { get; set; } = 0;
public string Message { get; set; } = "";
}
}

View File

@ -0,0 +1,24 @@
<UserControl
x:Class="LiveTools.Rule_ShowPic"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
Background="White"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid Height="120">
<Border Style="{StaticResource BorderTipPrimary}" Height="35" VerticalAlignment="Top">
<TextBlock Text="砸图片" Foreground="Black" FontWeight="Bold"/>
</Border>
<TextBlock Text="同时播放声效" HorizontalAlignment="Left" Margin="283,0,0,0" VerticalAlignment="Center"/>
<ToggleButton x:Name="ChkPlaySound" IsChecked="True" Margin="360,0,0,0" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" Height="24" VerticalAlignment="Center" HorizontalAlignment="Left" Width="45"/>
<hc:ImageSelector x:Name="PicSelector" HorizontalAlignment="Left" Margin="4,37,0,0" VerticalAlignment="Top" Height="80" Width="80" Filter="(.png)|*.png"/>
<TextBlock Text="图片大小" HorizontalAlignment="Left" Margin="91,0,0,0" VerticalAlignment="Center" RenderTransformOrigin="0.585,2.063" Width="75" />
<hc:NumericUpDown x:Name="NumPicSize" Value="70" HorizontalAlignment="Left" Margin="176,0,0,0" VerticalAlignment="Center" Width="97"/>
<TextBlock Text="砸图片数量" HorizontalAlignment="Left" Margin="91,88,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.585,2.063"/>
<hc:NumericUpDown x:Name="NumPicCount" HorizontalAlignment="Left" Margin="176,82,0,0" Value="50" VerticalAlignment="Top" Width="97"/>
<Button x:Name="BtnClose" HorizontalAlignment="Right" VerticalAlignment="Top" Height="32" Click="BtnClose_Click" Style="{StaticResource ButtonIcon}" Foreground="{DynamicResource DangerBrush}" hc:IconElement.Geometry="{StaticResource ErrorGeometry}"/>
</Grid>
</UserControl>

View File

@ -0,0 +1,93 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using HandyControl.Controls;
using LiveTools.Data;
using LiveTools.RuleItem;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// Rule_ShowPic.xaml 的交互逻辑
/// </summary>
public partial class Rule_ShowPic : UserControl, IRule
{
public Rule_ShowPic()
{
InitializeComponent();
}
public string RuleID { get;} = "ShowPic";
public int ID { get; set; } = 0;
public void LoadSetting(JObject jo)
{
ChkPlaySound.IsChecked = jo.GetJsonValue("PlaySound", true);
var PicPath = API.GetTruePath(jo.GetJsonValue("PicPath", ""));
if (System.IO.File.Exists(PicPath))
{
PicSelector.SetValue(ImageSelector.UriPropertyKey, new Uri(PicPath));
PicSelector.SetValue(ImageSelector.PreviewBrushPropertyKey, new ImageBrush(BitmapFrame.Create(PicSelector.Uri, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.None))
{
Stretch = PicSelector.Stretch
});
PicSelector.SetCurrentValue(FrameworkElement.ToolTipProperty, PicPath);
}
NumPicSize.Value = jo.GetJsonValue("PicSize", 70);
NumPicCount.Value = jo.GetJsonValue("PicCount", 10);
}
public JObject SettingJson()
{
return new JObject()
{
{ "Name",this.GetType().Name},
{ "Mode",RuleID},
{ "PlaySound", ChkPlaySound.IsChecked ?? true },
{ "PicPath",API.GetRelativePath(PicSelector.Uri.LocalPath) },
{ "PicSize", NumPicSize.Value.ToInt() },
{ "PicCount", NumPicCount.Value.ToInt() },
};
}
public void Run(EffectInfo info, JObject jo)
{
}
public bool CheckVerification()
{
if (PicSelector.Uri == null)
{
HandyControl.Controls.MessageBox.Warning("请选择图片。", "提示");
return false;
}
if (!System.IO.File.Exists(PicSelector.Uri.LocalPath))
{
HandyControl.Controls.MessageBox.Warning("选择的图片不存在。", "提示");
return false;
}
return true;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
WeakReferenceMessenger.Default.Send<RuleMsg>(new RuleMsg() { ID = ID, Message="Close" });
}
}
}

View File

@ -0,0 +1,28 @@
<UserControl
x:Class="LiveTools.Rule_SoundPlay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
Background="White"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
<Grid Height="120">
<Border Style="{StaticResource BorderTipPrimary}" Height="35" VerticalAlignment="Top">
<TextBlock Text="播放声音" Foreground="Black" FontWeight="Bold"/>
</Border>
<Button x:Name="BtnClose" HorizontalAlignment="Right" VerticalAlignment="Top" Height="32" Click="BtnClose_Click" Style="{StaticResource ButtonIcon}" Foreground="{DynamicResource DangerBrush}" hc:IconElement.Geometry="{StaticResource ErrorGeometry}"/>
<hc:TextBox x:Name="TxtCustomSound" IsReadOnly="True" Margin="7,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Center" HorizontalAlignment="Left" Width="396"/>
<Button x:Name="BtnBrowserCustomSound" Content="文件" Margin="485,0,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" Click="BtnBrowserCustomSound_Click" Width="73"/>
<TextBlock Text="允许声音同时播放" HorizontalAlignment="Left" Margin="7,89,0,0" VerticalAlignment="Top"/>
<ToggleButton x:Name="ChkMultiPlaySound" IsChecked="True" Margin="111,85,481,0" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" Height="24" VerticalAlignment="Top" Checked="ChkMultiPlaySound_Checked" Unchecked="ChkMultiPlaySound_Unchecked"/>
<TextBlock Text="声音间隔" HorizontalAlignment="Left" Margin="164,89,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.585,2.063"/>
<hc:NumericUpDown IsEnabled="False" x:Name="NumPlaySoundInterval" HorizontalAlignment="Left" Margin="217,82,0,0" Value="10" Minimum="0" Maximum="10000" VerticalAlignment="Top" Width="72"/>
<TextBlock Text="秒" HorizontalAlignment="Left" Margin="295,89,0,0" VerticalAlignment="Top" RenderTransformOrigin="-1.583,2.486"/>
<Button x:Name="BtnBrowserCustomSoundByFolder" Content="文件夹" Margin="561,0,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" Click="BtnBrowserCustomSoundByFolder_Click" Width="73"/>
<Button x:Name="BtnPlay" hc:IconElement.Geometry="{StaticResource Play}" Content="播放" Margin="408,0,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" Click="BtnPlay_Click" Width="72"/>
<TextBlock Text="音量" HorizontalAlignment="Left" Margin="323,89,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.585,2.063"/>
<Slider x:Name="SliVol" hc:TipElement.Visibility="Visible" hc:TipElement.Placement="Top" IsSnapToTickEnabled="True" Maximum="100" Value="100" TickFrequency="10" TickPlacement="BottomRight" Margin="352,85,43,10" ValueChanged="SliVol_ValueChanged"/>
</Grid>
</UserControl>

View File

@ -0,0 +1,173 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using HandyControl.Controls;
using LiveTools.Data;
using LiveTools.RuleItem;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// Rule_SoundPlay.xaml 的交互逻辑
/// </summary>
public partial class Rule_SoundPlay : UserControl, IRule
{
public Rule_SoundPlay()
{
InitializeComponent();
}
public string RuleID { get;} = "SoundPlay";
public int ID { get; set; } = 0;
public void LoadSetting(JObject jo)
{
TxtCustomSound.Text = jo.GetJsonValue("PlayCustomSound_Path", "");
ChkMultiPlaySound.IsChecked = jo.GetJsonValue("MultiPlaySound_On", false);
NumPlaySoundInterval.Value = jo.GetJsonValue("PlaySoundInterval", 10);
SliVol.Value = jo.GetJsonValue("Vol", 100);
NumPlaySoundInterval.IsEnabled = ChkMultiPlaySound.IsChecked == false;
}
public JObject SettingJson()
{
return new JObject()
{
{ "Name",this.GetType().Name},
{ "Mode",RuleID},
{ "PlayCustomSound_Path", TxtCustomSound.Text},
{ "MultiPlaySound_On",ChkMultiPlaySound.IsChecked },
{ "PlaySoundInterval", NumPlaySoundInterval.Value.ToInt() },
{ "Vol", SliVol.Value.ToInt() }
};
}
public void Run(EffectInfo info, JObject jo)
{
//for (int m = 0; m < info.LoopCount; m++)
//{
// for (int i = 0; i < info.Count; i++)
// {
// Random rd2 = new Random(Guid.NewGuid().GetHashCode());
// this.Dispatcher.Invoke(new Action(() =>
// {
// Image simpleImage = new Image();
// simpleImage.Width = info.PicSize;
// //Canvas.SetLeft(simpleImage, i * 300);
// // Set the image source.
// simpleImage.Source = GetImage(info.PicPath);
// cvsGround.Children.Add(simpleImage);
// RotateTransform rotateTransform = new RotateTransform(rd2.Next(0, 181));
// simpleImage.RenderTransform = rotateTransform;
// KK(simpleImage);
// }));
// }
//}
}
public bool CheckVerification()
{
if(!RyFiles.FileOrDirExist(API.GetTruePath(TxtCustomSound.Text)))
{
HandyControl.Controls.MessageBox.Warning("请选择音频文件或文件夹。", "提示");
return false;
}
return true;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
WeakReferenceMessenger.Default.Send<RuleMsg>(new RuleMsg() { ID = ID, Message="Close" });
}
private void BtnBrowserCustomSound_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.FileName = API.GetTruePath(TxtCustomSound.Text);
fileDialog.Filter = "音频文件|*.mp3;*.wav;*.flac;*.wma";
if (fileDialog.ShowDialog() == true)
{
TxtCustomSound.Text = API.GetRelativePath(fileDialog.FileName);
}
}
private void BtnBrowserCustomSoundByFolder_Click(object sender, RoutedEventArgs e)
{
var fileDialog = new System.Windows.Forms.FolderBrowserDialog();
fileDialog.SelectedPath = API.GetTruePath(TxtCustomSound.Text);
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
TxtCustomSound.Text = API.GetRelativePath(fileDialog.SelectedPath);
}
}
private void ChkMultiPlaySound_Checked(object sender, RoutedEventArgs e)
{
if (NumPlaySoundInterval == null) { return; }
NumPlaySoundInterval.IsEnabled = ChkMultiPlaySound.IsChecked==false;
}
private void ChkMultiPlaySound_Unchecked(object sender, RoutedEventArgs e)
{
NumPlaySoundInterval.IsEnabled = ChkMultiPlaySound.IsChecked == false;
}
LiveTools.SoundPlay soundPlay = new LiveTools.SoundPlay();
private bool Playing { get; set; } = false;
private void BtnPlay_Click(object sender, RoutedEventArgs e)
{
if (Playing) { soundPlay.Stop(); Playing = false;BtnPlay.Content = "播放"; return; }
Playing = true;
BtnPlay.Content = "停止";
var customSound_Path = API.GetTruePath(TxtCustomSound.Text);
soundPlay.Volume = SliVol.Value.ToInt()/100f;
new Thread(Start).Start();
void Start()
{
if (System.IO.File.Exists(customSound_Path))
{
soundPlay.Play(customSound_Path);
}
else if (System.IO.Directory.Exists(customSound_Path))
{
var files = RyFiles.GetFiles(customSound_Path,"*.mp3;*.wav;*.flac;*.wma");
if (files != null && files.Count>0)
{
Random rd = new Random(Guid.NewGuid().GetHashCode());
soundPlay.Play(files[rd.Next(0,files.Count)]);
}
}
Dispatcher.Invoke(new Action(() =>
{
BtnPlay.Content = "播放";
}));
Playing = false;
}
}
private void SliVol_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
soundPlay.Volume = SliVol.Value.ToInt()/100f;
}
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
if (Playing) { soundPlay.Stop(); Playing = false; }
}
}
}

View File

@ -0,0 +1,25 @@
<UserControl
x:Class="LiveTools.Rule_Variable"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
Background="White"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid Height="120">
<Border Style="{StaticResource BorderTipPrimary}" Height="35" VerticalAlignment="Top">
<TextBlock Text="设置变量" Foreground="Black" FontWeight="Bold"/>
</Border>
<Button x:Name="BtnClose" HorizontalAlignment="Right" VerticalAlignment="Top" Height="32" Click="BtnClose_Click" Style="{StaticResource ButtonIcon}" Foreground="{DynamicResource DangerBrush}" hc:IconElement.Geometry="{StaticResource ErrorGeometry}"/>
<hc:ComboBox Name="CbbVariable" IsEditable="True" Margin="63,0,0,0" Height="28" VerticalAlignment="Center" HorizontalAlignment="Left" Width="156"/>
<hc:NumericUpDown x:Name="NumValue" HorizontalAlignment="Left" Margin="306,0,0,0" Value="1" Minimum="0" Maximum="1000000" VerticalAlignment="Center" Width="72"/>
<TextBlock Text="变量名称" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Center" RenderTransformOrigin="0.585,2.063"/>
<hc:ComboBox x:Name="CbbOpMode" SelectedIndex="0" Margin="224,0,0,0" Height="28" VerticalAlignment="Center" HorizontalAlignment="Left" Width="77">
<ComboBoxItem Content="增加"/>
<ComboBoxItem Content="减少"/>
<ComboBoxItem Content="设为"/>
</hc:ComboBox>
</Grid>
</UserControl>

View File

@ -0,0 +1,91 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using HandyControl.Controls;
using LiveTools.Data;
using LiveTools.RuleItem;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// Rule_SoundPlay.xaml 的交互逻辑
/// </summary>
public partial class Rule_Variable : UserControl, IRule
{
public Rule_Variable()
{
InitializeComponent();
}
public string RuleID { get;} = "Variable";
public int ID { get; set; } = 0;
public void LoadSetting(JObject jo)
{
CbbVariable.Text = jo.GetJsonValue("Variable", "");
CbbOpMode.SelectedIndex=jo.GetJsonValue("OpMode", 0,2,0);
NumValue.Value = jo.GetJsonValue("Value",1);
}
public JObject SettingJson()
{
return new JObject()
{
{ "Name",this.GetType().Name},
{ "Mode",RuleID},
{ "Variable", CbbVariable.Text},
{ "OpMode",CbbOpMode.SelectedIndex },
{ "Value", NumValue.Value }
};
}
public void Run(EffectInfo info, JObject jo)
{
//for (int m = 0; m < info.LoopCount; m++)
//{
// for (int i = 0; i < info.Count; i++)
// {
// Random rd2 = new Random(Guid.NewGuid().GetHashCode());
// this.Dispatcher.Invoke(new Action(() =>
// {
// Image simpleImage = new Image();
// simpleImage.Width = info.PicSize;
// //Canvas.SetLeft(simpleImage, i * 300);
// // Set the image source.
// simpleImage.Source = GetImage(info.PicPath);
// cvsGround.Children.Add(simpleImage);
// RotateTransform rotateTransform = new RotateTransform(rd2.Next(0, 181));
// simpleImage.RenderTransform = rotateTransform;
// KK(simpleImage);
// }));
// }
//}
}
public bool CheckVerification()
{
return true;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
WeakReferenceMessenger.Default.Send<RuleMsg>(new RuleMsg() { ID = ID, Message="Close" });
}
}
}

View File

@ -0,0 +1,28 @@
<hc:Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LiveTools"
xmlns:hc="https://handyorg.github.io/handycontrol" x:Class="LiveTools.FrmAddDirect"
mc:Ignorable="d"
Style="{StaticResource WindowWin10}"
Title="添加直播" Height="240" Width="430"
Background="{DynamicResource RegionBrush}"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="名称" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox Name="TxtName" HorizontalAlignment="Left" Margin="10,30,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.ColumnSpan="4"/>
<Button Name="BtnOK" Content="应用" Width="74" Margin="262,164,0,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnOK_Click" Grid.Column="1"/>
<Button Name="BtnCancel" Content="取消" Width="74" Margin="341,164,0,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnCancel_Click" Grid.Column="1"/>
<TextBlock Text="直播ID" HorizontalAlignment="Left" Margin="13,69,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox x:Name="TxtDirectId" HorizontalAlignment="Left" Margin="10,89,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="290" Grid.ColumnSpan="2"/>
<TextBlock Text="直播平台" HorizontalAlignment="Left" Margin="305,73,0,0" VerticalAlignment="Top" Grid.Column="1"/>
<hc:ComboBox Name="CbbPlatform" Margin="305,89,15,0" Height="28" VerticalAlignment="Top" Grid.Column="1"/>
</Grid>
</hc:Window>

View File

@ -0,0 +1,78 @@
using HandyControl.Controls;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmAddDirect.xaml 的交互逻辑
/// </summary>
public partial class FrmAddDirect : HandyControl.Controls.Window
{
public FrmAddDirect()
{
InitializeComponent();
CbbPlatform.Items.Add("抖音");
CbbPlatform.SelectedIndex = 0;
}
public int SelectedId { get; set; } = 0;
public string PicPath { get; set; } = "";
public void GetInfo()
{
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
var ds = db.ReadData("select * from Direct where id=" + SelectedId);
if (ds.HaveData())
{
var row = ds.GetRow(0);
TxtName.Text = row["Name"].ToString();
CbbPlatform.Text= row["Platform"].ToString();
TxtDirectId.Text = row["DirectId"].ToString();
}
ds?.Dispose();
db.Free();
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
if (TxtName.Text.Length==0)
{
HandyControl.Controls.MessageBox.Show("请输入名称。", "提示");
return;
}
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(Config.DbFullPath);
ryCommonDb.RyQuickSQL mySQL = new ryCommonDb.RyQuickSQL("Direct");
mySQL.AddField("Name", TxtName.Text);
mySQL.AddField("Platform", CbbPlatform.Text);
mySQL.AddField("DirectId", TxtDirectId.Text);
mySQL.AddField("EditTime",DateTime.Now.ToInt64());
if(SelectedId==-1 || db.Update(mySQL,"id="+ SelectedId)==0)
{
mySQL.AddField("AddTime", DateTime.Now.ToInt64());
db.Insert(mySQL);
}
db.Free();
DialogResult = true;
}
private void BtnCancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
}
}

View File

@ -0,0 +1,63 @@
<UserControl
x:Class="LiveTools.FrmDirectView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools"
Margin="0,0,0,0"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="19*"/>
<RowDefinition Height="15*"/>
</Grid.RowDefinitions>
<ListView MinHeight="300" Name="LvDirect" Background="White" Margin="0,40,300,0" SelectionMode="Single" MouseDoubleClick="LvRules_MouseDoubleClick" PreviewMouseLeftButtonDown="LvRules_PreviewMouseLeftButtonDown" Grid.RowSpan="2" SelectionChanged="LvDirect_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Width="120" Header="名称" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Width="80" Header="直播平台" DisplayMemberBinding="{Binding Platform}" />
<GridViewColumn Width="130" Header="直播ID" DisplayMemberBinding="{Binding DirectId}" />
<GridViewColumn Width="70" Header="状态" DisplayMemberBinding="{Binding State}" />
<GridViewColumn Width="150" Header="编辑时间" DisplayMemberBinding="{Binding EditTime}" />
</GridView>
</ListView.View>
</ListView>
<TabControl MaxWidth="800" Style="{StaticResource TabControlInLine}" Margin="0,10,0,0" Grid.RowSpan="2" HorizontalAlignment="Right" Width="295">
<TabItem Header="日志" IsSelected="True" Width="100" HorizontalAlignment="Left">
<Grid Background="{DynamicResource RegionBrush}" HorizontalAlignment="Left">
<ListView MinHeight="300" Name="LvLogs" Background="White" SelectionMode="Single" >
<ListView.View>
<GridView>
<GridViewColumn Width="70" Header="时间" DisplayMemberBinding="{Binding AddTimeStr}" />
<GridViewColumn Width="280" Header="内容" DisplayMemberBinding="{Binding Content}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</TabItem>
<TabItem Header="礼物统计" IsSelected="True" Width="100" HorizontalAlignment="Left">
<Grid Background="{DynamicResource RegionBrush}" HorizontalAlignment="Left">
<DataGrid x:Name="LvGiftLogs" RowHeight="60" HeadersVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding DataList}" Background="White" BorderThickness="0">
<DataGrid.Columns>
<DataGridTemplateColumn Width="70" CanUserResize="False" Header="礼物">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding ImgPath}" Stretch="UniformToFill"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Content}" Header="数量" Width="200" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</TabItem>
</TabControl>
<Button Name="BtnAdd" Content="添加" Width="73" Margin="1,7,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnAdd_Click"/>
<Button x:Name="BtnEdit" Content="修改" Width="73" Margin="79,7,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnEdit_Click"/>
<Button x:Name="BtnDel" Content="删除" Width="73" Margin="157,7,0,0" Style="{StaticResource ButtonDanger}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnDel_Click"/>
<Button x:Name="BtnStart" Content="开启监控" Margin="0,7,300,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Right" VerticalAlignment="Top" Width="73" Click="BtnStart_Click"/>
<Button x:Name="BtnTestGifts" Content="测试礼物" Margin="0,7,378,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Right" VerticalAlignment="Top" Width="73" Click="BtnTestGifts_Click"/>
</Grid>
</UserControl>

View File

@ -0,0 +1,361 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmRuleView.xaml 的交互逻辑
/// </summary>
public partial class FrmDirectView : UserControl
{
public FrmDirectView()
{
InitializeComponent();
Config.CreateDb();
LvLogs.ItemsSource = list_logs;
LvGiftLogs.ItemsSource = list_gift_logs;
LoadDb();
WeakReferenceMessenger.Default.Register<MsgToken>(this, OnReceive);
}
public ObservableCollection<LogInfo> list_logs { get; set; } = new ObservableCollection<LogInfo>();
public ObservableCollection<GiftLogInfo> list_gift_logs { get; set; } = new ObservableCollection<GiftLogInfo>();
public ObservableCollection<DirectInfo> list { get; set; } = new ObservableCollection<DirectInfo>();
public void LoadDb()
{
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
var ds = db.ReadData("select * from Direct");
//this.DataContext = DataList;
list.Clear();
if (ds.HaveData())
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
var row = ds.GetRow(i);
list.Add(new DirectInfo() {Id=row["id"].ToInt(), Name = row["Name"].ToString()??"", Platform = row["Platform"].ToString() ?? "", DirectId = row["DirectId"].ToString() ?? "", EditTime = row["EditTime"].ToInt64().ToDateTime().ToString()});
}
}
ds?.Dispose();
LvDirect.ItemsSource = list;
db.Free();
}
private void BtnAdd_Click(object sender, RoutedEventArgs e)
{
FrmAddDirect frm = new FrmAddDirect
{
SelectedId = -1,
Owner = Application.Current.MainWindow,
};
if (frm.ShowDialog()==true)
{
LoadDb();
}
}
private void EditDirect()
{
var row = LvDirect.SelectedItem as DirectInfo;
if (row == null) { return; }
FrmAddDirect frm = new FrmAddDirect
{
SelectedId = row.Id,
Title = "修改直播",
Owner = Application.Current.MainWindow,
};
frm.GetInfo();
if (frm.ShowDialog() == true)
{
LoadDb();
}
}
private void BtnEdit_Click(object sender, RoutedEventArgs e)
{
EditDirect();
}
private void LvRules_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var row = LvDirect.SelectedItem as DirectInfo;
if (row == null) { return; }
EditDirect();
}
private void BtnDel_Click(object sender, RoutedEventArgs e)
{
var row = LvDirect.SelectedItem as DirectInfo;
if (row == null) { return; }
if(HandyControl.Controls.MessageBox.Show("一旦删除,将无法恢复。确定要删除吗?","警告",MessageBoxButton.OKCancel)!= MessageBoxResult.OK)
{
return;
}
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
db.DelById("Direct", row.Id.ToString());
list.Remove(row);
db.Free();
}
private void LvRules_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var point = e.GetPosition(null);
var hitTestResult = VisualTreeHelper.HitTest(LvDirect, point);
if (hitTestResult == null)
{
LvDirect.SelectedItem = null;
}
else if(hitTestResult.VisualHit is ScrollViewer)
{
LvDirect.SelectedItem = null;
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void OnReceive(object recipient, MsgToken message)
{
if (message.Value is EffectInfo info)
{
if (message.Msg == "Close")
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].Id == info.ID)
{
list[i].State = "";
var row = LvDirect.SelectedItem as DirectInfo;
if (row != null && row.Id== info.ID)
{
BtnStart.Content = "开启监控";
BtnTestGifts.IsEnabled = false;
}
break;
}
}
}
}
}
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
if(Config.MustUpdate)
{
HandyControl.Controls.MessageBox.Show("当前版本已经过老,请更新到新版再使用。", "提示");
RyFiles.OpenUrl(Config.NewVerUrl);
return;
}
var row = LvDirect.SelectedItem as DirectInfo;
if (row == null) { return; }
///如果已经过期
if (Config.UserInfo.UserId.Length == 0 || Config.UserInfo.OutTime < DateTime.Now.ToInt64() || Config.UserInfo.isOut == 1)
{
HandyControl.Controls.MessageBox.Show("当前账号VIP有效期已经过期,请及时续费,否则功能将失效。", "提示");
}
if (row.State.Length == 0)
{
row.State = "运行中";
BtnTestGifts.IsEnabled = true;
BtnStart.Content = "停止监控";
FrmWeb frmWeb = new FrmWeb();
frmWeb.DirectInfo = row;
frmWeb.Show();
FrmEffects frmEffects = new FrmEffects();
frmEffects.Title = row.Name + "-" + row.Platform + "特效";
frmEffects.DirectInfo = row;
frmEffects.Show();
}
else
{
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = row.Id;
effectInfo.EffectMode = -1;
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Web", Msg = "Close" });
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Effects", Msg = "Close" });
}
}
private void LvDirect_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
list_logs.Clear();
list_gift_logs.Clear();
if (e.AddedItems.Count==1)
{
var row = e.AddedItems[0] as DirectInfo;
if (row == null) { return; }
if(row.State == "运行中")
{
BtnStart.Content = "停止监控";
BtnTestGifts.IsEnabled = true;
}
else
{
BtnStart.Content = "开启监控";
BtnTestGifts.IsEnabled = false;
}
if (System.IO.File.Exists(Config.UserDbFolder + "\\DirectLogs\\" + row.Id + ".log.data"))
{
var time = DateTime.Now.Date;
IDbInterface db_logs = new SQLiteDataProvider();
db_logs.ConnDb(Config.UserDbFolder + "\\DirectLogs\\" + row.Id + ".log.data");
var ds = db_logs.ReadData("select * from Logs where AddTime>="+time.ToInt64()+ " and AddTime<"+ time.AddDays(1).ToInt64()+" order by AddTime desc");
if (ds.HaveData())
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
var item = ds.GetRow(i);
list_logs.Add(new LogInfo() {
Id = item["id"].ToInt(),
Content= item["NickName"].ToString()+":"+ item["Content"].ToString(),
AddTime= item["AddTime"].ToInt64().ToDateTime()
});
}
}
ds?.Dispose();
var ds_gifts = db_logs.ReadData("select distinct giftFileName from GiftLogs where AddTime>=" + time.ToInt64() + " and AddTime<" + time.AddDays(1).ToInt64());
if (ds_gifts.HaveData())
{
for (int i = 0; i < ds_gifts.Tables[0].Rows.Count; i++)
{
var item = ds_gifts.GetRow(i);
if ((item[0].ToString()??"").Length == 0) { continue; }
var ds_gift_count=db_logs.ReadData("select sum(GiftCount) from GiftLogs where AddTime>=" + time.ToInt64() + " and AddTime<" + time.AddDays(1).ToInt64()+ " and giftFileName='"+ item[0].ToString() + "'");
list_gift_logs.Add(new GiftLogInfo() { ImgPath= Config.AllUserDbFolder + "\\GiftImages\\Auto\\" + item[0].ToString(), Content=ds_gift_count.GetFirstRowCellValue()+"个" });
ds_gift_count?.Dispose();
}
}
ds_gifts?.Dispose();
db_logs.Free();
}
}
else
{
BtnTestGifts.IsEnabled = false;
}
}
private void BtnTestGifts_Click(object sender, RoutedEventArgs e)
{
var row = LvDirect.SelectedItem as DirectInfo;
if (row == null) { return; }
if (row.State.Length == 0) { return; }
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = row.Id;
effectInfo.LoopCount = 1;
var picPath = "";
var gifts = System.IO.Directory.GetFiles(Config.SysDbFolder+ "\\Gifts","*.png");
if(gifts!=null && gifts.Length>0)
{
Random rd = new Random();
picPath = gifts[rd.Next(0, gifts.Length)];
}
if (picPath.Length > 0)
{
JObject jo = new JObject()
{
{ "Name","Rule_ShowPic"},
{ "Mode","ShowPic"},
{ "PlaySound", Config.PlaySound},
{ "PicPath",API.GetRelativePath(picPath) },
{ "PicSize",Config.PicSize },
{ "PicCount", Config.PicCount },
{ "MultiPlaySound", Config.MultiPlaySound },
};
JArray jarr = new JArray();
jarr.Add(jo);
effectInfo.ActionList = jarr;
}
//HandyControl.Controls.MessageBox.Show(row["RuleName"].ToString());
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Web", Msg = "222" });
}
}
public class LogInfo : ObservableObject
{
/// <summary>
/// id
/// </summary>
public int Id { get; set; } = 0;
/// <summary>
/// AddTime
/// </summary>
public DateTime AddTime { get; set; } = DateTime.Now;
/// <summary>
/// AddTimeStr
/// </summary>
public string AddTimeStr {
get
{
return AddTime.ToString("HH:mm:ss");
}
}
/// <summary>
/// Content
/// </summary>
public string Content { get; set; } = "";
}
public class GiftLogInfo : ObservableObject
{
/// <summary>
/// id
/// </summary>
public int Id { get; set; } = 0;
/// <summary>
/// Content
/// </summary>
public string ImgPath { get; set; } = "";
/// <summary>
/// Content
/// </summary>
public string Content { get; set; } = "";
}
public class DirectInfo : ObservableObject
{
/// <summary>
/// id
/// </summary>
public int Id { get; set; } = 0;
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; } = "";
/// <summary>
/// 直播平台
/// </summary>
public string Platform { get; set; } = "";
/// <summary>
/// 直播ID
/// </summary>
public string DirectId { get; set; } = "";
/// <summary>
/// 编辑时间
/// </summary>
public string EditTime { get; set; } = "";
private string _state="";
/// <summary>
/// 状态
/// </summary>
public string State {
get => _state;
set => SetProperty(ref _state, value);
}
}
}

View File

@ -0,0 +1,21 @@
<UserControl
x:Class="LiveTools.FrmAccountInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid Height="300" Width="400">
<TextBlock Text="账户ID" HorizontalAlignment="Left" Margin="32,33,0,0" VerticalAlignment="Top" FontWeight="Bold"/>
<TextBlock Text="昵称" HorizontalAlignment="Left" Margin="32,53,0,0" VerticalAlignment="Top" FontWeight="Bold"/>
<TextBlock Text="过期时间" HorizontalAlignment="Left" Margin="32,73,0,0" VerticalAlignment="Top" FontWeight="Bold"/>
<TextBlock Name="LblUserId" Text="未知" HorizontalAlignment="Left" Margin="100,33,0,0" VerticalAlignment="Top"/>
<TextBlock Name="LblNickName" Text="未知" HorizontalAlignment="Left" Margin="100,53,0,0" VerticalAlignment="Top"/>
<TextBlock Name="LblOutDate" Text="未知" HorizontalAlignment="Left" Margin="100,73,0,0" VerticalAlignment="Top"/>
<Button x:Name="BtnUseSN" Content="续费" Width="86" Margin="30,103,0,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnUseSN_Click"/>
<TextBlock Name="LblPriceAds" TextWrapping="Wrap" FontSize="15" Text="月卡59元,季卡99元,年卡199元,永久卡299元" Margin="0,150,0,122" Foreground="#FF104D61"/>
<TextBlock x:Name="LblBuyContact" TextWrapping="Wrap" FontSize="15" Text="联系方式:QQ1017848709" Margin="0,183,0,89" Foreground="#FF104D61"/>
</Grid>
</UserControl>

View File

@ -0,0 +1,70 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmLogin.xaml 的交互逻辑
/// </summary>
public partial class FrmAccountInfo : UserControl
{
public FrmAccountInfo()
{
InitializeComponent();
LblUserId.Text = Config.UserInfo.UserId;
LblNickName.Text = Config.UserInfo.NickName;
LblOutDate.Text = Config.UserInfo.OutDateStr;
LblPriceAds.Text = Config.UserInfo.PriceAds;
if (Config.UserInfo.BuyContact.Length > 0)
{
LblBuyContact.Text = "购买联系方式:" + Config.UserInfo.BuyContact;
}
WeakReferenceMessenger.Default.Register<string>(this, OnReceive);
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void OnReceive(object recipient, string message)
{
if (message=="login")
{
LblUserId.Text = Config.UserInfo.UserId;
LblNickName.Text = Config.UserInfo.NickName;
LblOutDate.Text = Config.UserInfo.OutDateStr;
}
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
}
private void BtnUseSN_Click(object sender, RoutedEventArgs e)
{
FrmUseSN frm = new FrmUseSN();
frm.Owner = Application.Current.MainWindow;
if(frm.ShowDialog()==true)
{
LblOutDate.Text = Config.UserInfo.OutDateStr;
}
}
}
}

View File

@ -0,0 +1,22 @@
<UserControl
x:Class="LiveTools.FrmLogin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid Height="273" Width="431">
<ToggleButton x:Name="BtnOK" Content="登录" Width="72" Margin="138,157,0,0" Style="{StaticResource ToggleButtonLoadingPrimary}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnOK_Click" Checked="BtnOK_Checked"/>
<Button x:Name="BtnQuit" Content="退出" Width="72" Margin="216,157,0,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnQuit_Click"/>
<TextBlock Text="账号ID" HorizontalAlignment="Left" Margin="81,64,0,0" VerticalAlignment="Top"/>
<CheckBox Name="ChkAutoLogin_On" Margin="123,130,235,0" Content="记住账号" IsChecked="True" IsEnabled="True" VerticalAlignment="Top"/>
<hc:TextBox x:Name="TxtUserId" HorizontalAlignment="Left" Margin="123,58,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="164" Height="21"/>
<TextBlock Text="密码" HorizontalAlignment="Left" Margin="81,104,0,0" VerticalAlignment="Top"/>
<hc:PasswordBox x:Name="TxtPwd" HorizontalAlignment="Left" Margin="123,98,0,0" VerticalAlignment="Top" Width="164" Height="21" KeyDown="TxtPwd_KeyDown"/>
<CheckBox x:Name="ChkRememberUserId_On" Margin="214,130,144,0" Content="自动登录" IsChecked="True" IsEnabled="True" VerticalAlignment="Top"/>
<TextBlock Text="续费" Name="LblUseSN" HorizontalAlignment="Left" Margin="338,64,0,0" VerticalAlignment="Top" TextDecorations="Underline" Foreground="#FF184AC7" FontWeight="Bold" MouseDown="LblUseSN_MouseDown"/>
<TextBlock Text="注册" x:Name="LblRegUser" HorizontalAlignment="Left" Margin="300,64,0,0" VerticalAlignment="Top" TextDecorations="Underline" Foreground="#FF184AC7" FontWeight="Bold" MouseDown="LblRegUser_MouseDown"/>
</Grid>
</UserControl>

View File

@ -0,0 +1,248 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmLogin.xaml 的交互逻辑
/// </summary>
public partial class FrmLogin : UserControl
{
public FrmLogin()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Json json = new Json(RyFiles.ReadAllText(Config.AllUserDbFolder + "\\Setting.json"));
TxtUserId.Text = json.GetJsonValue("UserId", "");
string pwd = rySafe.AES.Decode(json.GetJsonValue("Pwd", ""), Config.GetMac() + "|" + TxtUserId.Text);
if (pwd.IndexOf("121") == 0) { pwd = pwd.Substring(3); } else { pwd = ""; }
TxtPwd.Password = pwd;
if (pwd != "")
{
ChkAutoLogin_On.IsChecked = true;
TxtUserId.IsEnabled = false;
TxtPwd.IsEnabled = false;
BtnOK_Click(this,new RoutedEventArgs());
}
else
{
TxtUserId.SelectionLength = 0;
TxtUserId.SelectionStart = 0;
if (TxtUserId.Text == "")
{ TxtUserId.Focus(); }
else
{
TxtPwd.Focus();
}
}
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
if (!TxtUserId.Text.Length.IsInRange(1, 20))
{
HandyControl.Controls.MessageBox.Show("请输入有效的用户id", "提示");
return;
}
if (!TxtPwd.Password.Length.IsInRange(1, 25))
{
HandyControl.Controls.MessageBox.Show("请输入有效的密码", "提示");
return;
}
TxtUserId.IsEnabled = false;
TxtPwd.IsEnabled = false;
BtnOK.IsEnabled = false;
BtnQuit.IsEnabled = false;
BtnOK.IsChecked = true;
LblUseSN.IsEnabled = false;
UserId = TxtUserId.Text;
Pwd = TxtPwd.Password;
AutoLogin_On = ChkAutoLogin_On.IsChecked??false;
RememberUserId_On = ChkRememberUserId_On.IsChecked ?? false;
Thread th = new Thread(Login);
th.Start();
}
private string UserId { get; set; } = "";
private string Pwd { get; set; } = "";
private bool AutoLogin_On { get; set; } = false;
private bool RememberUserId_On { get; set; } = false;
private void Login()
{
try
{
Config.UserInfo.Cookie = "";
Config.UserInfo.UserId = "";
Config.UserInfo.NickName = "";
Config.UserInfo.isOut = 1;
HttpResult html = Config.ry_api.Post(Config.Api_Url + "user.aspx", "api=login&userid=" + RyWeb.WebDecode.Escape(UserId) +
"&soft_id=" + RyWeb.WebDecode.Escape(Config.SoftId) + "&pwd=" + RyWeb.WebDecode.Escape(Pwd)
+ "&ver=" + RyWeb.WebDecode.Escape(RySoft.VersionStr) + "&hdid=" + RyWeb.WebDecode.Escape(Config.GetMac()) + "&login=1");
string jsonText = API.GetJson(html.Html);
if (jsonText != "")
{
Json json = new Json(jsonText);
string result = json.GetJsonValue(Data.ConstVar.json_Result);
if (result == Data.ResultVar.json_Success.ToString())
{
Config.UserInfo.UserId=UserId;
//Config.UserInfo.
Config.UserInfo.NickName = json.GetJsonValue("nickname");
Config.UserInfo.Pwd = Pwd;
Config.UserInfo.OutDateStr = json.GetJsonValue("out_date");
Config.UserInfo.OutTime = Config.UserInfo.OutDateStr.ToDateTime().ToInt64();
Config.UserInfo.isOut = json.GetJsonValue("isout").ToInt();
Config.UserInfo.PriceAds = json.GetJsonValue("PriceAds", "月卡59元,季卡99元,年卡199元,永久卡299元");
Config.UserInfo.BuyContact = json.GetJsonValue("BuyContact", "QQ1017848709");
//ClsPram.ZZ_Op = json.GetJsonValue("zz_op").ToInt();
Config.UserInfo.Media_id = json.GetJsonValue("media_id");
Config.UserInfo.Setting = json.GetJsonValue("setting");
Config.UserInfo.Sys_Setting = json.GetJsonValue("sys_setting");
Config.UserInfo.Parent_Setting = json.GetJsonValue("parent_setting");
//SysPram.LoadPram();
Config.UserInfo.Ads_id = json.GetJsonValue("ads_id");
//string notice = json.GetJsonValue("notice");
//if (notice != "")
//{
// JArray jar = JArray.Parse(json.GetJsonValue("notice"));
// for (int i = 0; i < jar.Count; i++)
// {
// JObject j = JObject.Parse(jar[i].ToString());
// ClsPram.notice_list.Add(new Notice()
// {
// title = j["title"].ToString(),
// link = j["link"].ToString(),
// ishot = j["ishot"].ToString().ToInt()
// });
// }
//}
Dispatcher.Invoke(new Action(() =>
{
if (Config.UserInfo.OutTime<=DateTime.Now.Date.AddDays(3).ToInt64())
{
HandyControl.Controls.MessageBox.Show("当前账号VIP有效期即将过期,请及时续费。", "提示");
}
Json json = new Json(RyFiles.ReadAllText(Config.UserDbFolder+ "\\Setting.json"));
if (AutoLogin_On || RememberUserId_On)
{
json.jo["UserId"] = UserId;
if (AutoLogin_On)
{
Config.isAutoLogin = 2;
json.jo["Pwd"] = rySafe.AES.Encode("121" + Pwd, Config.GetMac() + "|" + UserId);
}
else
{
Config.isAutoLogin = 1;
json.jo["Pwd"]="";
}
}
else
{
json.jo["UserId"] = "";
Config.isAutoLogin = 0;
}
RyFiles.WriteAllText(Config.AllUserDbFolder + "\\Setting.json", json.Text);
WeakReferenceMessenger.Default.Send<string>("login");
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken("") { ID = MsgTokenId.Login, From = "LeftMain", Msg = "222" });
}));
}
else if (result ==Data.ResultVar.json_UserOutDate.ToString())
{
HandyControl.Controls.MessageBox.Show("当前账号需要续费才能使用,请续费。", "提示");
FrmUseSN frm = new FrmUseSN();
frm.TxtUserId.Text = UserId;
frm.ShowDialog();
EndLoginUI();
}
else
{
HandyControl.Controls.MessageBox.Show(json.GetJsonValue(ConstVar.json_ResultText), "错误代码:" + result);
EndLoginUI();
}
}
else
{
EndLoginUI();
Dispatcher.Invoke(new Action(() =>
{
HandyControl.Controls.MessageBox.Show("服务器异常,请联系管理员", "错误代码:-100000");
}));
}
}
catch { EndLoginUI(); }
}
private void EndLoginUI()
{
Dispatcher.Invoke(new Action(() =>
{
TxtUserId.IsEnabled = true;
TxtPwd.IsEnabled = true;
BtnOK.IsEnabled = true;
BtnQuit.IsEnabled = true;
BtnOK.IsChecked = false;
LblUseSN.IsEnabled = true;
}));
}
private void TxtPwd_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
BtnOK_Click(this, new RoutedEventArgs());
}
}
private void BtnQuit_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Close() ;
}
private void BtnOK_Checked(object sender, RoutedEventArgs e)
{
}
private void LblUseSN_MouseDown(object sender, MouseButtonEventArgs e)
{
Config.UserInfo.UserId = TxtUserId.Text;
FrmUseSN frm = new FrmUseSN();
frm.Owner = Application.Current.MainWindow;
if (frm.ShowDialog() == true)
{
}
Config.UserInfo.UserId = "";
}
private void LblRegUser_MouseDown(object sender, MouseButtonEventArgs e)
{
FrmRegUser frm = new FrmRegUser();
frm.Owner = Application.Current.MainWindow;
if (frm.ShowDialog() == true)
{
TxtUserId.Text = frm.TxtUserId.Text;
}
}
}
}

View File

@ -0,0 +1,34 @@
<hc:Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LiveTools"
xmlns:hc="https://handyorg.github.io/handycontrol" x:Class="LiveTools.FrmRegUser"
mc:Ignorable="d"
Style="{StaticResource WindowWin10}"
Title="激活" Height="500" Width="455"
Background="{DynamicResource RegionBrush}"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="用户ID" HorizontalAlignment="Left" Margin="28,18,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox Name="TxtUserId" HorizontalAlignment="Left" Margin="29,38,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
<ToggleButton Name="BtnOK" Content="注册" Margin="0,0,99,19" Style="{StaticResource ToggleButtonLoadingPrimary}" Grid.ColumnSpan="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="BtnOK_Click" Width="74" Height="28"/>
<Button Name="BtnCancel" Content="取消" Margin="0,0,21,19" Style="{StaticResource ButtonPrimary}" Grid.ColumnSpan="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="BtnCancel_Click" Width="74" Height="28"/>
<TextBlock Text="昵称" HorizontalAlignment="Left" Margin="28,72,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox x:Name="TxtnickName" HorizontalAlignment="Left" Margin="29,92,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
<TextBlock Text="密码" HorizontalAlignment="Left" Margin="28,126,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:PasswordBox x:Name="txtPwd" ShowEyeButton="True" HorizontalAlignment="Left" Margin="29,146,0,0" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
<TextBlock Text="邮箱" HorizontalAlignment="Left" Margin="28,180,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox x:Name="TxtEmail" HorizontalAlignment="Left" Margin="29,200,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
<TextBlock Text="手机号" HorizontalAlignment="Left" Margin="27,235,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox x:Name="TxtPhone" HorizontalAlignment="Left" Margin="28,254,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
<TextBlock Text="邀请码" HorizontalAlignment="Left" Margin="28,289,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox x:Name="TxtInvite" HorizontalAlignment="Left" Margin="29,308,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
</Grid>
</hc:Window>

View File

@ -0,0 +1,117 @@
using DotNet4.Utilities;
using HandyControl.Controls;
using LiveTools.Data;
using Microsoft.VisualBasic.ApplicationServices;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmAddRule.xaml 的交互逻辑
/// </summary>
public partial class FrmRegUser : HandyControl.Controls.Window
{
public FrmRegUser()
{
InitializeComponent();
}
private string postdata { get; set; } = "";
private void RegUser()
{
try
{
Config.UserInfo.Cookie = "";
HttpResult html = Config.ry_api.Post(Config.Api_Url + "user.aspx", postdata);
string jsonText = API.GetJson(html.Html);
Dispatcher.Invoke(new Action(() =>
{
TxtUserId.IsEnabled = true;
txtPwd.IsEnabled = true;
BtnOK.IsEnabled = true;
}));
if (jsonText != "")
{
Json json = new Json(jsonText);
string result = json.GetJsonValue(ConstVar.json_Result);
if (result == ResultVar.json_Success.ToString())
{
Dispatcher.Invoke(new Action(() =>
{
HandyControl.Controls.MessageBox.Show(json.GetJsonValue(ConstVar.json_ResultText), "用户注册");
DialogResult = true;
}));
}
else
{
Dispatcher.Invoke(new Action(() =>
{
HandyControl.Controls.MessageBox.Show(json.GetJsonValue(ConstVar.json_ResultText), "注册失败");
TxtUserId.IsEnabled = true;
txtPwd.IsEnabled = true;
BtnOK.IsChecked = false;
BtnOK.IsEnabled = true;
}));
}
}
else
{
Dispatcher.Invoke(new Action(() =>
{
HandyControl.Controls.MessageBox.Show("服务器异常,请联系管理员", "错误代码:-100000");
TxtUserId.IsEnabled = true;
txtPwd.IsEnabled = true;
BtnOK.IsChecked = false;
BtnOK.IsEnabled = true;
}));
}
}
catch(Exception ex)
{
Dispatcher.Invoke(new Action(() =>
{
HandyControl.Controls.MessageBox.Show("程序出错", "注册失败");
TxtUserId.IsEnabled = true;
txtPwd.IsEnabled = true;
BtnOK.IsChecked = false;
BtnOK.IsEnabled = true;
}));
}
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
TxtUserId.IsEnabled = false;
txtPwd.IsEnabled = false;
BtnOK.IsChecked = true;
BtnOK.IsEnabled = false;
postdata = "api=reguser&userid=" + RyWeb.WebDecode.Escape(TxtUserId.Text) +
"&softid=" + RyWeb.WebDecode.Escape(Config.SoftId) + "&nickName=" + RyWeb.WebDecode.Escape(TxtnickName.Text) + "&pwd=" + RyWeb.WebDecode.Escape(txtPwd.Password) + "&email=" + RyWeb.WebDecode.Escape(TxtEmail.Text)
+ "&phone=" + RyWeb.WebDecode.Escape(TxtPhone.Text) + "&Invite=" + RyWeb.WebDecode.Escape(TxtInvite.Text) + "&hdid=" + RyWeb.WebDecode.Escape(Config.GetMac());
Thread th = new Thread(RegUser);
th.Start();
}
private void BtnCancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
}
}

View File

@ -0,0 +1,26 @@
<hc:Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LiveTools"
xmlns:hc="https://handyorg.github.io/handycontrol" x:Class="LiveTools.FrmUseSN"
mc:Ignorable="d"
Style="{StaticResource WindowWin10}"
Title="激活" Height="265" Width="455"
Background="{DynamicResource RegionBrush}"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="用户ID" HorizontalAlignment="Left" Margin="28,18,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox Name="TxtUserId" Background="{DynamicResource LightDangerBrush}" IsReadOnly="True" HorizontalAlignment="Left" Margin="29,38,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
<Button Name="BtnOK" Content="应用" Width="74" Margin="282,192,0,0" Style="{StaticResource ButtonPrimary}" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnOK_Click"/>
<Button Name="BtnCancel" Content="取消" Width="74" Margin="360,192,0,0" Style="{StaticResource ButtonPrimary}" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnCancel_Click"/>
<TextBlock Text="序列号" HorizontalAlignment="Left" Margin="28,78,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<hc:TextBox x:Name="TxtSN" HorizontalAlignment="Left" Margin="29,98,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="405" Grid.Column="1"/>
</Grid>
</hc:Window>

View File

@ -0,0 +1,60 @@
using DotNet4.Utilities;
using HandyControl.Controls;
using LiveTools.Data;
using Microsoft.VisualBasic.ApplicationServices;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmAddRule.xaml 的交互逻辑
/// </summary>
public partial class FrmUseSN : HandyControl.Controls.Window
{
public FrmUseSN()
{
InitializeComponent();
TxtUserId.Text = Config.UserInfo.UserId;
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
HttpResult html = Config.ry_api.Post(Config.Api_Url + "user.aspx", "api=usesn&userid=" + RyWeb.WebDecode.Escape(Config.UserInfo.UserId) +
"&sn=" + RyWeb.WebDecode.Escape(TxtSN.Text));
string jsonText = API.GetJson(html.Html);
Json json = new Json(jsonText);
string result = json.GetJsonValue(ConstVar.json_Result);
if (result == ResultVar.json_Success.ToString())
{
Config.UserInfo.OutDateStr= json.GetJsonValue("out_date");
Config.UserInfo.OutTime=Config.UserInfo.OutDateStr.ToDateTime().ToInt64();
HandyControl.Controls.MessageBox.Show("激活成功。", "提示");
DialogResult = true;
}
else
{
HandyControl.Controls.MessageBox.Show(json.GetJsonValue(ConstVar.json_ResultText), "激活失败");
}
}
private void BtnCancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
}
}

View File

@ -0,0 +1,77 @@
<hc:Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LiveTools"
xmlns:hc="https://handyorg.github.io/handycontrol" x:Class="LiveTools.FrmAddRule"
mc:Ignorable="d"
Style="{StaticResource WindowWin10}"
Title="添加规则" Height="695" Width="760"
Background="#FFF6F6F6"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize"
>
<Window.Resources>
<!-- 定义图标模板 -->
<DataTemplate x:Key="IconTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}" Width="25" Height="25" />
<TextBlock VerticalAlignment="Center" Text="{Binding Text}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="规则名称" HorizontalAlignment="Left" Margin="13,13,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
<hc:Divider Content="触发条件" LineStrokeThickness="1" Orientation="Horizontal" HorizontalContentAlignment="Center" Height="143" Grid.ColumnSpan="2" Margin="6,39,7,0" VerticalAlignment="Top">
</hc:Divider>
<hc:TextBox Name="TxtRuleName" HorizontalAlignment="Left" Margin="96,4,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="372" Grid.ColumnSpan="2"/>
<TextBlock Text="内容触发" Margin="13,68,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
<TextBlock Text="并且至少触发右边一种" TextWrapping="Wrap" Margin="13,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Grid.ColumnSpan="2" Width="76" FontWeight="Bold" Height="31"/>
<Grid Margin="90,59,10,0" Grid.ColumnSpan="2" Height="49" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<hc:ScrollViewer MaxWidth="500" Name="ScrTag" Grid.Column="0" Height="60" >
<hc:TagContainer BorderThickness="0" Name="TagContent" MaxWidth="520" VerticalAlignment="Top" HorizontalAlignment="Left">
</hc:TagContainer>
</hc:ScrollViewer>
<hc:TextBox x:Name="TxtContent" Grid.Column="1" HorizontalAlignment="Left" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="139" KeyDown="TxtContent_KeyDown"/>
<Button Name="BtnAddContent" Grid.Column="1" Content="添加" Width="52" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnAddContent_Click" Margin="144,0,0,0"/>
</Grid>
<ToggleButton Name="ChkGiftTrigger" IsChecked="True" Margin="153,116,0,0" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" Grid.ColumnSpan="2" Height="24" VerticalAlignment="Top" Checked="ChkGiftTrigger_Checked" Unchecked="ChkGiftTrigger_Unchecked" HorizontalAlignment="Left" Width="48">
</ToggleButton>
<TextBlock Text="礼物触发" HorizontalAlignment="Left" Margin="97,120,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" MouseDown="TextBlock_MouseDown"/>
<Button Name="BtnOK" Content="应用" Margin="0,0,99,21" Style="{StaticResource ButtonPrimary}" Grid.ColumnSpan="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="BtnOK_Click" Width="74" Height="28"/>
<Button Name="BtnCancel" Content="取消" Margin="0,0,21,21" Style="{StaticResource ButtonPrimary}" Grid.ColumnSpan="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="BtnCancel_Click" Width="74" Height="28"/>
<ToggleButton x:Name="ChkDianzan" IsChecked="True" Margin="567,116,0,0" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" Grid.ColumnSpan="2" Height="24" VerticalAlignment="Top" HorizontalAlignment="Left" Width="47" RenderTransformOrigin="0.5,0.5">
<ToggleButton.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</ToggleButton.RenderTransform>
</ToggleButton>
<TextBlock Text="点赞" HorizontalAlignment="Left" Margin="538,120,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" RenderTransformOrigin="0.167,-0.081"/>
<hc:Divider Content="执行动作" LineStrokeThickness="1" Orientation="Horizontal" HorizontalContentAlignment="Center" Height="19" Grid.ColumnSpan="2" Margin="6,181,7,0" VerticalAlignment="Top"/>
<hc:ScrollViewer Name="ScrRules" Grid.ColumnSpan="2" Margin="4,203,7,68">
<StackPanel Width="717" Name="PnlRules" />
</hc:ScrollViewer>
<Button x:Name="BtnShowPic" Content="砸图片" Width="74" Margin="10,631,0,0" Style="{StaticResource ButtonDefault}" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnShowPic_Click"/>
<Button x:Name="BtnSoundPlay" Content="播放声音" Width="74" Margin="89,631,0,0" Style="{StaticResource ButtonDefault}" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnSoundPlay_Click"/>
<TextBlock Text="排序" HorizontalAlignment="Left" Margin="484,13,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
<hc:NumericUpDown ToolTip="数值越大,优先级越高" x:Name="NumSortIndex" Value="0" HorizontalAlignment="Left" Margin="518,5,0,0" VerticalAlignment="Top" Width="98" Grid.ColumnSpan="2"/>
<Button x:Name="BtnVariable" Content="设置变量" Width="74" Margin="168,631,0,0" Style="{StaticResource ButtonDefault}" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnVariable_Click"/>
<hc:CheckComboBox MaxHeight="62" Name="CbbGifts" ItemTemplate="{StaticResource IconTemplate}" Margin="199,113,0,0" hc:InfoElement.ShowClearButton="True" MaxWidth="380" ShowSelectAllButton="True" Grid.ColumnSpan="2" VerticalAlignment="Top" HorizontalAlignment="Left" Width="334">
</hc:CheckComboBox>
</Grid>
</hc:Window>

View File

@ -0,0 +1,270 @@
using CommunityToolkit.Mvvm.Messaging;
using HandyControl.Controls;
using LiveTools.Data;
using LiveTools.RuleItem;
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmAddRule.xaml 的交互逻辑
/// </summary>
public partial class FrmAddRule : HandyControl.Controls.Window
{
public FrmAddRule()
{
InitializeComponent();
PnlRules.Width = ScrRules.Width;
//CbbGifts.Items.Clear();
//CbbGifts.ItemsSource = list_gift;
//list_gift.Add(new GiftItem2() { Text = "1111" });
if (System.IO.Directory.Exists(Config.AllUserDbFolder + "\\GiftImages\\Auto"))
{
var files = System.IO.Directory.GetFiles(Config.AllUserDbFolder + "\\GiftImages\\Auto","*.png");
for (int i = 0; i < files.Length; i++)
{
GiftItem item = new GiftItem();
//CbbGifts.DataContext = list_gift;
item.Text = "礼物" + (i + 1);
item.ImageFileName = System.IO.Path.GetFileName(files[i]);
item.Image = new BitmapImage(new Uri(files[i]));
CbbGifts.Items.Add(item);
}
}
//list_gift.Add(new GiftItem() { Text = "222" });
WeakReferenceMessenger.Default.Register<RuleMsg>(this, OnReceive);
}
private ObservableCollection<GiftItem2> list_gift { get; set; } = new ObservableCollection<GiftItem2>();
private void OnReceive(object recipient, RuleMsg message)
{
if (message.Message == "Close")
{
for (int i = 0; i < PnlRules.Children.Count; i++)
{
if (PnlRules.Children[i] is UserControl ctl)
{
if (ctl is IRule rule)
{
if (rule.ID == message.ID)
{
PnlRules.Children.Remove(ctl);
}
}
}
}
}
}
public int SelectedId { get; set; } = 0;
public string PicPath { get; set; } = "";
public void GetInfo()
{
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
var ds = db.ReadData("select * from Rules where id=" + SelectedId);
if (ds.HaveData())
{
var row = ds.GetRow(0);
TxtRuleName.Text = row["RuleName"].ToString();
NumSortIndex.Value = row["SortIndex"].ToDouble();
JObject jo = JObject.Parse(row["RuleJson"].ToString() ?? "");
JArray jarr = jo.GetJsonValue("Content", new JArray());
TagContent.Items.Clear();
for (int i = 0; i < jarr.Count; i++)
{
TagContent.Items.Add(new Tag() { Content = jarr[i].ToString() });
}
var GiftTriggerList = "|"+jo.GetJsonValue("GiftTriggerList","")+"|";//触发的礼物列表
CbbGifts.SelectedItems.Clear();
for (int i = 0; i < CbbGifts.Items.Count; i++)
{
var gift= (GiftItem)CbbGifts.Items[i];
if(GiftTriggerList.IndexOfEx("|"+ gift.ImageFileName+"|")>=0)
{
CbbGifts.SelectedItems.Add(gift);
}
}
ChkGiftTrigger.IsChecked = jo.GetJsonValue("GiftTrigger", false);
ChkDianzan.IsChecked = jo.GetJsonValue("DianzanTrigger", false);
PnlRules.Children.Clear();
var action = jo.GetJsonValue("ActionList", new JArray());
if (action != null)
{
for (int i = 0; i < action.Count; i++)
{
var action_item = (JObject)action[i];
var lll = "LiveTools." + action_item.GetJsonValue("Name", "");
Type type = Type.GetType("LiveTools." + action_item.GetJsonValue("Name", "")); // 获取类型对象
if (type != null)
{
object instance = Activator.CreateInstance(type);
if (instance != null && instance is UserControl ctl)
{
if (ctl is IRule rule)
{
ctl.Margin = new Thickness(1, 0, 1, 2);
rule.ID = index;
rule.LoadSetting(action_item);
PnlRules.Children.Add(ctl);
}
}
}
}
}
}
ds?.Dispose();
db.Free();
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
if (TxtRuleName.Text.Length == 0)
{
HandyControl.Controls.MessageBox.Show("请输入规则名称。", "提示");
return;
}
for (int i = 0; i < PnlRules.Children.Count; i++)
{
var item = PnlRules.Children[i];
if (item != null && item is UserControl ctl)
{
if (ctl is IRule rule)
{
if (!rule.CheckVerification())
{
return;
}
}
}
}
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(Config.DbFullPath);
ryCommonDb.RyQuickSQL mySQL = new ryCommonDb.RyQuickSQL("Rules");
mySQL.AddField("RuleName", TxtRuleName.Text);
JArray jarr = new();
for (int i = 0; i < TagContent.Items.Count; i++)
{
if (TagContent.Items[i] is Tag tag)
jarr.Add(tag.Content.ToString());
}
JArray jarr_actions = new();
for (int i = 0; i < PnlRules.Children.Count; i++)
{
var item = PnlRules.Children[i];
if (item != null && item is UserControl ctl)
{
if (ctl is IRule rule)
{
jarr_actions.Add(rule.SettingJson());
}
}
}
var GiftTriggerList = "";//触发的礼物列表
for (int i = 0; i < CbbGifts.SelectedItems.Count; i++)
{
var gift = (GiftItem)CbbGifts.SelectedItems[i];
GiftTriggerList += gift.ImageFileName+"|";
}
JObject jo = new()
{
{ "Content", jarr},
{ "GiftTrigger", ChkGiftTrigger.IsChecked ?? false },
{ "GiftTriggerList", GiftTriggerList.Trim('|')},
{ "DianzanTrigger", ChkDianzan.IsChecked ?? false },
{ "ActionList", jarr_actions },
};
mySQL.AddField("RuleJson", jo.ToString());
mySQL.AddField("SortIndex", NumSortIndex.Value);
mySQL.AddField("EditTime", DateTime.Now.ToInt64());
if (SelectedId == -1 || db.Update(mySQL, "id=" + SelectedId) == 0)
{
mySQL.AddField("AddTime", DateTime.Now.ToInt64());
db.Insert(mySQL);
}
db.Free();
DialogResult = true;
}
private void BtnCancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
private void BtnAddContent_Click(object sender, RoutedEventArgs e)
{
TagContent.Items.Add(new Tag() { Content = TxtContent.Text });
TxtContent.Text = "";
}
int index = 0;
private void BtnShowPic_Click(object sender, RoutedEventArgs e)
{
AddRuleItem(new Rule_ShowPic());
}
private void AddRuleItem(UserControl ctl)
{
index++;
var item = ctl;
item.Margin = new Thickness(1, 0, 1, 2);
if (ctl is IRule rule1)
{
rule1.ID = index;
}
PnlRules.Children.Add(item);
}
private void BtnSoundPlay_Click(object sender, RoutedEventArgs e)
{
AddRuleItem(new Rule_SoundPlay());
}
private void BtnVariable_Click(object sender, RoutedEventArgs e)
{
AddRuleItem(new Rule_Variable());
}
class GiftItem2
{
public string Text { get; set; } = "";
public string ImagePath { get; set; } = "";
}
private void ChkGiftTrigger_Checked(object sender, RoutedEventArgs e)
{
if (CbbGifts == null) { return; }
CbbGifts.IsEnabled = ChkGiftTrigger.IsChecked == true;
}
private void ChkGiftTrigger_Unchecked(object sender, RoutedEventArgs e)
{
if (CbbGifts == null) { return; }
CbbGifts.IsEnabled = ChkGiftTrigger.IsChecked == true;
}
private void TxtContent_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
BtnAddContent_Click(BtnAddContent, new RoutedEventArgs());
}
}
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
Growl.Info("右边不选择,则表示全部礼物都触发,否则表示指定礼物触发。");
}
}
}

View File

@ -0,0 +1,30 @@
<UserControl
x:Class="LiveTools.FrmRuleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid>
<ListView MinHeight="300" Name="LvRules" Background="White" Margin="0,40,0,0" SelectionMode="Single" MouseDoubleClick="LvRules_MouseDoubleClick" PreviewMouseLeftButtonDown="LvRules_PreviewMouseLeftButtonDown">
<ListView.View>
<GridView>
<GridViewColumn Width="350" Header="规则名称" DisplayMemberBinding="{Binding RuleName}" />
<GridViewColumn Width="150" Header="编辑时间" DisplayMemberBinding="{Binding EditTime}" />
<GridViewColumn Header="运行" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Width="70" Content="运行" Click="Cell_Button_Click" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Name="BtnAdd" Content="添加" Width="73" Margin="1,7,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnAdd_Click"/>
<Button x:Name="BtnEdit" Content="修改" Width="73" Margin="79,7,0,0" Style="{StaticResource ButtonDefault}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnEdit_Click"/>
<Button x:Name="BtnDel" Content="删除" Width="73" Margin="157,7,0,0" Style="{StaticResource ButtonDanger}" HorizontalAlignment="Left" VerticalAlignment="Top" Click="BtnDel_Click"/>
</Grid>
</UserControl>

View File

@ -0,0 +1,173 @@
using CommunityToolkit.Mvvm.Messaging;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmRuleView.xaml 的交互逻辑
/// </summary>
public partial class FrmRuleView :UserControl
{
public FrmRuleView()
{
InitializeComponent();
Config.CreateDb();
LoadDb();
}
public ObservableCollection<RuleInfo> list { get; set; } = new ObservableCollection<RuleInfo>();
public void LoadDb()
{
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
var ds = db.ReadData("select * from Rules order by SortIndex desc");
//this.DataContext = DataList;
list.Clear();
if (ds.HaveData())
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
var row = ds.GetRow(i);
list.Add(new RuleInfo() {Id=row["id"].ToInt(), RuleName = row["RuleName"].ToString()??"", EditTime = row["EditTime"].ToInt64().ToDateTime().ToString()});
}
}
ds?.Dispose();
LvRules.ItemsSource = list;
db.Free();
}
private void BtnAdd_Click(object sender, RoutedEventArgs e)
{
if (Config.MustUpdate)
{
HandyControl.Controls.MessageBox.Show("当前版本已经过老,请更新到新版再使用。", "提示");
RyFiles.OpenUrl(Config.NewVerUrl);
return;
}
FrmAddRule frm = new FrmAddRule
{
SelectedId = -1,
Owner = Application.Current.MainWindow,
};
if (frm.ShowDialog()==true)
{
LoadDb();
}
}
private void EditRule()
{
var row = LvRules.SelectedItem as RuleInfo;
if (row == null) { return; }
FrmAddRule frm = new FrmAddRule
{
SelectedId = row.Id,
Title = "修改规则",
Owner = Application.Current.MainWindow,
};
frm.GetInfo();
if (frm.ShowDialog() == true)
{
LoadDb();
}
}
private void BtnEdit_Click(object sender, RoutedEventArgs e)
{
EditRule();
}
private void LvRules_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var row = LvRules.SelectedItem as RuleInfo;
if (row == null) { return; }
EditRule();
}
private void BtnDel_Click(object sender, RoutedEventArgs e)
{
var row = LvRules.SelectedItem as RuleInfo;
if (row == null) { return; }
if (HandyControl.Controls.MessageBox.Show("一旦删除,将无法恢复。确定要删除吗?", "警告", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
{
return;
}
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
//db.DelById("Rules", row.Id.ToString());
list.Remove(row);
db.Free();
}
private void LvRules_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var point = e.GetPosition(null);
var hitTestResult = VisualTreeHelper.HitTest(LvRules, point);
if (hitTestResult == null)
{
LvRules.SelectedItem = null;
}
else if(hitTestResult.VisualHit is ScrollViewer item)
{
LvRules.SelectedItem = null;
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void Cell_Button_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var c = btn.DataContext as RuleInfo;
if (c != null)
{
IDbInterface db = new SQLiteDataProvider();
db.ConnDb(LiveTools.Config.DbFullPath);
var ds = db.ReadData("select * from Rules where id="+c.Id);
if (ds.HaveData())
{
EffectInfo effectInfo = new EffectInfo();
effectInfo.ID = 0;
effectInfo.LoopCount = 1;
JObject jo = JObject.Parse(ds.GetRow(0)["RuleJson"].ToString() ?? "");
effectInfo.ActionList = jo.GetJsonValue("ActionList", new JArray());
WeakReferenceMessenger.Default.Send<MsgToken>(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Web", Msg = "222" });
}
ds?.Dispose();
db.Free();
}
}
}
public class RuleInfo
{
/// <summary>
/// id
/// </summary>
public int Id { get; set; } = 0;
/// <summary>
/// 规则名称
/// </summary>
public string RuleName { get; set; } = "";
/// <summary>
/// 编辑时间
/// </summary>
public string EditTime { get; set; } = "";
}
}

View File

@ -0,0 +1,10 @@
<StackPanel x:Class="LiveTools.GiftItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools"
mc:Ignorable="d" Orientation="Horizontal" >
<Image x:Name="PicIcon" Source="{Binding Image}" Width="25" Height="25" />
<TextBlock x:Name="LblText" VerticalAlignment="Center" Text="{Binding Path=Text}" Margin="5,0,0,0" HorizontalAlignment="Center" />
</StackPanel>

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// GiftItem.xaml 的交互逻辑
/// </summary>
public partial class GiftItem
{
public GiftItem()
{
InitializeComponent();
}
private string text = "";
public string Text
{
get { return text; }
set { text = value;LblText.Text = text; }
}
public string ImageFileName { get; set; } = "";
private BitmapImage image;
public BitmapImage Image
{
get { return image; }
set { image = value; PicIcon.Source = image; }
}
}
}

View File

@ -0,0 +1,33 @@
<UserControl
x:Class="LiveTools.FrmSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LiveTools.Content"
Margin="0,0,0,0"
xmlns:hc="https://handyorg.github.io/handycontrol" Loaded="UserControl_Loaded">
<Grid >
<Button x:Name="BtnOK" Content="保存" Margin="0,0,8,0" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="BtnOK_Click" Height="28" Width="72"/>
<TabControl Style="{StaticResource TabControlInLine}" Margin="0,0,0,33">
<TabItem Header="默认特效" IsSelected="True" Width="100" HorizontalAlignment="Left">
<Grid Background="{DynamicResource RegionBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="发礼物自动触发" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,14,0,0" Grid.ColumnSpan="1" Width="91"/>
<ToggleButton x:Name="ChkGiftTrigger" HorizontalAlignment="Left" IsChecked="True" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" RenderTransformOrigin="0.5,0.5" Height="24" VerticalAlignment="Top" Width="48" Margin="106,10,275,0" Grid.ColumnSpan="2"/>
<TextBlock Text="播放声音" HorizontalAlignment="Left" Margin="10,43,0,0" VerticalAlignment="Top" Grid.ColumnSpan="1"/>
<ToggleButton x:Name="ChkPlaySound" IsChecked="True" Margin="6,39,493,0" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" Height="24" VerticalAlignment="Top" Grid.Column="2"/>
<TextBlock Text="图片大小" HorizontalAlignment="Center" Margin="0,80,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.585,2.063" Width="76" />
<hc:NumericUpDown x:Name="NumPicSize" Value="70" HorizontalAlignment="Left" Margin="10,74,0,0" VerticalAlignment="Top" Width="97" Grid.Column="2"/>
<TextBlock Text="砸图片数量" HorizontalAlignment="Left" Margin="10,121,0,0" VerticalAlignment="Top"/>
<hc:NumericUpDown x:Name="NumPicCount" HorizontalAlignment="Left" Margin="10,115,0,0" Value="50" VerticalAlignment="Top" Width="97" Grid.Column="2"/>
<TextBlock Text="允许同一时刻播放多个声音" HorizontalAlignment="Left" Margin="119,43,0,0" VerticalAlignment="Top" Grid.ColumnSpan="1" Grid.Column="1"/>
<ToggleButton x:Name="ChkMultiPlaySound" IsChecked="True" Margin="268,39,231,0" Style="{StaticResource ToggleButtonSwitch}" hc:VisualElement.HighlightBrush="{DynamicResource PrimaryBrush}" Height="24" VerticalAlignment="Top" Grid.Column="1"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
</UserControl>

View File

@ -0,0 +1,57 @@
using CommunityToolkit.Mvvm.Messaging;
using DotNet4.Utilities;
using LiveTools.Data;
using Newtonsoft.Json.Linq;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LiveTools
{
/// <summary>
/// FrmLogin.xaml 的交互逻辑
/// </summary>
public partial class FrmSetting : UserControl
{
public FrmSetting()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Json json = new Json(RyFiles.ReadAllText(Config.UserDbFolder + "\\Setting.json"));
ChkGiftTrigger.IsChecked = json.GetJsonValue("GiftTrigger", true);
ChkPlaySound.IsChecked = json.GetJsonValue("PlaySound", true);
ChkMultiPlaySound.IsChecked = json.GetJsonValue("MultiPlaySound", true);
NumPicSize.Value = json.GetJsonValue("PicSize", 70);
NumPicCount.Value = json.GetJsonValue("PicCount", 10);
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
Json json = new Json(RyFiles.ReadAllText(Config.UserDbFolder + "\\Setting.json"));
json.SetJsonValue("GiftTrigger", ChkGiftTrigger.IsChecked??true);
json.SetJsonValue("PlaySound", ChkPlaySound.IsChecked ?? true);
json.SetJsonValue("MultiPlaySound", ChkMultiPlaySound.IsChecked ?? true);
json.SetJsonValue("PicSize", NumPicSize.Value.ToInt());
json.SetJsonValue("PicCount", NumPicCount.Value.ToInt());
RyFiles.WriteAllText(Config.UserDbFolder + "\\Setting.json",json.Text);
Config.LoadSetting();
HandyControl.Controls.MessageBox.Show("保存成功。", "提示");
}
}
}

BIN
Source/主图.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB