202509031656
TCPServer 加入多控制方式
This commit is contained in:
parent
403e3c9606
commit
d3de8284f9
513
TCPServer.cs
513
TCPServer.cs
@ -1,10 +1,15 @@
|
|||||||
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.IO; // 為 Path 和 File 提供支持
|
using ActionString = System.Action<string>; // 现在可以在代码中使用 ActionString
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Drawing;
|
||||||
using DBObj;
|
using DBObj;
|
||||||
using OverlayFormObj;
|
using OverlayFormObj;
|
||||||
|
|
||||||
namespace DualScreenDemo
|
namespace DualScreenDemo
|
||||||
{
|
{
|
||||||
public class TCPServer
|
public class TCPServer
|
||||||
@ -12,9 +17,9 @@ namespace DualScreenDemo
|
|||||||
private TcpListener listener;
|
private TcpListener listener;
|
||||||
private const int Port = 1000;
|
private const int Port = 1000;
|
||||||
private readonly string hostNameSuffix;
|
private readonly string hostNameSuffix;
|
||||||
private Room _room;
|
private readonly Room _room;
|
||||||
//private bool isProcessingCommand = false;
|
public static event ActionString OnDisplayBarrage;
|
||||||
|
public static event ActionString OnDisplaySticker;
|
||||||
|
|
||||||
public TCPServer(Room room)
|
public TCPServer(Room room)
|
||||||
{
|
{
|
||||||
@ -25,29 +30,334 @@ namespace DualScreenDemo
|
|||||||
_ = Task.Run(() => Start());
|
_ = Task.Run(() => Start());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 啟動 TCP Server
|
||||||
|
// ================================
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
listener.Start();
|
||||||
|
Console.WriteLine($"Server started on port {Port}.");
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Waiting for connections...");
|
||||||
|
TcpClient client = await listener.AcceptTcpClientAsync();
|
||||||
|
Console.WriteLine("Client connected!");
|
||||||
|
|
||||||
|
_ = Task.Run(() => HandleClient(client));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[Server Error] {ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
listener.Stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 處理 Client 連線
|
||||||
|
// ================================
|
||||||
|
private async Task HandleClient(TcpClient client)
|
||||||
|
{
|
||||||
|
using (client)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NetworkStream stream = client.GetStream();
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
|
||||||
|
while (client.Connected)
|
||||||
|
{
|
||||||
|
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
|
||||||
|
if (bytesRead == 0) break;
|
||||||
|
|
||||||
|
string request = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
|
||||||
|
Console.WriteLine("Received: " + request);
|
||||||
|
|
||||||
|
// 先判斷是否是 Chat 指令 (格式帶有 ",")
|
||||||
|
if (request.Contains(","))
|
||||||
|
await HandleChatCommand(request, stream);
|
||||||
|
else if (request.Length >= 5)
|
||||||
|
{
|
||||||
|
string requestHostSuffix = request.Substring(0, 3);
|
||||||
|
string command = request.Substring(4);
|
||||||
|
|
||||||
|
if (requestHostSuffix.Equals(hostNameSuffix, StringComparison.OrdinalIgnoreCase))
|
||||||
|
await HandleRoomCommand(command, stream);
|
||||||
|
else
|
||||||
|
await HandleOverlayCommand(request, stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[Client Error] {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Client disconnected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 房間控制指令
|
||||||
|
// ================================
|
||||||
|
private async Task HandleRoomCommand(string command, NetworkStream stream)
|
||||||
|
{
|
||||||
|
switch (command.ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "X":
|
||||||
|
_ = SafeInvoke(VideoPlayerForm.Instance, async () =>
|
||||||
|
{
|
||||||
|
_room.set("closed");
|
||||||
|
try { await HttpServer.RestartServer(); }
|
||||||
|
catch (Exception ex) { Console.WriteLine($"RestartServer Error: {ex.Message}"); }
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "O":
|
||||||
|
_room.set("active");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "F":
|
||||||
|
_ = SafeInvoke(PrimaryForm.Instance, () => _room.set("fire"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "pause":
|
||||||
|
TogglePause();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "volume_up":
|
||||||
|
OverlayForm.MainForm.Invoke(() => OverlayForm.MainForm.ShowTopRightLabelTime("音量 ↑", "a2 b3 a4"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "volume_down":
|
||||||
|
OverlayForm.MainForm.Invoke(() => OverlayForm.MainForm.ShowTopRightLabelTime("音量 ↓", "a2 b4 a4"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "mic_up":
|
||||||
|
OverlayForm.MainForm.Invoke(() => OverlayForm.MainForm.ShowTopRightLabelTime("麥克風 ↑", "a2 b5 a4"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "mic_down":
|
||||||
|
OverlayForm.MainForm.Invoke(() => OverlayForm.MainForm.ShowTopRightLabelTime("麥克風 ↓", "a2 b6 a4"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "mute":
|
||||||
|
ToggleMute();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "original_song":
|
||||||
|
PrimaryForm.Instance.Invoke(() => PrimaryForm.Instance.videoPlayerForm.ToggleVocalRemoval());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "service":
|
||||||
|
OverlayForm.MainForm.Invoke(() => OverlayForm.MainForm.ShowTopRightLabel("服務鈴", "a2 53 a4"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "replay":
|
||||||
|
PrimaryForm.Instance.Invoke(() => PrimaryForm.Instance.videoPlayerForm.ReplayCurrentSong());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "male_key":
|
||||||
|
SendSerialCommand(new byte[] { 0xA2, 0x7F, 0xA4 }, new byte[] { 0xA2, 0xB2, 0xA4 }, 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "female_key":
|
||||||
|
SendSerialCommand(new byte[] { 0xA2, 0x7F, 0xA4 }, new byte[] { 0xA2, 0xB1, 0xA4 }, 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "cut":
|
||||||
|
PrimaryForm.Instance.Invoke(() => PrimaryForm.Instance.videoPlayerForm.PlayNextSong());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "lower_key":
|
||||||
|
SendSerialCommand(new byte[] { 0xA2, 0xB2, 0xA4 });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "standard_key":
|
||||||
|
SendSerialCommand(new byte[] { 0xA2, 0x7F, 0xA4 });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "raise_key":
|
||||||
|
SendSerialCommand(new byte[] { 0xA2, 0xB1, 0xA4 });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine($"[Unknown Command] {command}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await SendOkResponse(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 跑馬燈/公告指令
|
||||||
|
// ================================
|
||||||
|
private async Task HandleOverlayCommand(string message, NetworkStream stream)
|
||||||
|
{
|
||||||
|
if (!IsFormReady(OverlayForm.MainForm)) return;
|
||||||
|
|
||||||
|
Match match = Regex.Match(message, @"^(全部|\d{4})\((白色|紅色|綠色|黑色|藍色)\)-");
|
||||||
|
_ = SafeInvoke(OverlayForm.MainForm, () =>
|
||||||
|
{
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
string marqueeMessage = message.Substring(match.Value.Length).Trim();
|
||||||
|
Color textColor = GetColorFromString(match.Groups[2].Value);
|
||||||
|
OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Right, textColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OverlayForm.MainForm.UpdateMarqueeTextSecondLine("系統公告: ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await SendOkResponse(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// Chat 指令 (send-sticker, message)
|
||||||
|
// ================================
|
||||||
|
private async Task HandleChatCommand(string message, NetworkStream stream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] parts = message.Split(',', 2); // 只切一次
|
||||||
|
if (parts.Length < 2)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[ChatCommand Error] 格式錯誤: {message}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string cmd = parts[0].Trim().ToLowerInvariant();
|
||||||
|
string content = parts[1].Trim();
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case "send-sticker":
|
||||||
|
_ = SafeInvoke(OverlayForm.MainForm, () => OnDisplaySticker?.Invoke(content));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "message":
|
||||||
|
_ = SafeInvoke(OverlayForm.MainForm, () => OnDisplayBarrage?.Invoke(content) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine($"[Unknown ChatCommand] {cmd}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await SendOkResponse(stream);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[ChatCommand Error] {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 輔助方法
|
||||||
|
// ================================
|
||||||
|
private async Task SendOkResponse(NetworkStream stream)
|
||||||
|
{
|
||||||
|
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
||||||
|
await stream.WriteAsync(okResponse, 0, okResponse.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TogglePause()
|
||||||
|
{
|
||||||
|
PrimaryForm.Instance.Invoke(() =>
|
||||||
|
{
|
||||||
|
if (VideoPlayerForm.Instance.isPaused)
|
||||||
|
{
|
||||||
|
VideoPlayerForm.Instance.Play();
|
||||||
|
PrimaryForm.Instance.pauseButton.Visible = true;
|
||||||
|
PrimaryForm.Instance.playButton.Visible = false;
|
||||||
|
PrimaryForm.Instance.syncPauseButton.Visible = true;
|
||||||
|
PrimaryForm.Instance.syncPlayButton.Visible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VideoPlayerForm.Instance.Pause();
|
||||||
|
PrimaryForm.Instance.pauseButton.Visible = false;
|
||||||
|
PrimaryForm.Instance.playButton.Visible = true;
|
||||||
|
PrimaryForm.Instance.syncPauseButton.Visible = false;
|
||||||
|
PrimaryForm.Instance.syncPlayButton.Visible = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleMute()
|
||||||
|
{
|
||||||
|
PrimaryForm.Instance.Invoke(() =>
|
||||||
|
{
|
||||||
|
if (PrimaryForm.Instance.videoPlayerForm.isMuted)
|
||||||
|
{
|
||||||
|
PrimaryForm.Instance.videoPlayerForm.Mute(false);
|
||||||
|
PrimaryForm.Instance.videoPlayerForm.isMuted = false;
|
||||||
|
OverlayForm.MainForm.HideMuteLabel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrimaryForm.Instance.videoPlayerForm.Mute(true);
|
||||||
|
PrimaryForm.Instance.videoPlayerForm.isMuted = true;
|
||||||
|
OverlayForm.MainForm.ShowMuteLabel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendSerialCommand(byte[] prefix, byte[]? repeat = null, int repeatCount = 1)
|
||||||
|
{
|
||||||
|
if (SerialPortManager.mySerialPort == null || !SerialPortManager.mySerialPort.IsOpen)
|
||||||
|
{
|
||||||
|
Console.WriteLine("[SerialPort] Port not open.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPortManager.mySerialPort.Write(prefix, 0, prefix.Length);
|
||||||
|
|
||||||
|
if (repeat != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < repeatCount; i++)
|
||||||
|
SerialPortManager.mySerialPort.Write(repeat, 0, repeat.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color GetColorFromString(string colorName) => colorName switch
|
||||||
|
{
|
||||||
|
"白色" => Color.White,
|
||||||
|
"紅色" => Color.Red,
|
||||||
|
"綠色" => Color.LightGreen,
|
||||||
|
"黑色" => Color.Black,
|
||||||
|
"藍色" => Color.LightBlue,
|
||||||
|
_ => Color.Black
|
||||||
|
};
|
||||||
|
|
||||||
|
private string GetHostNameSuffix()
|
||||||
|
{
|
||||||
|
string hostName = Dns.GetHostName();
|
||||||
|
return hostName.Length > 3 ? hostName[^3..] : hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 表單安全呼叫
|
||||||
|
// ================================
|
||||||
private bool IsFormReady(Form form)
|
private bool IsFormReady(Form form)
|
||||||
{
|
{
|
||||||
if (form == null) return false;
|
if (form == null) return false;
|
||||||
bool isReady = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (form.IsHandleCreated && !form.IsDisposed)
|
return form.IsHandleCreated && !form.IsDisposed;
|
||||||
{
|
|
||||||
if (form.InvokeRequired)
|
|
||||||
{
|
|
||||||
form.Invoke(new Action(() => isReady = true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isReady = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
catch { return false; }
|
||||||
{
|
|
||||||
isReady = false;
|
|
||||||
}
|
|
||||||
return isReady;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SafeInvoke(Form form, Action action, int maxRetries = 10)
|
private async Task SafeInvoke(Form form, Action action, int maxRetries = 10)
|
||||||
@ -60,14 +370,8 @@ namespace DualScreenDemo
|
|||||||
{
|
{
|
||||||
if (IsFormReady(form))
|
if (IsFormReady(form))
|
||||||
{
|
{
|
||||||
if (form.InvokeRequired)
|
if (form.InvokeRequired) form.Invoke(action);
|
||||||
{
|
else action();
|
||||||
form.Invoke(action);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
action();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,157 +380,10 @@ namespace DualScreenDemo
|
|||||||
Console.WriteLine($"Invoke attempt {i + 1} failed: {ex.Message}");
|
Console.WriteLine($"Invoke attempt {i + 1} failed: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(500); // 等待500毫秒后重试
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Failed to invoke action after maximum retries");
|
Console.WriteLine("Failed to invoke action after maximum retries");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
listener.Start();
|
|
||||||
Console.WriteLine("Server started on port " + Port + ".");
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Waiting for connections...");
|
|
||||||
using (TcpClient client = listener.AcceptTcpClient())
|
|
||||||
{
|
|
||||||
Console.WriteLine("Connected!");
|
|
||||||
NetworkStream stream = client.GetStream();
|
|
||||||
|
|
||||||
while (client.Connected)
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int bytesRead = stream.Read(buffer, 0, buffer.Length);
|
|
||||||
if (bytesRead == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
string request = Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
|
||||||
Console.WriteLine("Received: " + request.Trim());
|
|
||||||
|
|
||||||
if (request.Length < 5)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string requestHostSuffix = request.Substring(0, 3);
|
|
||||||
string command = request.Substring(4);
|
|
||||||
|
|
||||||
if (requestHostSuffix.Equals(hostNameSuffix, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
// 新增監聽指令
|
|
||||||
|
|
||||||
if (command.Trim().Equals("X", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
_ = SafeInvoke(VideoPlayerForm.Instance, async () =>
|
|
||||||
{
|
|
||||||
_room.set("closed");
|
|
||||||
try{
|
|
||||||
await HttpServer.RestartServer();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Console.WriteLine("RestartServer 發生錯誤: " + ex.Message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
|
||||||
stream.Write(okResponse, 0, okResponse.Length);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Trim().Equals("O", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
// 開台時跳至首頁
|
|
||||||
_room.set("active");
|
|
||||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
|
||||||
stream.Write(okResponse, 0, okResponse.Length);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (command.Trim().Equals("F", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
_ = SafeInvoke(PrimaryForm.Instance, () =>
|
|
||||||
{
|
|
||||||
_room.set("fire");
|
|
||||||
});
|
|
||||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
|
||||||
stream.Write(okResponse, 0, okResponse.Length);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsFormReady(OverlayForm.MainForm))
|
|
||||||
{
|
|
||||||
string message = request.Trim();
|
|
||||||
string pattern = @"^(全部|\d{4})\((白色|紅色|綠色|黑色|藍色)\)-";
|
|
||||||
Match match = Regex.Match(message, pattern);
|
|
||||||
_ = SafeInvoke(OverlayForm.MainForm, () =>
|
|
||||||
{
|
|
||||||
if (match.Success)
|
|
||||||
{
|
|
||||||
string marqueeMessage = message.Substring(match.Value.Length).Trim();
|
|
||||||
Color textColor = GetColorFromString(match.Groups[2].Value);
|
|
||||||
OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Right, textColor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string marqueeMessage = "系統公告: " ;
|
|
||||||
OverlayForm.MainForm.UpdateMarqueeTextSecondLine(marqueeMessage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
|
||||||
stream.Write(okResponse, 0, okResponse.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (request.Trim().Equals("exit", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//Console.WriteLine("Connection closed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error: {e.Message}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
listener.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color GetColorFromString(string colorName)
|
|
||||||
{
|
|
||||||
switch (colorName)
|
|
||||||
{
|
|
||||||
case "白色":
|
|
||||||
return Color.White;
|
|
||||||
case "紅色":
|
|
||||||
return Color.Red;
|
|
||||||
case "綠色":
|
|
||||||
return Color.LightGreen;
|
|
||||||
case "黑色":
|
|
||||||
return Color.Black;
|
|
||||||
case "藍色":
|
|
||||||
return Color.LightBlue;
|
|
||||||
default:
|
|
||||||
return Color.Black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetHostNameSuffix()
|
|
||||||
{
|
|
||||||
string hostName = Dns.GetHostName();
|
|
||||||
return hostName.Length > 3 ? hostName.Substring(hostName.Length - 3) : hostName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user